Ceres非线性优库入门介绍

2020-12-11 17:06:19 浏览数 (2)

一、背景知识

Ceres是一款非线性优化库,广泛的应用于SLAM问题中的BA问题等求解,但并不局限于SLAM问题,而是更加通用的一个非线性优化库,由Google研发并在其项目中被使用,质量和性能可以保证。相比于g2o(另一款用于SLMA问题的优化库),具有更丰富的API文档和官方教程,更为推荐使用。

Ceres单词是指“谷神星”,之所以起这个名字是因当时高斯采用最小二乘法算出了谷神星的轨迹并被成功观测。而最小二乘法是非常经典的优化问题,故起名为Ceres。本文将介绍Ceres基本原理和简单的使用方法。

二、基本概念

对于任何一个优化问题,我们首先需要对问题进行建模,之后采用合适的优化方法,进行求解。在求解的过程中,往往需要进行梯度下降求取最优,这里涉及了导数计算。所以在代码中使用Ceres进行优化时,需要包含基本内容:建模、优化、求导方法。

2.1 问题建模

对于形如

问题来说,

表示残差块ResidualBlock,优化问题是多个残差块之和;

表示代价函数CostFunction;

为参数块ParameterBlock;

表示损失函数LossFunction。这样便完成了一个优化问题的建模。

在写代码时,我们需要先定义代价函数,定义时需要指明求导方式(见2.3),之后将残差块加入到优化问题中即可。代码如下:

(代码释义:定义一个代价函数,采用AutoDiffCostFunction自动求导方法,参数和优化的指都是1维变量,之后在当前problem中添加代价函数残差块,损失函数为NULL采用默认的最小二乘误差即L2范数,优化变量为x)

2.2 问题求解

问题求解时,需要指定求解时的优化方法、迭代次数等相关参数,只需要简单设置即可。例如采用如下代码设置最大迭代次数500,采用稠密QR分解进行线性求解的求解选项:

2.3 求导方法

Ceres提供了三种求导方法,分别是:解析求导、数值求导与自动求导。下面以最小二乘

为例解析求导Analytic Derivatives。解析求导需要自行定义迭代求导时的雅克比矩阵jacobians,和残差。显然残差为

,而雅可比矩阵维度为

且为常数-1。在求导的Evaluate函数中定义残差和雅克比如下:

数值求导 Numeric derivatives

数值求导核心思想是,当增量很小时,可以采用

近似求导,由此我们不需要实际计算导数的表达式,也可以从数值上进行近似。为此,求导方式的代码只需要写清楚残差怎么计算即可:

数值求导方法又具体分为:前向求导、中心求导和Ridders方法,对应的精度和耗时依次增加。官方建议在不考虑时间约束时采用Ridders方法,中心求导是一个均衡的选择。

自动求导 Automatic Derivatives

自动求导是Ceres很神奇的一个功能,能够对于一些数据形式较为基础的表达式,自动求解出导数形式(注意这里不是数值解)。采用的原理是对偶数(dual numbers)和Jets格式实现的,不理解意具体方法也不影响使用。代价函数编写时和数值方式接近,采用类模板形式。注意采用自动求导时即使是整数也要写成浮点型,否则会报错Jet类型匹配错误。

求导方法的选择

求导方法的选择的依据是多方面的,一方面是精度和速度,另一方面是使用的便捷性。毫无疑问,在代码优化的情况下,解析求导方式求解速度最快,但缺点是需要人工计算雅克比矩阵,失去了便捷性。数值求导几乎是万能的,只是时间稍慢。而自动求导,虽然较为方便,但也存在问题,例如传入的变量类型若不是较为基础的数据格式则不可用自动求导。

官方给出了几种方法的计算时间如下:

(多种求导方法耗时比较。从上到下:解析求导、优化后的解析求导、向前数值求导、中心数值求导、Ridders数值求导、自动求导)

可以看出,代码优化较好的解析法求导速度最快,其次是自动求导,数值求导相对较慢。

三、示例代码

一个简单的求解

的优化问题代码如下:

四、其他

Ceres库官方使用教程:

http://ceres-solver.org/tutorial.html

Ceres源码:

https://github.com/ceres-solver/ceres-solver

作者系3D视觉从入门到精通知识星球嘉宾~

上述内容,如有侵犯版权,请联系作者,会自行删文。

0 人点赞