对抗攻击FGSM的纯粹版FGNS
引言
?FGSM\mathrm{FGSM}FGSM是基于梯度迭代攻擊中生成對抗樣本的開創性工作。我第一次接觸相關工作的時候,給我困惑最多的就是論文中為什么要給梯度加上sign\mathrm{sign}sign這個符號函數,因為這會導致生成的對抗擾動的方向與最速梯度方向有一個銳角偏移。IanGoodfellow\mathrm{Ian\text{ } Goodfellow}Ian?Goodfellow在斯坦福大學的講座里對梯度符號中加入sign\mathrm{sign}sign符號給出了一個基于實證的解釋,即在線性假設下,給定一個數據集的樣本,當樣本中對抗擾動分量方向與梯度分量的方向相同的個數如果多余某個常數時,該樣本沿著對抗擾動的方向即可進入到對抗子區域中。這個解釋是在說明加入sign\mathrm{sign}sign符號后的擾動方向依然具有攻擊性,但從原理上來說這并不是最好的攻擊方向。最近看到了一篇文章,就討論了該問題,論文作者通過原理分析實驗驗證,發現當梯度方向加入sign\mathrm{sign}sign符號后會使得攻擊效率比較低。論文的代碼鏈接失效,我根據論文中的算法流程圖重新編寫了一下代碼。
論文鏈接:https://arxiv.org/abs/2110.12734
理論分析
?給定一個樣本xxx,其對應的標簽為yyy,損失函數為L(x,y)\mathcal{L}(x,y)L(x,y),其中第ttt步生成的對抗樣本為xTadvx^{adv}_TxTadv?。根據多元函數的泰勒展開公式可以得到如下方程組
{L(xTadv,y)=L(xT?1adv,y)+(xTadv?xT?1adv)??L(xT?1adv,y)+O(∥xTadv?xT?1adv∥2)L(xT?1adv,y)=L(xT?2adv,y)+(xT?1adv?xT?2adv)??L(xT?2adv,y)+O(∥xT?1adv?xT?2adv∥2)L(xT?2adv,y)=L(xT?3adv,y)+(xT?2adv?xT?3adv)??L(xT?3adv,y)+O(∥xT?2adv?xT?3adv∥2)?L(x3adv,y)=L(x2adv,y)+(x3adv?x2adv)??L(x2adv,y)+O(∥x3adv?x2adv∥2)L(x2adv,y)=L(x2adv,y)+(x2adv?x1adv)??L(x1adv,y)+O(∥x2adv?x1adv∥2)L(x1adv,y)=L(x0adv,y)+(x1adv?x0adv)??L(x0adv,y)+O(∥x1adv?x0adv∥2)\left\{\begin{aligned}\mathcal{L}(x^{adv}_T,y)&=\mathcal{L}(x^{adv}_{T-1},y)+(x^{adv}_T-x^{adv}_{T-1})\cdot \nabla \mathcal{L}(x^{adv}_{T-1},y)+O(\|x^{adv}_T-x^{adv}_{T-1}\|^2)\\\mathcal{L}(x^{adv}_{T-1},y)&=\mathcal{L}(x^{adv}_{T-2},y)+(x^{adv}_{T-1}-x^{adv}_{T-2})\cdot \nabla \mathcal{L}(x^{adv}_{T-2},y)+O(\|x^{adv}_{T-1}-x^{adv}_{T-2}\|^2)\\\mathcal{L}(x^{adv}_{T-2},y)&=\mathcal{L}(x^{adv}_{T-3},y)+(x^{adv}_{T-2}-x^{adv}_{T-3})\cdot \nabla \mathcal{L}(x^{adv}_{T-3},y)+O(\|x^{adv}_{T-2}-x^{adv}_{T-3}\|^2)\\ \vdots \\ \mathcal{L}(x^{adv}_{3},y)&=\mathcal{L}(x^{adv}_{2},y)+(x^{adv}_{3}-x^{adv}_{2})\cdot \nabla \mathcal{L}(x^{adv}_{2},y)+O(\|x^{adv}_{3}-x^{adv}_{2}\|^2)\\ \mathcal{L}(x^{adv}_{2},y)&=\mathcal{L}(x^{adv}_{2},y)+(x^{adv}_{2}-x^{adv}_{1})\cdot \nabla \mathcal{L}(x^{adv}_{1},y)+O(\|x^{adv}_{2}-x^{adv}_{1}\|^2)\\\mathcal{L}(x^{adv}_{1},y)&=\mathcal{L}(x^{adv}_0,y)+(x^{adv}_{1}-x^{adv}_0)\cdot \nabla \mathcal{L}(x^{adv}_0,y)+O(\|x^{adv}_{1}-x^{adv}_0\|^2) \end{aligned}\right.??????????????????????????????L(xTadv?,y)L(xT?1adv?,y)L(xT?2adv?,y)?L(x3adv?,y)L(x2adv?,y)L(x1adv?,y)?=L(xT?1adv?,y)+(xTadv??xT?1adv?)??L(xT?1adv?,y)+O(∥xTadv??xT?1adv?∥2)=L(xT?2adv?,y)+(xT?1adv??xT?2adv?)??L(xT?2adv?,y)+O(∥xT?1adv??xT?2adv?∥2)=L(xT?3adv?,y)+(xT?2adv??xT?3adv?)??L(xT?3adv?,y)+O(∥xT?2adv??xT?3adv?∥2)=L(x2adv?,y)+(x3adv??x2adv?)??L(x2adv?,y)+O(∥x3adv??x2adv?∥2)=L(x2adv?,y)+(x2adv??x1adv?)??L(x1adv?,y)+O(∥x2adv??x1adv?∥2)=L(x0adv?,y)+(x1adv??x0adv?)??L(x0adv?,y)+O(∥x1adv??x0adv?∥2)?根據以上方程組可以得到如下公式L(xTadv,y)=L(x,y)+∑t=0T?1(xt+1adv?xtadv)??L(xtadv,y)+∑t=0T?1O(∥xt+1adv?xtadv∥2)\mathcal{L}(x^{adv}_T,y)=\mathcal{L}(x,y)+\sum\limits_{t=0}^{T-1}(x^{adv}_{t+1}-x^{adv}_t)\cdot \nabla\mathcal{L}(x^{adv}_t,y)+\sum\limits_{t=0}^{T-1}O(\|x^{adv}_{t+1}-x^{adv}_t\|^2)L(xTadv?,y)=L(x,y)+t=0∑T?1?(xt+1adv??xtadv?)??L(xtadv?,y)+t=0∑T?1?O(∥xt+1adv??xtadv?∥2)令δt=xt+1adv?xtadv\delta_t=x_{t+1}^{adv}-x_t^{adv}δt?=xt+1adv??xtadv?,gt=?L(xtadv,y)g_t=\nabla\mathcal{L}(x^{adv}_t,y)gt?=?L(xtadv?,y),進而則有L(xTadv,y)=L(x,y)+∑t=0T?1δt?gt+∑t=0T?1O(∥δt∥2)=L(x,y)+∑t=0T?1∥δt∥?∥gt∥?cos??δt,gt?+∑t=0T?1O(∥δt∥2)≈L(x,y)+∑t=0T?1∥δt∥?∥gt∥?cos??δt,gt?\begin{aligned}\mathcal{L}(x^{adv}_T,y)&=\mathcal{L}(x,y)+\sum\limits_{t=0}^{T-1}\delta_t \cdot g_t + \sum\limits_{t=0}^{T-1}O(\|\delta_t\|^2)\\&=\mathcal{L}(x,y)+\sum\limits_{t=0}^{T-1}\|\delta_t\|\cdot \|g_t\|\cdot \cos\langle \delta_t, g_t \rangle + \sum\limits_{t=0}^{T-1}O(\|\delta_t\|^2)\\&\approx \mathcal{L}(x,y)+\sum\limits_{t=0}^{T-1}\|\delta_t\|\cdot\|g_t\|\cdot \cos\langle \delta_t, g_t \rangle \end{aligned}L(xTadv?,y)?=L(x,y)+t=0∑T?1?δt??gt?+t=0∑T?1?O(∥δt?∥2)=L(x,y)+t=0∑T?1?∥δt?∥?∥gt?∥?cos?δt?,gt??+t=0∑T?1?O(∥δt?∥2)≈L(x,y)+t=0∑T?1?∥δt?∥?∥gt?∥?cos?δt?,gt???假設xtadv=[xt1,xt2,?,xtD]x^{adv}_t=\left[x^1_t,x^2_t,\cdots,x^D_t\right]xtadv?=[xt1?,xt2?,?,xtD?],gt=[?xt1,?xt2,?,?xtD]g_t=\left[\nabla_{x^1_t},\nabla_{x^2_t},\cdots,\nabla_{x^D_t}\right]gt?=[?xt1??,?xt2??,?,?xtD??],且D=H×W×CD=H\times W \times CD=H×W×C。令δt=sign(gt)\delta_t=\mathrm{sign}(g_t)δt?=sign(gt?),則此時δt\delta_tδt?和gtg_tgt?的余弦值cos?θt\cos \theta_tcosθt?表示為cos?θt=gt?sign(gt)∥gt∥∥sign(gt)∥\cos \theta_t=\frac{g_t\cdot \mathrm{sign}{(g_t)}}{\|g_t\| \|\mathrm{sign}(g_t)\|}cosθt?=∥gt?∥∥sign(gt?)∥gt??sign(gt?)?因為gt?sign(gt)=?xt1?sign(?xt1)+?xt2?sign(?xt2)+?+?xtD?sign(?xtD)=∣?xt1∣+∣?xt2∣+?+∣?xtD∣=∥gt∥1\begin{aligned}g_t \cdot \mathrm{sign}(g_t)&=\nabla_{x^1_t} \cdot \mathrm{sign}(\nabla_{x^1_t})+\nabla_{x^2_t} \cdot \mathrm{sign}(\nabla_{x^2_t})+\cdots+\nabla_{x^D_t} \cdot \mathrm{sign}(\nabla_{x^D_t})\\&=\left|\nabla_{x^1_t}\right|+\left|\nabla_{x^2_t}\right|+\cdots+\left|\nabla_{x^D_t}\right|\\&=\left\|g_t\right\|_1\end{aligned}gt??sign(gt?)?=?xt1???sign(?xt1??)+?xt2???sign(?xt2??)+?+?xtD???sign(?xtD??)=∣∣∣??xt1??∣∣∣?+∣∣∣??xt2??∣∣∣?+?+∣∣∣??xtD??∣∣∣?=∥gt?∥1??又因為∥gt∥0=∥sign(gt)∥≈D\|g_t\|_0=\|\mathrm{sign}(g_t)\|\approx D∥gt?∥0?=∥sign(gt?)∥≈D,在向量所有的ppp范數中1范數是最大的,即∥?∥1≥∥?∥\|\cdot\|_1 \ge \|\cdot\|∥?∥1?≥∥?∥,此時則有cos?θt=∥gt∥1∥gt∥∥sign(gt)∥?1D<cos?θt≤1\begin{aligned}\cos \theta_t=\frac{\|g_t\|_1}{\|g_t\|\|\mathrm{sign}(g_t)\|}\Longrightarrow& \frac{1}{\sqrt{D}} < \cos \theta_t \le1 \end{aligned}cosθt?=∥gt?∥∥sign(gt?)∥∥gt?∥1????D?1?<cosθt?≤1?進而則有1<∥δt∥cos?θt≤D1 < \|\delta_t\| \cos \theta_t \le \sqrt{D}1<∥δt?∥cosθt?≤D?令新的對抗擾動為δt′\delta_t^{\prime}δt′?,且此時該擾動的方向與梯度方向一致即cos??δt′,gt?=cos??t=1\cos \langle \delta_t^{\prime},g_t\rangle=\cos \phi_t=1cos?δt′?,gt??=cos?t?=1為了能夠使得與FGSM\mathrm{FGSM}FGSM的擾動步長∥sign(gt)∥\|\mathrm{sign}(g_t)\|∥sign(gt?)∥范圍一致,則有ζ=∥sign(gt)∥∥gt∥\zeta=\frac{\|\mathrm{sign}(g_t)\|}{\|g_t\|}ζ=∥gt?∥∥sign(gt?)∥?進而則有δt′=ζ?gt?∥δt′∥=∥sign(gt)∥∥gt∥?∥gt∥=∥sign(gt)∥\begin{aligned}&\delta^{\prime}_t= \zeta \cdot g_t\\\Longrightarrow&\|\delta^\prime_t\|=\frac{\|\mathrm{sign}(g_t)\|}{\|g_t\|}\cdot \|g_t\|=\|\mathrm{sign}(g_t)\|\end{aligned}??δt′?=ζ?gt?∥δt′?∥=∥gt?∥∥sign(gt?)∥??∥gt?∥=∥sign(gt?)∥?根據以上公式則可以推導出∥δt∥cos?θt≤∥δt′∥cos??t=D\|\delta_t\|\cos \theta_t \le \|\delta_t^\prime\|\cos \phi_t=\sqrt{D}∥δt?∥cosθt?≤∥δt′?∥cos?t?=D?給定?\epsilon?的范圍,第ttt步的對抗擾動為xt+1adv?xtadv=clip?x(xtadv+α?δt′)?xtadvx^{adv}_{t+1}-x^{adv}_t=\mathrm{clip}_{\epsilon}^{x}\left(x^{adv}_t + \alpha \cdot \delta^{\prime}_t\right)-x^{adv}_txt+1adv??xtadv?=clip?x?(xtadv?+α?δt′?)?xtadv?FGNM\mathrm{FGNM}FGNM具體的算法流程圖如下所示
實驗結果
?如下圖所示,為原始梯度方向和sign\mathrm{sign}sign梯度方向的可視化剪頭圖。從下圖發現原始梯度更快更高效收斂到最優點中。然而sign\mathrm{sign}sign施加到梯度上會使得它推離最優方向,導致要以更多的迭代次數才能達到最優點。
?如下兩圖所示為不同方法的平均攻擊成功率比較。作者使用Inc?v3\mathrm{Inc-v3}Inc?v3作為白盒,并計算其它四種黑盒模型(Inc\mathrm{Inc}Inc-v4\mathrm{v4}v4、Res152\mathrm{Res152}Res152、IncRes\mathrm{IncRes}IncRes和Den161\mathrm{Den161}Den161)的平均攻擊成功率,可以發現在各個攻擊迭代方法下,應用論文中的方法會取得更好的效果。
算法實現
from torchvision import datasets, transforms from torch.utils.data import DataLoader, Dataset import torch import torch.nn as nn from torch.autograd import Variable import torch.optim as optim import torch.nn.functional as F import osclass CNN(nn.Module):def __init__(self):super().__init__()self.Sq1 = nn.Sequential( nn.Conv2d(in_channels=1, out_channels=16, kernel_size=5, stride=1, padding=2), # (16, 28, 28) # output: (16, 28, 28)nn.ReLU(), nn.MaxPool2d(kernel_size=2), # (16, 14, 14))self.Sq2 = nn.Sequential(nn.Conv2d(in_channels=16, out_channels=32, kernel_size=5, stride=1, padding=2), # (32, 14, 14)nn.ReLU(), nn.MaxPool2d(2), # (32, 7, 7))self.out = nn.Linear(32 * 7 * 7, 10) def forward(self, x):x = self.Sq1(x)x = self.Sq2(x)x = x.view(x.size(0), -1) output = self.out(x)return outputdef FGM_attack(inputs, targets, net, alpha, epsilon, attack_type):delta = torch.zeros_like(inputs)delta.requires_grad = Trueoutputs = net(inputs + delta)loss = nn.CrossEntropyLoss()(outputs, targets)loss.backward()grad = delta.grad.detach()if type == 'FGSN':zeta = (torch.norm(inputs, p=0, dim=(2,3), keepdim=True) / torch.norm(inputs, p=2, dim=(2,3), keepdim=True)) * torch.ones(inputs.shape)delta.data = torch.clamp(delta + alpha * zeta * grad, -epsilon, epsilon)else:delta.data = torch.clamp(delta + alpha * torch.sign(grad), -epsilon, epsilon)delta = delta.detach()return deltadef main():alpha = 0.2epsilon = 0.5total = 0correct1 = 0correct2 = 0model = CNN()model.load_state_dict(torch.load('model/model.pt'))use_cuda = torch.cuda.is_available()mnist_train = datasets.MNIST("mnist-data", train=True, download=True, transform=transforms.ToTensor())train_loader = torch.utils.data.DataLoader(mnist_train, batch_size= 5, shuffle=True)for batch_idx, (inputs, targets) in enumerate(train_loader):if use_cuda:inputs, targets = inputs.cuda(), targets.cuda()inputs, targets = Variable(inputs), Variable(targets)total += targets.size(0)delta1 = FGM_attack(inputs, targets, model, alpha, epsilon, 'FGNM')adv_image1 = torch.clamp(inputs + delta1, 0, 1)outputs1 = model(adv_image1)_, predicted1 = torch.max(outputs1.data, 1)correct1 += predicted1.eq(targets.data).cpu().sum().item()print('The FGNM accuracy:', correct1, total, correct1/total)delta2 = FGM_attack(inputs, targets, model, alpha, epsilon, 'FGSM')adv_images2 = torch.clamp(inputs + delta1, 0, 1)outputs2 = model(adv_images2)_, predicted2 = torch.max(outputs2.data, 1)correct2 += predicted2.eq(targets.data).cpu().sum().item()print('The FGSM accuracy:', correct2, total, correct2/total)print('The FGNM accuracy:', correct1)print('The FGSM accuracy:', correct2)if __name__ == '__main__':main()當給定的攻擊步長α=0.2\alpha=0.2α=0.2,則有如下實驗結果
總結
以上是生活随笔為你收集整理的对抗攻击FGSM的纯粹版FGNS的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 高级与低级编程语言的解释,哪一种更容易上
- 下一篇: 手把手教物体检测——M2Det