feat: 完整中文翻译 maths-cs-ai-compendium(数学·计算机科学·AI 知识大全)
翻译自英文原版 maths-cs-ai-compendium,共 20 章全部完成。 第01章 向量 | 第02章 矩阵 | 第03章 微积分 第04章 统计学 | 第05章 概率论 | 第06章 机器学习 第07章 计算语言学 | 第08章 计算机视觉 | 第09章 音频与语音 第10章 多模态学习 | 第11章 自主系统 | 第12章 图神经网络 第13章 计算与操作系统 | 第14章 数据结构与算法 第15章 生产级软件工程 | 第16章 SIMD与GPU编程 第17章 AI推理 | 第18章 ML系统设计 第19章 应用人工智能 | 第20章 前沿人工智能 翻译说明: - 所有数学公式 $...$ / $$...$$、代码块、图片引用完整保留 - mkdocs.yml 配置中文导航 + language: zh - README.md 已翻译为中文(兼 docs/index.md) - docs/ 目录包含指向各章文件的 symlink - 约 29,000 行中文内容,排除 .cache/ 构建缓存
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
# 向量空间
|
||||
|
||||
*向量空间构成了机器学习的数学舞台。本文涵盖向量加法、标量乘法、封闭性公理、子空间,以及为什么AI中几乎所有东西都表示为向量。*
|
||||
|
||||
- 将向量空间想象成一种特定类型的舞台,数学对象生活在其中,每个对象被称为一个**向量**。
|
||||
|
||||
- 为了机器学习(ML)中的几何直觉,我们始终将向量视为欧几里得空间中的一个点,由其坐标表示。
|
||||
|
||||
- 向量 $\mathbf{a}$(数学上用粗体小写字母表示)有 $n$ 个坐标,每个坐标代表沿一个轴的位置。
|
||||
|
||||
$$\mathbf{a} = [a_1, a_2, a_3]$$
|
||||
|
||||

|
||||
|
||||
- 向量空间中的向量遵循一套非常具体、不可打破的规则:
|
||||
|
||||
- **向量加法(组合)**:
|
||||
你可以取任意两个向量并将它们组合起来创建新向量。
|
||||
把向量想象成移动的指令。
|
||||
如果向量 A 表示"向前走 3 步",向量 B 表示"向右走 2 步",
|
||||
将它们相加(A + B)就创建了一条新的单一指令:"向前走 3 步并向右走 2 步。"
|
||||
|
||||
- **标量乘法(缩放)**:
|
||||
你可以使用一个普通数字("标量")来缩放任意向量。
|
||||
你可以拉伸它、缩小它或反转它。
|
||||
如果向量 A 是"向前走 3 步",将其乘以 2 就变成"向前走 6 步。"
|
||||
将其乘以 -1 则完全翻转成"向后走 3 步。"
|
||||
|
||||
- 向量空间的**维度**是其包含的独立方向的数量。$\mathbb{R}^2$ 是二维的(需要 2 个坐标),而上面的 $\mathbf{a}$ 存在于 $\mathbb{R}^3$ 中。
|
||||
|
||||
- 例如,我们可以将任何对象(比如一个人)表示为一个向量,其中 $h_1$ = 身高(厘米),$h_2$ = 体重(公斤),$h_3$ = 年龄。
|
||||
|
||||
$$\mathbf{h} = [185, 75, 30]$$
|
||||
|
||||
- 我们现在已经创建了一个包含表示人的向量的向量空间。
|
||||
|
||||
- 我们可以表示多个人,并观察他们之间的远近!
|
||||
|
||||

|
||||
|
||||
- 我们可以添加更多特征,创建丰富的人体表示,在 ML 中通常称为特征向量。
|
||||
|
||||
- 你拥有的独特且有意义的特征越多,特征向量的描述性就越强,这是需要记住的一个重要因素。
|
||||
|
||||
- 超过 3 维后,向量变得非常难以直观检查,这催生了一个名为**线性代数**的数学领域。
|
||||
|
||||
- 现在,**线性代数**是研究向量、向量空间以及向量之间映射关系的学科。
|
||||
|
||||
- 我们在 AI/ML 中将几乎所有东西都表示为向量,这使得线性代数成为该领域的基石。
|
||||
|
||||
- 向量加法可以通过将一个向量放在另一个向量的尾部,然后从原点画到终点的可视化方式执行。
|
||||
|
||||

