SGD 动量解决了"方向有时间相关性"的问题,但所有参数坐标共享同一个学习率 $\eta$。这在实际网络里很快撞上麻烦: embedding 表、输出层、归一化增益这些参数的梯度量级能差出几个数量级,共享步长意味着要么大梯度参数震荡,要么小梯度参数原地踏步。Adam(Kingma & Ba, 2015)的目标很直接:让每个坐标自己决定步长。做法是给每个梯度分量维护两个指数移动平均:
$$ m_t = \beta_1 m_{t-1} + (1-\beta_1) g_t, \qquad v_t = \beta_2 v_{t-1} + (1-\beta_2) g_t^2 . $$
然后更新参数:$\theta_{t+1} = \theta_t - \eta\, \hat m_t / (\sqrt{\hat v_t} + \varepsilon)$。下面拆解每一部分从哪来。
为什么分母是 $\sqrt{v}$:按坐标归一的步长
只看单坐标。设该坐标梯度序列的均值为 $\mu$、二阶矩为 $s^2 = E[g^2]$,Adam 的更新幅度约为
$$ |\Delta\theta| \approx \eta \cdot \frac{|\mu|}{\sqrt{s^2}} = \eta \cdot \frac{|\mu|}{\sqrt{\mu^2 + \sigma^2}}, $$
其中 $\sigma^2$ 是梯度噪声方差。这个比值就是信噪比:一致性好的坐标($\sigma \ll |\mu|$)拿到接近 $\eta$ 的满步长,噪声主导的坐标($\sigma \gg |\mu|$)步长被压到 $\eta|\mu|/\sigma$。分母 $\sqrt{\hat v_t}$ 起的作用就是把每个坐标的步长按它自身梯度的典型尺度归一化,从而所有坐标理论上都以"约 $\eta$ 个归一步"前进。这就是 Adam 对病态曲率的回答:不用 Hessian 也知道哪些方向该小步走。
顺着这条线可以把几个经典优化器排成一族。$\beta_1 \to 0$ 时 $m \approx (1-\beta_1)g$,更新近似 $-\eta\, g/(\sqrt{\hat v}+\varepsilon)$;$\beta_2$ 也趋小时 $v \propto g^2$,开方后分母约 $|g|$,整个更新退化为符号下降
$$ \Delta\theta \approx -\eta \cdot \mathrm{sign}(g), $$
每步更新向量的范数恒为 $\eta\sqrt{d}$,只保留方向信息,扔掉一切幅度信息。Adam 处在"SGD(保留全部幅度,$v$ 恒定)"和"符号下降(完全丢弃幅度)"之间的连续谱上,$(\beta_1, \beta_2)$ 决定它在谱上的位置。
偏差修正:EMA 的"预热期欠账"
直接拿 $m_t, v_t$ 用会在训练最初几十步出问题。初始化 $m_0 = v_0 = 0$,于是
$$ m_t = (1-\beta_1^t)\,\hat\mu_t, $$
其中 $\hat\mu_t$ 是按权重归一后的无偏均值估计(所有历史梯度按 $\beta_1^{t-k}$ 加权)。证明只需对递推展开求几何级数:$E[m_t] = (1-\beta_1)\sum_{k=1}^t \beta_1^{t-k} E[g_k]$,若各时刻梯度同分布,$E[g]$ 的系数和正是 $1-\beta_1^t$。$t$ 很小时这个系数远小于 1:$t=1$ 时 $m_1 = (1-\beta_1) g_1$,只有真实值的 $0.1$($\beta_1=0.9$)。二阶矩同理,且 $\beta_2 = 0.999$ 时 $v_t$ 要一千步才积累到真值的 $1-e^{-1}$ 量级。
修正办法就是把缺掉的系数除回来:$\hat m_t = m_t/(1-\beta_1^t)$,$\hat v_t = v_t/(1-\beta_2^t)$。注意一个常见误解——偏差修正修的是 EMA 冷启动的系统性偏小,不是估计方差。$t$ 足够大之后 $1-\beta^t \to 1$,修正项自动退化为恒等式;前期它把学习率拉回到正确刻度。Adam 官方实现都带修正项,但从零手写时很容易漏掉,表现为 loss 头几步异常大的抖动。
和 AdaGrad、RMSProp 的血缘
AdaGrad(2011)是这条路线的起点:$v_t = \sum_{k\le t} g_k^2$(累加而非平均),更新 $-\eta g/\sqrt{v_t}$。累积结构给出 $1/\sqrt{t}$ 的步长衰减,凸问题上收敛有保证,但非凸训练里 $v$ 只增不减,步长单调走向零,跑到一半就动弹不得。RMSProp(Hinton 讲义,2012)把累加换成 EMA,让步长既能适应不同坐标、又能在分布漂移后恢复——Adam 的二阶矩就是 RMSProp 的部分。Adam 加上动量项 $m_t$(一阶矩)成为完整方案,可以理解为"RMSProp 的坐标自适应步长 + 动量的方向平滑"两个早已存在的组件的组合。
两个默认值的来历
$\beta_1 = 0.9$ 是动量的标准值,时间常数 10 步,承接 SGD 动量篇的分析。$\beta_2 = 0.999$ 明显更长,原因是二阶矩估的是平方量的均值,而平方量本身方差大:梯度小幅震荡会被平方放大,$v$ 需要更长的窗口才能平滑掉采样噪声,否则 $\sqrt{\hat v}$ 抖动会直接传导进步长。代价是 $v$ 对分布漂移的响应慢(要上千步),所以切换数据分布(多阶段训练、领域续训)后的过渡期里,Adam 的步长刻度其实是过时的——后面 warmup 篇会讲重启优化器状态时为什么常把 $v$ 一并重置。
小结
Adam 的更新式可以拆解为三个有明确动机的组件:一阶矩 $m_t$ 平滑方向(动量),二阶矩 $v_t$ 提供逐坐标归一的步长刻度(信噪比加权),偏差修正补上 EMA 冷启动的系数欠账。它在 SGD 与符号下降之间的连续谱上取了一个经验甜点。已知漏洞也有对应补丁:L2 正则和 weight decay 混用是错的(下一篇),$\varepsilon$ 的取值不是随便拍的(再下一篇)。