Pytorch对机器学习模型的安全漏洞攻击方法之Fast Gradient Sign Attack(FGSM,快速梯度符号攻击)

news2024/11/20 1:22:26

原论文:EXPLAINING AND HARNESSING ADVERSARIAL EXAMPLES
一般本人的习惯是先看论文熟悉它,然后代码去实现它,这样感觉要好点。因为论文讲解的比较全面和一些实验对比还有很多的引用等,另外大家知道好论文基本都是英文,所以对于英文弱点的伙伴们可能需要多花点时间去研读了。论文有论文的好处:全面,博客也有博客的好处:重点展示,以及代码的实现。

1、快速梯度符号攻击

攻防是一个永恒的主题,同样也适应在机器学习模型中,这也是一门热门话题:对抗性机器学习。

通过论文的阅读,我这里表达下自己对论文的理解(如有错误请指正):FGSM是一种简单高效的对抗样本生成方法,​通过计算loss对于输入的梯度为∇xJ(θ,x,y),​然后将其符号化,使用这个函数sign(),​最后将符号化的梯度乘以一个小的扰动值ϵ,​这个扰动值ϵ是一个超参数,​从而生成肉眼难以察觉的对抗样本,让机器模型学习产生错误的分类结果。

我们先来看下一张“经典熊猫”图:

输入是一张“熊猫”,加了一些扰动之后,我们发现目标网络错误地将它归类为“长臂猿”了,而且这个置信度是99.3%,哈哈,这算不算迷之自信。所以说我们在设计和训练机器学习模型的时候,经常会忽视的方面是安全性和鲁棒性,特别是在面对希望欺骗模型的对手时,也就是说攻击模型,让这个模型的输出造成错误,比如分类错误。就是在我们的图像中添加不可察觉的扰动都会导致截然不同的模型性能。

本章将通过一个图像分类器的例子来探讨这个主题。具体来说,我们将使用一个最早最流行的攻击方法之一:快速梯度符号攻击(Fast Gradient Sign Attack)方法来欺骗MNIST分类器。
我们知道对于攻击分两种,白盒攻击和黑盒攻击,这里介绍的FGSM属于白盒攻击,而黑盒攻击的意思就是不清楚模型的架构和权重,只有输入和输出,也就是说模型对于攻击者来说是个黑盒子,不清楚里面的任何情况。

本人深度学习的第一个真正实例也是这个手写识别数字数据集MNIST,对于初次接触的可以先熟悉下这个数据集,很经典的例子,下面是一些MNIST相关文章,有兴趣的可以看看:
MNIST数据集手写数字识别(一)
MNIST数据集手写数字识别(二)
深度的卷积神经网络CNN(MNIST数据集示例)
卷积神经网络(CNN)之MNIST手写数字数据集的实现
这个攻击方法的示例来自于:https://github.com/pytorch/tutorials/blob/main/beginner_source/fgsm_tutorial.py
下面本人将对其进行一些通俗的解释,然后具体来看下是如何进行攻击的。最后通过可视化,让大家有个更直观的感受。

这里使用Jupyter Lab来测试,没有安装的可以安装来体验下,安装命令:

pip install jupyterlab -i http://pypi.douban.com/simple/  --trusted-host pypi.douban.com

安装好了之后,命令行输入启动命令即可:jupyter lab

2、MNIST模型 

首先导入相关需要的库 

from __future__ import print_function
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
import numpy as np
import matplotlib.pyplot as plt

这里使用的是PyTorch框架,如果你没有安装相关库,将报模块缺失的错误,然后安装的时候还是推荐使用加镜像安装,国内安装速度要快很多!

报错:ModuleNotFoundError: No module named 'torch'
安装命令:

pip install torch -i http://pypi.douban.com/simple/  --trusted-host pypi.douban.com

报错:ModuleNotFoundError: No module named 'torchvision'
安装命令:

pip install torchvision -i http://pypi.douban.com/simple/  --trusted-host pypi.douban.com
#这是一个hack,用来在下载MNIST数据集时绕过“User-agent”限制,看情况可选
from six.moves import urllib
opener = urllib.request.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
urllib.request.install_opener(opener)

