跳转至

15.3 自适应学习率算法

15.3 自适应学习率算法⚓︎

15.3.1 AdaGrad⚓︎

Adaptive subgradient method.\(^{[1]}\)

AdaGrad是一个基于梯度的优化算法,它的主要功能是:它对不同的参数调整学习率,具体而言,对低频出现的参数进行大的更新,对高频出现的参数进行小的更新。因此,他很适合于处理稀疏数据。

在这之前,我们对于所有的参数使用相同的学习率进行更新。但 Adagrad 则不然,对不同的训练迭代次数t,AdaGrad 对每个参数都有一个不同的学习率。这里开方、除法和乘法的运算都是按元素运算的。这些按元素运算使得目标函数自变量中每个元素都分别拥有自己的学习率。

输入和参数⚓︎

  • \(\eta\) - 全局学习率
  • \(\epsilon\) - 用于数值稳定的小常数,建议缺省值为1e-6
  • \(r=0\) 初始值

算法⚓︎


计算梯度:\(g_t = \nabla_\theta J(\theta_{t-1})\)

累计平方梯度:\(r_t = r_{t-1} + g_t \odot g_t\)

计算梯度更新:\(\Delta \theta = {\eta \over \epsilon + \sqrt{r_t}} \odot g_t\)

更新参数:\(\theta_t=\theta_{t-1} - \Delta \theta\)


从AdaGrad算法中可以看出,随着算法不断迭代,\(r\)会越来越大,整体的学习率会越来越小。所以,一般来说AdaGrad算法一开始是激励收敛,到了后面就慢慢变成惩罚收敛,速度越来越慢。\(r\)值的变化如下:

  1. \(r_0 = 0\)
  2. \(r_1=g_1^2\)
  3. \(r_2=g_1^2+g_2^2\)
  4. \(r_3=g_1^2+g_2^2+g_3^2\)

在SGD中,随着梯度的增大,我们的学习步长应该是增大的。但是在AdaGrad中,随着梯度\(g\)的增大,\(r\)也在逐渐的增大,且在梯度更新时\(r\)在分母上,也就是整个学习率是减少的,这是为什么呢?

这是因为随着更新次数的增大,我们希望学习率越来越慢。因为我们认为在学习率的最初阶段,我们距离损失函数最优解还很远,随着更新次数的增加,越来越接近最优解,所以学习率也随之变慢。

但是当某个参数梯度较小时,累积和也会小,那么更新速度就大。

经验上已经发现,对于训练深度神经网络模型而言,从训练开始时积累梯度平方会导致有效学习率过早和过量的减小。AdaGrad在某些深度学习模型上效果不错,但不是全部。

实际效果⚓︎

表15-6 AdaGrad算法的学习率设置

初始学习率 损失函数值变化
eta=0.3
eta=0.5
eta=0.7

表15-6表明,我们设定不同的初始学习率,分别为0.3、0.5、0.7,可以看到学习率为0.7时,收敛得最快,只用1750个epoch;学习率为0.5时用了3000个epoch;学习率为0.3时用了8000个epoch。所以,对于AdaGrad来说,可以在开始时把学习率的值设置大一些,因为它会衰减得很快。

15.3.2 AdaDelta⚓︎

Adaptive Learning Rate Method. \(^{[2]}\)

AdaDelta法是AdaGrad 法的一个延伸,它旨在解决它学习率不断单调下降的问题。相比计算之前所有梯度值的平方和,AdaDelta法仅计算在一个大小为w的时间区间内梯度值的累积和。

但该方法并不会存储之前梯度的平方值,而是将梯度值累积值按如下的方式递归地定义:关于过去梯度值的衰减均值,当前时间的梯度均值是基于过去梯度均值和当前梯度值平方的加权平均,其中是类似上述动量项的权值。

输入和参数⚓︎

  • \(\epsilon\) - 用于数值稳定的小常数,建议缺省值为1e-5
  • \(\alpha \in [0,1)\) - 衰减速率,建议0.9
  • \(s\) - 累积变量,初始值0
  • \(r\) - 累积变量变化量,初始为0

算法⚓︎


计算梯度:\(g_t = \nabla_\theta J(\theta_{t-1})\)

累积平方梯度:\(s_t = \alpha \cdot s_{t-1} + (1-\alpha) \cdot g_t \odot g_t\)

计算梯度更新:\(\Delta \theta = \sqrt{r_{t-1} + \epsilon \over s_t + \epsilon} \odot g_t\)

更新梯度:\(\theta_t = \theta_{t-1} - \Delta \theta\)

更新变化量:\(r = \alpha \cdot r_{t-1} + (1-\alpha) \cdot \Delta \theta \odot \Delta \theta\)


实际效果⚓︎

表15-7 AdaDelta法的学习率设置

初始学习率 损失函数值
eta=0.1
eta=0.01

从表15-7可以看到,初始学习率设置为0.1或者0.01,对于本算法来说都是一样的,这是因为算法中用r来代替学习率。

15.3.3 均方根反向传播 RMSProp⚓︎

Root Mean Square Prop。\(^{[3]}\)

RMSprop 是由 Geoff Hinton 在他 Coursera 课程中提出的一种适应性学习率方法,至今仍未被公开发表。RMSprop法要解决AdaGrad的学习率缩减问题。

