目录
1、FGSM原理
2、pytorch实现
2.1 建立模型
2.2 FGSM模块
2.3 测试
2.4 可视化对比
2.5 对比样本与对抗样本
1、FGSM原理
论文 Explaining and harnessing adversarial examples. 这篇论文由Goodfellow等人发表在ICLR2015会议上,是对抗样本生成领域的经典论文。
FGSM(fast gradient sign method)是一种基于梯度生成对抗样本的算法,属于对抗攻击中的无目标攻击(即不要求对抗样本经过model预测指定的类别,只要与原样本预测的不一样即可)
我们在理解简单的dp网络结构的时候,在求损失函数最小值,我们会沿着梯度的反方向移动,使用减号,也就是所谓的梯度下降算法;而FGSM可以理解为梯度上升算法,也就是使用加号,使得损失函数最大化。先看下图效果,goodfellow等人通过对一个大熊猫照片加入一定的扰动(即噪音点),输入model之后就被判断为长臂猿。
FGSM样本生成
公式
如下图,其中x 是原始样本,θ 是模型的权重参数(即w),y是x的真实类别。输入原始样本,权重参数以及真实类别,通过 J 损失函数求得神经网络的损失值,∇x 表示对 x 求偏导,即损失函数 J 对 x 样本求偏导。sign是符号函数,即sign(-2),sign(-1.5)等都等于 -1;sign(3),sign(4.7)等都等于 1。sign函数图如下。
损失只是概率的负对数。损失值通过神经网络反向传播,神经网络的参数根据所使用的优化器进行更新
ϵ(epsilon)的值通常是人为设定 ,可以理解为学习率,一旦扰动值超出阈值,该对抗样本会被人眼识别。

在这里插入图片描述

在这里插入图片描述
之后,原始图像x + 扰动值 η = 对抗样本 x + η 。
理解公式后,感觉FGSM并不难。其思想也和dp神经网络类似,但它更像是一个逆过程。我们机器学习算法中无论如何都希望损失函数能越小越好;那对抗样本就不一样了,它本身就是搞破坏的东西,当然是希望损失值越大越好,这样算法就预测不出来,就会失效。
2、pytorch实现
声明:代码来源于pytorch官网,跳转;你要是想看官网直接跳转即可,但是以下的内容我会讲解代码以及自己的理解。
下面代码需要下载预训练模型,将其放在如下代码指定文件夹下,预训练模型下载
pytorch不会 ?见pytorch从基础到实战,做学术可离不开它勒。
2.1 建立模型
from__future__importprint_functionimporttorchimporttorch.nnasnnimporttorch.nn.functionalasFimporttorch.optimasoptimfromtorchvisionimportdatasets,transformsimportnumpyasnpimportmatplotlib.pyplotasplt# 这里的epsilon先设定为几个值,到时候后面可视化展示它的影响如何epsilons=[0,.05,.1,.15,.2,.25,.3]# 这个预训练的模型需要提前下载,放在如下url的指定位置,下载链接如上pretrained_model="data/lenet_mnist_model.pth"use_cuda=True# 就是一个简单的模型结构classNet(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)defforward(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)returnF.log_softmax(x,dim=1)# 运行需要稍等,这里表示下载并加载数据集test_loader=torch.utils.data.DataLoader(datasets.MNIST('../data',train=False,download=True,transform=transforms.Compose([transforms.ToTensor(),])),batch_size=1,shuffle=True)# 看看我们有没有配置GPU,没有就是使用cpuprint("CUDA Available: ",torch.cuda.is_available())device=torch.device("cuda"if(use_cudaandtorch.cuda.is_available())else"cpu")# Initialize the networkmodel=Net().to(device)# 加载前面的预训练模型model.load_state_dict(torch.load(pretrained_model,map_location='cpu'))# 设置为验证模式. # 详解见这个博客 https://blog.csdn.net/qq_38410428/article/details/101102075model.eval()
Out:
定义的网络模型较为简单,如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QqouDTJj-1620884909006)(C:\Users\刘志远\AppData\Local\Temp\1620882912362.png)]
2.2 FGSM模块
# FGSM attack codedeffgsm_attack(image,epsilon,data_grad):# 使用sign(符号)函数,将对x求了偏导的梯度进行符号化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)# 返回对抗样本returnperturbed_image
2.3 测试
由于FGSM算法一次迭代即可,所以没必要单独加个train模块,直接在测试模块实现就行
deftest(model,device,test_loader,epsilon):# 准确度计数器correct=0# 对抗样本adv_examples=[]# 循环所有测试集fordata,targetintest_loader:# Send the data and label to the devicedata,target=data.to(device),target.to(device)# Set requires_grad attribute of tensor. Important for Attackdata.requires_grad=True# Forward pass the data through the modeloutput=model(data)init_pred=output.max(1,keepdim=True)[1]# get the index of the max log-probability# If the initial prediction is wrong, dont bother attacking, just move onifinit_pred.item()!=target.item():continue# Calculate the lossloss=F.nll_loss(output,target)# Zero all existing gradientsmodel.zero_grad()# Calculate gradients of model in backward passloss.backward()# Collect datagraddata_grad=data.grad.data# Call FGSM Attackperturbed_data=fgsm_attack(data,epsilon,data_grad)# Re-classify the perturbed imageoutput=model(perturbed_data)# Check for successfinal_pred=output.max(1,keepdim=True)[1]# get the index of the max log-probabilityiffinal_pred.item()==target.item():correct+=1# 这里都是为后面的可视化做准备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:# 这里都是为后面的可视化做准备iflen(adv_examples)<5:adv_ex=perturbed_data.squeeze().detach().cpu().numpy()adv_examples.append((init_pred.item(),final_pred.item(),adv_ex))# Calculate final accuracy for this epsilonfinal_acc=correct/float(len(test_loader))print("Epsilon: {}\tTest Accuracy = {} / {} = {}".format(epsilon,correct,len(test_loader),final_acc))# Return the accuracy and an adversarial examplereturnfinal_acc,adv_examples
这个函数看起来很多,其中有很多操作都是为后面的可视化做准备,这里我说下比较重要的代码
重要的肯定就是损失函数关于x的偏导,如何求出喽。
model.zero_grad(): PyTorch文档中提到,如果grad属性不为空,新计算出来的梯度值会直接加到旧值上面。 为什么不直接覆盖旧的结果呢?这是因为有些Tensor可能有多个输出,那么就需要调用多个backward。 叠加的处理方式使得backward不需要考虑之前有没有被计算过导数,只需要加上去就行了。我们的情况很简单,就一个输出,所以需要使用这条语句
loss.backward():这条语句并不会更新参数,它只会求出各个中间变量的grad(梯度)值,当然也求出了损失函数关于x的偏导啦
data_grad = data.grad.data:由于前面使用了loss.backward() ,所以data这个tensor的grad属性,自然就有值了,还是损失函数对于x的偏导值
2.4 可视化对比
accuracies=[]examples=[]# Run test for each epsilonforepsinepsilons: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()
Out:

