机器学习初探-常用优化算法介绍

目的:简单介绍机器学习中常用的一些优化算法,主要用于无约束最优化问题的求解。具体包括梯度下降法(最速梯度下降),牛顿法,几个拟牛顿法(包括DFP,BFGS,LBFGS等,共轭方向法,共轭梯度法,信赖域方法等不在本次做讨论)。

概述

一般的有监督的机器学习问题中,有了带有标注的数据之后,我们往往会先假设一个模型(比如在二分类问题中,我们可以假设有一个超平面把不同类别的case分开),这些假设的模型的数学表达中会有一些未定的参数。然后,我们会设计一个函数,来衡量会这个模型的输出和我们期望的输出之间的“差距”,这个函数一般被叫做损失函数。之后在将这个损失函数和正则化项组合成目标函数(obj)。最后对obj函数进行最优化(一般也就是求极值),来确定模型中的各个参数,最终完成模型假设。这个过程也就是我们常说的机器学习的过程,也就是参数估计的过程。

这当中的最优化问题,说直白点,就是有一个函数,我们要找到它的极值(全局或者局部)。如果我们找到这些极值,就可以用这些取得极值时的数据,来确定我们假设模型中的参数。总体来说,我们的目标就是当obj确定了之后,通过一些方法,来确定极值在哪里,是多少。

本文后面的部分,就是来讨论一下针对最优化这一问题,一般有哪些常用的方法。

 

问题抽象

确定函数下找最值(以下我们以找最小值为例),就是一般的通用无约束最优化问题:

 

怎么找呢?如果f本身连续,又可导,可微,而且f比较简单(比如说单变量二次函数),那么我们可能直接可以通过解方程的方式得到解析解,从而找到最小值。但是在一般情况下,f(x)都比较复杂(尤其是维度很大,f本身非凸的情况下),有可能会不可导,不可微分,或者求导困难,所以针对更一般的情况,我们采取的通用方法是迭代法。迭代法大体是如下一种方法:是先猜一个点(估计点),之后根据这个点x0,再附近(比较近的范围内)再找一个点x1,让f(x1),使得基本没办法再找到新的,使得了,或者周边的f(x)差距非常非常小了,那么这个点可能就是我们希望找到的f(x)取得最小值的x的取值点(全局或者局部最小点)。

用数学一点的话来讲,我们希望找到一个序列 x0,x1,x2.....(或者找到一个算法生成这样的序列),使得在定义域上,f(x0)>f(x1)>f(x2).....>f(),如果f() 基本上等于f(x)的最小值,或者说lim  == X*,lim ||-X*|| == 0(在k趋近于无穷时,X*为极值点的x取值),那我们就说这个算法产生的迭代,收敛于f(x)的最小值取值点X*。

 

一般做法

我们希望找到一个算法,或者找到一个迭代,使得上面的过程成立,从而找到最小值。具体怎么做呢?

我们聚焦到一步,来看看一般情况下的做法。假设我们目前更新到的Xk,那下面就有2种情况:第一种情况,无论向周边怎么移动,也没有比f()更小的值了,那么时就取得了f(x)的最小值;第二种,如果至少还有1个方向P(||P||==1),使得向这个方向移动,可以使f(x)的值变小,那么我们让+aP,使得f())即可。这里我们称P为方向,也就是X要往哪里走,a为步长,也就是走多少。如果算法是有效的,那么最终我们就会找到X*。

所以,优化问题基本可以看成2个阶段的抉择:1.选取一个方向P;2.选取一个步长a。其中选取P比较重要,各种各样不同的算法,基本上就是根据选取P的策略不同而不同的。对a的选择也有很多方法,最简单的方法是固定选取一个固定的,较小的a(比如a=0.005 ~ 0.01);有的时候可以先选一个a,之后根据迭代后P的大小,来动态的调整a;另外就是line search类a选取方法等等,我们下面会有详细的涉及。

 