输入和参数⚓︎

  • \(\eta\) - 全局学习率,建议设置为0.001
  • \(\epsilon\) - 用于数值稳定的小常数,建议缺省值为1e-8
  • \(\alpha\) - 衰减速率,建议缺省取值0.9
  • \(r\) - 累积变量矩阵,与\(\theta\)尺寸相同,初始化为0

算法⚓︎


计算梯度:\(g_t = \nabla_\theta J(\theta_{t-1})\)

累计平方梯度:\(r = \alpha \cdot r + (1-\alpha)(g_t \odot g_t)\)

计算梯度更新:\(\Delta \theta = {\eta \over \sqrt{r + \epsilon}} \odot g_t\)

更新参数:\(\theta_{t}=\theta_{t-1} - \Delta \theta\)


RMSprop也将学习率除以了一个指数衰减的衰减均值。为了进一步优化损失函数在更新中存在摆动幅度过大的问题,并且进一步加快函数的收敛速度,RMSProp算法对权重\(W\)和偏置\(b\)的梯度使用了微分平方加权平均数,这种做法有利于消除了摆动幅度大的方向,用来修正摆动幅度,使得各个维度的摆动幅度都较小。另一方面也使得网络函数收敛更快。

其中,\(r\)值的变化如下:

  1. \(r_0 = 0\)
  2. \(r_1=0.1g_1^2\)
  3. \(r_2=0.9r_1+0.1g_2^2=0.09g_1^2+0.1g_2^2\)
  4. \(r_3=0.9r_2+0.1g_3^2=0.081g_1^2+0.09g_2^2+0.1g_3^2\)

与AdaGrad相比,\(r_3\)要小很多,那么计算出来的学习率也不会衰减的太厉害。注意,在计算梯度更新时,分母开始时是个小于1的数,而且非常小,所以如果全局学习率设置过大的话,比如0.1,将会造成开始的步子迈得太大,而且久久不能收缩步伐,损失值也降不下来。

实际效果⚓︎

表15-8 RMSProp的学习率设置

初始学习率 损失函数值
eta=0.1
迭代了10000次,损失值一直在0.005下不来,说明初始学习率太高了,需要给一个小一些的初值
eta=0.01
合适的学习率初值设置
eta=0.005
初值稍微小了些,造成迭代次数增加才能到达精度要求

从上面的试验可以看出,0.01是本示例最好的设置。

15.3.4 Adam - Adaptive Moment Estimation⚓︎

计算每个参数的自适应学习率,相当于RMSProp + Momentum的效果,Adam\(^{[4]}\)算法在RMSProp算法基础上对小批量随机梯度也做了指数加权移动平均。和AdaGrad算法、RMSProp算法以及AdaDelta算法一样,目标函数自变量中每个元素都分别拥有自己的学习率。

输入和参数⚓︎

  • \(t\) - 当前迭代次数
  • \(\eta\) - 全局学习率,建议缺省值为0.001
  • \(\epsilon\) - 用于数值稳定的小常数,建议缺省值为1e-8
  • \(\beta_1, \beta_2\) - 矩估计的指数衰减速率,\(\in[0,1)\),建议缺省值分别为0.9和0.999

算法⚓︎


计算梯度:\(g_t = \nabla_\theta J(\theta_{t-1})\)

计数器加一:\(t=t+1\)

更新有偏一阶矩估计:\(m_t = \beta_1 \cdot m_{t-1} + (1-\beta_1) \cdot g_t\)

更新有偏二阶矩估计:\(v_t = \beta_2 \cdot v_{t-1} + (1-\beta_2)(g_t \odot g_t)\)

修正一阶矩的偏差:\(\hat m_t = m_t / (1-\beta_1^t)\)

修正二阶矩的偏差:\(\hat v_t = v_t / (1-\beta_2^t)\)

计算梯度更新:\(\Delta \theta = \eta \cdot \hat m_t /(\epsilon + \sqrt{\hat v_t})\)

更新参数:\(\theta_t=\theta_{t-1} - \Delta \theta\)


实际效果⚓︎

表15-9 Adam法的学习率设置

初始学习率 损失函数值
eta=0.1
迭代了10000次,但是损失值没有降下来,因为初始学习率0.1太高了
eta=0.01
比较合适的学习率
eta=0.005
学习率较低
eta=0.001
初始学习率太低,收敛到目标损失值的速度慢

由于Adam继承了RMSProp的传统,所以学习率不宜设置太高,从表15-9的比较可以看到,初始学习率设置为0.01时比较理想。

代码位置⚓︎

ch15, Level3

参考文献⚓︎

[1] Duchi, J., Hazan, E., & Singer, Y. (2011). Adaptive subgradient methods for online learning and stochastic optimization. Journal of Machine Learning Research, 12(Jul), 2121-2159.

[2] Zeiler, M. D. (2012). ADADELTA: an adaptive learning rate method. arXiv preprint arXiv:1212.5701.

[3] Tieleman, T., & Hinton, G. (2012). Lecture 6.5-rmsprop: Divide the gradient by a running average of its recent magnitude. COURSERA: Neural networks for machine learning, 4(2), 26-31.

[4] Kingma, D. P., & Ba, J. (2014). Adam: A method for stochastic optimization. arXiv preprint arXiv:1412.6980.