SLAM中的优化理论(一)—— 线性最小二乘

时间:2022-04-11 22:54:37

最近想写一篇系列博客比较系统的解释一下 SLAM 中运用到的优化理论相关内容,包括线性最小二乘、非线性最小二乘、最小二乘工具的使用、最大似然与最小二 乘的关系以及矩阵的稀疏性等内容。一方面是督促自己对这部分知识进行总结,另一方面也希望能够对其他人有所帮助。由于内容比较多希望能够坚持写完。

本篇博客主要讲解线性最小二乘问题,主要包括以下内容:

  • 最小二乘问题的定义
  • 正规方程求解
  • 乔姆斯基分解法求解
  • QR分解法求解
  • 奇异值分解法求解
  • 齐次方程的最小二乘

一. 问题的定义

  最小二乘问题通常可以表述为,通过搜集到的一些数据(获取得到的样本),对某一个模型进行拟合,并尽可能的使得模型结果和样本达到某种程度上的最佳拟合:

SLAM中的优化理论(一)—— 线性最小二乘  转化为数学表达式为:

SLAM中的优化理论(一)—— 线性最小二乘  其中 x 为模型中参数所组成的向量,e 通常被称为残差向量(residual vector).
  现在假设我们的模型函数为 Ax,样本为 b 且方程数大于未知量数则有:
SLAM中的优化理论(一)—— 线性最小二乘  转化为最小二乘表达式为:
SLAM中的优化理论(一)—— 线性最小二乘  该方程通常可以通过正规方程、QR 分解、乔姆斯基分解(Cholesky decomposition)和奇异值分解(SVD)等方法求解。

二. 求解方法

2.1. 正规方程(Normal Equation)

SLAM中的优化理论(一)—— 线性最小二乘SLAM中的优化理论(一)—— 线性最小二乘为了求解得到该方程的最优解(即最小值),我们可以求解其对于参数 x 的偏导数,并令其等于零:
SLAM中的优化理论(一)—— 线性最小二乘化简后得到:
SLAM中的优化理论(一)—— 线性最小二乘以上被称为最小二乘的正规方程(Normal Equation)。进一步求解可得到:
SLAM中的优化理论(一)—— 线性最小二乘该结果亦可表示为矩阵的伪逆形式(伪逆为逆矩阵广义形式,奇异阵或非方阵不存在逆矩阵,但可以求解其伪逆矩阵)

SLAM中的优化理论(一)—— 线性最小二乘

2.2. 乔姆斯基分解(Cholesky Decomposition)

以下内容参考[1].
由于简单的正规方程计算运算量,因此为了更快更稳定的求解,通常可以运用乔姆斯基分解进行求解。
对正规矩阵左侧进行乔姆斯基分解有:

SLAM中的优化理论(一)—— 线性最小二乘

该乔姆斯基分解会生成一个上三角矩阵 R ̄ 和它的转置矩阵,所以我们能够通过连续的向前和向后的替换来计算求解向量:

SLAM中的优化理论(一)—— 线性最小二乘

2.3. QR分解

以下图片参考[4]

  QR 分解可以将矩阵分解称为一个标准正交方阵和一个上三角矩阵的积:

SLAM中的优化理论(一)—— 线性最小二乘

QR 分解的计算方式有很多,以下以 Householder 变换为例进行分析。首先我们对基于 Householder 的 QR 分解进行简单的分析,假设 A 为一个 5X4 的矩阵,我们用 X 表示这次变换未变化的元素,用+表示发生变换的元素则有:

SLAM中的优化理论(一)—— 线性最小二乘

SLAM中的优化理论(一)—— 线性最小二乘

SLAM中的优化理论(一)—— 线性最小二乘

以此类推,通过四次 Householder 变换就可以将矩阵 A 转换为一个上三角矩阵,且若 A列不相关,则 R 为非奇异矩阵,则有:

SLAM中的优化理论(一)—— 线性最小二乘那么具体到实际的运算中我们应该怎么通过 Householder 方法计算 QR 分解呢?首先我们先来回顾一下 Householder 变化,对于 Householder 变换我们有以下定义:

SLAM中的优化理论(一)—— 线性最小二乘

然后我们通过一个实际的计算例子来说明 Householder 的 QR 分解变化。案例参考[2]。假设现在我们有以下五个数据:

(-1, 1), (-0.5, 0.5), (0, 0), (0.5, 0.5), (1.2)

并且有满足该数据的线性系统如下所示:

SLAM中的优化理论(一)—— 线性最小二乘  首先我们队第一列进行处理:

SLAM中的优化理论(一)—— 线性最小二乘

  其中的√5为SLAM中的优化理论(一)—— 线性最小二乘

SLAM中的优化理论(一)—— 线性最小二乘

  然后依次类推,对第二列和第三列进行求解:

SLAM中的优化理论(一)—— 线性最小二乘

至此完成矩阵 A 的 QR 分解。
通过以上方法我们能够求得 Q 和 R 矩阵,那么如何通过他们解决最小二乘问题呢。
对于一个最小二乘问题我们有:

SLAM中的优化理论(一)—— 线性最小二乘

对 A 进行 QR 分解,我们能够得到:

SLAM中的优化理论(一)—— 线性最小二乘

  在这里我们将SLAM中的优化理论(一)—— 线性最小二乘

SLAM中的优化理论(一)—— 线性最小二乘

由此进一步我们有:

SLAM中的优化理论(一)—— 线性最小二乘

该结果就为 QR 分解求解线性最小二乘的表达式。

2.4. 奇异值分解(SVD)

以上形式的最小二乘问题还可以通过 SVD 分解的方法进行求解。对于SLAM中的优化理论(一)—— 线性最小二乘

SLAM中的优化理论(一)—— 线性最小二乘

SLAM中的优化理论(一)—— 线性最小二乘

SLAM中的优化理论(一)—— 线性最小二乘

由于我们已经假设问题为超定(m>n),因此有:

SLAM中的优化理论(一)—— 线性最小二乘

SLAM中的优化理论(一)—— 线性最小二乘

SLAM中的优化理论(一)—— 线性最小二乘

SVD 的求解方法总结如下,参考[3].

SLAM中的优化理论(一)—— 线性最小二乘

三. 齐次方程的最小二乘

之前我们讨论的最小二乘问题其形式都为Ax − b = 0,如果问题形式发生改变,变为Ax = 0,那么这样的最小二乘问题应该如何求解呢?

Ax = 0形式的问题经常出现在重建问题(reconstruction)中。我们期望找到方程Ax = 0中 x 不等于零的解。由于该方程的特殊形式我们会发现对于 x 不等于零的解我们乘上任意的尺度因子 k 使解变为 kx 都不会改变最终结果。因为我们可以将问题转化为求解 x 使得||Ax||值最小并且||x||=1。

现在对矩阵 A 进行 SVD 分解有:

SLAM中的优化理论(一)—— 线性最小二乘

SLAM中的优化理论(一)—— 线性最小二乘

SLAM中的优化理论(一)—— 线性最小二乘

通过 SVD 分解中 D 矩阵的性质我们能够发现,D 为一个对角矩阵,且它的对角线元素呈降序排列。因此方程的解应该为:

SLAM中的优化理论(一)—— 线性最小二乘

该解在最后的位置有一个值为 1 的非零项。依据此结果,再根据方程:

SLAM中的优化理论(一)—— 线性最小二乘

我们可以发现,x 的值就为矩阵 V 的最后一列。

-------------------------------------------------------------------------------------------------------------------------

附:

对于Ax=b, A为一个mXn的矩阵,其结果有以下三种可能性:

  • m<n, 未知数个数大于方程格式,在这种情况下不存在唯一解,但是存在一个解的向量集合;
  • m=n, 如果矩阵A可逆,存在唯一解;
  • m>n, 方程个数大于未知数个数.通常情况下方程不会有解,除非b恰好位于矩阵A的列空间中;

参考内容:

[1]. 使用Math.NET求解线性和非线性最小二乘问题

[2]. Least Squares Approximation/Optimization

[3]. Multiple View Geometry in Computer Vision, Appendix 5, Least-squares Minimization

[4]. 机器学习中的矩阵方法03:QR 分解

