TensorFlow:如何生成可区分的遮罩

时间:2018-10-04 04:44:09

标签: python tensorflow mask

我想从张量生成蒙版。例如:

import numpy as np
import tensorflow as tf
input = tf.Variable(np.array([[0, 0.1], [0.9, 1.0]]))

然后从input,我想获得一个具有值的蒙版张量:

[[0, 1.0], [1.0, 1.0]]

一种方法是:

output = tf.cast(tf.cast(input, dtype=tf.bool), dtype=tf.float32)

但是,tf.cast是不可微的,并且梯度不能向后传播,而我希望该操作是可微的。 我还搜索其他方法,例如tf.floortf.where,但它们都是不可区分的。

一种可能的方法是使用这些不可微方法并为其定义梯度。但是,我想知道它们的梯度应该是多少才能使反向传播可行(也许只是将梯度设置为1?),为什么?

1 个答案:

答案 0 :(得分: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型本身作为遮罩呢?