优化算法
(一)Mini-batch gradient descent
如上图所示,批量梯度下降法对训练集的一轮处理只能得到一步梯度逼近,而小批量梯度下降法中对训练集的一轮处理也就是一次遍历,可以得到5000步梯度逼近。其中,训练集的一次遍历叫做一个epoch。
在批量梯度下降算法中,每一次迭代将遍历整个训练集,代价函数的值应该随之不断减小。如果某一次迭代值增加了,那么一定是哪里错了。也许是学习率设置的太大。
在小批量梯度下降中,并不是每一次迭代代价函数的值都会变小,但是整体趋势必须是向下的。之所以有噪声(震动)的存在,可能和计算代价函数时使用的那个批次X{t} Y{t}有关,让代价函数的值或大或小;也可能这个批次里含有一些标签标错的数据,导致代价函数有一些高等等。
那么在mini-batch的梯度下降中如何选择mini-batch的大小呢?
假设m=训练集中的样本数目,
- 当mini-batch size = m时,即为批量梯度下降
在优化代价函数时,噪声相对小些,每一步相对大些,并且最终可以达到最小值。缺点就是如果训练集非常大,就将在每一次迭代上花费太长的时间。 - 当mini-batch size = 1时,即为随机梯度下降
在优化代价函数时,最后不会收敛到一个点,一般会在最低点附近摆动。缺点就是失去了可以利用向量加速运算的机会,因为每次只处理一个训练数据是非常没有效率的。 - 当mini-batch size 位于(1,m)时,即为小批量梯度下降。
在优化代价函数时,虽然并不能保证总是可以达到最小值,但是相比随机梯度下降,噪声会更小而且不会总在最小值附近摆动 。弥补了上述两者的缺点,既可以进行向量操作又可以不用遍历完整个训练集才能进行一次迭代。
综上,当数据集大小<2000,直接采用批量梯度下降即可。对于大数据集一般选择64到512(2的整数幂)作为mini-batch的大小。最后就是确保所有的X{t} Y{t} 是可以放进CPU/GPU 内存的。
(二)指数加权平均操作
上图是一个关于天数和温度的散点图,计算公式为
v
t
=
β
v
t
−
1
+
(
1
−
β
)
θ
t
v_t = \beta v_{t-1} +(1-\beta) \theta_t
vt=βvt−1+(1−β)θt。其中
v
t
v_t
vt代表到第t天的平均温度值,
θ
t
\theta_t
θt代表第t天的温度值,
β
\beta
β是一个超参数。
当
β
=
0.9
\beta = 0.9
β=0.9时,指数加权平均的结果如红色线所示,当
β
=
0.98
\beta = 0.98
β=0.98时,指数加权平均的结果如绿色线所示,当
β
=
0.5
\beta = 0.5
β=0.5时,指数加权平均的结果如黄色线所示。通常取中间值0.9更好,也就是这里的红色的曲线,它对温度的平均比绿色或者黄色的曲线更好。
下面对100天的温度平均值计算公式进行展开。
本质就是以指数式递减加权的移动平均。各数值的加权而随时间而指数式递减,越近期的数据加权越重,但较旧的数据也给予一定的加权。
指数加权平均的结果是由当天温度值乘以指数衰减函数值,然后求和所得。
指数加权平均的实现
我们可以看到指数加权平均的求解过程实际上是一个递推的过程,那么这样就会有一个非常大的好处,每当我要求从0到某一时刻(n)的平均值的时候,我并不需要像普通求解平均值的作为,保留所有的时刻值,累加和然后除以n。
而是只需要保留0-(n-1)时刻的平均值和n时刻的温度值即可。也就是每次只需要保留常数值,然后进行运算即可,而这仅仅需要一行代码。这对于深度学习中的海量数据来说,是一个很好的减少内存和空间的做法。
指数加权平均的一个技术细节
当我们利用上述公式计算之后,实际上我们得到的并不是绿色的曲线而是紫色的曲线,通过紫色曲线可以看出在预测的初期值和真实值的差距很大,所以引入了偏差修正(bias correction)的概念。
简而言之,就是用
v
t
1
−
β
t
\frac{v_t}{1-\beta_t}
1−βtvt代替
v
t
v_t
vt。
(三)Gradient descent with momentum
动量梯度下降算法就是计算梯度的指数加权平均数并利用该提督来更新权重,而它几乎总是优于不使用动量的算法。
如上图所示,在进行代价函数优化时会发生震荡,这也让我们不能把学习率设置的太大。
直观解释:如果把这些梯度平均一下,你会发现这些震荡在纵轴上的平均值趋近于0。所以在垂直方向上,你会希望减慢速度。正数和负数在计算平均时相互抵消了,平均值接近于0。然而在水平方向上,所有导数都指向水平方向的右边,所以水平方向的平均值仍然较大。
因此在数次迭代之后,动量梯度下降算法的每一步在垂直方向上的振荡非常小且在水平方向上运动得更快,这会让你的算法选择更加直接的路径或者说减弱了前往最小值的路径上的振荡。
具体实现
通常 β \beta β设置为0.9是比较稳健的选择。
(四)RMSprop
Root Mean Square Prop也是一种可以加快梯度下降的自适应学习率算法。
在如上图的实现过程中,RMSprop将微分项进行平方,然后使用平方根进行梯度更新,同时为了确保算法不会除以0,平方根分母里面加了一个小的值
ε
=
1
0
−
8
\varepsilon = 10^{-8}
ε=10−8。
RMSprop 和动量一样能够降低梯度下降中的振荡并且能使用更大的学习率
α
\alpha
α, 从而提高算法的学习速度 。
(五)Adam
这是不同的神经网络架构中都是十分有效的一种优化算法——Adaptive moment estimation。
算法中超参数的选择:
- 参数α依然很重要且通常需要调整,可以尝试不同的值来比较效果
- β 1 \beta_1 β1默认设置0.9,表示 d w dw dw,被称为第一阶的矩
- β 2 \beta_2 β2默认设置0.999,表示 d w 2 dw^2 dw2,被称为第二阶矩
- ε = 1 0 − 8 \varepsilon = 10^{-8} ε=10−8
(六)Learning rate decay
逐渐缩小学习率或许可以使收敛速度更快,即学习率衰减。简而言之,随着迭代次数的增加,减小学习率。
在学习的初始步骤中,你可以采取大得多的步长;但随着学习开始收敛于一点时,较低的学习率可以允许你采取更小的步长。
常用实现方法
- α = 1 a + d e c a y r a t e ∗ e p o c h N u m b e r α 0 \alpha = \frac{1}{a+decayrate * epochNumber}\alpha_0 α=a+decayrate∗epochNumber1α0
- 指数衰减: α = 0.9 5 e p o c h N u m b e r α 0 \alpha = 0.95^{epochNumber}\alpha_0 α=0.95epochNumberα0
-
α
=
k
e
p
o
c
h
N
u
m
b
e
r
α
0
\alpha = \frac{k}{ \sqrt {epochNumber}}\alpha_0
α=epochNumberkα0 或者
α = k t α 0 \alpha = \frac{k}{ \sqrt {t}}\alpha_0 α=tkα0
(七) 如何看待局部最优以及深度学习中的优化问题
人们直觉的低维图像中,会存在如左图的陷入局部最优的情况;但在神经网络代价函数中,大部分梯度为零的点实际上并不是像这样的局部最优而是如右图的鞍点(Saddle Point)。
因为对于一个高维函数,要得到梯度为0的点,每个方向上全是向下弯曲或是全是向下弯曲,假设在20000维空间中,这样情况发生的概率为
2
−
20000
2^-20000
2−20000,概率特别低。
综上,在高维函数中:
- 几乎不可能出现陷入局部最优的情况
- 反而处于鞍点的停滞区会减慢训练过程,这时便可以利用Adam进行改善了。