向量积 向量积是衡量相似度和计算投影的基本运算。本节介绍内积、点积、余弦相似度、叉积和外积——这些运算支撑着 AI 中的注意力机制、嵌入和几何推理。 我们已经知道如何相加和缩放向量。但是我们能把两个向量「相乘」吗?事实证明不止有一种做法,每一种回答的都是不同的问题。 内积(inner product)是一个一般性概念:一个接受两个向量并产生单个数字(标量)的函数。它是「向量相乘」这一概念的抽象蓝图。 任何内积都必须满足三条规则: 正定性:$\langle \mathbf{v}, \mathbf{v} \rangle \geq 0$,且仅对零向量为零。一个向量与自身相乘总得到非负结果。
向量积是衡量相似度和计算投影的基本运算。本节介绍内积、点积、余弦相似度、叉积和外积——这些运算支撑着 AI 中的注意力机制、嵌入和几何推理。
我们已经知道如何相加和缩放向量。但是我们能把两个向量「相乘」吗?事实证明不止有一种做法,每一种回答的都是不同的问题。
内积(inner product)是一个一般性概念:一个接受两个向量并产生单个数字(标量)的函数。它是「向量相乘」这一概念的抽象蓝图。
任何内积都必须满足三条规则:
正定性:\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。它对加法和数乘可分配。
点积(dot product)是最常见的内积,也是你几乎处处都会用到的具体版本。对于两个向量 \mathbf{a} = (a_1, a_2, \ldots, a_n) 和 \mathbf{b} = (b_1, b_2, \ldots, b_n):
把对应分量相乘,再把所有结果加起来,仅此而已。
但这个数字到底意味着什么?点积有一个优美的几何解释:
这把点积与两个向量之间的夹角 \theta 直接联系起来。结果告诉你两个向量在方向上有多「一致」。
如果它们同向(\theta = 0°),\cos(\theta) = 1,点积最大。
如果它们正交(\theta = 90°),\cos(\theta) = 0,点积正好为零。这给了我们一个精确的正交性判据。
如果它们反向(\theta = 180°),\cos(\theta) = -1,点积为负。
一个向量与自身做点积得到它的大小的平方:\mathbf{a} \cdot \mathbf{a} = \|\mathbf{a}\|^2。
点积还给出投影(projection),即一个向量在另一个向量上投下的「影子」。\mathbf{a} 在 \mathbf{b} 上的投影为:
想象一束光垂直照向 \mathbf{b}。\mathbf{a} 在那条线上的影子就是投影。它告诉你 \mathbf{a} 有多少落在 \mathbf{b} 的方向上。
余弦相似度(cosine similarity)把点积除以两个向量的大小进行归一化:
这给出一个在 -1 和 1 之间的值,衡量方向上的对齐程度,而忽略向量有多长。它在 ML 中被广泛用于比较文档、嵌入和用户偏好等。
点积接受两个向量并返回一个标量。叉积(cross product)则相反——它接受两个向量并返回一个新向量。
叉积 \mathbf{a} \times \mathbf{b} 产生一个同时垂直于 \mathbf{a} 和 \mathbf{b} 的向量:
叉积只在 3 维中有效。点积在任意维数下都成立,而叉积是三维空间所特有的。
它的大小等于两个向量所张成的平行四边形的面积:
注意这个规律:点积用 \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)。没有面积,也就没有垂直方向。
当你把两种积结合三个向量一起用时会怎样?这就得到三重积(triple products)。
标量三重积 \mathbf{a} \cdot (\mathbf{b} \times \mathbf{c}) 先对两个向量做叉积,再把结果与第三个向量做点积。输出是一个数,等于三个向量所张成的平行六面体(一个倾斜的 3 维盒子)的体积。
如果标量三重积为零,则三个向量共面,它们都躺在同一个平面里,不形成任何体积。
顺序可以轮换而结果不变:\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}) 连续做两次叉积,返回一个向量。它可以整洁地展开为恒等式:
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}°")
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}")