SLAM中的优化理论(一)—— 线性最小二乘的更多相关文章

  1. SLAM中的优化理论(二)- 非线性最小二乘

    本篇博客为系列博客第二篇,主要介绍非线性最小二乘相关内容,线性最小二乘介绍请参见SLAM中的优化理论(一)-- 线性最小二乘.本篇博客期望通过下降法和信任区域法引出高斯牛顿和LM两种常用的非线性优化方 ...

  2. 第六篇 视觉slam中的优化问题梳理及雅克比推导

    优化问题定义以及求解 通用定义 解决问题的开始一定是定义清楚问题.这里引用g2o的定义. \[ \begin{aligned} \mathbf{F}(\mathbf{x})&=\sum_{k\ ...

  3. 从零开始一起学习SLAM &vert; 理解图优化,一步步带你看懂g2o代码

    首发于公众号:计算机视觉life 旗下知识星球「从零开始学习SLAM」 这可能是最清晰讲解g2o代码框架的文章 理解图优化,一步步带你看懂g2o框架 小白:师兄师兄,最近我在看SLAM的优化算法,有种 ...

  4. 视觉SLAM漫淡(二):图优化理论与g2o的使用

    视觉SLAM漫谈(二):图优化理论与g2o的使用 1    前言以及回顾 各位朋友,自从上一篇<视觉SLAM漫谈>写成以来已经有一段时间了.我收到几位热心读者的邮件.有的希望我介绍一下当前 ...

  5. SLAM中的EKF,UKF,PF原理简介

    这是我在知乎上问题写的答案,修改了一下排版,转到博客里.   原问题: 能否简单并且易懂地介绍一下多个基于滤波方法的SLAM算法原理? 目前SLAM后端都开始用优化的方法来做,题主想要了解一下之前基于 ...

  6. 视觉SLAM中的数学基础 第三篇 李群与李代数

    视觉SLAM中的数学基础 第三篇 李群与李代数 前言 在SLAM中,除了表达3D旋转与位移之外,我们还要对它们进行估计,因为SLAM整个过程就是在不断地估计机器人的位姿与地图.为了做这件事,需要对变换 ...

  7. SLAM中的非线性优化

    总结一下SLAM中关于非线性优化的知识. 先列出参考: http://jacoxu.com/jacobian%E7%9F%A9%E9%98%B5%E5%92%8Chessian%E7%9F%A9%E9 ...

  8. Linux中磁盘分区——理论篇

    Linux中磁盘分区——理论篇 现在主流的分区的方式有两种——MBR分区和GPT分区,本文将着重介绍MBR分区底层原理,及用相关命令验证相关原理 Linux中磁盘分区理论篇 为什么要对磁盘进行分区 M ...

  9. SVD分解及线性最小二乘问题

    这部分矩阵运算的知识是三维重建的数据基础. 矩阵分解 求解线性方程组:,其解可以表示为. 为了提高运算速度,节约存储空间,通常会采用矩阵分解的方案,常见的矩阵分解有LU分解.QR分解.Cholesky ...

随机推荐

  1. CSS Sprites优缺点

    利用CSS Sprites能很好地减少网页的http请求,从而大大的提高页面的性能,这也是CSS Sprites最大的优点,也是其被广泛传播和应用的主要原因: CSS Sprites能减少图片的字节, ...

  2. SpringHttpInvoker解析1-使用示例

    HTTP invoker是一个新的远程调用模型,作为Spring框架的一部分,来执行基于HTTP的远程调用(让防火墙可以接受),并使用Java的序列化机制. 服务端 定义服务接口UserService ...

  3. 011&lowbar;URL和Ajax辅助器方法

    创建基本的链接和URL 在我们介绍链接或URL之前先做一些准备,我们这部分要介绍的知识将要使用的项目就是之前建立的HelperMethods项目,现在需要先为其添加一个People控制器,并在其中定义 ...

  4. sharepoint One-Time Passwords &lpar;windows basic authentication&rpar;

    //设计中,未完成 references: http://www.asp.net/web-api/overview/security/basic-authentication http://techn ...

  5. 【原】Comparator和Comparable的联系与区别

    1.知识点了解 Comparator和Comparable都是用用来实现集合中元素的比较.排序的,所以,经常在集合外定义Comparator接口的方法和集合内实现Comparable接口的方法中实现排 ...

  6. Linq 关键字

    from var lowNums = from num in numbers            where num < 5            select num; numbers 是数 ...

  7. 遍历文件 创建XML对象 方法 python解析XML文件 提取坐标计存入文件

    XML文件??? xml即可扩展标记语言,它可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言. 里面的标签都是可以随心所欲的按照他的命名规则来定义的,文件名为roi.xm ...

  8. 如何在 Linux 中查看可用的网络接口

    在我们安装完一个 Linux 系统后最为常见的任务便是网络配置了.当然,你可以在安装系统时进行网络接口的配置.但是,对于某些人来说,他们更偏爱在安装完系统后再进行网络的配置或者更改现存的设置.众所周知 ...

  9. 解析 ViewTreeObserver 源码(上)

    主要内容:ViewTreeObserver 是被用来注册监听视图树的观察者,在视图树发生全局改变时将收到通知.本文从 ViewTreeObserver 源码出发,带你剖析 ViewTreeObserv ...

  10. python 保留两位小数

    >>> a = 1 >>> b = 3 >>> print(a/b) 0 >>> #方法一: ... print(round(a ...