deepfool攻击pytorch代码-程序员宅基地

技术标签: python  机器学习  深度学习  人工智能  adversarial example  

论文讲解参考对抗样本(五)DeepFool_Bai丁的博客-程序员宅基地

二、论文背景及简介
    目前,没有有效率的方法可以用来精确的计算深度模型对对抗扰动的鲁棒性。在这篇论文中,提出了DeepFool的算法来生成扰动,并且提出了一种量化分类器鲁棒性的方法。


三、论文内容总结
提出了一种计算分类器对对抗扰动的鲁棒性的评价方法
FGSM虽然快,但是它只是提供了最优扰动的一个粗略的估计,它执行的梯度的方法,经常得到的是局部最优解,DeepFool能够得到更小的扰动,甚至比FGSM小一个数量级
提出了一个新的对抗攻击方法DeepFool:

直接放pytorch代码吧

#Deepfool算法示例
from typing import Collection
import torch
import torchvision
from torchvision import datasets, transforms
from torch.autograd import Variable
# from torch.autograd.gradcheck import zero_gradients 这句话运行不了,改为下面这段函数
import torch.utils.data.dataloader as Data
import torch.nn as nn
from torchvision import models
import numpy as np
import cv2


def zero_gradients(x):
    if isinstance(x, torch.Tensor):
        if x.grad is not None:
            x.grad.detach_()
            x.grad.zero_()
    elif isinstance(x, Collection.abc.Iterable):
        for elem in x:
            zero_gradients(elem)
#对比展现原始图片和对抗样本图片
def show_images_diff(original_img,original_label,adversarial_img,adversarial_label):
    import matplotlib.pyplot as plt
    plt.figure()

    #归一化
    if original_img.any() > 1.0:
        original_img=original_img/255.0
    if adversarial_img.any() > 1.0:
        adversarial_img=adversarial_img/255.0

    plt.subplot(131)
    plt.title('Original')
    plt.imshow(original_img)
    plt.axis('off')

    plt.subplot(132)
    plt.title('Adversarial')
    plt.imshow(adversarial_img)
    plt.axis('off')

    plt.subplot(133)
    plt.title('Adversarial-Original')
    difference = adversarial_img - original_img
    #(-1,1)  -> (0,1)
    difference=difference / abs(difference).max()/2.0+0.5
    plt.imshow(difference,cmap=plt.cm.gray)
    plt.axis('off')
    plt.tight_layout()
    plt.show()
#获取计算设备 默认是CPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

#图像加载以及预处理
image_path="../picture/test_im1.jpg"# 这里用的是一张鹦鹉的图片,所以输出的label应该是88
orig = cv2.imread(image_path)[..., ::-1]
orig = cv2.resize(orig, (224, 224))
img = orig.copy().astype(np.float32)

mean = [0.485, 0.456, 0.406]
std = [0.229, 0.224, 0.225]
img /= 255.0
img = (img - mean) / std
img = img.transpose(2, 0, 1)

img=np.expand_dims(img, axis=0)

img = Variable(torch.from_numpy(img).to(device).float())
print(img.shape)

#使用预测模式 主要影响droupout和BN层的行为
model = models.alexnet(pretrained=True).to(device).eval()

orig_label=np.argmax(model(img).data.cpu().numpy())
print("label={}".format(orig_label))

上面这些代码都可以复用的所以我直接用
 

下面这部分是非定向攻击的代码

#图像数据梯度可以获取
img.requires_grad = True

#设置为不保存梯度值 自然也无法修改
for param in model.parameters():
    param.requires_grad = False
    
#最大迭代次数
epochs=100
#used as a termination criterion to prevent vanishing updates
overshoot=0.02
#类别数
num_classes=1000

# forward 
output = model(img)
#detach()是一个常用的函数,其作用是从计算图中分离出一个张量,返回一个新的张量,新张量与原张量共享数据存储空间,但不再与计算图相连,即新张量不会被用于计算梯度。这样可以避免梯度在反向传播过程中回传到已经不需要梯度的张量上,从而减少计算量,提高训练效率。
input_shape = img.cpu().detach().numpy().shape
w=np.zeros(input_shape)
r_tot=np.zeros(input_shape)

