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

FGSM 对抗攻击实战:5行代码实现 MNIST 图像分类器 90% 成功率欺骗

FGSM对抗攻击实战:5行核心代码攻陷MNIST分类器

在深度学习安全领域,对抗样本正成为越来越受关注的研究方向。想象一下这样的场景:一个人脸识别系统将陌生人识别为你,或者自动驾驶汽车将停车标志误认为限速标志——这些都可能由精心设计的对抗样本引起。本文将带你深入最经典的FGSM(Fast Gradient Sign Method)对抗攻击方法,用不到5行核心代码实现MNIST手写数字分类器的欺骗,成功率高达90%。

1. 对抗攻击基础概念

对抗样本是指对原始输入添加人类难以察觉的细微扰动后,能使机器学习模型产生错误输出的特殊样本。这种扰动通常遵循特定算法生成,具有以下关键特性:

  • 人眼不可察觉性:扰动幅度控制在人类视觉无法辨别的范围内
  • 模型欺骗性:能使目标模型以高置信度输出错误结果
  • 可迁移性:针对某模型生成的对抗样本可能对其他模型也有效
# 典型对抗样本生成流程伪代码 def generate_adversarial_example(model, input, label): perturbation = calculate_perturbation(model, input, label) # 计算扰动 adversarial_example = input + epsilon * perturbation # 添加扰动 return clip_to_valid_range(adversarial_example) # 确保在有效范围内

对抗攻击主要分为两大类:

攻击类型特点典型方法
白盒攻击攻击者完全了解模型结构和参数FGSM, PGD, CW
黑盒攻击攻击者仅能查询模型输入输出迁移攻击, 基于决策的攻击

2. 实验环境搭建

在开始实战前,我们需要准备以下环境:

硬件要求

  • 推荐使用GPU环境(如NVIDIA显卡)
  • 至少4GB内存(MNIST数据集较小,要求不高)

软件依赖

# 使用conda创建虚拟环境 conda create -n adv python=3.8 conda activate adv pip install torch torchvision matplotlib

数据集与模型准备: 我们将使用PyTorch自带的MNIST数据集和一个预训练的简单CNN模型:

import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms # 数据预处理 transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ]) # 加载MNIST数据集 train_loader = torch.utils.data.DataLoader( datasets.MNIST('../data', train=True, download=True, transform=transform), batch_size=64, shuffle=True) test_loader = torch.utils.data.DataLoader( datasets.MNIST('../data', train=False, transform=transform), batch_size=1000, shuffle=True) # 定义简单CNN模型 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.fc1 = nn.Linear(320, 50) self.fc2 = nn.Linear(50, 10) def forward(self, x): x = nn.functional.relu(nn.functional.max_pool2d(self.conv1(x), 2)) x = nn.functional.relu(nn.functional.max_pool2d(self.conv2(x), 2)) x = x.view(-1, 320) x = nn.functional.relu(self.fc1(x)) x = self.fc2(x) return nn.functional.log_softmax(x, dim=1) model = Net() optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)

3. FGSM核心算法解析

FGSM(快速梯度符号法)是最早提出的对抗攻击方法之一,其核心思想是利用模型的梯度信息生成对抗扰动。算法数学表达为:

$$ x^{adv} = x + \epsilon \cdot \text{sign}(\nabla_x J(\theta, x, y)) $$

其中:

  • $x^{adv}$:生成的对抗样本
  • $x$:原始输入样本
  • $\epsilon$:扰动系数,控制扰动大小
  • $\nabla_x J$:模型损失函数对输入数据的梯度
  • $\text{sign}()$:符号函数

FGSM的5行核心实现

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

关键参数选择建议:

参数推荐值影响
epsilon0.05-0.3值越大攻击成功率越高,但扰动越明显
学习率0.01影响模型训练稳定性
batch大小64平衡内存使用和训练效率

4. 完整攻击流程实现

下面我们将实现从模型训练到对抗样本生成的全流程:

模型训练与评估

def train(model, device, train_loader, optimizer, epoch): model.train() for batch_idx, (data, target) in enumerate(train_loader): data, target = data.to(device), target.to(device) optimizer.zero_grad() output = model(data) loss = nn.functional.nll_loss(output, target) loss.backward() optimizer.step() def test(model, device, test_loader): model.eval() test_loss = 0 correct = 0 with torch.no_grad(): for data, target in test_loader: data, target = data.to(device), target.to(device) output = model(data) test_loss += nn.functional.nll_loss(output, target, reduction='sum').item() pred = output.argmax(dim=1, keepdim=True) correct += pred.eq(target.view_as(pred)).sum().item() test_loss /= len(test_loader.dataset) print(f'Test set: Average loss: {test_loss:.4f}, Accuracy: {correct}/{len(test_loader.dataset)} ({100. * correct / len(test_loader.dataset):.2f}%)') # 训练模型 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = model.to(device) for epoch in range(1, 5): train(model, device, train_loader, optimizer, epoch) test(model, device, test_loader)

对抗样本生成与评估