|
||||
|
||||
- 对于两个向量 $\mathbf{a} = (a_1, a_2)$ 和 $\mathbf{b} = (b_1, b_2)$:$\mathbf{a} + \mathbf{b} = (a_1 + b_1, a_2 + b_2)$
|
||||
|
||||
- 向量也可以相减,所有加法规则同样适用。
|
||||
|
||||
- 将向量乘以标量会在相同方向上按该因子缩放向量。
|
||||
|
||||

|
||||
|
||||
- 对于标量 $c$ 和向量 $\mathbf{v} = (v_1, v_2)$:$c\mathbf{v} = (cv_1, cv_2)$
|
||||
|
||||
- **加法封闭性**:如果将向量空间中的任意两个向量相加,结果也属于同一空间:如果 $\mathbf{u} \in V$ 且 $\mathbf{v} \in V$,则 $\mathbf{u} + \mathbf{v} \in V$
|
||||
|
||||
- **标量乘法封闭性**:如果将向量空间中的任意向量乘以标量,结果也属于同一空间:如果 $\mathbf{v} \in V$ 且 $c \in F$,则 $c\mathbf{v} \in V$
|
||||
|
||||
- **加法结合律**:对于任意三个向量 $\mathbf{u}$、$\mathbf{v}$ 和 $\mathbf{w}$:$(\mathbf{u} + \mathbf{v}) + \mathbf{w} = \mathbf{u} + (\mathbf{v} + \mathbf{w})$
|
||||
|
||||
- **加法交换律**:对于任意两个向量 $\mathbf{u}$ 和 $\mathbf{v}$:$\mathbf{u} + \mathbf{v} = \mathbf{v} + \mathbf{u}$
|
||||
|
||||

|
||||
|
||||
- 通过平行四边形的两条路径都到达同一点。
|
||||
|
||||
- **(零向量)**:存在一个向量 $\mathbf{0}$,使得对于任何向量 $\mathbf{v}$:$\mathbf{v} + \mathbf{0} = \mathbf{v}$
|
||||
|
||||

|
||||
|
||||
- **加法逆元**:对于每个向量 $\mathbf{v}$,存在一个向量 $-\mathbf{v}$,使得:$\mathbf{v} + (-\mathbf{v}) = \mathbf{0}$
|
||||
|
||||

|
||||
|
||||
- **分配律 1**:对于任意标量 $c$ 和向量 $\mathbf{u}$、$\mathbf{v}$:$c(\mathbf{u} + \mathbf{v}) = c\mathbf{u} + c\mathbf{v}$
|
||||
|
||||

|
||||
|
||||
- 缩放和(金色)与分别缩放向量再求和的结果相同。
|
||||
|
||||
- **分配律 2**:对于任意标量 $c$、$d$ 和向量 $\mathbf{v}$:$(c + d)\mathbf{v} = c\mathbf{v} + d\mathbf{v}$
|
||||
|
||||
- **结合律**:对于任意标量 $c$、$d$ 和向量 $\mathbf{v}$:$(cd)\mathbf{v} = c(d\mathbf{v})$
|
||||
|
||||
- **单位元**:对于任何向量 $\mathbf{v}$:$1\mathbf{v} = \mathbf{v}$,其中 $1$ 是标量域中的乘法单位元。
|
||||
|
||||
- **子空间**就是大空间内部的一个较小舞台。把三维空间想象成一个房间。一张穿过房间中心的平坦纸片就是一个子空间,穿过中心的一根直导线也是子空间。
|
||||
|
||||
- 关键要求是子空间必须经过原点。如果你把那片纸移开中心,它就不再是子空间了,因为零向量不再位于其上。
|
||||
|
||||

