Adversarial Training-Fast gradient sign method

本文收录在无痛的机器学习第二季目录

在上一次的神经网络的局部泛化 - 知乎专栏中,我们一起计算了全连接层参数和卷积层参数的norm,这个值可以表示所在网络层对模型输入波动的抵抗能力,而在更早的文章寻找CNN的弱点 - 知乎专栏中,我们也提到了CNN模型的弱点,如何找到一些特殊的case,使得这些从某个训练数据演变出来的图片被错误识别。另外,同样的一篇之前的文章:CNN-反卷积(1) - 知乎专栏,我们分析了反卷积操作,以及梯度的含义。今天提到的一篇文章和上面的几篇文章都有关系,它试图帮助我们找到模型的一些盲点,用简单快捷的方法找到一些“应该可以搞定”但是没有搞定的case。

这篇文章叫做《Explaining and harnessing adversarial examples》,作者团队和上一篇文章的作者是一班人马。Ian Goodfellow同学真的和“adversarial”这个词有缘,先是做Adaversarial training,又是做GAN。

让我们直接进入主题——如何快速找到模型的盲点?所谓的盲点,就是找到一些输入数据,这些数据这样的特点:让人看很容易得出正确答案,而让模型却会识别错误。更要命的是,一般会有一个和它长得差不多的数据,这个数据可以被模型正确识别。一般来说,后面提到的这个数据存在于训练数据或者预测数据中,而前面提到的识别错误的数据是人为生成的。

前面我们提到过一种找到这类数据的方法,这种方法的思想源自遗传算法,需要反复地迭代,也需要模型去判别。而这篇文章中提到的方法则显得更加的直接有效,同时在理论上也更说的通,这个方法被称为Fast gradient sign method,简称FGSM。

它的方法用到了反向梯度的思想。假设我们现在拥有一张图片X,它的label为Y,同时模型的参数以\theta代替,那么输入数据对目标函数的偏导数为:

\nabla_x J(\theta,x,y)

利用当今的各种开源工具,我们可以设法求出这个数值来。这个数值有什么意义?它表示了对于输入数据而言,目标函数变化的方向和强度。如果图像的数据沿着这个方向进行变化,那么它的变化,相对于其他方向而言,对目标函数值的影响是最大的。换句话说,这样移动最容易改变最终的识别值。

既然如此,那么可以想象,沿着这个方向移动,肯定存在某个步长\eta,使得某个新输入数据

x'=x+\eta \nabla_x J(\theta,x,y)

和原始数据的识别结果不同。我们将\eta设到非常大时,这个情况肯定会出现。那么如果\eta设置得不那么大时,这个情况还会出现么?这个就是我们要考虑的问题了。

如果模型不做特殊的处理,对于上面这个公式,我们并不需要很大的\eta就可以找到x'这样的输入。由于\eta很小,所以对于人眼来说,x'和x的差距并不大,有时人眼甚至无法感知两张图片的明显区别,但是对于CNN模型来说,识别的错误还是发生了。

从前面章节的分析可以看出,\eta的大小和模型参数的范数(norm)也有关系。范数越大,\eta的取值就可能越小,模型的盲区就越可能比较多。


解决问题

遇到这样的问题怎么办?显然我们希望模型可以变得更加鲁棒。一个最简单的方法,就是生成这些数据,并且把这些数据加入到训练数据中。这样模型就会正视这些数据,并且尽可能地拟合这些数据,最终完成了模型拟合,这些盲区也就覆盖住了。

那么数据生成的公式是什么样的呢?所谓的FGSM是这样生成数据的:

x'=x+\eta* sign(\nabla_x J(\theta,x,y))

尽管计算梯度时不同的方向维度的梯度幅度不同,在生成数据时,各个方向被统一归一化成相同的数量。这样可以确保在修改图片时,每个像素的修改量尽量相同,修改得更均匀些。

除了这个方法,另外一个方法就是直接将这部分数据的影响整合到目标函数中:

\hat{J}(\theta,x,y)=\alpha J(\theta,x,y)+(1-\alpha) J(\theta, x + \eta * sign(\nabla_x J(\theta,x,y)))

可以看出,这个目标函数中,除了数据本身的loss部分,还有被修改后的输入的loss,保持两部分的loss平衡的参数为\alpha

这个方法带来了什么样的好处?如果我们让\eta在某个范围内随机取值,那么基本上每一个训练数据附近的一个临域内,我们都可以保持它的识别正确。这样模型的鲁棒性也有了一定的提升。

当然,说到这里,大家也会想到另外一种解决问题的方法,那就是数据增强的方法。如果我们对每一张输入数据随机加入高斯噪声,是不是也可以同样地解决这个问题呢?换句话说,我们的目标函数可以变成:

\hat{J}(\theta,x,y)=\alpha J(\theta,x,y)+(1-\alpha) J(\theta, x + \Delta x)

于是我们陷入了思考,这样是不是就可以解决问题呢?这个公式看上去目标函数更为简洁,为什么要用gradient呢?

广告时间

更多精彩尽在《深度学习轻松学:核心算法与视觉实践》

编辑于 2017-11-22

文章被以下专栏收录