前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >追溯Ceres-Solver中CostFunction类方法

追溯Ceres-Solver中CostFunction类方法

作者头像
3D视觉工坊
发布2021-12-01 13:59:42
1.1K0
发布2021-12-01 13:59:42
举报
文章被收录于专栏:3D视觉从入门到精通

本文作为《彻底搞懂视觉-惯性SLAM:VINS-Fusion原理精讲与源码剖析》课程补充材料

作者:Kehan

日期:2021/11/19

在使用Ceres-Solver进行解析求导时,需要继承CostFunction类,并重写virtual bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const函数,以来在残差项计算的同时给出对应的雅克比矩阵。

显而易见,在构建残差项的时候,我们通过AddResidualBlock(...)函数将上述构建的CostFunction传入ceres::Problem中。那么,上述重写的bool Evaluate(...)函数在何时被调用呢?追溯、阅读这个过程,会让我们对非线性优化问题的求解、以及函数实现方面有更深入的理解。

下面以Ceres-Solver的1.14.0版本源码(源码链接:https://github.com/ceres-solver/ceres-solver/releases/tag/1.14.0)为例,给出用Ceres做优化、求解问题时,其调用我们所实现的virtual bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const函数的过程。

1.internal/ceres/solver.cc文件

在求解问题时,我们调用了

ceres::Solve(options, &problem, &summary);

该函数的实现在文件internal/ceres/solver.cc的631行中。简单可以看到,它又调用了Solver::Solve(...)函数。

代码语言:javascript
复制
void Solver::Solve(const Solver::Options& options,
                  Problem* problem,
                  Solver::Summary* summary);

在Solver::Solve(...)函数中,首先对问题进行了预处理。然后在代码的第602行,调用了Minimize(...)函数。

代码语言:javascript
复制
void Minimize(internal::PreprocessedProblem* pp,
             Solver::Summary* summary);

Minimize(...)函数根据求解配置中的选择,选择不同类型的优化器。在代码464行minimizer->Minimize(...)(基类的虚函数,所以去找子类的实现)时调用所选择的求解器进行求解。求解器以的实现主要有三种,下文以Levenberg-Marquadt法所属的TrustRegionMinimizer求解器为例。

2. internal/ceres/trust_region_minimizer.h文件

我们看主要流程。

TrustRegionMinimizer在internal/ceres/trust_region_minimizer.h文件中重写实现的方法Minimize(...):

代码语言:javascript
复制
void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
                                   double* parameters,
                                   Solver::Summary* solver_summary)

第113行调用HandleSuccessfulStep()函数。在HandleSuccessfulStep()函数的实现代码777行中,调用了EvaluateGradientAndJacobian(...)函数。

EvaluateGradientAndJacobian(...)这个函数是一个重要的函数,就是在这里算的一系列东西,我们看源代码的注释便可知。

internal/ceres/trust_region_minimizer.cc文件第214行开始:

代码语言:javascript
复制
// For the current x_, compute
//
//  1. Cost
//  2. Jacobian
//  3. Gradient
//  4. Scale the Jacobian if needed (and compute the scaling if we are
//     in iteration zero).
//  5. Compute the 2 and max norm of the gradient.
//
// Returns true if all computations could be performed
// successfully. Any failures are considered fatal and the
// Solver::Summary is updated to indicate this.
bool TrustRegionMinimizer::EvaluateGradientAndJacobian(
   bool new_evaluation_point) {...}

EvaluateGradientAndJacobian(...)的实现中,在代码230行调用了evaluator_->Evaluate(...)。这又是一个基类的虚函数。我们看ProgramEvaluator类的实现,在internal/ceres/program_evaluator.h文件中。

3.internal/ceres/program_evaluator.h文件

ProgramEvaluator类所实现的Evaluate(...)函数中,internal/ceres/program_evaluator.h文件第254行,我们看到调用了residual_block->Evaluate(...),这里是不是有些眼熟了。我们就是将自己所实现的CostFunction类添加到了残差块ResidualBlock中去了。所以接下来我们看residual_block->Evaluate(...)的实现。

4.internal/ceres/residual_block.cc文件

residual_block->Evaluate(...)的实现在文件internal/ceres/residual_block.cc中,自第68行开始。

代码语言:javascript
复制
bool ResidualBlock::Evaluate(const bool apply_loss_function,
                            double* cost,
                            double* residuals,
                            double** jacobians,
                            double* scratch) const {...}

在实现代码里的第111行,我们发现调用了我们所实现的virtual bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const函数:

代码语言:javascript
复制
if (!cost_function_->Evaluate(parameters.get(), residuals, eval_jacobians)) {
   return false;
 }

在这里调用,实现了待优化变量的传入,并计算出了残差项与雅克比矩阵。

至此,我们追溯了我们所实现的virtual bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const函数是如何在Ceres-Solver做优化时被调用的。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-11-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 3D视觉工坊 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.internal/ceres/solver.cc文件
  • 2. internal/ceres/trust_region_minimizer.h文件
  • 3.internal/ceres/program_evaluator.h文件
  • 4.internal/ceres/residual_block.cc文件
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档