梯度下降算法及其改进方法详解

来源:互联网 发布:java compare 和equals 编辑:程序博客网 时间:2024/04/30 07:17

梯度下降算法及其改进方法详解

本文中例子来源于:
https://zhuanlan.zhihu.com/p/21486826
https://zhuanlan.zhihu.com/p/22810533

1. 前提

1.1 成本函数

设计完神经网络结构之后,接下来就要设计神经网络的学习算法。假设向量X为神经网络的输入向量,向量Y为神经网络的输出向量,向量A为实际输出。我们算法的目的是使实际输出尽可能等于期望输出。为了量化算法的好坏,我们定义一个损耗函数(cost function):

C(w,b)12ni=1nYiAi2(1)

上式中,w,b分别为网络中权值和偏置的集合,即w=w1,w2,b=b1,b2,n是输入训练样本的总数。 Yi表示在第i个样本输入下的期望输出,Ai 表示在第i 个样本下的实际输出。 为范数运算。
公式(1)实际上是计算的期望输出与实际输出差值的平均值,因此(1)也被称为均方误差(MSE, mean squard error)。当我们的算法足够好时,期望输出与实际输出应近似相等,此时公式(1)均方误差C0。换句话说,我们的算法的目的变为找到一组权值和偏置的集合使得均方误差取得最小值。

1.2 为什么要用均方误差?

我们最终的目的是神经网络输出的准确率,为什么不直接让正确率最大化而是找一个替代方法?这是因为神经网络的正确率不是关于权值和偏置的光滑函数。更进一步来说,权值和偏置的微小变化不一定能引起正确率的变化,所以我们就不能通过正确率来不断修改权值和偏置来提升性能。为什么我们选择均方误差作为成本函数而不用其他?当然有其他成本函数我们在后面介绍,但要指出的是,公式(1)很好用。

2. 梯度下降算法

上面已经说了,我们的目的是求成本函数的最小值。数学上常用的方法是通过求导计算目标函数的最小值(如拉格朗日乘数法)。这在目标函数变量不太多时非常有效,但在变量很多时就有些力不从心了。比如,一个大型神经网络,权值和偏置的数目往往以亿万计,如果用上述方法会变得异常麻烦(此时拉格朗日乘数法要解一个亿万个函数组成的方程组)。对此,我们提出了梯度下降算法(GD, gradient descent)来解决这个问题。

2.1 批梯度下降算法(BGD)

我们把成本函数C 想象成一个山谷表面,其梯度的负方向就是下降速度最快的方向,假设我们有一个小球,那么小球只要沿着这个方向就可以最快到达谷底,即最快取得最小值(有可能停在局部极小值处,我们要避免这种情况)。梯度的定义为:

C(Cw1,Cw2,Cb1,Cb2,)(2)

假设球在w1 方向上移动的距离为Δw1,在w2 方向上移动的距离为Δw2,。由全微分可得,求在曲面上移动距离为:
ΔC=Cw1Δw1+Cw2Δw2++Cb1+Δw1(3)

接下来要找到一种方式,保证ΔC是负的,只有这样,球才是往下走的。由公式(2)和公式(3)我们可以得出:
ΔC=CΔV(4)

其中ΔV=(Δw1,Δb1,)T,从公式(4)我们可以看出应如何选择ΔV才能保证ΔC为负数,假设我们的选择如下
ΔV=η(C)T(5)

其中η是一个取值0~1 的正数,称为学习率。此时公式(4)变为:
ΔC=ηC(C)T=ηC2(6)

因为C20,所以ΔC0
由公式(5)我们可以得到权值和偏置的更新公式V=Vη(C)T,具体来说就是:
wkbk==wkηCwkblηCbl(7)

上述算法称为批梯度下降算法(BGD, batch gradient descent) ,由公式(1)和公式(5)我们可以看出,为了计算出C 需要计算所有样本的误差,换句话,为了得到一次更新值需要把所有样本都输入计算一遍。
下面是批梯度下降算法的流程图:

