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

FGSM 与 PGD 攻击实战对比:PyTorch 实现 5 种扰动策略,CIFAR-10 准确率降至 10%

FGSM与PGD攻击实战对比:PyTorch实现5种扰动策略在CIFAR-10上的效果验证

深度神经网络在计算机视觉任务中表现出色,但研究表明它们容易受到精心设计的微小扰动影响。本文将深入分析FGSM(快速梯度符号法)和PGD(投影梯度下降)两种经典对抗攻击方法的核心差异,并提供5种攻击策略的完整PyTorch实现代码。我们使用ResNet-18模型在CIFAR-10数据集上进行系统评测,展示不同攻击方法如何将模型准确率从90%以上降至10%左右。

1. 实验环境搭建与基准模型训练

1.1 环境配置与依赖安装

首先确保已安装PyTorch 1.8+和TorchVision。实验使用NVIDIA RTX 3090 GPU加速计算:

pip install torch==1.8.1+cu111 torchvision==0.9.1+cu111 -f https://download.pytorch.org/whl/torch_stable.html pip install matplotlib numpy tqdm

1.2 ResNet-18模型训练

我们在CIFAR-10上训练一个标准ResNet-18作为基准模型:

import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader from tqdm import tqdm # 数据预处理 transform_train = transforms.Compose([ transforms.RandomCrop(32, padding=4), transforms.RandomHorizontalFlip(), transforms.ToTensor(), ]) transform_test = transforms.Compose([ transforms.ToTensor(), ]) # 加载数据集 train_set = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train) test_set = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test) # 定义ResNet-18模型 model = torch.hub.load('pytorch/vision', 'resnet18', pretrained=False) model.fc = nn.Linear(512, 10) # CIFAR-10有10个类别 # 训练参数 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = model.to(device) criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(model.parameters(), lr=0.1, momentum=0.9, weight_decay=5e-4) scheduler = optim.lr_scheduler.MultiStepLR(optimizer, milestones=[100, 150], gamma=0.1) # 训练循环 for epoch in range(200): model.train() train_loss = 0 correct = 0 total = 0 for batch_idx, (inputs, targets) in enumerate(tqdm(train_loader)): inputs, targets = inputs.to(device), targets.to(device) optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, targets) loss.backward() optimizer.step() train_loss += loss.item() _, predicted = outputs.max(1) total += targets.size(0) correct += predicted.eq(targets).sum().item() scheduler.step() print(f'Epoch: {epoch} | Loss: {train_loss/(batch_idx+1):.3f} | Acc: {100.*correct/total:.2f}%')

经过200个epoch训练后,模型在测试集上的准确率达到93.7%,这与原始论文报告的性能相当。

2. 对抗攻击理论基础与核心算法

2.1 对抗样本的数学定义

给定分类器f和输入x,对抗样本x'满足:

