当前位置: 首页 > news >正文

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

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

  • CIFAR数据集
  • DTA介绍
    • 算法流程
  • DTA代码实现
    • DTA算法实现
    • 攻击效果
  • 代码汇总
    • dta.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分类器进行对抗攻击
Pytorch | 利用VA-I-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用PC-I-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用IE-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用GRA针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用GNP针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用MIG针对CIFAR10上的ResNet分类器进行对抗攻击

本篇文章我们使用Pytorch实现DTA对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个不同的类别,这些类别都是现实世界中常见的物体,具有一定的代表性。

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

DTA介绍

DTA(Direction Tuning Attack, 方向调整攻击)是一种新型迁移式对抗攻击方法,旨在提高对抗样本的可迁移性。其核心思想是在每次更新迭代中,通过小步长采样多个示例,并使用这些采样示例的平均梯度来更新对抗样本,从而减小实际更新方向与最速更新方向之间的角度,同时减轻更新振荡。

算法流程

  1. 初始化:设置扰动幅度 ϵ \epsilon ϵ、迭代次数 T T T、大步长 α = ϵ / T \alpha=\epsilon/T α=ϵ/T、动量衰减因子 μ 1 \mu_1 μ1、内循环迭代次数 K K K和内循环动量衰减因子 μ 2 \mu_2 μ2。初始化梯度 g 0 = 0 g_0 = 0 g0=0,对抗样本 x 0 a d v = x x^{adv}_0 = x x0adv=x
  2. 外循环(从 t = 0 到 T - 1)
    • 内循环初始化:对于第 t t t次外循环迭代,设置 g t , 0 = g t g_{t,0} = g_t gt,0=gt x t , 0 a d v = x t a d v x^{adv}_{t,0} = x^{adv}_t xt,0adv=xtadv
    • 内循环(从 k = 0 到 K - 1)
      • 前瞻操作(look ahead operation):计算前瞻对抗样本 x t , k n e s x^{nes}_{t,k} xt,knes x t , k n e s = x t , k a d v + α ⋅ μ 1 ⋅ g t , k x^{nes}_{t,k} = x^{adv}_{t,k} + \alpha \cdot \mu_1 \cdot g_{t,k} xt,knes=xt,kadv+αμ1gt,k
      • 计算梯度:计算第 k k k个采样示例的梯度 g t , k + 1 g_{t,k+1} gt,k+1 g t , k + 1 = μ 2 ⋅ g t , k + ∇ x t , k a d v L ( x t , k n e s , y ; θ ) ∥ ∇ x t , k a d v L ( x t , k n e s , y ; θ ) ∥ 1 g_{t,k+1}=\mu _{2}\cdot g_{t,k}+\frac {\nabla _{x_{t,k}^{a d v}} L\left(x_{t, k}^{nes },y ; \theta\right) }{\parallel \nabla _{x_{t, k}^{a d v}} L\left(x_{t, k}^{n e s}, y ; \theta\right) \parallel _{1}} gt,k+1=μ2gt,k+xt,kadvL(xt,knes,y;θ)1xt,kadvL(xt,knes,y;θ),其中 μ 2 \mu_2 μ2是内循环中 g t , k g_{t,k} gt,k的衰减因子, x t , k a d v x^{adv}_{t,k} xt,kadv表示第 k k k个采样示例, ∇ x t , k a d v L ( x t , k n e s , y ; θ ) \nabla_{x_{t,k}^{adv}} L\left(x_{t, k}^{nes },y ; \theta\right) xt,kadvL(xt,knes,y;θ)是在 x t , k n e s x^{nes}_{t,k} xt,knes处的损失函数关于 x x x的梯度。
      • 更新采样示例:使用小步长 α K \frac{\alpha}{K} Kα更新采样示例 x t , k + 1 a d v x^{adv}_{t,k+1} xt,k+1adv x t , k + 1 a d v = C l i p x ϵ { x t , k a d v + α K ⋅ s i g n ( g t , k + 1 ) } x_{t, k+1}^{a d v}=Clip_{x}^{\epsilon}\left\{x_{t, k}^{a d v}+\frac{\alpha}{K} \cdot sign\left(g_{t, k+1}\right)\right\} xt,k+1adv=Clipxϵ{xt,kadv+Kαsign(gt,k+1)},其中 C l i p x ϵ ( ⋅ ) Clip_{x}^{\epsilon}(\cdot) Clipxϵ()函数将更新后的示例限制在以 x x x为中心、半径为 ϵ \epsilon ϵ的范围内。
    • 计算平均梯度:计算内循环中 K K K个采样示例的平均梯度, g t + 1 = μ 1 ⋅ g t + ∑ k = 1 K g t , k K g_{t+1}=\mu _{1}\cdot g_{t}+\frac{\sum_{k=1}^{K} g_{t, k}}{K} gt+1=μ1gt+Kk=1Kgt,k
    • 更新对抗样本:使用大步长 α \alpha α和平均梯度 g t + 1 g_{t+1} gt+1更新对抗样本 x t + 1 a d v x^{adv}_{t+1} xt+1adv x t + 1 a d v = C l i p x ϵ { x t a d v + α ⋅ s i g n ( g t + 1 ) } x_{t+1}^{a d v}=Clip_{x}^{\epsilon}\left\{x_{t}^{a d v}+\alpha \cdot sign\left(g_{t+1}\right)\right\} xt+1adv=Clipxϵ{xtadv+αsign(gt+1)}
  3. 输出:经过 T T T次迭代后,输出最终的对抗样本 x a d v = x T a d v x^{adv}=x^{adv}_T xadv=xTadv

