Pytorch | 利用SMI-FGRM针对CIFAR10上的ResNet分类器进行对抗攻击

Pytorch | 利用I-FGSSM针对CIFAR10上的ResNet分类器进行对抗攻击

  • CIFAR数据集
  • SMI-FGRM介绍
    • SMI-FGRM算法流程
  • SMI-FGRM代码实现
    • SMI-FGRM算法实现
    • 攻击效果
  • 代码汇总
    • smifgrm.py
    • train.py
    • advtest.py

之前已经针对CIFAR10训练了多种分类器:
Pytorch | 从零构建AlexNet对CIFAR10进行分类
Pytorch | 从零构建Vgg对CIFAR10进行分类
Pytorch | 从零构建GoogleNet对CIFAR10进行分类
Pytorch | 从零构建ResNet对CIFAR10进行分类
Pytorch | 从零构建MobileNet对CIFAR10进行分类
Pytorch | 从零构建EfficientNet对CIFAR10进行分类
Pytorch | 从零构建ParNet对CIFAR10进行分类

也实现了一些攻击算法:
Pytorch | 利用FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用BIM/I-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用MI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用NI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用PI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用VMI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用VNI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用EMI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用AI-FGTM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用I-FGSSM针对CIFAR10上的ResNet分类器进行对抗攻击

本篇文章我们使用Pytorch实现SMI-FGRM对CIFAR10上的ResNet分类器进行攻击.

CIFAR数据集

CIFAR-10数据集是由加拿大高级研究所(CIFAR)收集整理的用于图像识别研究的常用数据集,基本信息如下:

  • 数据规模:该数据集包含60,000张彩色图像,分为10个不同的类别,每个类别有6,000张图像。通常将其中50,000张作为训练集,用于模型的训练;10,000张作为测试集,用于评估模型的性能。
  • 图像尺寸:所有图像的尺寸均为32×32像素,这相对较小的尺寸使得模型在处理该数据集时能够相对快速地进行训练和推理,但也增加了图像分类的难度。
  • 类别内容:涵盖了飞机(plane)、汽车(car)、鸟(bird)、猫(cat)、鹿(deer)、狗(dog)、青蛙(frog)、马(horse)、船(ship)、卡车(truck)这10个不同的类别,这些类别都是现实世界中常见的物体,具有一定的代表性。

下面是一些示例样本:
在这里插入图片描述

SMI-FGRM介绍

SMI-FGRM(Sampling-based Momentum Iterative Fast Gradient Rescaling Method)是一种基于采样的动量迭代快速梯度重缩放方法,用于提升对抗攻击的可迁移性。它在传统的MI-FGSM算法基础上,引入了数据重缩放和深度优先采样策略,以更准确地近似梯度方向,从而提高攻击效果。

