通过神经网络分类器计算图像显着性

时间:2016-06-29 22:03:07

标签: classification tensorflow gradient

假设我们有一个卷积神经网络经过培训,可以在 Tensor-Flow 中对(w.l.g.灰度)图像进行分类。

鉴于经过训练的网络和测试图像,人们可以追踪它的哪些像素是显着的,或者等同于#34;哪些像素最负责图像的输出分类。 Theano中的一个很好的解释和实现细节在article中给出。

假设对于与输入图像直接相关的第一层卷积,我们确实具有每个卷积内核-wrt的参数的梯度。分类功能。

如何将渐变传播回输入图层,以便计算图像每个像素的偏导数?

  1. 传播和累积回梯度会给我们带来显着的像素(它们是具有大幅度导数的那些)。

  2. 找到渐变wrt。第一层的内核,到目前为止我做了:

    1. 用输出图层操作符替换了常用的损失运算符。
    2. 使用" compute_gradient"功能,
  3. 总而言之,它看起来像:

    • opt = tf.train.GradientDescentOptimizer(1)
    • grads = opt.compute_gradients(输出)
    • grad_var = [(grad 1))为毕业生毕业]
    • g1 = sess.run([grad_var [0]])

    其中,"输出"是NN的输出层的最大值。 并且g1是(k,k,1,M)张量,因为我在第一层使用M:k x k卷积核。

    现在,我需要找到在每个输入像素上传播g1的正确方法,以计算它们的导数wrt。输出。

1 个答案:

答案 0 :(得分:5)

要计算渐变,您不需要使用优化器,也可以直接使用tf.gradients
使用此函数,您可以直接计算output相对于图像input的渐变,而优化程序compute_gradients方法只能计算相对于变量的渐变

tf.gradients的另一个优点是您可以指定要反向传播的输出的渐变。

所以这里是如何获得输入图像相对于output[1, 1]

的渐变
  • 我们必须将输出渐变设置为0,除了indice [1, 1]
input = tf.ones([1, 4, 4, 1])
filter = tf.ones([3, 3, 1, 1])
output = tf.nn.conv2d(input, filter, [1, 1, 1, 1], 'SAME')

grad_output = np.zeros((1, 4, 4, 1), dtype=np.float32)
grad_output[0, 1, 1, 0] = 1.

grads = tf.gradients(output, input, grad_output)

sess = tf.Session()
print sess.run(grads[0]).reshape((4, 4))
# prints [[ 1.  1.  1.  0.]
#         [ 1.  1.  1.  0.]
#         [ 1.  1.  1.  0.]
#         [ 0.  0.  0.  0.]]