DTA代码实现

DTA算法实现

import torch
import torch.nn as nndef DTA(model, criterion, original_images, labels, epsilon, num_iterations=10, decay1=1.0, decay2=0.0, K=10):"""DTA (Direction Tuning Attack)参数:- model: 要攻击的模型- criterion: 损失函数- original_images: 原始图像- labels: 原始图像的标签- epsilon: 最大扰动幅度- num_iterations: 外循环迭代次数- decay: 动量衰减因子- K: 内循环迭代次数"""# 计算大步长alphaalpha = epsilon / num_iterations# 复制原始图像作为初始的对抗样本perturbed_images = original_images.clone().detach().requires_grad_(True)momentum = torch.zeros_like(original_images).detach().to(original_images.device)for t in range(num_iterations):inner_gradients = []sample_gradient = momentumfor k in range(K):# 计算前瞻对抗样本x_adv_lookahead = perturbed_images + alpha * decay1 * momentum# 计算损失x_adv_lookahead = x_adv_lookahead.clone().detach().requires_grad_(True)outputs = model(x_adv_lookahead)loss = criterion(outputs, labels)model.zero_grad()loss.backward()# 计算梯度data_grad = x_adv_lookahead.grad.datasample_gradient = decay2 * sample_gradient + data_grad / torch.sum(torch.abs(data_grad), dim=(1, 2, 3), keepdim=True)inner_gradients.append(sample_gradient)# 更新采样示例perturbed_images = perturbed_images + (alpha / K) * torch.sign(sample_gradient)perturbed_images = torch.clamp(perturbed_images, original_images - epsilon, original_images + epsilon)perturbed_images = perturbed_images.detach().requires_grad_(True)# 更新动量momentum = decay1 * momentum + sum(inner_gradients) / K# 更新对抗样本perturbed_images = perturbed_images + alpha * momentum.sign()perturbed_images = torch.clamp(perturbed_images, original_images - epsilon, original_images + epsilon)perturbed_images = perturbed_images.detach().requires_grad_(True)return perturbed_images

攻击效果

为节省时间,这里取 K=1,实际中可取 K=10.
在这里插入图片描述

代码汇总

dta.py

