为什么Adam优化器比SGD收敛更快:自适应学习率与动量结合
1. 理解核心差异:SGD与Adam的起点不同
首先,要明白两者解决的问题相同:寻找一个函数的最小值点(如神经网络的损失函数)。区别在于“下山”的策略。
- SGD(随机梯度下降) 像一个固执的登山者。他只看脚下最陡的方向(当前梯度),然后迈出固定大小的一步(学习率
η)。如果地形平坦,他走得慢;如果地形陡峭,他可能步子太大,直接冲过头。 - Adam 像一个聪明的导航者。他不仅看当前最陡方向,还参考了之前路径的记忆(动量),并且携带了一个自动调节步伐大小的智能设备(自适应学习率)。
这个根本区别导致了收敛速度的差异。
2. 剖析SGD的更新规则:简单但“一根筋”
SGD的更新公式非常直观:
$$θ_{t+1} = θ_t - η * ∇J(θ_t)$$
其中,$θ$ 是模型参数,$η$ 是固定的学习率,$∇J(θ_t)$ 是损失函数在参数 $θ_t$ 处的梯度(最陡下降方向)。
具体执行步骤:
- 计算 当前参数 $θ_t$ 对应的损失函数的梯度 $∇J(θ_t)$。
- 用 当前梯度乘以一个固定的步长(学习率
$η$)。 - 将 计算出的结果从当前参数中减去,得到新参数 $θ_{t+1}$。
其局限性在于:
- 学习率是全局的:所有参数共享同一个
$η$。然而,模型中不同参数的梯度尺度可能天差地别(有的参数更新快,有的慢),固定学习率无法兼顾。 - 没有惯性:每次更新只取决于当前梯度,容易在陡峭的维度上震荡,在平缓的维度上停滞。
3. 深入Adam的更新规则:自适应与动量的精妙结合
Adam(Adaptive Moment Estimation)的核心思想是同时估计梯度的“均值”(一阶矩)和“未中心化的方差”(二阶矩),并用它们来归一化学习率。
它的更新过程分为三步,我会用公式和文字结合说明。
第一步:计算梯度的“动量”和“方差”的移动平均。
Adam为每个参数维护两个状态变量:
$m_t$:梯度的指数移动平均(一阶矩估计),代表动量。$v_t$:梯度平方的指数移动平均(二阶矩估计),代表自适应学习率的基础。
它们的更新规则如下:
$$m_t = β_1 * m_{t-1} + (1 - β_1) * ∇J(θ_t)$$
$$v_t = β_2 * v_{t-1} + (1 - β_2) * (∇J(θ_t))^2$$
简单来说:$m_t$ 是历史梯度的加权和,$v_t$ 是历史梯度平方的加权和。$β_1$ 和 $β_2$ 是衰减系数,通常设为 0.9 和 0.999,用于控制历史信息的权重。
第二步:进行偏差校正。
由于 $m_t$ 和 $v_t$ 在训练初期偏向于零(因为初始值为0,而更新公式类似指数平均),需要进行校正:
$$\hat{m}_t = m_t / (1 - β_1^t)$$
$$\hat{v}_t = v_t / (1 - β_2^t)$$
第三步:执行最终的参数更新。
用校正后的值来更新参数:
$$θ_{t+1} = θ_t - η * (\hat{m}_t / (\sqrt{\hat{v}_t} + ε))$$
这里 $ε$ 是一个极小值(如 1e-8),用于防止除以零。
4. 实操分析:Adam更快收敛的三大原因
将上述公式转化为直观的理解:
-
自适应调整每个参数的学习率:
公式中的$\hat{m}_t / (\sqrt{\hat{v}_t} + ε)$是关键。$\sqrt{\hat{v}_t}$估计了梯度幅度的均方根。对于梯度一直很大的参数,$\sqrt{\hat{v}_t}$大,导致整体步长变小,避免震荡;对于梯度一直很小的参数,$\sqrt{\hat{v}_t}$小,整体步长相对变大,帮助快速前进。这解决了SGD所有参数共享同一学习率的问题。 -
内置动量,穿越“山谷”:
$m_t$项(动量)累积了历史梯度的方向。这相当于给参数更新添加了“惯性”。当梯度在一个方向上一致时(比如在峡谷中沿长轴方向),动量会累积并加速;当梯度方向摇摆不定时(比如在峡谷的短轴方向来回震荡),动量会相互抵消,从而稳定更新,减少震荡。 -
偏差校正保证初期稳定:
初始阶段,$m_t$和$v_t$接近零,校正项$(1 - β^t)$保证了参数更新的有效大小,使得优化器从一开始就能以合理的步伐前进,不会因为初始的零状态而停滞。
5. 实用选择指南:何时用Adam,何时用SGD
虽然Adam通常更快收敛,但SGD依然有其用武之地。
优先选择Adam的场景:
- 问题复杂,损失曲面崎岖:对于大多数深度学习任务(如CNN、RNN),Adam的自适应性和动量能更好地应对各种梯度状况。
- 数据稀疏:在自然语言处理(NLP)等领域,特征稀疏,Adam对每个特征的自适应学习率优势明显。
- 需要快速得到一个不错的解:作为大多数情况下的默认选择,它能快速将损失函数降到一个较低的水平。
考虑使用SGD(常配合动量)的场景:
- 追求模型的最终泛化性能:一些研究表明,在计算机视觉等领域,用SGD配合动量(
momentum)和精心调谐的学习率调度(如余弦退火),最终可能达到比Adam更低的测试误差。SGD的更新更“纯粹”,可能有助于跳出某些尖锐的极小值点,找到更平坦(泛化更好)的极小值。 - 训练资源极其紧张:Adam需要为每个参数额外存储
$m_t$和$v_t$,内存占用比SGD高。
具体操作建议:
- 启动新项目时,直接使用
Adam优化器,配合默认参数(学习率$η=0.001$,$β_1=0.9$,$β_2=0.999$,$ε=1e-8$),可以让你快速验证模型想法。 - 当需要精细优化以追求最佳性能时,切换 为
SGD并 尝试momentum=0.9。然后,设计 一个学习率衰减策略(例如,每30个epoch将学习率乘以0.1),并进行更细致的调参。 - 在实践中,一个常见的折中方案是 “AdamWarmup”:先用
Adam训练初期快速收敛,然后在 训练中后期 切换 为SGD并继续微调,以期获得更好的泛化能力。

暂无评论,快来抢沙发吧!