高斯牛顿法在具体工程中的应用——C++版
生活随笔
收集整理的這篇文章主要介紹了
高斯牛顿法在具体工程中的应用——C++版
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
高斯牛頓法在具體工程中的應用——C++版
說明:本文章沒有用大量篇幅來講述高斯牛頓的原理和數學中的應用,而是用具體的代碼來說明,具體是怎么應用的。
如果對高斯牛頓法的原理比較感興趣,可以閱讀以下鏈接中的內容:
https://zhuanlan.zhihu.com/p/42383070
概述:高斯牛頓法解決的是工程中的非線性最小二乘問題,如SLAM。具體代碼如下:
首先我們需要定義以下參數:
//設定的真實參數的值double ar = 1.0, br = 2.0, cr = 1.0; // 估計參數值,每一次迭代的時候,設定的參數值是不一樣的,這里是初始化參數 double ae = 2.0, be = -1.0, ce = 5.0;//設置的數據集的點數共100個數組 int N = 100; //設置的噪聲值,值越低表明對實際的影響越小 double w_sigma = 0.01; //調用CV庫里的rng函數,隨機值 cv::RNG rng;其次,我們要設置一個數據集,每一個問題的數據集是不一樣的,自己設置
//定義的100個數據點,數據集 vector<double> x_data, y_data; for (int i = 0; i < N; i++) {//定義的輸入xidouble x = i / 100.0;//push.函數的作用:將一個新的元素加到vector的最后面,位置為當前最后一個元素的下一個元素x_data.push_back(x);//返回的隨機數的平均值為零,標準偏差為指定的 sigma (高斯分布的特征)y_data.push_back(exp(ar * x * x + br * x + cr) + rng.gaussian(w_sigma));}第三,開始具體的應用:
// 開始Gauss-Newton迭代int iterations = 100; // 迭代次數,迭代次數應該設置的適中,太大太小都不好double cost = 0, lastCost = 0; // 本次迭代的cost和上一次迭代的costfor (int iter = 0; iter < iterations; iter++) {//定義一個海塞矩陣,Matrix3d H = Matrix3d::Zero(); // Hessian = J^T J in Gauss-Newton,這里的J為行向量,我們最終想得到的是一個矩陣//定義一個偏置矩陣Vector3d b = Vector3d::Zero(); // biascost = 0;//每一次的迭代,都有一個對應的參數值,也就是a,b,c的值for (int i = 0; i < N; i++) {//xi,yi為定義的數據集,yi在這里為實際值,xi為輸入值double xi = x_data[i], yi = y_data[i]; // 第i個數據點double error = 0; // 第i個數據點的計算誤差//每一個error的大小,一共100個//yi為觀測值//exp(ae * xi * xi + be * xi + ce)為理論值擬合函數error=yi - (exp(ae * xi * xi + be * xi + ce));// error = 0; // 填寫計算error的表達式Vector3d J; // 雅可比矩陣:函數對參數求偏導//求出每一個數值的Jacbian矩陣,對a,b,c參數分別求偏導J[0]=-xi*xi*exp(ae * xi * xi + be * xi + ce);J[1]=-xi*exp(ae * xi * xi + be * xi + ce);J[2]=-exp(ae * xi * xi + be * xi + ce);cout<<"J"<<i<<": "<<J.transpose()<<endl;//hessian矩陣用累加法,GN近似的HH += J * J.transpose(); cout<<"H:"<<H.transpose()<<endl;b += J*(-error) ;cout<<"b: "<<b.transpose()<<endl;//代價函數cost += error * error;}// 求解線性方程 Hx=b,建議用ldltVector3d dx;cout<<"H:"<< H<<endl;cout<<"B:"<< b<<endl;//H的逆矩陣再乘以bdx = H.ldlt().solve(b);if (isnan(dx[0])) {cout << "result is nan!" << endl;break;}if (iter > 0 && cost > lastCost) {// 誤差增長了,說明近似的不夠好cout << "cost: " << cost << ", last cost: " << lastCost << endl;break;}// 更新abc估計值ae += dx[0];be += dx[1];ce += dx[2];lastCost = cost;cout << "total cost: " << cost << endl;}cout << "estimated abc = " << ae << ", " << be << ", " << ce << endl;return 0; }總結
以上是生活随笔為你收集整理的高斯牛顿法在具体工程中的应用——C++版的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: A Graph-Based Tempor
- 下一篇: 切片[:, None, None]的含义