通过神经网络分类器计算图像显着性
Computing Image Saliency via Neural Network Classifier
假设我们在 Tensor-Flow.
中训练有一个卷积神经网络来分类(w.l.o.g. 灰度)图像
给定经过训练的网络和测试图像,您可以追踪它的哪些像素是显着的,或者 "equivalently" 哪些像素对图像的输出分类最负责。在这个 article 中给出了 Theano 中的一个很好的解释和实现细节。
假设对于与输入图像直接相关的第一层卷积,我们确实有每个卷积核参数的梯度-wrt。分类功能。
如何将梯度传播回输入层,以便计算图像每个像素的偏导数?
向后传播和累积梯度,会给我们显着像素(它们是那些具有大幅度导数的像素)。
求梯度wrt。第一层的内核,到目前为止我做了:
- 用输出层运算符替换了通常的损失运算符。
- 使用了"compute_gradient"函数,
总而言之,它看起来像:
- opt = tf.train.GradientDescentOptimizer(1)
- grads = opt.compute_gradients(输出)
- grad_var = [(grad1) for grad in grads]
- g1 = sess.run([grad_var[0]])
其中,"output"是神经网络输出层的最大值。
而 g1,是一个 (k, k, 1, M) 张量,因为我在第一层使用了 M: k x k 卷积核。
现在,我需要找到在每个输入像素上传播 g1 的正确方法,以计算它们的导数 wrt。输出。
计算梯度不需要使用优化器,直接使用tf.gradients
.
使用此函数,您可以直接计算 output
相对于图像 input
的梯度,而优化器 compute_gradients
方法只能计算相对于 Variables[ 的梯度 =31=].
tf.gradients
的另一个优点是您可以指定要反向传播的输出的梯度。
下面是如何获取输入图像相对于 output[1, 1]
的梯度:
- 我们必须将输出梯度设置为
0
除了索引 [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.]]
假设我们在 Tensor-Flow.
中训练有一个卷积神经网络来分类(w.l.o.g. 灰度)图像给定经过训练的网络和测试图像,您可以追踪它的哪些像素是显着的,或者 "equivalently" 哪些像素对图像的输出分类最负责。在这个 article 中给出了 Theano 中的一个很好的解释和实现细节。
假设对于与输入图像直接相关的第一层卷积,我们确实有每个卷积核参数的梯度-wrt。分类功能。
如何将梯度传播回输入层,以便计算图像每个像素的偏导数?
向后传播和累积梯度,会给我们显着像素(它们是那些具有大幅度导数的像素)。
求梯度wrt。第一层的内核,到目前为止我做了:
- 用输出层运算符替换了通常的损失运算符。
- 使用了"compute_gradient"函数,
总而言之,它看起来像:
- opt = tf.train.GradientDescentOptimizer(1)
- grads = opt.compute_gradients(输出)
- grad_var = [(grad1) for grad in grads]
- g1 = sess.run([grad_var[0]])
其中,"output"是神经网络输出层的最大值。 而 g1,是一个 (k, k, 1, M) 张量,因为我在第一层使用了 M: k x k 卷积核。
现在,我需要找到在每个输入像素上传播 g1 的正确方法,以计算它们的导数 wrt。输出。
计算梯度不需要使用优化器,直接使用tf.gradients
.
使用此函数,您可以直接计算 output
相对于图像 input
的梯度,而优化器 compute_gradients
方法只能计算相对于 Variables[ 的梯度 =31=].
tf.gradients
的另一个优点是您可以指定要反向传播的输出的梯度。
下面是如何获取输入图像相对于 output[1, 1]
的梯度:
- 我们必须将输出梯度设置为
0
除了索引[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.]]