目录

  • 1. 相关说明
  • 2. 相关简述
  • 3. 代码实现
    • 3.1 引入相关包
    • 3.2 输入
    • 3.3 定义被攻击的模型
    • 3.4 定义FGSM攻击函数
    • 3.5 测试函数
  • 4. 可视化结果
  • 5. 可视化对抗样本
  • 6. 预训练模型下载
  • 7. 训练模型
  • 8. 完整代码

1. 相关说明

最近在整理相关实验代码的时候,无意中需要重新梳理下对抗攻击里的FGSM,于是自己参考网上的一些资料以及自己的心得写下这篇文章,用来以后回忆。

2. 相关简述

快速梯度标志攻击(FGSM),是迄今为止最早和最受欢迎的对抗性攻击之一,它由 Goodfellow 等人在[Explaining and Harnessing Adversarial Examples] (https://arxiv.org/abs/1412.6572)中提出,是一种简单但是有效的对抗样本生成算法。它旨在通过利用模型学习的方式和渐变来攻击神经 网络。这个想法很简单,攻击调整输入数据以基于相同的反向传播梯度来最大化损失,而不是通过基于反向传播的梯度调整权重来最小化损失。 换句话说,攻击是利用损失函数的梯度,然后调整输入数据以最大化损失。

3. 代码实现

3.1 引入相关包

# 这句话的作用:即使是在Python2.7版本的环境下,print功能的使用格式也遵循Python3.x版本中的加括号的形式
from __future__ import print_function
import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision import datasets, transforms
import numpy as np
import matplotlib.pyplot as plt

3.2 输入

    # 设置不同扰动大小epsilons = [0, .05, .1, .15, .2, .25, .3]# 预训练模型pretrained_model = "./data/lenet_mnist_model.pth"# 是否使用cudause_cuda = True

3.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)#声明 MNIST 测试数据集何数据加载
test_loader = torch.utils.data.DataLoader(datasets.MNIST('../data', train=False, download=True, transform=transforms.Compose([transforms.ToTensor(),])),batch_size=1, shuffle=True)# 定义我们正在使用的设备
print("CUDA Available: ",torch.cuda.is_available())
device = torch.device("cuda" if (use_cuda and torch.cuda.is_available()) else "cpu")# 初始化网络
model = Net().to(device)# 加载已经预训练的模型
model.load_state_dict(torch.load(pretrained_model, map_location='cpu'))# 在评估模式下设置模型。在这种情况下,这适用于Dropout图层
model.eval()

然后我们运行下,出现下面结果,主要是在下载数据集。

Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz to …/data/MNIST/raw/train-images-idx3-ubyte.gz
Extracting …/data/MNIST/raw/train-images-idx3-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz to …/data/MNIST/raw/train-labels-idx1-ubyte.gz
Extracting …/data/MNIST/raw/train-labels-idx1-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz to …/data/MNIST/raw/t10k-images-idx3-ubyte.gz
Extracting …/data/MNIST/raw/t10k-images-idx3-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz to …/data/MNIST/raw/t10k-labels-idx1-ubyte.gz
Extracting …/data/MNIST/raw/t10k-labels-idx1-ubyte.gz
Processing…
Done!
CUDA Available: True

3.4 定义FGSM攻击函数

# FGSM算法攻击代码
def fgsm_attack(image, epsilon, data_grad):# 收集数据梯度的元素符号sign_data_grad = data_grad.sign()# 通过调整输入图像的每个像素来创建扰动图像perturbed_image = image + epsilon*sign_data_grad# 添加剪切以维持[0,1]范围perturbed_image = torch.clamp(perturbed_image, 0, 1)# 返回被扰动的图像return perturbed_image

3.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

再次运行,输出下面结果:

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 = 4303 / 10000 = 0.4303
Epsilon: 0.25 Test Accuracy = 2087 / 10000 = 0.2087
Epsilon: 0.3 Test Accuracy = 871 / 10000 = 0.0871

4. 可视化结果

在上面的基础上我们添加下面的代码:

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

运行,出现下面结果:

5. 可视化对抗样本

# 在每个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()

运行,结果如下:

6. 预训练模型下载

文中我们有一个预训练好的模型,如果自己不想训练可以在这里下载:
模型下载地址

7. 训练模型

如果自己想训练一个模型,可以运行下面这个函数main.py:

from __future__ import print_function
import argparse
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
from torch.optim.lr_scheduler import StepLR# 定义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)def train(args, model, device, train_loader, optimizer, epoch):model.train()for batch_idx, (data, target) in enumerate(train_loader):data, target = data.to(device), target.to(device)optimizer.zero_grad()output = model(data)loss = F.nll_loss(output, target)loss.backward()optimizer.step()if batch_idx % args.log_interval == 0:print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset),100. * batch_idx / len(train_loader), loss.item()))if args.dry_run:breakdef test(model, device, test_loader):model.eval()test_loss = 0correct = 0with torch.no_grad():for data, target in test_loader:data, target = data.to(device), target.to(device)output = model(data)test_loss += F.nll_loss(output, target, reduction='sum').item()  # sum up batch losspred = output.argmax(dim=1, keepdim=True)  # get the index of the max log-probabilitycorrect += pred.eq(target.view_as(pred)).sum().item()test_loss /= len(test_loader.dataset)print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset),100. * correct / len(test_loader.dataset)))def main():# Training settingsparser = argparse.ArgumentParser(description='PyTorch MNIST Example')parser.add_argument('--batch-size', type=int, default=64, metavar='N',help='input batch size for training (default: 64)')parser.add_argument('--test-batch-size', type=int, default=1000, metavar='N',help='input batch size for testing (default: 1000)')parser.add_argument('--epochs', type=int, default=14, metavar='N',help='number of epochs to train (default: 14)')parser.add_argument('--lr', type=float, default=1.0, metavar='LR',help='learning rate (default: 1.0)')parser.add_argument('--gamma', type=float, default=0.7, metavar='M',help='Learning rate step gamma (default: 0.7)')parser.add_argument('--no-cuda', action='store_true', default=False,help='disables CUDA training')parser.add_argument('--dry-run', action='store_true', default=False,help='quickly check a single pass')parser.add_argument('--seed', type=int, default=1, metavar='S',help='random seed (default: 1)')parser.add_argument('--log-interval', type=int, default=10, metavar='N',help='how many batches to wait before logging training status')parser.add_argument('--save-model', action='store_true', default=True,help='For Saving the current Model')args = parser.parse_args()use_cuda = not args.no_cuda and torch.cuda.is_available()torch.manual_seed(args.seed)device = torch.device("cuda" if use_cuda else "cpu")train_kwargs = {'batch_size': args.batch_size}test_kwargs = {'batch_size': args.test_batch_size}if use_cuda:cuda_kwargs = {'num_workers': 1,'pin_memory': True,'shuffle': True}train_kwargs.update(cuda_kwargs)test_kwargs.update(cuda_kwargs)transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,), (0.3081,))])dataset1 = datasets.MNIST('../data_row', train=True, download=True,transform=transform)dataset2 = datasets.MNIST('../data_row', train=False,transform=transform)train_loader = torch.utils.data.DataLoader(dataset1,**train_kwargs)test_loader = torch.utils.data.DataLoader(dataset2, **test_kwargs)model = Net().to(device)optimizer = optim.Adadelta(model.parameters(), lr=args.lr)scheduler = StepLR(optimizer, step_size=1, gamma=args.gamma)for epoch in range(1, args.epochs + 1):train(args, model, device, train_loader, optimizer, epoch)test(model, device, test_loader)scheduler.step()# 保存网络中的参数, 速度快,占空间少if args.save_model:torch.save(model.state_dict(), "lenet_mnist_model.pth")if __name__ == '__main__':main()

8. 完整代码

上面是将每个模块单独拿出来写的,需要完整代码的可以在我的GitHub上下载,如果您觉得好的话记得给个Star。
完整代码链接地址