Created with Raphaël 2.1.0开始初始化权值、偏置、学习率输入一个样本,计算输出A计算误差Y-A所有样本都已经输入完? 用更新公式更新权值和偏置结束 yesno

2.2 随机梯度下降算法(SGD)

当样本很多时,梯度下降算法每更新一次都要输入所有样本,因此非常耗时。因此就有了随机梯度下降算法(SGD, stochastic gradient descent),其基本思想是:随机选择一个样本作为输入然后更新一次权值和偏置。此时公式(1)变为:

C(w,b)=YA22(8)

更新公式为:
wkbk==wkηCwkblηCbl(9)

流程图为:

Created with Raphaël 2.1.0开始初始化权值、偏置、学习率输入一个样本,计算输出A计算误差均方误差用更新公式更新权值和偏置所有样本都已经输入完? 结束 输入下一样本yesno

实际上随机梯度下降算法计算的并不是真正的梯度,真正的梯度应该像批梯度计算那样需要所有样本才能计算。随机梯度只是用一个样本进行对真正的梯度进行了一次预估,因此可能会有偏差。即随机梯度下降算法不一定保证每次前进方向都是正确的,所以会带来波动。

2.3 微批量梯度下降算法(MGD)

随机梯度下降算法虽然更新速度变快,但每次更新方向不一定正确,所以有可能“绕远路”。因此又提出了微批量梯度下降算法(MGD, mini-batch gradient descent)。其核心思想是:每次选择若干样本估计梯度,比如每学习100个样本更新一次梯度和权值。
首先,从所有样本中随机选出m个样本。我们把这m 个样本编号为X1,X2,,Xi,,Xm, 并称他们为微批量(mini-batch)。此时,均方误差变为:

C(w,b)=12mi=1mYiAi2=1mi=1mCXi(10)

其中CXi=YiAi22,由梯度可得下式:
C=1mi=1mCXi(11)

因此,公式(11)就用m个样本数据估计出整体的梯度,当m 越大估计越准确。此时更新公式为:
wkbk==wkηCwk=wkηmi=1mCXiwkblηCbl=blηmi=1mCXibl(12)

其流程图为:

Created with Raphaël 2.1.0开始初始化权值、偏置、学习率输入一个样本,计算输出A计算误差均方误差所有m个样本都已经训练完? 用更新公式更新权值和偏置所有n个样本都训练完?结束 选取另外m个样本输入下一样本yesnoyesno

2.4 三种梯度下降算法比较

批梯度和随机梯度相比较而言,批梯度由于使用了所有样本数据,因此每一次都会朝着正确的方向前进,最后能保证收敛于极值点(凸函数收敛于极值点,非凸函数可能会收敛于局部极值点)。而随机梯度只用了一个样本数据进行估计真正的梯度,因此每次前进的方向不一定都是正确的,训练过程中会出现波动。这些波动使得会导致出现“绕远路”现象,即迭代次数变多,甚至收敛速度变慢。不过从另一个方面来看,随机梯度下降所带来的波动有个好处就是,对于类似盆地区域(即很多局部极小值点)那么这个波动的特点可能会使得优化的方向从当前的局部极小值点跳到另一个更好的局部极小值点,这样便可能对于非凸函数,最终收敛于一个较好的局部极值点,甚至全局极值点。另外,由于随机梯度的期望是梯度本身,即随机梯度以概率收敛于梯度,所以在训练样本足够多的情况下随机梯度和梯度有相似的结果。
微批量梯度下降算法与另外两种比较m=n 时即为批梯度下降算法,m=1 时即为随机梯度下降算法,因次微批量梯度下降算法具有其他两种算法的特性。当m值选择合适时,有超越另外两种算法的性能,而且微批量算法容易实现并行运算,因此应用最广。现在,有些文献中对微批量梯度下降算法和随机梯度下降算法不进行区分,随机梯度下降算法就是指微批量梯度下降算法(我们上文中所介绍的随机梯度下降算法医应用较少)。

