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 矿井地图及分析,提升了矿产开采的安全性与效率,为矿业管理提供数据驱动的智能决策支持,推动行业数字化转型。

XXL-TOOL v1.3.2 发布 | Java工具类库

Release Notes 1、【新增】新增工具类模块: Encrypt模块 | 一系列处理编解码、加解密的工具。Net模块 | 一系列处理Web、网络通讯相关的工具。 2、【完善】工具类单测完善;3、【升级】升级依赖版本,如freemarker、junit…等。 部分工具代码…

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

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

Java中StopWatch的使用详解

stopWatch 是org.springframework.util 包下的一个工具类,使用它可直观的输出代码执行耗时,以及执行时间百分比。 在未使用这个工具类之前,如果我们需要统计某段代码的耗时,我们会这样写: public static void main(String[] args…

数据中台从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…

org.apache.zookeeper.server.quorum.QuorumPeerMain

QuorumPeerMain源代码 package org.apache.zookeeper.server.quorum;import java.io.IOException; import javax.management.JMException; import javax.security.sasl.SaslException; import org.apache.yetus.audience.InterfaceAudience; import org.apache.zookeeper.audi…

在K8S中,如果Pod处于不健康状态如何排查?

在kubernetes中,Pod处于不健康状态可能由多种原因导致。为了排查这个问题,你需要采用一系列步骤来确定问题的根源。下面是一个详细的排查过程: 1. 检查Pod的状态: 使用kubectl get pods命令来查看Pod的当前状态。不健康的Pod可能…

广东粤万润与时序数据库TDengine携手打造智慧酒店新未来:数据驱动智能化转型

在智能化转型浪潮席卷全球的当下,智慧酒店行业已然成为推进智能生活应用的先锋领域。从智能照明到环境监测,从安防系统到沉浸式影音娱乐,智慧酒店通过技术赋能为用户提供了更加舒适、高效且个性化的服务体验。然而,随着设备的增多…

mysql_real_connect的概念和使用案例

mysql_real_connect 是 MySQL C API 中的一个函数,用于建立一个到 MySQL 数据库服务器的连接。这个函数尝试建立一个连接,并根据提供的参数进行连接设置。 概念 以下是 mysql_real_connect 函数的基本概念: 函数原型:MYSQL *my…

CSS系列(44)-- Nesting详解

前端技术探索系列:CSS Nesting详解 📦 致读者:探索样式嵌套的艺术 👋 前端开发者们, 今天我们将深入探讨 CSS Nesting,这个强大的样式组织特性。 基础语法 🚀 基础嵌套 /* 简单嵌套 */ .c…

ARM64 CSEL条件 B条件一览

其实整体概括下来,就是两个寄存器比大小,按照不同的格式(有符号,无符号)比 条件选择 (Conditional Selection, CSEL) 示例 CSEL X3, X1, X2, EQ在这个例子中,如果条件码 EQ 为真(即条件寄存器的…

BLE core 内容整理解释

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

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

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

一起来看--红黑树

【欢迎关注编码小哥,学习更多实用的编程方法和技巧】 红黑树是一种自平衡的二叉搜索树,广泛应用于计算机科学中,尤其是在实现关联数组和集合时。它的设计旨在确保在最坏情况下,基本动态集合操作(如插入、删除和查找&am…

聚类评价指标

聚类评价指标分为 内部指标 和 外部指标 两大类,用于评估聚类算法的性能。 一、内部评价指标 内部评价指标不依赖真实标签,主要通过聚类结果本身的紧凑性和分离性进行评估。 轮廓系数(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…

C++ 设计模式:抽象工厂(Abstract Factory)

链接:C 设计模式 链接:C 设计模式 - 工厂方法 链接:C 设计模式 - 原型模式 链接:C 设计模式 - 建造者模式 抽象工厂(Abstract Factory)是一种创建型设计模式,它提供一个接口,用于创…

docker 安装与配置 gitlab

前提条件 Docker:确保你已经安装了 Docker 和 Docker Compose。可以通过以下命令来检查是否安装 Docker:docker --version1. 拉取 GitLab Docker 镜像 首先,我们需要拉取 GitLab 的官方 Docker 镜像。可以使用以下命令来获取 GitLab CE&…