halo 的技术博客

返回

因子模型上线后最尴尬的一幕:回测里 IC 漂亮,实盘里因子值却天天”抽风”。原因往往不是模型错了,而是输入特征被噪声污染了——盘口跳动、陈旧报价、复权误差、甚至一笔错单 tick,都会让本应平稳的因子值瞬间抖一下,排名随之重排,信号跟着反转。

对抗训练(adversarial training)是深度学习里对抗这类扰动的经典武器。本文用 numpy 从零实现它,并做一个诚实的对照实验:看看在量化这种表格型、低频、平滑的特征上,它到底有多大用。剧透:有用于稳定,但远没有图像领域那么神。所有图表都是真实计算的,非占位图。

一、什么是对抗样本:在特征上施加”最坏情况噪声”#

对样本 x 和损失 L(θ, x, y),对抗扰动就是找一个在 ε 球内、让损失最大δ

δ* = argmax_{||δ||∞ ≤ ε} L(θ, x + δ, y)
text

最常用的两种构造:

  • FGSM(快速梯度符号法):一步到位,δ = ε·sign(∇_x L)。便宜但粗糙。
  • PGD(投影梯度下降):多步迭代、每步投影回 ε 球,是更强的攻击,也是鲁棒训练的事实标准。

注意 PGD 里那句 np.clip(Xa, X - eps, X + eps)——它把扰动每步都投影回 ε 球。漏掉这步,攻击就会一路漂走、变得不真实,这也是很多”复现翻车”的根源。

二、Min-Max 训练:在最坏样本上优化#

对抗训练把目标写成极小极大:

min_θ  E_{(x,y)} [ max_{||δ||∞ ≤ ε} L(θ, x+δ, y) ]
text

外层的”max”用 PGD 求近似对手样本,内层的”min”在这些更难的样本上做普通梯度下降。下面是完整可跑的 numpy 实现:

三、对照实验:诚实报数#

我们造 20 维合成因子特征,训练两个完全相同的逻辑回归:一个标准训练(eps=0),一个对抗训练(eps=0.1, PGD 7 步),然后在干净样本和 PGD 攻击样本上分别测准确率。先看二维决策边界的直观差异——鲁棒模型的边界更平滑:

标准训练 vs 对抗训练的决策边界

结果如下(全部为单次实验的真实数值):

指标标准模型对抗训练模型
干净准确率96.4%93.4%
ε=0.1 攻击下准确率75.0%77.6%
ε=0.1 攻击成功率28.0%24.3%
权重 L2 范数 ‖w‖1.7571.503

把攻击强度从 0 扫到 0.15,鲁棒模型的准确率全程压在标准模型之上

扰动越大,标准模型越容易崩;对抗训练扛得住

在 ε=0.1 这一档,攻击成功率从标准模型的 28.0% 降到鲁棒模型的 24.3%:

同一强度攻击下,标准模型被攻破的比例

四、机制:对抗训练本质是隐式正则化#

为什么鲁棒模型更抗造?看最后一行的权重范数——对抗训练把 ‖w‖1.757 压到 1.503(降 14.4%)。权重变小 → 输出曲面更平坦 → 同样的输入扰动引起的输出变化更小。换句话说,对抗训练在这里主要是一个正则化器,和 L2 惩罚干的是同一类事,只是它针对的是”最坏情况方向”而非整体幅度。

对抗训练把因子权重压低 14.4%

norm_std = np.linalg.norm(w_std)   # 1.757
norm_rob = np.linalg.norm(w_rob)   # 1.503
print((1 - norm_rob/norm_std)*100) # 14.4%
python

五、最该记住的洞察:表格金融数据 ≠ 图像#

本文刻意没有夸大效果,因为这里有一个对量化读者极其重要的真相:对抗训练在图像上能制造”断崖式”脆弱(标准 CNN 准确率从 95% 掉到 0%),在平滑的表格型金融特征上却几乎不会出现。

原因有三:

  1. 特征低频平滑。 收益率、估值、动量这类因子是连续、低频的,模型曲面本就温和,没有图像里逐像素的高频跳变。
  2. 样本相对充足、模型欠容量。 当数据够多、模型没过拟合时,边界天然不锋利,小扰动翻不动车。
  3. 扰动尺度难定义。 图像里 ε=8/255 是肉眼不可辨的物理意义;金融特征的单位各异,ε 该取多大没有天然答案,取错了要么无效、要么把信号也抹平。

所以如果你指望”加一层对抗训练就让因子刀枪不入”,大概率会失望。我们实验里干净准确率反而掉了 3 个点,攻击下的提升也只有几个百分点——这正是该有的诚实结论。

六、那它到底有什么用?(实用建议)#

虽然当不成银弹,对抗训练在量化里仍有三个真实价值:

  • 稳定性先验,而非攻击防御。 把它当成”让因子曲面更平”的正则项,换来更稳的因子值与排名,减少实盘的 signal flicker。
  • 最坏情况风险上界。 训练时显式考虑 ε 邻域内的最坏损失,等于给模型的脆弱性划了一条可见红线,便于风控定价。
  • 校准 ε 到真实噪声。 ε 应约等于你特征里真实存在的微观结构噪声量级(可由同标的多源报价差异估计),而不是随便拍。

配套手段往往比单用对抗训练更划算:对特征做 winsorize/中值滤波去脉冲、用 bagging/集成稀释单模型敏感方向、对因子值做滚动 z-score 截断。把对抗训练当作这套稳定化组合里的一块,而不是救命稻草。

七、诚实的边界#

  • 会牺牲干净性能。 实验里 96.4%→93.4%,这是 min-max 的固有代价,务必在验证集上权衡。
  • 外部攻击在金融里罕见。 多数”扰动”来自噪声而非对手,所以收益上限本就有限;别为防黑客而过度正则化。
  • PGD 很贵。 每步训练要多遍前向+反向,因子维度高、样本大时成本显著,可用 FGSM 或免费对抗(Free AT)近似。
  • 标签噪声会放大脆弱性。 当 y 本身含噪,对抗训练可能去拟合噪声方向,建议先净化标签再上对抗。

小结#

对抗训练给因子模型加的不是”噪声免疫力”的魔法,而是一种对最坏情况的显式谨慎:它把权重压平 14.4%,换来攻击下略高几个点的稳健,代价是干净性能小幅回落。在平滑的表格金融特征上,它的角色是正则化器与风险上界,而非攻防银弹。真正该做的,是把它放进”去噪 + 集成 + 截断”的稳定化工具箱,并用真实的微观结构噪声量级去标定 ε。


本文所有图表与指标均由 numpy 从零模拟计算生成,FGSM/PGD 与训练代码可直接复现。

对抗训练鲁棒因子:用 FGSM/PGD 给预测模型加噪声免疫力
https://blog.halo26812.eu.org/blog/adversarial-robust-factor-training
Author halo
Published at 2026年8月28日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