SMI-FGRM算法流程

  1. 初始化
    • 设置步长 α = ϵ / T \alpha=\epsilon/T α=ϵ/T,其中 ϵ \epsilon ϵ 是最大扰动, T T T 是迭代次数。初始化对抗样本 x 0 a d v = x x^{adv}_0 = x x0adv=x,动量 g 0 = 0 g_0 = 0 g0=0
  2. 迭代过程( t = 0 t = 0 t=0 T − 1 T - 1 T1
    • 计算采样梯度 g ^ t + 1 \hat{g}_{t + 1} g^t+1
      • 根据深度优先采样方法(DFSM),在输入空间中对当前点的邻居进行采样,计算采样点和原始图像的平均梯度。具体公式为 g ^ t = 1 N + 1 ∑ i = 0 N ∇ J ( x t i , y ; θ ) \hat{g}_{t}=\frac{1}{N + 1} \sum_{i = 0}^{N} \nabla J\left(x_{t}^{i}, y ; \theta\right) g^t=N+11i=0NJ(xti,y;θ),其中 x t 0 = x x_{t}^{0}=x xt0=x ξ i ∼ U [ − ( β ⋅ ϵ ) d , ( β ⋅ ϵ ) d ] \xi_{i} \sim U[-(\beta \cdot \epsilon)^{d},(\beta \cdot \epsilon)^{d}] ξiU[(βϵ)d,(βϵ)d] N N N 是采样数量, β \beta β 是确定采样范围的超参数, ∇ J ( x t i , y ; θ ) \nabla J\left(x_{t}^{i}, y ; \theta\right) J(xti,y;θ) 是损失函数 J J J 关于输入 x t i x_{t}^{i} xti 的梯度。
    • 更新动量 g t + 1 g_{t + 1} gt+1
      • 使用计算得到的采样梯度 g ^ t + 1 \hat{g}_{t + 1} g^t+1 更新动量 g t + 1 g_{t + 1} gt+1,公式为 g t + 1 = μ g t + g ^ t + 1 ∥ g ^ t + 1 ∥ 1 g_{t + 1}=\mu g_{t}+\frac{\hat{g}_{t + 1}}{\left\|\hat{g}_{t + 1}\right\|_{1}} gt+1=μgt+g^t+11g^t+1,其中 μ \mu μ 是衰减因子。
    • 更新对抗样本 x t + 1 a d v x^{adv}_{t + 1} xt+1adv
      • 通过快速梯度重缩放方法(FGRM)计算梯度缩放后的扰动,更新对抗样本。具体为 x t + 1 a d v = x t a d v + α ⋅ r e s c a l e ( g t + 1 ) x^{adv}_{t + 1}=x^{adv}_{t}+\alpha \cdot rescale(g_{t + 1}) xt+1adv=xtadv+αrescale(gt+1),其中 r e s c a l e ( g ) rescale(g) rescale(g) 是梯度重缩放函数,定义为 r e s c a l e ( g ) = c ∗ s i g n ( g ) ⊙ f ( n o r m ( l o g 2 ∣ g ∣ ) ) rescale(g)=c * sign(g) \odot f\left(norm\left(log _{2}|g|\right)\right) rescale(g)=csign(g)f(norm(log2g)) n o r m ( x ) = x − m e a n ( x ) s t d ( x ) norm(x)=\frac{x - mean(x)}{std(x)} norm(x)=std(x)xmean(x) f ( x ) = σ = 1 1 + e − x f(x)=\sigma=\frac{1}{1 + e^{-x}} f(x)=σ=1+ex1 c c c 是重缩放因子。
  3. 返回结果
    • 迭代结束后,返回最终的对抗样本 x a d v = x T a d v x^{adv}=x^{adv}_T xadv=xTadv

SMI-FGRM代码实现

sampling_num=0 时,SMI-FGRM退化为MI-FGRM.

SMI-FGRM算法实现

import torch
import torch.nn as nndef SMI_FGRM(model, criterion, original_images, labels, epsilon, num_iterations=10, decay=1, sampling_num=12, sampling_beta=1.5, rescale_c=2):"""SMI-FGRM (Sampling-based Momentum Iterative Fast Gradient Rescaling Method)参数:- model: 要攻击的模型- criterion: 损失函数- original_images: 原始图像- labels: 原始图像的标签- epsilon: 最大扰动幅度- num_iterations: 迭代次数- decay: 动量衰减因子- sampling_num: 采样数量- sampling_beta: 采样范围参数- rescale_c: 重缩放因子"""alpha = epsilon / num_iterationsperturbed_images = original_images.clone().detach().requires_grad_(True)momentum = torch.zeros_like(original_images).detach().to(original_images.device)for _ in range(num_iterations):# 深度优先采样sampled_gradients = []x_i = perturbed_images.clone()for _ in range(sampling_num):xi = x_i + torch.randn_like(x_i) * (sampling_beta * epsilon)sampled_gradients.append(compute_gradient(model, criterion, xi, labels))x_i = xisampled_gradients.append(compute_gradient(model, criterion, perturbed_images, labels))g_hat = torch.mean(torch.stack(sampled_gradients), dim=0)# 更新动量momentum = decay * momentum + g_hat / torch.sum(torch.abs(g_hat), dim=(1, 2, 3), keepdim=True)# 快速梯度重缩放rescaled_gradient = rescale_gradient(momentum, rescale_c)# 更新对抗样本perturbed_images = perturbed_images + alpha * rescaled_gradientperturbed_images = torch.clamp(perturbed_images, original_images - epsilon, original_images + epsilon)perturbed_images = perturbed_images.detach().requires_grad_(True)return perturbed_imagesdef rescale_gradient(g, c):"""梯度重缩放函数参数:- g: 梯度- c: 重缩放因子"""normed_log_gradient = (torch.log2(torch.abs(g)) - torch.mean(torch.log2(torch.abs(g)), dim=(1, 2, 3), keepdim=True)) / torch.std(torch.log2(torch.abs(g)), dim=(1, 2, 3), keepdim=True)sigmoid_applied = 1 / (1 + torch.exp(-normed_log_gradient))return c * torch.sign(g) * sigmoid_applieddef compute_gradient(model, criterion, x, labels):"""计算梯度参数:- model: 模型- criterion: 损失函数- x: 输入图像- labels: 标签"""x = x.clone().detach().requires_grad_(True)outputs = model(x)loss = criterion(outputs, labels)model.zero_grad()loss.backward()return x.grad.data

攻击效果

在这里插入图片描述

代码汇总

smifgrm.py

import torch
import torch.nn as nndef SMI_FGRM(model, criterion, original_images, labels, epsilon, num_iterations=10, decay=1, sampling_num=12, sampling_beta=1.5, rescale_c=2):"""SMI-FGRM (Sampling-based Momentum Iterative Fast Gradient Rescaling Method)参数:- model: 要攻击的模型- criterion: 损失函数- original_images: 原始图像- labels: 原始图像的标签- epsilon: 最大扰动幅度- num_iterations: 迭代次数- decay: 动量衰减因子- sampling_num: 采样数量- sampling_beta: 采样范围参数- rescale_c: 重缩放因子"""alpha = epsilon / num_iterationsperturbed_images = original_images.clone().detach().requires_grad_(True)momentum = torch.zeros_like(original_images).detach().to(original_images.device)for _ in range(num_iterations):# 深度优先采样sampled_gradients = []x_i = perturbed_images.clone()for _ in range(sampling_num):xi = x_i + torch.randn_like(x_i) * (sampling_beta * epsilon)sampled_gradients.append(compute_gradient(model, criterion, xi, labels))x_i = xisampled_gradients.append(compute_gradient(model, criterion, perturbed_images, labels))g_hat = torch.mean(torch.stack(sampled_gradients), dim=0)# 更新动量momentum = decay * momentum + g_hat / torch.sum(torch.abs(g_hat), dim=(1, 2, 3), keepdim=True)# 快速梯度重缩放rescaled_gradient = rescale_gradient(momentum, rescale_c)# 更新对抗样本perturbed_images = perturbed_images + alpha * rescaled_gradientperturbed_images = torch.clamp(perturbed_images, original_images - epsilon, original_images + epsilon)perturbed_images = perturbed_images.detach().requires_grad_(True)return perturbed_imagesdef rescale_gradient(g, c):"""梯度重缩放函数参数:- g: 梯度- c: 重缩放因子"""normed_log_gradient = (torch.log2(torch.abs(g)) - torch.mean(torch.log2(torch.abs(g)), dim=(1, 2, 3), keepdim=True)) / torch.std(torch.log2(torch.abs(g)), dim=(1, 2, 3), keepdim=True)sigmoid_applied = 1 / (1 + torch.exp(-normed_log_gradient))return c * torch.sign(g) * sigmoid_applieddef compute_gradient(model, criterion, x, labels):"""计算梯度参数:- model: 模型- criterion: 损失函数- x: 输入图像- labels: 标签"""x = x.clone().detach().requires_grad_(True)outputs = model(x)loss = criterion(outputs, labels)model.zero_grad()loss.backward()return x.grad.data

train.py

import torch
import torch.nn as nn
import torchvision
import torchvision.transforms as transforms
from models import ResNet18# 数据预处理
transform_train = transforms.Compose([transforms.RandomCrop(32, padding=4),transforms.RandomHorizontalFlip(),transforms.ToTensor(),transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))
])transform_test = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))
])# 加载Cifar10训练集和测试集
trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=False, transform=transform_train)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2)testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=False, transform=transform_test)
testloader = torch.utils.data.DataLoader(testset, batch_size=100, shuffle=False, num_workers=2)# 定义设备(GPU或CPU)
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")# 初始化模型
model = ResNet18(num_classes=10)
model.to(device)# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)if __name__ == "__main__":# 训练模型for epoch in range(10):  # 可以根据实际情况调整训练轮数running_loss = 0.0for i, data in enumerate(trainloader, 0):inputs, labels = data[0].to(device), data[1].to(device)optimizer.zero_grad()outputs = model(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()running_loss += loss.item()if i % 100 == 99:print(f'Epoch {epoch + 1}, Batch {i + 1}: Loss = {running_loss / 100}')running_loss = 0.0torch.save(model.state_dict(), f'weights/epoch_{epoch + 1}.pth')print('Finished Training')

