尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

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

FGSM 对抗攻击实战:5行代码实现 MNIST 图像分类器 90% 成功率欺骗
📅 发布时间:2026/7/5 15:31:55

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()

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

相关新闻

  • 如何去除 AI 输出文本中带 *、# 的小技巧,选用 AI 导出鸭优化文档导出,结合行业数据根除多余格式符号困扰
  • Python OpenCV 二维傅里叶变换实战:5种经典图像频谱图生成与解读
  • 大模型微调实战指南 —— 从 LoRA 到全参微调,一文搞懂 Fine-tuning

最新新闻

  • Ascend C uint8转half函数文档
  • rawpy错误处理:全面解析LibRawError异常体系与调试技巧
  • 终极Gamdl技术架构深度解析:构建高效的Apple Music下载流水线
  • Andromeda Web API详解:Canvas、Crypto与SQLite集成
  • 如何用离线OCR工具在3分钟内完成图片文字提取?
  • KMX63与PIC18LF25K40硬件协同与自然交互实现

日新闻

  • 基于YOLOv12的番茄成熟度智能检测系统开发
  • 终极RimWorld模组管理指南:用RimSort告别模组冲突烦恼
  • AI Agent框架开发:从理论到实践的完整指南

周新闻

  • 基于YOLOv12的番茄成熟度智能检测系统开发
  • 终极RimWorld模组管理指南:用RimSort告别模组冲突烦恼
  • AI Agent框架开发:从理论到实践的完整指南

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号