吴恩达改善深层神经网络章节笔记(二)——优化算法


视频课程链接:
https://www.bilibili.com/video/BV1FT4y1E74V?
笔记参考链接:
https://blog.csdn.net/weixin_36815313/article/details/105728919

1. Mini-batch梯度下降 (Mini-batch Gradient Descent)

机器学习的应用是一个高度依赖经验的过程,伴随着大量迭代的过程,你需要训练诸多模型,才能找到最合适的那一个,所以优化算法能够帮助你快速训练模型。
但是深度学习没有在大数据领域发挥最大的效果,我们可以利用一个巨大的数据集来训练神经网络,而在巨大的数据集基础上进行训练,训练速度很慢。因此你会发现,使用快速好用的优化算法能够大大提高你和团队的效率。那么,我们首先来谈谈mini-batch梯度下降法

1.1 什么是mini-batch?

向量化能够有效地对所有 m m m个样本进行计算,允许你处理整个训练集,而无需某个明确的公式。所以我们要把所有的训练样本放大一个巨大的矩阵 X X X当中去,即 X = [ x ( 1 ) x ( 2 ) x ( 3 ) ⋯ x ( m ) ] X=[x^{(1)}x^{(2)}x^{(3)}\cdots x^{(m)}] X=[x(1)x(2)x(3)x(m)]。输出 Y Y Y也是如此,即 Y = [ y ( 1 ) y ( 2 ) y ( 3 ) ⋯ y ( m ) ] Y=[y^{(1)}y^{(2)}y^{(3)}\cdots y^{(m)}] Y=[y(1)y(2)y(3)y(m)]。所以 X X X的维数是 ( n x , m ) (n_x,m) (nx,m) Y Y Y的维数是 ( 1 , m ) (1,m) (1,m),向量化能够让你相对较快地处理所有 m m m个样本。
但是如果 m m m很大的话,处理速度仍然缓慢。举例来说,如果 m m m是500万,在对整个训练集执行梯度下降法时,你需要做的是处理这500万个训练样本,然后才能进行一步梯度下降法。接着你需要再重新处理这500万个训练样本,才能进行下一步梯度下降法。所以如果你在处理完500万个样本的训练集之前,先让梯度下降法处理一部分,你的算法速度会更快。
你可以把训练集分割为小一点的子集训练,这些子集被取名为mini-batch。假设每一个子集中只有1000个样本,把其中的 x ( 1 ) x^{(1)} x(1) x ( 1000 ) x^{(1000)} x(1000)取出来,将其称为第一个子训练集,记作 X { 1 } X^{\{1\}} X{ 1},然后你再取出接下来1000个样本,即从 x ( 1001 ) x^{(1001)} x(1001) x ( 2000 ) x^{(2000)} x(2000),记作 X { 2 } X^{\{2\}} X{ 2},然后再取1000个样本,以此类推,最后一个mini-batch记作 X { 5000 } X^{\{5000\}} X{ 5000}。如果你的训练样本一共有500万个,那么每个mini-batch都有1000个样本,也就是说,你有5000个mini-batch
在这里插入图片描述

Y Y Y也要进行相同处理,相应地拆分 Y Y Y的训练集,从 y ( 1 ) y^{(1)} y(1) y ( 1000 ) y^{(1000)} y(1000)为第一个子集,记作 Y { 1 } Y^{\{1\}} Y{ 1},然后从 y ( 1001 ) y^{(1001)} y(1001) y ( 2000 ) y^{(2000)} y(2000)记作 Y { 2 } Y^{\{2\}} Y{ 2},以此类推,直到 Y { 5000 } Y^{\{5000\}} Y{ 5000}
在这里插入图片描述

mini-batch的数量 t t t组成了 X ( t ) X^{(t)} X(t) Y ( t ) Y^{(t)} Y(t),这就是1000个训练样本,包含相应的输入输出对。如果 X { 1 } X^{\{1\}} X{ 1}是一个有1000个样本的训练集,或者说是1000个 x x x值,所以维数应该是 ( n x , 1000 ) (n_x,1000) (nx,1000),同理, X { 2 } X^{\{2\}} X{ 2}的维数应该是 ( n x , 1000 ) (n_x,1000) (nx,1000)。以此类推,所有的子集维数都是 ( n x , 1000 ) (n_x,1000) (nx,1000),而 Y { t } Y^{\{t\}} Y{ t}的维数都是 ( 1 , 1000 ) (1,1000) (1,1000)
mini-batch梯度下降法,指的是每次同时处理的单个的mini-batch,即 X { t } X^{\{t\}} X{ t} Y { t } Y^{\{t\}} Y{ t},而不是同时处理全部的 X X X Y Y Y训练集。

1.2 Mini-batch梯度下降法的实现流程