advtest.py

import torch
import torch.nn as nn
import torchvision
import torchvision.transforms as transforms
from models import *
from attacks import *
import ssl
import os
from PIL import Image
import matplotlib.pyplot as pltssl._create_default_https_context = ssl._create_unverified_context# 定义数据预处理操作
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.491, 0.482, 0.446), (0.247, 0.243, 0.261))])# 加载CIFAR10测试集
testset = torchvision.datasets.CIFAR10(root='./data', train=False,download=False, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=128,shuffle=False, num_workers=2)# 定义设备(GPU优先,若可用)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")model = ResNet18(num_classes=10).to(device)criterion = nn.CrossEntropyLoss()# 加载模型权重
weights_path = "weights/epoch_10.pth"
model.load_state_dict(torch.load(weights_path, map_location=device))if __name__ == "__main__":# 在测试集上进行FGSM攻击并评估准确率model.eval()  # 设置为评估模式correct = 0total = 0epsilon = 16 / 255  # 可以调整扰动强度for data in testloader:original_images, labels = data[0].to(device), data[1].to(device)original_images.requires_grad = Trueattack_name = 'SMI-FGRM'if attack_name == 'FGSM':perturbed_images = FGSM(model, criterion, original_images, labels, epsilon)elif attack_name == 'BIM':perturbed_images = BIM(model, criterion, original_images, labels, epsilon)elif attack_name == 'MI-FGSM':perturbed_images = MI_FGSM(model, criterion, original_images, labels, epsilon)elif attack_name == 'NI-FGSM':perturbed_images = NI_FGSM(model, criterion, original_images, labels, epsilon)elif attack_name == 'PI-FGSM':perturbed_images = PI_FGSM(model, criterion, original_images, labels, epsilon)elif attack_name == 'VMI-FGSM':perturbed_images = VMI_FGSM(model, criterion, original_images, labels, epsilon)elif attack_name == 'VNI-FGSM':perturbed_images = VNI_FGSM(model, criterion, original_images, labels, epsilon)elif attack_name == 'EMI-FGSM':perturbed_images = EMI_FGSM(model, criterion, original_images, labels, epsilon)elif attack_name == 'AI-FGTM':perturbed_images = AI_FGTM(model, criterion, original_images, labels, epsilon)elif attack_name == 'I-FGSSM':perturbed_images = I_FGSSM(model, criterion, original_images, labels, epsilon)elif attack_name == 'SMI-FGRM':perturbed_images = SMI_FGRM(model, criterion, original_images, labels, epsilon)perturbed_outputs = model(perturbed_images)_, predicted = torch.max(perturbed_outputs.data, 1)total += labels.size(0)correct += (predicted == labels).sum().item()accuracy = 100 * correct / total# Attack Success RateASR = 100 - accuracyprint(f'Load ResNet Model Weight from {weights_path}')print(f'epsilon: {epsilon:.4f}')print(f'ASR of {attack_name} : {ASR :.2f}%')

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

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

