高斯牛顿法

高斯牛顿法

主要思想是将\(f(x)\)进行一阶的泰勒展开。然后求解其最小二乘解。

\[f(x_k+\triangle x_k)\approx f(x_k)+J(x_k)^T \triangle x_k \]

求解问题变为:

\[\triangle x^*=argmin _{\triangle x}\frac {1}{2}\lvert f(x)+J(x)^T\triangle x\rvert ^2 \]
\[\frac {1}{2}\lvert {f(x)+J(x)^T\triangle x}\rvert ^2=\frac {1}{2}(\lvert f(x) \rvert ^2+2f(x)J(x)^T\triangle x+\triangle x^TJ(x)J(x)^T\triangle x \]

右侧求导,$$J(x)f(x)+J(x)J^T(x)\triangle x=0$$
则,可得 高斯-牛顿方程:

\[J(x)J^T(x)\triangle x=-J(x)f(x) \]

这个方程是关于变量\(\delta x\)的线性方程组,我们称他为增量方程,也叫做高斯牛顿方程(Gauss-Newton equation)或者正规方程(Normal equation)。
左边的定义为\(H\)右边的定义为\(g\)

\[H\triangle x=g \]

对比牛顿法,其实高斯-牛顿法运用\(JJ^T\)作为牛顿法中二阶Hessian矩阵的近似,从而省略了H的估计
算法流程:
1.给定初始值\(x_0\)
2.对于第k次迭代,求出当前的雅可比矩阵\(J(x_k)\)和误差\(f(x_k)\)
3.求解增量方程:\(H\triangle x_k =g\)
4.若\(\triangle x_k\)足够小则停止。否则,令\(x_{k+1}=x_k+\triangle x_k\),返回第2步

手写高斯牛顿法拟合曲线

#include
#include
#include
#include
#include 

using namespace std;
using namespace Eigen;

int main(int argc,char **argv){
    double ar=1.0,br=2.0,cr=1.0;    //真实参数
    double ae=2.0,be=-1.0,ce=5.0;   //估计参数值
    int N=100;                      //数据点
    double w_sigma=1.0;
    double inv_sigma=1.0/w_sigma;   
    cv::RNG rng;                    //OpenCV随机数生成
    
    vector x_data,y_data;   //生成观测数据
    for(int i=0;i0&&cost>=lastCost){
            cout<<"cost:"<=last cost:"<time_used=chrono::duration_cast>(t2-t1);
    cout<<"solve time cost"<

CMakeLists.txt文件

cmake_minimum_required(VERSION 2.8)
project(gaussNewton)
set(CMAKE_BUILD_TYPE Release)

find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

include_directories("/usr/include/eigen3")

add_executable(gaussNewton gaussNewton.cpp)
target_link_libraries(gaussNewton ${OpenCV_LIBS})

你可能感兴趣的:(高斯牛顿法)