深度学习中优化器的NovoGrad算法原理与二阶矩修正机制
题目描述
NovoGrad是一种由谷歌在2019年提出的自适应随机优化算法。其核心设计目标是在训练大型深度神经网络(如Transformer、BERT)时,结合Adam的优点,同时减少内存占用、提高数值稳定性,特别是在混合精度训练场景下。NovoGrad通过解耦梯度的一阶矩和二阶矩计算,并对二阶矩进行逐层归一化,来实现这些目标。本题将详细讲解NovoGrad的算法原理、实现步骤、优势及其背后的数学动机。
解题过程
为了让你完全理解NovoGrad,我们将从“为什么需要NovoGrad”开始,然后逐步拆解其算法步骤,最后分析其特点。
1. 背景与动机
在Adam等传统自适应优化器中,梯度的一阶矩(均值,m)和二阶矩(未中心化的方差,v)是紧密耦合的。计算v时,使用了当前梯度的平方(g²)。这在高维、混合精度训练中可能带来两个问题:
- 内存占用:需要为模型的每一个参数同时存储m和v,v的存储量(g²)与参数数量成正比。
- 数值稳定性:梯度的平方(g²)在混合精度(如FP16)训练中容易导致下溢(值太小变为0)或溢出(值太大变为无穷大),尤其是在梯度范数较大或层间差异显著时。
NovoGrad提出一种改进:不为每个参数单独计算一个完整的二阶矩v,而是为每个网络层计算一个共享的二阶矩(即梯度平方的标量值),并用这个共享的二阶矩对当前层的梯度进行归一化。这大大减少了二阶矩相关的存储开销,并增强了稳定性。
2. NovoGrad算法核心步骤
我们以一个具有L层的神经网络为例,假设有参数θ。对于第l层的参数,其更新步骤如下:
步骤1:计算当前小批量的梯度
设当前迭代步为t,对于参数θ_t,计算损失函数L(θ_t)关于θ_t的梯度g_t。
g_t = ∇θ_t L(θ_t)
步骤2:计算二阶矩(方差估计)
这是NovoGrad与传统Adam的关键区别。对于第l层:
- 首先,计算该层所有参数梯度g_t^l(是一个张量)的L2范数的平方,再除以该层的参数数量(或维度)d_l,得到一个标量值 v_t^(l):
v_t^(l) = (||g_t^(l)||₂²) / d_l
这个值衡量了该层梯度总体的“能量”大小。 - 然后,像Adam一样,对这个标量的二阶矩进行指数移动平均(EMA)平滑:
v_hat_t^(l) = β₂ * v_hat_{t-1}^(l) + (1 - β₂) * v_t^(l)
其中 β₂ 是衰减率超参数(例如0.999)。这里v_hat_t^(l)是一个标量,而不是像Adam那样是一个与参数同形状的张量。
步骤3:用二阶矩归一化梯度
使用平滑后的标量二阶矩 v_hat_t^(l) 对该层的原始梯度 g_t^(l) 进行归一化:
g'_t^(l) = g_t^(l) / sqrt(v_hat_t^(l) + ε)
这里ε是一个很小的常数(例如1e-8),防止除零。g'_t^(l)是经过该层梯度能量归一化后的新梯度。
步骤4:计算一阶矩(动量)
对归一化后的梯度 g'_t(注意,这里是对所有层统一的符号)计算指数移动平均,得到一阶矩 m_t:
m_t = β₁ * m_{t-1} + (1 - β₁) * g'_t
其中 β₁ 是动量衰减率超参数(例如0.9)。
步骤5:参数更新
最后,使用计算出的动量 m_t 和学习率 α_t 更新参数:
θ_{t+1} = θ_t - α_t * m_t
注意:NovoGrad的原始论文中,步骤4和5还可以选择性地加入权重衰减。通常采用解耦权重衰减(类似于AdamW)的方式:
θ_{t+1} = θ_t - α_t * (m_t + λ * θ_t)
其中λ是权重衰减系数。
3. 算法伪代码与直观解释
将上述步骤整合成算法伪代码(以单个参数向量为例,但强调其层级特性):
初始化:时间步 t=0,参数 θ, 一阶矩 m=0,对于每个层 l,其二阶矩标量 v_hat^(l)=0。
设置超参数:学习率 α, 衰减率 β₁, β₂, 常数 ε, 权重衰减 λ(可选)。
while θ 未收敛 do
t = t + 1
计算当前小批量的损失,得到梯度 g_t。
for 网络中的每一层 l do
# 1. 计算该层的梯度标量二阶矩
d_l = 第l层参数的维度(元素总数)。
v_t^(l) = (||g_t^(l)||₂²) / d_l # 一个标量
# 2. 更新该层的标量二阶矩EMA
v_hat_t^(l) = β₂ * v_hat_{t-1}^(l) + (1 - β₂) * v_t^(l)
# 3. 用该层的标量二阶矩归一化该层的梯度
g'_t^(l) = g_t^(l) / sqrt(v_hat_t^(l) + ε)
end for
# 4. 用归一化后的梯度更新一阶矩(动量)
m_t = β₁ * m_{t-1} + (1 - β₁) * g'_t
# 5. 更新参数(带解耦权重衰减)
θ_t = θ_{t-1} - α_t * (m_t + λ * θ_{t-1})
end while
直观解释:
- 逐层归一化:
v_hat_t^(l)反映了第l层梯度历史平均的“大小”。除以它的平方根,相当于将这一层的所有梯度缩放到一个相对稳定的范围,减轻了不同层之间梯度尺度差异过大的问题,类似于一种“层级的自适应学习率”。 - 内存节省:存储
v_hat_t^(l)(一个标量)而不是v_t(一个张量),使得二阶矩的内存占用从 O(n) 减少到 O(L),其中n是参数总数,L是网络层数(L << n)。这对于拥有数十亿参数的大模型至关重要。 - 数值稳定:计算标量的L2范数平方,相比直接计算每个元素的平方再求和(在FP16下容易溢出),数值上更加鲁棒。标量运算也避免了张量级下溢/溢出风险。
4. 与Adam的对比与总结
| 特性 | Adam | NovoGrad |
|---|---|---|
| 二阶矩形式 | 张量(与参数同形) | 标量(逐层共享) |
| 内存占用 | 较高(需存m和v张量) | 较低(v是标量) |
| 归一化对象 | 使用每个参数的二阶矩v直接调整更新量 | 使用层的二阶矩标量先归一化梯度,再计算动量 |
| 计算顺序 | 先计算m和v,再用v归一化更新步 | 先归一化梯度,再对归一化梯度计算动量m |
| 稳定性 | 对混合精度训练敏感(g²易溢出) | 更稳定(层标量计算更安全) |
核心优势总结:
NovoGrad通过解耦梯度归一化与动量计算,并采用层级的标量二阶矩估计,在大规模深度学习训练中实现了:
- 内存效率:显著降低优化器状态的内存占用。
- 训练稳定性:在混合精度训练中表现更鲁棒,允许使用更大的批大小。
- 收敛性能:在实践中(如在训练Transformer和BERT时),常能取得与Adam相当甚至更优的收敛速度和最终精度。
因此,NovoGrad可以被视为一种为现代大规模、混合精度深度学习模型量身定制的高效、稳定的自适应优化器变种。