假设训练集中500万个样本,划分成5000个mini-batch,即每个mini-batch中包含1000个训练样本。在训练集上运行mini-batch梯度下降法,因为我们有5000个mini-batch,其中各有1000个样本,因此使用for循环for t in range(1,5000),对5000个mini-batch X { t } X^{\{t\}} X{ t} Y { t } Y^{\{t\}} Y{ t}执行一步梯度下降法。
首先,对输入 X { t } X^{\{t\}} X{ t}执行前向传播(Forward propagation)。因为现在你需要处理一个mini-batch,而不是一个样本集,因此前向传播过程中的输入 X X X变成了 X { t } X^{\{t\}} X{ t},即 Z [ 1 ] = W [ 1 ] X { t } + b [ 1 ] Z^{[1]}=W^{[1]}X^{\{t\}}+b^{[1]} Z[1]=W[1]X{ t}+b[1] A [ 1 ] = g [ 1 ] ( Z [ 1 ] ) A^{[1]}=g^{[1]}(Z^{[1]}) A[1]=g[1](Z[1]) 之所以用大写的 Z Z Z,是因为这是一个向量,以此类推,直到得到最终的预测值 y ^ \hat{y} y^ y ^ = A [ L ] = g [ L ] ( Z [ L ] ) \hat{y}=A^{[L]}=g^{[L]}(Z^{[L]}) y^=A[L]=g[L](Z[L]) 注意这里你需要用到一个向量化的执行命令,这个向量化的执行命令,一次性处理1000个而不是500万个样本。
接下来需要计算损失成本函数 J J J,因为子集规模是1000,因此 J { t } = 1 1000 ∑ i = 1 l L ( y ^ ( i ) , y ( i ) ) J^{\{t\}}=\frac1{1000}\sum_{i=1}^lL(\hat{y}^{(i)},y^{(i)}) J{ t}=10001i=1lL(y^(i),y(i)) 说明一下, L ( y ^ ( i ) , y ( i ) ) L(\hat{y}^{(i)},y^{(i)}) L(y^(i),y(i))指的是来自于某一项mini-batch X { t } X^{\{t\}} X{ t} Y { t } Y^{\{t\}} Y{ t}中的样本。
如果你用到了正则化,也可以添加正则化项,即 J { t } = 1 1000 ∑ i = 1 l L ( y ^ ( i ) , y ( i ) ) + λ 2 ∗ 1000 ∑ l ∣ ∣ w [ l ] ∣ ∣ F 2 J^{\{t\}}=\frac1{1000}\sum_{i=1}^lL(\hat{y}^{(i)},y^{(i)})+\frac{\lambda}{2*1000}\sum_l||w^{[l]}||^2_F J{ t}=10001i=1lL(y^(i),y(i))+21000λlw[l]F2 接下来执行反向传播(Back propagation)来计算 J { t } J^{\{t\}} J{ t}的梯度,这里使用 X { t } X^{\{t\}} X{ t} Y { t } Y^{\{t\}} Y{ t}。然后根据 d W dW dW d b db db更新 W W W b b b,即 W [ l ] : = W [ l ] − α d W [ l ] W^{[l]}:=W^{[l]}-\alpha dW^{[l]} W[l]:=W[l]αdW[l] b [ l ] : = b [ l ] − α d b [ l ] b^{[l]}:=b^{[l]}-\alpha db^{[l]} b[l]:=b[l]αdb[l] 上述过程是使用mini-batch梯度下降法训练样本的一步,也可被称为进行一代(1 epoch)的训练。一代意味着遍历了一次训练集,也就是说,所有训练样本在神经网络中都进行了一次正向传播和一次反向传播。
使用batch梯度下降法,一次遍历训练集只能让你做一个梯度下降,而使用mini-batch梯度下降法,遍历一次训练集能让你做5000个梯度下降。
在这里插入图片描述

1.3 Batch vs. Mini-batch梯度下降法

在这里插入图片描述

使用batch梯度下降法时,每次迭代你都需要遍历整个训练集,并且每次迭代成本函数 J J J都会下降。如果成本函数 J J J在某次迭代中增加了,那肯定出了问题,也许是你的学习率(Learning rate)太大。
使用mini-batch梯度下降法时,成本函数 J J J并不是在整个过程中每次迭代都是下降的,特别是在每次迭代中,你需要处理的是 X { t } X^{\{t\}} X{ t} Y { t } Y^{\{t\}} Y{ t},而成本函数 J { t } J^{\{t\}} J{ t}只和 X { t } X^{\{t\}} X{ t} Y { t } Y^{\{t\}} Y{ t}有关,也就是每次迭代下你都在训练不同的mini-batch或者说训练不同的样本集。因此在训练mini-batch梯度下降法时,经过多代,你可能会看到上图这样的曲线,走向朝下,但有更多的噪声。如果没有每次迭代都下降,这是不要紧的,但整体走势应该向下。
噪声产生的原因在于每次迭代下你都在训练不同的mini-batch或者说是样本集,也许 X { 1 } X^{\{1\}} X{ 1} Y { 1 } Y^{\{1\}} Y{ 1}是比较容易计算的mini-batch,因此成本会低一些。不过也许出于偶然, X { 2 } X^{\{2\}} X{ 2} Y { 2 } Y^{\{2\}} Y{ 2}是比较难运算的mini-batch,或许你需要一些残缺的样本,这样一来,成本会更高一些,所以才会出现这些摆动。

1.4 如何选择mini-batch大小?

