提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录

一、模型训练总结回顾

二、对RMB分类模型进行fgsm攻击

1.fgsm原理

2.大致思路流程概述

1.求数据集中每个数据集的梯度(以供fgsm生成噪声)

2.通过fgsm,得到对抗样本数据集

3.检验fgsm攻击效果

3.设定扰动量epsilon和识别准确度accuracies

4.定义FGSM攻击函数(原理超级通俗)

5.具体攻击过程(仅展示思路,详细代码显示于文末)

6.攻击结果实例化

代码展示

成果展示

三.完整代码

总结


一、模型训练总结回顾

RMB识别模型的具体训练流程已在之前的文章详细叙述,故在此仅聊一聊大致思路

1.数据导入:(仅限导入本地已有的数据(已分类放置)的方法)

先使用Dataset(包含initgetitem,len函数),其中我们所需要设定的就是init函数和getitem函数。定义init函数,使其根据我们所输入的存储主路径将每一张图片的存储路径和图片类别存放于列表中。定义getitem函数(需要在DataLoader中通过index才能进行下述操作),使其能够根据列表中的路径提取图片信息,并执行我们所设定的transform函数,进行图片信息的变换。

再使用DataLoader,这一步不需要我们去定义什么,只需要输入Dataset并设定一些参数的值即可(如批大小,每个epoch是否乱序等等)

2.模型初定义

因为是继承了nn.Module这个父类的,所以我们只需要设定init函数和forward函数,其中init函数中设定自己想要的卷积层和线性层,结构如下:

self.conv1 = nn.Conv2d(输入层数, 输出层数, 卷积核大小)                                                      self.fc1 = nn.Linear(层数*长*宽, 想要的数值)(最终目的是缩小为分类的种类数,但不能直接一步成,必须分成几次达成)

而forward函数则是制定数据信息变化过程先是依次进行以下操作,直到无法继续缩小图片信息为止(长宽不满足执行条件)

out = F.relu(self.conv1(x)) (长宽减少,层数增加)                                                                       执行条件:满足卷积神将网络的计算公式:          N=(W-F+2P)/S+1                                               其中N:输出大小     W:输入大小      F:卷积核大小     P:填充值的大小      S:步长大小       out = F.max_pool2d(out, 2) (长宽减半,层数不变)                                                                    执行条件:长宽为偶数

当无法继续缩小图片信息后,执行设定好的线性层即可。

3.定义损失函数和优化器

损失函数到没什么需要我们去操作的,直接用现成的就行。

优化器(optimizer)也直接用现成的,只需要设定以下学习率的大小即可。再将optimizer作为输入,放在scheduler中,同时再设定学习率下降策略,即学习率缩小倍数即可。

4.训练过程

定义数据集循环次数,每轮循环中,将数据集中的图片信息导入模型得到outputs,将该结果与实际结果导入loss函数,并进行backward,根据梯度,通过优化器改变图片每个信息点对应的权重值。比较outputs中的不同分类的数值,得出其中每张图片的最大可能分类(即预测结果),将其与实际情况比较,得出识别正确率。

二、对RMB分类模型进行fgsm攻击

1.fgsm原理

具体内容参考此链接,写的很详细  https://blog.csdn.net/qq_35414569

一种基于梯度生成对抗样本的算法,属于对抗攻击中的无目标攻击即不要求对抗样本经过model预测指定的类别,只要与原样本预测的不一样即可)

图1                                                          图二(噪声)                            图三(对抗样本)

把图一喂给模型,模型告诉你57.7%的概率是熊猫,别看概率小,机器总会输出概率值最大的那个结果。随后把图二加入图一中,生成一张新的图三,把图三喂给模型,模型告诉你99.3%是金丝猴,但肉眼看依然是熊猫,这就是FGSM攻击方法


2.大致思路流程概述

前提:已有一个已经训练好的模型

1.求数据集中每个数据集的梯度(以供fgsm生成噪声)

