我想从张量生成蒙版。例如:
import numpy as np
import tensorflow as tf
input = tf.Variable(np.array([[0, 0.1], [0.9, 1.0]]))
从
input
,我想获得一个具有值的mask张量:[[0, 1.0], [1.0, 1.0]]
一种方法是:
output = tf.cast(tf.cast(input, dtype=tf.bool), dtype=tf.float32)
但是,
tf.cast
是不可微的,并且渐变不能向后传播,而我希望该操作是可微的。我也搜索其他方法,例如
tf.floor
,tf.where
,但是它们都是不可区分的。一种可能的方法是使用这些不可微的方法并为其定义梯度。但是,我想知道它们的梯度应该是多少才能使反向传播可行(也许只是将梯度设置为1?),为什么?
最佳答案
如您所建议,您可以人为地将渐变粘贴到无法区分的遮罩操作上。这是一个示例,其中渐变始终为1:
import tensorflow as tf
def my_mask(x):
return tf.to_float(tf.greater(x, 0))
def diff_mask(mask_op):
@tf.custom_gradient
def _diff_mask(x):
def grad(dy):
return dy * tf.ones_like(x)
return mask_op(x), grad
return _diff_mask
x = tf.random_normal((5,))
w = tf.random_normal((5,))
m = diff_mask(my_mask)(w)
loss = x * m
g = tf.gradients([loss], [x, w])
sess = tf.InteractiveSession()
sess.run([x, loss] + g)
您当然可以选择其他渐变,例如S型渐变。这实际上取决于您想做什么。由于阈值不可区分,因此任何选择都是错误的,但希望有一种选择对您有用。
这种技术的一个陷阱是,现在您使用的梯度不是您要最小化的损耗的梯度。这就是为什么人们通常倾向于使用软阈值,而不是硬阈值。例如,如果由于感觉需要在反馈中使用阈值而打算使用S型梯度,那么为什么不使用S型本身作为遮罩呢?
关于python - TensorFlow:如何生成可区分的 mask ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52639165/