在这里插入图片描述
使用mini-batch梯度下降法的过程中,你需要决定的变量之一是mini-batch的大小,另外 m m m是训练集的大小。
第一种极端情况,假设mini-batch的大小等于 m m m,也就是batch梯度下降法,在这种极端情况下,你就有了mini-batch X { 1 } X^{\{1\}} X{ 1} Y { 1 } Y^{\{1\}} Y{ 1},并且该mini-batch等于整个训练集,即 ( X { 1 } , Y { 1 } ) = ( X , Y ) (X^{\{1\}},Y^{\{1\}})=(X,Y) (X{ 1},Y{ 1})=(X,Y),所以把mini-batch大小设为 m m m,也就等于batch梯度下降法。
另一种极端情况,假设mini-batch大小为1,此时每个样本都是独立的mini-batch,这种新的算法,叫做随机梯度下降法。对于第一个mini-batch,也就是 X { 1 } X^{\{1\}} X{ 1} Y { 1 } Y^{\{1\}} Y{ 1},如果mini-batch大小为1,实际上它就是你的第一个训练样本,即 ( X { 1 } , Y { 1 } ) = ( X ( 1 ) , Y ( 1 ) ) (X^{\{1\}},Y^{\{1\}})=(X^{(1)},Y^{(1)}) (X{ 1},Y{ 1})=(X(1),Y(1))。接着再看第二个mini-batch,也就是第二个训练样本,即 ( X { 2 } , Y { 2 } ) = ( X ( 2 ) , Y ( 2 ) ) (X^{\{2\}},Y^{\{2\}})=(X^{(2)},Y^{(2)}) (X{ 2},Y{ 2})=(X(2),Y(2)),然后是第三个训练样本,以此类推,直到最后一个样本,而每一次梯度下降只处理一个样本。
在这里插入图片描述

接下来在上述两种极端下看一下成本函数的优化情况,如果上图是你想要最小化的成本函数的轮廓。batch梯度下降法(蓝色曲线)从某处开始,相对噪声低些,幅度也大一些,并最终找到最小值。
相反,在随机梯度下降法(紫色曲线)中,从某一点开始,每次迭代只对一个样本进行梯度下降,其大部分时候向着全局最小值靠近,有时候也会远离最小值,因为可能那个样本恰好给你指的方向不对,因此随机梯度下降法是有很多噪声的。平均来看,它最终会靠近最小值,不过有时候也会方向错误,因为随机梯度下降法永远不会收敛,而是会一直在最小值附近波动,并不会在达到最小值并停留在此。
而如果使用mini-batch梯度下降法(绿色曲线)的话,它不会总朝向最小值靠近,但它比随机梯度下降要更持续地靠近最小值的方向,它也不一定在很小的范围内收敛或者波动,如果出现这个问题,可以慢慢减少学习率。
在这里插入图片描述

如果使用batch梯度下降法,即mini-batch的大小为 m m m,每次迭代需要处理大量训练样本,该算法的主要弊端在于如果训练样本数量巨大,单次迭代耗时太长。如果训练样本不大,那么batch梯度下降法可以运行地很好。
使用随机梯度下降法的话,即mini-batch的大小为1,如果你只要处理一个样本,那这个方法很好,通过减小学习率,噪声会被改善或有所减小,但随机梯度下降法的一大缺点是,你会失去所有向量化带给你的加速,因为一次性只处理了一个训练样本,这样效率过于低下。
所以实践中最好选择不大不小的mini-batch尺寸,这样子学习率可以达到最快。你会发现两个好处,一方面,你得到了大量的向量化操作,上个视频我们用过的例子中,如果mini-batch大小为1000个样本,你就可以对1000个样本向量化,比你一次性处理多个样本快得多。另一方面,你不需要等待整个训练集被处理完就可以开始进行后续工作,同样在上个视频我们用过的例子中,每次训练集允许我们执行5000个梯度下降,所以实际上一些位于中间的mini-batch大小效果最好。
而位于中间的mini-batch大小应该如何选择,指导原则如下:

  1. 如果训练集较小,即样本数目小于2000个样本,直接使用batch梯度下降法即可。样本数目较小就没必要使用mini-batch梯度下降法,因为你可以快速处理整个训练集。如果样本数目较大的话,一般mini-batch大小设置为64到512,考虑到电脑内存设置和使用的方式,如果mini-batch大小是2的 n n n次方,代码会运行地快一些,比如64就是2的6次方,128是2的7次方,以此类推,256是2的8次方,512是2的9次方。所以我经常把mini-batch大小设成2的 n n n次方。在上一章节里,mini-batch大小设为了1000,你可以试一下1024,也就是2的10次方。
  2. 最后需要注意的是,在你的mini-batch中,要确保 X { t } X^{\{t\}} X{ t} Y { t } Y^{\{t\}} Y{ t}符合CPU/GPU内存,取决于你的应用方向以及训练集的大小。如果你处理的mini-batch和CPU/GPU内存不相符,不管用什么方法处理数据,你会发现算法的表现急转直下,变得惨不忍睹,所以我希望你对一般的mini-batch大小有一个直观了解。事实上mini-batch大小是一个重要的变量,你需要做一个快速尝试,才能找到能够最有效地减少成本函数的那个,我一般会尝试几个不同的值,几个不同的2的 n n n次方,然后看能否找到一个让梯度下降优化算法最高效的mini-batch大小。

2. 指数加权平均 (Exponentially Weighted Averages)

2.1 基本原理

在这里插入图片描述

