创建适用于特定像素的自定义 ReLU
Creating a Custom ReLU that works on specific pixels
我想创建一个自定义 ReLU 函数,该函数采用一个向量 V
,该向量包含像素的二维位置,即 [[1, 3], [1,1] ..]
并对所有通道中的这些像素执行 ReLU 操作。
input_tensor 是一个张量,在它穿过 Conv2D
层之后 - 所以它的形状是:(None, 30, 30, 16)
(原图为32x32x3
)
我的代码(我知道它实际上不会 return 改变 input_tensor,它只是为了解决我遇到的一些第一个问题):
def relu(x):
if x > 0:
return x
else:
return 0
class Custom_ReLU(Layer):
def __init__(self):
super(Custom_ReLU, self).__init__()
def call(self, input_tensor, V=None):
for i in range(len(V)):
relu(input_tensor[ V[i] ])
return input_tensor
当 运行 出现此错误时,我将张量传递给 relu - 所以我的索引不正确,但我尝试以不同的方式对其进行索引,但我一无所获:
ValueError: Exception encountered when calling layer "custom__re_lu" (type Custom_ReLU).
in user code:
File "/home/adav/prog/tf/main.py", line 63, in call *
relu(input_tensor[ V[i][0], V[i][1] ])
File "/home/adav/prog/tf/main.py", line 51, in relu *
if x > 0:
ValueError: condition of if statement expected to be `tf.bool` scalar, got Tensor("my_model/custom__re_lu/Greater:0", shape=(30, 16), dtype=bool); to check for None, use `is not None`
Call arguments received:
• input_tensor=tf.Tensor(shape=(None, 30, 30, 16), dtype=float32)
• V=array([[ 1, 1],
[ 1, 4],
[ 1, 7],
.
.
.
如有任何帮助,我们将不胜感激!
您可以尝试使用 tf.gather_nd
和 tf.tensor_scatter_nd_update
:
import tensorflow as tf
class Custom_ReLU(tf.keras.layers.Layer):
def __init__(self):
super(Custom_ReLU, self).__init__()
def call(self, inputs):
shape = tf.shape(inputs)
V = tf.stack([(i, j) for i in tf.range(1,29,3) for j in tf.range(1,29,3)])
indices = tf.concat([tf.expand_dims(tf.repeat(tf.range(0, shape[0]), repeats=tf.shape(V)[0]), axis=-1), tf.tile(V, [shape[0],1])], axis=-1)
y = tf.gather_nd(inputs, indices)
y = tf.where(tf.greater(y, 0.0), y, tf.constant(0.0))
return tf.tensor_scatter_nd_update(x, indices, y)
custom_relu = Custom_ReLU()
x = tf.random.normal((2, 30, 30, 16))
print(custom_relu(x))
运行 使用较小的张量进行几次迭代以查看值如何变化。
我想创建一个自定义 ReLU 函数,该函数采用一个向量 V
,该向量包含像素的二维位置,即 [[1, 3], [1,1] ..]
并对所有通道中的这些像素执行 ReLU 操作。
input_tensor 是一个张量,在它穿过 Conv2D
层之后 - 所以它的形状是:(None, 30, 30, 16)
(原图为32x32x3
)
我的代码(我知道它实际上不会 return 改变 input_tensor,它只是为了解决我遇到的一些第一个问题):
def relu(x):
if x > 0:
return x
else:
return 0
class Custom_ReLU(Layer):
def __init__(self):
super(Custom_ReLU, self).__init__()
def call(self, input_tensor, V=None):
for i in range(len(V)):
relu(input_tensor[ V[i] ])
return input_tensor
当 运行 出现此错误时,我将张量传递给 relu - 所以我的索引不正确,但我尝试以不同的方式对其进行索引,但我一无所获:
ValueError: Exception encountered when calling layer "custom__re_lu" (type Custom_ReLU).
in user code:
File "/home/adav/prog/tf/main.py", line 63, in call *
relu(input_tensor[ V[i][0], V[i][1] ])
File "/home/adav/prog/tf/main.py", line 51, in relu *
if x > 0:
ValueError: condition of if statement expected to be `tf.bool` scalar, got Tensor("my_model/custom__re_lu/Greater:0", shape=(30, 16), dtype=bool); to check for None, use `is not None`
Call arguments received:
• input_tensor=tf.Tensor(shape=(None, 30, 30, 16), dtype=float32)
• V=array([[ 1, 1],
[ 1, 4],
[ 1, 7],
.
.
.
如有任何帮助,我们将不胜感激!
您可以尝试使用 tf.gather_nd
和 tf.tensor_scatter_nd_update
:
import tensorflow as tf
class Custom_ReLU(tf.keras.layers.Layer):
def __init__(self):
super(Custom_ReLU, self).__init__()
def call(self, inputs):
shape = tf.shape(inputs)
V = tf.stack([(i, j) for i in tf.range(1,29,3) for j in tf.range(1,29,3)])
indices = tf.concat([tf.expand_dims(tf.repeat(tf.range(0, shape[0]), repeats=tf.shape(V)[0]), axis=-1), tf.tile(V, [shape[0],1])], axis=-1)
y = tf.gather_nd(inputs, indices)
y = tf.where(tf.greater(y, 0.0), y, tf.constant(0.0))
return tf.tensor_scatter_nd_update(x, indices, y)
custom_relu = Custom_ReLU()
x = tf.random.normal((2, 30, 30, 16))
print(custom_relu(x))
运行 使用较小的张量进行几次迭代以查看值如何变化。