|
||||
|
||||
- 向量空间的所有规则(加法、缩放、封闭性)在子空间内部仍然有效。你可以在子空间内添加或缩放向量,永远不会"掉出"到更大的空间。
|
||||
|
||||
- 经过原点的直线是一维子空间,经过原点的平面是二维子空间,而整个空间是自身的子空间。
|
||||
|
||||
- 在 ML 中,子空间自然出现。高维数据通常具有存在于低维子空间上的结构。PCA 等技术找到那个子空间,这样我们可以更高效地处理数据。
|
||||
|
||||
## 编程练习(使用 CoLab 或 notebook)
|
||||
|
||||
1. 运行代码验证分配律性质,然后修改并尝试测试其他规则!
|
||||
```python
|
||||
import jax.numpy as jnp
|
||||
|
||||
u = jnp.array([1, 2])
|
||||
v = jnp.array([3, 0])
|
||||
c = 2
|
||||
|
||||
lhs = c * (u + v)
|
||||
rhs = c*u + c*v
|
||||
|
||||
print(f"LHS: {lhs}")
|
||||
print(f"RHS: {rhs}")
|
||||
```
|
||||
|
||||
2. 运行代码可视化不同的向量,然后修改不同坐标的值以理解每个轴如何影响位置。
|
||||
```python
|
||||
import jax.numpy as jnp
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
# 尝试修改这些向量!
|
||||
a = jnp.array([3, 2, 4])
|
||||
b = jnp.array([1, 4, 2])
|
||||
c = jnp.array([4, 1, 3])
|
||||
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(111, projection="3d")
|
||||
|
||||
for vec, name, color in [(a, "a", "red"), (b, "b", "blue"), (c, "c", "green")]:
|
||||
ax.quiver(0, 0, 0, *vec, color=color, arrow_length_ratio=0.1, linewidth=2, label=name)
|
||||
|
||||
lim = int(jnp.abs(jnp.stack([a, b, c])).max()) + 1
|
||||
ax.set_xlim([0, lim]); ax.set_ylim([0, lim]); ax.set_zlim([0, lim])
|
||||
ax.set_xlabel("X"); ax.set_ylabel("Y"); ax.set_zlabel("Z")
|
||||
ax.legend()
|
||||
plt.show()
|
||||
```
|
||||
@@ -0,0 +1,97 @@
|
||||
# 向量性质
|
||||
|
||||
*向量性质描述了定义向量行为的几何和代数特征。本文涵盖模长、方向、单位向量、相等性、平行性、正交性和线性无关性,它们是每个 ML 特征空间的基石。*
|
||||
|
||||
- 向量的**模长**(或长度)告诉你它延伸了*多远*。把它想象成箭头的长度。对于向量 $\mathbf{a} = (a_1, a_2, a_3)$,其模长为:
|
||||
|
||||
$$\|\mathbf{a}\| = \sqrt{a_1^2 + a_2^2 + a_3^2}$$
|
||||
|
||||
- 这只是勾股定理推广到更高维度,测量从原点到该点的直线距离。
|
||||
|
||||
- 向量的**方向**告诉你它指向*哪里*;只需想象从原点到坐标点的一条直线即可。
|
||||
|
||||
- 当没有明确指定原点时,我们通常隐含地使用 $(0,0,\ldots,0)$ 即中心点,至少为了可视化目的如此。
|
||||
|
||||
- 位置并不重要,它总是关于位移:从原点画出的向量 $(3, 2)$ 和从另一个点画出的同样的 $(3, 2)$ 仍然是相等的。
|
||||
|
||||

|
||||
|
||||
- 两个向量可以有相同的长度但指向完全不同的方向,或者指向相同方向但长度不同。
|
||||
|
||||

|
||||
|
||||
- 两个向量**相等**当且仅当它们所有对应的分量都匹配;相同的长度,相同的方向,完全相同的箭头。
|
||||
|
||||
$$\mathbf{a} = \mathbf{b} \iff a_i = b_i \text{ 对所有 } i$$
|
||||
|
||||
- 两个向量**平行**如果一个是另一个的标量倍数。它们沿着同一条直线,要么同向,要么完全反向。
|
||||
|
||||
$$\mathbf{a} \parallel \mathbf{b} \iff \mathbf{a} = k\mathbf{b} \text{ 对于某个标量 } k \neq 0$$
|
||||
|
||||

|
||||
|
||||
- 如果 $k > 0$,它们指向相同方向。如果 $k < 0$,它们指向相反方向。无论哪种情况,它们都位于经过原点的同一条直线上。
|
||||
|
||||
- 直观地说,平行向量不携带任何"新的"方向信息。一个只是另一个的拉伸或翻转版本。
|
||||
|
||||
- 两个向量**正交**(垂直)如果它们指向完全独立的方向。沿一个方向移动不会让你在另一个方向上有任何进展。
|
||||
|
||||