上图是天气与日期的变化关系,横轴表示的是一年中的第几天,纵轴表示的是该天的温度。1月份和12月份的温度相对于年中(6、7月份)的温度要低一些。
下面我们通过温度的局部平均值(移动平均值)来描述温度的变化趋势。 v 0 = 0 v_0=0 v0=0 v 1 = 0.9 ∗ v 0 + 0.1 ∗ θ 1 v_1=0.9*v_0+0.1*\theta_1 v1=0.9v0+0.1θ1 v 2 = 0.9 ∗ v 1 + 0.1 ∗ θ 2 v_2=0.9*v_1+0.1*\theta_2 v2=0.9v1+0.1θ2 v 3 = 0.9 ∗ v 2 + 0.1 ∗ θ 3 v_3=0.9*v_2+0.1*\theta_3 v3=0.9v2+0.1θ3 ⋯ ⋯ \cdots \cdots 以此类推,我们可以用如下公式来计算局部平均值。 v t = β ∗ v t − 1 + ( 1 − β ) ∗ θ t v_t=\beta*v_{t-1}+(1-\beta)*\theta_t vt=βvt1+(1β)θt 其中 v t v_t vt表示到第 t t t天的局部平均温度值, θ t \theta_t θt表示第 t t t天的温度, β \beta β表示可调节的超参数。
在计算时可将 v t v_t vt看作是 1 ( 1 − β ) \frac 1{(1-\beta)} (1β)1天内的平均温度。假设 β \beta β是0.9,即 1 ( 1 − β ) = 1 ( 1 − 0.9 ) = 10 \frac{1}{(1-\beta)}=\frac{1}{(1-0.9)}=10 (1β)1=(10.9)1=10天内的平均温度,如下图中的红线部分。
在这里插入图片描述

假设将 β \beta β设置为一个接近1的值,比如0.98,即 1 ( 1 − 0.98 ) = 50 \frac1{(1-0.98)}=50 (10.98)1=50,这就是粗略平均了一下过去50天的温度,如下图中的绿线部分。
在这里插入图片描述

相对于红线来说,得到的曲线要平坦一些,原因在于多平均了几天的温度,所以这个曲线,波动更小,更加平坦,但缺点是曲线进一步右移,产生了延迟。
假设 β \beta β取另一个极端值,比如说0.5,根据公式 1 ( 1 − β ) \frac1{(1-\beta)} (1β)1可知这是平均了两天的温度,如下图中的黄线部分。
在这里插入图片描述

相对于红线来说,它抖动的更加厉害,因为它只平均了两天的温度,所以对于温度的趋势反馈能够更加的及时,更快的适应温度的变化,同时它也会带来更多的噪声(平均的天数太少)。

2.2 本质作用

对于这个计算指数加权平均的方程 v t = β ∗ v t − 1 + ( 1 − β ) ∗ θ t v_t=\beta*v_{t-1}+(1-\beta)*\theta_t vt=βvt1+(1β)θt 假设 β = 0.9 \beta=0.9 β=0.9 t t t从100到1逐级递减,写下如下公式 v 100 = 0.9 ∗ v 99 + 0.1 ∗ θ 100 v_{100}=0.9*v_{99}+0.1*\theta_{100} v100=0.9v99+0.1θ100 v 99 = 0.9 ∗ v 98 + 0.1 ∗ θ 99 v_{99}=0.9*v_{98}+0.1*\theta_{99} v99=0.9v98+0.1θ99 v 98 = 0.9 ∗ v 97 + 0.1 ∗ θ 98 v_{98}=0.9*v_{97}+0.1*\theta_{98} v98=0.9v97+0.1θ98 v 97 = 0.9 ∗ v 96 + 0.1 ∗ θ 97 v_{97}=0.9*v_{96}+0.1*\theta_{97} v97=0.9v96+0.1θ97 ⋯ ⋯ \cdots \cdots v 1 = 0.9 ∗ v 0 + 0.1 ∗ θ 1 v_1=0.9*v_0+0.1*\theta_1 v1=0.9v0+0.1θ1 v 99 v_{99} v99代入到 v 100 v_{100} v100中,可得: v 100 = 0.1 ∗ θ 100 + 0.9 ∗ ( 0.1 ∗ θ 99 + 0.9 ∗ v 98 ) v_{100}=0.1*\theta_{100}+0.9*(0.1*\theta_{99}+0.9*v_{98}) v100=0.1θ100+0.9(0.1θ99+0.9v98) 再将 v 98 v_{98} v98代入到 v 99 v_{99} v99中,可得: v 100 = 0.1 ∗ θ 100 + 0.9 ∗ ( 0.1 ∗ θ 99 + 0.9 ∗ ( 0.1 ∗ θ 98 + 0.9 ∗ v 97 ) ) v_{100}=0.1*\theta_{100}+0.9*(0.1*\theta_{99}+0.9*(0.1*\theta_{98}+0.9*v_{97})) v100=0.1θ100+0.9(0.1θ99+0.9(0.1θ98+0.9v97)) 以此类推,将这些括号里面的内容展开,可得:
v 100 = 0.1 ∗ θ 100 + 0.1 ∗ 0.9 ∗ θ 99 + 0.1 ∗ 0. 9 2 ∗ θ 98 + 0.1 ∗ 0. 9 3 ∗ θ 97 + ⋯ + 0.1 ∗ 0. 9 99 ∗ θ 1 = 0.1 ∗ ∑ i = 1 100 0. 9 ( 100 − i ) ∗ θ i \begin{aligned} v_{100}&=0.1*\theta_{100}+0.1*0.9*\theta_{99}+0.1*0.9^2*\theta_{98}+0.1*0.9^3*\theta_{97}+\cdots+0.1*0.9^{99}*\theta_1\\ &=0.1*\sum_{i=1}^{100} 0.9^{(100-i)}*\theta_i \\ \end{aligned} v100=0.1θ100+0.10.9θ99+0.10.92θ98+0.10.93θ97++0.10.999θ1=0.1i=11000.9(100i)θi 由此可知,上面的式子就是一个指数加权平均。
ϵ = 1 − β = 0.1 \epsilon=1-\beta=0.1 ϵ=1β=0.1,即 β = 0.9 \beta=0.9 β=0.9。当 ( 1 − ϵ ) 1 ϵ = 1 e (1-\epsilon)^{\frac{1}{\epsilon}}=\frac{1}{e} (1ϵ)ϵ1=e1时,即 ( 0.9 ) 10 = 1 e ≈ 0.37 (0.9)^{10}=\frac{1}{e}\approx0.37 (0.9)10=e10.37 e e e为自然对数, e = 2.71828 e=2.71828 e=2.71828),也就是当曲线的高度下降到峰值的 1 3 \frac13 31,权重下降到峰值权重的 1 e \frac{1}{e} e1时,我们就说它平均了 1 ϵ \frac{1}{\epsilon} ϵ1= 1 1 − β \frac{1}{1-\beta} 1β1天的数据。

