假设我们有一个卷积神经网络经过培训,可以在 Tensor-Flow 中对(w.l.g.灰度)图像进行分类。
鉴于经过训练的网络和测试图像,人们可以追踪它的哪些像素是显着的,或者等同于#34;哪些像素最负责图像的输出分类。 Theano中的一个很好的解释和实现细节在article中给出。
假设对于与输入图像直接相关的第一层卷积,我们确实具有每个卷积内核-wrt的参数的梯度。分类功能。
如何将渐变传播回输入图层,以便计算图像每个像素的偏导数?
传播和累积回梯度会给我们带来显着的像素(它们是具有大幅度导数的那些)。
找到渐变wrt。第一层的内核,到目前为止我做了:
总而言之,它看起来像:
其中,"输出"是NN的输出层的最大值。 并且g1是(k,k,1,M)张量,因为我在第一层使用M:k x k卷积核。
现在,我需要找到在每个输入像素上传播g1的正确方法,以计算它们的导数wrt。输出。
答案 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.]]