Ceres Solver库使用方法(防止忘记)

该优化库在slam中常用,记录一下,防止忘记

Ceres-solver 是解决具有边界约束的非线性最小二乘优化和一般无约束优化问题。=

首先就是一些概念的问题,它解决的是优化问题,也就是什么样的输入会使预计值接近观测值,所以有了残差的概念,残差就是观测值 - 预计值

 里面一系列x被称为参数块(笔者理解就是优化对象),而fx函数被称为代价函数,是关于参数块的函数,代价函数用于衡量模型预测值与实际观测值之间的差异,优化过程中希望最小化这个函数。px被称为损失函数,损失函数是用来减少某些观测点对优化过程影响的一个工具,通常用于处理异常值或强调某些观测的影响。损失函数可以将代价函数中的每个残差转换为一个值,允许对某些残差赋予更大的权重或惩罚。

总体而言,代价函数用于计算整体误差,是优化的主要目标。损失函数则用于调整代价函数中每个误差的贡献,以便对异常值或特定观测给予不同的处理。这一些列整体被称为残差块ResidualBlock),残差块中包含了参数块代价函数损失函数。

Ceres 求解过程主要有两大步骤,构建问题和求解问题

先是自定义残差计算方式,也就是你要优化什么问题,举个例子,y = (12-x)^{^{2}}对于求解该函数的最小值问题,先构建残差计算方式:

struct MyCostFunctorAutoDiff 
{
	template<typename Type>
	bool operator()(const Type* const x, Type* residual) const
	{
		residual[0] = 12.0 - x[0];
		return true;
	}
};

在ceres中,double 类型与 ceres::Jet 类型之间可以进行自动类型转换。所以要写12.0。

然后构建代价函数和问题:

在这里,先构建Ceres代价函数CostFuntion,用来计算残差,残差计算方法为自定义残差计算模型MyCostFunctorAutoDiff,由于只存在一个代价函数,使用自动微分方法AutoDiffCostFunction来计算导数,而AutoDiffCostFunction<MyCostFunctorAutoDiff, 1, 1>模板参数中,需要依次指定
 用户自定义残差计算模型MyCostFunctorAutoDiff、输出(resudual)维度大小、输入(参数x)维度大小。这两个维度大小需要与残差计算模型中输入、输出参数的维度一致,对应residual[0]和x[0]。

在构建问题时添加残差块ResidualBlock,需要依次指定代价函数CostFunction,损失函数LossFunction(这里为单位函数),参数块ParameterBlock

// 构建非线性最小二乘问题
ceres::Problem problem;
// 添加残差块,需要依次指定代价函数,损失函数,参数块
// 损失函数为单位函数
problem.AddResidualBlock(new ceres:: AutoDiffCostFunction<MyCostFunctorAutoDiff, 1, 1>(new MyCostFunctorAutoDiff());, nullptr, &x);

接着,配置求解器参数Options、输出日志内容Summary:

// 配置求解器参数
ceres::Solver::Options options;
//也可以指定最大迭代次数
//options.max_num_iterations = 25;
// 指定线性求解器来求解问题
options.linear_solver_type = ceres::DENSE_QR;
// 输出每次迭代的信息
options.minimizer_progress_to_stdout = true;
// 输出日志内容
ceres::Solver::Summary summary;

最终,优化求解:

// 开始优化求解
ceres::Solve(options, &problem, &summary);

这一系列就对x输出最终的最优解 ,经过这些,我们初步对ceres库有了一个了解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值