2.3 算法实现

你要做的是,一开始先将 v v v初始化为0

v = 0

然后在第一天使 v : = β v + ( 1 − β ) θ 1 v:=\beta v+(1-\beta)\theta_1 v:=βv+(1β)θ1

v = beta * v + (1 - beta) * theta_1

​第二天继续更新 v v v值,使 v : = β v + ( 1 − β ) θ 2 v:=\beta v+(1-\beta)\theta_2 v:=βv+(1β)θ2

v = beta * v + (1 - beta) * theta_2

以此类推,接下来每一天根据第 t t t天的数据,把 v v v更新为 v t = β v θ + ( 1 − β ) θ t v_t=\beta v_{\theta}+(1-\beta)\theta_t vt=βvθ+(1β)θt
指数加权平均公式的好处之一在于,它占用极少内存,电脑内存中只占用一行数字而已,然后把最新数据代入公式,不断覆盖就可以了。但缺点是,如果保存所有最近的温度数据和过去10天的总和,必须占用更多的内存,执行更加复杂,计算成本也更加高昂。

2.4 偏差修正

2.4.1 偏差来源

在这里插入图片描述

在之前的章节中讲到,红色曲线对应的 β \beta β值为0.9,绿色曲线对应的 β \beta β值为0.98。但实际上,如果你执行公式 v t = β v t − 1 + ( 1 − β ) θ t v_t=\beta v_{t-1}+(1-\beta)\theta_t vt=βvt1+(1β)θt,在 β \beta β等于0.98的时候,得到的并不是绿色曲线,而是紫色曲线,可以注意到紫色曲线的起点较低。
在这里插入图片描述

计算移动平均数的时候,首先初始化 v 0 v_0 v0 v 0 = 0 v_0=0 v0=0 因为 v 0 = 0 v_0=0 v0=0,所以 v 1 = 0.98 v 0 + 0.02 θ 1 = 0.02 θ 1 v_1=0.98v_0+0.02\theta_1=0.02\theta_1 v1=0.98v0+0.02θ1=0.02θ1 如果第一天的温度是40华氏度,那么 v 1 = 0.02 θ 1 = 0.02 ∗ 40 = 8 v_1=0.02\theta_1=0.02*40=8 v1=0.02θ1=0.0240=8,得到的值会比实际值小很多,所以第一天的温度估计不准确。
v 2 = 0.98 v 1 + 0.02 θ 2 v_2=0.98v_1+0.02θ_2 v2=0.98v1+0.02θ2 v 1 v_1 v1代入到 v 2 v_2 v2 v 2 = 0.98 ∗ 0.02 θ 1 + 0.02 θ 2 = 0.0196 θ 1 + 0.02 θ 2 v_2=0.98*0.02\theta_1+0.02\theta_2=0.0196\theta_1+0.02\theta_2 v2=0.980.02θ1+0.02θ2=0.0196θ1+0.02θ2 假设 θ 1 \theta_1 θ1 θ 2 \theta_2 θ2都是正数,计算后 v 2 v_2 v2要远小于 θ 1 \theta_1 θ1 θ 2 \theta_2 θ2,所以 v 2 v_2 v2不能很好地估算出这一年前两天的温度。

2.4.2 修正方法

在估测初期,不使用 v t v_t vt,而是用 v t 1 − β t \frac{v_t}{1-\beta^t} 1βtvt,其中 t t t是现在的天数。
举例来说,假设 t = 2 t=2 t=2时,那么 1 − β t = 1 − 0.9 8 2 = 0.0396 1-\beta^t=1-0.98^2=0.0396 1βt=10.982=0.0396,因此对第二天温度的估测变成了 v 2 0.0396 = 0.0196 θ 1 + 0.02 θ 2 0.0396 \frac{v_2}{0.0396}=\frac{0.0196\theta_1+0.02\theta_2}{0.0396} 0.0396v2=0.03960.0196θ1+0.02θ2,也就是 θ 1 \theta_1 θ1 θ 2 \theta_2 θ2的加权平均数,并且去除了偏差。随着 t t t增加, β t \beta^t βt接近于0,所以当 t t t很大的时候,偏差修正几乎没有作用,因此当 t t t较大的时候,紫线基本和绿线重合了。

