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

Pet*_*ter 4 gradient classification tensorflow

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

给定经过训练的网络和测试图像,人们可以追踪其中的哪些像素是显着的,或者“等效地”追踪哪些像素最负责图像的输出分类。在Theano一个漂亮的解释和实施细则,在此给出的文章

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

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

  1. 传播并累积回梯度,将为我们提供显着的像素(它们是幅值较大的像素)。

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

    1. 将通常的损失算子替换为输出层算子。
    2. 使用了“ compute_gradient”功能,

总而言之,它看起来像:

  • opt = tf.train.GradientDescentOptimizer(1)
  • 等级= opt.compute_gradients(输出)
  • grad_var = [(grad 1代表grads等级)
  • g1 = sess.run([grad_var [0]])

其中,“输出”是NN的输出层的最大值。g1是一个(k,k,1,M)张量,因为我在第一层使用了M:kxk卷积核。

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

Oli*_*rot 5

要计算梯度,您无需使用优化程序,而可以直接使用tf.gradients
使用此功能,您可以直接计算output相对于图像的渐变input,而优化器compute_gradients方法只能计算相对于Variables的渐变。

的另一个优点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.]]
Run Code Online (Sandbox Code Playgroud)