本文为深度学习的学习总结,讲解神经网络中的优化算法。欢迎交流

Mini-batch 梯度下降法

  • 批量梯度下降:每次更新所有样本,每轮对于 θ\theta 的更新,所有样本都有贡献,计算得到的是标准梯度,对于凸问题,肯定能找到全局最优解。但每次更新幅度较大,样本很多时耗时太久。下面是更新公式:

    【深度学习】优化算法

  • 随机梯度下降:每次更新时用 1 个样本,用 1 个样本来近似所有样本来调整 θ\theta,计算出的梯度不是准确的梯度,因而随机梯度下降会带来一些问题。对于凸问题,代价函数整体向着全局最优解,永远不会收敛,但最终得到的结果往往在全局最优解附近,我们可以接收。相比于批量梯度,这种方法更快收敛。减小学习率可以改善噪声(后面会详细讲解),但会失去所有向量化带来的加速。更新公式如下:

    【深度学习】优化算法

  • mini-batch 梯度下降:在每次更新时用 b 个样本,用一些小样本近似全部样本,是上面两种方式的折中。这种方式在深度学习中使用最多,因为其收敛不会很慢,并且收敛的局部最优解也更容易被接受。一方面得到了大量的向量化,另一方面,无需等待整个训练集被处理完,就可以开始后续工作了。更新公式如下:

    【深度学习】优化算法

当我们使用批量梯度下降法时,代价函数 JJ 与迭代次数间的关系如左图。如果使用 mini-batch 梯度下降法,则函数 JJ 与迭代次数间的关系如右图,走向朝下,但有很多的噪声,它并不是每次迭代都在下降。

【深度学习】优化算法

右图产生噪声的原因是,如果第一批数据容易计算而第二批数据较难计算时,则成本会增加。

因此我们要决定 min-batch 的大小。如果样本容量很小(<2000<2000),我们直接使用批量梯度算法,如果样本容量较大,一般取 mini-batch 为 64 到 512,因为计算机内存的特点,取 2 的次方时代码会运行的快一些。最后,X{t},Y{t}X^{\{t\}},Y^{\{t\}} 要符合 CPU/GPU 内存,否则算法的表现将急剧下降。通常我们多次尝试不同的 mini-batch 选择最好的大小。

指数加权平均

在讲解其他更快速的优化算法之前,我们需要先讲解指数加权平均

下图为一年中温度随时间的变化图:

【深度学习】优化算法

如果我们想要计算温度的趋势或局部平均值时,我们会使用指数加权平均,公式为:
vt=βvt1+(1β)θt v_t=\beta v_{t-1}+(1-\beta)\theta_t
β=0.9\beta=0.9 时,得到红色的趋势曲线:

【深度学习】优化算法

在计算时,可视 vtv_t11β\frac{1}{1-\beta} 天的温度的平均。此时是 10 天的平均值。

若取 β=0.98\beta=0.98,则得到的结果为过去 50 天的平均温度,我们作图得到绿色的曲线:

【深度学习】优化算法

因为我们多平均了几天的温度,所以得到的曲线波动更小更平坦。缺点是,为了平均更多的值,公式在温度变化时适应地会较为缓慢。

我们再设 β=0.5\beta=0.5,平均了 2 天的温度,得到下图中的黄线:

【深度学习】优化算法

我们平均的数据太少,曲线有很多噪声,更可能出现异常值,但是能更快地适应温度变化。

通过调整不同的参数值,我们最终可以得到一个最佳的计算公式。

下面我们来理解这个公式的本质。我们将所有的 vt1v_{t-1} 代入到 vtv_t 的公式中,最终得到这样的公式(公式中的 β=0.9\beta=0.9):
vt=i=0t1(1β)βiθti v_t=\sum\limits_{i=0}^{t-1}(1-\beta)\beta^i\theta_{t-i}
我们假设有一些日期的温度,分别为 θ1,...,θt\theta_1,...,\theta_t

【深度学习】优化算法

然后我们构建一个指数衰减函数,最大值为 1β=0.11-\beta=0.1

【深度学习】优化算法

计算 vtv_t 通过将两个函数横坐标 tt 对应的值相乘,然后求和。上图中所有的数相加起来为 1 或逼近 1,我们称之为偏差修正。

那么我们需要平均多少天的温度。0.9100.351e0.9^{10}≈0.35≈\frac{1}{e}(1ϵ)1ϵ1e0.35(1-\epsilon)^{\frac{1}{\epsilon}}≈\frac{1}{e}≈0.35。则 10 天后曲线的高度下降到峰值的 1e\frac{1}{e},数值快速衰减,本质上是一个下降幅度喊打。因此当 β=0.9\beta=0.9 时,我们计算了过去 10 天的平均温度。得到公式 11β\frac{1}{1-\beta}