下面我们就来看看几个常用的无约束问题的优化算法。


梯度下降法(最速下降法)

梯度下降(Gradient Descent) 也被称之为最快下降法(Steepest Descent),可用于寻找函数的最小值(局部最小值)。梯度下降法的思路,是利用函数值在梯度反方向来作为X的迭代方向,也就是。只要沿着函数的梯度反方向移动足够小的距离到一个新的点,那么函数值必定是非递增的,而且在梯度下降法的假设前提下,负的梯度方向是下降是最快的方向。

梯度下降法,顾名思义,就是利用obj函数的一阶导数来寻找最小值。对于f(x),我们根据泰勒公式的一阶展开,可以得到如下的拟合(对应向量的情况):

其中的高阶无穷小,忽略。并且是我们要找的方向,且==1,是步长,且>0。

我们先来看看如何找到。我么你要找一个,使。我们根据,要达到,只要 <0即可。

根据向量夹角公式,我们可以把写成 。cos的最小值是-1,即theta的取值为π时,当取得。(Cuachy-Schwartz不等式保证了)。

梯度下降算法就是选取了,所以也叫最速下降法(一阶情况下,这个方向最快!)

 

下面给出了梯度下降算法的基本算法描述:

按照上面的算法一,第三步的d,我们每次选取当前点的负梯度方向,这个已经解决了。在第四步,需要选取一个合理的步长,使得的h(a)最小。

a的好坏对收敛速度的影响也很大,一句话来说:a太小,收敛太慢;a太大,容易震荡,甚至找不到最小值点。(如图)

怎么寻找合适的步长呢?答案就是 Line search

线性搜索,又叫一维搜索,试求一元函数极值的迭代方法。

在给定搜索方向 dk  的前提下,线性搜索要解决的问题如下:  

如果 h(α)  可微且导数也是连续函数,我们能直接通过解方程的方式求出解析解,从而得到最优的步长,这种方法一般叫做*精确线性搜索(精确line search);但非线性,不连续的优化问题需要通过迭代形式求得近似的最优步长。对于上式,局部或全局最优解对应的导数为

因为dk与f(xk)在xk处的梯度方向夹角大于90度(这样才函数值会下降),因此h'(a)<=0,如果能找到α1,使得h'(α1)>0,那么必定存在 αt[0,α1) ,使得h'(αt)=0。有多种迭代算法可以求得αt的近似值,下面选择几种典型的介绍。

    *二分线性搜索(Bisection Line Search),其实就是二分折半查找,收敛速度就是log级别的

    *黄金分割发,单峰函数上的搜索,可以不要求函数连续

    *回溯线性搜索(Backing Line Search),根据Armijo(阿米霍)法则,从大得a开始逐渐按比例减小,直到达到满足下降情况的要求。(后续还可以加入wolfe准则)

                Armijo准则:

    *多项式插值法(Interpolation),也是基于Armijo法则,常用的是根据f(xk),f'(xk)和一个尝试的f(xk+a0dk),来构造一个二项式来拟合f(x) ,通过迭代来得到f(x)的最小值

    *其实牛顿法也可以用来求步长,牛顿法我们后面具体再说,求步长其实就是把要求的函数换成h(a),求a得极值即可。


ok,现在我们找到了要移动的方向P,又找到了移动的步长a,这样迭代下去,直到收敛或者达到最大的设定迭代次数,基本就可以找到obj的最小值了。那么梯度下降法有什么缺点呢?它真的是下降最快的算法吗?其实选取负梯度的方向作为x的移动方向,只能保证在x一定的邻域内有这种快速的下降性质,对整个定义域内,f的最小化来说,并不一定是这样。比如下图:

 