#这里的epsilons就是扰动量,随着这个值的增加,我们可以观察到它们的分类错误将越来越大
epsilons = [0, .05, .1, .15, .2, .25, .3]
pretrained_model = "data/lenet_mnist_model.pth"
use_cuda=True #由于这里使用的数据集比较小,所以使用CPU也是可以的

其中预训练模型下载:https://drive.google.com/drive/folders/1fn83DF14tWmit0RTKWRhPq5uVXt73e0h

当然这里需要科学上网,对于不方便的,我将其上传到了CSDN,点击下载:MNIST预训练模型.pth文件

# 定义被攻击的模型
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 dataset and dataloader declaration
test_loader = torch.utils.data.DataLoader(
    datasets.MNIST('../data', train=False, download=True, transform=transforms.Compose([
            transforms.ToTensor(),
            ])),
        batch_size=1, shuffle=True)

#CUDA Available:  False
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'))

# 设置模型为评估模式
model.eval()

如果没有下载好MNIST数据集将先自动下载,然后初始化模型并加载预训练模型的权重。

'''
Net(
  (conv1): Conv2d(1, 10, kernel_size=(5, 5), stride=(1, 1))
  (conv2): Conv2d(10, 20, kernel_size=(5, 5), stride=(1, 1))
  (conv2_drop): Dropout2d(p=0.5, inplace=False)
  (fc1): Linear(in_features=320, out_features=50, bias=True)
  (fc2): Linear(in_features=50, out_features=10, bias=True)
)
'''

3、FGSM攻击函数

模型定义并初始化好了之后,我们就开始写FGSM的攻击代码
通过干扰原始输入来定义产生对抗性例子的函数,公式如下:
perturbed_image=image+epsilon∗sign(data_grad)=x+ϵ∗sign(∇xJ(θ,x,y))
另外为了保持数据的原始范围,将扰动后的图像裁剪到范围内[0,1]
代码如下: 

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

4、攻击MNIST模型代码

def test( model, device, test_loader, epsilon ):
    # 正确的计数
    correct = 0
    adv_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] # 得到最大对数概率的索引

        # 如果最初的预测是错误的,不要攻击,继续前进
        if init_pred.item() != target.item():
            continue

        # 计算损失
        loss = F.nll_loss(output, target)

        # 梯度置零
        model.zero_grad()
        loss.backward()
        data_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]
        if final_pred.item() == target.item():
            correct += 1
            # 保存ε为0的例子
            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) )

    # 计算最终精度
    final_acc = correct/float(len(test_loader))
    print("Epsilon: {}\tTest Accuracy = {} / {} = {}".format(epsilon, correct, len(test_loader), final_acc))

    # 返回最终精度和对抗性例子
    return final_acc, adv_examples

5、运行攻击代码

accuracies = []
examples = []

# 为每个epsilon运行测试
for eps in epsilons:
    acc, ex = test(model, device, test_loader, eps)
    accuracies.append(acc)
    examples.append(ex)

'''
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 = 4301 / 10000 = 0.4301
Epsilon: 0.25	Test Accuracy = 2082 / 10000 = 0.2082
Epsilon: 0.3	Test Accuracy = 869 / 10000 = 0.0869
'''

可以看到随着ε的增加,准确率是越来越低了。

6、精度的可视化 

 我们将上面的迭代数据做一个可视化,更直观的感受下:

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

 7、对抗性示例

 最后我们在每个epsilon上绘制几个对抗性样本的例子来感受下,原始分类 -> 对抗分类

cnt = 0
plt.figure(figsize=(8,10))
for i in range(len(epsilons)):
    for j in range(len(examples[i])):
        cnt += 1
        plt.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()

我们可以看到在epsilon=0.25甚至0.3的时候,在有噪声的情况下,人眼还是可以区分这些数字,但是这个模型的识别在epsilon=0.05的时候就开始分类有误了。

对于模型有攻击,那就会有防御,这块有兴趣的可以看这篇论文:Adversarial Attacks and Defences Competition 就是讲解对抗性攻击和防御竞争,对抗性攻击不限于图片,其他的语音和文本模型的攻击都是可以。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/451010.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Python】【进阶篇】2、Django MTV和MVC的区别