将数据集代入模型,求得outputs,将结果与数据集实际类别输入到选定的loss函数中,进行backward,并将每张图片对应梯度收集入列表。

2.通过fgsm,得到对抗样本数据集

将数据集,收集的梯度列表,当前设定的扰动量输入定义的fgsm中,得到最终的对抗样本数据集

3.检验fgsm攻击效果

将抗样本数据集输入进模型中,得到攻击后的outputs,比较outputs中的不同分类的数值,得出其中每张图片的最大可能分类(即预测结果),统计该结果同实际类别的吻合度,得到收到攻击后的模型识别的准确度


3.设定扰动量epsilon和识别准确度accuracies

内容如图所示:

# 这里的扰动量先设定为几个值,后面可视化展示不同的扰动量影响以及成像效果
epsilons = [0, .05, .1, .15, .2, .25, .3, .35, .4]
# 将epsilons中的每个eps所对应的识别准确度放入列表中以供线形图展示
accuracies = list()

4.定义FGSM攻击函数(原理超级通俗)

如图所示,我们可以假象为每个图片信息就是这根曲线上的点,该点对应的位置就会影响对其类别的判断,fgsm攻击的目的就是以尽可能小的移动幅度让该点尽可能的远离当前位置,故而就得顺着梯度最大的方向走,才能达到最佳效果,即让每个图片信息点所增加的噪声都能对其远离的行为产生正向作用。

对应代码及解释如下所示:

def fgsm_attack(image, epsilon, data_grad):# 使用sign(符号)函数,将对x求了偏导的梯度进行符号化(正数为1,零为0,负数为-1)sign_data_grad = data_grad.sign()# 通过epsilon生成对抗样本perturbed_image = image + epsilon * sign_data_grad# 噪声越来越大,机器越来越难以识别,但人眼可以看出差别# 做一个剪裁的工作,将torch.clamp内部大于1的数值变为1,小于0的数值等于0,防止image越界perturbed_image = torch.clamp(perturbed_image, 0, 1)# 返回对抗样本return perturbed_image

5.具体攻击过程(仅展示思路,详细代码显示于文末)

1.设定循环的最大轮数

2.每一轮都将数据集中的一个batch的图片信息代入模型,求得outputs

3.通过outputs与图片实际类别,输入loss函数并进行backward,收集每张图片的梯度信息

4..将数据,梯度信息,设定的扰动量输入fgsm函数中,最终得到对抗样本数据。

5.可以设定当运行了几个batch时,显示当前的攻击信息(如显示当前多个batch计算得出的loss的平均值,对比预测结果与实际类别得出准确度等等)


6.攻击结果实例化

注意:x,y值必须是列表的形式

代码展示

valid_x = epsilons                            # 设定的几个eps
valid_y = accuracies                          # 每个eps对应的准确度plt.plot(valid_x, valid_y, label='Valid')plt.legend(loc='upper right')
plt.ylabel('Acc')
plt.xlabel('Epsilon')
plt.show()

成果展示

三.完整代码

