跳转至

基与对偶

一句话总结:基是给向量空间搭坐标系的最小骨架,对偶基则是配套的一组"尺子"; \(P\) 与 \(P^{-1}\) 让两组基彼此翻译,撑起 PCA 与注意力等机器学习变换。

基定义了向量空间的坐标系,对偶则揭示线性函数如何作用于向量。本文覆盖线性无关、张成集、基变换、对偶空间和余向量 (covector) —— 这些概念是机器学习中主成分分析 (Principal Component Analysis, PCA)、特征变换和注意力查询背后的骨架。

  • 我们已经看到,向量活在具有一定维数的空间里。但究竟是什么定义了这些维数?这就是基向量 (basis vectors) 登场的地方。

  • 基 (basis) 是一组向量,通过缩放和相加 (线性组合) 就能搭出空间里的每一个向量,而且没有冗余。它们是空间的构造积木。

  • 一组基必须满足两个条件:

    • 线性无关 (Linearly independent):任何一个基向量都不能由其他基向量搭出来。每一个都贡献一个真正新的方向。

    • 张成 (Spanning):空间里的每一个向量都能表示为基向量的组合。一个不漏。

  • 一组基里向量的数量等于空间的维度 (dimension)。在 \(\mathbb{R}^2\) 里你需要 2 个,在 \(\mathbb{R}^3\) 里你需要 3 个,依此类推。

  • 最自然的基是标准基 (standard basis),也就是沿每条坐标轴的单位向量:

    • 在 \(\mathbb{R}^2\) 里:\(\hat{\mathbf{i}} = (1, 0)\) 和 \(\hat{\mathbf{j}} = (0, 1)\)
    • 在 \(\mathbb{R}^3\) 里:\(\hat{\mathbf{i}} = (1, 0, 0)\)、\(\hat{\mathbf{j}} = (0, 1, 0)\)、\(\hat{\mathbf{k}} = (0, 0, 1)\)
  • 任何向量都不过是这些基向量的加权和。向量 \((3, 2)\) 其实就是 \(3\hat{\mathbf{i}} + 2\hat{\mathbf{j}}\)。权重 (3 和 2) 就是这个向量在该基下的坐标 (coordinates)。

  • 但标准基并不是唯一有效的基。在 \(\mathbb{R}^2\) 里,向量 \((1, 1)\) 和 \((-1, 1)\) 也构成一组基。它们线性无关,能够触达平面上的任意一点。同一个向量在这组新基下会有不同的坐标,仅此而已。

  • 基变换 (change of basis) 就是用不同的基重新表达同一个向量。向量并没有动,我们只是从另一个视角来描述它。

  • 具体做法是乘以一个基变换矩阵 (change of basis matrix) \(P\),\(P\) 的列就是用旧坐标写出来的新基向量。要变回去,就乘以 \(P^{-1}\)。

  • 把它想象成两位朋友给同一家咖啡馆指路。你按街道走:\((3, 2)\) 意思是"往东 3 个街区,往北 2 个街区"。你的朋友按对角线走:她的方向是 \(\mathbf{b}_1 = (1, 1)\) (东北) 和 \(\mathbf{b}_2 = (-1, 1)\) (西北),也就是刚才那组新基。同一家咖啡馆,两套描述如何抵达的语言。

  • 你朋友说咖啡馆在 \((2.5, -0.5)\):""沿我的东北对角线走 2.5 步,然后沿我的西北对角线倒着走半步"。要知道这句话翻成你的街道语言是什么,你只要照着她的配方来一遍:

\[2.5 \begin{bmatrix} 1 \\ 1 \end{bmatrix} - 0.5 \begin{bmatrix} -1 \\ 1 \end{bmatrix} = \begin{bmatrix} 3 \\ 2 \end{bmatrix}\]
  • 这就是你叫做 \((3, 2)\) 的同一家咖啡馆!

  • "照配方走一遍"这个动作恰恰就是乘以 \(P\) 做的事。把朋友的基向量按列堆叠起来,再乘一个装着她坐标的向量,就是把第一列取 2.5 份、第二列取 -0.5 份,还是那个配方,只不过写得更紧凑:

\[P = \begin{bmatrix} 1 & -1 \\ 1 & 1 \end{bmatrix}, \qquad P \begin{bmatrix} 2.5 \\ -0.5 \end{bmatrix} = \begin{bmatrix} 3 \\ 2 \end{bmatrix}\]
  • 反过来翻译,把你的 \((3, 2)\) 翻成朋友的语言,就意味着把配方倒回去,而把 \(P\) 倒回去正是 \(P^{-1}\) 干的活:
\[P^{-1} \begin{bmatrix} 3 \\ 2 \end{bmatrix} = \begin{bmatrix} 2.5 \\ -0.5 \end{bmatrix}\]
  • 什么都没动。\((3, 2)\) 和 \((2.5, -0.5)\) 是同一个点的两种描述,\(P\) 就是在这两种描述之间做翻译的字典。

  • 在机器学习里,基变换频繁出现。例如 PCA 会找到一组新基 (主成分),让数据更容易理解——坐标轴会对齐到方差最大的方向。

  • 接下来这组概念会比较抽象,现在乍看不太好抓住,要等到后面章节里我们真的用上它们才会变得直观,所以扶稳了,抱歉。

  • 好,这里其实藏着一个更深的想法。当我们写 \(\mathbf{v} = (3, 2)\) 时,坐标 3 和 2 其实是"沿每个基方向去测量" \(\mathbf{v}\) 的结果。第一个坐标在问"\(\mathbf{v}\) 里有多少 \(\hat{\mathbf{i}}\)?",第二个在问"有多少 \(\hat{\mathbf{j}}\)?"

  • 在咖啡馆的故事里,这些测量就是朋友的两个问题:"你沿我的东北对角线走了多远?"和"沿我的西北对角线走了多远?"每一组基都自带一组问题,每个方向一个。

  • 每一个问题都是一个线性泛函 (linear functional):接收一个向量、返回一个数字 (读数) 的函数。

  • 线性这个词是说,这个泛函尊重向量空间的两种运算。测量两个向量之和,得到的是各自读数之和;把一个向量翻倍,读数也翻倍:

\[f(\mathbf{u} + \mathbf{v}) = f(\mathbf{u}) + f(\mathbf{v}), \qquad f(c\mathbf{v}) = c\,f(\mathbf{v})\]
  • 换句话说,线性泛函是诚实的尺子。向量是被测量的对象,线性泛函是测量它们的尺子,而所有可能尺子的集合就构成了对偶空间 (dual space) \(V^\ast\)。

  • 对每一组基 \(\{\mathbf{e}_1, \mathbf{e}_2, \ldots, \mathbf{e}_n\}\),都有一套配套的尺子——对偶基 (dual basis) \(\{\mathbf{e}_1^\ast, \mathbf{e}_2^\ast, \ldots, \mathbf{e}_n^\ast\}\),其中 \(\mathbf{e}_i^\ast\) 只回答一个问题:"有多少步 \(\mathbf{e}_i\)?"。一把校准良好的尺子在它对应的那个基向量上读数为 1,对其他所有基向量彻底无视——这一点可以用克罗内克 δ (Kronecker delta) \(\delta_{ij}\) 紧凑地写出来:

\[ \mathbf{e}_i^\ast(\mathbf{e}_j) = \delta_{ij} = \begin{cases} 1 & \text{if } i = j \\ 0 & \text{if } i \neq j \end{cases} \]
  • 一把尺子只需要这么一条小小的校准规则就够了,因为线性会帮它把剩下的事做完。看看 \(\mathbf{e}_1^\ast\) 读取 \(\mathbf{v} = 3\mathbf{e}_1 + 2\mathbf{e}_2\) 的第一个坐标:
\[\mathbf{e}_1^\ast(3\mathbf{e}_1 + 2\mathbf{e}_2) = 3\,\mathbf{e}_1^\ast(\mathbf{e}_1) + 2\,\mathbf{e}_1^\ast(\mathbf{e}_2) = 3 \cdot 1 + 2 \cdot 0 = 3\]
  • 这把尺子无视所有除它自己以外的方向,只报告一个坐标。坐标就是对偶基读数。

  • 那么一把尺子具体长什么样?在 \(\mathbb{R}^n\) 里,每个线性泛函都不过是"一行数字,用点积作用上去"。而对于朋友那组基,其实我们已经不知不觉造出了它的尺子:把 \((3, 2)\) 翻译成朋友的语言就是乘 \(P^{-1}\),\(P^{-1}\) 的每一行产出一个坐标。\(P^{-1}\) 的行就是对偶基:

\[P^{-1} = \frac{1}{2}\begin{bmatrix} 1 & 1 \\ -1 & 1 \end{bmatrix} \quad\Rightarrow\quad \mathbf{b}_1^\ast = (0.5,\ 0.5), \qquad \mathbf{b}_2^\ast = (-0.5,\ 0.5)\]
  • 拿咖啡馆之行来验证一下:\(\mathbf{b}_1^\ast \cdot (3, 2) = 0.5 \cdot 3 + 0.5 \cdot 2 = 2.5\),正好就是朋友的第一个坐标。本文的两半合起来其实是同一件事:基变换换掉了构造积木,而对偶基是配套的一组尺子,用来读出新坐标。

  • 校准规则也一直大大方方地躺在那儿:\(P^{-1}P = I\) 说的正是尺子 \(i\) 在基向量 \(i\) 上读 1,在其他基向量上读 0。单位矩阵不过是把克罗内克 δ 写成表格的样子。

  • 一点告诫。人很容易猜想 \(\mathbf{b}_1\) 对应的尺子就是 \(\mathbf{b}_1\) 自己,也就是直接和 \((1, 1)\) 做点积。但 \((1, 1) \cdot (3, 2) = 5\),是真正坐标 2.5 的两倍。用基向量自己做点积能读出对应坐标,只在基是单位正交 (orthonormal) (互相垂直、每个长度为 1) 的时候成立,比如标准基。这就是为什么 \(\mathbf{e}_1^\ast\) 恰好长得和 \(\mathbf{e}_1\) 一模一样。对其他任何基,尺子都躲在 \(P^{-1}\) 的行里。

  • 这也解释了点积的双重身份。每一个向量 \(\mathbf{u}\) 都悄悄定义了一把尺子 (用 \(\mathbf{u} \cdot \mathbf{v}\) 去测量 \(\mathbf{v}\)),而每一把尺子也不过是和某个向量做点积。在有限维里,对偶空间本质上是原空间的镜像。

  • 对偶现在也许显得抽象,但它其实撑起了许多实用的想法:坐标是对偶基的求值、点积是对偶配对,而神经网络里的注意力这类变换,本质上是让一组向量"查询"另一组,这就是对偶在运作。

编程练习 (使用 CoLab 或 notebook)

  1. 用两组不同的基表达同一个向量,并验证它们代表同一个点。试着自己造一组基,看看向量在其中的坐标是什么。

    import jax.numpy as jnp
    
    v = jnp.array([3.0, 2.0])
    
    # 标准基:坐标就是分量本身
    print(f"Standard basis coords: {v}")
    
    # 新基:(1,1) 和 (-1,1)
    P = jnp.array([[1.0, -1.0],
                   [1.0,  1.0]])
    new_coords = jnp.linalg.solve(P, v)
    print(f"New basis coords: {new_coords}")
    
    # 验证:用新坐标重构
    reconstructed = new_coords[0] * P[:, 0] + new_coords[1] * P[:, 1]
    print(f"Reconstructed: {reconstructed}")
    

  2. 为练习 1 中朋友的基构造对偶基 (P⁻¹ 的行),并验证每一把尺子恰好读出一个坐标。然后看看为什么用基向量自身做点积只对单位正交基才成立。

    import jax.numpy as jnp
    
    v = jnp.array([3.0, 2.0])
    
    # 朋友的基 (1,1) 和 (-1,1),按列堆叠
    P = jnp.array([[1.0, -1.0],
                   [1.0,  1.0]])
    
    # 对偶基:P^{-1} 的行
    P_inv = jnp.linalg.inv(P)
    b1_star, b2_star = P_inv[0], P_inv[1]
    print(f"b1* = {b1_star}, b2* = {b2_star}")
    
    # 每把尺子读出朋友基下的一个坐标 (与练习 1 一致!)
    print(f"b1*(v) = {jnp.dot(b1_star, v)}")  # 2.5
    print(f"b2*(v) = {jnp.dot(b2_star, v)}")  # -0.5
    
    # 校准:在自己的基向量上为 1,在另一个上为 0
    print(f"b1*(b1) = {jnp.dot(b1_star, P[:, 0])}, b1*(b2) = {jnp.dot(b1_star, P[:, 1])}")
    
    # 陷阱:直接和 b1 做点积得不到坐标
    print(f"b1 . v = {jnp.dot(P[:, 0], v)}  (5.0, not 2.5 -- b1 is not orthonormal)")
    
    # 标准基是单位正交的,所以那里这种捷径成立
    e1 = jnp.array([1.0, 0.0])
    print(f"e1 . v = {jnp.dot(e1, v)}  (3.0, the first standard coordinate)")
    


📌 本节要点

  • 基 (basis):一组线性无关且能张成整个空间的向量,数量等于空间的维度。
  • 坐标与基变换:同一向量在不同基下有不同坐标,换基矩阵 \(P\) 的列是新基向量,\(P^{-1}\) 负责反向翻译。
  • 线性泛函:从向量到实数的线性函数,满足加法与数乘保持不变,是测量向量的"诚实尺子".
  • 对偶空间 \(V^\ast\):所有线性泛函组成的空间,是原空间在有限维下的镜像。
  • 对偶基与 Kronecker δ:对偶基 \(\{\mathbf{e}_i^\ast\}\) 由 \(\mathbf{e}_i^\ast(\mathbf{e}_j) = \delta_{ij}\) 校准,恰好读出对应坐标。
  • \(P^{-1}\) 的行就是对偶基:换基矩阵的逆的每一行就是新基对应的尺子,单位矩阵 \(P^{-1}P = I\) 正是 Kronecker δ 的表格化。
  • 正交陷阱:用基向量自身做点积读坐标只在单位正交基下成立,否则必须用 \(P^{-1}\) 的行。