目录 2、Django MTV和MVC的区别1. MVC设计模式2. MTV设计模式 2、Django MTV和MVC的区别 在上一节《Django是什么》中&#xff0c;我们对 Django 的诞生以及 Web 框架的概念有了基本的了解&#xff0c;本节我们介绍 Django 的设计模式&#xff0c;也就是 MTV。 在 Web 开发领…

Point cloud tools for Matlab(点云学习工具)

Point cloud tools for Matlab (tuwien.ac.at)https://www.geo.tuwien.ac.at/downloads/pg/pctools/pctools.html#PointCloud_class 下载&#xff1a;Download Matlab Code 添加路径 addpath(genpath(D:\MyMatlabCode\pointCloudTools)); pc pointCloud(Lion.xyz); pc.plot…

AI绘画——ChilloutMix模型(现实真人,实现写实逼真的图像)

目录 重要提示&#xff1a;首先&#xff0c;我从不建议再生“真实”人物的图像&#xff0c; 但是&#xff0c;照片“逼真”图像。 本人郑重声明&#xff1a;本模型原则上禁止用于训练基于明星、公众人物肖像的风格模型训练&#xff0c;因为这会带来争议&#xff0c;对AI社区…

全网详细介绍百度低代码框架amis及实例讲解

文章目录 1. 文章引言2. amis官网3. amis介绍3.1 amis的简述3.2 amis的初衷3.3 amis的其他亮点3.4 amis不适之处 4. amis使用4.1 amis框架集成4.2 amis切换主题4.3 amis配置与组件4.4 amis变量 5. amis实例5.1 amis实例5.2 列表查询5.3 查看详情5.4 自定义操作按钮5.5 提交表单…

你知道ChatGPT中的数据模型是什么吗?

本文将为你揭开ChatGPT和GPT-4中使用的以数据为中心的人工智能技术的秘密。 人工智能在改变我们的生活、工作和与技术互动的方式方面取得了令人难以置信的进步。最近&#xff0c;一个取得重大进展的领域是大型语言模型&#xff08;LLM&#xff09;的开发&#xff0c;如​​GPT…

二十、SQL 数据分析基础与进阶(一)

文章目录 一、破冰 SELECT 基础检索1.1 检索所需要的列1.1.1 检索单列数据1.1.2 检索多列数据 1.2 * 符号初体验1.3 独特的 DISTINCT1.4 使用 ORDER BY 排序检索结果1.5 使用 LIMIT 限制返回行数1.6 ORDER BY 与 LIMIT 结合的妙用 二、过滤数据&#xff0c;选你所想三、计算字段…

ArcGIS Pro快捷键

目录 1 常规应用快捷键 2 动画快捷键 3 内容窗格快捷键 4 数据工程试图快捷键 5 编辑工具快捷键 5.1 常规编辑 5.3 选择工具 5.4 表 5.5 文本格式化标签 5.6 编辑注记 5.7 移动 5.8 旋转 5.9 比例 5.10 编辑折点 5.11 几何属性表 5.12 创建注记 5.13 创建点要…

安装 FME Desktop 2020 教程(内置补丁可以有效激活软件)

介绍&#xff1a;FME Desktop 2020是由加拿大Safe Software公司开发的空间数据转换处理系统&#xff0c;采用先进的数据转换技术&#xff0c;内置几十个转换器&#xff0c;能够满足绝大部分用户的空间数据格式转换功能。除此之外&#xff0c;该软件基于OpenGIS组织提出的新的数…

MySQL_第12章_MySQL数据类型精讲

第12章_MySQL数据类型精讲 1. MySQL中的数据类型 类型 类型举例 整数类型 TINYINT 、 SMALLINT 、 MEDIUMINT 、 INT( 或 INTEGER) 、 BIGINT 浮点类型 FLOAT 、 DOUBLE 定点数类型 DECIMAL 位类型 BIT 日期时间类型 YEAR 、 TIME 、 DATE 、 DATETIME 、 TIMESTAMP 文…

Java 7、8 HashMap源码详解与分析

文章目录 一、哈希表的简介二、JDK1.7 HashMap1、构造方法2、添加方法put()方法addEntry()方法 3、存在的问题 三、JDK1.8 HashMap1、红黑树TreeMap2、属性3、存储的结构4、构造方法5、添加方法put(K, V)方法resize扩容方法 5、putAll()方法6、移除方法remove&#xff08;Objec…

