跳转至

# 向量积

向量积是衡量相似性和计算投影的基本运算。本文涵盖内积、点积、余弦相似度、叉积和外积，这些运算支撑了 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 jnp2​3u = jnp.array([1.0, 2.0, 3.0])4v = jnp.array([4.0, 0.0, 1.0])5​6euclidean = jnp.sqrt(jnp.sum((u - v) ** 2))7manhattan = jnp.sum(jnp.abs(u - v))8​9print(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. 计算两个向量的点积并用它求出它们之间的角度。尝试让它们正交、平行或反向，观察角度如何变化。

       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. 计算两个三维向量的叉积，并通过检查结果与每个原始向量的点积为零来验证结果垂直于两者。

       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}")