zoukankan      html  css  js  c++  java
  • 最优化-使用导数的最优化方法

    牛顿法

     需求:知道每个点的一阶导数和二阶倒数(Hessian矩阵)

      

      目标:

        若x*是无约束问题的局部解,则x*满足▽f(x) = 0

        ▽f(x) 表示多元函数对其中每一元求偏导数组成的向量

        ▽f(x) = (∂f/∂x1, ∂f/∂x2, ∂f/∂x3, .......)

      过程:

        对于多元函数▽f(x)我们在初始点x1做线性展开得到

        ▽f(x) = ▽f(x1) +  ▽2f(x1) (x-x1)

        将▽f(x) = 0 代入

        解出x2 = (▽f(x) - ▽f(x1))  * ▽2f(x1)-1 + x1

        x2即为下一个迭代点, 当迭代到达到精度要求时,结束迭代

        当然,如果知道更高阶的倒数的话,也可以使用泰勒展开做近似,一般应用场景中只使用到二阶导数

      

      优点:

        算法具有二次终止性,收敛较快

      缺点:

        迭代过程中,函数值可能不是严格下降的

        当初始点与正解距离较大时,迭代点列可能不收敛

        要计算Hessian矩阵的逆矩阵,计算量较大

        Hessian矩阵要是不可逆就凉了

    修正牛顿法

     需求: 同牛顿法

        

      目标:

        解决牛顿法中函数值可能上升的问题

      过程:

        解线性方程组

        

        d为f(x)的收敛方向,为线性近似中的xk到0点的梯度

        在xk处,方向d上做精确一维搜索,搜索到的点即为下一个迭代点

        当xk处导数的范数小于精度要求时,终止迭代

      优点:

        解决了牛顿法中函数值上升的问题

        对收敛在鞍点的情况有所改善       

          

    共轭梯度法 

     引入:

        对于正定二次函数,其函数图像是一个超球面

        对于n维超球面,我得出n个正交方向

        沿着这些正交方向做n次精确一维搜索即可得到最优解

        

        对于一般的二次函数

        

        将其做一个变换改变为正定二次函数就能解决问题了

        下面就引入变换 

        

        这样就改造成了正定二次函数

        接下来就是要找在w下的n个正交方向了q

        因为对于这n个正交方向,在一遍的空间中有

        所以

        那么我们将d1, d2称作共轭方向(G必须要对称正定)

        可以看到当G = I时,共轭方向就是正交方向

       过程

        可以知道,共轭梯度法的过程就是去找n个共轭梯度,然后去做精确一维搜索就好

        令

        进行一维搜索,得到x2

        令(个人认为,这是为了找到一个离梯度最近的共轭方向,所以才这么做的)

        

        

        每一步这样迭代下去即可

        当▽f(x) <= 精度要求时,终止迭代

        可以看到,在计算梯度时我们还是用了G

        进行一系列化简之后得到下式

        

         dk = -▽f(xk) + βk-1 * dk-1

           βk-1 = || f(xk) ||2  / || f(xk-1) ||2 

      优点:

        不用二阶导,计算量减小

      

      算法的名称

     PRP算法

          

      FR算法

        

     变度量法(大概率不考)

    主要思想

      使用▽f(x)的泰勒展开式去获取Hessin矩阵的近似值

      ▽f(x) = ▽f(x0) +  ▽2f(x0) * (x - x0)

    具体算法

      (很不走心的直接贴书上的图

      

      

      

      

      

      

  • 相关阅读:
    块设备驱动框架分析(一)
    LIN总线协议
    LCD驱动分析(三)时序分析
    str_shuffle — 随机打乱一个字符串
    str_replace — 子字符串替换
    str_repeat — 重复一个字符串
    str_pad — 使用另一个字符串填充字符串为指定长度
    str_getcsv — 解析 CSV 字符串为一个数组
    ltrim — 删除字符串开头的空白字符(或其他字符)
    lcfirst — 使一个字符串的第一个字符小写
  • 原文地址:https://www.cnblogs.com/shensobaolibin/p/10097240.html
Copyright © 2011-2022 走看看