import torch
import torch.nn as nndef DTA(model, criterion, original_images, labels, epsilon, num_iterations=10, decay1=1.0, decay2=0.0, K=10):"""DTA (Direction Tuning Attack)参数:- model: 要攻击的模型- criterion: 损失函数- original_images: 原始图像- labels: 原始图像的标签- epsilon: 最大扰动幅度- num_iterations: 外循环迭代次数- decay: 动量衰减因子- K: 内循环迭代次数"""# 计算大步长alphaalpha = epsilon / num_iterations# 复制原始图像作为初始的对抗样本perturbed_images = original_images.clone().detach().requires_grad_(True)momentum = torch.zeros_like(original_images).detach().to(original_images.device)for t in range(num_iterations):inner_gradients = []sample_gradient = momentumfor k in range(K):# 计算前瞻对抗样本x_adv_lookahead = perturbed_images + alpha * decay1 * momentum# 计算损失x_adv_lookahead = x_adv_lookahead.clone().detach().requires_grad_(True)outputs = model(x_adv_lookahead)loss = criterion(outputs, labels)model.zero_grad()loss.backward()# 计算梯度data_grad = x_adv_lookahead.grad.datasample_gradient = decay2 * sample_gradient + data_grad / torch.sum(torch.abs(data_grad), dim=(1, 2, 3), keepdim=True)inner_gradients.append(sample_gradient)# 更新采样示例perturbed_images = perturbed_images + (alpha / K) * torch.sign(sample_gradient)perturbed_images = torch.clamp(perturbed_images, original_images - epsilon, original_images + epsilon)perturbed_images = perturbed_images.detach().requires_grad_(True)# 更新动量momentum = decay1 * momentum + sum(inner_gradients) / K# 更新对抗样本perturbed_images = perturbed_images + alpha * momentum.sign()perturbed_images = torch.clamp(perturbed_images, original_images - epsilon, original_images + epsilon)perturbed_images = perturbed_images.detach().requires_grad_(True)return perturbed_images

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 = 'DTA'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)elif attack_name == 'VA-I-FGSM':perturbed_images = VA_I_FGSM(model, criterion, original_images, labels, epsilon)elif attack_name == 'PC-I-FGSM':perturbed_images = PC_I_FGSM(model, criterion, original_images, labels, epsilon)elif attack_name == 'IE-FGSM':perturbed_images = IE_FGSM(model, criterion, original_images, labels, epsilon)elif attack_name == 'GRA':perturbed_images = GRA(model, criterion, original_images, labels, epsilon)elif attack_name == 'GNP':perturbed_images = GNP(model, criterion, original_images, labels, epsilon)elif attack_name == 'MIG':perturbed_images = MIG(model, original_images, labels, epsilon)elif attack_name == 'DTA':perturbed_images = DTA(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.mrgr.cn/news/81811.html

相关文章:

  • 小程序配置文件 —— 13 全局配置 - window配置
  • vue3+vite+nginx打包
  • 添砖java第四更@(+)@
  • Direct Preference Optimization: Your Language Model is Secretly a Reward Model
  • RCCL/NCCL中的Transports方式选择:P2P or SHM or NET
  • JUC并发工具---线程协作
  • ipad如何直连主机(Moonlight Sunshine)
  • 【Linux学习五】时间日期指令与查找指令
  • 将现有Web 网页封装为macOS应用
  • Shell的变量功能
  • 学习记录—正则表达式-基本语法
  • 总结TCP/IP四层模型
  • jdk动态代理和cglib动态代理对比
  • Linux Debian安装ClamAV和命令行扫描病毒方法,以及用Linux Shell编写了一个批量扫描病毒的脚本
  • QTday3
  • 2024第一届Solar杯应急响应挑战赛
  • iDP3复现代码数据预处理全流程(二)——vis_dataset.py
  • 使用Xilinx PCIE XDMA框架读写访问DDR3内容
  • 远方的灯塔(自创诗歌浅析)
  • Atcoder Beginner Contest 385
  • HTML4笔记
  • 【MATLAB】对连续信号采样的研究
  • 我们来学activiti -- bpmn
  • Jupyter在运行上出现错误:ModuleNotFoundError: No module named ‘wordcloud‘
  • 计算机的错误计算(一百九十四)
  • Day1 微服务 单体架构、微服务架构、微服务拆分、服务远程调用、服务注册和发现Nacos、OpenFeign