参考链接:
https://www.jianshu.com/p/72c072551e10
论文地址:
FGSM:地址
DeepFool:地址

导入包

import numpy as np
import torch   # pytorch机器学习开源框架
import torch.nn as nn
from torch.autograd import Variable
import torch.nn.functional as F
import torchvision
import torch.optim as optim
from torchvision import transforms
from tqdm import *
import matplotlib.pyplot as plt
import copy
from torch.autograd.gradcheck import zero_gradients

建立目标模型

class Net(nn.Module):# 定义Net的初始化函数,这个函数定义了该神经网络的基本结构def __init__(self):# 复制并使用Net的父类的初始化方法,即先运行nn.Module的初始化函数super(Net, self).__init__()# 定义fc1(fullconnect)全连接函数1为线性函数:y = Wx + b,并将28*28个节点连接到300个节点上。self.fc1 = nn.Linear(28*28, 300)# 定义fc2(fullconnect)全连接函数2为线性函数:y = Wx + b,并将300个节点连接到100个节点上。self.fc2 = nn.Linear(300, 100)# 定义fc3(fullconnect)全连接函数3为线性函数:y = Wx + b,并将100个节点连接到10个节点上。self.fc3 = nn.Linear(100, 10)#定义该神经网络的向前传播函数,该函数必须定义,一旦定义成功,向后传播函数也会自动生成(autograd)def forward(self, x):# 输入x经过全连接1,再经过ReLU激活函数,然后更新xx = F.relu(self.fc1(x))x = F.relu(self.fc2(x))# 输入x经过全连接3,然后更新xx = self.fc3(x)return x

加载数据集

# 定义数据转换格式
mnist_transform = transforms.Compose([transforms.ToTensor(), transforms.Lambda(lambda x : x.resize_(28*28))])# 导入数据,定义数据接口
# 1.root,表示mnist数据的加载的相对目录
# 2.train,表示是否加载数据库的训练集,false的时候加载测试集
# 3.download,表示是否自动下载mnist数据集
# 4.transform,表示是否需要对数据进行预处理,none为不进行预处理
traindata = torchvision.datasets.MNIST(root="./drive/My Drive/fgsm/mnist", train=True, download=True, transform=mnist_transform)
testdata  = torchvision.datasets.MNIST(root="./drive/My Drive/fgsm/mnist", train=False, download=True, transform=mnist_transform)# 将训练集的*张图片划分成*份,每份256(batch_size)张图,用于mini-batch输入
# shffule=True在表示不同批次的数据遍历时,打乱顺序
# num_workers=n表示使用n个子进程来加载数据
trainloader = torch.utils.data.DataLoader(traindata, batch_size=256, shuffle=True, num_workers=0)
testloader = torch.utils.data.DataLoader(testdata, batch_size=256, shuffle=True, num_workers=0)# 展示图片
index = 100
image = testdata[index][0]
label = testdata[index][1]
image.resize_(28,28) # 调整图片大小
img = transforms.ToPILImage()(image)
plt.imshow(img)

运行显示

展示图片(每次刷新显示不一样)

index = 100
batch = iter(testloader).next() # 将testloader转换为迭代器
# 例如:如果batch_size为4,则取出来的images是4×c×h×w的向量,labels是1×4的向量
image = batch[0][index]
label = batch[1][index]
image.resize_(28,28)
img = transforms.ToPILImage()(image)
plt.imshow(img)

初始化模型、选择代价函数及优化器

net = Net()
loss_function = nn.CrossEntropyLoss() # 交叉熵损失函数
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9, weight_decay=1e-04) # 随机梯度下降优化

训练分类模型

num_epoch = 50
for epoch in tqdm(range(num_epoch)): # python进度条,num_epoch=50,所以每2%显示一次losses = 0.0for data in trainloader:inputs, labels = data # 获取输入# inputs, labels = Variable(inputs), Variable(labels)optimizer.zero_grad() # 参数梯度置零# 前向+ 反向 + 优化outputs = net(inputs)loss = loss_function(outputs, labels) # 计算lossloss.backward() # 传回反向梯度optimizer.step() # 梯度传回,利用优化器将参数更新losses += loss.data.item() # 输出统计 print("*****************当前平均损失为{}*****************".format(losses/2000.0))

运行显示

测试模型拟合效果

correct = 0 # 定义预测正确的图片数,初始化为0
total = 0 # 总共参与测试的图片数,也初始化为0
for data in testloader:images, labels = data outputs = net(Variable(images))# 输入网络进行测试 # 因为神经网络只能输入Variable_, predicted = torch.max(outputs.data, 1)#返回了最大的索引,即预测出来的类别。# 这个_,predicted是python的一种常用的写法,表示后面的函数其实会返回两个值# 但是我们对第一个值不感兴趣,就写个_在那里,把它赋值给_就好,我们只关心第二个值predicted# torch.max(outputs.data,1) ,返回一个tuple(元组)。第二个元素是labeltotal += labels.size(0) # 更新测试图片的数量correct += (predicted == labels).sum() # 更新正确分类的图片的数量
print("预测准确率为:{}/{}".format(correct, total))

运行显示

