导读:本期聚焦于IT小魔仙创作的《对抗训练为什么能有效防御对抗样本?FGSM与PGD实现解析》,敬请观看详情。如果把一张正常图片加入人眼几乎无法察觉的噪声,神经网络就可能以极高置信度给出错误分类,这种被精心构造的输入就是对抗样本。对抗训练的核心做法是在每轮训练中动态生成对抗扰动并加入原始样本,强制模型在扰动边界内保持稳定预测。FGSM利用梯度符号做单步扰动,计算快但防御能力有限;PGD采用多次小步迭代并投影回约束球体,能逼近更强的局部最坏扰动。训练过程中相当于求解一个min-max问题,内层寻找最大损失扰动,外层最小化该损失。实际落地时需要平衡训练开销、干净样本精度与鲁棒精度,常配合早停、标签平滑、混合训练等稳定策略。本文结合PyTorch代码拆解对抗训练流程,讨论步长、扰动半径和迭代次数对最终防御效果的影响。

把一张正常图片加入人眼几乎无法察觉的噪声,神经网络就可能以极高置信度给出错误分类。这种被精心构造的输入称为对抗样本,而对抗训练正是针对这一现象的正则化手段。它的思路并不复杂:既然模型会因微小扰动而犯错,那就把这些扰动直接放进训练集,让模型在训练阶段学会抵抗它们。与普通随机噪声增强不同,对抗扰动不是随机撒在图像上,而是沿着损失函数的梯度方向专门生成,能够更准确地暴露模型决策边界上的薄弱位置。

对抗训练为什么能有效防御对抗样本?FGSM与PGD实现解析

对抗训练要解决的min-max问题

对抗训练的形式化目标可以写成一个min-max优化问题:

min θ E(x,y)[max δ∈S L(fθ(x+δ), y)]

这里的θ表示模型参数,x是原始输入,y是真实标签,δ是对抗扰动,S是扰动的约束集合。内层的max负责在当前模型参数下寻找一个损失最大的扰动,也就是让模型预测错误最严重的对抗样本;外层的min则要求模型参数优化,使得即便输入被施加了这种最坏扰动,损失也能被控制在较低水平。这个结构决定了对抗训练不是简单地增加数据量,而是不断在模型最脆弱的位置做针对性修正。

通常S会选择L∞球,即限制每个像素点的最大偏移不超过ε。这样做的原因有两个:一是L∞约束容易投射到图像像素范围,计算相对简单;二是它能保证扰动在视觉上难以察觉。如果只使用普通的高斯噪声或随机裁剪,模型学到的可能只是在随机波动下保持稳定,而对抗训练要求模型在一个紧致的局部区域中输出不变,这种约束更严格,也更能刻画决策边界与数据流形之间的距离。

当ε设置得过大时,对抗训练会使模型倾向于记住强扰动样本,干净样本精度可能明显下降;当ε过小时,训练出的模型又难以防御实际攻击。因此在实际实现中,ε通常表示为图像像素范围的较小比例,例如将像素归一化到0到1后取8/255作为默认扰动半径。

FGSM与PGD:两种常用攻击生成方式

内层最大化问题的求解方式直接决定了对抗训练的效果和计算成本。FGSM是单步方法,它只沿着损失函数关于输入的梯度方向走一步:

def fgsm_attack(model, x, y, epsilon):
    x.requires_grad_(True)
    loss = nn.CrossEntropyLoss()(model(x), y)
    grad = torch.autograd.grad(loss, x)[0]
    delta = epsilon * grad.sign()
    return x + delta

FGSM的优势在于速度极快,每一步训练只需要额外一次前向和反向传播。它假设损失函数在输入附近是近似线性的,因此梯度符号能够代表最坏扰动方向。但对于深度非线性网络来说,这个假设常常不成立,单步攻击容易低估真实的最坏损失,模型经过FGSM对抗训练后可能只对FGSM攻击鲁棒,在面对多步迭代攻击时仍然脆弱。

PGD则把内层求解扩展为多次小步迭代。它的核心是每一步都沿梯度方向移动,然后把扰动投影回允许范围内,确保最终对抗样本始终落在x附近:

def pgd_attack(model, x, y, epsilon, alpha, steps):
    x_adv = x.clone().detach()
    for _ in range(steps):
        x_adv.requires_grad_(True)
        loss = nn.CrossEntropyLoss()(model(x_adv), y)
        grad = torch.autograd.grad(loss, x_adv)[0]
        x_adv = x_adv.detach() + alpha * grad.sign()
        delta = torch.clamp(x_adv - x, min=-epsilon, max=epsilon)
        x_adv = torch.clamp(x + delta, min=0, max=1)
    return x_adv

每次迭代的步长α通常设置为ε的1/4或更小,迭代步数常取10步。投影操作可以通过两层clamp实现:第一层保证扰动每个分量不超过±ε,第二层保证最终图像像素值仍然在合法范围内。PGD并不是保证找到全局最坏扰动,但在经验上它能够稳定逼近一个较强的局部扰动,因此使用PGD对抗训练得到的模型通常比FGSM训练具有更可靠的鲁棒性。

从训练信号的角度看,FGSM相当于用当前模型附近线性近似下的最坏点来更新参数,而PGD则尽可能去逼近真实的最坏点。虽然PGD训练开销显著增大,但它减少了模型利用虚假鲁棒性通过梯度掩蔽欺骗单步攻击的可能性。

PyTorch中的对抗训练实现

将PGD集成到标准训练循环中并不复杂,核心是在每一轮前向传播之前先把普通样本替换成对抗样本。以下是一个简化版的训练步骤:

for images, labels in train_loader:
    images, labels = images.to(device), labels.to(device)
    adv_images = pgd_attack(model, images, labels,
                             epsilon=8.0 / 255,
                             alpha=2.0 / 255,
                             steps=10)
    optimizer.zero_grad()
    outputs = model(adv_images)
    loss = criterion(outputs, labels)
    loss.backward()
    optimizer.step()

这里先调用pgd_attack生成对抗样本,再把对抗样本输入模型计算损失。注意pgd_attack内部多次调用模型并获取梯度,这些梯度仅用于构造扰动,不参与参数更新。训练循环中的optimizer.zero_grad放在攻击之后,可以避免攻击过程中产生的梯度污染模型参数的累积梯度。

在更完整的实现中,可以在每个epoch开始时随机初始化对抗样本,例如在原始样本上加入均匀分布的小扰动,再执行PGD迭代。这个随机初始化有助于防止多步攻击在每次训练中都收敛到相同的局部最坏点,从而提升模型的泛化防御能力。也可以混合一定比例的干净样本与对抗样本共同训练,或对干净样本和对抗样本分别计算损失后加权求和。

训练开销、精度权衡与调优实践

对抗训练最明显的代价是计算量。PGD每生成一个对抗样本都要执行steps次前向和反向传播,假设steps为10,训练时间大约会变为普通训练的10倍。对于图像分类任务,这会让原本数小时的训练延长到一天以上。缓解方法包括:只在部分训练阶段开启对抗训练、使用更小的steps进行预热、在分布式训练中把对抗样本生成分散到不同设备上,或采用更高效的近似攻击作为训练信号。

另一个需要接受的现实是干净精度与鲁棒精度之间的权衡。强化对抗训练后,模型在未扰动测试集上的准确率通常会下降几个百分点,但在对抗攻击下准确率会显著提升。这种权衡并不是绝对的,可以通过更宽的网络、标签平滑、MixUp或CutMix等数据增强来减轻。训练过程中应同时监控干净验证集和对抗验证集指标,当对抗精度开始下降时考虑早停或降低扰动半径。

评估模型鲁棒性时不要只用FGSM或训练时使用的相同攻击。因为有些模型会通过让梯度变得不连续或饱和来制造梯度掩蔽,使得基于梯度的攻击难以找到有效扰动,但面对CW攻击或自适应攻击时仍然脆弱。合理的方式是使用多步PGD、随机重启PGD,以及尽可能与威胁模型匹配的攻击参数进行测试。只有在这种多角度评估下仍能保持稳定表现的模型,才具备实际部署条件下的对抗鲁棒性。

对抗训练对抗样本模型鲁棒性修改时间:2026-08-24 08:13:59

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。