3. 动量梯度下降法 (Gradient Descent with Momentum)

还有一种优化算法叫做Momentum,或者叫做动量梯度下降法,运行速度几乎总是快于标准的梯度下降算法,其基本的思路就是计算梯度的指数加权平均数,并利用该梯度更新你的权重。

3.1 案例说明

在这里插入图片描述

以优化成本函数为例,成本函数的形状如上图,红点代表最小值的位置。
以优化成本函数为例,假设从蓝点位置开始执行梯度下降,如果进行梯度下降的一次迭代,你会发现,无论是batch或mini-batch下降法,都会从起始点开始在这个椭圆范围内来回波动,然后一步一步梯度计算下去,慢慢摆动到最小值,这种上下波动减慢了梯度下降法的速度,你就无法使用更大的学习率(紫色曲线),如果你要用较大的学习率,结果可能会偏离函数的范围,因此为了避免摆动过大,你要用一个较小的学习率。
另一个看待问题的角度是,在纵轴上,你希望学习慢一点,因为你不想要这些摆动,但是在横轴上,你希望加快学习,能够快速从左向右移动,移向最小值。

3.2 算法实现

使用动量梯度下降法,你需要做的是,在每次迭代中,或者说在第 t t t次迭代的过程中,首先使用现有的mini-batchbatch来计算微分 d W dW dW d b db db,这里省略上标 [ l ] [l] [l]
其次你要做的是通过指数加权平均来计算 v d W v_{dW} vdW v d b v_{db} vdb v d W = β v d W + ( 1 − β ) d W v_{dW}=\beta v_{dW}+(1-\beta)dW vdW=βvdW+(1β)dW v d b = β v d b + ( 1 − β ) d b v_{db}=\beta v_{db}+(1-\beta)db vdb=βvdb+(1β)db 然后重新赋值权重 W : = W − α v d W W:=W-\alpha v_{dW} W:=WαvdW b : = b − α v d b b:=b-\alpha v_{db} b:=bαvdb 这样就可以减缓梯度下降的幅度。
在这里插入图片描述

这个算法中有两个超参数,即学习率 α \alpha α和参数 β \beta β,其中 β \beta β控制着指数加权平均数。 β \beta β最常用的值是0.9,我们之前平均了过去十天的温度,所以这里是平均了前十次迭代的梯度。
关于偏差修正,按照之前的公式,这里应该使用 v d W 1 − β t \frac{v_{dW}}{1-\beta^t} 1βtvdW v d b 1 − β t \frac{v_{db}}{1-\beta^t} 1βtvdb,但实际上人们不这么做,因为经过10次迭代之后,移动平均已经过了初始阶段,所以不会受到偏差修正的困扰。
v d W v_{dW} vdW的初始值是0,这是和 d W dW dW以及 W W W拥有相同维数的零矩阵。同样的, v d b v_{db} vdb的初始值也是向量零,并且和 d b db db以及 b b b拥有相同的维数。
使用动量梯度下降法时,还会遇到另一种表达公式,即 1 − β 1-\beta 1β被删除了。 v d W = β v d W + d W v_{dW}=\beta v_{dW}+dW vdW=βvdW+dW 所以 v d W v_{dW} vdW缩小了 1 − β 1-\beta 1β倍,相当于乘以 1 1 − β \frac1{1-\beta} 1β1,因此当你要使用梯度下降最新值的话, α \alpha α也要根据 1 1 − β \frac1{1-\beta} 1β1相应变化。实际上,二者效果都不错,只会影响到学习率 α \alpha α的最佳值。但是第二个公式使用起来没那么自然,它会有一个影响,如果最后要调整超参数 β \beta β,就会影响到 v d W v_{dW} vdW v d b v_{db} vdb,也许还要修改学习率 α \alpha α,因此更倾向于使用第一个公式。

3.3 本质理解

在这里插入图片描述

如果你要最小化的函数是碗状函数,微分项 d W dW dW d b db db相当于加速度,Momentum项 v d W v_{dW} vdW v d b v_{db} vdb相当于速度。假设你有一个碗,把一个球从碗的某个位置放下,微分项给了这个球一个加速度,此时球向下滚动,因为加速度的作用越滚越快,而因为 β \beta β稍小于1,相当于摩擦力作用,所以球不会无限加速下去,不像梯度下降法那样,每一步都独立于之前的步骤,你的球可以向下滚,从而获得动量。

4. RMSprop (Root Mean Square Rrop)

4.1 算法实现