保存和加载模型

# 保存整个网络 #...It won't be checked...是保存模型时的输出
PATH1="./drive/My Drive/fgsm/mnist_net_all.pkl"
torch.save(net,PATH1)
# 保存网络中的参数,速度快,占空间少,PATH1是保存路径和文件名
PATH2="./drive/My Drive/fgsm/mnist_net_param.pkl"
torch.save(net.state_dict(),PATH2)
#针对上面一般的保存方法,加载的方法分别是:
#model_dict=torch.load(PATH)
#model_dict=model.load_state_dict(torch.load(PATH))
net = torch.load(PATH1) # 加载模型index = 100 # 选择测试样本
image = testdata[index][0]
label = testdata[index][1]outputs = net(Variable(image)) # 因为神经网络只能输入Variable
predicted = torch.max(outputs.data,0)[1]
print('预测值为:{}'.format(predicted))image.resize_(28,28) # 显示一下测试的图片,和上文代码相同
img = transforms.ToPILImage()(image)
plt.imshow(img)

运行显示

FGSM对抗样本

index = 100 # 选择测试样本
image = Variable(testdata[index][0].resize_(1,784), requires_grad=True) # requires_grad存储梯度值
label = torch.tensor([testdata[index][1]])
outputs = net(image)
loss = loss_function(outputs, label)
loss.backward()
# 计算结束后,其梯度值存储在image.grad.data中
# FGSM添加扰动
epsilon = 0.1 # 扰动程度
x_grad = torch.sign(image.grad.data) # 快速梯度符号法
x_adversarial = torch.clamp(image.data + epsilon * x_grad, 0, 1) # 0和1表示限制范围的下限和上限# 使用之前建立的模型对扰动后的图片数据进行分类
outputs = net(x_adversarial) # net = torch.load(PATH1)。
predicted = torch.max(outputs.data,1)[1] #outputs含有梯度值,其处理方式与之前有所不同
print('预测值为:{}'.format(predicted[0]))# 展示扰动之后的图片
x_adversarial.resize_(28,28)
img = transforms.ToPILImage()(x_adversarial)
plt.imshow(img)

运行显示

Deepfool对抗样本

PATH1="./drive/My Drive/fgsm/mnist_net_all.pkl"
net = torch.load(PATH1) # 加载模型
index = 100 # 选择测试样本
image = Variable(testdata[index][0].resize_(1,784), requires_grad=True)
label = torch.tensor([testdata[index][1]])
f_image = net.forward(image).data.numpy().flatten() # flatten()函数默认是按行的方向降维
I = (np.array(f_image)).flatten().argsort()[::-1] # argsort()[::-1]表示降维排序后返回索引值
label = I[0] # 样本标签input_shape = image.data.numpy().shape # 获取原始样本的维度,返回(第一维长度,第二维长度,...)
pert_image = copy.deepcopy(image) # 深度复制原始样本,复制出来后就独立了
w = np.zeros(input_shape) # 返回来一个给定形状和类型的用0填充的数组
r_tot = np.zeros(input_shape)loop_i = 0 # 循环
max_iter = 50 # 最多迭代次数
overshoot = 0.0x = Variable(pert_image, requires_grad=True) # 因为神经网络只能输入Variable
fs = net.forward(x) # 调用forward函数
fs_list = [fs[0][I[k]] for k in range(len(I))] # 每个类别的取值情况,及其对应的梯度值
k_i = label

参考论文算法2理解,通过内部的for循环可以获得x到各分类边界的距离;在外部的while循环中,我们利用内部循环获得的所有边界距离中的最小值对x进行更新。重复这一过程,直到的分类标签发生变化。

#参考论文算法2理解
while k_i == label and loop_i < max_iter: # 分类标签变化时结束循环pert = np.inf # np.inf表示一个足够大的数fs[0][I[0]].backward(retain_graph=True) # 反向传播,计算当前梯度;连续执行两次backward,参数表明保留backward后的中间参数。orig_grad = x.grad.data.numpy().copy() # 原始梯度for k in range(len(I)): # 获得x到各分类边界的距离zero_gradients(x)fs[0][I[k]].backward(retain_graph=True)cur_grad = x.grad.data.numpy().copy() # 现在梯度w_k = cur_grad - orig_gradf_k = (fs[0][I[k]] - fs[0][I[0]]).data.numpy()pert_k = abs(f_k) / np.linalg.norm(w_k.flatten())if pert_k < pert:  # 获得最小的分类边界距离向量pert = pert_k # 更新perk,pert为最小距离w = w_kr_i = (pert + 1e-4) * w / np.linalg.norm(w)r_tot = np.float32(r_tot + r_i) # 累积扰动pert_image = image + (1+overshoot)*torch.from_numpy(r_tot) # 添加扰动x = Variable(pert_image, requires_grad=True)fs = net.forward(x)k_i = np.argmax(fs.data.numpy().flatten()) # 扰动后的分类标签loop_i += 1
r_tot = (1+overshoot)*r_tot # 最终累积的扰动
outputs = net(pert_image.data.resize_(1,784))
predicted = torch.max(outputs.data,1)[1] #outputs含有梯度值,其处理方式与之前有所不同
print('预测值为:{}'.format(predicted[0]))pert_image = pert_image.reshape(28,28)
img = transforms.ToPILImage()(pert_image)
plt.imshow(img)

