对抗样本之FGSM原理coding
生活随笔
收集整理的這篇文章主要介紹了
对抗样本之FGSM原理coding
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
目錄
- 1、FGSM原理
- 公式
- 2、pytorch實(shí)現(xiàn)
- 2.1 建立模型
- 2.2 FGSM模塊
- 2.3 測(cè)試
- 2.4 可視化對(duì)比
- 2.5 對(duì)比樣本與對(duì)抗樣本
1、FGSM原理
論文 Explaining and harnessing adversarial examples. 這篇論文由Goodfellow等人發(fā)表在ICLR2015會(huì)議上,是對(duì)抗樣本生成領(lǐng)域的經(jīng)典論文。
- FGSM(fast gradient sign method)是一種基于梯度生成對(duì)抗樣本的算法,屬于對(duì)抗攻擊中的無(wú)目標(biāo)攻擊(即不要求對(duì)抗樣本經(jīng)過(guò)model預(yù)測(cè)指定的類別,只要與原樣本預(yù)測(cè)的不一樣即可)
- 我們?cè)诶斫夂?jiǎn)單的dp網(wǎng)絡(luò)結(jié)構(gòu)的時(shí)候,在求損失函數(shù)最小值,我們會(huì)沿著梯度的反方向移動(dòng),使用減號(hào),也就是所謂的梯度下降算法;而FGSM可以理解為梯度上升算法,也就是使用加號(hào),使得損失函數(shù)最大化。先看下圖效果,goodfellow等人通過(guò)對(duì)一個(gè)大熊貓照片加入一定的擾動(dòng)(即噪音點(diǎn)),輸入model之后就被判斷為長(zhǎng)臂猿。
公式
2、pytorch實(shí)現(xiàn)
聲明:代碼來(lái)源于pytorch官網(wǎng),跳轉(zhuǎn);你要是想看官網(wǎng)直接跳轉(zhuǎn)即可,但是以下的內(nèi)容我會(huì)講解代碼以及自己的理解。
-
下面代碼需要下載預(yù)訓(xùn)練模型,將其放在如下代碼指定文件夾下,預(yù)訓(xùn)練模型下載
-
pytorch不會(huì) ?見 pytorch從基礎(chǔ)到實(shí)戰(zhàn),做學(xué)術(shù)可離不開它勒。
2.1 建立模型
from __future__ import print_function import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torchvision import datasets, transforms import numpy as np import matplotlib.pyplot as plt# 這里的epsilon先設(shè)定為幾個(gè)值,到時(shí)候后面可視化展示它的影響如何 epsilons = [0, .05, .1, .15, .2, .25, .3] # 這個(gè)預(yù)訓(xùn)練的模型需要提前下載,放在如下url的指定位置,下載鏈接如上 pretrained_model = "data/lenet_mnist_model.pth" use_cuda=True# 就是一個(gè)簡(jiǎn)單的模型結(jié)構(gòu) class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = nn.Conv2d(1, 10, kernel_size=5)self.conv2 = nn.Conv2d(10, 20, kernel_size=5)self.conv2_drop = nn.Dropout2d()self.fc1 = nn.Linear(320, 50)self.fc2 = nn.Linear(50, 10)def forward(self, x):x = F.relu(F.max_pool2d(self.conv1(x), 2))x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))x = x.view(-1, 320)x = F.relu(self.fc1(x))x = F.dropout(x, training=self.training)x = self.fc2(x)return F.log_softmax(x, dim=1)# 運(yùn)行需要稍等,這里表示下載并加載數(shù)據(jù)集 test_loader = torch.utils.data.DataLoader(datasets.MNIST('../data', train=False, download=True, transform=transforms.Compose([transforms.ToTensor(),])),batch_size=1, shuffle=True)# 看看我們有沒有配置GPU,沒有就是使用cpu print("CUDA Available: ",torch.cuda.is_available()) device = torch.device("cuda" if (use_cuda and torch.cuda.is_available()) else "cpu")# Initialize the network model = Net().to(device)# 加載前面的預(yù)訓(xùn)練模型 model.load_state_dict(torch.load(pretrained_model, map_location='cpu'))# 設(shè)置為驗(yàn)證模式. # 詳解見這個(gè)博客 https://blog.csdn.net/qq_38410428/article/details/101102075 model.eval()Out:
- 定義的網(wǎng)絡(luò)模型較為簡(jiǎn)單,如下
2.2 FGSM模塊
# FGSM attack code def fgsm_attack(image, epsilon, data_grad):# 使用sign(符號(hào))函數(shù),將對(duì)x求了偏導(dǎo)的梯度進(jìn)行符號(hào)化sign_data_grad = data_grad.sign()# 通過(guò)epsilon生成對(duì)抗樣本perturbed_image = image + epsilon*sign_data_grad# 做一個(gè)剪裁的工作,將torch.clamp內(nèi)部大于1的數(shù)值變?yōu)?,小于0的數(shù)值等于0,防止image越界perturbed_image = torch.clamp(perturbed_image, 0, 1)# 返回對(duì)抗樣本return perturbed_image2.3 測(cè)試
- 由于FGSM算法一次迭代即可,所以沒必要單獨(dú)加個(gè)train模塊,直接在測(cè)試模塊實(shí)現(xiàn)就行
- 這個(gè)函數(shù)看起來(lái)很多,其中有很多操作都是為后面的可視化做準(zhǔn)備,這里我說(shuō)下比較重要的代碼
- 重要的肯定就是損失函數(shù)關(guān)于x的偏導(dǎo),如何求出嘍。
- model.zero_grad(): PyTorch文檔中提到,如果grad屬性不為空,新計(jì)算出來(lái)的梯度值會(huì)直接加到舊值上面。 為什么不直接覆蓋舊的結(jié)果呢?這是因?yàn)橛行㏕ensor可能有多個(gè)輸出,那么就需要調(diào)用多個(gè)backward。 疊加的處理方式使得backward不需要考慮之前有沒有被計(jì)算過(guò)導(dǎo)數(shù),只需要加上去就行了。我們的情況很簡(jiǎn)單,就一個(gè)輸出,所以需要使用這條語(yǔ)句
- loss.backward():這條語(yǔ)句并不會(huì)更新參數(shù),它只會(huì)求出各個(gè)中間變量的grad(梯度)值 ,當(dāng)然也求出了損失函數(shù)關(guān)于x的偏導(dǎo)啦
- data_grad = data.grad.data:由于前面使用了loss.backward() ,所以data這個(gè)tensor的grad屬性,自然就有值了,還是損失函數(shù)對(duì)于x的偏導(dǎo)值
2.4 可視化對(duì)比
accuracies = [] examples = []# Run test for each epsilon for eps in epsilons:acc, ex = test(model, device, test_loader, eps)accuracies.append(acc)examples.append(ex)plt.figure(figsize=(5,5)) plt.plot(epsilons, accuracies, "*-") plt.yticks(np.arange(0, 1.1, step=0.1)) plt.xticks(np.arange(0, .35, step=0.05)) plt.title("Accuracy vs Epsilon") plt.xlabel("Epsilon") plt.ylabel("Accuracy") plt.show()Out:
2.5 對(duì)比樣本與對(duì)抗樣本
# Plot several examples of adversarial samples at each epsilon cnt = 0 plt.figure(figsize=(8,10)) for i in range(len(epsilons)):for j in range(len(examples[i])):cnt += 1plt.subplot(len(epsilons),len(examples[0]),cnt)plt.xticks([], [])plt.yticks([], [])if j == 0:plt.ylabel("Eps: {}".format(epsilons[i]), fontsize=14)orig,adv,ex = examples[i][j]plt.title("{} -> {}".format(orig, adv))plt.imshow(ex, cmap="gray") plt.tight_layout() plt.show()Out:
如有疑惑,以下評(píng)論區(qū)留言。力所能及,必答之。
歡迎關(guān)注,帶你開啟全方位的AI之旅。
總結(jié)
以上是生活随笔為你收集整理的对抗样本之FGSM原理coding的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 手把手教你c语言队列实现代码,通俗易懂超
- 下一篇: 深度学习CV八股文