在深度学习的世界里,优化器 (Optimizer) 就像是我们在群山中寻找最低谷(损失函数最小值)的向导。然而大家最常用的是 Adam 以及它的修正版 AdamW。为什么有了 Adam 还要 AdamW?这中间到底发生了什么?

1. 理想很丰满:牛顿法 (Newton’s Method) 🍎

在介绍各种花哨的优化器之前,我们先来看看“上帝视角”的优化方法——牛顿法。
很多时候,我们只知道往哪里走(梯度下降),但牛顿法告诉我们,不仅要看方向,还要看地形的弯曲程度。

  • 直观理解:泰勒展开 (Taylor Expansion)
    假设我们要优化的损失函数是 f(x)f(x)f(x)。我们可以在当前点 xtx_txt 附近,用一个二次函数来近似它(二阶泰勒展开):
    f(x)≈f(xt)+f′(xt)(x−xt)+12f′′(xt)(x−xt)2 f(x) \approx f(x_t) + f'(x_t)(x - x_t) + \frac{1}{2}f''(x_t)(x - x_t)^2 f(x)f(xt)+f(xt)(xxt)+21f′′(xt)(xxt)2

    • f′(xt)f'(x_t)f(xt)一阶导数(梯度),告诉我们坡度。
    • f′′(xt)f''(x_t)f′′(xt)二阶导数,告诉我们坡度的变化率(也就是曲率)。

    我们希望找到这个近似函数的最低点。很简单,对 xxx 求导并令其为 0:
    f′(x)≈f′(xt)+f′′(xt)(x−xt)=0 f'(x) \approx f'(x_t) + f''(x_t)(x - x_t) = 0 f(x)f(xt)+f′′(xt)(xxt)=0

    解出 xxx(即我们要去的下一步 xt+1x_{t+1}xt+1):
    xt+1=xt−f′(xt)f′′(xt) x_{t+1} = x_t - \frac{f'(x_t)}{f''(x_t)} xt+1=xtf′′(xt)f(xt)

  • 公式的含义
    注意看最后的公式,更新步长不再是固定的 η\etaη,而是 1f′′(xt)\frac{1}{f''(x_t)}f′′(xt)1

    • 如果曲率 f′′f''f′′ 很大(地形很陡峭),分母大,步子就迈小点,防止走过头。
    • 如果曲率 f′′f''f′′ 很小(地形很平坦),分母小,步子就迈大点,快速通过平原。
      这就是最早的“自适应学习率”思想!
  • 为什么不用它?
    在多维情况下,二阶导数 f′′f''f′′ 变成了一个巨大的矩阵——海森矩阵 (Hessian Matrix)
    θt+1=θt−H−1gt \theta_{t+1} = \theta_t - H^{-1}g_t θt+1=θtH1gt
    计算它太贵了!如果有 1 亿个参数,这个矩阵就有 1亿 ×\times× 1亿 个元素,根本算不动。


2. AdaGrad:为每个参数量身定制学习率 📏

承接上文,既然牛顿法的分母 f′′f''f′′(曲率)太难算,AdaGrad 想了一个偷懒的办法:用梯度的历史平方和来模拟曲率

  • 为什么要这样模拟?
    牛顿法的核心是:坡度陡(曲率大)的地方步子小,坡度平(曲率小)的地方步子大
    AdaGrad 发现,如果一个参数过去经常有很大的梯度,那它的梯度平方和 ∑g2\sum g^2g2 就会很大。如果我们把这个平方和放在分母上,是不是就达到了“大梯度 →\to 小步长”的效果?

    这正是 AdaGrad 的设计初衷。

  • 理论支撑:Fisher Information Matrix
    你可能会问:凭什么用梯度平方就能代表二阶导数?这不是乱来吗?
    其实原论文(以及后来的 Fisher Information 相关研究)给出了证明:
    对于常见的损失函数(如对数似然函数),梯度的协方差矩阵(即 g⋅gTg \cdot g^TggT)在期望上等于海森矩阵(二阶导数)
    这就是著名的 Fisher Information Matrix ≈\approx Hessian
    AdaGrad 其实就是利用了这一点,用 g2g^2g2 的累积来近似海森矩阵的对角线元素,从而实现了低成本的“准牛顿法”。

  • 它是怎么做的?
    AdaGrad 引入了 二阶动量 的概念。它会记录每个参数历史上所有梯度的平方和。
    Gt=∑i=1tgi2 G_t = \sum_{i=1}^t g_i^2 Gt=i=1tgi2
    更新时,学习率会除以这个平方和的根号:
    wt+1=wt−ηGt+ϵ⋅gt w_{t+1} = w_t - \frac{\eta}{\sqrt{G_t + \epsilon}} \cdot g_t wt+1=wtGt+ϵ ηgt
    注:ϵ\epsilonϵ 是防止分母为 0 的小常数。

  • 效果分析

    • 频繁更新的参数(梯度总是不为 0):分母 GtG_tGt 很大,学习率变小,更新谨慎。
    • 稀疏更新的参数(梯度偶尔出现):分母 GtG_tGt 很小,学习率保持较大,一旦出现梯度就能抓住机会大步更新。
      这使得 AdaGrad 非常适合处理稀疏数据(如 NLP 中的词向量)。
  • 致命缺点
    GtG_tGt 是单调递增的(因为它一直在累加正数)。这意味着分母会越来越大,学习率 ηGt\frac{\eta}{\sqrt{G_t}}Gt η持续衰减,最终趋近于 0。
    导致的结果是:模型还没训练完,学习率就已经死掉了,参数不再更新。


3. RMSProp:别看太远,只看当下 👀

为了解决 AdaGrad 学习率衰减过快的问题,Hinton 大神提出了 RMSProp。

  • 它是怎么做的?
    它不再简单累加所有历史梯度平方,而是使用 指数加权移动平均 (Exponential Moving Average)
    vt=βvt−1+(1−β)gt2 v_t = \beta v_{t-1} + (1 - \beta) g_t^2 vt=βvt1+(1β)gt2
    这里的 β\betaβ 通常设为 0.9。这意味着我们主要关注最近的梯度情况,而逐渐“遗忘”很久以前的梯度。
  • 效果
    这样分母就不会无限变大,学习率就能保持在一个合理的范围内波动。这让算法在非凸优化问题上表现更好。

4. Adam:集大成者 (Momentum + RMSProp) 🌟

Adam (Adaptive Moment Estimation) 是目前的默认首选。它结合了 Momentum (一阶动量)RMSProp (二阶动量) 的优点。

  • 它是怎么做的?
    Adam 维护了两个状态:
    1. 一阶动量 mtm_tmt (梯度的均值,类似惯性,冲下坡):
      mt=β1mt−1+(1−β1)gt m_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t mt=β1mt1+(1β1)gt
    2. 二阶动量 vtv_tvt (梯度的未中心化方差,类似 RMSProp,调整步长):
      vt=β2vt−1+(1−β2)gt2 v_t = \beta_2 v_{t-1} + (1 - \beta_2) g_t^2 vt=β2vt1+(1β2)gt2
      偏差修正 (Bias Correction)
      刚开始 m0,v0m_0, v_0m0,v0 都是 0,会导致初期估计偏向 0。所以需要修正:
      m^t=mt1−β1t,v^t=vt1−β2t \hat{m}_t = \frac{m_t}{1 - \beta_1^t}, \quad \hat{v}_t = \frac{v_t}{1 - \beta_2^t} m^t=1β1tmt,v^t=1β2tvt
      最终更新公式
      wt+1=wt−η⋅m^tv^t+ϵ w_{t+1} = w_t - \eta \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} wt+1=wtηv^t +ϵm^t
  • 地位
    Adam 几乎适用于所有场景,收敛快,参数鲁棒。但是,它在某些情况下(如图像分类)的泛化能力(Generalization)有时不如精调过的 SGD。