同心椭圆的最速下降过程可以看出,最速下降法对全局来说,不一定是下降最快的,它的下降过程是一种阶梯下降,而且随着越来越接近最优点(即f'(x)接近0的点),收敛速度会变的越来越缓慢。

下面就请出传说中的Rosenbrock function(罗森布罗克方程)!噔噔蹬蹬! 

它是个非凸函数,在最优化领域,它通常被用来作为一个最优化算法的performance test函数,三维图像如下:

利用梯度下降法,我们的迭代情况如下图所示:


可以看到刚一开始速度还可以,但是到后面的收敛情况变得非常的缓慢。

在看另一个函数:

它的图像如下:

利用梯度下降法,迭代情况如下图所示:

由此可见,从全局情况来看,梯度下降法(最速下降法)不一定会快,但是他还是能收敛的,收敛速度是线性收敛。

当然,梯度下降法也有很多优点:对初始化点无要求,过程简单(程序好写),计算量也不大,它是很多其他优化算法的基础,其他方法的初始化方向很多也是选用负梯度方向。

 

梯度下降法应用的3种方式

实际应用(训练)中一般有三种使用梯度下降的方式:随机梯度下降(stochastic gradient descent),批量梯度下降(batch gradient descent)以及小批量梯度下降(mini-batch gradient descent)。看名字就知道,这三种的区分,就是看要用多少数据来计算梯度方向。

批量梯度下降(batch gradient descent),也叫Vanilla gradient descent,是用全部数据来计算梯度方向,,计算量比较大,但是单次迭代看方向更准。

随机梯度下降(stochastic gradient descent)每一轮都会用一个数据来计算梯度方向,,比较适合做online learn,计算很简单,但是更新方向不稳定,可能波动会很大,需要学习率配合来达到收敛。下图描述的就是sgd的下降情况,他是在小范围呢波动的情况下,整体趋势下降。

小批量梯度下降(mini-batch gradient descent)介于上面两个方法之间,,计算量介于前两者之间0,方向波动比sgd小。

 

在海量训练数据的情况下,sgd相对于batch在整体收敛速度方面有很大的优势,这也使它在现在的实际应用中更为常见一些;在收敛性质方面,sgd是依期望收敛域最小值附近,这个证明比较复杂,会基于几个基本假设,比如梯度变化不能太剧烈,梯度选择的分布情况等,还会涉及强凸函,又牵扯到很多数学上计算boundary的过程,在这里不再详细描述,感兴趣的同学,可以参考《Optimization Methods for Large-Scale Machine Learning》 一文中的 ”4 Analyses of Stochastic Gradient Methods“中的详细证明。l领一个简单版本的证明请见慕容熙熙的博客中”随机梯度下降“一文。(http://www.cnblogs.com/murongxixi/p/3467365.html)

PS:为了防止那天404,我们把简单的证明过程贴过来。copyright by 慕容熙熙。

可以看到,这个证明基本上也是基于几个假设:梯度的期望值不能太大,初始点的值不能距离最优值不靠谱的远,另外证明过程中隐含了F的凸函数特性。当满足这些假设后,我们选取合适的学习率让,它满足上面的条件,即可以得到SGD依照期望收敛的证明。

 

速度方面,海量训练数据情况下,sgd有着比较明显的优势,我们看下表来得到收敛的速度以及误差的情况。

可以看到,sgd的搜索速度,基本和迭代次数相关,而batch的梯度下降,和训练数据n成正比。具体细节,可以参考上面提到的综述。


理性放一旁!感性的认识。。

看证明比较痛苦,不过没关系,我们可以直接的从感官上来理解一下为什么sgd比bgd的收敛,一般情况下会快一点。

我们看一个一般的需要优化的目标函数,如下:

我们假设L函数是简单的单变量2次形式,我们又有6个样本点,每个样本点都有点噪声波动,暂时不考虑正则部分欧米伽的话,于是我们有了下图:

其中黑色的是每个样例的单独的图像,对应sgd一次迭代时的某一种选择,而红色的是所有的样例合起来再取均值的图像,对应的最终我们要求得目标函数,也就是bgd时的图像。

当我们初始化了一个x之后,如果x比较靠近数轴的左边(或者比较靠近右边),比如x取的值小于-10,那么无论你随机取到哪一个样例来做sgd,x的更新方向都和做bgd时一样,是向右的。但是sgd得到这个向右的更新方向,要比用bgd少算了5次。看到了吧,计算量变少了!这时间我们跟新x,比如x变成了-5,那么后面的计算同理,无论下一轮sdg取哪个样例来计算方向,方向还是对的,你有,有少算了5次。。。那是不是一直会这样的?不是的,当x更新的比较接近最优值了,比如x在4左右,那么在使用sgd的时候,就有很大概率会取得错误的方向,这时候就看出了bgd的好处,它的方向是稳定了,但是得到这个方向还是要经过N此计算才可以。反观sdg,虽然有不小的概率取得错误的方向,但是,取得对的方向的概率还是会比取得错误的概率大一些(正确方向刚好是sgd的期望),在这样的情况下,如果我们能让步长不太大,那么x更新的范围就不会太大,收敛情况的震荡的就不会太厉害了,多迭代几轮,或者接受一个可以忍受的小误差,我们还是能很快得到最小值时x*的近似解的,这个计算每次只需要一次计算,及时做很多次,只要比N小,还是划算,这也就是sgd在很多时候,收敛的速度都比bgd快的原因了。

这中采样的方式,使得sgd的波动在取值在最优值附近的时候难以避免,整个收敛因为采样的原因呈现波动性,随着学习率的不断降低,波动的幅度减小。整个收敛的过程如下图所示。

 

这里要注意的是,当梯度变小时,sgd要求学习率也要变得很小,这个会导致sgd对x的更新变慢,但是由于只有梯度很小时才有这个问题,这个时候x的值已经比接近最优值x*了,所以还是可以接受的。实际中,使用sgd的时候,经验上我们也推荐使用更小的学习率,来保证收敛。

 

牛顿法(Newton's Method)

牛顿法,也叫牛顿迭代法,也是以迭代方式来求函数的根,变通一下就可用于求极值。它基本思想是从一个初始点出发,不断在当前点xk处用切线近似函数f(x),并求得该切线与x轴的交点作为下一次的迭代初始点xk+1,直到找到 f(x)=0的近似解为止。对于二次可微函数f(x),如果我们是对其导数来求0值点,那么对于也就相当于求得了原先f(x)的驻点,如果f(x)是凸函数,也就求到了f(x)的极值了。因此Newton法可用于二次可微函数f(x)的最优化问题。


假设我们要最优化的函数为f(x),我们在xk处对f(x)进行二阶的泰勒展开:

 

Bk就是f(x)在kx对应的hessian矩阵,我们可以用

的右边来拟合f(x),我们称之为q(x)。于是问题就化成了,在xk附近找到一个增量△x,使得q(x)取得极小值,所以变量就变为△x。我们对q(△x)求导可得xk+1=xk+△x处的导数为

要求q(xk+1)为最值,那么q(xk+1)==1,所以有

这样,我们通过解方程,或者直接求海森矩阵的逆来计算新的xk+1的值即可。

牛顿法的迭代算法流程如下:

牛顿法的收敛速度很快,二次函数的话(正定),可以直接1次找到最优解。这点很不错,但是也有缺点:1.计算比较多。每个迭代都要求一阶导数,二阶导数(海森矩阵)以及海森矩阵的逆矩阵。2.要求函数可导,海森举证可逆(海森矩阵非奇异,若果奇异了,就需要修正)。3.迭代有可能出现循环(),这个就尴尬了,有时候虽然得到了行的xk+1,但是却并不能使f(xk+1)

 

拟牛顿法(Quasi-Newton's Method)

拟牛顿法是一些列方法的总称,顾名思义,这些方法都是通过”模拟“牛顿法的方法来解决最优化问题的,它们模拟了牛顿法中搜索方向(可以叫作”牛顿方向“)的生成方式。

前面提到了,牛顿法在每一次要得到新的搜索方向的时候,都需要计算海森矩阵。这个计算在自变量维数非常大的时候非常耗时,为了优化这一计算,拟牛顿法就应运而生了。它们采用了一定的方法来构造与海森矩阵相似的正定矩阵,而这个构造方法计算量比牛顿法小很多了。

那用海森矩阵的相似矩阵代替的话,优化效果会变差么?简单来说,我们知道牛顿方向本身就是根据泰勒公式的二阶拟合来推断下降方向的,其中已经舍弃了高阶无穷小的部分,本身就是一种近似了,如果海森矩阵的相似矩阵跟原始的海森矩阵相差很小,那么这个替代计算出的,也应该还是下降方向的近似,不会差太远,不会对下降方向的选择造成很大影响。实际上,这个相似矩阵的替换,不但不会降低效果,反而很多时候效果还会变好。。。根据牛顿迭的原理,我们可以得到

进而可以得到

左边的部分就是Y,也就是f(x)沿着q'(x)方向的变化量,如果要函数下降,就需要这个值是负数,也就是右边是负数。也就是要求Bk是正定矩阵。在远离最小点的区域,牛顿法求得的B不一定是正定矩阵,而拟牛顿法中我们找的B的相似矩阵H就可以是正定矩阵,保证了下降。当靠近最小点的区域,那么B和H很接近,都有二阶收敛速度。所以整体上来说,这种相似替代,很可能会有差不多,甚至更好的收敛。

一般的拟牛顿算法流程如下:

下面就让我们看看几种有名的拟牛顿算法。

 a.DFP方法

DFP方法应该是历史上的第一个拟牛顿方法,是William C.Davidson在1959年发明的,并由Roger Fletcher和Michael J.D.Powell完善,因此这个方法就称为DFP。我们的目标是,在第k个迭代过程中,我们希望从上一个迭代的海森矩阵Bk-1的基础上,得到当前点xk的海森矩阵Bk,在计算出牛顿方向。在第k个迭代中,我们已知的有xk,xk-1,f'(x),f'(xk-1),要通过它们来计算出Bk,之后通过它找到xk+1。DFP通过求解这个优化问题来通过Bk-1求得Bk

这个最优化问题希望找到一个B,和Bk-1尽量接近,B本身是对称矩阵,让后要满足B(xk-xk-1)=yk-1,这是因为B本身应该满足在xk的比较小的邻域内,有

而xk-1距离xk就非常近,因此将xk-1带入,也应该满足这个性质。在一整理,就得到了上面的第二个约束。

这个方程有解析解如下:

这个等式的解法略复杂,在这里不再给出,有感兴趣的同学可以参考最优化理论与方法(袁亚湘 孙文瑜)的第五章。

这个迭代能保证f一直下降么?我们知道f要下降,就要B正定,以下资料给出了这种迭代下B正定的证明(这里是B的逆矩阵来迭代的推导过程)。

有了上面的解法,容易想到,B能推的话,当然B的逆矩阵应该也能推!(这里的推导过程留给下面的BFGS来展示)

优点:不用每次计算海森矩阵,收敛速速很快

缺点:要计算逆矩阵(*),存储空间大

b.BFGS方法

最初的DFP算法是每次求得海森矩阵个的近似,值后再求逆矩阵计算拟牛顿方向,每次求逆比较费力,这一步可以优化么?我们能直接近似得到海森矩阵逆矩阵的近似么?1970年,四位大师Charles G.Broyden,Roger Fletcher,Daniel Goldfarb,David F.Shanno各自独立的发现了这个可行性,并发明了BFGS算法。把增量的求解B转换成了增量的求解B的逆矩阵H。于是乎和DFP的优化问题相似,我们的优化问题变成了如下形式:

这个几乎和DFP的优化问题是一样的,只是将s和y的位置互换了而已。相应的,问题的解也有相似的形式:

下面给一个BGFS的逆问题的证明过程,如果我们假设Bk=Bk-1+▽B的话,那么我们要求▽B对称,且尽量小,如果在保证第二个约束,那么基本就能满足上式子。要▽B尽量小,我们最容易想到的就是可以限制它的秩,比如我们让▽B的秩为2,于是▽B就可以写成 aUUt+bVVt,在带入约束,有

对于这样的公式,U和V可以有无数组解,于是我们可以很容易想到一组解,让

其中两个括号内的乘机为实数,所以可以设

带入可得

解得

最终得到

于是我们得到了递推式

各种拟牛顿算法的主要差异在于近似Hessian矩阵的更新策略,下面的列表列出了部分主流的拟牛顿算法的迭代更新规则。


BFGS保留并更新H,进而通过H*f'达到牛顿方法的收敛速度。这个在维度不大的时候还可以,但是当维度比较大的时候,保存H需要O(n^2)的存储空间,这个比较被动,因此出现了L-BFGS算法。

优点:不用每次计算海森矩阵,收敛速速很快,收敛稳定

缺点:存储空间大


c.L-BFGS

L-BFGS就是Limited-memory BFGS,顾名思义,就是更少使用内存的BFGS。BFGS要存储海森矩阵个的逆,这个需要O(n^2)的存储空间,如果feature有10W维,每个fearture用double存储,那么总共需要100000*100000*8/(10^9)约80G的空间,这个存储要求的空间太多,为了减少内存,L-BFGS算法诞生了。它通过2重迭代,保存之前m个步骤之中的y和s,用它们来近似出牛顿方向,这样就省去了存储海森矩阵的逆,它把存储降低到了O(m*n)。一般情况下m设置为3-20之间。

我们让


则根据BFGS中Hk和Hk-1的关系,我们有如下的展开:


最终可以得到

于是我们看到,可以通过上面的公式,用s和y,以及一个之前的H,推导出现在的H。这个过程可以通过2重循环实现,具体的作法如下:

通过分析可以看到,第一个循环内,我们假定qi为第i轮的q的值,假定ai为第i轮的a的值,那么可以得到


这个就是上面每一个+号分割的项的右半边,之后q再乘上H(k-m),进入第二轮循环,我们可以得到


这样展开下去,最终就可以的得到Hk了。看到这里可能有同学会问,这里面还有个H(k-m)那,这个不是还是n*n的么?对,为了不保存这个n*n,我们需要找到一个H的近似,且占用空间要是n级别的。因为上面的2重循环操作都是矩阵乘法(本质上就是一系列的伸缩和旋转),那么比较相似的矩阵经过这一些列操作后,还是和相似的。其次解决占用空间的问题,我们可以让H变化呢过对角矩阵,这样存储空间就变为n了。实际解决中会尝试多种H的近似,实践上使用


效果比较好,因为刚好是梯度的梯度的逆,用它来拟合海森矩阵的初值比较合理。H0的近似使用单位矩阵就可以。这样一来,连这n数也不用存啦,可以通过计算得到,所以总的空间复杂度变成了O(m*n)。


常用的梯度下降算法改进(深度学习中)

神经网络的训练一般都离不开梯度下降,由于网络本身比较复杂,数据的维度也很大,所以实际应用上一般都不选择二阶的方法(比如牛顿法),而且以sdg来进行训练居多。

但是一般的sdg有一些问题,比如:1.学习率(步长)不好定 2.为了收敛,学习率往往会使用类似退火算法来逐步缩小,但是这个缩小往往是按照预先制定的计划,或者是根据某个阈值来进行逐步收缩的,这里就牵扯到设定这个计划,或者设定阈值需要有比较多的经验,而且不能自动的根据数据来匹配。3.学习率会一视同仁的作用在所有param上。4.sdg往往会收敛在局部最小,跟严重的是面对马鞍形面时,sdg很难走出鞍点,因为鞍点附近的梯度都非常小。

针对上面的几个弱点,有了下面一些优化的算法。


Momentum

Momentum(动量)方法通过将之前的梯度信息,用到本次更新中,来带来更好的更新方向。这相当于考虑了更多之前的方向信息(更趋向全局信息)来生成本次更新的方向。公式和图像如下:

一般经验上把设定为0.9左右。

这个可以想成圆球在椭圆形的碗里滚到最低点的过程类似:动量每次都在累积,小球越来越快。每次梯度一致的方向上,速度越来越大,不一致的方向上,累积较小,甚至减小。这个最终使得收敛加速,震荡减少。

  "With Momentum update, the parameter vector will build up velocity in any direction that has consistent gradient."

Nesterov Momentum(Nesterov accelerated gradient)

Nesterov动量跟上面的动量法类似,区别在于在计算新梯度的时候,没有用当前的,而使用了距离更新后参数更接近的来计算,具体公式如下:


他和一般动量法的区别,可以看以下图像解释:


这个更新方法,可以更快的估计更新后的点的梯度,从而更快的知道是否跑过了。。。从而减少震荡,可以看下面的图来理解下:

蓝线是Momentum的一次更新,可以看到他先算了当前的梯度,之后和之前的剩余(大蓝线)加起来。而NAG则是直接看剩余(棕色箭头),之后计算这个点的梯度(红色),在更新参数(绿箭头)。注意:第二次更新,红箭头回头了!!!这说明,过了,往回走吧~~,从而可以看出,NAG可以更更好的防止震荡问题。


上面的算法我们已经根据之前的多个梯度,通过调整参数更新方向,使收敛加速啦~~~下面我们在看看针对不同参数的重要度,能否通过算法来调整它们更新的大小。


Adagrad

Adagrad的想法很简单:更新次数越频繁的参数,应该快到达了微调阶段,后面的学习率要更小;更新次数比较少的,刚开始向最优点移动,学习率可以大一些。这些在sparse的数据里尤为明显。adagrad的公式如下:

t是轮数,i是第i个参数,是当前的梯度,而是之前t步的g的平方和,是防止除0的,一般设置成1e-8。


Adadelta

Adagrad中,因为分母部分一直在增加,训练轮数多了之后,会导致学习率变得非常非常小,导致收敛很慢的问题。另外全局的默认学习率也需要人工给定。

针对第一种问题,Adadelta做出了改进,让最近几轮(window)的g决定衰减,之前的g使之影响最小化,同时不在使用梯度的平方和来做累积,转而使用窗口中的梯度平方和的均值作为影响的主要项。简化起见,可以给了一个乘数因子来模拟窗口的作用,利用这个乘数因子来计算衰减,具体公式如下:

这样会使更新率的减低速度得到缓解,从而解决了第一个问题。但是通过上面的公式可以看到,更新的参数单位有点不对了,因为现在的分母部分有了单位。。。按照梯度的定义,根据牛顿迭代法,我们知道梯度乘以x的变化量,才是y的变化量拟合,之前的学习率是没有单位的,所以梯度的单位还在,但这里梯度的单位似乎消掉了。这咋办?简答的做法是把分母部分的单位直接去掉,搞成标量,但是有点粗暴哈。Adadelta的发明者考虑了另一种方法,他又计算了一个参数的平方累积,用来衡量参数本身的更新情况(其实用的也是均值)来加入影响,并且使单位问题的到解决。


这样一搞,我们发现,不但单位问题解决了,隐隐的,公式还有了点动量累积的感觉~~~而且后续的学习率也不用人工给出啦。好的,除了学习率的自动退火,之前的梯度累积也被考虑到了更新参数的公式中。PS:因为在计算本轮参数之前,我们是没有本轮参数与之前参数的平方均值的(这句话说得比较绕),所以我们用前一次的来代替。

RMS(x)是平方和求根函数。


RMSprop

RMSprop是Geoff Hinton在他的“neural Networks for ML”课程中提到的算法,基本和Adadelta的第一部分一样,公式如下:


这里,学习率推荐值是0.001。

同上面Adadelta类似,我们也可以把之前的theta搞进去,这里也可以用RMS,大同小异哈。

Adam

Adaptive Moment Estimation(Adam,自适应矩估计),它也是一种可以自动调节不同参数学习率的算法,和Adadelta类似,还包含了类似Momentum保存之前累积的梯度的做法,这样就让Adam可以即更新方向,有自动更新学习率。它保存了参数的梯度累积,以及梯度平方的累积,在根据他们的期望估计新的参数在哪里。

是梯度方向的累积,可以对应g的一阶矩估计,是g^2的累积,对应g的二级估计,我们希望通过当前的m和v,估计出g和g^2的期望,然后按照

 

来估计参数的更新。

我们可以得到,进而得到

最终得到了=/,即。同样的推理,可得。最终的跟新规则如下:




经验上,我们设置  β1=0.9,β2=0.999,ϵ=1e-8。实际上用的时候,我们可以直接m和v替换m_head和v_head,实践上效果和速度没有太大区别。


几个方法的可视化比较

                               图1

上面的等高线图图1可以直观的看出几个算法的特性:SDG(带固定学习率退火的)比较慢;Adagrad,Adadelta,RMSprop3个算法可以调整学习率,很快找到朝向全局的最低方向;Momentum,NAG刚一开始的时候由于步子大,过了,但是找到合理方向后,在正确方向上的累积,导致最终的收敛速度还不错。


                              图2

图2展现了马鞍形表面在鞍点附近(一维梯度是正的,一位梯度是负的)的下降情况。可以看到,普通的SGD到达鞍点之后就跪了(梯度基本为0了),Adagrad,Adadelta,RMSprop可以快速突破,但是Adagrad会越来越慢,Momentum,NAG由于步子大,刚开始呈现震荡(对称),但是找到正确方向之后,下降速度很快。

 

最终的实践结论,Adadelta,RMSprop,Adam都还不错,不过也有很多就是用的naive的SDG(尤其是object functin比较简单的,凸的情况),不过针对神经网络的,还是建议用优化过的梯度下降算法,正如下面说的: 

“Consequently, if you care about fast convergence and train a deep or complex neural network, you should choose one of the adaptive learning rate methods.”


总结

以上就是我们平时常用的一阶,二阶的优化方法,另外还有共轭方向法,共轭梯度法等方法,这里就不设计了,感兴趣的同学可以查查书和资料。

我们的目的是让大家了解常用的一般的优化的方法,在实践中清楚其原理,进而可以轻松驾驭,或者根据实际情况优化自己的算法提供些许信息,能达到这个目的就ok了。


参考资料

最优化理论与方法 (袁亚湘 孙文瑜)

最优化理论与方法 (傅英定 成孝予 唐应辉)

http://www.cnblogs.com/jeromeblog/p/3801025.html

http://www.codelast.com

http://www.tianyancha.com/research/LR_intro.pdf

http://imgur.com/a/Hqolp

http://sebastianruder.com/optimizing-gradient-descent/

https://homes.cs.washington.edu/~galen/files/quasi-newton-notes.pdf

http://www.cnblogs.com/xinchrome/p/4964930.html

https://arxiv.org/abs/1606.04838

http://www.cnblogs.com/murongxixi/p/3467365.html

https://zhuanlan.zhihu.com/p/21486826

https://zhuanlan.zhihu.com/p/22810533

https://blog.slinuxer.com/2016/09/sgd-comparison

你可能感兴趣的:(算法)