论文链接:https://arxiv.org/abs/1412.6572
源码出处:https://github.com/Harry24k/adversarial-attacks-pytorch/tree/master
源码
import torch
import torch.nn as nn
from ..attack import Attack
class FGSM(Attack):
r"""
FGSM in the paper 'Explaining and harnessing adversarial examples'
[https://arxiv.org/abs/1412.6572]
Distance Measure : Linf
Arguments:
model (nn.Module): model to attack.
eps (float): maximum perturbation. (Default: 8/255)
Shape:
- images: :math:`(N, C, H, W)` where `N = number of batches`, `C = number of channels`, `H = height` and `W = width`. It must have a range [0, 1].
- labels: :math:`(N)` where each value :math:`y_i` is :math:`0 \leq y_i \leq` `number of labels`.
- output: :math:`(N, C, H, W)`.
Examples::
>>> attack = torchattacks.FGSM(model, eps=8/255)
>>> adv_images = attack(images, labels)
"""
def __init__(self, model, eps=8/255):
super().__init__("FGSM", model)
self.eps = eps
self.supported_mode = ['default', 'targeted']
def forward(self, images, labels):
r"""
Overridden.
"""
self._check_inputs(images)
images = images.clone().detach().to(self.device)
labels = labels.clone().detach().to(self.device)
if self.targeted:
target_labels = self.get_target_label(images, labels)
loss = nn.CrossEntropyLoss()
images.requires_grad = True
outputs = self.get_logits(images)
# Calculate loss
if self.targeted:
cost = -loss(outputs, target_labels)
else:
cost = loss(outputs, labels)
# Update adversarial images
grad = torch.autograd.grad(cost, images,
retain_graph=False, create_graph=False)[0]
adv_images = images + self.eps*grad.sign()
adv_images = torch.clamp(adv_images, min=0, max=1).detach()
return adv_images
解析
FGSM的全称是Fast Gradient Sign Method(快速梯度下降法),在白盒环境下,通过求出损失cost
对输入的导数,然后用符号函数sign()
得到其具体的梯度方向,接着乘以一个步长eps
,得到的“扰动”加在原来的输入上就得到了在FGSM攻击下的样本。
可以仔细回忆一下,在神经网络的反向传播当中,我们在训练过程时就是沿着梯度下降的方向来更新更新
w
,
b
w,b
w,b的值。这样做可以使得网络往损失cost
减小的方向收敛。简单来说,梯度方向代表了损失cost
改变速度最快的方向,FGSM算法假设目标损失函数
J
(
x
,
y
)
J(x,y)
J(x,y)与
x
x
x之间是近似线性的,即
J
(
x
,
y
)
≈
w
T
x
J(x ,y)≈w^Tx
J(x,y)≈wTx,所以沿着梯度上升的方向改变输入
x
x
x可以增大损失,从而达到使模型分类错误的目的。具体做法是在图像上加一个扰动
η
\eta
η,
η
=
ϵ
s
i
g
n
(
▽
x
J
(
θ
,
x
,
y
)
)
\eta= \epsilon sign(\triangledown_{x}J(\theta,x,y))
η=ϵsign(▽xJ(θ,x,y)),其中
▽
x
\triangledown_{x}
▽x即梯度,
ϵ
\epsilon
ϵ即步长,也就是每个像素扰动的最大值。
若是无目标攻击,综上所述,公式如下:
X
a
d
v
=
X
+
ϵ
s
i
g
n
(
▽
x
J
(
X
,
y
t
r
u
e
)
)
X^{adv}=X+\epsilon sign(\triangledown_xJ(X,y_{true}))
Xadv=X+ϵsign(▽xJ(X,ytrue))其中,
y
t
r
u
e
y_{true}
ytrue为样本
X
X
X的真实标签。
若是有目标攻击,则需要增加扰动去逼近目标标签,也就是要让样本与目标标签之间损失减小,公式如下:
X
a
d
v
=
X
−
ϵ
s
i
g
n
(
▽
x
J
(
X
,
y
t
a
r
g
e
t
)
)
X^{adv}=X-\epsilon sign(\triangledown_xJ(X,y_{target}))
Xadv=X−ϵsign(▽xJ(X,ytarget))其中,
y
t
a
r
g
e
t
y_{target}
ytarget即为目标标签,目标标签的选取有多种方式,例如可以选择与真实标签相差最大的标签,也可以随机选择除真实标签外的标签。
forward()
函数就是攻击过程,输入图像images
和标签y
,即可返回对抗图像adv_images
。images = images.clone().detach().to(self.device)
:clone()
将图像克隆到一块新的内存区(pytorch默认同样的tensor共享一块内存区);detach()
是将克隆的新的tensor从当前计算图中分离下来,作为叶节点,从而可以计算其梯度;to()
作用就是将其载入设备。target_labels = self.get_target_label(images, labels)
:若是有目标攻击的情况,获取目标标签。目标标签的选取有多种方式,例如可以选择与真实标签相差最大的标签,也可以随机选择除真实标签外的标签。loss = nn.CrossEntropyLoss()
:设置损失函数为交叉熵损失。images.requires_grad = True
:将这个参数设置为True,pytorch就会在程序运行过程中自动生成计算图,供计算梯度使用。outputs = self.get_logits(images)
:获得图像的在模型中的输出值。cost = -loss(outputs, target_labels)
:有目标情况下计算损失cost = loss(outputs, labels)
:无目标情况下计算损失grad = torch.autograd.grad(cost, images, retain_graph=False, create_graph=False)[0]
:cost
对images
求导,得到梯度grad
。adv_images = images + self.eps*grad.sign()
:根据公式在原图像上增加一个扰动,得到对抗图像。adv_images = torch.clamp(adv_images, min=0, max=1).detach()
:将images
中大于1的部分设为1,小于0的部分设为0,防止越界。文章来源:https://www.toymoban.com/news/detail-718736.html
思考
FGSM算法假设目标损失函数 J ( x , y ) J(x,y) J(x,y)与 x x x之间是近似线性的,但是这个线性假设不一定正确,如果它们之间不是线性的,那么在 ( 0 , ϵ s i g n ( ▽ x J ( θ , x , y ) ) ) (0,\epsilon sign(\triangledown_{x}J(\theta,x,y))) (0,ϵsign(▽xJ(θ,x,y)))之间是否存在某个扰动,使得 J J J增加的也很大,此时 x x x的修改量就可以小于 ϵ \epsilon ϵ。于是,有学者就提出迭代的方式来找各个像素点的扰动,也就是BIM算法,具体可以查看下一篇博客。文章来源地址https://www.toymoban.com/news/detail-718736.html
到了这里,关于FGSM(Fast Gradient Sign Method)算法源码解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!