import os
import random
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader
from torch.utils.data import Dataset
import torchvision.transforms as transforms
import torch.optim as optim
from matplotlib import pyplot as plt
from PIL import Imagedef set_seed(seed=1):random.seed(seed)np.random.seed(seed)torch.manual_seed(seed)torch.cuda.manual_seed(seed)class RMBDataset(Dataset):def __init__(self, data_dir, transform=None):self.label_name = {"1": 0, "100": 1}self.data_info = self.get_img_info(data_dir)  # data_info存储所有图片路径和标签,在DataLoader中通过index读取样本self.transform = transformdef __getitem__(self, index):path_img, label = self.data_info[index]img = Image.open(path_img).convert('RGB')     # 0~255if self.transform is not None:img = self.transform(img)   # 在这里做transform,转为tensor等等return img, labeldef __len__(self):return len(self.data_info)@staticmethoddef get_img_info(data_dir):data_info = list()for root, dirs, _ in os.walk(data_dir):# 遍历类别for sub_dir in dirs:img_names = os.listdir(os.path.join(root, sub_dir))img_names = list(filter(lambda x: x.endswith('.jpg'), img_names))# 遍历图片for i in range(len(img_names)):img_name = img_names[i]path_img = os.path.join(root, sub_dir, img_name)label = rmb_label[sub_dir]data_info.append((path_img, int(label)))return data_infoclass LeNet(nn.Module):def __init__(self, classes):super(LeNet, self).__init__()self.conv1 = nn.Conv2d(3, 6, 5)self.conv2 = nn.Conv2d(6, 16, 5)self.fc1 = nn.Linear(16*5*5, 120)self.fc2 = nn.Linear(120, 84)self.fc3 = nn.Linear(84, classes)def forward(self, x):out = F.relu(self.conv1(x))out = F.max_pool2d(out, 2)out = F.relu(self.conv2(out))out = F.max_pool2d(out, 2)out = out.view(out.size(0), -1)out = F.relu(self.fc1(out))out = F.relu(self.fc2(out))out = self.fc3(out)return outdef initialize_weights(self):for m in self.modules():if isinstance(m, nn.Conv2d):nn.init.xavier_normal_(m.weight.data)if m.bias is not None:m.bias.data.zero_()elif isinstance(m, nn.BatchNorm2d):m.weight.data.fill_(1)m.bias.data.zero_()elif isinstance(m, nn.Linear):nn.init.normal_(m.weight.data, 0, 0.1)m.bias.data.zero_()set_seed()  # 设置随机种子
rmb_label = {"1": 0, "100": 1}# 参数设置
MAX_EPOCH = 10
BATCH_SIZE = 5
LR = 0.001
log_interval = 10
val_interval = 1# ============================ step 1/5 数据 ============================split_dir = os.path.join(".", "RMB_data", "rmb_split")
train_dir = os.path.join(split_dir, "train")
valid_dir = os.path.join(split_dir, "valid")norm_mean = [0.485, 0.456, 0.406]
norm_std = [0.229, 0.224, 0.225]train_transform = transforms.Compose([transforms.Resize((32, 32)),transforms.RandomCrop(32, padding=4),transforms.ToTensor(),transforms.Normalize(norm_mean, norm_std),
])valid_transform = transforms.Compose([transforms.Resize((32, 32)),transforms.ToTensor(),transforms.Normalize(norm_mean, norm_std),
])# 构建MyDataset实例
train_data = RMBDataset(data_dir=train_dir, transform=train_transform)
valid_data = RMBDataset(data_dir=valid_dir, transform=valid_transform)# 构建DataLoder
train_loader = DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)
valid_loader = DataLoader(dataset=valid_data, batch_size=BATCH_SIZE)# ============================ step 2/5 模型 ============================
net = LeNet(classes=2)
net.initialize_weights()# ============================ step 3/5 损失函数 ============================
criterion = nn.CrossEntropyLoss()                                                   # 选择损失函数# ============================ step 4/5 优化器 ============================
optimizer = optim.SGD(net.parameters(), lr=LR, momentum=0.9)                        # 选择优化器
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)     # 设置学习率下降策略# ============================ step 5/5 训练 ============================
train_curve = list()
valid_curve = list()for epoch in range(MAX_EPOCH):loss_mean = 0.correct = 0.total = 0.net.train()for i, data in enumerate(train_loader):# forwardinputs, labels = dataoutputs = net(inputs)# backwardoptimizer.zero_grad()loss = criterion(outputs, labels)loss.backward()# update weightsoptimizer.step()# 统计分类情况_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted == labels).squeeze().sum().numpy()# 打印训练信息loss_mean += loss.item()train_curve.append(loss.item())if (i+1) % log_interval == 0:loss_mean = loss_mean / log_intervalprint("Training:Epoch[{:0>3}/{:0>3}] Iteration[{:0>3}/{:0>3}] Loss: {:.4f} Acc:{:.2%}".format(epoch, MAX_EPOCH, i+1, len(train_loader), loss_mean, correct / total))loss_mean = 0.scheduler.step()  # 更新学习率def fgsm_attack(image, epsilon, data_grad):# 使用sign(符号)函数,将对x求了偏导的梯度进行符号化(正数为1,零为0,负数为-1)sign_data_grad = data_grad.sign()# 通过epsilon生成对抗样本perturbed_image = image + epsilon * sign_data_grad# 噪声越来越大,机器越来越难以识别,但人眼可以看出差别# 做一个剪裁的工作,将torch.clamp内部大于1的数值变为1,小于0的数值等于0,防止image越界perturbed_image = torch.clamp(perturbed_image, 0, 1)# 返回对抗样本return perturbed_image# 这里的扰动量先设定为几个值,后面可视化展示不同的扰动量影响以及成像效果
epsilons = [0, .05, .1, .15, .2, .25, .3, .35, .4]
# epsilons = [0, .05, .1, .15, .2, ]
accuracies = list()
for eps in epsilons:loss_mean = 0.correct = 0.total = 0.log_interval = 10MAX_EPOCH = 3for epoch in range(MAX_EPOCH):net.train()for j, data in enumerate(valid_loader):inputs, labels = data# 图像数据梯度可以获取inputs.requires_grad = Trueoutputs = net(inputs)optimizer.zero_grad()loss = criterion(outputs, labels)loss.backward()# 收集datagraddata_grad = inputs.grad.data# 调用FGSM攻击perturbed_data = fgsm_attack(inputs, eps, data_grad)# 对受扰动的图像进行重新分类output = net(perturbed_data)# 统计分类情况_, final_pred = torch.max(output.data, 1)    # 得到最大对数概率的索引total += labels.size(0)correct += (final_pred == labels).squeeze().sum().numpy()# 打印训练信息loss_mean += loss.item()valid_curve.append(loss.item())if (j + 1) % log_interval == 0:loss_mean = loss_mean / log_intervalprint("Validing:Epsilon: {:} Epoch[{:0>3}/{:0>3}] Iteration[{:0>3}/{:0>3}] Loss: {:.4f} Acc:{:.2%}".format(eps, epoch, MAX_EPOCH, j + 1, len(valid_loader), loss_mean, correct / total))loss_mean = 0.accuracies.append(correct / total * 100)valid_x = epsilons
valid_y = accuraciesplt.plot(valid_x, valid_y, label='Valid')plt.legend(loc='upper right')
plt.ylabel('Acc')
plt.xlabel('Epsilon')
plt.show()