for epoch in range(epochs):
    scores=model(img).data.cpu().numpy()[0]
    label=np.argmax(scores)
    print("epoch={},label={},score={}".format(epoch,label,scores[label])

# 如果无定向攻击成功
    if label!=orig_label:
        break
    pert=np.inf
    output[0,orig_label].backward(retain_graph=True)
    grad_orig=img.grad.data.cpu().numpy().copy()
    for k in range(1, num_classes):
        if k==orig_label:# 如果label不变
            continue
        zero_gradients(img)# 梯度清零
        output[0,k].backward(retain_graph=True)
        cur_grad=img.grad.data.cpu().numpy().copy()
        # set new w_k,f_k
        w_k=cur_grad-grad_orig
        f_k=(output[0,k]-output[0,orig_label]).data.cpu().numpy()
        pert_k=abs(f_k)/np.linalg.norm(wk.flatten())

        # 选择pert最小值
        if pert_k<pert:
            pert=pert_k
            w=w_k
    # 计算r_i和r_tot
    r_i = (pert+1e-8)*w/np.linalg.norm(w)
    r_tot=np.float32(r_tot+r_i)
    img.data=img.data+(1+overshoot)*torch.from_numpy(r_tot).to(device)
        
            
adv=img.data.cpu().numpy()[0]
print(adv.shape)
adv = adv.transpose(1, 2, 0)
adv = (adv * std) + mean
adv = adv * 255.0
adv = np.clip(adv, 0, 255).astype(np.uint8)

show_images_diff(orig,orig_label,adv,label)

 

下面这部分是定向攻击的代码

#图像数据梯度可以获取
img.requires_grad = True

#设置为不保存梯度值 自然也无法修改
for param in model.parameters():
    param.requires_grad = False

epochs=100
overshoot=0.02

#攻击目标
target_label=288
target=Variable(torch.Tensor([float(target_label)]).to(device).long())

input_shape = img.cpu().detach().numpy().shape
w = np.zeros(input_shape)
r_tot = np.zeros(input_shape)

loss_func = torch.nn.CrossEntropyLoss()

for epoch in range(epochs):
    
    # forward 
    output = model(img)
    
    label=np.argmax(output.data.cpu().numpy())
    loss = loss_func(output, target)
    print("epoch={} label={} loss={}".format(epoch,label,loss))
    
    #如果定向攻击成功
    if label == target_label:
        break
   
    #梯度清零
    zero_gradients(img)

    output[0, target_label].backward(retain_graph=True)
    w = img.grad.data.cpu().numpy().copy()

    f = output[0, target_label].data.cpu().numpy()

    pert = abs(f)/np.linalg.norm(w.flatten())

    # 计算 r_i 和 r_tot
    r_i =  (pert+1e-8) * w / np.linalg.norm(w)
        
    r_tot = np.float32(r_tot + r_i)
    
    img.data=img.data + (1+overshoot)*torch.from_numpy(r_tot).to(device)


adv=img.data.cpu().numpy()[0]
print(adv.shape)
adv = adv.transpose(1, 2, 0)
adv = (adv * std) + mean
adv = adv * 255.0
adv = np.clip(adv, 0, 255).astype(np.uint8)

show_images_diff(orig,orig_label,adv,target_label)

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42732826/article/details/130435618

智能推荐

数据结构与算法 - 07 二分搜索与贪婪_基础结果搜索数据结构贪心-程序员宅基地

文章浏览阅读250次。二分搜索 Binary Search 定义 又叫 折半搜索 在有序数组中查找某一特定元素的搜索算法 前提:数组必须有序 优点 时间复杂度:O(lgn),非常高效 又叫 对数搜索 缺点 要求待查找的数组或区间是排好序的 应用 数据是排好序的,且不会经常变动 代码 递归 非递归 贪婪 Greedy 定义 每一步都采用在当前状态下最好或最优的选择,从而希望导致结果是最好或最优的算法 优点 从局部考_基础结果搜索数据结构贪心

【个人网站开发 · 记录四】开发阶段一 —— 原生VuePress开发(上)手动搭建个人博客网站的详细记录_vuepress创建项目模板还是手动-程序员宅基地

文章浏览阅读929次。文章目录一. 第一部分1.1 xxx1.2 xxx二. 第二部分2.1 yyy2.2 yyy前言部分一. 第一部分1.1 xxx1.2 xxx二. 第二部分2.1 yyy2.2 yyy_vuepress创建项目模板还是手动

kali系统简单入门_kali快速入门-程序员宅基地

文章浏览阅读997次。kali基础操作命令作用及格式_kali快速入门

word 此文件来自其它计算机,问题解决: 此文件来自其他计算机,可能被阻止以帮助保护该计算机/WORD在试图打开文件时遇到错误……...-程序员宅基地

文章浏览阅读3.1k次,点赞2次,收藏6次。最近,在打开下载的office文档(包括word、excel、ppt等)时候,总是无法直接打开,错误提示如下:无论是邮件中的还是别的网站下载的,均提示该错误。后来搜索相关资料发现,修改其文件属性即可打开(属性---》解除锁定)。但是也不能每次下载文件都去修改呀,太费事了。原因分析:这一切都要从WindowsXP的SP2说起,在SP2之前,大概是2004年吧,由于当时互联网得到了一个比较大的发展,导..._此文件来自其他计算机可能被阻止

谷歌chorme浏览器版本降级_如何将googlecharme的版本降低-程序员宅基地

文章浏览阅读3.8k次。升级了谷歌最新版不习惯,如何降级版本未完待续。。电脑中的Chrome谷歌浏览器升级到了最新版本,但是有种种的不适应,如何能恢复到之前的旧版本呢?我们来看看操作步骤,而且无需卸载重装。怎么恢复Chrome 之前版本?1、关闭Chrome进程,打开chrome.exe所在目录,在Win8下的路径是(X:\Users\用户名\AppData\Local\Google\Chrom..._如何将googlecharme的版本降低

通过EDID信息,获取电脑显示器序列号_edid-decode查询显示器序列号-程序员宅基地

文章浏览阅读5k次。某天突发奇想,能不能通过软件把电脑主机和显示器绑定,于是研究了下,发现需要获取显示器的DDC信息,通过驱动层面获取难度比较大,网上查询了下,linux的driver里video中有相关代码段,通过一直可以搞定,不过没有尝试,最后通过注册表发现了一个键值也能达到目的,HKEY_LOCAL_MACHINE->SYSTEM->ControlSet001->Enum->Display中的第一项就是_edid-decode查询显示器序列号

随便推点

Linux命令行访问U盘内容_linux查看u盘命令-程序员宅基地

该文章介绍了使用Linux命令行访问U盘内容的方法,通过查看U盘信息、挂载U盘到指定文件夹、访问U盘内容等步骤实现。同时指出不能访问名称为中文的文件夹和文件。

阿里巴巴OSS对象存储在java中使用(简单好用,一看就会)_oss仓库java文档-程序员宅基地

文章浏览阅读3.1k次。阿里云OSS(Object Storage Service,对象存储服务)是一种高可用、高可靠、海量、安全的云存储服务,可以帮助用户存储和管理海量非结构化数据,如图片、音频、视频等。阿里云OSS提供了简单易用的API,可以方便地上传、下载、管理和分享数据。它还提供了多种数据存储类型和数据访问方式,以满足不同场景下的需求,如标准存储、低频访问存储、归档存储等。阿里云OSS还具有高可用性和高可靠性,它采用了多副本存储和多机房容灾技术,确保数据的安全性和可用性。_oss仓库java文档

NetSetMan IP快速切换_netsetman csdn-程序员宅基地

文章浏览阅读454次。NetSetMan 是一个小巧好用的工具,你可以设置五组不同的网络参数值,让使用者可以针对不同的网络环境,而调用不同的参数,只要使用NetSetMan,就可以让我们省去了许多时间,以及繁杂的网络设置步骤。 NetSetMan 可以让我们设置计算机IP地址、子网掩码、默认网关、DNS、计算机名、DNS 域、工作组、WINS、打印机等。除此之外还可以让我们运行Script(例如:bat、cmd、vbs_netsetman csdn

授权服务是如何颁发授权码和访问令牌的?_访问令牌 授权书-程序员宅基地

文章浏览阅读2.7k次,点赞2次,收藏2次。授权服务如何生成访问令牌?访问令牌过期了而用户又不在场的情况下,又如何重新生成访问令牌?授权服务的工作过程在 xx让我去公众号开放平台给它授权数据时,你是否好奇?开放平台怎么知道 xx 是谁?他合法备案了吗?万一是个病毒软件咋办?所以,授权的前提是xx要去开放平台备案,即注册。之后,开放平台就会给xx软件app_id和app_secret等,方便后面授权时的各种校验。注册时,三方软件也会请求受保护资源的可访问范围。比如,xx能否获取我的公众号半年前的文章,能否获取每个文章的所有信息(比如标题、封面_访问令牌 授权书

中望cad能编写lisp吗_又一家掌握CAE核心技术企业诞生!发布电磁仿真软件中望Sim-EM...-程序员宅基地

文章浏览阅读141次。7月30日,中望软件发布首款完全自主产权的全波三维电磁仿真软件:中望Sim-EM 2019。这标志着中望软件已经掌握了CAE电磁仿真核心技术,并具备了自主开发专业CAE产品的能力。同时,中望CAE电磁仿真软件的推出极大地丰富了中望软件All-in-One CAx一体化解决方案的产品结构,大幅度提升行业服务能力。随着数字制造的发展,计算机仿真技术成为工业产品设计和发展不可或缺的核心技术。业内人士认为..._晓天博士杜克大学

企业 Elasticsearch日志分析平台_elastic日志平台-程序员宅基地

文章浏览阅读805次。Elasticsearch介绍 安装配置 添加图形界面 ES分布式部署 Logstash数据采集 kibana数据可视化xpack安全验证_elastic日志平台

推荐文章

热门文章

相关标签