安得万里风,飘飖吹我裳。
求解最小二乘问题
Ceres的有效使用需要熟悉非线性最小二乘解算器的基本组成部分,因此在我们描述如何配置和使用解析器之前,我们将简要地了解一下Ceres的一些核心优化算法是如何工作的。
定义
由于对F(x)的全局最小化是一个棘手的问题,我们将不得不满足于寻找局部最小值。
解决非线性优化问题的一般策略是,解决原始问题的一系列逼近问题。在每次迭代中,这个近似都得到了解决,以确定Δx修正向量x。对于非线性最小二乘,可以利用线性化
不幸的是,天真地解决了一系列的问题并更新了
- 置信域置信域的方法近似目标方程,是在搜索空间的一个子集(置信域)中使用模型函数(通常是平方的)。如果模型函数成功地最小化了真正的目标函数,那么信任区域就会展开;反过来,置信域就会收缩,模型优化问题又会得到解决。
- 线性搜索线性搜索方法首先找到一个下降方向,目标函数将被减少,然后计算一个步长,决定沿着这个方向移动的距离。许多方法其可用来计算利用下降方向例如梯度下降法、牛顿法和拟牛顿法,步长也可以精确的或不精确的确定。
在某种意义上,置信域方法是线性搜索方法的对偶:任区域方法首先选择一个步长(置信域的大小),然后是下降方向,而行搜索方法首先选择一个下降方向,然后是步长。Ceres对这两种类别都实现了多种算法。
Trust Region Methods
基本的信任区域算法是这样的
- 给定一个初始点x和一个信任区域半径μ。
- 求解
argminΔxsuch that12∥J(x)Δx+F(x)∥2∥D(x)Δx∥2≤μL≤x+Δx≤U. -
ρ=∥F(x+Δx)∥2−∥F(x)∥2∥J(x)Δx+F(x)∥2−∥F(x)∥2 - 如果
ρ>ϵ ,那么x=x+Δx - 如果
ρ>η1 ,那么μ=2μ - 否则如果
ρ<η2 ,那么μ=0.5∗μ - 跳转到2
μ是置信域半径,D(x)是一个矩阵定义F(x)域上的一个度量,ρ 便是步长Δx的质量,例如线性模型预测非线性目标值的下降有多好。其思想是: 增加或减少信任区域的半径取决于线性化预测非线性目标的行为的好坏,而这反过来又反映在ρ的值上。
在置信域算法中的关键计算步骤是解决约束优化问题的方法
解决这个问题有许多不同的方法,每一个都产生一个不同的具体的置信域算法。目前,Ceres实现了两个置信域算法LM和Dogleg。如果有边界约束,那么每一个都被加了一个线性搜索。用户可以通过设置Solver::Options::trust_region_strategy_type.来选择它们。
Levenberg-Marquardt
LM算法是解决非线性最小二乘问题最流行的方法,它也是最先开发出来的置信域方法。Ceres实现了LM算法的一个精确步骤和一个不精确步骤变体。
可以证明,解决(3)可以通过解决具有如下形式的非约束优化来获得
λ 是拉格朗日乘数与 μ 逆相关
矩阵D(x)是一个非负的对角矩阵,通常是矩阵
我们假设矩阵D(x)已经在矩阵
除了最小的问题,LM 算法的每一次迭代中(5)的求解是Ceres的主要计算成本。Ceres为解决(5)提供了许多不同的选择,有两种主要的方法——分解和迭代。
分解方法是精确的求解(4),使用 Cholesky 或 QR分解的方法,得到精确的step。但是还不清楚在LM算法的每一步中求解(4)的精确值对于解决(1)是否是必要的。事实上,我们已经看到证据表明,事实并非如此,因为(4)本身是一个规范化的版本(2)。实际上,构造线性化问题的非线性优化算法是可行的。这些算法被称为不精确牛顿或截断牛顿法。
一种不精确的牛顿法需要两种原料。首先,一种近似解线性方程组的廉价方法。一般来说,像 Conjugate Gradients 法这样的迭代线性求解是用于这个目的的。第二,迭代求解程序的终止规则。典型的终止规则是这样的
k表示LM迭代数,
Ceres支持精确和不精确的步骤解决方案。当用户选择基于分解的线性分解器时,使用了精确的步骤LM算法。当用户选择一个迭代的线性解算器时,将使用不精确的步骤LM算法。
Dogleg
另一种解决置信域问题(3)的策略是由 M. J. D. Powell提出的。这里的关键思想是计算两个向量
注意向量
TRADITIONAL_DOGLEG 就像 Powell 所描述的,用高斯-牛顿和柯西矢量构造两条线段,发现沿着这条线最远处的点,形状就像一条狗腿(因此得名)。关于具体的推理和计算的更多细节,请参见 Madsen et al [Madsen]。
SUBSPACE_DOGLEG 是一种更复杂的方法 ,它考虑了由这两个向量形成的2维子空间,并在这个子空间中找到最小化置信域问题的点。
对LM来说,Dogleg的关键优势在于,如果对μ的某一特定选择计算的step并没有导致目标函数值的明显的减少,那么LM用更小μ值从头开始解决线性近似,另一方面,Dogleg只需要计算高斯-牛顿和柯西矢量之间的值,它们都不依赖于 μ的值。
Dogleg方法只能与基于分解的线性求解器一起使用。
Inner Iterations
一些非线性最小二乘问题在参数块相互作用的方式中有额外的结构,这有利于修改信任区域步骤的计算方式。例如,考虑以下回归问题
对于一组点对,用户希望去估计
注意,表达式的左边是a1和a2的线性表达式,对于任何的b1、b2和c1值,可以使用线性回归来估计a1和a2的最优值。从问题的角度分析完全可以消除变量a1和a2。像这样的问题被称为可分离的最小二乘问题而最著名的解决方法是 Golub & Pereyra 发明的Variable Projection算法。
在矩阵分解中,也可以找到类似的结构,去掉数据。对应的算法被称为Wiberg的算法。
实现变量投影是乏味且昂贵的。Ruhe & Wedin提出了一种更简单的算法,具有类似的收敛性,他们称之为Algorithm II 。Algorithm II在计算一个成功的牛顿步骤之后,执行一个额外的优化步骤来估计a1和a2。
这个思想可以推广到在a1和a2,残差不是线性的情况。例如:
在这种情况下,我们将求解整个问题的信任区域,然后使用它作为起点,进一步优化a1和a2。对于线性情况,这相当于做一个线性最小二乘解。对于非线性问题,任何解决a1和a2优化问题的方法都可以。对于a1和a2(如果它们在两个不同的参数块),惟一的约束是它们不会出现在一个残差块中。
这一思想可以进一步推广,不仅仅是优化(a1,a2),而是将与Hessian矩阵的稀疏结构相对应的图形分解成一组不重叠的独立集,并对它们进行优化。
将 Solver::Options::use_inner_iterations 设置为 true,使用Ruhe&Wedin算法II的非线性泛化。这个版本的Ceres具有更高的迭代复杂度,但是在每次迭代中也表现出更好的收敛性。
推荐将 Solver::Options::num_thread 设置为最大数目,
Non-monotonic Steps
注意,置信域方法是一种下降算法,如果一个点严格地降低目标函数的值,它就会接受它。
放宽这一要求,可以使算法在长期内更有效,代价是增加了目标函数局部的值。
这是因为允许非下降的目标函数值允许算法”跳过巨石”,因为该方法不局限于在保留其收敛属性的情况下移动到狭窄的山谷中。
将 Solver::Options::use_nonmonotonic_steps设为 true 使能Conn, Gould & Toint 提出的非单调置信域算法。
尽管目标函数的值可能大于在优化过程中遇到的最小值,但是返回给用户的最终参数是与所有迭代的最小cost对应的。
对于所有置信域策略,非单调步骤的选项是可用的。
Line Search Methods
目前,Ceres的线性搜索方法不能处理边界约束,因此只能用于解决不受约束的问题。
线性搜索方法
- 给定一个初始点x
-
Δx=−H−1(x)g(x) -
argminμ12∥F(x+μΔx)∥2 -
x=x+μΔx - 跳转到2
第4步,这是一个一维的优化或者是沿着\Delta x$的线性搜索,这给这类方法名字。
不同的线搜索算法在选择搜索方向
- STEEPEST_DESCENT 这对应于
H(x) 是单位矩阵。除了最简单的问题,这并不是一个好的搜索方向。它只是为了完整性而被包含在这里。 - NONLINEAR_CONJUGATE_GRADIENT 将共轭梯度法推广到非线性函数中。推广可以以多种不同的方式进行,从而产生不同的搜索方向。Ceres Solver目前支持FLETCHER_REEVES、POLAK_RIBIERE和HESTENES_STIEFEL方向。
- BFGS 将Secant的方法推广到多个维中,在这种情况下,得到了一种完全的、密集的近似于逆Hessian的近似,并用来计算拟牛顿step。BFGS是目前已知的最著名的拟牛顿算法。
- LBFGS 有限的内存近似于完整的BFGS方法,在此方法中,最后的M次迭代被用来计算拟牛顿Hessian的逆的近似。
目前,Ceres Solver同时支持回溯和插值的基于 Armijo线性搜索的算法,以及一种分割/缩放插值(strong)Wolfe 条件线性搜索算法。然而,注意,为了保证BFGS和LBFGS方法的基础假设,应该使用Wolfe的搜索算法。
LinearSolver
回想一下,在上面描述的两个置信域方法中,关键的计算成本是一个具有如下形式的线性最小二乘问题
让
Ceres提供了许多不同的方案解决(8)。
DENSE_QR
对于较小的问题(几百个参数和几千个残差),相对稠密的Jacobians,DENSE_QR 是一个选择。让
Ceres使用了Eigen的稠密QR分解步骤。
DENSE_NORMAL_CHOLESKY & SPARSE_NORMAL_CHOLESKY
大型非线性最小二乘问题通常是稀疏的。在这种情况下,使用稠密的QR分解是低效的。让
细心的读者会注意到,
DENSE_NORMAL_CHOLESKY
正如这个名字所暗示的,它会对正常的方程进行密集的Cholesky分解。Ceres使用了Eigen的稠密的LDLT分解程序。
SPARSE_NORMAL_CHOLESKY
正如这个名字所暗示的,在正常方程中执行稀疏的Cholesky分解。这就让大的稀疏问题节省了大量的时间和内存。
CGNR
对于一般的稀疏问题来说,如果这个问题对CHOLMOD来说太大,或者一个稀疏的线性代数库没有链接到Ceres,那么另一个选择就是CGNR方案。这个方案在普通方程上使用共轭梯度求解,但不需要显式地规范化方程。它利用
共轭梯度的收敛依赖于调节数
当用户选择CGNR作为线性解决程序时,Ceres自动从精确的步骤算法切换到不精确的步骤算法。
DENSE_SCHUR & SPARSE_SCHUR
虽然可以使用SPARSE_NORMAL_CHOLESKY来解决BA问题,但BA问题有一个特殊的结构,并且可以构造一个更有效的方案解决(8)。
假设SfM问题由p个摄像机和q个点组成,而变量向量x有块结构
BA问题的一个关键特性是,没有一个
并应用高斯消元。正如我们上面所提到的,C是一个块对角矩阵,对角块大小s×s。因此,计算C的逆矩阵通过每个块的逆运算是很简单的。这让我们可以消除
其中
是H中C的Schur complement。它也被称为缩小的摄像机矩阵,因为参与(11)的唯一变量是与摄像机相对应的变量。
现在,(10)可以通过先S的形式,求解Δy,然后用Δy来求Δz的值。因此,
(11)仍待解决,对于对称正定系统的求解方法完全是通过Cholesky分解并取决于矩阵的结构,通常有两种选择,第一种,直接分解,我们存储和分解S当作一个稠密的矩阵。这个方法有
但是,S是典型的相当稀疏的矩阵,因为大多数图片只能看到一小部分场景。这就让我们有了第二个选择:稀疏直接法。这些方法将S作为一个稀疏矩阵,使用行和列的重新排序算法来最大限度地增加Cholesky 分解的稀疏性,并将它们的计算工作重点放在分解的非零部分上。稀疏直接法,依赖于Schur complement的稀疏结构,允许BA调整算法将稠密分解显著的优化。Ceres实现这个策略叫做 SPARSE_SCHUR。
ITERATIVE_SCHUR
BA问题的另一个选择是应用Preconditioned Conjugate Gradients来减少相机矩阵S而不是H。这样做的一个原因是S要比H小的多,但是更重要的是,你可以看到
使用Conjuagate Gradients的关键计算是
- 隐式的 这是默认的。隐式求值适用于大问题,即计算和存储S Schur Complement S的成本太高,因为PCG只需要通过乘以一个矢量来得到S,一个计算
Sx 的方法就是观察
x1=ET
x2=C−1x1
x3=Ex2
x4=Bx
(12)Sx=x4−x3
因此,我们可以在S中运行PCG,与在H中每一次迭代PCG有一样的计算量。在享受更强大的预调节带来的好处的同时。事实上,我们甚至不需要计算H,(12)可以使用J的列来实现。
方程(12)与结构工程和偏微分方程中出现的大线性系统的Domain Decomposition 方法密切相关。在 Domain Decomposition中,BA问题中的每一个点都是一个域,摄像机在这些域之间形成了交互。Schur complement的迭代求解属于迭代子结构技术的子范畴。
2. 显式的 隐式矩阵向量乘积求值的复杂性与雅可比矩阵中的非零数有关。对于小到中型的问题,构建Schur complement的成本足够小,可以在内存中显式地构造它,并使用它来评估Sx乘积。
当用户选择迭代器作为线性解决程序时,Ceres自动地从精确的步骤算法切换到不精确的步骤算法。
Preconditioner
解(8)的Conjugate Gradients 的收敛速度取决于H的特征值的分布。一个有用的上界是
这个问题的解决方法是用一个预条件系统来替换(8)。给一个线性系统,
使用预调式M的计算成本是计算M和计算任意向量y的乘积
所有的预调器中最简单的是对角或雅可比的预调机。例如,
ITERATIVE_SCHUR 的另一个明显的选择是,Schur complement 矩阵 S的块对角线。例如,S的块Jacobi预调器,Ceres实现了它,并把它称为 SCHUR_JACOBI 预调器。
对于图片集3维重建中出现的BA问题,可以通过分析和利用场景中的相机点可视性结构来构建更有效的预调器。Ceres实现了 Kushal & Agarwal 所描述的两种可见性的预调,CLUSTER_JACOBI 和 CLUSTER_TRIDIAGONAL。这些都是全新的预调器,Ceres的实现还处于早期阶段,并不像上面描述的其他预调机那样成熟。
Ordering
在线性求解器中消除变量的顺序对方法的效率和准确性有很大的影响。例如,当做稀疏的Cholesky 分解时,有一个矩阵,一个好的排序将会给出一个带有O(n)的存储,一个坏的排序将导致一个完全密集的因子。
Ceres允许用户向解决程序提供各种提示关于变量消除顺序。这可以从没有任何提示,求解程序可以根据用户的选择来决定最佳的排序,比如使用的线性解析器,到一个精确的变量应该被消除的顺序,以及在其间的各种可能性。
ParameterBlockOrdering 类的实例用于向Ceres传递这些信息。
形式上的排序是参数块的有序分割。每个参数块都属于一个组,每个组都有一个与之关联的惟一整数,这决定了组中的顺序。我们称这些组为消除组。
有了这样的排序,Ceres确保最低编号的消除组的参数块首先被消除,然后消除下一个最低编号的消除组,依次下去。在每个消除组中,Ceres可以自由地按照它所选择的参数块顺序来排序。例如,线性系统
有两种方法可以解决这个问题。首先从两个方程中消去x,然后再用x代替解出y,或者先消除y,解出x,然后再用y替换。用户可以在这里构造三个排序。
-
{0:x},{1:y} :先求解x -
{0:y},{1:x} :先求解y -
{0:x,y} :求解器决定消除顺序。
因此,为了让Ceres启发式自动确定排序,将所有的变量放在同一个消除组中。这个群体的身份并不重要。这和没有指定一个排序是一样的。为了控制每个变量的排序,为每个变量创建一个消处组,按需要的顺序排列它们。
如果用户使用一个Schur解决方案(DENSE_SCHUR、SPARSE_SCHUR、ITERATIVE_SCHUR),并选择指定一个排序,那么它必须具有一个重要的属性。最低编号的消除组必须在与Hessian相对应的图中形成一个独立的集合,或者换句话说,在第一个消除组中没有两个参数块应该在同一个残差块中。为了达到最佳的性能,这个消除组应该尽可能的大。对于标准BA问题,这对应于第一个消除组包含所有3d点,第二个包含所有摄像机参数块。
如果用户让Ceres选择,那么解析器使用近似最大的独立集算法来识别第一个消除组。
MarkDown出了点问题,这篇就到这了,Great Saturday.