4、优化器选择(上):SGD与Momentum的原理与适用场景、Adam与AdamW的对比

说到优化器,很多同学上来就无脑用Adam。我刚开始做模型调优时也这样,觉得Adam省心、收敛快。但后来踩了不少坑才发现——选不对优化器,模型精度可能直接掉几个点。今天咱们就把SGD、Momentum、Adam和AdamW这几个主流优化器掰开揉碎讲清楚。

4.1 SGD:最朴素的梯度下降

SGD(随机梯度下降)是所有优化器的老祖宗。它的思想很简单:沿着梯度反方向走一步。

公式长这样:

θ = θ - η * ∇θ J(θ)

其中η是学习率,∇θ J(θ)是损失函数对参数的梯度。

听起来很合理对吧?但实际用起来问题不少。我印象最深的一次,训练一个图像分类模型,SGD跑了200个epoch还没收敛。为什么?因为SGD在峡谷地形里会来回震荡——梯度指向最优解的方向分量小,垂直方向的分量大,参数就在山谷两边来回跳,就是下不去。

SGD的核心特点:

  • 每次更新只依赖当前batch的梯度,随机性强
  • 容易跳出局部极小点(因为噪声大)
  • 但收敛慢,尤其在病态曲面上
  • 对学习率非常敏感

我的经验:SGD适合数据量极大、需要精细调优的场景。比如在CV领域做迁移学习,用SGD微调往往比Adam效果好。但前提是你得把学习率、动量、权重衰减这些超参数调好。

4.2 Momentum:给梯度加上惯性

为了解决SGD震荡的问题,Momentum(动量)引入了速度累积的概念。说白了就是:如果梯度方向一直朝一个方向走,那就加速;如果方向来回变,那就减速。

公式:

v = γ * v + η * ∇θ J(θ)
θ = θ - v

γ是动量系数,通常取0.9。v是累积的速度。

你可以想象一个小球从山坡上滚下来——它不会因为遇到一个小坑就停下来,而是靠着惯性冲过去。这就是Momentum的精髓。

我曾经在训练一个NLP模型时,用SGD死活不收敛,换成Momentum后,50个epoch就达到了SGD 200个epoch的效果。差别就这么大。

注意:动量不是越大越好。γ=0.99时,模型可能冲过头,在最优解附近震荡。我一般从0.9开始调,效果不好再试0.95或0.99。

4.3 Adam:自适应学习率的集大成者

Adam结合了Momentum和RMSProp的思想——既考虑梯度的一阶矩(动量),又考虑二阶矩(自适应学习率)。

它的核心公式:

m = β1 * m + (1-β1) * g          # 一阶矩估计
v = β2 * v + (1-β2) * g²         # 二阶矩估计
m_hat = m / (1 - β1^t)           # 偏差修正
v_hat = v / (1 - β2^t)
θ = θ - η * m_hat / (√v_hat + ε)

Adam为什么受欢迎?因为它对超参数不敏感。默认的β1=0.9、β2=0.999、ε=1e-8,在很多任务上都能直接跑出不错的结果。

但Adam有个问题——泛化能力不如SGD。我在做图像分类比赛时发现,Adam在训练集上loss降得很快,但验证集精度就是上不去。换成SGD+Momentum后,验证集精度反而高了1-2个点。

为什么会这样?学术界有几种解释:

  • Adam的自适应学习率导致权重更新过于激进,容易陷入尖锐的局部极小点
  • SGD的随机性更强,能找到更平坦的最优解,泛化更好
  • Adam对权重衰减的处理方式有问题(这点下面细说)

4.4 AdamW:修复Adam的权重衰减问题

AdamW是Adam的改进版,主要改了权重衰减(Weight Decay)的实现方式。

在Adam中,权重衰减是这么做的:

# Adam的权重衰减(错误方式)
g = ∇θ J(θ) + λ * θ           # 把权重衰减加到梯度里
m = β1 * m + (1-β1) * g
v = β2 * v + (1-β2) * g²
θ = θ - η * m_hat / (√v_hat + ε)

而AdamW把权重衰减从梯度计算中分离出来:

# AdamW的权重衰减(正确方式)
g = ∇θ J(θ)                    # 先算原始梯度
m = β1 * m + (1-β1) * g
v = β2 * v + (1-β2) * g²
θ = θ - η * (m_hat / (√v_hat + ε) + λ * θ)  # 权重衰减单独加

区别在哪?Adam把权重衰减和梯度混在一起,导致自适应学习率对权重衰减也做了缩放——这其实是不对的。AdamW把两者分开,让权重衰减不受学习率自适应的影响。

我在实际项目中发现,AdamW在大规模预训练模型上效果明显优于Adam。比如训练BERT、GPT这类模型,用AdamW几乎成了标配。

4.5 四者对比一览

优化器 核心思想 适用场景 优点 缺点
SGD 纯梯度下降 数据量大、需要精细调优 泛化好、理论成熟 收敛慢、对学习率敏感
Momentum 梯度累积+惯性 有震荡的优化问题 加速收敛、抑制震荡 可能冲过头
Adam 动量+自适应学习率 快速原型、NLP任务 收敛快、超参数鲁棒 泛化差、权重衰减有bug
AdamW Adam+正确权重衰减 大规模预训练、CV 泛化好、权重衰减有效 计算量略大

4.6 我的选择建议

说了这么多,到底该用哪个?我个人的经验是:

  • 快速验证想法:用Adam,默认参数就行
  • 做CV比赛或产品:用SGD+Momentum,花时间调学习率和动量
  • 训练大模型(BERT/GPT等):用AdamW,权重衰减设0.01
  • 迁移学习微调:SGD+Momentum往往比Adam好

避坑指南:我曾经在一个推荐系统项目里,用Adam训了3天,线上A/B测试效果还不如老模型。换成SGD+Momentum后,AUC提升了0.8%。后来分析发现,Adam把模型推到了一个尖锐的极小点,泛化能力差。所以——别迷信Adam,该用SGD时别犹豫。

4.7 知识体系图

下面这张图帮你理清四个优化器的关系:

优化器选择知识体系 优化器 SGD Momentum Adam AdamW 特性 纯梯度下降 泛化好 收敛慢 特性 梯度累积+惯性 加速收敛 抑制震荡 特性 动量+自适应LR 收敛快 泛化差 特性 正确权重衰减 泛化好 大模型标配 适用场景速查 SGD:数据量大 精细调优 Momentum: 震荡问题 Adam:快速原型 NLP任务 AdamW:大模型 迁移学习

嗯,优化器选择这块,说白了就是在收敛速度和泛化能力之间做权衡。Adam快但可能泛化差,SGD慢但泛化好。AdamW算是目前比较好的折中方案。

下一节咱们聊聊学习率调度和权重初始化,这两个跟优化器配合好了,效果能再上一个台阶。

可可精品资料库