【对抗攻击代码实战】对抗样本的生成——FGSM
文章目錄
- 前言
- 基于優化的對抗樣本
- FGSM
- 1.首先導入相關包和參數設置:
- 2.加載數據
- 3.定義網絡模型
- 4.定義攻擊函數
- 5.開始攻擊
- 6.可視化測試
前言
讓我們來看一下,怎么從深度學習的基本過程到對抗樣本的生成?回顧一下深度學習訓練的過程,通過計算預測值與實際值之間的損失函數,通過梯度下降,反向傳播,更新了參數,不斷減小損失函數的值,過程如下圖所示:
那對抗樣本的生成也可以參考這樣的過程。不同的是,對抗樣本的生成過程中網絡參數不變(一般是訓練好的分類器),通過反向傳播不斷地更新調整對抗樣本,也是不斷的減小損失函數。關于loss函數這篇有講到:來自人類的惡意:對抗攻擊
基于優化的對抗樣本
基于優化方法的對抗樣本生成與深度學習訓練過程類似,核心代碼如下:
optimizer = torch.optim.Adam([img])(優化的對象是img)
代碼參考自:AI安全之對抗樣本
FGSM
之前是用優化的方法,現在考慮的是用梯度來生成對抗樣本——Fast Gradient Sign Method(FGSM)
論文鏈接:Explaining andHarnessing Adversarial Examples
論文筆記鏈接:click here
代碼參考于pytorch官網:fgsm_tutoriall
1.首先導入相關包和參數設置:
預訓練模型下載:lenet_mnist_model.pth
也可以通過訓練文件重新訓練模型:example-mnist
2.加載數據
采用MNIST測試集數據,batch_size=1
test_loader = torch.utils.data.DataLoader(datasets.MNIST('./datasets', train=False, download=True, transform=transforms.ToTensor()),batch_size=1,shuffle=True)3.定義網絡模型
# 定義LeNet模型 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)# 初始化網絡 model = Net().to(device)# 加載已經預訓練的模型 model.load_state_dict(torch.load(pretrained_model, map_location='cpu'))# 在評估模式下設置模型(Dropout層不被考慮) model.eval()4.定義攻擊函數
FGSM論文中的公式:
perturbed_image=image+epsilon?sign(data_grad)=x+??sign(?x?J(θ,x,y))perturbed\_image=image+epsilon?sign(data\_grad)=x+??sign(?_ x?J(θ,x,y))perturbed_image=image+epsilon?sign(data_grad)=x+??sign(?x??J(θ,x,y))
5.開始攻擊
def test( model, device, test_loader, epsilon ):# 精度計數器correct = 0adv_examples = []# 循環遍歷測試集中的所有示例for data, target in test_loader:# 把數據和標簽發送到設備data, target = data.to(device), target.to(device)# 設置張量的requires_grad屬性,這對于攻擊很關鍵data.requires_grad = True# 通過模型前向傳遞數據output = model(data)init_pred = output.max(1, keepdim=True)[1] # get the index of the max log-probability# 如果初始預測是錯誤的,不打斷攻擊,繼續if init_pred.item() != target.item():continue# 計算損失loss = F.nll_loss(output, target)# 將所有現有的漸變歸零model.zero_grad()# 計算后向傳遞模型的梯度loss.backward()# 收集datagraddata_grad = data.grad.data# 喚醒FGSM進行攻擊perturbed_data = fgsm_attack(data, epsilon, data_grad)# 重新分類受擾亂的圖像output = model(perturbed_data)# 檢查是否成功final_pred = output.max(1, keepdim=True)[1] # get the index of the max log-probabilityif final_pred.item() == target.item():correct += 1# 保存0 epsilon示例的特例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) )# 計算這個epsilon的最終準確度final_acc = correct/float(len(test_loader))print("Epsilon: {}\tTest Accuracy = {} / {} = {}".format(epsilon, correct, len(test_loader), final_acc))# 返回準確性和對抗性示例return final_acc, adv_examples輸出:
6.可視化測試
# 對每個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()# 在每個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()總結
以上是生活随笔為你收集整理的【对抗攻击代码实战】对抗样本的生成——FGSM的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 循迹小车项目
- 下一篇: wpd小波包分解_基于奇异值分解和小波包