5. 这里的“坑”:L2 正则化 vs 权重衰减 (Weight Decay) 🕳️

在讲 AdamW 之前,必须先厘清一个长期被误解的概念。

我们为了防止过拟合,通常会使用 L2 正则化权重衰减。在很多教材和框架文档中,这两者被混为一谈,认为它们是等价的。

  • L2 正则化:是在 Loss 函数后面加一项 12λ∣∣w∣∣2\frac{1}{2} \lambda ||w||^221λ∣∣w2
    Losstotal=Lossoriginal+12λ∣∣w∣∣2 Loss_{total} = Loss_{original} + \frac{1}{2} \lambda ||w||^2 Losstotal=Lossoriginal+21λ∣∣w2
    求导后,梯度变为:gt′=gt+λwtg_t' = g_t + \lambda w_tgt=gt+λwt

  • 权重衰减 (Weight Decay):是在更新参数时,直接让权重衰减一点点。
    wt+1=wt−ηgt−ηλwt w_{t+1} = w_t - \eta g_t - \eta \lambda w_t wt+1=wtηgtηλwt

关键点来了:

  • SGD 中,推导一下你会发现,L2 正则化和权重衰减确实在数学上是等价的。
  • 但是在 Adam 这种自适应学习率算法中,它们不等价

为什么?
如果在 Adam 中使用 L2 正则化(即把 λw\lambda wλw 加到梯度 gtg_tgt 里),这个正则化项会被 Adam 的二阶动量 v^t\sqrt{\hat{v}_t}v^t 给除一下。
这意味着:正则化的力度被参数的梯度的幅度归一化了

  • 梯度大的参数,正则化力度变小了。
  • 梯度小的参数,正则化力度变大了。

这显然不是我们想要的。我们希望权重衰减是独立的,不受梯度大小影响。


6. AdamW:修正后的 Adam ✅

这就是 AdamW (Adam with Decoupled Weight Decay) 诞生的原因。

  • 它是怎么解决的?
    AdamW 将权重衰减从梯度更新中剥离 (Decouple) 出来。
    它不再修改梯度 gtg_tgt,而是直接在更新公式的最后一步,减去权重衰减项。

    AdamW 更新公式
    wt+1=wt−ηm^tv^t+ϵ⏟Adam原本的更新−ηλwt⏟独立的权重衰减 w_{t+1} = \underbrace{w_t - \eta \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon}}_{\text{Adam原本的更新}} - \underbrace{\eta \lambda w_t}_{\text{独立的权重衰减}} wt+1=Adam原本的更新 wtηv^t +ϵm^t独立的权重衰减 ηλwt

  • 为什么 AdamW 更好?

    1. 解耦:学习率和权重衰减超参数不再耦合,调参更容易。
    2. 泛化能力提升:修复了 Adam 在 L2 正则化下的错误行为,使得 AdamW 在很多任务(尤其是 Transformer、BERT 等大模型训练)中,泛化性能追平甚至超越了 SGD。

总结 📝

算法 核心思想 一句话点评
AdaGrad 累积梯度平方,调整学习率 适合稀疏数据,但后期学不动。
RMSProp 移动平均梯度平方 解决了 AdaGrad 衰减过快问题。
Adam 动量 + RMSProp 现在的默认王者,但在 L2 正则上有缺陷。
AdamW 解耦权重衰减 修复版王者,大模型训练标配。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