引言:当空间开始弯曲
想象一下,你是一只生活在二维平面上的蚂蚁。你可以自由地在平面上行走,测量距离,画出直线和三角形。你所知道的几何——欧几里得几何——似乎是那么完美、那么自洽。
现在,让我们把这只蚂蚁放到一个巨大的篮球表面。
蚂蚁会发现什么呢?首先,它会发现"直线"不再存在。如果它一直往前走,最终会回到起点——它走的是"大圆",而不是直线。其次,它会发现三角形的内角和不再是180度,而是大于180度。最神奇的是,如果它足够聪明,它可以通过测量距离和角度来发现这个空间的曲率——尽管它从未"跳出"过这个二维曲面。
这就是内蕴几何的魔力,也是流形(Manifold)概念的起点。
在接下来的篇幅中,我将带你进行一次从19世纪的几何革命到21世纪人工智能的漫游。我们会看到:
- 流形的诞生:高斯和黎曼如何改变了我们对空间的理解
- 流形的数学:为什么流形是"局部平坦、整体弯曲"的几何对象
- 流形在深度学习:从流形假设到球面Embedding
- 流形在机器人学:从四元数到SLAM
- 实战案例:四个让你真正理解流形威力的例子
准备好了吗?让我们开始这段跨越时空的数学之旅。
第一章:几何的危机与重生
1.1 欧几里得的第五公设
公元前300年,亚历山大港的数学家欧几里得写下了《几何原本》——这部奠定了西方科学基础的巨著。欧几里得从五条公设出发,推导出无数深刻的几何定理。其中第五条公设——平行公设——却让数学家们困惑了两千多年。
平行公设:如果一条直线与两条直线相交,且同侧内角之和小于两个直角,则这两条直线在该侧无限延伸后必定相交。
这条公设看起来比其他公设复杂得多。数学家们不禁想问:它能否从前四条公设中推导出来?如果可以,那它就不是真正的公设;如果不可以,那是否存在一种"非欧几里得几何",其中平行公设不成立?
1.2 罗巴切夫斯基的革命
1829年,俄罗斯数学家罗巴切夫斯基(Nikolai Lobachevsky)发表了第一篇非欧几何的论文。他假设过一点可以作多条平行线,由此推导出一套完整的几何体系——双曲几何。
在双曲几何中:
- 三角形的内角和小于180度
- 相似三角形只有大小完全相同才算相似
- 不存在矩形,因为四边形的内角和小于360度
罗巴切夫斯基的发现彻底改变了数学家对几何本质的认识:几何不是关于"真实空间"的真理,而是关于某种抽象结构的逻辑系统。
1.3 高斯的绝妙定理
几乎在同一时间,德国数学家高斯也在思考类似的问题。高斯不仅是一个理论家,还是一个实测工作者——他参与了汉诺威的大地测量。在测量中,高斯意识到一个深刻的问题:地球表面的几何能告诉我们什么?
1827年,高斯发表了绝妙定理(Theorema Egregium):曲面的高斯曲率是一个内蕴不变量——它完全由曲面自身的几何性质决定,与曲面如何嵌入周围空间无关。
这个定理的惊人之处在于:曲率不是"外部"观察者看到的弯曲,而是曲面"内部"几何结构的必然结果。一只生活在曲面上的蚂蚁,通过测量距离和角度,可以计算出它所在空间的曲率——即使它永远无法"看到"曲面在三维空间中的弯曲方式。
高斯的工作开创了内蕴几何的新时代,为流形的诞生奠定了基础。
1.4 黎曼的推广
1854年,高斯的学生黎曼(Bernhard Riemann)在哥廷根大学发表了著名的就职演讲《论作为几何学基础的假设》。黎曼将高斯的二维曲面理论推广到任意维数,创立了黎曼几何。
黎曼的核心思想是:几何不在于"空间是什么",而在于"我们如何测量空间中的距离"。
黎曼提出用一个度规张量(Metric Tensor)来描述空间的几何性质。度规告诉我们如何在空间的每一点测量距离和角度。有了度规,我们就可以定义:
- 曲线的长度
- 向量的点积
- 角度和面积
- 平行移动
- 测地线(最直的曲线)
黎曼几何成为了20世纪物理学的基石。1915年,爱因斯坦用黎曼几何描述时空的弯曲,建立了广义相对论。
第二章:流形的数学定义
2.1 什么是流形?
在数学中,流形(Manifold)是一个抽象的空间概念。直观地说,流形是一个"局部看起来像欧几里得空间"的空间。
流形的定义:
一个 $n$ 维流形 $M$ 是一个满足以下条件的拓扑空间:
局部欧几里得性:对于 $M$ 中的每一点 $p$,存在一个开集 $U \subseteq M$ 包含 $p$,以及一个从 $U$ 到 $\mathbb{R}^n$ 的开集的同胚映射(称为坐标图): $$\varphi: U \to \mathbb{R}^n$$
相容性:如果两个坐标图 $\varphi: U \to \mathbb{R}^n$ 和 $\psi: V \to \mathbb{R}^n$ 有重叠 $U \cap V$,那么映射 $\psi \circ \varphi^{-1}$ 和 $\varphi \circ \psi^{-1}$ 是光滑的($C^\infty$)。
第二可数性:流形可以被可数个坐标图覆盖。
满足条件2的坐标图集合称为图册(Atlas)。如果所有坐标变换都是光滑的,我们称这个流形为光滑流形(Smooth Manifold)。
2.2 从直观到抽象
让我用几个例子来解释这个抽象定义:
例子1:圆周
圆周 $S^1 = {(x, y) \in \mathbb{R}^2 \mid x^2 + y^2 = 1}$ 是一个一维流形。
为什么?因为圆周的每一点附近都"看起来像"一条直线。我们可以用角度 $\theta$ 作为局部坐标。对于点 $(1, 0)$ 附近,可以用 $\theta \in (-\pi/2, \pi/2)$;对于点 $(0, 1)$ 附近,可以用 $\theta \in (0, \pi)$,等等。
例子2:球面
球面 $S^2 = {(x, y, z) \in \mathbb{R}^3 \mid x^2 + y^2 + z^2 = 1}$ 是一个二维流形。
我们可以用经度 $\phi$ 和纬度 $\theta$ 作为局部坐标。但球面有一个特点:没有任何单个坐标图能覆盖整个球面(南极和北极会导致纬度坐标的奇点)。这就是为什么我们需要多个坐标图——每个坐标图覆盖一部分,然后用坐标变换将它们"粘"在一起。
例子3:环面
环面(甜甜圈表面)$T^2 = S^1 \times S^1$ 是一个二维流形。它可以看作是两个圆周的直积。环面是"紧致"(compact)流形的经典例子——它是有限的,但没有边界。
2.3 为什么要用流形?
你可能会问:为什么要引入这么抽象的概念?直接用 $\mathbb{R}^n$ 不就行了吗?
答案是:现实世界中的许多空间不是平坦的 $\mathbb{R}^n$,而是弯曲的流形。
考虑以下几个例子:
- 旋转:三维空间中的旋转不是 $\mathbb{R}^3$ 中的向量,而是特殊正交群 $SO(3)$——一个三维流形
- 姿态:机器人的姿态由旋转矩阵或四元数描述,这些都定义在流形上
- 图像:所有MNIST数字图像的集合构成一个流形——尽管是高维的,但本质上只有低维结构
- 蛋白质结构:蛋白质的所有可能构象形成一个流形
流形让我们能够用局部线性化的方法处理全局弯曲的空间。在流形的每一点,我们可以建立局部坐标系(切空间),在切空间中我们可以使用熟悉的线性代数工具。
2.4 切空间与向量场
在流形上,我们需要一种方法来描述"方向"和"变化"。这就是切空间(Tangent Space)的概念。
切空间的定义:
在流形 $M$ 的点 $p$ 处,切空间 $T_p M$ 是所有经过 $p$ 的曲线的切向量的集合。更抽象地说,切空间是所有在 $p$ 处为零的导数的空间。
对于 $n$ 维流形,切空间 $T_p M$ 是一个 $n$ 维向量空间。如果 $p$ 的局部坐标是 $(x^1, \dots, x^n)$,那么切空间的一组基是: $$\left\lbrace\frac{\partial}{\partial x^1}, \dots, \frac{\partial}{\partial x^n}\right\rbrace$$
向量场是流形上的一个函数,它为每一点 $p$ 指定一个切向量 $V(p) \in T_p M$。向量场可以看作是流形上的"速度场"或"方向场"。
2.5 余切空间与张量
与切空间对偶的是余切空间(Cotangent Space)$T^*_p M$。余切空间是切空间的对偶空间,其中的元素是切空间上的线性泛函(线性函数)。
如果 $\omega \in T^*_p M$ 且 $v \in T_p M$,那么 $\omega(v)$ 是一个标量。
更一般地,我们可以定义张量(Tensor)。张量是多线性映射,例如:
- $(0, 1)$ 型张量:余切向量
- $(1, 0)$ 型张量:切向量
- $(0, 2)$ 型张量:双线性形式(如度规张量)
张量在物理学和工程中无处不在。它们是描述几何和物理量的自然语言。
第三章:黎曼流形
3.1 度规张量
黎曼流形(Riemannian Manifold)是一个配备了度规张量(Metric Tensor)的光滑流形。度规是一个对称正定的 $(0, 2)$ 型张量:
$$g_p: T_p M \times T_p M \to \mathbb{R}$$
度规告诉我们如何在每一点的切空间中测量长度和角度。对于切向量 $u, v \in T_p M$:
- 长度:$|u| = \sqrt{g_p(u, u)}$
- 角度:$\cos\theta = \frac{g_p(u, v)}{|u||v|}$
在局部坐标 $(x^1, \dots, x^n)$ 中,度规可以写成矩阵形式:
$$g = \begin{pmatrix} g_{11} & g_{12} & \cdots & g_{1n} \ g_{21} & g_{22} & \cdots & g_{2n} \ \vdots & \vdots & \ddots & \vdots \ g_{n1} & g_{n2} & \cdots & g_{nn} \end{pmatrix}$$
其中 $g_{ij} = g\left(\frac{\partial}{\partial x^i}, \frac{\partial}{\partial x^j}\right)$。
3.2 弧长与测地线
有了度规,我们就可以定义曲线的弧长。对于参数化曲线 $\gamma(t) = (x^1(t), \dots, x^n(t))$,$t \in [a, b]$:
$$\text{Length}(\gamma) = \int_a^b \sqrt{\sum_{i,j} g_{ij}(\gamma(t)) \frac{dx^i}{dt} \frac{dx^j}{dt}} , dt$$
测地线(Geodesic)是曲面上"最直的曲线"——它是弧长的极值曲线。测地线满足测地线方程:
$$\frac{d^2x^k}{dt^2} + \sum_{i,j} \Gamma^k_{ij} \frac{dx^i}{dt} \frac{dx^j}{dt} = 0$$
其中 $\Gamma^k_{ij}$ 是克里斯托费尔符号(Christoffel Symbol),由度规及其导数计算得出:
$$\Gamma^k_{ij} = \frac{1}{2} g^{kl} \left( \frac{\partial g_{il}}{\partial x^j} + \frac{\partial g_{jl}}{\partial x^i} - \frac{\partial g_{ij}}{\partial x^l} \right)$$
3.3 曲率
曲率是黎曼流形最重要的几何不变量。黎曼曲率张量(Riemann Curvature Tensor)描述了流形的弯曲程度:
$$R^i_{jkl} = \frac{\partial \Gamma^i_{jl}}{\partial x^k} - \frac{\partial \Gamma^i_{jk}}{\partial x^l} + \Gamma^i_{km}\Gamma^m_{jl} - \Gamma^i_{lm}\Gamma^m_{jk}$$
曲率张量衡量平行移动与路径的依赖程度。在平坦空间(如 $\mathbb{R}^n$)中,沿任何闭合路径平行移动一个向量都会回到原来的值;但在弯曲空间中,平行移动的结果与路径有关。
从黎曼曲率张量,我们可以缩并得到:
- 里奇张量(Ricci Tensor):$R_{jl} = R^i_{jil}$
- 标量曲率(Scalar Curvature):$R = g^{jl} R_{jl}$
3.4 联络与平行移动
在流形上,我们不能用普通的偏导数来比较不同点的向量——因为没有"全局坐标系"。为此,我们引入联络(Connection)的概念。
协变导数(Covariant Derivative)$\nabla$ 是一种"平行移动+微分"的运算。对于向量场 $V = V^i \frac{\partial}{\partial x^i}$:
$$\nabla_j V^i = \frac{\partial V^i}{\partial x^j} + \Gamma^i_{jk} V^k$$
协变导数让我们能够在流形上进行"微分"——这是微积分在弯曲空间中的推广。
平行移动是协变导数的积分。一个向量沿曲线 $\gamma(t)$ 平行移动,如果它的协变导数为零:
$$\frac{DV^i}{dt} = \frac{dV^i}{dt} + \Gamma^i_{jk} \frac{dx^j}{dt} V^k = 0$$
第四章:流形在深度学习中的应用
4.1 流形假设
深度学习成功的关键洞察之一是流形假设(Manifold Hypothesis):
高维数据(如图像、文本、声音)实际上分布在低维流形上。
这个假设是什么意思呢?
考虑一张 $28 \times 28$ 像素的MNIST数字图像。从像素的角度看,这个图像是 $\mathbb{R}^{784}$ 中的一个点。但并非 $\mathbb{R}^{784}$ 中的所有点都是有效的数字图像。实际上,所有"看起来像数字"的图像只占整个空间的很小一部分——它们分布在某个低维流形上。
类似地:
- 人脸图像分布在"人脸流形"上
- 自然语言句子分布在"语义流形"上
- 语音信号分布在"语音流形"上
流形学习的目标是从高维数据中恢复这个低维流形的结构。传统的方法包括:
- 等度量映射(Isomap):用图上的最短路径近似测地距离
- 局部线性嵌入(LLE):保持局部线性结构
- 拉普拉斯特征映射(LE):保持局部邻域关系
4.2 球面Embedding
在深度学习中,我们经常需要将离散对象(如单词、用户、物品)嵌入到连续空间中。传统的嵌入方法使用欧几里得空间 $\mathbb{R}^d$,但越来越多的研究表明,球面空间 $S^{d-1}$ 可能是更好的选择。
为什么是球面?
- 归一化:球面上的向量自动归一,这对于比较相似度很有用
- 曲率:球面的正曲率可能更适合某些类型的数据
- 边界问题:欧几里得空间没有边界,而球面是紧致的
SphereFace 和 FaceNet 等人脸识别方法使用球面嵌入。在球面上,两个向量的内积 $\langle u, v \rangle = \cos\theta$ 直接与它们之间的角度相关。
球面上的分布:
在球面上,我们可以定义各种概率分布,如冯·米塞斯-费舍尔分布(von Mises-Fisher distribution):
$$f(x; \mu, \kappa) = C_d(\kappa) \exp\left(\kappa \mu^\top x\right)$$
其中 $\mu$ 是均值方向,$\kappa$ 是集中度参数。这个分布在方向统计中有广泛应用。
4.3 双曲空间Embedding
如果说球面适合"封闭"的数据,那么双曲空间则适合"树状"或"层次化"的数据。
双曲空间是曲率为 $-1$ 的空间。在双曲几何中:
- 过一点可以作无穷多条平行线
- 三角形的内角和小于180度
- 面积和周长增长比欧几里得空间快得多
双曲空间的一个惊人性质是它能自然地表示层次结构。考虑一棵树:从根节点到叶节点的路径长度随深度指数增长。双曲空间的"指数增长体积"正好匹配这种结构。
庞加莱球模型是最常用的双曲空间模型:
$$\mathbb{B}^d = {x \in \mathbb{R}^d \mid |x| < 1}$$
距离函数为:
$$d(u, v) = \text{arcosh}\left(1 + 2\frac{|u - v|^2}{(1 - |u|^2)(1 - |v|^2)}\right)$$
双曲嵌入的应用:
- 词嵌入:Nickel和Kiela (2017) 展示了双曲空间能更好地捕捉WordNet的层次结构
- 图嵌入:双曲空间能自然地表示图的层次结构
- 少样本学习:双曲空间可能更适合捕捉概念的层次关系
4.4 李群与神经网络
李群(Lie Group)既是群(代数结构)又是流形(几何结构),且群运算在流形上是光滑的。李群在深度学习中有重要应用,特别是在处理对称性和变换时。
特殊正交群 $SO(3)$ 是三维旋转的群:
- 单位元是恒等旋转
- 群运算是旋转的复合
- 它是一个三维流形
在机器人学和计算机视觉中,我们需要处理旋转。一个常见的问题是:如何在神经网络中参数化旋转?
几种常见的方法:
- 旋转矩阵:$3 \times 3$ 正交矩阵,缺点是有冗余(9个参数,只有3个自由度)
- 欧拉角:三个旋转角,缺点是有万向锁问题
- 四元数:四个参数,约束 $|\mathbf{q}| = 1$,这是最常用的方法
- 轴角:三个参数(旋转轴 $\mathbf{u}$ 和角度 $\theta$)
图神经网络中的等变性:
近年来,等变神经网络(Equivariant Neural Networks)成为一个热门研究方向。这类网络在变换群(如旋转、平移)下保持等变性:
$$f(g \cdot x) = g \cdot f(x)$$
代表工作包括:
- E(n)等变图神经网络(EGNN)
- SE(3)-等变Transformer
- 匹兹堡大学的等变消息传递网络
4.5 黎曼流形优化
深度学习中的优化通常使用随机梯度下降(SGD)及其变体。但当参数位于流形上时,普通的欧几里得优化可能不再适用。
黎曼流形优化是研究如何在黎曼流形上进行优化的学科。核心思想是:
- 使用黎曼梯度代替普通梯度
- 使用黎曼度量定义学习率
- 使用黎曼更新来移动点
黎曼梯度是普通梯度关于度规的"提升":
$$\text{grad}M f = g^{-1} \text{grad}{\mathbb{R}^n} f$$
黎曼流形SGD(RMSGD)的更新规则为:
$$x_{t+1} = \text{Exp}_{x_t}(-\eta \cdot \text{grad}_M f(x_t))$$
其中 $\text{Exp}_x(v)$ 是从 $x$ 出发、沿 $v$ 方向的测地线(指数映射)。
应用场景:
- 正交约束优化:当参数矩阵需要保持正交时(如RNN的正交初始化)
- 低秩矩阵恢复:当参数矩阵需要保持低秩时
- 概率分布优化:当参数是概率分布时(如KL散度优化)
第五章:流形在机器人学中的应用
5.1 姿态表示:SO(3)与SE(3)
机器人学的核心问题之一是如何表示和操作三维空间中的姿态(position and orientation)。
位置可以用 $\mathbb{R}^3$ 中的向量表示,这很简单。
方向则复杂得多。描述三维旋转的群是:
- SO(3):特殊正交群,三维旋转,3个自由度
- SE(3):特殊欧几里得群,三维刚体变换(旋转+平移),6个自由度
SO(3)的参数化:
旋转可以用多种方式参数化:
- 旋转矩阵:$R \in \mathbb{R}^{3 \times 3}$,满足 $R^\top R = I$,$\det(R) = 1$
- 轴角:旋转轴 $\mathbf{u} \in S^2$ 和角度 $\theta \in \mathbb{R}$
- 欧拉角:三个顺序旋转角(如XYZ, ZYX等),有12种约定
- 四元数:$\mathbf{q} = (w, x, y, z) \in \mathbb{R}^4$,满足 $|\mathbf{q}| = 1$
四元数是SO(3)的最佳参数化:
四元数相比其他表示有几个优势:
- 无奇点:不像欧拉角有万向锁
- 紧凑:4个参数,而旋转矩阵有9个
- 高效:旋转的复合只需要四元数乘法
- 数值稳定:归一化后保持单位范数
四元数的乘法:
两个四元数 $\mathbf{q}_1 = (w_1, \mathbf{v}_1)$ 和 $\mathbf{q}_2 = (w_2, \mathbf{v}_2)$ 的乘积为:
$$\mathbf{q}_1 \otimes \mathbf{q}_2 = (w_1 w_2 - \mathbf{v}_1 \cdot \mathbf{v}_2, w_1 \mathbf{v}_2 + w_2 \mathbf{v}_1 + \mathbf{v}_1 \times \mathbf{v}_2)$$
旋转的复合对应四元数的乘法。
5.2 运动学与动力学
机器人的运动学描述关节角度与末端执行器位置之间的关系。逆运动学是根据期望末端位置计算所需关节角度的问题。
对于串联机械臂(如UR5),运动学方程为:
$$T_{ee} = T_{base} \cdot A_1(q_1) \cdot A_2(q_2) \cdot \cdots \cdot A_n(q_n)$$
其中 $T_{ee}$ 是末端执行器的变换矩阵,$A_i(q_i)$ 是第 $i$ 个关节的变换矩阵,$q_i$ 是关节角度。
雅可比矩阵描述关节速度与末端速度之间的关系:
$$\dot{x} = J(q) \dot{q}$$
雅可比矩阵在奇点处会奇异——这是机器人学中的一个核心问题。
动力学描述关节力矩与运动之间的关系。欧拉-拉格朗日方程是:
$$M(q) \ddot{q} + C(q, \dot{q}) \dot{q} + G(q) = \tau$$
其中 $M(q)$ 是质量矩阵,$C(q, \dot{q})$ 是科里奥利和离心力项,$G(q)$ 是重力项,$\tau$ 是关节力矩。
所有这些方程都在流形(SO(3)或SE(3))上操作。理解流形的几何对于正确处理机器人问题至关重要。
5.3 运动规划
机器人运动规划的目标是找到一条从起点到目标的无碰撞路径。
配置空间(Configuration Space)是机器人所有可能配置的集合。对于 $n$ 自由度的机器人,配置空间是 $\mathbb{R}^n$(位置关节)或 $T^n$(旋转关节)的子流形。
传统方法:
- 人工势场法:在配置空间中构造势函数,障碍物产生斥力,目标产生引力
- 快速随机树(RRT):通过随机采样构建路径树
- 概率路线图(PRM):预先构建随机路线图
流形上的运动规划:
当配置空间是流形时,运动规划变得更加复杂:
- 边界处理:流形可能没有边界(如SO(3)),需要考虑循环路径
- 曲率影响:流形的曲率影响"最短路径"(测地线)的形状
- 拓扑障碍:流形可能有非平凡的拓扑(如环面的"洞"),这可能导致路径不存在
SE(3)上的运动规划是一个特别重要的问题。SE(3) 的拓扑是 $\mathbb{R}^3 \times SO(3)$,它有一个非平凡的基本群(旋转360度和720度在拓扑上是不同的)。
5.4 状态估计与SLAM
状态估计是机器人确定自身位置和姿态的问题。当机器人移动时,传感器噪声和运动不确定性会累积,因此需要滤波器或优化来融合多个测量。
扩展卡尔曼滤波(EKF)是最经典的方法:
- 预测步骤:使用运动模型预测状态
- 更新步骤:使用传感器测量更新状态
在SE(3)上使用EKF需要小心处理:
- 状态必须在流形上定义
- 协方差矩阵需要适当重参数化
- 雅可比矩阵需要在切空间中计算
同步定位与建图(SLAM)是机器人领域的核心问题。SLAM的目标是同时构建环境地图并定位机器人在其中的位置。
图优化是现代SLAM的主流方法。问题被建模为一个图:
- 节点:机器人的位姿(SE(3)元素)和路标位置($\mathbb{R}^3$元素)
- 边:约束来自运动模型和观测模型
图优化是一个最小二乘问题:
$$\min_X \sum_{(i,j) \in E} |z_{ij} - h_{ij}(X_i, X_j)|^2_{\Sigma_{ij}}$$
其中 $X$ 是所有位姿的集合,$z_{ij}$ 是测量值,$h_{ij}$ 是测量模型,$\Sigma_{ij}$ 是协方差矩阵。
流形上的优化需要使用左扰动或右扰动来参数化SE(3)的切空间。
5.5 强化学习中的流形
机器人强化学习是让机器人通过试错学习控制策略的方法。当状态或动作空间是流形时,我们需要特殊处理。
状态空间的流形结构:
- 姿态:末端执行器的姿态是SE(3)元素
- 关节配置:旋转关节的角度在 $S^1$ 或 $SO(3)$ 上
- 接触状态:接触/分离是离散状态
动作空间的流形结构:
- 关节速度/力矩:在 $\mathbb{R}^n$ 上,通常没问题
- 末端速度:线速度在 $\mathbb{R}^3$ 上,角速度在 $\mathfrak{so}(3)$(SO(3)的李代数)上
- 连续动作:如力/力矩,在 $\mathbb{R}^6$ 上
策略梯度方法:
在流形上使用策略梯度方法时,需要:
- 正确计算流形上的梯度
- 使用适当的参数化(如四元数表示旋转)
- 处理流形的边界或约束
实例:训练机器人开门
- 状态:机器人末端的位置($\mathbb{R}^3$)、姿态(四元数,$S^3$)、关节角度($\mathbb{R}^7$)
- 动作:关节速度($\mathbb{R}^7$)
- 挑战:四元数的约束 $|\mathbf{q}| = 1$ 必须在优化中保持
第六章:实战案例
案例一:人脸识别的流形学习
问题背景:
人脸识别是计算机视觉的核心问题之一。传统方法依赖于手工设计的特征(如HOG、LBP),而深度学习方法则直接从数据中学习特征。
流形视角:
所有人脸图像的集合构成一个流形,称为人脸流形。这个流形:
- 是高维图像空间($\mathbb{R}^{H \times W \times 3}$)的低维嵌入
- 具有非平凡的拓扑结构(可能同胚于某个低维流形)
- 上面的距离对应于人脸之间的"视觉相似度"
DeepFace和FaceNet:
Facebook的DeepFace和Google的FaceNet是两个里程碑式的工作。它们都使用深度卷积神经网络学习人脸嵌入,但关键洞察是:
- 中心损失(Center Loss):让同一个人的所有图像聚集在嵌入空间中的某个中心周围
- 角度边界损失(Angular Margin Loss):在球面上增加类别之间的边界
SphereFace 提出了角度边界损失(Angular Margin Loss):
$$L_{ang} = -\log\left(\frac{e^{|x| \cos(m\theta_{y})}}{e^{|x| \cos(m\theta_{y})} + \sum_{j \neq y} e^{|x| \cos\theta_j}}\right)$$
这个损失函数在球面空间上操作,因为 $\cos\theta$ 直接对应于球面上两个向量的内积。
实践要点:
- 归一化:将特征向量归一化到单位球面
- 角度度量:使用角度距离而非欧几里得距离
- 多尺度:在不同尺度上提取特征,捕捉不同粒度的信息
代码示例:
import torch
import torch.nn as nn
class AngularMarginLoss(nn.Module):
def __init__(self, margin=0.5, scale=30):
super().__init__()
self.margin = margin
self.scale = scale
def forward(self, logits, labels):
# logits: [batch_size, num_classes], 归一化特征的内积
# labels: [batch_size]
one_hot = torch.zeros_like(logits)
one_hot.scatter_(1, labels.view(-1, 1), 1)
# 角度边界
sine = torch.sqrt(1 - logits ** 2)
phi = logits - self.margin
# 添加角度边界
output = (one_hot * phi + (1 - one_hot) * sine) * self.scale
return nn.functional.cross_entropy(output, labels)
案例二:四元数与3D旋转
问题背景:
在机器人学、计算机图形学和计算机视觉中,精确表示和操作3D旋转是一个核心问题。四元数是解决这个问题的最佳工具之一。
为什么是四元数?
考虑以下几种旋转表示的对比:
| 表示 | 参数数量 | 奇点 | 数值稳定性 | 复合效率 |
|---|---|---|---|---|
| 旋转矩阵 | 9 | 无 | 中等 | 低 |
| 欧拉角 | 3 | 有 | 低 | 中等 |
| 轴角 | 4 | 无 | 中等 | 中等 |
| 四元数 | 4 | 无 | 高 | 高 |
四元数的基础知识:
一个四元数 $\mathbf{q} = w + xi + yj + zk$ 可以写成 $\mathbf{q} = (w, \mathbf{v})$,其中 $\mathbf{v} = (x, y, z)$ 是向量部分。
四元数表示旋转的规则:
- 单位四元数:只有单位四元数($|\mathbf{q}| = 1$)表示有效的旋转
- 旋转角度:$\theta = 2 \arccos(w)$
- 旋转轴:$\mathbf{u} = \mathbf{v} / \sin(\theta/2)$
绕任意轴旋转:
要将一个点 $\mathbf{p}$ 绕轴 $\mathbf{u}$ 旋转角度 $\theta$:
- 将点写成纯四元数:$\mathbf{p} = (0, \mathbf{p})$
- 构造旋转四元数:$\mathbf{q} = (\cos(\theta/2), \sin(\theta/2)\mathbf{u})$
- 执行旋转:$\mathbf{p}’ = \mathbf{q} \mathbf{p} \mathbf{q}^{-1}$
- 提取向量部分
四元数的SLERP:
在动画和路径规划中,我们经常需要在两个旋转之间插值。球面线性插值(SLERP)是专门为四元数设计的插值方法:
$$\text{SLERP}(\mathbf{q}_0, \mathbf{q}_1, t) = \frac{\sin((1-t)\Omega)}{\sin\Omega}\mathbf{q}_0 + \frac{\sin(t\Omega)}{\sin\Omega}\mathbf{q}_1$$
其中 $\Omega$ 是 $\mathbf{q}_0$ 和 $\mathbf{q}_1$ 之间的角度,$t \in [0, 1]$ 是插值参数。
SLERP保证:
- 角速度恒定(如果 $t$ 与时间成正比)
- 路径是最短测地线
- 不会产生"万向锁"问题
代码示例:
import numpy as np
def quaternion_to_rotation_matrix(q):
"""将四元数转换为旋转矩阵"""
w, x, y, z = q
# 归一化
q = q / np.linalg.norm(q)
w, x, y, z = q
R = np.array([
[1 - 2*y**2 - 2*z**2, 2*x*y - 2*w*z, 2*x*z + 2*w*y],
[2*x*y + 2*w*z, 1 - 2*x**2 - 2*z**2, 2*y*z - 2*w*x],
[2*x*z - 2*w*y, 2*y*z + 2*w*x, 1 - 2*x**2 - 2*y**2]
])
return R
def slerp(q0, q1, t):
"""球面线性插值"""
# 确保四元数在同一个半球
if np.dot(q0, q1) < 0:
q1 = -q1
dot = np.dot(q0, q1)
dot = np.clip(dot, -1, 1) # 避免数值误差
omega = np.arccos(dot)
sin_omega = np.sin(omega)
if sin_omega < 1e-6:
return (1-t) * q0 + t * q1
a = np.sin((1-t) * omega) / sin_omega
b = np.sin(t * omega) / sin_omega
return a * q0 + b * q1
案例三:自动驾驶中的状态估计
问题背景:
自动驾驶汽车需要精确估计自己的位置和姿态(自车状态)。这包括:
- 位置:$(x, y, z)$ 在某个世界坐标系中
- 姿态:绕三个轴的旋转(横滚、俯仰、偏航)
- 速度:线速度和角速度
传感器融合:
自动驾驶使用多种传感器:
- GPS:提供全局位置,但精度有限(几米到几十米)
- 惯性测量单元(IMU):提供高频加速度和角速度,但会漂移
- 轮式里程计:从轮子转速估计位移,但有打滑问题
- 激光雷达/相机:提供局部环境信息,可以用于匹配
扩展卡尔曼滤波:
EKF是融合多传感器测量的经典方法。在自动驾驶中,状态通常定义为:
$$\mathbf{x} = [x, y, z, \phi, \theta, \psi, v_x, v_y, v_z, \omega_x, \omega_y, \omega_z]^\top$$
其中 $\phi, \theta, \psi$ 是欧拉角,$v$ 是线速度,$\omega$ 是角速度。
流形上的EKF:
关键问题是如何处理姿态的流形结构。一种方法是局部切空间滤波:
- 在某个参考姿态 $\bar{R}$ 处建立切空间
- 在切空间中执行标准的卡尔曼滤波
- 使用指数映射将结果映射回流形
另一种方法是无迹卡尔曼滤波(UKF),它不需要显式计算雅可比矩阵。
误差状态卡尔曼滤波:
在机器人学中,误差状态(Error State)形式更为常见:
$$\mathbf{x}{true} = \mathbf{x}{nom} \oplus \delta\mathbf{x}$$
其中 $\mathbf{x}_{nom}$ 是标称状态(在流形上),$\delta\mathbf{x}$ 是误差状态(在切空间中)。
这种形式的优势:
- 误差状态是小的,可以用高斯分布近似
- 避免了大角度旋转的三角函数计算
- 数值更稳定
代码示例:
import numpy as np
class ErrorStateEKF:
def __init__(self):
# 状态维度: 位置(3) + 姿态(3) + 速度(3) + 偏置(6) = 15
self.dim = 15
# 状态: [pos(3), rotvec(3), vel(3), accel_bias(3), gyro_bias(3)]
self.state = np.zeros(self.dim)
self.cov = np.eye(self.dim) * 0.1
# 噪声参数
self.Q = np.eye(12) * 0.01 # 过程噪声
def predict(self, dt, accel, gyro):
"""预测步骤"""
# 提取状态
pos = self.state[:3]
rotvec = self.state[3:6] # 旋转向量
vel = self.state[6:9]
accel_bias = self.state[9:12]
gyro_bias = self.state[12:15]
# 校正测量
accel_corrected = accel - accel_bias
gyro_corrected = gyro - gyro_bias
# 更新状态
# 位置: pos += vel * dt
pos = pos + vel * dt
# 速度: vel += accel_corrected * dt (在世界坐标系)
# 需要将加速度从体坐标系转换到世界坐标系
C_bn = rotation_vector_to_matrix(rotvec) # 体到世界的旋转
vel = vel + C_bn @ accel_corrected * dt
# 姿态: rotvec += gyro_corrected * dt
rotvec = rotvec + gyro_corrected * dt
# 偏置随机游走
# (简化处理,不更新偏置)
# 更新协方差
# ... (雅可比矩阵和卡尔曼增益计算)
self.state[:3] = pos
self.state[3:6] = rotvec
self.state[6:9] = vel
def update(self, measurement, H, R):
"""更新步骤"""
# 计算残差
z_pred = H @ self.state
y = measurement - z_pred
# 卡尔曼增益
S = H @ self.cov @ H.T + R
K = self.cov @ H.T @ np.linalg.inv(S)
# 更新状态
self.state = self.state + K @ y
# 更新协方差 (Joseph form for numerical stability)
I_KH = np.eye(self.dim) - K @ H
self.cov = I_KH @ self.cov @ I_KH.T + K @ R @ K.T
def rotation_vector_to_matrix(rotvec):
"""将旋转向量转换为旋转矩阵"""
theta = np.linalg.norm(rotvec)
if theta < 1e-8:
return np.eye(3)
k = rotvec / theta
K = np.array([
[0, -k[2], k[1]],
[k[2], 0, -k[0]],
[-k[1], k[0], 0]
])
# Rodrigues公式
R = np.eye(3) + np.sin(theta) * K + (1 - np.cos(theta)) * (K @ K)
return R
案例四:强化学习中的黎曼流形优化
问题背景:
在强化学习中,策略梯度方法需要优化高维参数空间。当参数空间具有流形结构时(如正交矩阵、低秩矩阵),黎曼流形优化可以显著提高性能和稳定性。
实例:正交RNN
在循环神经网络中,隐藏状态的演化是:
$$\mathbf{h}t = \tanh(W \mathbf{h}{t-1} + U \mathbf{x}_t)$$
如果权重矩阵 $W$ 是正交的,那么梯度会沿着隐藏状态的方向传播而不会消失或爆炸——这解决了RNN的梯度消失问题。
流形约束:
$W$ 需要是正交矩阵,即 $W^\top W = I$。这意味着 $W$ 位于正交群 $O(n)$ 上。
黎曼梯度下降:
在正交群上进行优化的步骤:
黎曼梯度:计算普通梯度 $\nabla f$,然后投影到切空间 $$\text{grad}_{O(n)} f = \nabla f - \nabla f \cdot W^\top W + \nabla f \cdot W^\top W$$(简化) 更准确地说:$\text{grad} = \nabla f \cdot W^\top W - W^\top \cdot \nabla f \cdot W$ 的对称部分
指数映射:从切空间映射回流形 $$\text{Exp}_W(V) = W \cdot \exp(V)$$ 其中 $\exp$ 是矩阵指数,$V$ 是切空间中的反对称矩阵
** retraction**:指数映射的近似,计算更高效 $$\text{Retr}_W(V) = \text{qf}(W + V)$$ 其中 $\text{qf}$ 是正交化(QR分解)
代码示例:
import torch
import torch.nn as nn
import torch.nn.functional as F
class OrthogonalRNN(nn.Module):
def __init__(self, input_size, hidden_size):
super().__init__()
self.hidden_size = hidden_size
# 权重矩阵,初始化为正交矩阵
self.W = nn.Parameter(torch.randn(hidden_size, hidden_size))
nn.init.orthogonal_(self.W)
self.U = nn.Parameter(torch.randn(hidden_size, input_size))
def forward(self, x, h=None):
if h is None:
h = torch.zeros(x.size(0), self.hidden_size, device=x.device)
output = []
for t in range(x.size(1)):
h = F.tanh(self.W @ h.unsqueeze(2) + self.U @ x[:, t].unsqueeze(2))
output.append(h.squeeze(2))
return torch.stack(output, dim=1), h
def orthogonalize(self):
"""将权重矩阵正交化"""
with torch.no_grad():
W = self.W.data
Q, R = torch.linalg.qr(W)
# 调整符号以保持与原矩阵一致
d = torch.diag(torch.sign(torch.diag(R)))
self.W.data = Q @ d
def riemannian_gradient(W, grad):
"""计算正交流形上的黎曼梯度"""
# 梯度投影到切空间
# 对于正交群,切空间是反对称矩阵
# grad_O(n)(f) = grad - grad @ W^T @ W + W^T @ grad @ W 的对称部分
# 简化版本
G = grad - W @ grad.T @ W
G = (G + G.T) / 2 # 对称化
return G
def riemannian_step(W, grad, lr):
"""黎曼梯度下降一步"""
G = riemannian_gradient(W, grad)
# 构建反对称矩阵
K = (G - G.T) / 2
# 使用 retraction 而非指数映射(更高效)
# Retr_W(V) = qf(W + V) where qf is QR decomposition
with torch.no_grad():
W_new = W - lr * K
Q, R = torch.linalg.qr(W_new)
d = torch.diag(torch.sign(torch.diag(R)))
W.copy_(Q @ d)
return W
第七章:现代流形学习的深入探讨
7.1 局部线性嵌入(LLE)
核心思想:
LLE假设数据在局部是线性的——每个数据点都可以由其邻居的线性组合表示。LLE保持这种局部线性关系,同时将数据嵌入到低维空间。
算法步骤:
- 邻居选择:对于每个点 $x_i$,找到 $k$ 个最近邻 ${x_j}$
- 局部重建权值:求解最小二乘问题: $$\min_{w_{ij}} |x_i - \sum_j w_{ij} x_j|^2$$ 约束:$\sum_j w_{ij} = 1$(归一化)
- 低维嵌入:在低维空间 $y_i$ 中保持相同的权值: $$\min_{y_i} |y_i - \sum_j w_{ij} y_j|^2$$
数学性质:
- LLE的解由稀疏特征值问题给出
- 保持数据的局部邻域结构
- 对噪声和异常值敏感
7.2 等度量映射(Isomap)
核心思想:
Isomap是流形学习的里程碑工作,它用图上的最短路径近似流形上的测地距离,然后使用多维缩放(MDS)将数据嵌入到低维空间。
算法步骤:
- 邻居图构建:连接每个点到其 $k$ 个最近邻
- 测地距离估计:对于每对点,计算图上的最短路径距离 $d_G(i, j)$
- 经典MDS:将距离矩阵嵌入到低维空间
数学性质:
- Isomap理论上可以恢复等距嵌入(如果噪声足够小)
- 对"孔洞"和非均匀采样敏感
- 计算复杂度较高(需要计算所有对的最短路径)
7.3 拉普拉斯特征映射(LE)
核心思想:
LE假设相似的点在嵌入空间中应该保持相似。它最小化邻居之间权重的拉普拉斯算子。
算法步骤:
- 邻居图构建:同上
- 权重计算:$W_{ij} = \exp(-|x_i - x_j|^2 / t)$ 或二值化
- 特征分解:求解广义特征值问题: $$L y = \lambda D y$$ 其中 $L = D - W$ 是拉普拉斯矩阵,$D$ 是度矩阵
数学性质:
- LE与图的拉普拉斯算子的谱相关
- 保持局部结构,但不保证全局结构
- 对参数选择(如邻居数 $k$ 和带宽 $t$)敏感
7.4 t-分布随机邻域嵌入(t-SNE)
核心思想:
t-SNE是可视化高维数据的强大工具。它使用t-分布来测量低维空间中的相似度,解决了"拥挤问题"。
算法步骤:
- 高维相似度:使用高斯核: $$p_{j|i} = \frac{\exp(-|x_i - x_j|^2 / 2\sigma^2)}{\sum_{k \neq i} \exp(-|x_i - x_k|^2 / 2\sigma^2)}$$
- 低维相似度:使用t-分布(自由度为1): $$q_{ij} = \frac{(1 + |y_i - y_j|^2)^{-1}}{\sum_{k \neq l}(1 + |y_k - y_l|^2)^{-1}}$$
- KL散度最小化: $$C = KL(P | Q) = \sum_{i \neq j} p_{ij} \log\frac{p_{ij}}{q_{ij}}$$
数学性质:
- t-SNE的解通过梯度下降获得
- 不保持全局结构,只保持局部结构
- 随机性:多次运行可能产生不同结果
结语:流形的哲学
从几何到智能
回顾我们走过的旅程,从高斯和黎曼的几何革命,到深度学习和机器人学的前沿应用,我们看到了数学概念如何塑造现代科技。
流形的本质洞察是:复杂系统通常可以分解为局部简单的部分,这些部分通过某种"粘合"方式组装成复杂的整体。
这种洞察无处不在:
- 深度学习:神经网络通过叠加简单的非线性变换来学习复杂的函数
- 机器人学:复杂的机器人运动可以分解为关节空间的简单旋转和平移
- 计算机视觉:复杂的视觉场景可以分解为局部特征的组合
思想的进化
高斯不会想到他关于曲面曲率的工作会影响到自动驾驶汽车;黎曼不会想到他的几何会成为机器学习的理论基础。
这就是数学的力量:抽象的概念往往会在意想不到的地方找到应用。
给读者的话
如果你读到这里,我希望你已经:
- 理解了流形的基本概念:从拓扑空间到黎曼流形
- 看到了流形的应用:从深度学习到机器人学
- 学到了实战技能:从四元数计算到流形优化
流形是一个庞大的领域,这篇文章只是冰山一角。如果你有兴趣深入学习,我推荐:
- 微分几何:Do Carmo的《Differential Geometry of Curves and Surfaces》
- 黎曼几何:Lee的《Riemannian Manifolds: An Introduction to Curvature》
- 流形学习:Burges的《Dimension Reduction: A Guided Tour》
- 李群与机器:Hall的《Lie Groups, Lie Algebras, and Representations》
最后,让我用黎曼1854年演讲的结语来结束这篇文章:
“几何命题的真实性是不容置疑的,只要它们涉及可感知的关系;但它们的意义是无穷的,如果我们假设这些命题的真实性扩展到可感知范围之外——扩展到无限大的领域……这正是几何与哲学的联系所在。”
附录:重要公式汇总
流形基础
坐标变换: $$\frac{\partial}{\partial x^i} = \sum_j \frac{\partial \bar{x}^j}{\partial x^i} \frac{\partial}{\partial \bar{x}^j}$$
黎曼几何
度规张量: $$g_{ij} = \left\langle \frac{\partial}{\partial x^i}, \frac{\partial}{\partial x^j} \right\rangle$$
克里斯托费尔符号: $$\Gamma^k_{ij} = \frac{1}{2} g^{kl} \left( \frac{\partial g_{il}}{\partial x^j} + \frac{\partial g_{jl}}{\partial x^i} - \frac{\partial g_{ij}}{\partial x^l} \right)$$
测地线方程: $$\frac{d^2x^k}{dt^2} + \Gamma^k_{ij} \frac{dx^i}{dt} \frac{dx^j}{dt} = 0$$
黎曼曲率张量: $$R^i_{jkl} = \partial_k \Gamma^i_{jl} - \partial_l \Gamma^i_{jk} + \Gamma^i_{km}\Gamma^m_{jl} - \Gamma^i_{lm}\Gamma^m_{jk}$$
四元数
乘法: $$(w_1, \mathbf{v}_1) \otimes (w_2, \mathbf{v}_2) = (w_1 w_2 - \mathbf{v}_1 \cdot \mathbf{v}_2, w_1 \mathbf{v}_2 + w_2 \mathbf{v}_1 + \mathbf{v}_1 \times \mathbf{v}_2)$$
SLERP: $$\text{SLERP}(\mathbf{q}_0, \mathbf{q}_1, t) = \frac{\sin((1-t)\Omega)}{\sin\Omega}\mathbf{q}_0 + \frac{\sin(t\Omega)}{\sin\Omega}\mathbf{q}_1$$
流形优化
黎曼梯度: $$\text{grad}M f = g^{-1} \text{grad}{\mathbb{R}^n} f$$
指数映射: $$\text{Exp}_p(v) = \gamma_v(1)$$ 其中 $\gamma_v$ 是以 $v$ 为初始速度的测地线
本文旨在为有一定数学基础的读者提供流形的入门导引。更深入的学习建议参考专业教材。
