梯度下降优化算法总结

本次介绍梯度下降优化算法。主要参考资料为一篇综述《An overview of gradient descent optimization algorithms》

1. 引言

梯度下降 是一种目前相当火的优化算法,因为神经网络模型基本都依赖其训练。

绝大部分优化问题都可以转化为下面的问题:

给定一个与参数 \(\theta \) 有关的目标函数 \(J(\theta)\), 求使得 \(J\) 最小的参数 \(\theta \).

针对此类问题, 梯度下降通过不断往梯度的负方向移动参数来求解。

2. 梯度下降算法变种

梯度下降算法主要有三种变种,主要区别在于使用多少数据来计算目标函数的梯度。 不同方法主要在准确性和优化速度间做权衡。

2-1 Batch gradient descent (BGD)

Vanilla gradient descent 又称为 Batch gradient descent (BGD),其需要计算整个训练集的梯度,即:

\(\theta = \theta -\eta \nabla_{\theta}J(\theta)\) ,其中 \(\eta\) 为学习率,用来控制更新的“力度”。

优点:

对于凸目标函数,可以保证全局最优; 对于非凸目标函数,可以保证一个局部最优。

缺点:

速度慢; 数据量大时不可行; 无法在线优化(即无法处理动态产生的新样本)。

2-2 Stochastic gradient descent (SGD)

Stochastic gradient descent (SGD),仅计算某个样本的梯度,即针对某一个训练样本 \(x^i\) 及其label \(y^i\)更新参数:

\(\theta = \theta -\eta \nabla_{\theta}J(\theta;x^i,y^i)\)

逐步减小学习率,SGD表现得同BGD很相似,最后都可以有不错的收敛。

优点:

更新频次快,优化速度更快; 可以在线优化(可以无法处理动态产生的新样本);一定的随机性导致有几率跳出局部最优(随机性来自于用一个样本的梯度去代替整体样本的梯度)

缺点:

随机性可能导致收敛复杂化,即使到达最优点仍然会进行过度优化,因此SGD得优化过程相比BGD充满动荡;

2-3 Mini-batch gradient descent (MBGD)

Mini-batch gradient descent (MBGD) 计算包含\(n\) 个样本的mini-batch的梯度

\(\theta = \theta -\eta \nabla_{\theta}J(\theta;x^{(i:i+n)},y^{(i:i+n)})\)

MBGD是训练神经网络最常用的优化方法。

优点:

参数更新时的动荡变小,收敛过程更稳定,降低收敛难度;可以利用现有的线性代数库高效的计算多个样本的梯度。

3. 挑战

由第2节来看, Mini-batch gradient descent (MBGD) 是一种相对较好的策略,但同样不能保证一个最优解。此外,这里还存在很多问题需要处理:

1. 如何选择合适的学习率?。

学习率过小导致收敛太慢,过大又导致收敛动荡甚至偏离最优点。

2. 如何确定学习率的调整策略?

目前调整学习率基本都按照一种 “退火”的思想,要么按照预定模式调整,要么根据目标函数值的变化是否满足阈值动态改变学习率。 但是,“模式”和“阈值”都需要事先指定,无法自适应不同数据集。

3. 对所有参数的更新采用相同的学习率是否恰当?

如果数据是稀疏的且特征分布不均,似乎我们更应该给予较少出现的特征一个大的更新。

4. 如何跳出局部最优?

理论上只有严格的凸函数才可以通过梯度下降获得全局最优解。 但是,神经网络所面临的基本上都是严重非凸的目标函数,这也意味着优化容易陷入局部最优。 事实上,我们的困难往往来自 “鞍点” 而非局部极小点。 鞍点周围通常拥有相同的损失函数值,这导致SGD很难发挥作用,因为每个方向的梯度都接近于0.

4. 梯度下降优化算法

下面介绍一些在深度学习中常用的用以解决上述问题的梯度下降优化方法。 一些对高维数据不可行的方法不再讨论,如二阶方法中的牛顿法。

4-1 Momentum

以下图a为例,面对某一方向上特别陡峭的目标函数曲面,SGD可能会表现得踌躇不前(来回波动)。

float

动量的引入是为了加速SGD的优化过程。

