深度学习中的优化器之AdaMod算法原理与自适应学习率边界机制
题目描述
在深度学习的优化领域中,自适应学习率优化器(如Adam、RMSProp)因其快速收敛性而被广泛使用,但它们也常面临训练后期泛化性能下降、收敛不稳定等问题。AdaMod(Adaptive and Momental Bound)算法是对Adam优化器的一种改进,其核心思想是引入一个自适应边界(mod)来裁剪自适应学习率中的指数移动平均值(EMA),从而在训练后期稳定学习率,防止其无限制地增长或振荡,以期实现更好的收敛性和泛化性能。请你详细讲解AdaMod算法的设计动机、核心公式、实现步骤及其背后的自适应边界机制。
解题过程
第一步:理解基础——Adam优化器的回顾与问题分析
在深入AdaMod之前,我们需要先回顾Adam优化器的核心步骤,并分析其潜在问题。
-
Adam的核心公式:
- 动量(一阶矩): \(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\)
- 偏差修正: \(\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 \hat{m}_t / (\sqrt{\hat{v}_t} + \epsilon)\)
- 其中,\(g_t\)是当前梯度,\(\eta\)是初始学习率,\(\beta_1, \beta_2\)是衰减率,\(\epsilon\)是平滑项。
-
Adam的潜在问题:
- 收敛不稳定:在训练后期,当梯度变小时,\(\hat{v}_t\)(二阶矩估计)也可能变得很小,导致有效学习率 \(\eta / \sqrt{\hat{v}_t}\) 变得很大,使得参数更新步长过大,在最优解附近振荡,甚至发散。
- 泛化差距:一些研究表明,Adam在训练集上收敛很快,但在测试集上的泛化性能有时不如带动量的SGD。这可能与Adam在训练后期过大的有效学习率有关。
第二步:AdaMod的核心思想——引入自适应边界(Mod)
AdaMod算法的核心创新在于对Adam中的二阶矩估计 \(v_t\) 进行上限约束,而不是直接使用它。这个上限是一个自适应的、单调不减的边界,称为“mod”。
-
设计动机:
- 我们希望控制有效学习率的下限(即 \(\eta / \sqrt{v_t}\) 的上限),防止它在训练后期变得过大。一个直观的想法是使用一个缓慢增长的、平滑的值来“记住”历史\(v_t\)中较大的值,作为当前\(v_t\)的上限。
- 这个上限应该是自适应的,能根据优化过程自动调整;并且是单调不减的,以确保学习率只会被“收紧”而不会“放松”,从而在训练后期提供稳定性。
-
自适应边界(Mod)的计算:
- AdaMod引入了一个新的状态变量 \(b_t\),用于计算这个自适应边界 \(mod_t\)。
- 边界基值更新:首先,像更新\(v_t\)一样,用指数移动平均来更新一个基础值 \(b_t\):
\[ b_t = \beta_2 b_{t-1} + (1 - \beta_2) g_t^2 \]
* **边界值(Mod)计算**:然后,计算当前步的自适应边界为历史$b_t$的**指数移动最大值**(Exponential Moving Maximum)。为了保证单调性,AdaMod取当前$b_t$与上一个边界$mod_{t-1}$的较大值,但用一个新的衰减因子$\beta_3$(通常接近1,如0.99)来平滑这个过程:
\[ mod_t = \beta_3 \cdot mod_{t-1} + (1 - \beta_3) \cdot \max(b_t, mod_{t-1}) \]
* **物理意义**:$mod_t$ 可以看作是 $b_t$(即梯度二阶矩的EMA)的一个**平滑的、保守的上界估计**。由于$\beta_3$很大,$mod_t$增长非常缓慢,且一旦增长就不会下降。
第三步:AdaMod的完整算法流程
现在我们整合AdaMod的所有步骤。假设要最小化的目标函数为\(J(\theta)\),初始参数为\(\theta_0\),初始学习率为\(\eta\)。
-
初始化:
- 初始化一阶矩向量 \(m_0 = 0\)
- 初始化二阶矩向量 \(v_0 = 0\)
- 初始化边界基值向量 \(b_0 = 0\)
- 初始化自适应边界向量 \(mod_0 = 0\)
- 设置超参数:衰减率 \(\beta_1, \beta_2 \in [0, 1)\)(通常0.9, 0.999),边界衰减率 \(\beta_3 \in [0, 1)\)(通常0.99),平滑项 \(\epsilon > 0\)(如1e-8),初始学习率 \(\eta\)。
-
对于每个训练步 \(t = 1, 2, ...\):
- 计算当前小批量的梯度:\(g_t = \nabla_\theta J_t(\theta_{t-1})\)
- 更新一阶矩估计:\(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\)
- 更新边界基值:\(b_t = \beta_2 b_{t-1} + (1 - \beta_2) g_t^2\) (注意:这里与\(v_t\)使用相同的\(\beta_2\)和梯度信号,但状态独立)
- 计算自适应边界:\(mod_t = \beta_3 \cdot mod_{t-1} + (1 - \beta_3) \cdot \max(b_t, mod_{t-1})\)
- 偏差修正(可选,但推荐):
- \(\hat{m}_t = m_t / (1 - \beta_1^t)\)
- 对\(v_t\)和\(mod_t\)的修正稍微不同。AdaMod的作者建议对\(\max(v_t, mod_t)\)进行整体修正,但实践中也常见对\(v_t\)和\(mod_t\)分别修正。一种清晰的实现是:
\[ \hat{v}_t = v_t / (1 - \beta_2^t) \]
\[ \hat{mod}_t = mod_t \]
(由于$mod_t$的定义已经是平滑最大值,且$\beta_3$很大,通常不进行$(1-\beta_3^t)$的修正,或修正影响极小)。
* **计算裁剪后的二阶矩估计**:关键步骤来了。我们用自适应边界$mod_t$(或其修正版$\hat{mod}_t$)来裁剪$v_t$(或其修正版$\hat{v}_t$):
\[ v_t^{'} = \min(\hat{v}_t, \hat{mod}_t) \]
* **参数更新**:
\[ \theta_t = \theta_{t-1} - \eta \cdot \frac{\hat{m}_t}{\sqrt{v_t^{'}} + \epsilon} \]
第四步:算法机制与优势分析
-
边界机制如何工作:
- 在训练早期,梯度通常较大且变化剧烈,\(b_t\)和\(v_t\)也较大。此时,\(mod_t\)会逐渐“学习”到一个较高的值。由于\(v_t\)可能仍然小于或等于\(mod_t\),所以\(v_t^{'} = v_t\),算法行为类似于Adam。
- 在训练后期,接近收敛时,梯度变小,\(v_t\)会变得很小,导致Adam的有效学习率急剧增大。但在AdaMod中,由于\(mod_t\)是历史\(b_t\)的平滑最大值,它已经“记住”了早期较大的二阶矩水平。此时,即使当前的\(v_t\)很小,但\(mod_t\)仍然保持在一个相对较高的水平。因此,\(v_t^{'} = \min(v_t, mod_t) = v_t\)(如果\(v_t < mod_t\))?这里需要仔细看:实际上,后期\(v_t\)会小于\(mod_t\),所以\(v_t^{'}\)被限制为不大于\(mod_t\),但\(v_t\)本身已经很小,所以\(v_t^{'} = v_t\)?不,关键点在于偏差修正后的 \(\hat{v}_t\)。在训练后期,\(t\)很大,\(1/(1-\beta_2^t) \approx 1\),所以\(\hat{v}_t \approx v_t\)。由于\(v_t\)很小,而\(mod_t\)较大,所以\(\min(\hat{v}_t, \hat{mod}_t) = \hat{v}_t\)。这看起来没有裁剪?
- 更精确的理解在于偏差修正。AdaMod原论文中对\(mod_t\)不进行\((1-\beta_3^t)\)的修正,而对\(v_t\)进行修正。在训练初期(\(t\)较小),\(\hat{v}_t = v_t / (1-\beta_2^t)\)会被放大(因为分母很小)。而被放大的\(\hat{v}_t\)可能会超过相对稳定的\(mod_t\)。此时,\(\min(\hat{v}_t, mod_t) = mod_t\),从而裁剪了初期被放大的二阶矩估计,防止了学习率在初期过小。在训练后期,\(\hat{v}_t \approx v_t\),且通常小于\(mod_t\),所以裁剪不生效。但其核心稳定作用体现在防止后期学习率过大吗? 仔细分析,后期\(v_t\)小,如果没裁剪,学习率\(\eta/\sqrt{v_t}\)会很大。但被裁剪后,如果\(v_t < mod_t\),仍然用\(v_t\),学习率还是大。这里似乎矛盾?
- 实际上,AdaMod的稳定机制更微妙。它通过在每一步用\(mod_t\)限制当前\(v_t\)的上限,而这个上限是基于历史梯度幅值的、单调不减的平滑估计。这意味着,有效学习率的分母\(\sqrt{v_t^{'}}\)有一个下限(即\(\sqrt{mod_t}\))。换句话说,学习率\(\eta / \sqrt{v_t^{'}}\)有一个上限(即\(\eta / \sqrt{mod_t}\))。由于\(mod_t\)增长缓慢且不会下降,这个学习率上限在训练过程中是缓慢下降或保持稳定的,从而防止了学习率在训练后期因梯度变小而爆炸性增长。这才是“自适应边界”的核心:它为每一步的适应性子学习率设置了一个动态的、保守的、不会缩小的上限。
-
核心优势:
- 训练稳定性提升:通过限制学习率的上限,有效缓解了Adam类优化器在训练后期可能出现的振荡或发散问题。
- 潜在的泛化性能提升:更稳定的学习率调度有助于模型收敛到更平坦的极小值,而平坦极小值通常被认为具有更好的泛化能力。
- 超参数鲁棒性:对初始学习率\(\eta\)的选择可能比Adam更不敏感,因为边界机制提供了一定的自动调节能力。
第五步:总结与实现要点
- 算法本质:AdaMod是Adam的一个变体,在Adam的自适应学习率分母(\(\sqrt{\hat{v}_t}\))上施加了一个自适应的、单调不减的上界约束。这个上界是通过对梯度二阶矩的指数移动平均值(\(b_t\))再取指数移动最大值(\(mod_t\))得到的。
- 关键超参数:除了Adam的\(\beta_1, \beta_2, \epsilon, \eta\),AdaMod引入了边界衰减率\(\beta_3\),它控制着边界\(mod_t\)的“记忆长度”和增长平滑度。\(\beta_3\)越接近1,边界增长越缓慢、越平滑,约束也越强。
- 实现注意事项:
- 偏差修正的处理需要小心。常见做法是对\(m_t\)和\(v_t\)进行修正,但对\(mod_t\)不进行\((1-\beta_3^t)\)的修正。
- 在计算\(v_t^{'}\)时,使用修正后的\(\hat{v}_t\)和\(mod_t\)(或未修正的\(mod_t\))。
- \(b_t\)的更新与\(v_t\)完全独立,尽管公式相似。
- 与相关工作的区别:
- 与AMSGrad:AMSGrad也试图约束二阶矩,它使用 \(\hat{v}_t^{max} = \max(\hat{v}_{t-1}^{max}, \hat{v}_t)\),然后更新参数用 \(\hat{m}_t / \sqrt{\hat{v}_t^{max}}\)。AdaMod的\(mod_t\)计算更复杂(引入了额外的EMA平滑\(\beta_3\)和中间变量\(b_t\)),理论上能提供更平滑、更保守的边界。
- 与AdamW:AdamW解决了权重衰减与自适应学习率耦合的问题,而AdaMod解决的是学习率边界问题。两者可以结合(即AdaModW)。
通过以上步骤,AdaMod算法通过引入一个自适应边界机制,为Adam优化器的自适应学习率提供了一个稳定、单调的“天花板”,旨在提升训练后期的稳定性和模型的泛化性能。