在实际执行中,初始化 v0=0v_0=0,然后不断更新等式:
vt:=βv+(1β)θt v_t:=\beta v+(1-\beta)\theta_t
可以看出,使用该方法时,我们只需要对变量 vv 不断覆盖,占用的内存极小,但它不是最好最精确的计算平均数的方法。如果计算过去 50 天的平均温度,可以对过去 50 天的温度求和后除以 50,这样做虽然精确,但缺点是需要保存更多的数据。

指数加权平均的偏差修正

当我实际在预测温度的例子中执行指数加权平均公式时取 β=0.98\beta=0.98,实际得到的是紫线:

【深度学习】优化算法

因为我们初始化 v0=0v_0=0,在公式估计的初期,估计值远小于实际值。我们可以使用偏差修正的方法来解决这一问题。我们使用 vt1βt\frac{v_t}{1-\beta^t} 作为估计值,当 tt 较小时,分母较小,估计值会较大;而当 tt 较大时,βt\beta^t 会很小,此时分母为 1,所以在图像的后半段,绿线和紫线重合。

动量梯度下降法

动量梯度下降法又称为 Momentum 法,其基本思想是计算梯度的指数加权平均数,并利用该梯度更新权重,一般使用 mini-batch 梯度下降法。

下图是梯度下降法的优化图:

【深度学习】优化算法

图中的上下波动减慢了梯度下降法的速度,我们无法使用更大的学习率,否则结果可能会偏离函数范围,因此我们只能选择较小的学习率。在纵轴上,我们希望学习慢一点,而在横轴上,我们希望学习快一点,这样能够更快收敛。

使用 Momentum,在第 tt 次迭代中,会计算 dW,dbdW,db,我们现在要做的是:
vdW=βvdW+(1β)dW v_{dW}=\beta*v_{dW}+(1-\beta)*dW

vdb=βvdb+(1β)db v_{db}=\beta*v_{db}+(1-\beta)*db

W=WαvdW W=W-\alpha*v_{dW}

b=bαvdb b=b-\alpha*v_{db}

在上图中,纵轴方向的均值近似为 0,横轴方向都指向最优解,我们使用指数加权平均法可以使得纵轴的摆动变小,横轴方向运动更快。

我们用从山上滚落小球的例子进行直观的解释。如果要最小化碗状函数,可以将微分项想象为小球提供了加速度,Momentum 项(vdWv_{dW})相当于速度,小球因为加速度越滚越快,而因为 β\beta 略小于 1,因此小球会表现出一些摩擦力,不会无限加速。梯度下降法每一步都相互独立,而小球可以向下滚,获得动量。于是我们可以选一个较大的学习率 α\alpha

上面公式中通常取 β=0.9\beta=0.9, 相当于平均了前 10 次迭代的梯度,实验证明 0.9 是很好的鲁棒数。因为 10 次迭代后移动平均已经超过了初始阶段,因此我们无需使用偏差修正。

这个公式还有一种写法,相当于 vdWv_{dW} 缩小了 1β1-\beta 倍:
vdW=βvdW+dW v_{dW}=\beta*v_{dW}+dW
此时 α\alpha 要根据 11β\frac{1}{1-\beta} 相应变化。两种方法的效果相似,都通常将取 β=0.9\beta=0.9,但第二种在调整 β\beta 时会影响到 vdW,vdbv_{dW},v_{db}α\alpha

RMSprop

还是上面的那张图,我们仍然要减少纵轴方向的摆动,增加横轴方向的运动。假设纵轴代表参数 bb,横轴代表参数 WW

【深度学习】优化算法

RMSprop 的数学表达式如下,因为后面要将 Momentum 与 RMSprop 结合,这里参数使用 β2\beta_2
SdW=β2SdW+(1β)(dW)2 S_{dW}=\beta_2 S_{dW}+(1-\beta)(dW)^2

Sdb=β2Sdb+(1β)(db)2 S_{db}=\beta_2 S_{db}+(1-\beta)(db)^2

W:=WαdWSdW W:=W-\alpha\frac{d_W}{\sqrt{S_{dW}}}

b:=bαdbSdb b:=b-\alpha\frac{d_b}{\sqrt{S_{db}}}

这样做能够保留微分平方的加权平均数。因为在图像的斜率主要在纵轴方向,因此 dWdW 是一个小数字,从而 SdWS_{dW} 是一个小数字,所以用 dWdW 除以一个较小的数;而 dbdb 是一个较大的数,从而 SdbS_{db} 是一个大数字,所以用 dbdb 除以一个较大的数。这样一来,我们减缓了纵轴的变化。和 Momentum 相同,我们可以选一个较大的学习率 α\alpha

实际中,参数会位于高维度空间,因此在垂直方向上,我们可能需要消除 W1,W3W_1,W_3 的合集,在横轴消除 W2,W4W_2,W_4 的合集。