\(\nu_t = \gamma\nu_{t-1} + \eta \nabla_{\theta}J(\theta)\)

\(\theta = \theta - \nu_t\)

分析上式就会明白动量的作用原理:利用惯性,即当前梯度与上次梯度进行加权,如果方向一致,则累加导致更新步长变大;如果方向不同,则相互抵消中和导致更新趋向平衡。

动量 \(\gamma\) 常被设定为0.9或者一个相近的值。

4-2 Nesterov accelerated gradient

带动量的SGD可以加速超车,但是却不知道快到达终点时减速。 Nesterov accelerated gradient (NAG)就是用来解决这个问题的。

\(\nu_t = \gamma\nu_{t-1} + \eta \nabla_{\theta}J(\theta-\gamma\nu_{t-1})\)

\(\theta = \theta - \nu_t\)

很明显,同带动量的SGD相比,梯度不是根据当前位置 \(\theta\) 计算出来的,而是在移动之后的位置\((\theta-\gamma\nu_{t-1})\)计算梯度。 (已经确定会移动 \(\gamma\nu_{t-1}\),那不如之前去看移动后的梯度)。

这个改进的目的就是为了提前看到前方的梯度。如果前方的梯度和当前梯度目标一致,那我直接大步迈过去; 如果前方梯度同当前梯度不一致,那我就小心点更新。

下面是一个示意图:

float

蓝色线表示正常的带动量SGD的两次移动; 棕色线是计划移动的量( \(\gamma\nu_{t-1}\) ); 红色线是在移动后位置计算的移动量; 棕色线和红色线的合并效果就是绿色线NAG。

4-3 Adagrad

针对挑战3.3,Adagrad 为出现频率不高的参数提供一个大学习率,为经常出现的参数提供较小的学习率。

Adagrad为每一个参数 \(\theta_i\) 提供了一个与自身相关的学习率:

\(\theta_{t+1,i} = \theta_{t,i} - \frac{\eta }{\sqrt{G_{t,ii} + \epsilon}}\nabla_{\theta}J(\theta_{t,i})\)

其中 \(G_{t}\) 为一个对角矩阵,其对角上的每一个元素 \(G_{t,ii}\) 为 \(t\)时刻前所有施加到参数 \(\theta_i\) 上的梯度的平方的和。 \(\epsilon\) 用来防止除0操作,通常设置为 \(10^{-8}\). 实验表明,如果分母不开方,性能会很差。

简单分析上式,有三点结论:

(1) 经常出现(累积梯度大)的参数的学习率会被拉低,较少出现(累积梯度小)的参数的学习率会被拉高;

(2) 随着训练次数增加,累积梯度肯定会上升,导致分母变大,则学习率会自动下降。因此,Adagrad可以自动调节学习率,而我们只需给其一个初始学习率即可;

(3) 同样是随着训练参数增加,学习率会下降的很快,这可能导致后期学习率过低而学不到东西。

4-4 Adadelta

由于Adagrad采用了以往所有梯度平方之和,因此会导致累计梯度持续增加,最后因为学习率过低而学不到东西。为了解决该问题,这里引入Adadelta: 仅采用一个窗口范围内的梯度平方之和。

具体地,采用滑动窗口的方法计算梯度平方和的滑动平均值:

\(G_t \leftarrow E[g^2]_t=\gamma E[g^2]_{t-1} + (1-\gamma)g^2_t\)

其中 \(\gamma\) 为滑动系数,通常被设置为0.9.

于是,最终的Adadelta的更新策略为:

\( \Delta\theta_{t} = - \frac{\eta }{\sqrt{E[g^2]_t + \epsilon}}g_t\)

\(\theta_{t} = \theta_{t} + \Delta\theta_{t}\)

此外,上面计算 \(\Delta\theta_{t}\)的等式中等号两边的单位并不一致。 左边为 \(\theta \) 的单位,而右边的单位却是 \(\frac{g的单位}{g的单位} = 1\) 这一问题同样存在与SGD、带动量SGD以及Adagrad中。

解决方案如下,人为给等号右边增加一个单位:

\(\eta \leftarrow E[\Delta\theta^2]_t=\gamma E[\Delta\theta^2]_{t-1} + (1-\gamma)\Delta\theta^2_t\)

\( \Delta\theta_{t} = - \frac{\sqrt{E[\Delta\theta^2]_{t} + \epsilon}}{\sqrt{E[g^2]_t + \epsilon}}g_t\)

由于 \(t\) 时刻的 \(\Delta\theta_t\)不知道,因此用 \(t-1\) 时刻近似。

\(E[\Delta\theta^2]_t \rightarrow E[\Delta\theta^2]_{t-1}\)

\( \Delta\theta_{t} = - \frac{\sqrt{E[\Delta\theta^2]_{t-1} + \epsilon}}{\sqrt{E[g^2]_t + \epsilon}}g_t\)

由上式可以看出,Adadelta已经无需设置初始学习率了,其可以自动计算并更新学习率。

4-5 RMSprop

RMSprop是一种未公开发表的方法,来自于Hinton的Coursera公开课。 RMSprop基本上等同于未做 单位统一 的Adadelta。

\( E[g^2]_t=\gamma E[g^2]_{t-1} + (1-\gamma)g^2_t\)

\( \theta_{t+1} = \theta_{t} - \frac{\eta }{\sqrt{E[g^2]_t + \epsilon}}g_t\)

Hinton建议滑动系数 \(\gamma\) 设置为0.9, 初始学习率 \(\eta\) 设置为0.001.

4-6 Adam

Adaptive Moment Estimation (自适应矩估计Adam)是另外一种为每个参数提供自适应学习率的方法。
同RMSprop、Adadelta相比,Adam在对梯度平方(二阶矩)估计的基础上增加了对梯度(一阶矩)的估计,使得整个学习过程更加稳定。

\( E[g]_t=\beta_1 E[g]_{t-1} + (1-\beta_1)g_t\)

\( E[g^2]_t=\beta_2 E[g^2]_{t-1} + (1-\beta_2)g^2_t\)

由于 \(E[g]_t\) 和 \(E[g^2]_t\)通常都初始化为0, 因此在训练初期或者 \(\beta_1,\beta_2\)接近1时,估计的期望往往偏向于0.

为了解决这种偏置,增加了偏基矫正:

\(\hat{E[g]_t} = \frac{E[g]_t}{1-\beta_1}\)

\(\hat{E[g^2]_t} = \frac{E[g^2]_t}{1-\beta_2}\)

于是最终的更新公式为:

\( \theta_{t+1} = \theta_{t} - \frac{\eta }{\sqrt{\hat{E[g^2]_t} + \epsilon}}\hat{E[g]_t} \)

通常 \(\beta_1,\beta_2\)分别被设置为0.9和0.999.

4-7 AdaMax

AdaMax是Adam的一种变种。主要是对原来的二阶矩估计扩展到无穷阶矩。(高阶矩往往不稳定,但无穷阶矩通常趋于稳定)

通过替换Adam中的分母项:

\(\sqrt{\hat{E[g^2]_t} + \epsilon} \quad\leftarrow \quad\mu_t = \beta_2^{\infty}\mu_{t-1}+(1-\beta_2^{\infty})g_t^{\infty} = max(\beta_2\mu_{t-1},|g_t|)\)

于是最终的更新公式为:

\( \theta_{t+1} = \theta_{t} - \frac{\eta }{\mu_t}\hat{E[g]_t} \)

注意,由于 \(\mu_t\)采用了 \(max\)操作,因此无需进行偏置矫正。 通常 \(\beta_1,\beta_2\)分别被设置为0.9和0.999, \(\eta\)设置为0.001.

5. 如何选择合适的优化方法

关于如何选择合适的优化方法,文章给出了一些建议。 这些建议几乎都可以从下图展现出来。

图片来源:http://imgur.com/a/Hqolp

floatfloat

从上图来看,似乎SGD是一种 “最蠢”的方法,但文献
《The Marginal Value of Adaptive Gradient Methods in Machine Learning》给出的结论却是:

自适应优化算法训练出来的结果通常都不如SGD,尽管这些自适应优化算法在训练时表现的看起来更好。 使用者应当慎重使用自适应优化算法。

  • 14
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值