第六章 · 常见防御方法与失败原因
第六章 · 常见防御方法与失败原因:为什么大多数防御都“看起来有效,实际上没用”
对抗攻击研究发展十余年,防御技术也提出过数百种,但绝大部分最终都被证明“无效”或“可轻易绕过”。
尤其是许多论文提出的防御方法:
- 初看非常强大
- 实验效果似乎很好
- 简单攻击(FGSM/PGD)都被“挡住了”
但只要使用稍微强一点的攻击(C&W、AutoAttack、EOT),
就会立即崩溃。
本章系统讲解防御方法为何失败、失败机制是什么,以及真实有效的防御到底有多难。
1. 最常见的防御类型(以及它们为什么大多无效)
从技术角度,防御方法大致分为以下几类:
- 输入预处理类
- 去噪(Gaussian blur)
- JPEG 压缩
- 缩放、平滑
- bit-depth reduction
- 随机增强(randomization)
- 模型结构类
- 使用非线性层
- 激活函数裁剪
- 特征压缩/降维
- 梯度干扰类
- 对输入加入非可导操作
- 随机 mask
- 破坏梯度流动
- 检测类
- 用另一模型检测对抗样本
- 鲁棒训练类
- 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)的本质
绝大多数失败的防御都属于这种现象:
防御方法不是提高模型鲁棒性,而是让攻击者算不到正确梯度。
典型表现:
- FGSM 成功率低
- PGD 成功率低
- C&W 成功率突然高
- 黑盒攻击也成功
- AutoAttack 一击必杀
- 干净样本精度下降
梯度遮蔽包括:
- 梯度消失(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)
流程:
- 用 PGD 生成对当前模型最强的对抗样本
- 在训练中加入对抗样本
- 优化:
[ \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. 总结:为什么防御难?
深度模型极其脆弱,原因包括:
- 高维空间局部线性化
- 梯度极其敏感
- 决策边界过于复杂和稠密
- 模型学习的“非鲁棒特征”多
- 自然精度与鲁棒性存在 trade-off
导致目前的结论是:
真正有效的防御只有少数几类(尤其是对抗训练),且代价高昂;
其他大部分防御看起来有效,但实际上都是梯度遮蔽。
这也是为什么 AI 安全是一个持续困难、但必须深入研究的领域。