相关文章

基于PREEvision的UML设计

众所周知,PREEvision是一款强大的电子电气架构协同开发及管理软件,可以很好地帮助架构工程师完成架构开发工作,其功能包括需求管理、定义功能逻辑、系统软件开发、网络设计、线束设计及整体工程的产品线管理和变形管理等。随着工程师们越来越…

闲谭Scala(2)--安装与环境配置

1. 概述 Java开发环境安装,需要两步,第一安装JDK,第二配置环境变量。 Scala的话,也是两步,第一安装Scale环境,第二配置环境变量。 需要注意的是,配置环境变量,主要是想让windows操…

智慧地下采矿:可视化引领未来矿业管理

图扑智慧地下采矿可视化平台通过整合多源数据,提供实时 3D 矿井地图及分析,提升了矿产开采的安全性与效率,为矿业管理提供数据驱动的智能决策支持,推动行业数字化转型。

王鹤棣新剧《大奉打更人》开播 数据亮眼刷新招商纪录

临近年末,各类国产剧集仍频上新,档期竞争格外激烈。而由王鹤棣领衔主演的古装悬疑轻喜剧《大奉打更人》已于12月28日在CCTV-8和腾讯视频同步播出,开播即横扫各大榜单。该剧从定档官宣到开播,热度一路攀升,开播后更是掀…

数据中台从centos升级为国产操作系统后,资源增加字段时,提交报500错误