在每一次迭代中,或者说在第 t t t次迭代中,首先RMSprop算法会计算当下mini-batch的微分 d W dW dW d b db db
接着RMSprop会通过指数加权平均的方式计算 S d W S_{dW} SdW S d b S_{db} Sdb S d W = β S d W + ( 1 − β ) ( d W ) 2 S_{dW}=\beta S_{dW}+(1-\beta)(dW)^2 SdW=βSdW+(1β)(dW)2 S d b = β S d b + ( 1 − β ) ( d b ) 2 S_{db}=\beta S_{db}+(1-\beta)(db)^2 Sdb=βSdb+(1β)(db)2 需要注意的是,这里的平方是针对整个符号的操作,这样做能够保留微分平方的加权平均数。
最后更新参数值 W W W b b b W : = W − α d W S d W + ϵ W:=W-\alpha \frac{dW}{\sqrt{S_{dW}}+\epsilon} W:=WαSdW +ϵdW b : = b − α d b S d b + ϵ b:=b-\alpha \frac{db}{\sqrt{S_{db}}+\epsilon} b:=bαSdb +ϵdb 为了确保这里不会除以0,在实际应用中,需要在分母上加上一个很小很小的 ϵ \epsilon ϵ ϵ \epsilon ϵ一般取 1 0 − 8 10^{−8} 108

4.2 原理解释

在这里插入图片描述

以优化成本函数为例,假设纵轴代表参数 b b b,横轴代表参数 W W W
在横轴方向或者说在例子中的 W W W方向,我们希望学习速度快,即希望 α d W S d W \alpha \frac{dW}{\sqrt{S_{dW}}} αSdW dW较大,因此 S d W S_{dW} SdW会相对较小。
而在垂直方向,也就是例子中的 b b b方向,我们希望减缓纵轴上的摆动,也就是希望 b b b的浮动较小,即 α d b S d b \alpha \frac{db}{\sqrt{S_{db}}} αSdb db的值较小,所以需要分母上的 S d b S_{db} Sdb相对较大。
从上图中可以看到函数的倾斜程度,在纵轴上,也就是 b b b方向上的斜率要大于在横轴上的斜率,也就是 d b db db较大, d W dW dW较小。 d b db db的平方较大,所以 S d b S_{db} Sdb也会较大,而相比之下, d W dW dW会小一些,亦或 d W dW dW平方会小一些,因此 S d W S_{dW} SdW会小一些,结果就是纵轴上的更新要被一个较大的数相除,就能消除摆动,而水平方向的更新则被较小的数相除,就能加快学习。
注:这里把纵轴和横轴方向分别称为 b b b W W W,只是为了方便展示而已。实际上,你会处于参数的高维度空间,可能是参数 W 1 W1 W1 W 2 W2 W2 W 3 W3 W3等的合集。同样的, d W dW dW d b db db也是一个高维度的参数向量。

5. Adam优化算法 (Adam Optimization Algorithm)

5.1 算法实现

使用Adam算法,首先需要初始化 v d W = 0 , S d W = 0 , v d b = 0 , S d b = 0 v_{dW}=0,S_{dW}=0,v_{db}=0,S_{db}=0 vdW=0SdW=0vdb=0Sdb=0 接下来需要在第 t t t次迭代中计算微分,用当前的mini-batch计算 d W dW dW d b db db,一般会用mini-batch梯度下降法
然后计算Momentum指数加权平均数 v d W = β 1 v d W + ( 1 − β 1 ) d W v_{dW}=\beta_1v_{dW}+(1-\beta_1)dW vdW=β1vdW+(1β1)dW v d b = β 1 v d b + ( 1 − β 1 ) d b v_{db}=\beta_1v_{db}+(1-\beta_1)db vdb=β1vdb+(1β1)db 接着使用RMSprop进行更新,即使用不同的超参数 β 2 \beta_2 β2 S d W = β 2 S d W + ( 1 − β 2 ) ( d W ) 2 S_{dW}=\beta_2S_{dW}+(1-\beta_2)(dW)^2 SdW=β2SdW+(1β2)(dW)2 S d b = β 2 S d b + ( 1 − β 2 ) ( d b ) 2 S_{db}=\beta_2S_{db}+(1-\beta_2)(db)^2 Sdb=β2Sdb+(1β2)(db)2 相当于Momentum更新了超参数 β 1 \beta_1 β1RMSprop更新了超参数 β 2 \beta_2 β2
一般使用Adam算法的时候,要计算偏差修正 v d W c o r r e c t e d = v d W 1 − β 1 t v_{dW}^{corrected}=\frac{v_{dW}}{1-\beta_1^t} vdWcorrected=1β1tvdW v d b c o r r e c t e d = v d b 1 − β 1 t v_{db}^{corrected}=\frac{v_{db}}{1-\beta_1^t} vdbcorrected=1β1tvdb S S S也使用偏差修正,也就是 S d W c o r r e c t e d = S d W 1 − β 2 t S_{dW}^{corrected}=\frac{S_{dW}}{1-\beta_2^t} SdWcorrected=1β2tSdW S d b c o r r e c t e d = S d b 1 − β 2 t S_{db}^{corrected}=\frac{S_{db}}{1-\beta_2^t} Sdbcorrected=1β2tSdb 最后更新参数值 W : = W − α v d W c o r r e c t e d S d W c o r r e c t e d + ϵ W:=W-\frac{\alpha v_{dW}^{corrected}}{\sqrt{S_{dW}^{corrected}}+\epsilon} W:=WSdWcorrected +ϵαvdWcorrected b : = b − α v d b c o r r e c t e d S d b c o r r e c t e d + ϵ b:=b-\frac{\alpha v_{db}^{corrected}}{\sqrt{S_{db}^{corrected}}+\epsilon} b:=bSdbcorrected +ϵαvdbcorrected 所以Adam算法结合了MomentumRMSprop梯度下降法,并且是一种极其常用的学习算法,被证明能有效适用于不同神经网络以及适用于广泛的结构。

