优化算法 (机器学习)(TensorFlow)
RMSProp算法
RMSProp
算法作为将速率调度与坐标自适应学习率分离的简单修复方法。问题在于,Adagrad
算法将梯度RMSProp
算法。
算法
让我们详细写出这些方程式。
常数
总结
RMSProp
算法与Adagrad
算法非常相似,因为两者都使用梯度的平方来缩放系数。RMSProp
算法与动量法都使用泄漏平均值。但是,RMSProp
算法使用该技术来调整按系数顺序的预处理器。在实验中,学习率需要由实验者调度。系数
Adadelta算法
Adadelta
是AdaGrad
的另一种变体,主要区别在于前者减少了学习率适应坐标的数量。此外,广义上Adadelta
被称为没有学习率,因为它使用变化量本身作为未来变化的校准。Adadelta
使用两个状态变量,du jour
是
我们使用重新缩放的梯度
那么,调整后的梯度
其中
和
总结
Adadelta
没有学习率参数。相反,它使用参数本身的变化率来调整学习率。Adadelta
需要两个状态变量来存储梯度的二阶导数和参数的变化。Adadelta
使用泄漏的平均值来保持对适当统计数据的运行估计。
Adam算法
我们学习了:随机梯度下降在解决优化问题时比梯度下降更有效;在一个小批量中使用更大的观测值集,可以通过向量化提供额外效率。这是高效的多机、多GPU和整体并行处理的关键;我们添加了一种机制,用于汇总过去梯度的历史以加速收敛。我们通过对每个坐标缩放来实现高效计算的预处理器。我们通过学习率的调整来分离每个坐标的缩放。Adam
算法将所有这些技术汇总到一个高效的学习算法中。不出预料,作为深度学习中使用的更强大和有效的优化算法之一,它非常受欢迎。但是它并非没有问题,有时Adam
算法可能由于方差控制不良而发散。
算法
Adam
算法的关键组成部分之一是:它使用指数加权移动平均值来估算梯度的动量和二次矩,即它使用状态变量。
这里
有了正确的估计,我们现在可以写出更新方程。首先,我们以非常类似于RMSProp
算法的方式重新缩放梯度以获得
与RMSProp
不同,我们的更新使用动量RMSProp
算法有所区分。通常,我们选择
回顾Adam算法,它的设计灵感很清楚:首先,动量和规模在状态变量中清晰可见,它们相当独特的定义使我们移除偏项(这可以通过稍微不同的初始化和更新条件来修正)。其次,RMSProp
算法中两项的组合都非常简单。最后,明确的学习率
Adam
算法也存在一些问题:即使在凸环境下,当Adam
算法更新如下:
每当Yogi
更新,现在更新的规模不再取决于偏差的量。
论文中,作者还进一步建议用更大的初始批量来初始化动量,而不仅仅是初始的逐点估计。
总结
Adam
算法将许多优化算法的功能结合到了相当强大的更新规则中。Adam
算法在RMSProp
算法基础上创建的,还在小批量的随机梯度上使用EWMA
。在估计动量和二次矩时,Adam
算法使用偏差校正来调整缓慢的启动速度。对于具有显著差异的梯度,我们可能会遇到收敛性问题。我们可以通过使用更大的小批量或者切换到改进的估计值Yogi
提供了这样的替代方案。
学习率调度器
到目前为止,我们主要关注如何更新权重向量的优化算法,而不是它们的更新速率。然而,调整学习率通常与实际算法同样重要,有如下几方面需要考虑:
- 首先,学习率的大小很重要。如果它太大,优化就会发散;如果它太小,训练就会需要过长时间,或者我们最终只能得到次优的结果。我们之前看到问题的条件数很重要。直观地说,这是最不敏感与最敏感方向的变化量的比率。
- 其次,衰减速率同样很重要。如果学习率持续过高,我们可能最终会在最小值附近弹跳,从而无法达到最优解。简而言之,我们希望速率衰减,但要比
慢,这样能成为解决凸问题的不错选择。 - 另一个同样重要的方面是初始化。这既涉及参数最初的设置方式,又关系到它们最初的演变方式。这被戏称为预热(
warmup
),即我们最初开始向着解决方案迈进的速度有多快。一开始的大步可能没有好处,特别是因为最初的参数集是随机的。最初的更新方向可能也是毫无意义的。 - 最后,还有许多优化变体可以执行周期性学习率调整。
鉴于管理学习率需要很多细节,因此大多数深度学习框架都有自动应对这个问题的工具。
策略
虽然我们不可能涵盖所有类型的学习率调度器,但我们会尝试在下面简要概述常用的策略:多项式衰减和分段常数表。 此外,余弦学习率调度在实践中的一些问题上运行效果很好。在某些问题上,最好在使用较高的学习率之前预热优化器。
单因子调度器
多项式衰减的一种替代方案是乘法衰减,即
1 | class FactorScheduler: |
多因子调度器
训练深度网络的常见策略之一是保持学习率为一组分段的常量,并且不时地按给定的参数对学习率做乘法衰减。具体地说,给定一组降低学习率的时间点,例如
1 | class MultiFactorScheduler: |
这种分段恒定学习率调度背后的直觉是,让优化持续进行,直到权重向量的分布达到一个驻点。此时,我们才将学习率降低,以获得更高质量的代理来达到一个良好的局部最小值。
余弦调度器
余弦调度器是提出的一种启发式算法。它所依据的观点是:我们可能不想在一开始就太大地降低学习率,而且可能希望最终能用非常小的学习率来“改进”解决方案。这产生了一个类似于余弦的调度,函数形式如下所示,学习率的值在
这里
1 | class CosineScheduler: |
预热
在某些情况下,初始化参数不足以得到良好的解。这对某些高级网络设计来说尤其棘手,可能导致不稳定的优化结果。对此,一方面,我们可以选择一个足够小的学习率,从而防止一开始发散,然而这样进展太缓慢。另一方面,较高的学习率最初就会导致发散。解决这种困境的一个相当简单的解决方法是使用预热期,在此期间学习率将增加至初始最大值,然后冷却直到优化过程结束。为了简单起见,通常使用线性递增。预热可以应用于任何调度器,而不仅仅是余弦。其中,这篇论文的点睛之笔的发现:预热阶段限制了非常深的网络中参数的发散程度 。这在直觉上是有道理的:在网络中那些一开始花费最多时间取得进展的部分,随机初始化会产生巨大的发散。
总结
在训练期间逐步降低学习率可以提高准确性,并且减少模型的过拟合。在实验中,每当进展趋于稳定时就降低学习率,这是很有效的。从本质上说,这可以确保我们有效地收敛到一个适当的解,也只有这样才能通过降低学习率来减小参数的固有方差。余弦调度器在某些计算机视觉问题中很受欢迎。优化之前的预热期可以防止发散。优化在深度学习中有多种用途。对于同样的训练误差而言,选择不同的优化算法和学习率调度,除了最大限度地减少训练时间,可以导致测试集上不同的泛化和过拟合量。