一、研究机器学习模型攻防的动机
我们训练的模型并非只部署在实验室,我们还需要部署到现实世界中。我们希望机器学习模型能够对专门设计来“欺骗”的输入具备一定的鲁棒性,模型光是对噪声具备一定的鲁棒性是不够的。尤其是在垃圾邮件检测、恶意软件入侵、网络入侵检测这些任务上,我们可能会遇到一些专门设计用来骗过机器学习模型的输入,因此研究机器学习模型的攻击和防御的方法是有必要的。
二、攻击模型的方法
- 概述
对于一个图片分类器来说,我们希望通过为原来可以正确分类的图片(比如一只猫)添加一些噪声来使得模型预测出错误的结果,这些噪声通常是经过专门设计的,并非通过高斯或均匀分布产生的随机噪声。具体的操作是通过为图片的每个像素都添加噪声然后获得被攻击的图片,这张图片虽然肉眼看上去还是猫,但是模型会识别出错误的结果:
- 损失函数的设计
首先我们知道在训练模型时,我们需要使用交叉熵来调整模型的参数,要注意训练时训练资料是固定的,调整的是参数。对于某一张图片,对应的模型的输出为,其标签为,训练时的损失函数为:
该过程如下图所示:
而现在我们要做的是对于图片,我们要找到另一张图片来使得上述训练的模型得到错误的分类结果,也就是使模型受到攻击。这里与训练时不同的是,我们需要固定模型的参数,然后调整输入来获得我们需要的被攻击的输入。这里的攻击分为两种类型:
①Non-targeted Attack
②Targeted Attack
- Non-targeted Attack
无目标的攻击也就是说我们只需要让模型辨认的结果是错误的就好,我们不关系它会被识别成什么类别,而只关心不让输入被识别成正确的类别,因此我们的思想就是要使得对应的模型的输出与真实的标签偏差越大越好,因此我们设计损失函数如下:
该过程如下图所示:
- Targeted Attack
有目标的攻击也就是说我们不只要让模型获得错误的分类结果,而且要让其被分类成某一类,因此在无目标攻击的基础上我们还需要使得对应的模型的输出与我们希望被分类成类别的标签越接近越好,因此我们设计损失函数如下:
该过程如下图所示:
- 限制
为了不被发现,我们还需要使得我们找到的满足一定的限制。比如我们希望被识别成“fish”标签,但是找到的图片真的像一只鱼,那我们的攻击的方法就没有意义了。我们的初衷是在猫的图片上加一点噪声,然后该图片肉眼看起来还和原来一样,因此上述无论Non-targeted Attack还是Targeted Attack都要满足以下限制:
在实际操作中要使得尽可能得小,度量标准就是要使得小到能骗过人类的感知。
接下来举例说明两种度量distance的计算方式,首先定义:
可以使用L2-norm和L-infinity两种方式来计算:
①L2-norm
②L-infinity
对于图像处理来说,使用L-infinity更好一些,可以看以下的例子,一张图片由四个像素组成,我们微调这张图片的像素得到两张与原来的图片具有相同L2-norm距离的图片,如果对应的像素的偏差分布比较均匀的话对于人类的感知来说是看不出差异来的,但是如果这个距离集中在某一个像素上就会有明显的差异。然而使用L-infinity的话就可以避免这个问题,得到的两张图片显然上面的图片L-infinity较小,而下面的L-infinity较大:
- 训练的方法
根据上面的描述训练的过程就是求解一个满足要求的:
使用梯度下降的方法进行求解,该过程如下:
start from original image
for t = 1 to T:
if :
其中:
def :
return the one closest to for all x fulfill
也就是说如果梯度下降的结果超出了限制的范围就要找一个范围以内的值来把超出的结果“拉回来”,该过程如下所示:
要注意L-infinity的方法是在哪个维度上超出了范围就把哪个维度“拉回来”。
训练获得的被攻击的图片与原图有微小的差异,肉眼无法察觉,但是如果将其与原图相减再放大50倍就可以看到图片确实被加入了一些噪声,而且被攻击过的图片也被识别成了“star fish”,置信度也非常高:
- 可视化的解释
我们尝试使用直观的方法来解释为什么可以对模型的输入进行攻击。以下图为例,如果我们随机地为输入添加一些噪声,则可能不会使得加噪的输入跑出原来类别的范围:
然而在高维空间中在某些方向上就有可能该类别的范围非常的狭窄,只需要添加特定的噪声就可以使得识别发生错误,从而实现攻击模型的目的:
- 攻击的不同方法
攻击的方法是多种多样的:
FGSM:https://arxiv.org/abs/1412.6572
Basic iterative method:https://arxiv.org/abs/1607.02533
L-BFGS:https://arxiv.org/abs/1312.6199
Deepfool:https://arxiv.org/abs/1511.04599
JSMA:https://arxiv.org/abs/1511.07528
C&W:https://arxiv.org/abs/1608.04644
Elastic net attack:https://arxiv.org/abs/1709.04114
Spatially Transformed:https://arxiv.org/abs/1801.02612
One Pixel Attack:https://arxiv.org/abs/1710.08864
不同的方法主要区别在于使用不同的优化方法和不同的距离度量函数:
这里介绍一种典型的方法——Fast Gradient Sign Method (FGSM),这个方法在训练时的更新方法为:
这种方法只需要攻击一次(进行一次梯度下降)就可以找到最优的被攻击的输入,而且这种方法不在乎梯度的大小,只在乎梯度的方向。该方法的过程如下图所示:
也可以认为这种方法是学习率非常大的L-infinity方法,因为学习率非常大所以一次梯度下降以后一定会超出限制的范围,所以会被“拉回来”:
- White Box v.s. Black Box
之前的攻击方式都是在知道模型参数的情况下才训练出的被攻击的图片,这种属于White Box Attack,因此是不是只要我们保护好自己的线上模型就可以避免被攻击了呢?事实上不是这样的,因为Black Box Attack是可能的,这是因为被攻击的输入在攻击其他模型时表现出了一定的普适性。
举例来说,如果你拥有你想要攻击的模型的训练资料,只需要用这些训练资料来训练一个自己的Proxy Network,然后攻击这个Proxy Network获得被攻击的输入,然后使用这个输入就可以实现对我们原先想要攻击的模型的攻击。另外,如果没有训练资料的话也可以从模型中获取输入输出对来当做训练资料,然后训练Proxy Network,这种方式也是可以的。这证明了攻击方法的普适性:
下表展示了使用不同的Proxy Network攻击不同的网络模型时模型表现出的正确率,可以看到相同网络结构的模型效果会好一些,同时不同网络模型也会表现出相当不错的攻击效果:
- Universal Adversarial Attack
事实上也可以找到一个普适性的噪声使得这个噪声加到多种图片前面都可以实现攻击的目的,而且这种方法也是可以进行黑盒攻击的,这里列一个reference供参考:https://arxiv.org/abs/1610.08401。
- Adversarial Reprogramming
我们也可以攻击一个模型使得这个模型改变其原来的功能,比如在下面的例子中一个图像分类的模型就可以被攻击来使其用来“数方块”,模型被攻击后使得只要为不同数量的方块图片外围添加噪声然后输入到模型中,就可以使得模型输出不同的类别:
- 现实生活中的攻击
将被攻击的加噪图片印刷出来也是可以通过摄像机镜头来进行识别的,另外有实验也尝试了将影响分类结果的噪声加在图片的特定部位来达到攻击的目的,比如将噪声集中在一副眼镜上,就可以使得人脸识别的结果发生错误。比如在下图中,上面的人带了有噪声的眼睛然后就被识别成了下面的人:
在寻找这样一副眼镜时需要满足一些限制条件,比如:
①要找到一个普适性的噪声使得任何人戴上眼镜都可以被误识别;
②噪声像素之间的差异不可太大,要保证能够被摄像机捕捉到;
③颜色要可以被打印机打印出来;
④……
同时也有实验尝试了给一些路标贴上一些不太显眼的噪声来让路标被识别错误:
三、防御的方法
可能有人会怀疑模型之所以会被攻击,是因为模型过拟合,但是事实证明权重衰减、dropout和模型集成的方法无法应对被攻击的问题。
在防御的方法中分为被动防御(Passive defense)和主动防御(Proactive defense)。
- 被动防御
被动防御的方式是指不修改模型,可以通过在模型前面加一个过滤器(filter),普通的图片通过这个过滤器不会受到影响,但是被攻击的图片通过过滤器会产生小一些的危害。过滤器的作用,举个例子来说,可以对图片进行平滑化处理(Smoothing),可以理解为,被攻击的图片只是在特定方向上被加了噪声,进行平滑化后可以减弱噪声的影响:
以下是普通图片和被攻击的图片经过平滑化后的识别结果:
可以尝试使用多个过滤器来进行防御,在下图中使用了多个过滤器,我们先将图片不经过过滤器进行识别得到结果,然后经过多个过滤器进行预测,如果经过过滤器的预测结果与不经过过滤器的结果差很多就认为图片是被攻击过的,该过程如下:
另外一种过滤方法是先将图片随机进行缩放,然后再在图片周围随机添加一些阴影,最后随机选择一张图片作为模型输入,这样可以对添加的噪声造成一些影响,从而减少攻击的危害,该过程如下:
- 主动防御
主动防御相比被动防御就会改变模型的参数,它是通过重新训练模型的方式来使模型本身具备防御攻击的能力,他的精神就是找出漏洞然后补起来。接下来介绍这个方法的流程。首先,我们假设有数据,这个方法的流程如下:
Using X to train your model
for t = 1 to T:
for n = 1 to N:
Find adversarial input given by an attack algorithm
We have new training data
Using to update your model
这类似于用了增加数据(Data Augmentation)的方式来训练模型。这里需要迭代T次的作用在于每次模型被更新以后,模型的参数就变了,就有可能产生新的漏洞,所以需要迭代多次。遗憾的是,如果在训练过程中获得被攻击的输入的方法是Algorithm A,当模型受到来自使用Algorithm B获得的输入攻击时仍然会被攻击成功。
从来都是造矛容易造盾难,相比于攻击的方法,模型防御的方法还有待进一步研究。