我们要确保分母不为 0 或很接近 0,因此通常在分母上加 ϵ=108\epsilon=10^{-8}

Adam 优化算法

Adam 优化算法是 Momentum 和 RMSprop 的结合。使用 Adam 算法需要首先初始化
vdW=0,SdW=0,vdb=0,Sdb=0 v_{dW}=0, \quad S_{dW}=0, \quad v_{db}=0, \quad S_{db}=0
在第 tt 次迭代中需要用当前的 mini-batch 计算 dW,dbdW,db,接下来计算 Momentum
vdW=β1vdW+(1β1)dW v_{dW}=\beta_1v_{dW}+(1-\beta_1)dW

vdb=β1vdb+(1β1)db v_{db}=\beta_1v_{db}+(1-\beta_1)db

接着用 RMSprop 更新
SdW=β2SdW+(1β)(dW)2 S_{dW}=\beta_2 S_{dW}+(1-\beta)(dW)^2

Sdb=β2Sdb+(1β)(db)2 S_{db}=\beta_2 S_{db}+(1-\beta)(db)^2

相当于 Momentum 更新了超参数 β1\beta_1,而 RMSprop 更新了超参数 β2\beta_2。通常使用 Adam 算法时还要计算偏差修正
vdWcorrect=vdW1β1t v_{dW}^{correct}=\frac{v_{dW}}{1-\beta_1^t}

vdbcorrect=vdb1β1t v_{db}^{correct}=\frac{v_{db}}{1-\beta_1^t}

SS 也使用偏差修正:
SdWcorrect=SdW1β2t S_{dW}^{correct}=\frac{S_{dW}}{1-\beta_2^t}

Sdbcorrect=Sdb1β2t S_{db}^{correct}=\frac{S_{db}}{1-\beta_2^t}

最后更新权重:
W=WαvdWcorrectSdWcorrect+ϵ W=W-\alpha\frac{v_{dW}^{correct}}{\sqrt{S_{dW}^{correct}+\epsilon}}
Adam 算法广泛适用于各种结构,并且有很多超参数 α,β1,β2,ϵ\alpha,\beta_1,\beta_2,\epsilon,通常取 β1=0.9,β2=0.999,ϵ=108\beta_1=0.9,\beta_2=0.999,\epsilon=10^{-8},参数 ϵ\epsilon 的值不影响算法表现,找个小数字就行,参数 α\alpha 需要进行调试。其中 β1\beta_1 称为第一矩,β2\beta_2 称为第二矩。

学习率衰减

加快学习的另一种方法是随时间而减少学习率 α\alpha。在使用梯度下降法时,算法会在最小值附近摆动。而如果我们在最小值附近缩小学习率 α\alpha,则摆动会相应的减小,而在算法初期 α\alpha 较大,下降较快,这样可以更快地收敛。

我们可以将学习率设为 α=11+drenα0\alpha=\frac{1}{1+dr*en}\alpha_0,其中 drdr 为 decay-rate(衰减率),enen 为 epoch-num(mini-batch 中的代数),dr,α0dr,\alpha_0 为需要调试的超参数。根据公式,其函数图像为:

【深度学习】优化算法

还有其他的衰减公式:

  • 指数衰减:学习率呈指数下降。数学公式如下,其中 0.95 可选为略小于 1 的数字:
    α=0.95enα0 \alpha=0.95^{en}\alpha_0

  • 右如下面的两个公式,其中 kk 为常数:
    α=kenα0 \alpha=\frac{k}{\sqrt{en}}\alpha_0
    或下面的式子,其中 tt 为 mini-batch 中的 tt
    α=ktα0 \alpha=\frac{k}{\sqrt{t}}\alpha_0

  • 离散下降:每个步骤有不同的学习率,如下图:

    【深度学习】优化算法

  • 手动选择:耗费时间,只适用数据量较小的情况。

虽然学习率不是我们调试参数的要点,但是一个好的 α\alpha 确实会加快训练

局部最优的问题

下图为一个二维的代价函数图像,平面的高度是代价函数:

【深度学习】优化算法

似乎各处都分布着局部最优,梯度下降法可能困在一个局部最优解中,而在高维的图像中,其实梯度为 0 的点通常并不是局部最优解,通常是鞍点:

【深度学习】优化算法

一个具有高维空间的函数如果梯度为 0,则在每个方向可能是凸函数。如果要是局部最优解,则需要在所有方向上都是凸函数,这种情况发生的几率很小。因此在高维空间中,我们通常会遇到鞍点而不是局部最优点。上述问题的结果是导数长时间接近 0 的平稳段会减缓学习。

因此我们需要知道:

  • 当我们训练大量样本并且代价函数定义在高危空间时,不太可能困在极差的局部最优中
  • 平稳段会导致学习缓慢,而优化算法可以让我们更快的走出平稳段。

相关文章: