深度学习中的优化器之SGD with Layer-wise Adaptive Moments (LAMB) 算法原理与实现细节
题目描述
在深度学习模型的训练中,优化器的选择至关重要。Adam 等自适应优化器在训练初期通常收敛很快,但在训练后期或在某些任务上(如 BERT 等大型语言模型)的泛化性能可能不如带有动量(Momentum)的随机梯度下降。然而,SGD 通常需要一个精细的手动学习率调度。LAMB 优化器旨在解决这一困境,其核心思想是结合自适应优化器的优点(如 Adam 的逐参数更新)和 SGD 的泛化能力,特别是通过对每一层的权重更新进行自适应缩放,从而能够高效地训练大型模型。请解释 LAMB 算法的动机、原理推导、更新公式以及关键的“层自适应”(Layer-wise adaptation)机制。
解题过程
第一步:理解问题背景与动机
- 大型模型训练的挑战:训练像 BERT 这样的大型 Transformer 模型时,由于其参数空间巨大,使用标准 SGD 或 Adam 优化器可能导致收敛困难、训练不稳定,或者需要非常精细的学习率预热和衰减策略。
- Adam 的局限性:Adam 通过计算每个参数的“一阶矩”(均值,即动量)和“二阶矩”(方差)的自适应估计,为每个参数提供个性化的更新步长。这使其在训练早期收敛快。然而,在训练后期,其自适应步长可能导致“过度适应”训练数据,从而损害模型的最终泛化性能。
- LAMB 的核心洞察:LAMB 算法的提出者(You et al., 2019)认为,问题可能在于 Adam 对不同参数赋予的更新步长差异过大。他们提出,对权重的更新量不应该完全由其自身的历史梯度统计量决定,而应该与该层权重自身的“尺度”(norm)成比例。这样可以确保模型的所有层在训练过程中都以相似的速度更新,从而稳定训练,并允许使用非常大的批量大小,显著加快大型模型的训练速度。
第二步:回顾 Adam 优化器的公式
LAMB 是在 Adam 的基础上修改的。我们先回顾 Adam 对一个参数 \(\theta_t\) 在时间步 \(t\) 的更新过程:
- 计算动量和方差:
\[ m_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t \]
\[ v_t = \beta_2 v_{t-1} + (1 - \beta_2) g_t^2 \]
其中,$ g_t = \nabla_\theta f(\theta_{t-1}) $ 是 t 时刻的梯度,$ \beta_1, \beta_2 $ 是衰减率。
- 偏差修正(用于抵消初始零估计的影响):
\[ \hat{m}_t = m_t / (1 - \beta_1^t) \]
\[ \hat{v}_t = v_t / (1 - \beta_2^t) \]
- 参数更新:
\[ \theta_t = \theta_{t-1} - \eta \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} \]
其中,$ \eta $ 是学习率,$ \epsilon $ 是为数值稳定性添加的小常数。
第三步:引入“层自适应”(Layer-wise Adaptation)机制
LAMB 的核心创新在于引入一个缩放因子(trust ratio),将 Adam 的更新步长与权重本身的幅度(norm)关联起来。其目标是让所有权重更新后的“相对变化”处于一个合理的范围内,而不是对每个参数进行独立的、可能差异巨大的缩放。
对于一个模型中的某一层(例如,一个线性层的权重矩阵 \(W^{(l)}\)),LAMB 的执行步骤如下:
- 计算“Adam 风格的更新方向”:
对于该层中的每一个参数(即 \(W^{(l)}\) 的每一个元素),我们像标准 Adam 一样计算其更新向量 \(\Delta^{(l)}_t\) 的分量:
\[ \Delta^{(l)}_t = \frac{\hat{m}^{(l)}_t}{\sqrt{\hat{v}^{(l)}_t} + \epsilon} \]
这里,$ \hat{m}^{(l)}_t $ 和 $ \hat{v}^{(l)}_t $ 是针对该层所有参数计算的偏差修正后的动量和方差。这个 $ \Delta^{(l)}_t $ 是一个向量/矩阵,与 $ W^{(l)} $ 形状完全相同,它指示了参数空间中的更新方向。
- 计算信任比率(Trust Ratio):
这是 LAMB 的关键步骤。我们比较“建议的更新幅度”与“当前权重的幅度”:
\[ \text{ratio} = \frac{\|\Delta^{(l)}_t\|}{\|W^{(l)}_t\| + \delta} \]
其中,$ \|\cdot\| $ 表示 L2 范数(Frobenius 范数,对于矩阵来说就是所有元素的平方和开根号),$ \delta $ 是一个防止除零的小常数(例如 1e-8)。这个比率衡量了**建议的更新步长相对于当前权重大小的比例**。
- 缩放更新量:
然后,我们将原始的 Adam 更新方向 \(\Delta^{(l)}_t\) 乘以这个比率,再乘以全局学习率 \(\eta\)。
但是,为了更精细地控制,LAMB 论文中实际使用了一个修正形式:
\[ \text{update}^{(l)} = \eta \cdot \frac{\|\phi(W^{(l)}_t)\|}{\|\Delta^{(l)}_t\|} \cdot \Delta^{(l)}_t \]
等等,这个公式看起来有点不同。实际上,LAMB 论文中定义“信任比率”为:
\[ r^{(l)}_t = \frac{\|\phi(W^{(l)}_t)\|}{\|\Delta^{(l)}_t\| + \lambda \|W^{(l)}_t\|} \]
这里:
* $ \phi(W^{(l)}_t) $ 是原始的、未经过比例缩放的参数。在实际更新中,为了与权重衰减兼容,LAMB 通常将权重衰减从更新公式中分离出来,即计算 $ \phi(W^{(l)}_t) = W^{(l)}_t - \eta \cdot \lambda W^{(l)}_t $,其中 $ \lambda $ 是权重衰减系数。这使得权重衰减成为一个独立的、不依赖梯度的操作。在简化理解中,可以先将 $ \phi(W^{(l)}_t) $ 近似视为 $ W^{(l)}_t $。
* $ \lambda $ 是一个权重衰减超参数。
* 这个公式的**核心思想是**:我们希望最终的权重更新幅度与原始权重大小成比例。**分子 $ \|\phi(W^{(l)}_t)\| $ 代表了该层权重的“自然尺度”**。**分母 $ \|\Delta^{(l)}_t\| $ 代表了建议的、由梯度信息驱动的更新幅度**。如果建议的更新幅度(分母)比权重大(分子)大很多,这个比率会变小,从而抑制更新;反之亦然。这确保了更新的“相对变化”是受控的。
- 应用更新:
最终,该层权重的更新公式为:
\[ W^{(l)}_{t+1} = W^{(l)}_t - \eta \cdot r^{(l)}_t \cdot \Delta^{(l)}_t \]
这里,$ r^{(l)}_t $ 就是上一步计算出的信任比率。由于 $ r^{(l)}_t $ 是一个**标量**(对整个层计算一个值),它对该层的所有参数进行**统一的缩放**。这就是“层自适应”——整个层共享一个缩放因子。
第四步:整合权重衰减与完整的 LAMB 算法
在实际实现中,为了与 AdamW 保持一致,LAMB 通常采用解耦权重衰减。具体步骤如下:
对于一个模型的每一层 \(l\) 的参数 \(W^{(l)}\):
- 计算梯度:\(g^{(l)}_t = \nabla_{W^{(l)}} f(W^{(l)}_{t-1})\)
- 计算动量和方差(同 Adam):
\[ m^{(l)}_t = \beta_1 m^{(l)}_{t-1} + (1 - \beta_1) g^{(l)}_t \]
\[ v^{(l)}_t = \beta_2 v^{(l)}_{t-1} + (1 - \beta_2) (g^{(l)}_t)^2 \]
- 偏差修正:
\[ \hat{m}^{(l)}_t = m^{(l)}_t / (1 - \beta_1^t) \]
\[ \hat{v}^{(l)}_t = v^{(l)}_t / (1 - \beta_2^t) \]
- 计算 Adam 风格的更新方向:
\[ \Delta^{(l)}_t = \hat{m}^{(l)}_t / (\sqrt{\hat{v}^{(l)}_t} + \epsilon) \]
- 计算信任比率:
\[ r^{(l)}_t = \frac{\|W^{(l)}_t\|}{\|\Delta^{(l)}_t\| + \lambda \|W^{(l)}_t\|} \]
注意,这里的分子用了 $ W^{(l)}_t $,而不是 $ \phi(W^{(l)}_t) $。在解耦权重衰减的设定下,权重衰减是单独应用的,所以直接用当前的权重范数即可。这个公式是 LAMB 的核心实现。
- 解耦权重衰减与参数更新:
- 首先应用权重衰减:
\[ W^{(l)}_t := (1 - \eta \lambda) W^{(l)}_t \]
* **然后使用缩放后的自适应步长进行更新**:
\[ W^{(l)}_{t+1} = W^{(l)}_t - \eta \cdot r^{(l)}_t \cdot \Delta^{(l)}_t \]
第五步:总结 LAMB 的优势与特性
- 训练稳定性:通过对整个层应用统一的缩放因子,LAMB 防止了模型不同层之间更新步长差异过大,从而稳定了训练过程,尤其是在使用非常大的批量大小时。
- 加速大型模型训练:因为 LAMB 使得训练能稳定地使用超大批次,从而能更好地利用分布式训练的计算资源,显著缩短训练时间(例如,训练 BERT 的时间可以从数天缩短到数小时)。
- 自适应与泛化的平衡:LAMB 保留了 Adam 对每个参数的“方向”自适应(由 \(\Delta^{(l)}_t\) 给出),同时通过“层自适应”来控制更新的“幅度”,使其与权重大小相适应,从而在理论上结合了 Adam 的快速收敛和 SGD 的最终泛化优势。
- 与权重衰减的兼容性:通过采用解耦权重衰减,避免了自适应学习率对权重衰减效果的影响,使得正则化更有效。
总之,LAMB 优化器通过引入层自适应的信任比率,将 Adam 的参数级自适应与 SGD 的稳定性结合起来,使其成为训练大规模深度学习模型(尤其是 Transformer 类模型)的一个强大且实用的选择。