Newton Conjugate Gradient Method

Newton Conjugate Gradient Method

共轭梯度法

  • 背景
    • 本质上是一种求的方法,它厉害在不需要知道的具体值,只需要多调用几次点积接口就可以把求出来
    • 计算复杂度
      • 函数的梯度的计算复杂度一般是
      • 求函数的梯度的复杂度和求函数本身的复杂度是常数倍的关系
      • Hessian的计算复杂度是
      • Hessian的逆的计算复杂度是
      • Hessian-vec的复杂度是,证明过程如下:
        • 假设是一个已知的常向量
        • 根据泰勒展开有:
        • 简单变形:
        • 可以发现,求Hessian-vec的近似解只需要求原函数的两次导即可
      • hessian-vec
  • Linear Conjugate Gradient Method
    • 针对问题,我们可以将其转化成一个优化问题,因为该优化问题的导数是,最优解即令其导数为零的点。
    • 梯度下降法和牛顿法求该问题
      • gd newton
      • 梯度法没法得到精确解,步长总会引入误差;牛顿法计算量太大,而且牛顿法需要求,而我们本来就是要求这个,鸡生蛋蛋生鸡了;我们需要一种折中的方法——LCG方法
    • 假设,LCG法就是找个互相共轭(如果是单位阵,共轭就是垂直)的向量,每次沿着一个向量(的方向)走到最低点,最终一定能走到全局最低点
      • 下图是为单位阵的情况
        • lcg
      • general的情况如下
        • lcg general
    • LCG算法流程
      • 个互相共轭的向量
        • 初始化个线性不相关的向量
        • 计算互相共轭的向量:
        • cg vector
        • 这里的投影操作也叫做Gram-Schmidt process,分别考虑是单位阵(右)和不是单位阵(左)的情况:
        • conjugare proj
        • 最终得到的就是我们需要的互相共轭的向量
        • 注意到计算的时候需要对过去的个向量做投影,这个计算量很大,我们可以增量地计算(这也是lcg方法一个很大的贡献点):
        • inc cg vector
        • 至于为什么用这种方法生成的就可以保证可以去看论文证明
      • 有了互相共轭向量后,继续看迭代流程
        • lcg progress
        • 的迭代公式是由公式的导数取0推导而来的
        • 公式中的不需要把(也是该优化目标函数的Hessian)完整的算出来,直接用Hessian-vec方法进行近似求解,计算复杂度和求导一样
      • 最终的伪代码流程如下:
        • lcg code
    • LCG特点
      • 很多时候需要在求LCG之前把 normalize一下,可以通过L-BFGS(memory size=8)去近似估计(即Hessian的逆),令,对进行lcg求解,最后将做线性变换恢复到真实值。的条件数会比更低,CG过程会收敛的更快。下图是一个例子,A的维度是,条件数是,Preconditioned CG收敛速度比其他方法快很多
        • cg with preconditioner
  • Newton-CG Method
    • 回顾一下newton要解的问题,套用上面的LCG方法就可以解出。但还有两个问题需要考虑:
      • 如何处理Hessian不正定的问题?
        • Truncated CG(截断法),见下面的算法流程
      • 我们是否需要求一个精确的
        • 答案是否。针对问题,我们只需要保证即可(是最优解,是迭代得到的解),简单说就是一开始梯度还比较大的时候,我们求的精度也不需要很高,越靠近最优点的时候,精度要求越高。这是牛顿法非常重要的一个结论。
    • 算法流程(伪代码)
      • newton cg
      • 本质上就是将牛顿法中求解下降方向的步骤替换成蓝色框中的模块
      • 注意点
        • 需要初始化为0向量,因为我们希望最优的direction尽可能稳定,所以需要它从0开始出发
        • 时,说明我们当前所处的位置的Hessian是不定的,分两种情况对待:
          • 如果当前是第一次迭代,那可能是我们距离最优解太远了,这时候直接采用sgd方法更新direction(
          • 如果当前不是第一次迭代,就直接break,依然使用上一次算出来的direction去更新外部的循环(因为本次的direction可能会让函数上升,上一次的虽然是旧的信息,但至少方向没错),这就是截断法
    • 算法对比
      • newton cg vs lbfgs
      • 两种都是Hessian-Free的方法
      • 两种方法只能保证函数值是单调下降的,不能保证梯度的模是单调下降的
      • 通常情况下,Newton-CG比L-BFGS的最终得到的梯度模长更小

Search

    欢迎添加我的微信

    闷骚的程序员

    Table of Contents