论文简述
本文依旧是Ian J. Goodfellow大神的系列,提出神经网络对对抗样本的脆弱性的根本原因是其线性特征,这也解释了对抗样本在结构和训练集上的泛化性,并在此基础上提出了FSGM算法用来生成对抗样本。
论文重点
先前工作
发现的问题
研究背景:对抗样本
假设和方法
方法:FGSM:
大白话解释:与常见的分类模型更新参数正好相反 常规的分类模型训练在更新参数时都是将参数减去计算得到的梯度,这样就能使得损失值越来越小,从而模型预测对的概率越来越大。既然无目标攻击是希望模型将输入图像错分类成正确类别以外的其他任何一个类别都算攻击成功,那么只需要损失值越来越大就可以达到这个目标,也就是模型预测的概率中对应于真实标签的概率越小越好,这和原来的参数更新目的正好相反。因此我只需要在输入图像中加上计算得到的梯度方向,这样修改后的图像经过分类网络时的损失值就比修改前的图像经过分类网络时的损失值要大,换句话说,模型预测对的概率变小了。这就是FGSM算法的内容,一方面是基于输入图像计算梯度,另一方面更新输入图像时是加上梯度,而不是减去梯度,这和常见的分类模型更新参数正好背道而驰。
代码实现Pytorch
1 class FGSM(nn.Module):
2 def __init__(self,model):
3 super().__init__()
4 self.model=model#必须是pytorch的model
5 self.device=torch.device("cuda" if (torch.cuda.is_available()) else "cpu")
6 def generate(self,x,**params):
7 self.parse_params(**params)
8 labels=self.y
9 if self.rand_init:
10 x_new = x + torch.Tensor(np.random.uniform(-self.eps, self.eps, x.shape)).type_as(x).cuda()
11
12 # get the gradient of x
13 x_new=Variable(x_new,requires_grad=True)
14 loss_func = nn.CrossEntropyLoss()
15 preds = self.model(x_new)
16 if self.flag_target:
17 loss = -loss_func(preds, labels)
18 else:
19 loss = loss_func(preds, labels)
20 self.model.zero_grad()
21 loss.backward()
22 grad = x_new.grad.cpu().detach().numpy()
23 # get the pertubation of an iter_eps
24 if self.ord==np.inf:
25 grad =np.sign(grad)
26 else:
27 tmp = grad.reshape(grad.shape[0], -1)
28 norm = 1e-12 + np.linalg.norm(tmp, ord=self.ord, axis=1, keepdims=False).reshape(-1, 1, 1, 1)
29 # 选择更小的扰动
30 grad=grad/norm
31 pertubation = grad*self.eps
32
33 adv_x = x.cpu().detach().numpy() + pertubation
34 adv_x=np.clip(adv_x,self.clip_min,self.clip_max)
35
36 return adv_x
37
38 def parse_params(self,eps=0.3,ord=np.inf,clip_min=0.0,clip_max=1.0,
39 y=None,rand_init=False,flag_target=False):
40 self.eps=eps
41 self.ord=ord
42 self.clip_min=clip_min
43 self.clip_max=clip_max
44 self.y=y
45 self.rand_init=rand_init
46 self.model.to(self.device)
47 self.flag_target=flag_target