总结

本周学习了fgsm攻击的基本原理,并将之与之前学习的RMB识别模型进行结合(使用了原先选择的loss函数及训练好的模型),学有所获并详细记录了其中的思路流程。之后,会学习如何使用cifar-10和  imagenet数据集进行FGSM攻击,以及其他评价模型的指标等等。

FGSM实例:利用fgsm攻击RMB识别模型相关推荐

  1. 利用PaddleOCR训练车牌识别模型

    目录 1--前言 2--生成车牌数据集 3--构建车牌数据集标签 4--自定义字典 5--训练模型 6--模型转换和推理 7--模型转换为onnx模型 8--参考 1--前言 ①系统:Ubuntu18 ...

  2. 属性与意图识别_攻击意图动态识别模型

    模型框架 由于计算机网络空间的动态性.开放性以及攻防双方为了争取主动积极调整攻击或防守策略,网络的安全形式也随之瞬息万变.攻击方在攻击过程中发现新的脆弱性.攻击方法.攻击目标或者攻击遇到阻碍时,会随时 ...

  3. CV之IS:利用pixellib库基于mask_rcnn_coco模型对《庆余年》片段实现实例分割简单代码全实现

    CV之IS:利用pixellib库基于mask_rcnn_coco模型对<庆余年>片段实现实例分割简单代码全实现 目录 利用pixellib库的instance_segmentation函 ...

  4. ICCV 2019 | 爱奇艺提出半监督损失函数,利用无标签数据优化人脸识别模型

    点击我爱计算机视觉标星,更快获取CVML新技术 论文发表于ICCV 2019 作者 | 爱奇艺技术产品团队 编辑 | 唐里 论文标题:Unknown Identity Rejection Loss: ...

  5. python实现人脸检测及识别(2)---- 利用keras库训练人脸识别模型

    前面已经采集好数据集boss文件夹存放需要识别的对象照片,other存放其他人的训练集照片,现在,我们终于可以尝试训练我们自己的卷积神经网络模型了.CNN擅长图像处理,keras库的tensorflo ...

  6. 【Python】利用python和百度通用OCR文字识别模型处理pdf文件(有水印且加密)

    pdf文件是办公中非常常见的文件,而且为了保密,常常加水印并且加密,你无法直接复制内容出来. 直接复制出来的效果如图所示. 贯,署,纵 ...

  7. TensorFlow笔记(3)——利用TensorFlow和MNIST数据集训练一个最简单的手写数字识别模型...

    前言 当我们开始学习编程的时候,第一件事往往是学习打印"Hello World".就好比编程入门有Hello World,机器学习入门有MNIST. MNIST是一个入门级的计算机 ...

  8. 翻译:Identifying Encrypted Malware Traffic with Contextual Flow Data利用上下文流数据识别加密恶意软件流量

    利用上下文流数据识别加密恶意软件流量 blake anderson思科blake.anderson@cisco.com 摘要 识别加密网络流量中包含的威胁是一组独特的挑战.监视此通信量以防威胁和恶意软 ...

  9. Mask TextSpotter v3 来了!最强端到端文本识别模型

    场景文本的识别可以用文本检测+文本识别两个过程来做,近年来端到端的场景文本识别(即Text Spotting)越来越引起学术界的重视,而华中科技大学白翔老师组的 Mask TextSpotter v1 ...

  10. php7 viewmodel,【初念科技】| php框架实例: Laravel之Model Observer模型

    原标题:[初念科技]| php框架实例: Laravel之Model Observer模型 本文主要学习下Laravel的Model Observer模型观察者,小编把自己的一点点经验分享出来希望对别 ...