|
||||
|
||||
- 想象向北走然后向东走,这些是正交方向,无论向北走多远都不会使你向东移动。我们经常会遇到正交性。
|
||||
|
||||
- 正交性对 ML 至关重要:正交的特征携带完全独立的信息,这对于表示是最理想的。
|
||||
|
||||
- 更一般地,任意两个向量之间都有一个**夹角** $\theta$,范围从 $0°$ 到 $180°$。
|
||||
|
||||
- 这个角度捕捉了两个方向之间的全部关系:$0°$ 表示平行(相同方向),$180°$ 表示平行(相反方向),$90°$ 表示正交。介于之间的都是混合情况。
|
||||
|
||||
- ML 中的大多数向量关系都处在这个范围的某处。稍后,我们将看到精确的工具(点积、余弦相似度)来计算这个角度。
|
||||
|
||||
- 一组向量是**线性相关**的,如果其中至少一个可以通过缩放和相加从其他向量构造出来。它没有为该集合带来新的信息。
|
||||
|
||||
- 例如,如果 $\mathbf{c} = 2\mathbf{a} + 3\mathbf{b}$,那么 $\mathbf{c}$ 是冗余的,你已经通过 $\mathbf{a}$ 和 $\mathbf{b}$ 拥有了 $\mathbf{c}$ 所提供的全部信息。
|
||||
|
||||
- 平行向量总是线性相关的,因为一个只是另一个的缩放副本。任何包含零向量的集合也是线性相关的。
|
||||
|
||||
- 向量是**线性无关**的,如果其中没有一个能从其他向量构造出来。每个向量都贡献了一个真正的新方向。正交向量总是线性无关的。
|
||||
|
||||
- 在二维中,两个线性无关的向量可以到达平面上的任何点。在三维中,你需要三个。"需要多少个独立的向量"这个想法直接与维度相关。
|
||||
|
||||
- 当向量的大多数分量为零时,该向量是**稀疏**的。相反,大多数分量非零称为**稠密**。
|
||||
|
||||
$$\mathbf{s} = [0, 0, 3, 0, 0, 0, 1, 0, 0, 0]$$
|
||||
|
||||
- 稀疏性很重要,因为它影响存储和计算。稀疏向量可以通过只跟踪非零条目来更高效地存储和处理。
|
||||
|
||||
- **单位向量**是模长正好为 1 的向量。它纯粹表示方向,不包含长度信息。你可以通过除以模长将任何向量变成单位向量:
|
||||
|
||||
$$\hat{\mathbf{a}} = \frac{\mathbf{a}}{\|\mathbf{a}\|}$$
|
||||
|
||||
- 这个过程称为**归一化**。它剥离了"多远",只保留"往哪走。"
|
||||
|
||||
- 标准单位向量指向每个轴:$\hat{\mathbf{i}} = (1, 0, 0)$,$\hat{\mathbf{j}} = (0, 1, 0)$,$\hat{\mathbf{k}} = (0, 0, 1)$。任何向量都可以写成这些向量的组合,例如 $(3, 2, 4) = 3\hat{\mathbf{i}} + 2\hat{\mathbf{j}} + 4\hat{\mathbf{k}}$。
|
||||
|
||||
## 编程练习(使用 CoLab 或 notebook)
|
||||
|
||||
1. 计算向量的模长并验证它符合勾股定理,然后修改代码计算单位向量。
|
||||
```python
|
||||
import jax.numpy as jnp
|
||||
|
||||
a = jnp.array([3.0, 4.0])
|
||||
|
||||
magnitude = jnp.sqrt(jnp.sum(a ** 2))
|
||||
print(f"Magnitude of a: {magnitude}")
|
||||
```
|
||||
|
||||
2. 通过测试一个向量是否是另一个的标量倍数来检查两个向量是否平行。
|
||||
```python
|
||||
import jax.numpy as jnp
|
||||
|
||||
a = jnp.array([2, 4, 6])
|
||||
b = jnp.array([1, 2, 3])
|
||||
|
||||
ratios = a / b
|
||||
print(f"Ratios: {ratios}")
|
||||
print(f"Parallel: {jnp.allclose(ratios, ratios[0])}")
|
||||
```
|
||||
@@ -0,0 +1,90 @@
|
||||
# 度量与范数
|
||||
|
||||
*范数衡量单个向量的大小;度量衡量两个向量之间的距离。本文涵盖 L1、L2 和 L-无穷范数、欧几里得距离和余弦距离,以及为什么为 kNN、聚类和 ML 中的检索选择合适的距离函数至关重要。*
|
||||
|
||||
- 我们知道向量有模长和方向。但我们如何实际衡量单个向量"有多大",或者两个向量"有多远"?这就是**范数**和**度量**发挥作用的地方。
|
||||
|
||||
- 对标量而言,我们知道 10 > 5,因为它们的值对它们进行了量化,但是我们如何量化一个向量?它的**范数**衡量单个向量的大小。
|
||||
|
||||
- 最熟悉的范数是**欧几里得范数**(L2),它就是我们已知的模长公式:
|
||||
|
||||
$$\|\mathbf{v}\|_2 = \sqrt{v_1^2 + v_2^2 + \cdots + v_n^2}$$
|
||||
|
||||
- 但还有其他衡量大小的方法。想象你在一个街道呈网格状的城市中。你不能斜穿建筑物,所以你旅程的"长度"是沿着每条街道行走的总街区数。这就是**曼哈顿范数**(L1):
|
||||
|
||||
$$\|\mathbf{v}\|_1 = |v_1| + |v_2| + \cdots + |v_n|$$
|
||||
|
||||
- 或者你可能只关心单个最大的分量,忽略其余部分。这就是**最大范数**(L-无穷):
|
||||
|
||||
$$\|\mathbf{v}\|_\infty = \max(|v_1|, |v_2|, \ldots, |v_n|)$$
|
||||
|
||||
- 这三个都是**一般 Lp 范数**的特例:
|
||||
|
||||
$$\|\mathbf{v}\|_p = (|v_1|^p + |v_2|^p + \cdots + |v_n|^p)^{1/p}$$
|
||||
|
||||
- 设置 $p = 2$ 得到欧几里得,$p = 1$ 得到曼哈顿,而当 $p \to \infty$ 时得到最大范数。随着 $p$ 增大,最大分量贡献越来越大,直到最终只有它重要。
|
||||
|
||||
- 每个范数必须遵守三条规则:
|
||||
|
||||
- **非负性**:$\|\mathbf{v}\| \geq 0$,且 $\|\mathbf{v}\| = 0$ 仅当 $\mathbf{v} = \mathbf{0}$。大小从不为负,只有零向量的大小为零。
|
||||
|
||||
- **缩放性**:$\|c\mathbf{v}\| = |c| \cdot \|\mathbf{v}\|$。将向量加倍,其大小也加倍。
|
||||
|
||||
- **三角不等式**:$\|\mathbf{u} + \mathbf{v}\| \leq \|\mathbf{u}\| + \|\mathbf{v}\|$。捷径永远不会比绕远路更长。
|
||||
|
||||
- 现在,**度量**衡量*两个*向量之间的距离。把它想象成问:"这两个点相距多远?"
|
||||
|
||||
- 获得度量的最简单方法是使用差值的范数:$d(\mathbf{u}, \mathbf{v}) = \|\mathbf{u} - \mathbf{v}\|$。减去两个向量,然后测量剩余部分的大小。
|
||||
|
||||
- 使用欧几里得范数,我们得到熟悉的**欧几里得距离**:
|
||||
|
||||
$$d(\mathbf{u}, \mathbf{v}) = \sqrt{(u_1 - v_1)^2 + (u_2 - v_2)^2 + \cdots + (u_n - v_n)^2}$$
|
||||
|
||||
- 使用曼哈顿范数得到**曼哈顿距离**,沿着每个轴的总差异,就像计算两个位置之间的城市街区数。
|
||||
|
||||
- 每个度量必须遵守四条规则:
|
||||
|
||||
- **非负性**:$d(\mathbf{u}, \mathbf{v}) \geq 0$。距离从不为负。
|
||||
|
||||
- **同一性**:$d(\mathbf{u}, \mathbf{v}) = 0$ 当且仅当 $\mathbf{u} = \mathbf{v}$。零距离意味着同一点。
|
||||
|
||||
- **对称性**:$d(\mathbf{u}, \mathbf{v}) = d(\mathbf{v}, \mathbf{u})$。从 A 到 B 的距离与从 B 到 A 的距离相同。
|
||||
|
||||
- **三角不等式**:$d(\mathbf{u}, \mathbf{w}) \leq d(\mathbf{u}, \mathbf{v}) + d(\mathbf{v}, \mathbf{w})$。直接走永远不会比绕路更长。
|
||||
|
||||
- 那么两者之间的关系是什么?范数衡量一个向量,度量衡量两个向量之间的差距。每个范数自然地创建一个度量(通过测量差值),但并非每个度量都来自范数。
|
||||
|
||||
- 例如,**汉明距离**计算两个向量不同的位置数量。它是一个有效的度量,但并非来自任何范数。
|
||||
|
||||
- 在 ML 中,选择合适的范数或度量很重要。
|
||||
|
||||
- L2 距离在求和前对每个差值平方,因此单个大的差值会主导结果。
|
||||
|
||||
- L1 距离对绝对差值求和,平等对待每个差值。与 L2 相比,单个大的差值影响较小。
|
||||
|
||||
## 编程练习(使用 CoLab 或 notebook)
|
||||
|
||||
1. 计算同一向量的 L1 和 L2 范数。尝试更改值,注意哪个范数对大的分量最敏感,哪个对许多小分量最敏感。然后尝试计算 p 值递增(例如 1、2、5、10、50、100)时的 Lp 范数,观察它如何收敛到 L-无穷值。
|
||||
```python
|
||||
import jax.numpy as jnp
|
||||
|
||||
v = jnp.array([3.0, -4.0, 1.0])
|
||||
|
||||
l1 = jnp.sum(jnp.abs(v))
|
||||
l2 = jnp.sqrt(jnp.sum(v ** 2))
|
||||
|
||||
print(f"L1: {l1}, L2: {l2:.2f}")
|
||||
```
|
||||
|
||||
2. 计算两个向量之间的欧几里得距离和曼哈顿距离。尝试让向量彼此靠近或远离,观察每种距离如何不同地响应。
|
||||
```python
|
||||
import jax.numpy as jnp
|
||||
|
||||
u = jnp.array([1.0, 2.0, 3.0])
|
||||
v = jnp.array([4.0, 0.0, 1.0])
|
||||
|
||||
euclidean = jnp.sqrt(jnp.sum((u - v) ** 2))
|
||||
manhattan = jnp.sum(jnp.abs(u - v))
|
||||
|
||||
print(f"Euclidean: {euclidean:.2f}, Manhattan: {manhattan}")
|
||||
```
|
||||
@@ -0,0 +1,113 @@
|
||||
# 向量积
|
||||
|
||||
*向量积是衡量相似性和计算投影的基本运算。本文涵盖内积、点积、余弦相似度、叉积和外积,这些运算支撑了 AI 中的注意力机制、嵌入和几何推理。*
|
||||
|
||||
- 我们已经看到如何相加和缩放向量。但是我们可以*相乘*两个向量吗?事实证明不止一种方法,每种方法回答不同的问题。
|
||||
|
||||
- **内积**是一个广义概念:一个接受两个向量并产生一个标量的函数。它是"相乘"向量的抽象蓝图。
|
||||
|
||||
- 任何内积必须满足三条规则:
|
||||
|
||||
- **正定性**:$\langle \mathbf{v}, \mathbf{v} \rangle \geq 0$,且仅对零向量等于零。向量与自身相乘总是给出非负结果。
|
||||
|
||||
- **对称性**:$\langle \mathbf{u}, \mathbf{v} \rangle = \langle \mathbf{v}, \mathbf{u} \rangle$。顺序无关紧要。
|
||||
|
||||
- **线性性**:$\langle a\mathbf{u} + b\mathbf{v}, \mathbf{w} \rangle = a\langle \mathbf{u}, \mathbf{w} \rangle + b\langle \mathbf{v}, \mathbf{w} \rangle$。它对加法和缩放具有分配性。
|
||||
|
||||
- **点积**是最常见的内积。它是你几乎到处都会用到的具体版本。对于两个向量 $\mathbf{a} = (a_1, a_2, \ldots, a_n)$ 和 $\mathbf{b} = (b_1, b_2, \ldots, b_n)$:
|
||||
|
||||
$$\mathbf{a} \cdot \mathbf{b} = a_1 b_1 + a_2 b_2 + \cdots + a_n b_n$$
|
||||
|
||||
- 将匹配的分量相乘,然后全部加起来。这就是全部。
|
||||
|
||||
- 但这个数字*意味着*什么?点积有一个优美的几何解释:
|
||||
|
||||
$$\mathbf{a} \cdot \mathbf{b} = \|\mathbf{a}\| \, \|\mathbf{b}\| \cos(\theta)$$
|
||||
|
||||

