AdamW
接着 Adam 的例子:
【L2 正则化】 为了防止过拟合,我们会给登山者一个惩罚:“如果你携带的行李(权重)太多太重,我就要罚你时间(增加损失)。”
我们已经知道 Adam 是一个装备了“记忆球”和“地形感知器”的超级登山者,能又快又稳地走下山。但是,这个登山者有一个致命的缺点:他太聪明了,聪明到会“作弊”来应对惩罚。
在 Adam 的“地形感知器”里,每个方向的“灵敏度”是根据这个方向的历史梯度大小自动调整的。
- 正常情况(SGD):登山者感受到背包重了(L2惩罚),他会自觉地扔掉一些东西(权重衰减)。
- Adam 的情况:当 Adam 感受到惩罚带来的额外“重力”(正则化梯度)时,他的“地形感知器”会说:“哎呀,这个方向突然变陡了,是不是有风险?我得小心点,步子迈小点。”问题来了:这个惩罚是故意让他迈小步的,而 Adam 的自动调整却把惩罚的一部分给抵消了。结果,背包并没有真正变轻多少,惩罚的效果大打折扣。这就是 “L2正则化在Adam中不等于权重衰减”。
L2正则化的目的很简单:哪个权重特别大,就狠狠惩罚它。
在代码里,这种惩罚是通过在梯度里加一项
Adam 维护了一个“二阶矩
- 如果某个方向过去经常出现大梯度,
就大,Adam 就觉得:“这方向震荡厉害,我得小心点,步子迈小一点。” - 如果某个方向过去梯度很小,
就小,Adam 就觉得:“这方向很平缓,可以走快一点。”
这本身是一个很好的特性,能防止模型在陡峭的方向上 overshoot。
但这里就出现了矛盾:L2 惩罚的梯度 vs 自适应机制
假设有一个权重
现在你给损失函数加了 L2 正则化。对
Adam 看到这个
“天哪,这个方向的梯度还是这么大,看来真的很陡峭,我必须再小心一点,把步子再迈小一点。”
于是 Adam 会进一步降低这个方向的有效学习率。
你原本想的是:让
但 Adam 的反应是:因为更新幅度变大了,所以我要降低学习率。
结果是:
- 目标更新量 = 学习率 × 总梯度
- 总梯度确实变大了,但学习率也变小了
- 两者相乘,最后的有效更新量可能几乎没变!
也就是说,L2 正则化的惩罚信号,被 Adam 的自适应机制“识别”为需要降低学习率的信号,从而抵消了惩罚的效果。
AdamW 的做法是:不让惩罚的梯度经过自适应计算。
在 AdamW 中,更新公式变成:
最后这一项
总结
- L2 + Adam:惩罚信号被 Adam 的“自适应”机制稀释了,大权重并没有真正变小。
- AdamW:把惩罚拿出来单独做,确保大权重实实在在地被衰减。
所以 AdamW 能让模型真正变简单,泛化能力更好。