文章目录 背景一、步骤1.分析阶段2.查看nginx3.修改用户(也可以修改所有者权限) 背景 故障报错: nginx报错信息: 2024/12/19 15:25:31 [crit, 500299#0: *249 onen0 " /var/lib/nginx/tmp/cient body/0000000001" f…

BLE core 内容整理解释

本文内容比较杂散,只是做记录使用,后续会整理的有条理些 link layer 基本介绍 **Link Layer Control(链路层控制)**是蓝牙低功耗(BLE)协议栈的核心部分,负责实现设备间可靠、安全、低功耗的数…

【疑难杂症】 HarmonyOS NEXT中Axios库的响应拦截器无法拦截424状态码怎么办?

今天在开发一个HarmonyOS NEXT的应用的时候,发现http接口如果返回的状态码是424时,我在axios中定义的拦截器失效了。直接走到了业务调用的catch中。 问题表现: 我的拦截器代码如下: 解决办法: 先说解决办法&#xff…

聚类评价指标

聚类评价指标分为 内部指标 和 外部指标 两大类,用于评估聚类算法的性能。 一、内部评价指标 内部评价指标不依赖真实标签,主要通过聚类结果本身的紧凑性和分离性进行评估。 轮廓系数(Silhouette Coefficient, SC) 衡量数据点与其…

flask后端开发(1):第一个Flask项目

目录 一、Helloworddebug、host、port的配置 gitcode地址: https://gitcode.com/qq_43920838/flask_project.git 一、Helloword 一般是会创建两个文件夹和app.py app.py from flask import FlaskappFlask(__name__)app.route(/) def hello_world():return Hello…

一文复盘:RAG技术-大模型

原文:https://zhuanlan.zhihu.com/p/13962398269 RAG(Retrieval-Augmented Generation)之所以被关注,有两方面原因: 1、没有跑大模型的资源:大多数人没有GPU集群搞LLM的预训练。 2、大模型缺乏知识&…

使用 OpenCV 绘制线条和矩形

OpenCV 是一个功能强大的计算机视觉库,它不仅提供了丰富的图像处理功能,还支持图像的绘制。绘制简单的几何图形(如线条和矩形)是 OpenCV 中常见的操作。在本篇文章中,我们将介绍如何使用 OpenCV 在图像上绘制线条和矩形…

WinForm 美化秘籍:轻松实现 Panel 圆角虚线边框

文章目录 1、引言2、案例实现1、创建自定义 Panel 类2、定义圆角矩形3. 使用自定义 Panel4. 调整属性5、使用背景图片来实现5、拓展:使用 Panel 的 Paint重绘单独实现虚线边框效果 3、实现效果4、总结 1、引言 在 Winform 应用程序开发中,美化用户界面&…

Spring Cloud LoadBalancer (负载均衡)

目录 什么是负载均衡 服务端负载均衡 客户端负载均衡 Spring Cloud LoadBalancer快速上手 启动多个product-service实例 测试负载均衡 负载均衡策略 自定义负载均衡策略 什么是负载均衡 负载均衡(Load Balance,简称 LB) , 是高并发, 高可用系统必不可少的关…

OpenCloudOS简介

OpenCloudOS是一款开源的云操作系统,具有诸多特性和优势,广泛应用于多个领域。 一、项目背景 开源社区发起:由操作系统、云平台、软硬件厂商与个人共同倡议发起的操作系统社区项目,旨在打造全面中立、开放、安全、稳定易用、高…

NLP 中文拼写检测纠正论文 Automatic-Corpus-Generation

拼写纠正系列 NLP 中文拼写检测实现思路 NLP 中文拼写检测纠正算法整理 NLP 英文拼写算法,如果提升 100W 倍的性能? NLP 中文拼写检测纠正 Paper java 实现中英文拼写检查和错误纠正?可我只会写 CRUD 啊! 一个提升英文单词拼…

区块链安全常见的攻击合约和简单复现,附带详细分析——不安全调用漏洞 (Unsafe Call Vulnerability)【6】

区块链安全常见的攻击分析——不安全调用漏洞 Unsafe Call Vulnerability 区块链安全常见的攻击合约和简单复现,附带详细分析——不安全调用漏洞 (Unsafe Call Vulnerability)【6】1.1 漏洞合约1.2 漏洞分析1.3 攻击步骤分析1.4 攻击合约 区块链安全常见的攻击合约和…

留学生交流互动系统|Java|SSM|VUE| 前后端分离

【技术栈】 1⃣️:架构: B/S、MVC 2⃣️:系统环境:Windowsh/Mac 3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7 4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库可…

算法基础一:冒泡排序

一、冒泡排序 1、定义 冒泡排序(英语:Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。 …

跨域请求问题

跨域请求简介 跨域请求:通过一个域的JavaScript脚本和另外一个域的内容进行交互 域的信息:协议、域名、端口号 同域:当两个域的协议、域名、端口号均相同 如下所示: 同源【域】策略:在浏览器中存在一种安全策略就是…

C++“STL之String”

​ 🌹个人主页🌹:喜欢草莓熊的bear 🌹专栏🌹:C入门 目录 ​编辑 前言 一、STL简介 1.1 STL是什么? 1.2 STL的版本(这个不是很重要了解即可) 1.3 STL的六大组件 二…