Ceres是一個非線性的優化庫,在優化問題中廣泛使用,今天我們就來使用這一優化庫來求解一個函數的極值點。非線性優化庫優化的原理是在給定初值的條件下不斷計算偏移量,使得待優化參數向着目标函數梯度最小處移動。
使用Ceres優化庫的步驟可以歸納為以下幾步:
- 定義參數塊,主要定義待優化參數的形式;
- 定義殘差塊的計算方式。殘差塊通常關聯若幹個參數塊,對它們進行一些自定義的計算,然後傳回殘內插補點;
- 殘差塊也需要定義雅可比的計算方式。在Ceres中,你可以使用它提供的“自動求導”功能,也可以手動指定雅可比的計算過程。如果要使用自動求導,那麼殘差塊需要按照特定的寫法書寫;殘差的計算過程應該是一個帶模闆的括号運算符;
- 将所有的參數塊和殘差塊加入Ceres定義的Problem對象中,調用Slove函數求解即可。求解之前,我們可以傳入一些配置資訊,例如疊代次數、終止條件等,也可以使用預設的配置。
#include <iostream>
#include <ceres/ceres.h>
#include <glog/logging.h>
#include<chrono>
#include <math.h>
#include <algorithm>
using namespace std;
using ceres::AutoDiffCostFunction;
using ceres::CostFunction;
using ceres::Problem;
using ceres::Solve;
using ceres::Solver;
//x表示待優化參數塊,residual表示殘差塊
//通過非線性優化找到函數梯度下降的自變量的取值。
struct CostFunctor {
template <typename T>
bool operator()(const T* const x, T* residual) const {
residual[0] = 2.0*pow(x[0]-5.0,2);
return true;
}
};
int main(int argc, char** argv) {
google::InitGoogleLogging(argv[0]);
// The variable to solve for with its initial value. It will be
// mutated in place by the solver.
double x = 0.5;
const double initial_x = x;
// Build the problem.
Problem problem;
// Set up the only cost function (also known as residual). This uses
// auto-differentiation to obtain the derivative (jacobian).
//定義誤差函數,誤差類型,輸入次元,輸出次元
CostFunction* cost_function =
new AutoDiffCostFunction<CostFunctor, 1, 1>(new CostFunctor);
//優化問題添加殘差塊,不使用核函數
problem.AddResidualBlock(cost_function, nullptr, &x);
// Run the solver!
Solver::Options options;
options.minimizer_progress_to_stdout = true;
Solver::Summary summary;
Solve(options, &problem, &summary);
std::cout << summary.BriefReport() << "\n";
std::cout << "x : " << initial_x << " -> " << x << "\n";
return 0;
}
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TPR5UMFpnTxkkeNBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL5MTMzQDO0kTMxIzMwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)