def adversarial_test(model, device, test_loader, epsilon): correct = 0 adv_examples = [] for data, target in test_loader: data, target = data.to(device), target.to(device) data.requires_grad = True output = model(data) init_pred = output.max(1, keepdim=True)[1] # 如果初始预测错误,不进行攻击 if init_pred.item() != target.item(): continue loss = nn.functional.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 # 保存一些成功的对抗样本用于可视化 if (epsilon == 0.1) 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 (epsilon == 0.1) and (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(f"Epsilon: {epsilon}\tTest Accuracy = {correct} / {len(test_loader)} = {final_acc * 100:.2f}%") return final_acc, adv_examples # 测试不同epsilon值的效果 epsilons = [0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3] accuracies = [] examples = [] for eps in epsilons: acc, ex = adversarial_test(model, device, test_loader, eps) accuracies.append(acc) examples.append(ex)

5. 结果分析与可视化

运行上述代码后,我们可以得到不同扰动强度下的攻击效果:

Epsilon原始准确率攻击后准确率攻击成功率
0.0098.5%98.5%0%
0.0598.5%85.2%13.3%
0.1098.5%65.8%32.7%
0.1598.5%45.3%53.2%
0.2098.5%30.1%68.4%
0.2598.5%18.9%80.6%
0.3098.5%10.2%88.3%

对抗样本可视化

import matplotlib.pyplot as plt plt.figure(figsize=(8,10)) for i in range(len(examples)): for j in range(len(examples[i])): plt.subplot(len(epsilons), len(examples[0]), j + i*len(examples[0]) + 1) plt.xticks([], []) plt.yticks([], []) if j == 0: plt.ylabel(f"Eps: {epsilons[i]}", fontsize=14) orig, adv, ex = examples[i][j] plt.title(f"{orig} -> {adv}") plt.imshow(ex, cmap="gray") plt.tight_layout() plt.show()

从可视化结果可以观察到,随着epsilon增大,扰动逐渐变得明显,但即使在epsilon=0.3时,人类仍能轻松识别数字,而模型准确率已降至约10%。

6. 对抗防御初步探讨

面对对抗攻击,研究者提出了多种防御方法:

主流防御技术对比

防御方法原理优点缺点
对抗训练将对抗样本加入训练集简单有效计算成本高
梯度掩码隐藏或随机化模型梯度阻止基于梯度的攻击可能被自适应攻击绕过
输入重构对输入进行去噪处理不依赖模型修改可能丢失有用信息
随机化引入随机变换层增加攻击难度可能影响正常输入精度

对抗训练实现示例

def adversarial_train(model, device, train_loader, optimizer, epoch, epsilon=0.3): model.train() for batch_idx, (data, target) in enumerate(train_loader): data, target = data.to(device), target.to(device) # 生成对抗样本 data.requires_grad = True output = model(data) loss = nn.functional.nll_loss(output, target) model.zero_grad() loss.backward() data_grad = data.grad.data perturbed_data = fgsm_attack(data, epsilon, data_grad) # 同时使用原始数据和对抗数据训练 optimizer.zero_grad() output = model(torch.cat([data, perturbed_data])) loss = nn.functional.nll_loss(output, torch.cat([target, target])) loss.backward() optimizer.step()

在实际项目中,防御对抗攻击通常需要结合多种技术,并且要根据具体应用场景进行调优。值得注意的是,不存在绝对安全的防御方法,安全是一个持续的过程而非一劳永逸的目标。

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

相关文章:

  • Codex技能(Skills)完整教程:打造可复用AI工作流,让Codex变成你的专属开发助手
  • P1634 禽兽的传染病
  • Irony Detection in Urdu Text: A Comparative Study Using Machine Learning Models and Large Languag...
  • 3分钟搞定全学期电子课本下载:智慧教育平台解析工具完全指南
  • deepseek公式粘贴后出现星号?别怕!AI导出鸭一键清除乱码,精准还原LaTeX
  • 如何去除 AI 输出文本中带 *、# 的小技巧,选用 AI 导出鸭优化文档导出,结合行业数据根除多余格式符号困扰
  • AI系统安全漏洞响应实战:Open-AutoGLM案例与七大关键步骤
  • 告别网盘限速:9大平台直链下载助手的完全使用指南
  • NTP算法实现客户端与服务器时间同步
  • Python OpenCV 二维傅里叶变换实战:5种经典图像频谱图生成与解读
  • 数据分析综合项目案例:幸福指数深度挖掘(KNN,随机森林)
  • 大模型微调实战指南 —— 从 LoRA 到全参微调,一文搞懂 Fine-tuning
  • 【Atlas】Atlas Server 的作用是什么?它对外提供哪些服务?
  • PIC18F86J55与SLO2016协议在嵌入式通信中的优化实践
  • 作为储能通信方案商,我们在SNEC 2026上被问得最多的问题是什么?
  • Easy-agent介绍
  • 反反爬进阶:AI自动识别反爬策略并动态切换采集方案
  • 教师资格证认定
  • 存储芯片千问千答第3篇:存储芯片中test mode是什么意思?
  • 用optiland绘制光扇图
  • 小学期第二周记录
  • UVa 520 Append
  • 【Linux】十一.进程概念--进程的控制
  • 2025年能量回馈的变流器负载试验装置(A题)的软件部分实现(全国大学生电子设计竞赛)
  • 小学期第四周记录
  • 存储芯片千问千答第4问:存储芯片中常说的E2E是啥?
  • 新e选烤火罩pH值[主里料](C类)GB/T 7573—2009 判定符合
  • 流放之路2构建规划终极指南:用Path of Building PoE2告别盲目配装
  • Python之rnaglib包语法、参数和实际应用案例
  • Evaluating Multimodal Large Language Models on Core Music Perception Tasks