五、自适应学习率算法
假设代价函数高度敏感于参数空间中的某些方向,则优化算法最好针对不同的参数设置不同的学习率。
- 代价函数变化明显的参数方向(偏导数较大):学习率较小,使得更新的步长较小。
- 代价函数变化不明显的参数方向(偏导数较小):学习率较大,使得更新的步长较大。
对于标准的
batch
梯度下降优化算法,沿着负梯度的方向就是使得代价函数下降的方向。- 如果不同的方向设置了不同的学习率,则前进的方向不再是负梯度方向,有可能出现代价函数上升。
- 对于
mini-batch
梯度下降,由于对梯度引入了躁扰,因此可以针对不同的方向设置不同的学习率。
选择哪个算法并没有一个统一的共识,并没有哪一个算法表现的最好。
目前流行的优化算法包括:
SGD
,具有动量的SGD
,RMSProp
,AdaDelta
,Adam
。选用哪个算法似乎主要取决于使用者对于算法的熟悉程度,以便调节超参数。
5.1 delta-bar-delta
delta-bar-delta
算法是一个自适应学习率的算法,其策略是:对于代价函数,如果其偏导数保持相同的符号,则该方向的学习率应该增加;如果偏导数变化了符号,则该方向的学习率应该减小。偏导数符号变化,说明更新的方向发生了反向。如果此时降低了学习率,则会对震荡执行衰减,会更有利于到达平衡点(偏导数为0的位置)。
delta-bar-delta
算法只能用于标准的梯度下降中。mini-batch
算法对于梯度的估计不是精确的,因此对于正负号的判断会出现较大偏差。对于
mini-batch
随机梯度下降,有一些自适应学习率的算法。包括:AdaGrad、RMSProp、Adam
等算法。
5.2 AdaGrad
AdaGrad
算法会独立设置参数空间每个轴方向上的学习率。- 如果代价函数在某个方向上具有较大的偏导数,则这个方向上的学习率会相应降低。
- 如果代价函数在某个方向上具有较小的偏导数,则这个方向上的学习率会相应提高。
AdaGrad
算法的思想是:参数空间每个方向的学习率反比于某个值的平方根。这个值就是该方向上梯度分量的所有历史平方值之和。其中 表示两个向量的逐元素的相乘。
- 用平方和的平方根而不是均值,因为分量可能为负值。
- 用历史结果累加,因为考虑的是该方向上的平均表现,而不仅仅是单次的表现。
AdaGrad
算法:输入:
- 全局学习率
- 初始参数
- 小常数 (为了数值稳定,大约为 )
算法步骤:
初始化梯度累计变量
迭代,直到停止条件。迭代步骤为:
从训练集中随机采样 个样本 构成
mini-batch
,对应的标记为 。计算
mini-batch
上的梯度作为训练集的梯度的估计:累计平方梯度:
计算更新(逐元素):
更新参数:
由于随迭代次数的增加, 的值也会增加,因此 随着迭代的推进而降低。这起到了一个学习率衰减的效果。
另一方面,不同方向的分量 不同,平均来说梯度分量越大的方向的学习率下降的最快。这起到了一个自适应的效果。
效果:
在凸优化中,
AdaGrad
算法效果较好。AdaGrad
算法在某些深度学习模型上效果不错,但大多数情况下效果不好。在训练深度神经网络模型的实践中发现:
AdaGrad
学习速率减小的时机过早,且减小的幅度过量。因为学习率与历史梯度的平方和的开方成反比,导致过快、过多的下降。
5.3 RMSProp
5.3.1 RMSProp 原始算法
RMSProp
是AdaGrad
的一个修改:将梯度累计策略修改为指数加权的移动平均。其中 为衰减速率,它决定了指数加权移动平均的有效长度。
标准的
RMSProp
算法:输入:
- 全局学习率
- 衰减速率
- 初始参数
- 小常数 (为了数值稳定,大约为 )
算法步骤:
初始化梯度累计变量
迭代,直到停止条件。迭代步骤为:
从训练集中随机采样 个样本 构成
mini-batch
,对应的标记为 。计算
mini-batch
上的梯度作为训练集的梯度的估计:累计平方梯度:
计算更新(逐元素):
更新参数:
实践证明
RMSProp
是一种有效、实用的深度神经网络优化算法,目前它是深度学习业界经常采用的优化方法之一。
5.3.2 RMSProp 原始算法性质
假设迭代过程中,梯度刚好是固定的某个量,令 。对于某个方向,假设其分量为 。
对于
RMSProp
算法:根据等比数列求和公式,该方向的比例因子为: ,其中 为迭代次数。该方向的学习率为:
- 随着 的增大, 会减小,因为分母在增加。
- 在 逐渐增大时,从 增加到 ,其取值范围有限。它使得 取值从 降低到 。
当某个方向的导数 相对于 较大时,更新步长为(考虑到 ):
- 它与梯度无关,只与迭代次数 有关。
- 随着 增大,从 降低到 。
RMSProP
算法确保了在梯度较大时,学习的步长不会很小。
当导数 非常小以至于和 相差无几时,此时更新步长与梯度有关。
但是由于此时梯度非常小,算法可能已经收敛。
对于
AdaGrad
算法的情况:根据等差数列的求和公式,该方向的比例因子为: ,其中 为迭代次数。该方向的学习率为:
- 随着 的增大, 会减小,因为分母在增加。
- 在 逐渐增大时,从 增加到 。从而使得 取值从 降低到 。
当该方向的梯度对于 较大时,更新步长为:
它与梯度无关,只与迭代次数 有关。随着 增大,从 降低到 。
因此,即使此时的梯度仍然较大,学习的步长仍然接近 0 。
RMSProp
算法vs AdaGrad
算法:AdaGrad
算法中,随着迭代次数的增加,其学习率降低到 0。 而RMSProp
算法中,学习率降低到一个较大的渐进值 。AdaGrad
算法中,随着迭代次数的增加,更新步长降低到 0 。而RMSProp
算法中,更新步长降低到一个较大的值 。
5.3.3 RMSProp 动量算法
RMSProp
也可以结合Nesterov
动量算法。本质上
Nesterov
算法(包括其他的动量算法)是关于如何更新参数 的算法,它并不涉及任何学习率 的选取。RMSProp
算法是关于如何选取学习率 的算法,它并不涉及如何更新参数 。因此二者可以结合。RMSProp
动量算法输入:
- 全局学习率
- 衰减速率
- 动量系数
- 初始参数
- 初始速度
算法步骤:
初始化梯度累计变量
迭代,直到停止条件。迭代步骤为:
从训练集中随机采样 个样本 构成
mini-batch
,对应的标记为计算临时更新:
这是因为
Nesterov
动量算法使用更新后的参数来计算代价函数。如果使用原始的动量算法,则不需要这一步。计算
mini-batch
上的梯度作为训练集的梯度的估计:累计平方梯度:
计算速度更新(逐元素):
更新参数:
5.3.4 AdaDelta
AdaDelta
也是AdaGrad
的一个修改。AdaDelta
将梯度平方和的累计策略修改为:只考虑过去窗口 内的梯度。RMSProp
可以认为是一种软化的AdaDelta
,衰减速率 决定了一个软窗口: 。- 加权梯度平方和主要由 内的梯度决定。
- 更早的梯度由于衰减,其贡献非常小。
5.4 Adam
Adam
来自于Adaptive moments
,它是另一种引入了动量的RMSProp
算法。
5.4.1 Adam 算法
Adam
算法:输入:
- 学习率 (建议默认为 0.001)
- 矩估计的指数衰减速率 ,它们都位于区间 (建议默认值分别为: 0.9 和 0.999)
- 用于数值稳定的小常数 (建议默认为 )
- 初始参数
算法步骤:
初始化一阶和二阶矩变量
初始化时间步
迭代,直到停止条件。迭代步骤为:
从训练集中随机采样 个样本 构成
mini-batch
,对应的标记为计算
mini-batch
上的梯度作为训练集的梯度的估计:更新有偏一阶矩估计: 。
它是梯度的指数加权平均,用于计算梯度。
更新有偏二阶矩估计: 。
它是梯度平方的指数加权平均,用于计算学习率。
修正一阶矩的偏差: 。
它使得修正之后的结果更接近真实的梯度。
修正二阶矩的偏差: 。
它使得修正之后的结果更接近真实的梯度平方。
计算更新(逐元素):
更新参数:
RMSProp
算法中,通过累计平方梯度(采用指数移动平均)来修正学习率。而
Adam
算法中,不仅采用同样的方式来修正学习率,还通过累计梯度(采用指数移动平均) 来修正梯度。动量的计算可以类似
Nesterov
动量的思想:计算mini-batch
的梯度时,采用更新后的参数 。此时称作
NAdam
算法。
5.4.2 Adam 算法性质
假设迭代过程中,梯度刚好是固定的某个量,则有: 。对于某个方向,假设其分量为 ,则对于
Adam
算法有:无论梯度的大小如何,
Adam
算法的参数更新步长几乎都是相比较而言,
AdaGrad
和RMSProp
算法的参数更新步长随时间在减少。虽然最终结果不包含 ,但是这是由于假定梯度保持不变这一特殊情况推导的。
实际中梯度很少保持不变,因此 还是比较重要。
Adam
算法之所以需要使用一阶矩的修正和二阶矩的修正,是为了剔除时间因子 的影响。在某些情况下,
Adam
可能导致训练不收敛。主要原因是:随着时间窗口的变化,遇到的数据可能发生巨变。这就使得 可能会时大时小,从而使得调整后的学习率 不再是单调递减的。这种学习率的震荡可能导致模型无法收敛。
AdaDelta
、RMSProp
算法也都存在这样的问题。解决方案为:对二阶动量的变化进行控制,避免其上下波动(确保 是单调递增的):
实践证明,虽然在训练早期
Adam
具有很好的收敛速度,但是最终模型的泛化能力并不如使用朴素的SGD
训练得到的模型好:Adam
训练的模型得到的测试集误差会更大。其主要原因可能是:训练后期,
Adam
的更新步长过小。一种改进策略为:在训练的初期使用
Adam
来加速训练,并在合适的时期切换为SGD
来追求更好的泛化性能。这种策略的缺陷是:切换的时机不好把握,需要人工经验来干预。
5.5 SGD 及其变种的比较
下图为
SGD
及其不同的变种在代价函数的等高面中的学习过程。这里batch-size
为全体样本大小。AdaGrad
、Adadelta
、RMSprop
从最开始就找到了正确的方向并快速收敛。SGD
找到了正确的方向,但是收敛速度很慢。SGD
的动量算法、Netsterov
动量算法(也叫做NAG
) 最初都偏离了正确方向,但最终都纠正到了正确方向。
下图为
SGD
及其不同的变种在代价函数的鞍点上的学习过程。这里batch-size
为全体样本大小。SGD
、SGD
的动量算法、Netsterov
动量算法(也叫做NAG
) 都受到鞍点的严重影响。SGD
最终停留在鞍点。如果采用
mini-batch
,则mini-batch
引入的梯度噪音,可以使得SGD
能够逃离鞍点。SGD
的动量算法、Netsterov
动量算法最终逃离了鞍点。
Adadelta
、Adagrad
、RMSprop
都很快找到了正确的方向。