最新文章

  1. 00后电竞女学霸直博中科院,本科武大王者全国16强,网友:现实版爽文女主角...
  2. 求100以内的素数c语言_100万以内的四胞胎素数166组
  3. eclipse maven在哪里_Maven操作
  4. dnSpy反编译、部署调试神器
  5. 《C++ Primer》2.6.1节练习
  6. html鼠标滑轮换图片,JavaScript实现鼠标滚轮控制页面图片切换
  7. selinux 导致ftp文件夹出错~
  8. 原生JS、jQuery 遍历方法总结
  9. 操作系统课程设计之Pintos
  10. PDF转Word的时候需要输入密码怎么办?
  11. 抖音短视频教程VIP培训课程(2019实时更新中)
  12. CyanogenMOD移植教程]
  13. codevs1515 瞎搞+Lucas
  14. 阿里巴巴数据库架构演进分析
  15. LeetCode 460. LFU 缓存 -- 哈希查询+双向链表
  16. easyExcel合并单元格策略
  17. HBASE MOB设计
  18. ctf show-web入门 php特性篇部分题解
  19. 什么是Visa payWave
  20. 奥比中光 astra 乐视三合一体感摄像头采集深度图彩色图并保存

热门文章

  1. 全球与中国ARM开发套件市场现状及未来发展趋势
  2. JSON 的几种简单格式和转换
  3. node2vec文献出处_图表示学习入门2——Node2Vec
  4. JAVAweb之SSH框架
  5. shell卸载 simatic_西门子软件在WIN7操作系统中安装步骤和须知
  6. python 拼音输入法_用Python从头开始实现一个中文拼音输入法?
  7. Ubuntu下利用python实现自动打卡系统全过程
  8. 【数字信号处理】fft幅频特性和相频特性理解
  9. 深入学习软件测试:混合正交表工具
  10. 多终端房地产项目管理系统源码,源码分享