Salesforce官方_中文学习、考证资源

Salesforce将Trailhead描述为学习热门技能的有趣且免费的平台。该平台有助于缩小技能差距&#xff0c;是所有Salesforce用户的宝藏资源。 Trailhead适合所有学习者。它涵盖了适用于Salesforce任何角色的主题和学习模块&#xff0c;从管理员、开发人员、销售主管到最终用户。学…

数据库基础篇 《12.MySQL数据类型精讲》

1. MySQL中的数据类型 2. 整数类型 2.1 类型介绍 整数类型一共有 5 种&#xff0c;包括 TINYINT、SMALLINT、MEDIUMINT、INT&#xff08;INTEGER&#xff09;和 BIGINT。 它们的区别如下表所示&#xff1a; 2.2 可选属性 整数类型的可选属性有三个&#xff1a; 2.2.1 M …

【Python】【进阶篇】3、Django ORM模块精讲

目录 3、Django ORM模块精讲1. 什么是 ORM&#xff1f;2. Django中定义数据表1) 模型类2) 定义数据表 3. ORM 管理器对象4. ORM优势与不足 3、Django ORM模块精讲 Django 框架向我们提供了丰富的模块&#xff0c;避免程序员在开发的过程中重复“造轮子”&#xff0c;提高了开发…

Docker开发基础使用(针对开发者足够)

一.Docker概述 容器就是虚拟化吗&#xff1f; 是&#xff0c;但也不竟然。我们用一种简单方式来思考一下&#xff1a; 虚拟化使得许多操作系统可同时在单个系统上运行。 容器则可共享同一个操作系统内核&#xff0c;将应用进程与系统其他部分隔离开。 这意味着什么&#xf…

Kotlin 用于数据科学的基础库(深度学习、数据挖掘)

Kotlin 用于数据科学 从构建数据流水线到生产机器学习模型&#xff0c; Kotlin 可能是处理数据的绝佳选择&#xff1a; Kotlin 简洁、易读且易于学习。静态类型与空安全有助于创建可靠的、可维护的、易于故障排除的代码。作为一种 JVM 语言&#xff0c;Kotlin 提供了出色的性…

机器视觉工程师买车就买“宝马”车-德国制造-世界精工

世界离开德国,整个地球的制造业将会落后五百年。 说起德国制造 在光学领域最牛的卡尔蔡司公司是制造相机镜头的世界级企业。,在机器视觉行业里面公司Mvtec,我们机器视觉工程师大多数用的halcon,就是来自于德国Mvtec,电气工程师使用的西门子PLC,西门子是是全球电子电气工程及…

兼容性测试用例

兼容性测试用例 兼容性测试是软件测试中非常重要的一块&#xff0c;它主要测试两个方面&#xff1a; 1.同一软件系统&#xff0c;不同版本之间的兼容性 在实际项目中&#xff0c;我们会遇到多种不同版本的软件系统&#xff0c;比如 Windows和 Linux&#xff0c;甚至还有 Unix、…

操作系统原理 —— 什么是进程?进程由什么组成?有什么特征?(六)

进程的概念 在我小时候&#xff0c;刚刚接触电脑的时候&#xff0c;只会在浏览器中输入 4399 搜索小游戏玩一玩&#xff0c;到后来&#xff0c;我学会了安装游戏&#xff0c;然后知道安装完成之后&#xff0c;找到对应的 .exe 的图标就可以运行游戏。 好&#xff0c;那么什么…

2.数据库开发

二.数据库开发 1.开发数据库流程 2.数据库,数据表,数据字段的命名 3.数据库字符集和排序规则设置 4.数据表的引擎选择 二.数据库开发 1.开发数据库流程 ①建立数据库

虚幻图文笔记:面部动画基本原理以及在UE5中如何导入面部动画

0. 面部动画的基本原理 之前做过的项目没有涉及过面部动画&#xff0c;所以最这方面不是很了解&#xff0c;一直以为面部动画也是通过骨骼来驱动的&#xff08;理论上用骨骼驱动当然也是可以的&#xff09;&#xff0c;但很多时候面部动画更多是使用Morph Target&#xff08;有…