Ceres Solver 入门

1. Ceres Solver 是什么

Ceres 可以解决以下形式的边界约束鲁棒化非线性最小二乘问题:

在这里插入图片描述
给定初始值,通过优化算法,得到最优解。

其中, f i f_i fi是CostFunction,也叫误差函数,或者代价函数。 ρ i \rho_i ρi是LossFunction。LossFunction 是一个标量函数,用于减少异常值对非线性最小二乘问题的解决方案的影响。 x i x_i xi就是我们输入的变量(包括要优化的和不用优化的)。

2. 如何使用Ceres

Ceres 求解优化问题的函数是:

CERES_EXPORT void Solve(const Solver::Options& options,
                        Problem* problem,
                        Solver::Summary* summary);

Ceres的用法就是围绕这个函数的参数展开的。

2.1 Solver::Options

Solver::Options 用来设置优化的参数。

常用的就是设置迭代的次数,步长,线性求解器的类型。

2.2 Problem

Problem 用来定义待解的优化问题。

在这里插入图片描述
核心就是往优化问题里面添加Residual block:

template <typename... Ts>
ResidualBlockId AddResidualBlock(CostFunction* cost_function,
                                 LossFunction* loss_function,
                                 double* x0,
                                 Ts*... xs)

残差块有三个参数,cost_function对应 f i f_i fi,loss_function对应 ρ i \rho_i ρi,x0和xs对应 x i x_i xi

我们来展开讲CostFunction和LossFunction。

2.2.1 CostFunction

CostFunction是一个基类,单看这个基类本身是没什么作用的,实际上使用的时候是用它的派生类AutoDiffCostFunction,如下所示:

template <typename CostFunctor,
	int kNumResiduals,  // Number of residuals, or ceres::DYNAMIC.
	int... Ns>          // Number of parameters in each parameter block.
class AutoDiffCostFunction final
	: public SizedCostFunction<kNumResiduals, Ns...> {
public:
	// Takes ownership of functor by default. Uses the template-provided
	// value for the number of residuals ("kNumResiduals").
	explicit AutoDiffCostFunction(CostFunctor* functor,
		Ownership ownership = TAKE_OWNERSHIP)
		: functor_(functor), ownership_(ownership) {
		static_assert(kNumResiduals != DYNAMIC,
			"Can't run the fixed-size constructor if the number of "
			"residuals is set to ceres::DYNAMIC.");
	}
	...
}

对于这个类,我们要关注的是CostFunctor,因为它定义的就是我们优化问题的cost_function,也就是方程中的 f i f_i fi。这个CostFunctor是一个结构体,我们需要在里面重写Operator(),从而定义我们的cost_function,如下所示:

struct CostFunc
{
	template <typename T>
	bool operator()(const T* const x0,
		const T* const ... xs,
		T* residuals) const
		{
			//定义residuals是怎么来的
			//...
			return true;
		}
};

举个例子:

f ( x ) = 1 2 ( 10 − x ) 2 f(x)= \frac {1} {2} (10−x)^2 f(x)=21(10x)2

那么,residuals就对应方程里面的10-x.

2.2.2 LossFunction

LossFunction 就是套在cost_function外面一层的修饰,为了提升鲁棒性。一般是nullptr,代表LossFunction就是1。如果为了提升鲁棒性,可以换成别的函数,常用的是HuberLoss:

在这里插入图片描述
在Ceres里面的代码如下:

class CERES_EXPORT HuberLoss final : public LossFunction {
	 public:
	  explicit HuberLoss(double a) : a_(a), b_(a * a) {}
	  void Evaluate(double, double*) const override;
	
	 private:
	  const double a_;
	  // b = a^2.
	  const double b_;
};

举个例子:

f ( x ) = 1 2 ( 10 − x ) 2 f(x)= \frac {1} {2} (10−x)^2 f(x)=21(10x)2

当我们将LossFunction定义成nullptr的时候,那么优化函数就是上面的式子。如果定义成HuberLoss的时候,那么优化函数如下所示:

f ( x ) = H u b e r ( 1 2 ( 10 − x ) 2 ) f(x)=Huber( \frac {1} {2} (10−x)^2) f(x)=Huber(21(10x)2)

2.3 Solver::Summary

用来存日志的。

3. 示例

参考ceres教程(1)

参考

  1. ceres教程(1)
  2. Ceres Solver 入门教程
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值