menu

梯度下降 之 优化算法(上)

  • date_range 13/09/2018 15:02 info
    sort label

尽管梯度下降可以帮助我们更快地寻找到模型的最优解,但是,仍然面对诸多问题。解决这些问题的方法,被称为梯度下降优化方法。本文将详述流行的梯度下降优化方法。

挑战

  • 选择一个合适的学习率很难。学习率过小会导致收敛过慢;学习率过大会导致不收敛或者损失函数在最小波动(甚至偏离最小位置)

  • 预定义learning rate的变化。通过预定义 learning rate, 使不同的迭代次数,对应着不同的learning rate。这种方式可以在一定程度上提高训练的收敛速度、缓解在最小位置出的波动,但是需要预定,并很难预定义。

在预定义阶段,可以先预定义 learning rate (比如 1e-2),进行训练,观察loss曲线的变化,找到loss非收敛初对应的迭代次数(比如30epoch), 然后更新 learning rate集合 [0 : 1e-2, 30: 1e-3]。 重新训练,继续观察,直至达到理想的loss值

  • 不同的参数对应着同样的学习率。如果训练样本是稀疏的,模型参数具在不同阈值范围,在更新参数的时候,根据不同阈值下的模型参数对应不同的学习率可能会更好

  • 另一个挑战是 优化方法往往会寻找到非凸模型被困在局部最小位置处,而这些最小位置处周围的值往往比较大而且最小位置处往往也比较平坦,这样使梯度向量在各个方向近似为0,SGD无法脱离该处。

梯度下降优化算法

下面,我们将详述被广泛用于深度学习的一些方法,这里不会讨论不易在实践中使用的方法(比如 二次导方法 Newton’s Method)。

Momentum

SGD 在跨过“沟壑”会遇到很多问题,所谓的沟壑, 如下图这个模型,在沟壑处,SGD会左右摆动,而这些摆动则是无意义的.

Momentum就是一种减少这种无意义摆动,并且加速往真正有意义的方向前进的方法. 结合前一次的梯度向量和当前的梯度向量,如下述公式:

其中,$\gamma$是前一次的梯度向量的权重,$\eta$是学习率, $\Delta_\theta J(\theta)$是当前计算出来的梯度向量。

$\gamma$ 往往选取 0.9 或者相似的值

拿一个球在山坡上滚落来说,实质上,增加momentum,类似于给球的下落增加了惯性的因子,当球在下坡阶段,下降速度会不断增加,当球由下坡阶段进入上坡阶段,球仍会上升一段距离,当球左右摆动的时候,惯性会趋于让其停止。(这估计就是为什么叫做momentum的缘由吧)

Nesterov Momentum

Nesterov Momentum 与标准的mementum有些不同,它在解决凸函数的时候,在理论上更加有效。

如果当前小球所在位置 $x$,针对标准的momentum,会使用上次的梯度向量,然后计算当前位置的梯度向量,最后再把两个梯度向量合并在一起;而对于Nesterov Momentum则不然,会利用上次的梯度向量更新$x$,近似为新的位置,然后再新位置出计算梯度向量,然后再合并上次梯度梯度向量和新位置的梯度向量,最后利用合并后的梯度向量更新当前位置$x$。它的公式如下:

Adagrad

Adagrad 是梯度更新的优化方法,它通过根据参数来调整学习率。比如经常出现的特征,对应的学习率会变低,而不经常出现的特征,学习率会变高。基于这个原因,Adagrad往往更适用于稀疏数据的训练。

上述中,针对所有的参数,我们的学习率都是使用同一个参数$\eta$。而Adagrad则不然。记每次迭代$t$下的不同的参数$\theta_i$,$g_t$是$t$次迭代的梯度向量,$g_{t,i}$ 是 $g_t$ 关于 $\theta_i$的偏导数,

那么,在$t$次迭代,SGD针对每个$\theta_i$的更新有如下公式:

而,Adagra更改通用的学习率,如下述公式:

其中,$G_t\in \mathbb{R}^{d\times d}$是对角矩阵,每个位置$(i, i)$出的值为$\theta_i$的梯度(包含历史)开方之和,$\epsilon$ 是平滑因子,用于避免除零(通常为$1e-8$)。比较有趣的是,如果不用$\sqrt{}$,则算法的表现便会比较糟糕。

由于$G_t$包含了所有参数的历史梯度之和,我们可以利用矩阵向量相乘符号$\odot$向量化参数更新公式,如下:

Adagrad的一个主要的好处是不需要手动调整学习率。

Adagrad的缺点坟墓中有平方根操作,这就导致每个增加的都是正的,随着训练的增加,分母的值会不断上升,到最后,学习率会被调节成非常小的值,后续的训练,网络本身则不会学到更多东西。下述优化方法的引入,就是为了解决这一问题。

Adadelta

Adadelta是用于弥补Adagrad缺陷的算法,相比Adagrad而言,Adadelta引入了一个用于计算梯度平方之和的窗口 $\omega$。

相比保存$\omega$个以前的梯度平方而言,在$t$次迭代的时候,这里采用了一种迭代的方式来计算所有以前的平均梯度平方 $E[g^2]_t$。类似于Momentum,这里引入$\gamma$:

通过这种递归的方式,可以实现窗口的目的。比如 $x_t = \gamma x_{t-1}$,进行100次递归调用,$x_t = \gamma^{100} x_{t-100}$,如果$\gamma=0.9$,

那么$\gamma^{100} = 2.65\times 10^{-5}$,可见通过$\gamma$是可以达到窗口的效果的。

类似于Momentum中的$\gamma$选项,我们设置$\gamma$在0.9左右,那么现在的梯度向量更新公式则变成下述公式:

Autograd中的参数更新向量$\Delta\theta$为下述:

那在Autodelta中,我们只要将$G_t$替换为之前梯度向量的$E[g^2]_t$:

由于分母是平方平均根 (Root Mean Square),我们可以将上述公式简写为:

然而这种方法仍然会有默认的学习率$\eta$, 为了进一步替代掉这个学习率,该方法的继续使用$\gamma$作为窗口的衰减系数,有如下公式:

然后,

最后,我们将学习率$\eta$替换为$\mathop{RMS}[\Delta\theta]_t$,如下:

在第一步骤的时候由于无法计算$\mathop{RMS}[\Delta\theta]_t$,我们拿$g_t$作为近似。

RMSprop

RMSProp是一种为公开的方法,他在Geoff Hinton的课程中有所讲述。它与Adadelta是同一时期出现的,主要是为了解决Adagrad的学习率急剧下降的问题。

实际上,RMSprop只是Adadelta的中间方程:

其中$\eta$最佳的初始值是0.001。


上面讲述了,一些梯度下降的优化方法,后续文章我们继续这方面的算法