第六章 · 常见防御方法与失败原因:为什么大多数防御都“看起来有效,实际上没用”

对抗攻击研究发展十余年,防御技术也提出过数百种,但绝大部分最终都被证明“无效”或“可轻易绕过”。
尤其是许多论文提出的防御方法:

  • 初看非常强大
  • 实验效果似乎很好
  • 简单攻击(FGSM/PGD)都被“挡住了”

但只要使用稍微强一点的攻击(C&W、AutoAttack、EOT),
就会立即崩溃

本章系统讲解防御方法为何失败、失败机制是什么,以及真实有效的防御到底有多难。


1. 最常见的防御类型(以及它们为什么大多无效)

从技术角度,防御方法大致分为以下几类:

  1. 输入预处理类
    • 去噪(Gaussian blur)
    • JPEG 压缩
    • 缩放、平滑
    • bit-depth reduction
    • 随机增强(randomization)
  2. 模型结构类
    • 使用非线性层
    • 激活函数裁剪
    • 特征压缩/降维
  3. 梯度干扰类
    • 对输入加入非可导操作
    • 随机 mask
    • 破坏梯度流动
  4. 检测类
    • 用另一模型检测对抗样本
  5. 鲁棒训练类
    • FGSM 训练
    • PGD 训练
    • TRADES、MART 等(后面会细讲)

其中 前三类(预处理/结构/梯度干扰)几乎全部被证明无效
主要原因是:它们不是在增强模型的真实鲁棒性,而是在隐藏梯度

下面我们分别分析。


2. 输入预处理防御为什么失败?

这类方法通常对输入做一定变换:

  • 去噪
  • 平滑
  • JPEG 压缩
  • 随机裁剪、旋转
  • 缩放后再插值
  • 颜色量化

它们能对抗 FGSM/BIM 等简单攻击,是因为:

攻击假设输入是固定的,但预处理让输入“变形”了。

然而,这类方法都有一个共同弱点:

2.1 攻击者可以把预处理纳入攻击流程

最典型方法:EOT(Expectation Over Transformation)

攻击者计算:

[ \nabla_x \mathbb{E}_{t \sim T}[L(f(t(x)), y)] ]

即对多次随机变换求期望。

这样攻击能在预处理后仍然有效。

因此预处理没有本质防御能力。


3. 模型结构类防御:改变网络让梯度“不好用”

例如:

  • 使用不可导激活(如 hard-threshold)
  • 使用 saturated activation(让梯度消失)
  • 加入 random layer
  • 加入噪声层

它们确实让 FGSM/PGD 无法找到有效梯度

但问题在于:

3.1 攻击改用黑盒估计梯度再次成功

NES、ZOO 等黑盒攻击能在没有梯度的情况下逼近梯度:

[ \nabla_x L \approx \frac{1}{m}\sum L(x + \sigma u_i)u_i ]

因此这种“坏梯度”的防御只阻止了一阶攻击,但无法阻止黑盒攻击。

3.2 不可导操作仍可用可导近似替代

攻击者可以使用可导 surrogate 模型。

3.3 结构类防御往往破坏模型精度

这类防御往往会让模型:

  • 标准精度下降
  • 前向传播变得不稳定
  • 表达能力下降

因此目前已经被放弃。


4. 梯度遮蔽(Gradient Masking)的本质

绝大多数失败的防御都属于这种现象:

防御方法不是提高模型鲁棒性,而是让攻击者算不到正确梯度。

典型表现:

  1. FGSM 成功率低
  2. PGD 成功率低
  3. C&W 成功率突然高
  4. 黑盒攻击也成功
  5. AutoAttack 一击必杀
  6. 干净样本精度下降

梯度遮蔽包括:

  • 梯度消失(vanishing)
  • 梯度爆炸(exploding)
  • 不可导操作(nondifferentiable)
  • 随机性(randomization)
  • 输入离散化(quantization)
  • 激活函数饱和(saturation)

这种防御会在简单攻击下“看起来很强”,但实际上毫无意义。

论文《Obfuscated Gradients Give a False Sense of Security》系统阐述了这一点。


5. 检测类防御:为什么失败?

许多论文尝试训练一个模型检测“对抗样本”。

它们常见失败原因:

5.1 对抗样本分布与自然分布重叠

对抗样本没有稳定特征,攻击者可以学习如何绕过检测器。

5.2 检测器本身可被攻击

攻击目标变成:

[ \text{让分类器误判 + 让检测器认为是自然样本} ]

攻击将两者一起优化即可。

5.3 特征空间不稳定

不同模型、不同攻击、不同口径下的对抗样本特征完全不同。

使得检测器无法泛化。

因此检测类防御目前并未被认为可靠。


6. 只有对抗训练(Adversarial Training)被证明有效,但代价巨大

现阶段唯一能显著提升鲁棒性的防御是:

PGD-based 对抗训练 + 变体(TRADES/MART)

流程:

  1. 用 PGD 生成对当前模型最强的对抗样本
  2. 在训练中加入对抗样本
  3. 优化:

[ \min_\theta \mathbb{E} L(f_\theta(x), y) + \lambda L(f_\theta(x+\delta), y) ]

对抗训练经过大量验证后被认为:

  • 能有效提升鲁棒性
  • 能抵抗多数一阶攻击
  • 在工业界也可落地

但是,它的问题也非常严重:

6.1 极度昂贵

每个 batch 都要跑 PGD,代价至少是:

训练成本 × 20~50 倍

对大模型几乎无法承受。

6.2 降低标准精度

鲁棒模型通常:

  • 自然精度下降 2%~10%
  • 高维数据下降更明显
  • 小模型下降更严重

6.3 难以对抗非梯度攻击

对抗训练主要对梯度攻击有效,对:

  • HSJ
  • Square
  • 物理攻击
  • LPIPS Attack

仍然存在脆弱性。

因此,尽管对抗训练是最强防御,但依然无法全面解决问题。


7. 现实世界中真正有用的防御策略是什么?

工业界逐渐形成共识:

1. 威胁模型限定(Threat Model Constraint)

明确攻击者能力:

  • 能否访问 logits?
  • 能否访问梯度?
  • query 限制?
  • perturbation 空间?

限制攻击者能力是最实际的防御。


2. 输入检查(Sanity Check)

并不是检测对抗样本,而是:

  • 分布偏移(OOD)
  • 不自然输入
  • 恶意 query 行为(多次微调输入)
  • 随机重复查询检测

这属于 MLOps 层面的“反滥用”机制。


3. 模型集成(Ensemble)

多模型结构使得攻击者更难对特定模型优化扰动。


4. 差分对抗训练(Ensemble Adversarial Training)

利用多个模型生成对抗样本参与训练,提升迁移鲁棒性。


5. 防止查询攻击(query limiting)

限制:

  • 单 IP 查询速率
  • 每个输入的变化幅度
  • 总查询次数

能有效降低黑盒攻击成功率。


6. 对抗训练(唯一真正有效的模型级方法)

如 PGD/FreeLB/TRADES/MART。


8. 总结:为什么防御难?

深度模型极其脆弱,原因包括:

  1. 高维空间局部线性化
  2. 梯度极其敏感
  3. 决策边界过于复杂和稠密
  4. 模型学习的“非鲁棒特征”多
  5. 自然精度与鲁棒性存在 trade-off

导致目前的结论是:

真正有效的防御只有少数几类(尤其是对抗训练),且代价高昂;
其他大部分防御看起来有效,但实际上都是梯度遮蔽。

这也是为什么 AI 安全是一个持续困难、但必须深入研究的领域。