梯度下降、牛顿法、坐标下降法的优化问题

    最优化问题在机器学习中有非常重要的地位,很多机器学习算法最后都归结为求解最优化问题。在各种最优化算法中,梯度下降法是最简单、最常见的一种,在深度学习的训练中被广为使用。

    最优化问题是求解函数极值的问题,包括极大值和极小值。微积分为我们求函数的极值提供了一个统一的思路:找函数的导数等于0的点,因为在极值点处,导数必定为0。这样,只要函数的可导的,我们就可以用这个万能的方法解决问题,幸运的是,在实际应用中我们遇到的函数基本上都是可导的。

     在机器学习之类的实际应用中,我们一般将最优化问题统一表述为求解函数的极小值问题,即:

                                                                min_{x}f(x)
其中x称为优化变量,f称为目标函数。有些时候会对优化变量x有约束,包括等式约束和不等式约束,它们定义了优化变量的可行域,即满足约束条件的点构成的集合。在这里我们先不考虑带约束条件的问题。

导数与梯度

由于实际应用中一般都是多元函数,因此我们跳过一元函数,直接介绍多元函数的情况。梯度是导数对多元函数的推广,它是多元函数对各个自变量偏导数形成的向量。多元函数的梯度定义为:

                                                               \bigtriangledown f(x)=(\frac{\partial f}{\partial x_{1}},...,\frac{\partial f}{\partial x_{n}})^{T}

其中\bigtriangledown称为梯度算子,它作用于一个多元函数,得到一个向量。下面是计算函数梯度的一个例子:

                                          

       可导函数在某一点处取得极值的必要条件是梯度为0,梯度为0的点称为函数的驻点,这是疑似极值点。需要注意的是,梯度为0只是函数取极值的必要条件而不是充分条件,即梯度为0的点可能不是极值点。

       至于是极大值还是极小值,要看二阶导数/Hessian矩阵,Hessian矩阵我们将在后面的文章中介绍,这是由函数的二阶偏导数构成的矩阵。这分为下面几种情况:

如果Hessian矩阵正定,函数有极小值;如果Hessian矩阵负定,函数有极大值;如果Hessian矩阵不定,则需要进一步讨论

       这和一元函数的结果类似,Hessian矩阵可以看做是一元函数的二阶导数对多元函数的推广。一元函数的极值判别法为,假设在某点处导数等于0,则:

如果二阶导数大于0,函数有极小值;如果二阶导数小于0,函数有极大值;如果二阶导数等于0,情况不定

      直接求函数的导数/梯度,然后令导数/梯度为0,解方程,问题不就解决了吗?事实上没这么简单,因为这个方程可能很难解。对于有指数函数,对数函数,三角函数的方程,我们称为超越方程,求解的难度并不比求极值本身小。精确的求解不太可能,因此只能求近似解,这称为数值计算。工程上实现时通常采用的是迭代法,它从一个初始点x_{0}开始,反复使用某种规则从x_{k}移动到下一个点x_{k_{1}},构造这样一个数列,直到收敛到梯度为0的点处。这个过程就像我们处于山上的某一位置,要到山底找水喝,因此我们必须到达最低点处.此时我们没有全局信息,根本就不知道哪里是地势最低的点,只能想办法往山下走,走 一步看一步。刚开始我们在山上的某一点处,每一步,我们都往地势更低的点走,以期望能走到山底。