5.2 超参数的选择

(1) 学习率 α \alpha α:学习率 α \alpha α很重要,经常需要调试,你可以尝试一系列值,然后看哪个更有效。
(2) 移动加权平均系数 β 1 \beta_1 β1:常用的缺省值为0.9,这是 d W dW dW的移动平均数,也就是 d W dW dW的加权平均数,这是Momentum涉及的项。
(3) 移动加权平均系数 β 2 \beta_2 β2:Adam算法的发明者推荐使用0.999,这是在计算 ( d W ) 2 (dW)^2 (dW)2以及 ( d b ) 2 (db)^2 (db)2的移动加权平均值。
(4) 偏置项 ϵ \epsilon ϵ ϵ \epsilon ϵ的选择其实没那么重要,Adam论文的作者建议 ϵ \epsilon ϵ 1 0 − 8 10^{-8} 108,但你并不需要设置它,因为它并不会影响算法表现。

6. 学习率衰减 (Learning Rate Decay)

6.1 概念解释

加快学习算法的一个办法就是随时间慢慢减少学习率。
在这里插入图片描述

假设你要使用mini-batch梯度下降法mini-batch数量不大,大约是64或者128个样本,在迭代过程中会有噪音(蓝色曲线),下降朝向最小值,但是不会精确地收敛,所以最后会在最小值附近摆动,并不会真正收敛,因为使用的学习率 α \alpha α是固定值,不同的mini-batch中有噪音。
在这里插入图片描述

但要慢慢减少学习率 α \alpha α的话,在初期的时候,学习率 α \alpha α还较大,学习还是相对较快,但随着 α \alpha α变小,步伐也会变慢变小,所以最后会在最小值附近的一小块区域里摆动(绿色曲线),而不是在训练过程中,大幅度在最小值附近摆动。
所以慢慢减少 α \alpha α的本质在于,在学习初期,学习率大一些,能以较大的步伐向最小值下降,但当开始收敛的时候,小一些的学习率能让步伐小一些。

6.2 学习率衰减的方法

方法 备注
α = 1 1   +   d e c a y   r a t e   ∗   e p o c h _ n u m α 0 \alpha=\frac{1}{1\ +\ decay\ rate\ *\ epoch\_num}\alpha_0 α=1 + decay rate  epoch_num1α0 decay-rate为衰减率,epoch-num为代数,即遍历训练集的次数, α 0 \pmb{\alpha_0} α0α0α0为初始学习率
α = 0.9 5 e p o c h _ n u m α 0 \alpha=0.95^{epoch\_num}\alpha_0 α=0.95epoch_numα0 学习率呈指数下降
α = k e p o c h _ n u m α 0 \alpha=\frac{k}{\sqrt{epoch\_num}}\alpha_0 α=epoch_num kα0 α = k t α 0 \alpha=\frac{k}{\sqrt{t}}\alpha_0 α=t kα0 t t tmini-batch的数字
离散下降(discrete stair cease) 在这里插入图片描述

7. 局部最优的问题 (The Problem of Local Optima)

在深度学习研究早期,人们总是担心优化算法会困在极差的局部最优,不过随着深度学习理论不断发展,我们对局部最优的理解也发生了改变。
在这里插入图片描述

上图是曾经人们在想到局部最优时脑海里会出现的图,在图中似乎各处都分布着局部最优。梯度下降法或者某个算法可能困在一个局部最优中,而不会抵达全局最优。如果你要作图计算一个数字,比如在上图的两个维度中,就容易出现有多个不同局部最优的图,而这些低维的图曾经影响了我们的理解,但是这些理解并不正确。事实上,如果你要创建一个神经网络,通常梯度为零的点并不是这个图中的局部最优点,实际上成本函数的零梯度点,通常是鞍点。
在这里插入图片描述

但是一个具有高维度空间的函数,如果梯度为0,那么在每个方向,它可能是凸函数,也可能是凹函数。假设你在一个2万维空间中,想要得到局部最优,那么所有的2万个方向都需要是凹函数或者都是凸函数,但这样子发生的机率也许很小,大概只有 1 2 20000 \frac{1}{2^{20000}} 2200001,而更有可能遇到有些方向的曲线会向上弯曲,另一些方向曲线向下弯曲,而不是所有的都向上弯曲,因此在高维度空间,你更可能碰到鞍点,而不会碰到局部最优。
在这里插入图片描述

而另一个问题是在平稳段会减缓学习,平稳段是一块区域,其中导数长时间接近于0,如果你在此处,梯度会从曲面自上而下地下降,因为梯度等于或接近0,曲面很平坦,你得花上很长时间慢慢抵达平稳段的这个点(蓝色曲线),然后因为左边或右边的随机扰动,你的算法能够走出平稳段(红色曲线)。
总结一下这部分的要点:
第一,你不太可能困在极差的局部最优中,除非是在训练较大的神经网络,存在大量参数,并且成本函数 J J J被定义在较高的维度空间。
第二,平稳段是一个问题,这会使得学习十分缓慢,在这种情况下,使用更成熟的优化算法,如Adam算法,能够加快速度,让你尽早往下走出平稳段。

猜你喜欢

转载自blog.csdn.net/baoli8425/article/details/118607407