|
||||
|
||||
- 这将点积直接与两个向量之间的角度 $\theta$ 联系起来。结果告诉你两个向量在方向上"一致"的程度。
|
||||
|
||||
- 如果它们指向相同方向($\theta = 0°$),$\cos(\theta) = 1$ 且点积最大。
|
||||
|
||||
- 如果它们正交($\theta = 90°$),$\cos(\theta) = 0$ 且点积恰好为零。这给出了正交性的精确检验。
|
||||
|
||||
- 如果它们指向相反方向($\theta = 180°$),$\cos(\theta) = -1$ 且点积为负。
|
||||
|
||||
- 向量与自身的点积给出其模长的平方:$\mathbf{a} \cdot \mathbf{a} = \|\mathbf{a}\|^2$。
|
||||
|
||||
- 点积还给出了**投影**,即一个向量在另一个向量上投下的影子。$\mathbf{a}$ 在 $\mathbf{b}$ 上的投影为:
|
||||
|
||||
$$\text{proj}_{\mathbf{b}}(\mathbf{a}) = \frac{\mathbf{a} \cdot \mathbf{b}}{\|\mathbf{b}\|^2} \, \mathbf{b}$$
|
||||
|
||||
- 想象一束光线直射到 $\mathbf{b}$ 上。$\mathbf{a}$ 在那条线上的影子就是投影。它告诉你 $\mathbf{a}$ 有多少位于 $\mathbf{b}$ 的方向上。
|
||||
|
||||
- **余弦相似度**通过除以两个模长来归一化点积:
|
||||
|
||||
$$\cos(\theta) = \frac{\mathbf{a} \cdot \mathbf{b}}{\|\mathbf{a}\| \, \|\mathbf{b}\|}$$
|
||||
|
||||
- 这会给出一个介于 $-1$ 和 $1$ 之间的值,衡量方向对齐程度,忽略向量的长度。它广泛应用于 ML 中来比较文档、嵌入和用户偏好等事物。
|
||||
|
||||
- 现在,点积接受两个向量并返回标量。**叉积**则相反,它接受两个向量并返回一个*新向量*。
|
||||
|
||||
- 叉积 $\mathbf{a} \times \mathbf{b}$ 产生一个同时垂直于 $\mathbf{a}$ 和 $\mathbf{b}$ 的向量:
|
||||
|
||||
$$\mathbf{a} \times \mathbf{b} = (a_2 b_3 - a_3 b_2, \; a_3 b_1 - a_1 b_3, \; a_1 b_2 - a_2 b_1)$$
|
||||
|
||||
- 叉积只适用于三维。点积适用于任意维度,而叉积是三维空间特有的。
|
||||
|
||||
- 其模长等于由这两个向量形成的平行四边形的面积:
|
||||
|
||||
$$\|\mathbf{a} \times \mathbf{b}\| = \|\mathbf{a}\| \, \|\mathbf{b}\| \sin(\theta)$$
|
||||
|
||||
- 注意模式:点积使用 $\cos(\theta)$,叉积使用 $\sin(\theta)$。点积衡量两个向量对齐的程度,叉积衡量它们在方向上*差异*的程度。
|
||||
|
||||
- 结果的方向遵循**右手定则**:将右手的手指从 $\mathbf{a}$ 弯向 $\mathbf{b}$,拇指指向 $\mathbf{a} \times \mathbf{b}$ 的方向。
|
||||
|
||||
- 与点积不同,叉积**不可交换**:$\mathbf{a} \times \mathbf{b} = -(\mathbf{b} \times \mathbf{a})$。交换顺序会翻转方向。
|
||||
|
||||
- 如果两个向量平行,它们的叉积是零向量(因为 $\sin(0°) = 0$)。没有面积,没有垂直方向。
|
||||
|
||||
- 当你使用两个乘积结合三个向量会发生什么?这就得到了**三重积**。
|
||||
|
||||
- xxxxxxxxxx9 1import jax.numpy as jnp23u = jnp.array([1.0, 2.0, 3.0])4v = jnp.array([4.0, 0.0, 1.0])56euclidean = jnp.sqrt(jnp.sum((u - v) ** 2))7manhattan = jnp.sum(jnp.abs(u - v))89print(f"Euclidean: {euclidean:.2f}, Manhattan: {manhattan}")python
|
||||
|
||||
- 如果标量三重积为零,则这三个向量**共面**,它们都位于同一个平坦平面上,不形成体积。
|
||||
|
||||
- 顺序可以循环而不改变结果:$\mathbf{a} \cdot (\mathbf{b} \times \mathbf{c}) = \mathbf{b} \cdot (\mathbf{c} \times \mathbf{a}) = \mathbf{c} \cdot (\mathbf{a} \times \mathbf{b})$。
|
||||
|
||||
- **向量三重积** $\mathbf{a} \times (\mathbf{b} \times \mathbf{c})$ 应用两次叉积并返回一个向量。它可以使用恒等式简洁展开:
|
||||
|
||||
$$\mathbf{a} \times (\mathbf{b} \times \mathbf{c}) = (\mathbf{a} \cdot \mathbf{c})\mathbf{b} - (\mathbf{a} \cdot \mathbf{b})\mathbf{c}$$
|
||||
|
||||
- 结果总是位于由 $\mathbf{b}$ 和 $\mathbf{c}$ 张成的平面内。注意叉积**不满足结合律**:$\mathbf{a} \times (\mathbf{b} \times \mathbf{c}) \neq (\mathbf{a} \times \mathbf{b}) \times \mathbf{c}$。
|
||||
|
||||
## 编程练习(使用 CoLab 或 notebook)
|
||||
|
||||
1. 计算两个向量的点积并用它求出它们之间的角度。尝试让它们正交、平行或反向,观察角度如何变化。
|
||||
```python
|
||||
import jax.numpy as jnp
|
||||
|
||||
a = jnp.array([1.0, 2.0, 3.0])
|
||||
b = jnp.array([4.0, -1.0, 2.0])
|
||||
|
||||
dot = jnp.dot(a, b)
|
||||
angle = jnp.arccos(dot / (jnp.linalg.norm(a) * jnp.linalg.norm(b)))
|
||||
|
||||
print(f"Dot product: {dot}")
|
||||
print(f"Angle: {jnp.degrees(angle):.1f}°")
|
||||
```
|
||||
|
||||
2. 计算两个三维向量的叉积,并通过检查结果与每个原始向量的点积为零来验证结果垂直于两者。
|
||||
```python
|
||||
import jax.numpy as jnp
|
||||
|
||||
a = jnp.array([1.0, 0.0, 0.0])
|
||||
b = jnp.array([0.0, 1.0, 0.0])
|
||||
|
||||
cross = jnp.cross(a, b)
|
||||
|
||||
print(f"a x b = {cross}")
|
||||
print(f"Perpendicular to a: {jnp.dot(cross, a) == 0}")
|
||||
print(f"Perpendicular to b: {jnp.dot(cross, b) == 0}")
|
||||
```
|
||||
@@ -0,0 +1,89 @@
|
||||
# 基与对偶性
|
||||
|
||||
*基定义了向量空间的坐标系,而对偶性揭示了线性函数如何作用于向量。本文涵盖线性无关性、生成集、基变换、对偶空间和余向量,这些概念支撑了 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\}$。每个对偶基向量恰好提取一个坐标:
|
||||
|
||||
```math
|
||||
\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. 在两个不同的基中表达一个向量,并验证它们代表同一个点。尝试创建你自己的基,观察向量得到什么坐标。
|
||||
```python
|
||||
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. 验证对偶基性质:每个对偶基向量恰好提取一个坐标,对其他向量返回零。
|
||||
```python
|
||||
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)}")
|
||||
```
|
||||
Reference in New Issue
Block a user