Ceres Solver中文详细易懂版学习笔记

1.Ceres Slover简介

Ceres Solver是谷歌开发的一种高效的非线性优化开源库,应用场景广泛,可以解决常见数据拟合,最小二乘,非线性最小二乘的问题,类似于图像处理中的OpenCv。

大多数人接触此库,往往是因为SLAM中的图优化,归根到底最后也是一个非线性的最小二乘问题,Ceres在数值处理方面有着更加广泛的应用。

本笔记主要参考官方教程,内容为官方教程的再理解和补充。

笔者将大多数学习理解都写入了代码的中文注释中,如有参考请细读。

官方教程链接:http://www.ceres-solver.org/nnls_tutorial.html.
官方网站:http://www.ceres-solver.org/

2.CeresSlover之Helloworld实现

不论是什么语言,经典的Helloworld总是必不可少的,在某种意义上,如果你的python或者java能输出Helloworld,那代表着你的环境配置和程序的基本使用已经完善,下面我们用一个非常简单的例子进行Ceres使用的Helloworld讲解。

2.1 目标问题

我们使用ceres求取下列函数的最小值(为方便教学,函数选取的非常简单):
1 2 ( 10 − x ) 2 \frac{1}{2}(10-x)^2 21(10x)2
我们很容易算出这个最小值在x等于10处,但是简单的问题更适合用来说来用法。

2.2 代码实现

第一步:建立起f(x)= 10- x 的数学函数模型。

struct CostFunctor {
   
   template <typename T>
   //operators是一种模板方法,其假定所的输入输出都变为T的格式
   bool operator()(const T* const x, T* residual) const 
	//其中x为带估算的参数,residual是残差
	{
   
     residual[0] = T(10.0) - x[0];//这里的T[10。0],可以将10 转换位所需的T格式,如double,Jet等
     return true;
   }
};

这样我们就建立起了一个残差的计算模型,接下来:
第二步:就要构建最小二乘的问题框架并解决它。

int main(int argc, char** argv) {
   
  google::InitGoogleLogging(argv[0]);

  // 设置迭代的初值
  double initial_x = 5.0;
  double x = initial_x;

  // 申明构建的问题,用Problem类
  Problem problem;

  // 设置好的残差计算的公式,使用auto-differentiation选项去获得导数(雅克比). 
  CostFunction* cost_function =
  //注意:costFunctor是前面定义的f(x)=10-x。这里的第一个1是待测参量的维数,第二个1是每个待测参量的size
  // 比如有两个参量。第一个为m,大小9;第二个c,大小为3。那么就是<CostFunctor, 2, 9,3>
      new AutoDiffCostFunction<CostFunctor, 1, 1>(new CostFunctor);
  problem.AddResidualBlock(cost_function, NULL, &x);

  // 运行solver
  Solver::Options options;//为Solver的设置参数类,使用options可以对Solver类型使用方法等进行设置
  options.linear_solver_type = ceres::DENSE_QR;//使用得是稠密的QR分解方式
  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;
}

本部分的官方参照代码在examples/helloworld.cc
笔者在ubuntumate 18.04下进行验证,结果为:

iter      cost      cost_change  |gradient|   |step|    tr_ratio  tr_radius  ls_iter  iter_time  total_time
   0  4.512500e+01    0.00e+00    9.50e+00   0.00e+00   0.00e+00  1.00e+04       0    5.33e-04    3.46e-03
   1  4.511598e-07    4.51e+01    9.50e-04   9.50e+00   1.00e+00  3.00e+04       1    5.00e-04    4.05e-03
   2  5.012552e-16    4.51e-07    3.17e-08   9.50e-04   1.00e+00  9.00e+04       1    1.60e-05    4.09e-03
Ceres Solver Report: Iterations: 2, Initial cost: 4.512500e+01, Final cost: 5.012552e-16, Termination: CONVERGENCE
x : 0.5 -> 10

如果你得到同样的结果,那么说明环境的配置和基础使用已经OK

2.3 Helloworld小结

学习完本部分后,依托着简单的函数,我们可以大致总结出ceres解决的问题的框架和步骤:

1.建立constFuntions 1
2.设置初值,构建出最小二乘问题(使用Probolem类)
3.构建solver,设置使用的方法如线性最小二乘等
4.输出程序结果

3.ceres在powell法上的实现

接下来介绍一个较为复杂的问题,鲍威尔优化算法。有兴趣的可以查询其算法细节,本文主要是针对ceres的使用。
参数为 x = [ x 1 , x 2 , x 3 , x 4 ] x=[x_1,x_2,x_3,x_4] x=[x1,x2,x3,x4],具体的函数为:
f 1 ( x ) = x 1 + 10 x 2 f 2 ( x ) = 5 ( x 3 − x 4 ) f 3 ( x ) = ( x 2 − 2 x 3 ) 2 f 4 ( x ) = 1 0 ( x 1 − x 4 ) 2 F ( x ) = [ f 1 ( x ) , f 2 ( x ) , f 3 (

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值