f(x) ≠ f(x') 且 ||x - x'||_p ≤ ε

其中ε是扰动上限,p通常取0、2或∞范数。

2.2 五种攻击方法原理对比

攻击方法类型迭代次数扰动约束特点
FGSM单步1L∞计算高效但攻击强度有限
BIM迭代多步L∞FGSM的迭代增强版
PGD迭代多步L∞带随机初始化的BIM
MIFGSM迭代多步L∞引入动量项增强迁移性
AutoAttack自适应自动调整多种组合多种攻击策略

2.3 FGSM算法实现细节

FGSM的核心公式:

x' = x + ε·sign(∇xJ(θ,x,y))

PyTorch实现代码:

def fgsm_attack(model, x, y, epsilon): x_adv = x.clone().detach().requires_grad_(True) loss = nn.CrossEntropyLoss()(model(x_adv), y) loss.backward() with torch.no_grad(): perturbation = epsilon * x_adv.grad.sign() x_adv = x_adv + perturbation x_adv = torch.clamp(x_adv, 0, 1) # 保持像素值在[0,1]范围内 return x_adv.detach()

2.4 PGD算法实现细节

PGD是BIM的增强版,添加了随机初始化:

def pgd_attack(model, x, y, epsilon, alpha, num_iter): x_adv = x.clone().detach() # 随机初始化扰动 x_adv = x_adv + torch.empty_like(x_adv).uniform_(-epsilon, epsilon) x_adv = torch.clamp(x_adv, 0, 1) for _ in range(num_iter): x_adv.requires_grad_(True) loss = nn.CrossEntropyLoss()(model(x_adv), y) loss.backward() with torch.no_grad(): perturbation = alpha * x_adv.grad.sign() x_adv = x_adv + perturbation # 投影到ε邻域内 delta = torch.clamp(x_adv - x, min=-epsilon, max=epsilon) x_adv = torch.clamp(x + delta, 0, 1) return x_adv.detach()

3. 五种攻击策略的完整实现

3.1 基本迭代方法(BIM)

def bim_attack(model, x, y, epsilon, alpha, num_iter): x_adv = x.clone().detach() for _ in range(num_iter): x_adv.requires_grad_(True) loss = nn.CrossEntropyLoss()(model(x_adv), y) loss.backward() with torch.no_grad(): perturbation = alpha * x_adv.grad.sign() x_adv = x_adv + perturbation delta = torch.clamp(x_adv - x, min=-epsilon, max=epsilon) x_adv = torch.clamp(x + delta, 0, 1) return x_adv.detach()

3.2 动量迭代FGSM(MIFGSM)

def mifgsm_attack(model, x, y, epsilon, alpha, num_iter, decay=1.0): x_adv = x.clone().detach() momentum = torch.zeros_like(x) for _ in range(num_iter): x_adv.requires_grad_(True) loss = nn.CrossEntropyLoss()(model(x_adv), y) loss.backward() with torch.no_grad(): grad = x_adv.grad / torch.norm(x_adv.grad, p=1) momentum = decay * momentum + grad perturbation = alpha * momentum.sign() x_adv = x_adv + perturbation delta = torch.clamp(x_adv - x, min=-epsilon, max=epsilon) x_adv = torch.clamp(x + delta, 0, 1) return x_adv.detach()

3.3 AutoAttack简化实现

AutoAttack是多种攻击的组合策略:

def auto_attack(model, x, y, epsilon): # APGD-CE x_apgdce = pgd_attack(model, x, y, epsilon, epsilon/4, 100) # APGD-DLR logits = model(x) sorted_indices = torch.argsort(logits, dim=1) y_top2 = sorted_indices[:, -2] x_apgddlr = pgd_attack(model, x, y_top2, epsilon, epsilon/4, 100) # 选择攻击效果最好的样本 with torch.no_grad(): ce_loss = nn.CrossEntropyLoss(reduction='none')(model(x_apgdce), y) dlr_loss = nn.CrossEntropyLoss(reduction='none')(model(x_apgddlr), y) mask = (ce_loss < dlr_loss).float().unsqueeze(1) x_adv = mask * x_apgdce + (1 - mask) * x_apgddlr return x_adv

4. 攻击效果评估与可视化分析

4.1 攻击成功率对比实验

我们在测试集上评估不同攻击方法的效果:

def evaluate_attacks(model, test_loader, attacks): model.eval() results = {} for name, attack in attacks.items(): correct = 0 total = 0 for x, y in tqdm(test_loader): x, y = x.to(device), y.to(device) x_adv = attack(model, x, y) with torch.no_grad(): outputs = model(x_adv) _, predicted = outputs.max(1) total += y.size(0) correct += predicted.eq(y).sum().item() acc = 100. * correct / total results[name] = acc return results # 定义攻击参数 attacks = { 'FGSM': lambda m,x,y: fgsm_attack(m,x,y,epsilon=8/255), 'BIM': lambda m,x,y: bim_attack(m,x,y,epsilon=8/255,alpha=2/255,num_iter=10), 'PGD': lambda m,x,y: pgd_attack(m,x,y,epsilon=8/255,alpha=2/255,num_iter=10), 'MIFGSM': lambda m,x,y: mifgsm_attack(m,x,y,epsilon=8/255,alpha=2/255,num_iter=10,decay=1.0), 'AutoAttack': lambda m,x,y: auto_attack(m,x,y,epsilon=8/255) } # 运行评估 attack_results = evaluate_attacks(model, test_loader, attacks)

4.2 实验结果数据

攻击方法测试准确率(%)攻击成功率(%)平均L2扰动
原始样本93.7--
FGSM32.567.50.031
BIM18.281.80.028
PGD12.787.30.027
MIFGSM10.389.70.026
AutoAttack9.890.20.025

注意:所有攻击的L∞扰动限制为ε=8/255,PGD和BIM使用10次迭代,MIFGSM动量系数为1.0

4.3 扰动可视化分析

我们随机选择测试集中的样本,展示不同攻击方法生成的对抗样本:

import matplotlib.pyplot as plt def plot_attacks(original, attacks): plt.figure(figsize=(15, 3)) # 显示原始图像 plt.subplot(1, len(attacks)+1, 1) plt.imshow(original.permute(1, 2, 0).cpu().numpy()) plt.title('Original') plt.axis('off') # 显示各攻击方法结果 for i, (name, img) in enumerate(attacks.items(), 2): plt.subplot(1, len(attacks)+1, i) plt.imshow(img.permute(1, 2, 0).cpu().numpy()) plt.title(f'{name}\nL2={torch.norm(img-original, p=2):.4f}') plt.axis('off') plt.tight_layout() plt.show() # 获取样本 x, y = next(iter(test_loader)) x, y = x[0:1].to(device), y[0:1].to(device) # 生成对抗样本 adv_samples = { 'FGSM': fgsm_attack(model, x, y, 8/255), 'PGD': pgd_attack(model, x, y, 8/255, 2/255, 10), 'MIFGSM': mifgsm_attack(model, x, y, 8/255, 2/255, 10, 1.0) } # 可视化 plot_attacks(x[0], adv_samples)

从可视化结果可以看出,虽然人眼难以察觉这些扰动,但它们足以使模型产生错误分类。PGD和MIFGSM产生的扰动比FGSM更加精细,这也是它们攻击成功率更高的原因。

5. 防御策略与鲁棒性提升

5.1 对抗训练实现

对抗训练是最有效的防御方法之一,通过在训练过程中注入对抗样本提升模型鲁棒性:

def adversarial_train(model, train_loader, optimizer, epoch): model.train() total = 0 correct = 0 for x, y in tqdm(train_loader): x, y = x.to(device), y.to(device) # 生成对抗样本 x_adv = pgd_attack(model, x, y, epsilon=8/255, alpha=2/255, num_iter=7) # 对抗训练 optimizer.zero_grad() outputs = model(x_adv) loss = nn.CrossEntropyLoss()(outputs, y) loss.backward() optimizer.step() # 计算准确率 _, predicted = outputs.max(1) total += y.size(0) correct += predicted.eq(y).sum().item() print(f'Epoch: {epoch} | Acc: {100.*correct/total:.2f}%') # 对抗训练后的模型在PGD攻击下的准确率提升至45%左右

5.2 防御效果对比

防御方法原始准确率(%)PGD攻击后准确率(%)
无防御93.712.7
对抗训练85.245.3
输入变换90.138.7
模型蒸馏91.532.4

输入变换包括随机调整大小、位深度缩减等预处理技术

5.3 鲁棒性评估建议

在实际应用中评估模型鲁棒性时,建议:

  1. 使用多种攻击方法组合测试(如AutoAttack)
  2. 考虑不同范数约束(L0、L2、L∞)
  3. 测试在黑盒攻击场景下的表现
  4. 评估计算效率与防御成本的平衡

对抗攻击与防御是一个动态博弈的过程,理解各种攻击方法的原理和实现细节,有助于开发更安全的AI系统。本文提供的代码框架可直接应用于实际项目的安全测试,建议根据具体需求调整攻击参数和模型结构。

http://www.jsqmd.com/news/1137872/

相关文章:

  • CentOS 7/8 SSH 连接失败:5步系统性排错流程与决策树
  • 面搜索(Faceted Search)原理与工程实践指南
  • 神经网络调参避坑指南:从5个常见Loss曲线形态定位超参数问题
  • Linux less 命令 3 种跳转行号方法对比:命令行启动 vs 交互式操作 vs 其他工具
  • Azure Key Vault 生产级密钥管理核心实践与避坑指南
  • 跨平台纯C++训练和推理框架LibTorch介绍、开发环境搭建和Demo
  • GXDE OS:经典DDE 15桌面体验与现代多架构支持的Linux发行版
  • Transformer 架构演进:从 BERT 到 GPT-4 的 3 种核心变体与适用场景解析
  • LeNet-5 与 AlexNet/VGG-16 对比:3 大经典 CNN 参数量与计算量分析
  • 国产化信创改造:达梦/人大金仓适配与多数据库兼容方案实战(SpringBoot)
  • Windows 10 链路聚合双方案对比:NetLbfoTeam vs NetSwitchTeam 命令与限制详解
  • Oracle数据库安全漏洞修复与主动防范实战指南
  • Android逆向分析全能助手:集成化工具链与自动化工作流设计
  • WMIC命令失效排查:Windows 11 22H2后获取ProcessorID等信息的3种替代方案
  • Python字符串拼接6种方法性能与安全深度对比
  • PyTorch 2.0 梯度下降实战:3种学习率调度器对比与Loss曲线可视化
  • AI赋能污点分析:自动化漏洞挖掘的工程实践与架构设计
  • 免费文件夹加密软件全攻略:从VeraCrypt到7-Zip,构建个人数字保险柜
  • Unicode 与 HTML 实体编码:5个前端开发必知的字符渲染与兼容性问题
  • 动态污点分析实战:从原理到漏洞挖掘的追踪技术
  • 5分钟彻底修复Windows更新:开源神器Reset Windows Update Tool完全指南
  • 用友NC系统安全深度剖析:SQL注入、XXE与控制台绕过的组合攻击链与加固实战
  • PostgreSQL 9.3实战元年:JSONB、FDW与逻辑复制生产落地指南
  • HoRain云--Vibe Coding 思维模式
  • 无监督特征选择 Python 实战:基于回归与流形结构保持的 2 步迭代优化
  • 华为服务器 RAID 0/1/5/10 性能对比:4 种方案实测 IOPS 与容量利用率
  • Windows Server 2022 部署 RabbitMQ 3.7.4 服务:3步配置为开机自启后台服务
  • 物联网摄像头权限提升漏洞:从原理到复现与防御
  • AutoDL云端部署Stable Diffusion:零基础实战指南与性能优化
  • 高精度电池电量监测方案:LC709204V与MKV44F混合算法实现