在这里插入图片描述
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DvgZtpPf-1620884909008)(C:\Users\刘志远\AppData\Local\Temp\1620884610752.png)]
2.5 对比样本与对抗样本
# Plot several examples of adversarial samples at each epsiloncnt=0plt.figure(figsize=(8,10))foriinrange(len(epsilons)):forjinrange(len(examples[i])):cnt+=1plt.subplot(len(epsilons),len(examples[0]),cnt)plt.xticks([],[])plt.yticks([],[])ifj==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()
Out:
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现
文章目录认识unity打包目录结构游戏逆向流程Unity游戏攻击面可被攻击原因mono的打包建议方案锁血飞天无限金币攻击力翻倍以上统称内存挂透视自瞄压枪瞬移内购破解Unity游戏防御开发时注意数据安全接入第三方反作弊系统外挂检测思路狠人自爆实战查看目录结构用il2cppdumper例子2-森林whoishe后记认识unity打包目录结构dll一般很大,因为里面是所有的游戏功能编译成的二进制码游戏逆向流程开发人员代码被编译打包到GameAssembly.dll中使用il2ppDumper工具,并借助游戏名_Data\il2cpp_data\Metadata\global-metadata.dat
最近在工作中,看到一些新手测试同学,对接口测试存在很多疑问,甚至包括一些从事软件测试3,5年的同学,在聊到接口时,也是一知半解;今天借着这个机会,对接口测试做个实战教学,顺便总结一下经验,分享给大家。计划拆分成4个模块跟大家做一个分享,(接口测试、接口基础知识、接口自动化、接口进阶)感兴趣的小伙伴记得关注,希望对你的日常工作和求职面试,带来一些帮助。注:文章较长有5000多字,希望小伙伴们认真看完,当然有些内容对小白同学不是太友好,如果你需要详细了解其中的一些概念或者名词,请在文章之后留言,后续我将针对大家的疑问,整理输出一些大家感兴趣的文章。随着开发模式的迭代更新,前后端分离已不是新的概念,
前言 Slowloris攻击是我在李华峰老师的书——《MetasploitWeb 渗透测试实战》里面看的,感觉既简单又使用,现在这种攻击是很容易被防护的啦。不过我也不敢真刀实战的去试,只是拿个靶机玩玩罢了。 废话还是写在结语里面吧。(划掉)结语可以不看(划掉)Slowloris攻击的原理 Slowloris是一种资源消耗类DoS攻击,它利用部分HTTP请求进行操作。也叫做慢速攻击,这里的慢速并不是说发动攻击慢,而是访问一条链接的速度慢。Slowloris攻击的功能是打开与目标Web服务器的连接,然后尽可能长时间的保持这些连接打开。如果由多台电脑同时发起Slo
目录FIFO一.自定义同步FIFO1.1代码设计1.2Testbech1.3行为仿真***学习位宽计算函数$clog2()***$clog2()系统函数使用,可以不关注***分布式资源或者BLOCKBRAM二.异步FIFO2.1在FIFO判满的时候有两种方式:2.2异步FIFO为什么要使用格雷码2.2.1介绍格雷码2.2.2格雷码在异步FIFO中的应用2.2.2格雷码判满2.4二进制与格雷码之间的转换2.4.1二进制码转换为格雷码的方法2.4.2格雷码转换为二进制码的方法2.3实现框图2.5实现及仿真代码2.6仿真图验证2.7结论FIFO 这篇更多的是记录FIFO学习,参考了众多优秀的文章,
运行有问题或需要源码请点赞关注收藏后评论区留言一、利用ContentResolver读写联系人在实际开发中,普通App很少会开放数据接口给其他应用访问。内容组件能够派上用场的情况往往是App想要访问系统应用的通讯数据,比如查看联系人,短信,通话记录等等,以及对这些通讯数据及逆行增删改查。首先要给AndroidMaifest.xml中添加响应的权限配置 下面是往手机通讯录添加联系人信息的例子效果如下分成三个步骤先查出联系人的基本信息,然后查询联系人号码,再查询联系人邮箱代码 ContactAddActivity类packagecom.example.chapter07;importandroid
目录一、原理部分1、什么是串行通信(1)并行通信与串行通信(2)串行通信的制式(3)串行通信的主要方式 2、配置串口(1)SCON和PCON:串行口1的控制寄存器(2)SBUF:串行口数据缓冲寄存器 (3)AUXR:辅助寄存器编辑(4)ES、PS:与串行口1中断相关的寄存器(5)波特率设置 3、串口框架编写二、程序案例一、原理部分1、什么是串行通信(1)并行通信与串行通信微控制器与外部设备的数据通信,根据连线结构和传送方式的不同,可以分为两种:并行通信和串行通信。并行通信:数据的各位同时发送与接收,每个数据位使用一条导线,这种方式传输快,但是需要多条导线进行信号传输。串行通信:数据一位一
📝学技术、更要掌握学习的方法,一起学习,让进步发生👩🏻作者:一只IT攻城狮。💐学习建议:1、养成习惯,学习java的任何一个技术,都可以先去官网先看看,更准确、更专业。💐学习建议:2、然后记住每个技术最关键的特性(通常一句话或者几个字),从主线入手,由浅入深学习。❤️《SpringCloud入门实战系列》解锁SpringCloud主流组件入门应用及关键特性。带你了解SpringCloud主流组件,是如何一战解决微服务诸多难题的。项目demo:源码地址👉🏻SpringCloud入门实战系列不迷路👈🏻:SpringCloud入门实战(一)什么是SpringCloud?SpringCloud入门实战
例如,我一直看到称为String#split的方法,但从未见过String.split,这似乎更合乎逻辑。或者甚至可能是String::split,因为您可以认为#split位于String的命名空间中。当假定/隐含类(#split)时,我什至单独看到了该方法。我知道这是ri中识别方法的方式。哪个先出现?例如,这是为了区分方法和字段吗?我还听说这有助于区分实例方法和类方法。但这从哪里开始呢? 最佳答案 不同之处在于您如何访问这些方法。类方法使用::分隔符来表示消息可以发送到类/模块对象,而实例方法使用#分隔符表示消息可以发送到实例对
1、为什么压缩的原始数据一般采用YUV格式(1)利用人对图片感觉的生理特性,对于亮度信息比较敏感,对于色度信息不太敏感,所以视频编码是将Y分量和UV分量分开来编码,并且可以减少UV分量.2、视频压缩原理(1)空间冗余:图像相邻像素之间的相关性,比如一帧图片被划分成多个16x16的块之后,相邻的块之间有很多明显的相似性。(2)时间冗余:时间相差较近的两张图片变化较小。(3)视觉冗余:我们的眼睛对某些细节不太敏感,对图像中的高频信息的敏感度小于低频信息,可以去除一些高频信息。(4)编码冗余:一幅图片中不同像素出现的概率是不同的,对于出现次数较多的像素,用少的位数来编码,对于出现次数较少的像素,用多