运行显示

对抗样本生成算法复现代码解析:FGSM和DeepFool相关推荐

  1. 对抗样本生成算法之BIM算法

    目录 论文主要内容 BIM算法原理 ILCM算法原理 实验效果 物理世界实验 论文 2017ICLR-Adversarial Examples in the physical world. 论文主要内 ...

  2. GAN 系列的探索与pytorch实现 (数字对抗样本生成)

    GAN 系列的探索与pytorch实现 (数字对抗样本生成) 文章目录 GAN 系列的探索与pytorch实现 (数字对抗样本生成) GAN的简单介绍 生成对抗网络 GAN 的基本原理 大白话版本 非 ...

  3. 《Comprehensive Privacy Analysis of Deep Learning》补完以及Deepfool对抗样本构造算法

    本文关于推理攻击领域关于深度学习的隐私性的全面分析<Comprehensive Privacy Analysis of Deep Learning>,以及介绍Deepfool对抗样本构造算 ...

  4. 对抗攻击与防御 (1):图像领域的对抗样本生成

    文章目录 1 引入 2 白盒攻击 2.1 Biggio 2.2 Szegedy's limited-memory BFGS (L-BFGS) 2.3 Fast gradient sign method ...

  5. 【综述】对抗样本生成及攻防技术综述

    作者是电子科技大学的刘小垒等,2019年发表在计算机应用研究 主要内容: 以机器学习的安全性问题为出发点,介绍了当前机器学习面临的隐私攻击.完整性攻击等安全问题,归纳了目前常见对抗样本生成方法的发展过 ...

  6. FGPM:文本对抗样本生成新方法

    ©PaperWeekly 原创 · 作者|孙裕道 学校|北京邮电大学博士生 研究方向|GAN图像生成.情绪对抗样本生成 论文标题: Fast Gradient Projection Method fo ...

  7. 对抗样本生成方法论文阅读笔记

    论文<针对黑盒智能语音软件的对抗样本生成方法> 一.论文中提到的相关名词解释 1.1什么是对抗样本? 所谓对抗样本就是指:在原始样本添加一些人眼无法察觉的扰动(这样的扰动不会影响人类的识别 ...

  8. PPQ库中KLD算法实现代码解析

    PPQ量化工具库KLD算法解析 前言 PPQ算法实现 NVIDIA的PPT中KLD算法流程 KLD算法PPQ实现版本 PPQ与NVIDIA的区别: 前言 这是对PPQ库中KLD算法实现代码解析,关于P ...

  9. YOLO-V5 算法和代码解析系列 —— 学习路线规划综述

    目录标题 为什么学习 YOLO-V5 ? 博客文章列表 面向对象 开源项目学习方法 预备知识 项目目录结构 为什么学习 YOLO-V5 ? 算法性能:与YOLO系列(V1,V2,V3,V4)相比,YO ...

最新文章

  1. python用途与前景-Python的发展前景及干货!!
  2. 并发编程-11线程安全策略之线程封闭
  3. 【Mark 常用方法】Html中<form>标签作用和属性详解
  4. git commit撤销_Git 实用操作:撤销 Commit 提交
  5. UCOSII学习笔记[开篇]
  6. 批量修改txt文件名,删除相同部分
  7. html5浏览器最小化,javascript – 在浏览器最小化时引起用户的注意(跨浏览器桌面通知?)...
  8. 内网通修改积分文件_【页游逆向】4399小游戏积分系统分析及修改积分
  9. 阿里云Centos7安装mysql5.7
  10. 数据组,请求组,职责,用户关系
  11. 如何申请独立服务商(支付宝ISV)
  12. 深入理解Linux内核使用浮点运算问题
  13. 英语作文计算机的出现,临时英文(电脑输入法出现临时英文)
  14. [万字长文]使用 React 重写学成在线前端项目 I 代码完整可运行,步骤有详解
  15. vue3 props 声明默认值
  16. 使用ssh对服务器进行登录
  17. 论文阅读——(邬江兴院士) 网络空间内生安全综述 Cyberspace Endogenous Safety and Security
  18. EndNote20 【无法编辑Range】解决办法
  19. 2022企业卓越运营国际峰会
  20. 【Python】批量从doc简历中提取出需要的信息

热门文章

  1. 窄带干扰与宽带干扰的模型
  2. VUE H5页面微信/QQ/微博 分享连接设置
  3. 使用蒙特卡罗方法计算圆周率
  4. 学习.NET MAUI Blazor(三)、创建.NET MAUI Blazor应用并使用AntDesignBlazor
  5. 低调,中国的FPGA到底有多强?!
  6. React中文文档之Rendering Elements
  7. 李宏毅2022机器学习HW2解析
  8. Vero praesentium odio suscipit dolor.Eos accusamus rem tempore.
  9. 使用Arduino控制TB6600步进电机驱动器教程(更新于 2022.03.19)
  10. Java-汉字字符串转拼音,包括首字母和全拼