Pytorch实现FGSM(Fast Gradient Sign Attack)相关推荐

  1. Fast Gradient Sign Attack(FGSM)算法小结

    Fast Gradient Sign Attack(FGSM)算法小结 对抗攻击引发了机器学习一系列的思考,训练出来的model是否拥有强大的泛化能力?模型的准确率是否真实? 在对抗攻击中添加一些肉眼 ...

  2. 《Fast Gradient Projection Method for Text Adversary Generation and Adversarial Training》论文学习笔记

    最近在学习对抗学习在文本分类方面的论文,对抗训练在提高深度神经网络对图像分类的鲁棒性方面表现出了有效性和高效性.然而,对于文本分类,文本输入空间的离散特性使得基于梯度的对抗方法难以从图像域进行自适应. ...

  3. Protect Privacy from Gradient Leakage Attack in Federated Learning

    wangjunxiao/GradDefense: Defense against Gradient Leakage Attack (github.com) Summary 针对DGA和DIA攻击,提出 ...

  4. 论文推荐:Minimally distorted Adversarial Examples with a Fast Adaptive Boundary Attack

    ICML 2020 论文推荐: 论文名称:Minimally distorted Adversarial Examples with a Fast Adaptive Boundary Attack 推 ...

  5. pytorch笔记:policy gradient

    本文参考了 策略梯度PG( Policy Gradient) 的pytorch代码实现示例 cart-pole游戏_李莹斌XJTU的博客-CSDN博客_策略梯度pytorch 在其基础上添加了注释和自 ...

  6. pytorch DDP加速之gradient accumulation设置

    pytorch DDP 参考:https://zhuanlan.zhihu.com/p/250471767 GPU高效通信算法-Ring Allreduce: https://www.zhihu.co ...

  7. pytorch 梯度累积(gradient accumulation)

    梯度累积 - gradient accumulation 在深度学习训练的时候,数据的batch size大小受到GPU内存限制,batch size大小会影响模型最终的准确性和训练过程的性能.在GP ...

  8. pytorch backward中的gradient参数实验

    x = torch.FloatTensor([1, 1, 5]) # x.grad:tensor([0., 0., 1.]) x.requires_grad = True y = torch.Floa ...

  9. PyTorch FGSM Attack 对抗样本生成

    要阅读 带有插图的文章版本 请前往 http://studyai.com/pytorch-1.4/beginner/fgsm_tutorial.html 如果你正在阅读这篇文章,希望你能体会到一些机器 ...

  10. 李宏毅机器学习作业10——Adversarial Attack,FGSM,IFGSM

    理论部分参见​李宏毅机器学习--对抗攻击Adversarial Attack_iwill323的博客-CSDN博客 目录 目标和方法 评价方法 导包 Global Settings Data tran ...

最新文章

  1. 提高网站首页载入速度的常用方法
  2. 关于python pdb的描述_The python debugger(PDB)的简介
  3. php查询一对多,PHP并输出一对多结果
  4. 26岁,发25篇SCI,当上211教授、博导。
  5. 使用ClickOnce部署VS2005中的WinForm应用程序.(ZT)
  6. 在CSS中使用not:first-child选择器
  7. TensorFlow 深度学习实战指南中文版
  8. Sentinel系统规则_分布式系统集群限流_线程数隔离_削峰填谷_流量控制_速率控制_服务熔断_服务降级---微服务升级_SpringCloud Alibaba工作笔记0044
  9. iis ftp 隔离账户
  10. Tensorflow函数映射:py_func和map_fn
  11. 示例1---从记事本中读取数值,然后写到数组中---切片,优化版本
  12. hdu 1394 Minimum Inversion Number(逆序数对) : 树状数组 O(nlogn)
  13. 二年级孩子适合学C语言吗,小孩子适合学习编程吗?孩童时期对变成的接受程度有多少呢?...
  14. 户籍管理系统的设计与实现
  15. Android上边抽屉式标题,Android Navigation Drawer样式抽屉的使用
  16. 论文笔记 General Advantage Estimation(GAE)
  17. 买房的疯了-开发商笑不起来了
  18. FFmpeg从入门到入魔(2):保存流到本地MP4
  19. 更透明的隐私设置和全新的APP资源库:iOS 14测试版深度体验~~~
  20. 1.运行npm install 时,卡在sill idealTree buildDeps没有反应

热门文章

  1. Tomcat优化大全,进来看了,真就会了
  2. IAR8.3 STM8安装过程
  3. Android Protect-0.luyten+jadx+simplify简单介绍
  4. IOS-性能优化/内存优化常用方法小总结
  5. 初级程序员和二级Java哪个难,软考初级程序员和计算机二级哪个更受欢迎
  6. Tomcat 日志配置与优化
  7. 花样机模板电脑CAD免费打板转格式软件PS300B使用步骤教程:日本兄弟牌Brother花样机通用CAD画图打板.dxf文件转.emb文件
  8. 概率算法/拉斯维加斯 蒙特卡洛 舍伍德算法
  9. 台达触摸屏MODBUS直接与台达变频器通讯程序
  10. Ubuntu删除用户和卸载服务命令