Fast Gradient Sign Attack

主要內容
主要講述通過對原始數據加入細微的噪聲得到一組新數據,在新舊兩個數據通過人眼難以辨別的情況下,新數據可以欺騙分類器,從而使分類器做出錯誤的判斷。這種方法可以用來攻擊一些分類器,並且是完全可行的。
教程以手寫數字MINST數據集爲例,展示了這種方法。

首先加載包:


 
  • 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

加載數據集:


 
  • test_loader = torch.utils.data.DataLoader(
  • datasets.MNIST('../data', train=False, download=True, transform=transforms.Compose([
  • transforms.ToTensor(),
  • ])),
  • batch_size=1, shuffle=True)

定義一個網絡模型(分類器):


 
  • 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)

定義其他的參數


 
  • device = torch.device("cuda" if (use_cuda and torch.cuda.is_available()) else "cpu")#是否CUDA
  • epsilons = [0, .05, .1, .15, .2, .25, .3]#
  • pretrained_model = "data/lenet_mnist_model.pth"#模型的路徑

實例化模型


 
  • model = Net()#實例化
  • model=model.to(device)#放入GPU
  • model.load_state_dict(torch.load(pretrained_model, map_location='cpu'))#將之前訓練好的參數加載
  • model.eval()#轉化爲測試模式

定義FGSM攻擊函數


 
  • def fgsm_attack(image, epsilon, data_grad):
  • #獲取梯度的符號
  • sign_data_grad = data_grad.sign()
  • #在原始圖片的基礎上加上epsilon成符號
  • perturbed_image = image + epsilon*sign_data_grad
  • #將數值裁剪到0-1的範圍內
  • perturbed_image = torch.clamp(perturbed_image, 0, 1)
  • return perturbed_image

sign()函數返回數值的符號,如果爲正數返回1,如果爲負數返回-1.否則返回0.

測試函數:


 
  • def test( model, device, test_loader, epsilon ):
  • correct = 0#攻擊之後預測依然正確的個數
  • adv_examples = []#受攻擊的樣本
  • for data, target in test_loader:
  • data, target = data.to(device), target.to(device)#將數據加載進GPU
  • data.requires_grad = True#需要保存梯度
  • output = model(data)#利用分類器區分結果
  • init_pred = output.max(1, keepdim=True)[1] #獲取最大概率的索引值
  • if init_pred.item() != target.item():#如果分類錯誤,則不攻擊該樣本
  • continue
  • loss = F.nll_loss(output, target)#計算損失值
  • model.zero_grad()
  • loss.backward()
  • # 抽取梯度值
  • data_grad = data.grad.data
  • #攻擊樣本
  • perturbed_data = fgsm_attack(data, epsilon, data_grad)
  • # 再次分類
  • output = model(perturbed_data)
  • final_pred = output.max(1, keepdim=True)[1] # 得到最終分類結果
  • if final_pred.item() == target.item():#如果最終分類結果和真實結果相同
  • correct += 1
  • # 保存epsilon爲0
  • if (epsilon == 0) and (len(adv_examples) < 5):
  • adv_ex = perturbed_data.squeeze().detach().cpu().numpy()
  • adv_examples.append( (init_pred.item(), final_pred.item(), adv_ex) )
  • else:
  • # 保存其他的一些結果,用於後期的可視化操作
  • if len(adv_examples) < 5:
  • adv_ex = perturbed_data.squeeze().detach().cpu().numpy()
  • adv_examples.append( (init_pred.item(), final_pred.item(), adv_ex) )
  • #計算準確率
  • final_acc = correct/float(len(test_loader))
  • print("Epsilon: {}\tTest Accuracy = {} / {} = {}".format(epsilon, correct, len(test_loader), final_acc))
  • #返回準確率和攻擊樣例
  • return final_acc, adv_examples

如對於以上代碼中 final_pred = output.max(1, keepdim=True)[1]有疑問,請移步至

輸出準確率


 
  • #依次迭代epsilon
  • for eps in epsilons:
  • acc, ex = test(model, device, test_loader, eps)
  • accuracies.append(acc)
  • examples.append(ex)

 

  • Epsilon: 0 Test Accuracy = 9810 / 10000 = 0.981
  • Epsilon: 0.05 Test Accuracy = 9426 / 10000 = 0.9426
  • Epsilon: 0.1 Test Accuracy = 8510 / 10000 = 0.851
  • Epsilon: 0.15 Test Accuracy = 6826 / 10000 = 0.6826
  • Epsilon: 0.2 Test Accuracy = 4301 / 10000 = 0.4301
  • Epsilon: 0.25 Test Accuracy = 2082 / 10000 = 0.2082
  • Epsilon: 0.3 Test Accuracy = 869 / 10000 = 0.0869

可以發現epsilon越大,則準確度越低,且劇烈下降。

本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可,轉載請附上原文出處鏈接和本聲明。 
本文鏈接地址:https://www.flyai.com/article/artc2d5aeff7778460c86bb7687

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章