向量的内积、外积、范数(L1/L2/∞)定义与几何意义?
- —用 numpy 实现 L1/L2/∞ 范数并对比 torch.linalg.norm 结果
核心概念
向量内积(Dot Product)是两个向量在代数或几何上的乘法,结果是一个标量。它衡量了两个向量在方向上的相似性或对齐程度,即一个向量在另一个向量方向上的投影的度量。
向量外积(Cross Product)是定义在三维空间中两个向量的二元运算,结果是一个新的向量。这个新向量垂直于原始两个向量构成的平面,其大小等于以这两个向量为边的平行四边形的面积。
向量范数(Vector Norm)是一个函数,它为向量空间中的每个向量赋予一个非负的“长度”或“大小”。L1、L2 和无穷范数是其中最常见的几种,它们以不同的方式度量向量的大小,分别对应“曼哈顿距离”、“欧几里得距离”和“切比雪夫距离”。
原理与推导
1. 向量内积 (Dot Product)
对于两个 n 维向量 和 。
- 代数定义:
在矩阵表示法中,如果 和 是列向量,则内积为 。
- 几何定义:
其中 是 L2 范数(见下文),代表向量的欧几里得长度, 是两个向量之间的夹角。
- 推导与几何解释: 几何定义可以通过余弦定理推导。考虑由向量 、 和 构成的三角形。根据余弦定理:
同时,从代数上我们有:
联立以上两式,即可得到 。
几何意义: 内积 是向量 在向量 方向上的投影长度(即 )与向量 的长度 的乘积。这直观地解释了为什么内积可以度量对齐性:
-
(同向): ,内积取最大正值。
-
(正交): ,内积为 0。
-
(反向): ,内积取最小负值。
-
复杂度: 对于 n 维向量,需要 n 次乘法和 n-1 次加法,时间复杂度为 。
2. 向量外积 (Cross Product)
主要用于三维空间。对于向量 和 。
- 定义:
其中 是笛卡尔坐标系的单位基向量。
-
几何意义:
- 方向: 结果向量 同时垂直于 和 ,其方向由右手定则确定。
- 大小: 结果向量的模(长度)为: 这个值等于由向量 和 张成的平行四边形的面积。
-
复杂度: 对于三维向量,计算是常数时间 。
3. 向量范数 (Vector Norms)
对于向量 ,其 范数定义为:
-
L1 范数 (Manhattan Norm):
几何意义: 向量各元素绝对值之和。在二维空间中,是从原点到点 沿着坐标轴网格走过的距离(出租车几何)。L1 范数的“单位球”(所有范数为 1 的点的集合)是一个菱形(二维)或超菱形(高维)。
-
L2 范数 (Euclidean Norm):
几何意义: 向量在欧几里得空间中的“直线”长度,即从原点到向量末端点的距离。这是最直观、最常用的范数。L2 范数的“单位球”是一个圆形(二维)或球面(高维)。
-
无穷范数 (Infinity Norm / Max Norm):
推导: 这是 范数在 时的极限。令 。
当 时, 对于 的项趋于 0,对于 的项等于 1。假设有 个元素的大小等于 ,则上式变为 。由于 ,故极限为 。 几何意义: 向量中绝对值最大的元素。L-无穷范数的“单位球”是一个正方形(二维)或超立方体(高维)。
代码实现
1import numpy as np2import torch34# --- 代码练习:用 numpy 实现 L1/L2/∞ 范数并对比 torch.linalg.norm 结果 ---56# 1. 定义一个样本向量7# 使用 numpy 创建一个 ndarray8vec_np = np.array([-3, 1, 4, -1.5])9# 使用 torch 创建一个 tensor,注意要用浮点数以保证和 numpy 的类型一致10vec_pt = torch.from_numpy(vec_np).float()1112print(f"原始向量: {vec_np}\n")1314# 2. L1 范数 (Manhattan Norm)15print("--- L1 范数 ---")16# NumPy 实现: 对向量中所有元素的绝对值求和17# 为什么这样做: 这完全符合 L1 范数的定义: ||x||_1 = sum(|x_i|)18l1_norm_np = np.sum(np.abs(vec_np))19print(f"NumPy 手动实现: {l1_norm_np:.4f}")2021# PyTorch 对比: 使用 torch.linalg.norm,并指定 ord=122# 为什么这样做: PyTorch 的官方接口提供了高效且数值稳定的范数计算23l1_norm_pt = torch.linalg.norm(vec_pt, ord=1)24print(f"PyTorch linalg.norm(ord=1): {l1_norm_pt:.4f}\n")25# 验证结果: |-3| + |1| + |4| + |-1.5| = 3 + 1 + 4 + 1.5 = 9.52627# 3. L2 范数 (Euclidean Norm)28print("--- L2 范数 ---")29# NumPy 实现: 计算向量元素平方和的平方根30# 为什么这样做: 这完全符合 L2 范数的定义: ||x||_2 = sqrt(sum(x_i^2))31l2_norm_np = np.sqrt(np.sum(vec_np**2))32print(f"NumPy 手动实现: {l2_norm_np:.4f}")3334# PyTorch 对比: 使用 torch.linalg.norm,并指定 ord=2 (或不指定,默认为2)35# 为什么这样做: L2 范数是最常用的范数,作为默认值符合惯例36l2_norm_pt = torch.linalg.norm(vec_pt, ord=2)37print(f"PyTorch linalg.norm(ord=2): {l2_norm_pt:.4f}\n")38# 验证结果: sqrt((-3)^2 + 1^2 + 4^2 + (-1.5)^2) = sqrt(9 + 1 + 16 + 2.25) = sqrt(28.25) ≈ 5.3153940# 4. 无穷范数 (Infinity Norm / Max Norm)41print("--- 无穷范数 ---")42# NumPy 实现: 找到向量中绝对值最大的元素43# 为什么这样做: 这完全符合无穷范数的定义: ||x||_inf = max(|x_i|)44inf_norm_np = np.max(np.abs(vec_np))45print(f"NumPy 手动实现: {inf_norm_np:.4f}")4647# PyTorch 对比: 使用 torch.linalg.norm,并指定 ord=torch.inf48# 为什么这样做: PyTorch 使用 float('inf') 或 torch.inf 来表示无穷大49inf_norm_pt = torch.linalg.norm(vec_pt, ord=float('inf'))50print(f"PyTorch linalg.norm(ord=inf): {inf_norm_pt:.4f}\n")51# 验证结果: max(|-3|, |1|, |4|, |-1.5|) = max(3, 1, 4, 1.5) = 4.0
工程实践
-
内积:
- 注意力机制:
Transformer中的核心操作,通过计算 Query 和 Key 向量的内积(缩放后)来得到注意力权重,衡量不同 token 之间的相关性。 - 相似度计算: 在推荐系统、信息检索中,用户和物品的 embedding 向量之间的内积(或余弦相似度,即归一化后的内积)是衡量其匹配度的常用指标。
- 性能: 内积是矩阵乘法的基本组成部分,在现代硬件(GPU/TPU)上通过 BLAS 库(如 cuBLAS)得到了极高程度的优化。
- 注意力机制:
-
外积:
- 在主流的深度学习模型中不常用。
- 机器人学与计算机图形学: 用于计算法线向量、处理旋转(如计算力矩)、三维几何重建等场景。
-
范数:
- L2 范数:
- L2 正则化 (Weight Decay): 在损失函数中加入模型权重 L2 范数的平方项,。这会惩罚大的权重,促使模型学习到更小、更分散的权重,有效防止过拟合,提升模型的泛化能力。
- 损失函数: 均方误差(MSE)损失函数本质上是预测值与真实值之差向量的 L2 范数的平方。
- L1 范数:
- L1 正则化 (LASSO): 在损失函数中加入模型权重 L1 范数的项,。L1 正则化会引导模型产生稀疏解(许多权重变为精确的 0),因此常被用于特征选择。
- 损失函数: 平均绝对误差(MAE)损失函数是基于预测值与真实值之差向量的 L1 范数。相比 MSE,MAE 对异常值(outliers)更鲁棒。
- 无穷范数:
- 对抗性攻击: 在生成对抗样本时,常用无穷范数来限制扰动的大小。例如,FGSM 算法在无穷范数球内寻找能最大化损失的扰动,意味着对输入图像的每个像素点的修改量都不能超过一个阈值 。
- 数值稳定性: 在数值分析中,无穷范数常用于衡量误差向量中的最大误差。
- L2 范数:
常见误区与边界情况
-
内积 vs. 外积:
- 误区: 混淆两者的输出和用途。
- 辨析: 内积(点乘)输入两个向量,输出一个标量,用于衡量相似性。向量外积(叉乘)输入两个三维向量,输出一个向量,用于几何计算。更广义的外积(Outer Product)输入两个向量(维度可不同),输出一个矩阵。
- 面试追问: "两个 n 维向量的内积、外积(Outer Product)和叉积(Cross Product)结果的维度分别是什么?" 答:标量(1x1)、n x n 矩阵、仅在 n=3 时有定义,结果是 3 维向量。
-
L1 vs. L2 正则化:
- 误区: 认为两者效果相似,可随意替换。
- 辨析: L1 产生稀疏性,L2 产生平滑性。从几何上看,L1 范数的等值线是菱形,在优化时更容易与损失函数的等值线在坐标轴上相切,从而产生稀疏解。L2 范数的等值线是圆形,切点通常不在坐标轴上,因此权重会趋近于 0 但不等于 0。
- 面试追问: "为什么 L1 正则化能实现特征选择?" 答:因为 L1 惩罚项的导数在 0 附近是常数(-1 或 1),即使权重很小,梯度下降时也会以恒定的速度将其推向 0。而 L2 惩罚项的导数与权重成正比,权重越小,梯度越小,收敛到 0 的速度越慢,难以精确为 0。
-
数值稳定性:
- 计算 L2 范数 时,如果向量元素 的值非常大, 可能会导致浮点数溢出(Overflow)。如果 非常小,则可能导致下溢(Underflow)和精度损失。
- 解决方案: 专业的库(如 NumPy, PyTorch)在内部实现时会先对向量进行缩放,例如除以向量中的最大绝对值,计算完毕后再乘回去,从而避免溢出问题。
-
边界情况:
- 零向量: 任何向量与零向量的内积为 0。零向量的范数为 0。两个非零向量内积为 0,说明它们正交。
- 平行向量: 两个平行或反平行向量的外积(叉乘)是零向量,因为 。