跳转至

# 基与对偶性

基定义了向量空间的坐标系，而对偶性揭示了线性函数如何作用于向量。本文涵盖线性无关性、生成集、基变换、对偶空间和余向量，这些概念支撑了 ML 中的 PCA、特征变换和注意力查询。

- 我们已经看到向量存在于具有一定维度数的空间中。但什么定义了这些维度？这就是基向量发挥作用的地方。

- 基是一组向量，可以通过缩放和相加（线性组合）构建空间中的每个其他向量，且没有冗余。它们是空间的构建块。

- 基必须满足两个条件：

  - 线性无关：没有基向量能从其他基向量构造出来。每个都贡献了一个真正的新方向。

  - 生成性：空间中的每个向量都可以表示为基向量的组合。没有任何遗漏。

- 基中的向量数量等于空间的维度。在 \(\mathbb{R}^2\) 中你需要 2 个，在 \(\mathbb{R}^3\) 中你需要 3 个，依此类推。

- 最自然的基是标准基，即沿每个轴的单位向量：

  - 在 \(\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）是该基下向量的坐标。

- 但标准基并不是唯一有效的基。在 \(\mathbb{R}^2\) 中，向量 \((1, 1)\) 和 \((-1, 1)\) 也构成基。它们线性无关，并且可以到达平面上的任何点。同一个向量在这个新基下只是有不同的坐标。

- 基变换使用不同的构建块重新表达同一个向量。向量没有移动，我们只是从不同的角度描述它。

- 这是通过乘以一个基变换矩阵 \(P\) 来完成的，其列是用旧坐标表示的新基向量。要变回去，乘以 \(P^{-1}\)。

- 在 ML 中，基变换经常出现。例如，PCA 找到一个新基（主成分），在该基下数据更容易理解，坐标轴与最大变化方向对齐。

- 现在，这里隐藏着一个更深层的想法。当我们写 \(\mathbf{v} = (3, 2)\) 时，坐标 3 和 2 实际上是沿着每个基方向"测量" \(\mathbf{v}\) 的结果。第一个坐标问"\(\hat{\mathbf{i}}\) 在 \(\mathbf{v}\) 中有多少？"，第二个问"\(\hat{\mathbf{j}}\) 呢？"

- 这些测量中的每一个都是一个线性泛函，一个接受向量并返回单个标量的函数。所有这样的线性泛函的集合构成了对偶空间 \(V^\ast\)。

- 这样想：向量是被测对象，线性泛函是测量它们的标尺。对偶空间是所有可能的标尺的集合。

- 对于每个基 \(\{\mathbf{e}_1, \mathbf{e}_2, \ldots, \mathbf{e}_n\}\)，存在一个对应的对偶基 \(\{\mathbf{e}_1^\ast, \mathbf{e}_2^\ast, \ldots, \mathbf{e}_n^\ast\}\)。每个对偶基向量恰好提取一个坐标：

\[ \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{e}_1\) 时返回 1，对其它所有向量返回 0。它完美地隔离了第一个坐标。

- 点积连接了这两个世界。当你计算 \(\mathbf{u} \cdot \mathbf{v}\) 时，你可以把其中一个向量看作"标尺"在测量另一个向量。点积 \(\mathbf{u} \cdot \mathbf{v}\) 等同于将由 \(\mathbf{u}\) 定义的线性泛函应用于向量 \(\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. 验证对偶基性质：每个对偶基向量恰好提取一个坐标，对其他向量返回零。

       import jax.numpy as jnp

       # R3 中的标准基
       e1 = jnp.array([1.0, 0.0, 0.0])
       e2 = jnp.array([0.0, 1.0, 0.0])
       e3 = jnp.array([0.0, 0.0, 1.0])

       v = jnp.array([5.0, 3.0, 7.0])

       # 每个点积提取一个坐标
       print(f"e1 · v = {jnp.dot(e1, v)}")
       print(f"e2 · v = {jnp.dot(e2, v)}")
       print(f"e3 · v = {jnp.dot(e3, v)}")