推导过程

      首先我们来看一元函数的泰勒展开,如果一个一元函数n阶可导,它的泰勒展开公式为:

                            f(x+\Delta x)=f(x)+f^{'}(x)\Delta x+\frac{1}{2}f^{''}(x)(\Delta x)^{2}+.. \frac{1}{n!} f^{(n)}(x)(\Delta x)^{n}...
      如果在某一点处导数值大于0(+),则函数在此处是增函数,加大x的值函数值会增加,减小x的值(-)函数会减小。相反的,如果在某一点处导数值小于0(-),则函数是减函数,增加x的值函数值会减小(+),减小x的值函数会增加。因此我们可以得出一个结论:如果x的变化很小,并且变化值与导数值反号,则函数值下降。对于一元函数,x的变化只有两个方向,要么朝左,要么朝右。

      下面我们把这一结论推广到多元函数的情况。多元函数f(x)在x点处的泰勒展开为:

                                         f(x+\Delta x)=f(x)+(\bigtriangledown f(x))^{T}\Delta x+o(\Delta x)
      这里我们忽略了二次及更高的项。其中,一次项是梯度向量\bigtriangledown f(x)与自变量增量 \Delta x的内积 (\bigtriangledown f(x))^{T}\Delta x  ,这等价于一元函数的f^{'}(x)\Delta x。这样,函数的增量与自变量的增量、函数梯度的关系可以表示为:

                                           f(x+\Delta x)-f(x)=(\bigtriangledown f(x))^{T}\Delta x+o(\Delta x)
     只要梯度不为0,往梯度的反方向走函数值一定是下降的,在梯度相反的方向函数值下降的最快。此时有:

                                                         \Delta x=-\alpha \bigtriangledown f(x)

     从初始点x_{0}开始,使用如下迭代公式:

                                                       x_{k+1}=x_{k}-\alpha \bigtriangledown f(x_{k})

    只要没有到达梯度为0的点,则函数值会沿着序列x_{k}递减,最终会收敛到梯度为0的点,这就是梯度下降法。迭代终止的条件是函数的梯度值为0(实际实现时是接近于0),此时认为已经达到极值点。注意我们找到的是梯度为0的点,这不一定就是极值点,后面会说明。梯度下降法只需要计算函数在某些点处的梯度,实现简单,计算量小。

面临的问题

在实现时,梯度下降法可能会遇到一些问题,典型的是局部极小值和鞍点问题。

局部极小值:有些函数可能有多个局部极小值点,下面是一个例子:

                         
这张图中的函数有3个局部极值点,分别是A,B和C,但只有A才是全局极小值,梯度下降法可能迭代到B或者C点处就终止。

      鞍点 :指梯度为0,Hessian矩阵既不是正定也不是负定,即不定的点。下面是鞍点的一个例子,假设有函数:x^{2}-y^{2},显然在(0, 0)这点处不是极值点,但梯度为0,下面是梯度下降法的运行结果:

                               
     在这里,梯度下降法遇到了鞍点,认为已经找到了极值点,从而终止迭代过程,而这根本不是极值点。对于怎么逃离局部极小值点和鞍点,有一些解决方案,在这里我们暂时不细讲,以后有机会再专门写文章介绍。对于凸优化问题,不会遇到上面的局部极小值与鞍点问题,即梯度下降法一定能找到全局最优解。

     梯度下降法有大量的变种,它们都只利用之前迭代时的梯度信息来构造每次的更新值,最流行的:动量优化,Nesterov 加速梯度,AdaGrad,RMSProp, Adam 优化.详情参见:快速优化器

牛顿法

       除了前面说的梯度下降法,牛顿法也是机器学习中用的比较多的一种优化算法。牛顿法的基本思想是利用迭代点处的一阶导数(梯度)和二阶导数(Hessen矩阵)对目标函数进行二次函数近似,然后把二次模型的极小点作为新的迭代点,并不断重复这一过程,直至求得满足精度的近似极小值。它使用函数(x)的泰勒级数的前面几项来寻找方程(x) = 0的根。牛顿法最大的特点就在于它的收敛速度很快,而且能高度逼近最优值。

1、基本牛顿法的原理

    考虑同样的一个无约束最优化问题:

                                                  min_{x\in R^{n}}f(x)     
     基本牛顿法是一种是用导数的算法,它每一步的迭代方向都是沿着当前点函数值下降的方向。我们主要集中讨论在一维的情形,对于一个需要求解的优化函数, 其中具有二阶连续偏导数的性质,求函数的极值的问题可以转化为求导函数。对函数进行泰勒展开到二阶,得到:

                                 

牛顿法的每次迭代就是让一阶导为零,即对上式求导并令其为0,则:

                                                  

即得到牛顿法的更新公式。

                                                       

2、基本牛顿法的流程

  1. 给定终止误差值,初始点,令
  2. 计算,若,则停止,输出
  3. 计算,并求解线性方程组得解
  4. ,并转2。

       由于牛顿法是基于当前位置的切线来确定下一次的位置,所以牛顿法又被很形象地称为是"切线法"。牛顿法的搜索路径(二维情况)牛顿法搜索动态示例图(这里我们可以把y看作优化函数的导数,我们要找y的零点,即优化函数的最小值):

                                    

关于牛顿法和梯度下降法的效率对比:

  从本质上去看,牛顿法是二阶收敛,梯度下降是一阶收敛,所以牛顿法就更快。如果更通俗地说的话,比如你想找一条最短的路径走到一个盆地的最底部,梯度下降法每次只从你当前所处位置选一个坡度最大的方向走一步,牛顿法在选择方向时,不仅会考虑坡度是否够大,还会考虑你走了一步之后,坡度是否会变得更大。所以,可以说牛顿法比梯度下降法看得更远一点,能更快地走到最底部。(牛顿法目光更加长远,所以少走弯路;相对而言,梯度下降法只考虑了局部的最优,没有全局思想。)

   从几何上说,牛顿法就是用一个二次曲面去拟合你当前所处位置的局部曲面,而梯度下降法是用一个平面去拟合当前的局部曲面,通常情况下,二次曲面的拟合会比平面更好,所以牛顿法选择的下降路径会更符合真实的最优下降路径。

                                                  

注:红色的牛顿法的迭代路径,绿色的是梯度下降法的迭代路径。

牛顿法的优缺点总结:

  优点:二阶收敛,收敛速度快;

  缺点:牛顿法是迭代算法,每一步都需要求解目标函数的Hessian矩阵的逆矩阵,计算复杂。初始点要足够“靠近”极小点

Hessian矩阵:            

                                  

拟牛顿法(Quasi-Newton Methods)

  拟牛顿法是求解非线性优化问题最有效的方法之一,拟牛顿法的本质思想是改善牛顿法每次需要求解复杂的Hessian矩阵的逆矩阵的缺陷,它使用正定矩阵来近似Hessian矩阵的逆,从而简化了运算的复杂度。拟牛顿法和最速下降法一样只要求每一步迭代时知道目标函数的梯度。通过测量梯度的变化,构造一个目标函数的模型使之足以产生超线性收敛性。这类方法大大优于最速下降法,尤其对于困难的问题。另外,因为拟牛顿法不需要二阶导数的信息,所以有时比牛顿法更为有效。如今,优化软件中包含了大量的拟牛顿算法用来解决无约束,约束,和大规模的优化问题。

具体步骤:

    拟牛顿法的基本思想如下。首先构造目标函数在当前迭代x_{k}的二次模型: 
                                                               

                                                                             
    这里B_{k}是一个对称正定矩阵,于是我们取这个二次模型的最优解作为搜索方向,并且得到新的迭代点:

                                                                 x_{k+1}=x_{k}+a_{k}p_{k}
     其中我们要求步长a_{k}满足Wolfe条件。这样的迭代与牛顿法类似,区别就在于用近似的Hesse矩阵B_{k}  代替真实的Hesse矩阵(牛顿法:p_{k}=-H_{k}^{-1} \bigtriangledown f(x_{k}))。所以拟牛顿法最关键的地方就是每一步迭代中矩阵B_{k} 的更新。现在假设得到一个新的迭代x_{k+1},并得到一个新的二次模型:

                                               
 我们尽可能地利用上一步的信息来选取B_{k}。具体地,我们要求 

                                                               
从而得到
                                                        

这个公式被称为割线方程。常用的拟牛顿法有DFP算法和BFGS算法。

from:http://www.cnblogs.com/shixiangwan/p/7532830.html

坐标下降法

     坐标上升与坐标下降可以看做是一对,坐标上升是用来求解max最优化问题,坐标下降用于求min最优化问题,但是两者的执行步骤类似,执行原理相同。

例如要求接一个min f(x_{1},x_{2},...x_{n})的问题,其中各个x_i是自变量,如果应用坐标下降法求解,其执行步骤就是:

1.首先给定一个初始点,如 X_0=(x_{1},x_{2},...x_{n})

2.for dim=1:n

固定x_i;(其中i是除dim以外的其他所有维度)

x_{dim}为自变量求取使得f取得最小值的x_{dim}

  end 

3.循环执行步骤2,直到f的值不再变化或变化很小。

其关键点就是每次只变换一个维度x_i,而其他维度都用当前值进行固定,如此循环迭代,最后得到最优解。

猜你喜欢

转载自blog.csdn.net/qq_30815237/article/details/89432999