🔋 优化算法
🔈 本节我们将继续讨论深度神经网络中的一些优化算法,通过使用这些技巧和方法来提高神经网络的训练速度和精度。
一、Mini-batch 梯度下降 Mini-batch gradient descent
之前我们介绍的神经网络训练过程是对所有 m 个样本,称为 batch,通过向量化计算方式,同时进行的。如果 m 很大,例如达到百万数量级,训练速度往往会很慢,因为每次迭代都要对所有样本进行进行求和运算和矩阵运算。我们将这种梯度下降算法称为 Batch Gradient Descent。
为了解决这一问题,我们可以把 m 个训练样本分成若干个子集,称为 mini-batches,这样每个子集包含的数据量就小了,例如只有1000,然后每次在单一子集上进行神经网络训练,速度就会大大提高。这种梯度下降算法叫做 Mini-batch Gradient Descent。
🏷 假设总的训练样本个数 m=5000000,其维度为 $(n_x,m)$。将其分成 5000 个子集,每个 mini-batch 含有 1000 个样本。我们将每个 mini-batch 记为 $X^{{t}}$,其维度为 $(n_x,1000)$ 。相应的每个 mini-batch 的输出记为 $Y^{{t}}$,其维度为 (1,1000),且 $t=1,2,\cdots,5000$。
Mini-batches Gradient Descent 的实现过程是先将总的训练样本分成 T 个子集(mini-batches),然后对每个 mini-batch 进行神经网络训练,包括 Forward Propagation,Compute Cost Function,Backward Propagation,循环至 T 个 mini-batch 都训练完毕:
二、理解 Mini-batch 梯度下降
Batch gradient descent 和 Mini-batch gradient descent 的 cost 曲线(代价函数值) 如下图所示:
对于一般的神经网络模型,使用 Batch gradient descent,随着迭代次数增加,cost 是不断减小的。
然而,使用 Mini-batch gradient descent,随着在不同的 mini-batch 上迭代训练,其 cost 不是单调下降,而是受类似噪音的影响,出现振荡。但整体的趋势是下降的,最终也能得到较低的 cost 值。
之所以出现细微振荡的原因是不同的 mini-batch 之间是有差异的。例如可能第一个子集 $(X^{{1}},Y^{{1}})$ 是好的子集,而第二个子集 $(X^{{2}},Y^{{2}})$ 包含了一些噪声 noise。出现细微振荡是正常的
❓ 如何选择每个 mini-batch 的大小,即包含的样本个数呢?有两个极端,假设样本个数一共为 m 个:
如果 mini-batch size = m(每个 mini-batch 包含 m 个样本),即为 批量梯度下降 Batch gradient descent,只包含一个子集为 $(X^{{1}},Y^{{1}})=(X,Y)$
如果 mini-batch size = 1(每个 mini-batch 包含 1 个样本),即有了新的算法,称为 随机梯度下降 Stachastic gradient descent,每个样本就是一个子集 $(X^{{1}},Y^{{1}})=(x^{(i)},y^{(i)})$ ,共有 m 个子集。
🎨 我们来比较一下 Batch gradient descent 和 Stachastic gradient descent 的梯度下降曲线。如下图所示:
蓝色的线代表 Batch gradient descent,紫色的线代表 Stachastic gradient descent:
🔹 Batch gradient descent 会比较平稳地接近全局最小值,但是因为使用了所有 m 个样本,每次前进的速度有些慢。
🔹 Stachastic gradient descent 每次前进速度很快,但是路线曲折,有较大的振荡,最终会在最小值附近来回波动,难以真正达到最小值处。而且在数值处理上就不能使用向量化的方法来提高运算速度。
实际使用中,mini-batch size 不能设置得太大(Batch gradient descent),也不能设置得太小(Stachastic gradient descent)。这样,相当于结合了 Batch gradient descent 和 Stachastic gradient descent 各自的优点,既能使用向量化优化算法,又能叫快速地找到最小值。Mini-batch gradient descent 的梯度下降曲线如下图绿色所示,每次前进速度较快,且振荡较小,基本能接近全局最小值
🚩 一般来说:
如果总体样本数量 m 不太大时,例如 m ≤ 2000,建议直接使用 Batch gradient descent。
如果总体样本数量 m 很大时,建议将样本分成许多 mini-batches。推荐常用的 mini-batch size 为64,128,256,512。这些都是 2 的幂。之所以这样设置的原因是计算机存储数据一般是 2 的幂,这样设置可以提高运算速度。
三、指数加权平均 Exponentially weighted averages
该部分我们将介绍指数加权平均(Exponentially weighted averages)的概念。
举个例子,记录半年内伦敦市的气温变化,并在二维平面上绘制出来,如下图所示:
看上去,温度数据似乎有noise,而且抖动较大。如果我们希望看到半年内气温的整体变化趋势,可以通过移动平均(moving average)的方法来对每天气温进行平滑处理。
例如我们可以设 $V_0=0$ ,当成第 0 天的气温值:
经过移动平均处理得到的气温如下图红色曲线所示:
⭐ 这种滑动平均算法称为指数加权平均(exponentially weighted average)。根据之前的推导公式,其一般形式为:
上面的例子中, β=0.9。β 值决定了指数加权平均的天数,近似表示为:$\frac{1}{1-\beta}$
例如,当 β=0.9,则 $\frac{1}{1-\beta}=10$ ,表示将前10天进行指数加权平均。当 β=0.98,则 $\frac{1}{1-\beta}=50$1 ,表示将前50天进行指数加权平均。
😏 β 值越大,则指数加权平均的天数越多,平均后的趋势线就越平缓,但是同时也会向右平移。下图绿色曲线和黄色曲线分别表示了 β=0.98 和 β=0.5 时,指数加权平均的结果:
💡 这里简单解释一下公式 $\frac{1}{1-\beta}$ 是怎么来的。准确来说,指数加权平均算法跟之前所有天的数值都有关系,根据之前的推导公式就能看出。但是指数是衰减的,一般认为衰减到 $\frac1e$ 就可以忽略不计了。因此,根据之前的推导公式,我们只要证明 即可:
指数加权平均数公式的好处之一在于,它占用极少内存,电脑内存中只占用一行数字而已,然后把最新数据代入公式,不断覆盖就可以了
四、指数加权平均的偏差修正 Bias correction
上文中提到当 β=0.98 时,指数加权平均结果如下图绿色曲线所示。但是实际上,真实曲线如紫色曲线所示:
我们注意到,紫色曲线与绿色曲线的区别是,紫色曲线开始的时候相对较低一些。这是因为开始时我们设置$V_0=0$ ,所以初始值会相对小一些,直到后面受前面的影响渐渐变小,趋于正常。
💡 修正这种问题的方法是进行偏移校正(bias correction),即在每次计算完 $V_t$ 后,对 $V_t$ 进行下式处理:
在刚开始的时候,t 比较小,$(1-\beta^t) < 1$ ,这样就将 $V_t$ 修正得更大一些,效果是把紫色曲线开始部分向上提升一些,与绿色曲线接近重合。随着t增大,$(1-\beta^t)\approx1$ ,$V_t$ 基本不变,紫色曲线与绿色曲线依然重合。这样就实现了简单的偏移校正,得到我们希望的绿色曲线。
值得一提的是,机器学习中,偏移校正并不是必须的。因为,在迭代一定次数后(t 较大),$V_t$ 受初始值影响微乎其微,紫色曲线与绿色曲线基本重合。所以,一般可以忽略初始迭代过程,等到一定迭代之后再取值,这样就不需要进行偏移校正了。
五、动量梯度下降 Momentum Gradient descent
🥩 首先回顾一下传统梯度下降的 w 和 b 的更新过程:
$w:=w-\alpha\frac{\partial J(w,b)}{\partial w} = w - αdw$
$b:=b-\alpha\frac{\partial J(w,b)}{\partial b} = b - αdb$
该部分将介绍动量梯度下降算法,其速度要比传统的梯度下降算法快很多。做法是在每次训练时,对梯度进行指数加权平均处理,然后用得到的梯度值更新权重 W 和常数项 b。下面介绍具体的实现过程。
原始的梯度下降算法如上图蓝色折线所示。在梯度下降过程中,梯度下降的振荡较大,尤其对于W、b之间数值范围差别较大的情况。此时每一点处的梯度只与当前方向有关,产生类似折线的效果,前进缓慢。而如果对梯度进行指数加权平均,这样使当前梯度不仅与当前方向有关,还与之前的方向有关,这样处理让梯度前进方向更加平滑,减少振荡,能够更快地到达最小值处。
权重 W 和常数项 b 的指数加权平均表达式如下:
从动量的角度来看,以权重 W 为例,$V_{dW}$ 可以看成是速度 V,$dW$ 可以看成是加速度 a。指数加权平均实际上是计算当前的速度,当前速度由之前的速度和现在的加速度共同影响。而 β < 1,又能限制速度 $V_{dW}$ 过大。也就是说,当前的速度是渐变的,而不是瞬变的,是动量的过程。这保证了梯度下降的平稳性和准确性,减少振荡,较快地达到最小值处。
动量梯度下降算法的过程如下:
另外,关于偏移校正,可以不使用。因为经过 10 次迭代后,随着滑动平均的过程,偏移情况会逐渐消失。
补充一下,在其它文献资料中,动量梯度下降还有另外一种写法:
即消去了dW和 db 前的系数 (1−β)。这样简化了表达式,但是学习因子 α 相当于变成了 $\frac{\alpha}{1-\beta}$ ,表示 α 也受 β 的影响。从效果上来说,这种写法也是可以的,但是不够直观,且调参涉及到 α,不够方便。所以,实际应用中,推荐第一种动量梯度下降的表达式。
六、RMSprop — Root Mean Square prop
你们知道了动量(Momentum)可以加快梯度下降,还有一个叫做RMSprop的算法,全称是 root mean square prop算法,它也可以加速梯度下降,我们来看看它是如何运作的。
每次迭代训练过程中,其权重W和常数项b的更新表达式为:
下面简单解释一下RMSprop算法的原理,仍然以下图为例,为了便于分析,令水平方向为W的方向,垂直方向为b的方向。
从图中可以看出,梯度下降(蓝色折线)在垂直方向(b)上振荡较大,在水平方向(W)上振荡较小。表示在b方向上梯度较大,即db较大,而在W方向上梯度较小,即dW较小。因此,上述表达式中 $S_b$ 较大,而 $S_W$ 较小。在更新W和b的表达式中,变化值 $\frac{dW}{\sqrt{S_W}}$ 较大,而$ \frac{db}{\sqrt{S_b}}$ 较小。也就使得W变化得多一些,b变化得少一些。即加快了W方向的速度,减小了b方向的速度,减小振荡,实现快速梯度下降算法,其梯度下降过程如绿色折线所示。总得来说,就是如果哪个方向振荡大,就减小该方向的更新速度,从而减小振荡。
还有一点需要注意的是为了避免RMSprop算法中分母为零,通常可以在分母增加一个极小的常数 $\varepsilon$ :
七、Adam 优化算法 Adam optimization algorithm
在深度学习的历史上,包括许多知名研究者在内,提出了优化算法,并很好地解决了一些问题,但随后这些优化算法被指出并不能一般化,并不适用于多种神经网络,时间久了,深度学习圈子里的人开始多少有些质疑全新的优化算法,很多人都觉得动量(Momentum)梯度下降法很好用,很难再想出更好的优化算法。所以RMSprop以及Adam优化算法,就是少有的经受住人们考验的两种算法,已被证明适用于不同的深度学习结构。
Adam(Adaptive Moment Estimation)算法结合了动量梯度下降算法和RMSprop算法。其算法流程为:
Adam算法包含了几个超参数,分别是:α, β1, β2, ε。其中,β1 通常设置为 0.9,β2 通常设置为 0.999,ε 通常设置为 $10^{−8}$ 。一般只需要对 β1 和 β2 进行调试。
实际应用中,Adam 算法结合了动量梯度下降和RMSprop各自的优点,使得神经网络训练速度大大提高。
八、学习率衰减 Learning rate decay
减小学习因子 α 也能有效提高神经网络训练速度,这种方法被称为 learning rate decay。
Learning rate decay 就是随着迭代次数增加,学习因子α 逐渐减小。下面用图示的方式来解释这样做的好处:
下图中,蓝色折线表示使用恒定的学习因子 α,由于每次训练 α 相同,步进长度不变,在接近最优值处的振荡也大,在最优值附近较大范围内振荡,与最优值距离就比较远。
绿色折线表示使用不断减小的 α,随着训练次数增加, α 逐渐减小,步进长度减小,使得能够在最优值处较小范围内微弱振荡,不断逼近最优值。相比较恒定的 α 来说,learning rate decay 更接近最优值。
Learning rate decay 中对 α 可由下列公式得到:
其中,deacy_rate
是参数(可调),epoch
是训练完所有样本的次数。随着 epoch
增加,α 会不断变小。
除了上面计算 α 的公式之外,还有其它可供选择的计算公式:
除此之外,还可以设置 α 为关于 t 的离散值,随着 t 增加, α 呈阶梯式减小。当然,也可以根据训练情况灵活调整当前的 α 值,但会比较耗时间。
九、局部最优问题 local optima
在使用梯度下降算法不断减小 cost function 时,可能会得到局部最优解(local optima)而不是全局最优解(global optima)。之前我们对局部最优解的理解是形如碗状的凹槽,如下图左边所示:
但是在神经网络中,local optima 的概念发生了变化。准确地来说,大部分梯度为零的“最优点”并不是这些凹槽处,而是形如右边所示的马鞍状,称为 saddle point。也就是说,梯度为零并不能保证都是 convex(极小值),也有可能是 concave(极大值)。特别是在神经网络中参数很多的情况下,所有参数梯度为零的点很可能都是右边所示的马鞍状的 saddle point,而不是左边那样的 local optimum。
类似马鞍状的 Plateaus(平稳段) 会降低神经网络学习速度。Plateaus 是梯度接近于零的平缓区域,如下图所示。在 plateaus 上梯度很小,前进缓慢,到达 saddle point 需要很长时间。到达 saddle point 后,由于随机扰动,梯度一般能够沿着图中绿色箭头,离开 saddle point,继续前进,只是在 plateaus 上花费了太多时间。
总的来说,关于 local optima,有两点总结:
只要选择合理的强大的神经网络,一般不太可能陷入 local optima
Plateaus 可能会使梯度下降变慢,降低学习速度
👍 值得一提的是,上文介绍的动量梯度下降,RMSprop,Adam 算法都能有效解决 plateaus 下降过慢的问题,大大提高神经网络的学习速度。