计算神经网络的梯度

Calculate gradient of neural network

我正在阅读有关对抗图像和破坏神经网络的内容。我正在尝试逐步完成这篇文章,但由于我缺乏经验,我很难理解以下说明。

目前,我有一个 MNIST 数据集的逻辑回归模型。如果你给一张图片,它会预测它最有可能是的数字......

saver.restore(sess, "/tmp/model.ckpt")
# image of number 7
x_in = np.expand_dims(mnist.test.images[0], axis=0)
classification = sess.run(tf.argmax(pred, 1), feed_dict={x:x_in})
print(classification)

现在,文章指出,为了打破这个形象,我们需要做的第一件事就是获得神经网络的梯度。换句话说,这将告诉我使图像看起来更像数字 2 或 3 所需的方向,即使它是 7。

文章指出,使用 back propagation 做到这一点相对简单。所以你可以定义一个函数...

compute_gradient(image, intended_label)

...这基本上告诉我们神经网络在那个时候正在寻找什么样的形状。

对于更有经验的人来说,这似乎很容易实现,但我却不明白其中的逻辑。

从函数 compute_gradient 的参数中,我可以看到您为其提供了一张图像和一组标签,其中预期标签的值设置为 1。

但我不明白这应该如何 return 神经网络的形状。

无论如何,我想了解我应该如何将此 back propagation 算法实现为 return 神经网络的梯度。如果答案不是很简单,我想要一些关于如何让我的 back propagation 像文章建议的那样工作的分步说明。

换句话说,我不需要有人给我一些我可以复制的代码,但我也想了解如何实现它。

反向传播涉及计算网络输出(成本函数)中的误差作为输入和网络参数的函数,然后计算成本函数相对于每个参数的偏导数。在这里详细解释太复杂,但this chapter from a free online book解释反向传播在其通常应用中作为训练深度神经网络的过程。

生成欺骗神经网络的图像只需要将此过程进一步扩展到输入层之外的图像本身。我们不是稍微调整网络中的权重来减少误差,而是稍微调整像素值来增加误差,或者说对于错误的 class.

来减少误差。

有一种简单的(尽管计算密集型)方法可以使用 Calc 101 中的技术来近似梯度:对于足够小的 e,df/dx 大约是 (f(x + e) - f(x) ) / e.

类似地,要使用此技术计算图像的梯度,计算对单个像素添加微小变化后loss/cost的变化量,将该值保存为关于的近似偏导数到那个像素,并为每个像素重复。

那么关于图像的梯度大约是:

(
    (cost(x1+e, x2, ... xn) - cost(x1, x2, ... xn)) / e,
    (cost(x1, x2+e, ... xn) - cost(x1, x2, ... xn)) / e,
    .
    .
    .
    (cost(x1, x2, ... xn+e) - cost(x1, x2, ... xn)) / e
)