3. 梯度下降算法的改进

梯度下降算法有很多改进算法,比如一阶方法主要有:动量法、Nesterov accelerated gradient 、Adagrad、Adadelta与RMSprop,二阶方法有:牛顿法、拟牛顿法等。因为有些改进方法仅仅是某些情况下才有较好的效果,而有的方法较为复杂,增加了计算量。因而它们大部分应用并不广泛。这里我们仅仅介绍一种简单而且应用最广泛的一种改进方法——动量法(momentum)

3.1 动量法(Momentmu)

动量法是一种非常简单的改进方法,已经成功应用数十年。动量法的核心思想是:在梯度方向一致的地方加速,在梯度方向不断改变的地方减速。其更新公式为:

ΔVt=ρΔVt1η[C(Vt1)]T(13)

其中ρ 是一个取值0~1的常数,称为动量因子,常取0.9。它的大小决定这动量项作用的强弱,当ρ=0 时没有影响,当ρ=1 时影响最强,平滑效果明显。这种方法对于像一些又长有窄的山谷一样的复杂的成本函数面时更为有效。尽管沿着山谷方向的梯度要比横跨山谷方向的梯度要小的多,但因为沿着山谷方向的梯度方向是一致的,因此动量项能加快其学习速度。而横跨山谷的方向梯度的方向不断变化,因此动量项能减小其更新量,减慢学习速度,这有效减小了在横跨山谷方向上的来回震荡。具体而言,动量项发挥作用主要表现在以下几个方面:

* 在下降初期,使用前一次的大比重下降方向,加速。
* 在越过函数谷面时,异常的学习率,会使得两次更新方向基本相反,在原地“震荡” 此时,动量因子使得更新幅度减小,协助越过函数谷面。
* 在下降中后期,函数面局部最小值所在的吸引盆数量较多,一旦陷进吸引盆地当中,梯度趋于零,会导致止步不前,学习无法进行。如果有动量项的话,动量因子使得更新幅度增大,协助跃出吸引盆。
为了更详细理解动量法的作用,下面我们举一个例子。假设被优化函数即成本函数C=x2+50y2,其函数等高线为(图中蓝点表示最优值):

成本函数的等高线图

我们现在用随机梯度下降算法用较小步长迭代50次看看:
这里写图片描述

可以看到整体是向着最优点前进,但到后面却有些乏力。接下来增大步长看看:
这里写图片描述

可以看出有很严重的震荡现象,继续增大步长:
这里写图片描述

可以明显看出,再面对山谷这种函数表面时,随机梯度下降算法会在横跨山谷的方向上来回震荡。接下来,我们有加入动量项的改进方法试试:
这里写图片描述

我们发现,加入动量项在迭代50次以后,已经基本来到了最优点附近,比原来方法要好不少。

3.2 涅斯捷罗夫梯度加速法(NAG)

由公式(13)我们可以看出,动量法更新其实包括两部分:一部分是上一时刻的更新值ρΔVt1,这一部分是上一次就已经算出来了,是已知的;另一部分是基于当前位置计算出来的梯度η(C)T涅斯捷罗夫梯度加速法(NAG, Nesterov accelerated gradient) 则指出:既然我已经知道本次更新一定会走ρΔVt1 的量,我为什么不先走上ρΔVt1,然后再根据那里的梯度前进一下,岂不美哉?于是就有了以下更新公式:

ΔVt=ρΔVt1η[C(Vt1ρΔVt1)]T(14)

上式与动量法公式(13)相比,唯一的区别就是梯度的计算不是在位置Vt1 处,而是多走了一步,计算(Vt1ρΔVt1)位置处的梯度。
我们用NAG方法迭代50次之后得到下图:

这里写图片描述

可以看出,NAG方法不仅接近了最优点,而且更有效的减少了震荡。

0 0
原创粉丝点击