Day 02|线性代数核心:向量、矩阵、点积与特征值(AI 学习笔记 · 基础筑基周 · 第 2 篇)
线性代数是后续所有机器学习、深度学习论文的「共同语法」:神经网络的每一层无非是一次「线性变换 + 非线性激活」,而点积决定了相似度、注意力、卷积等几乎所有「打分」操作。本节把向量、矩阵、点积、特征值四块拼图用几何直觉串成一条线。
1. 向量:带方向的信息容器
1.1 定义
向量是 $\mathbb{R}^n$ 中的一个有大小、有方向的量。给定基底下,一个 $n$ 维向量可写成一列实数:
\mathbf{v} = \begin{bmatrix} v_1 \\ v_2 \\ \vdots \\ v_n \end{bmatrix}
在 AI 工程中,列向量是默认形态:每个样本的特征是一个向量,模型的权重也是一个向量,矩阵按列向量堆叠。
1.2 几何直觉
把 $\mathbf{v}$ 看成从原点射出的箭头。长度叫模:
\|\mathbf{v}\|_2 = \sqrt{\sum_{i=1}^{n} v_i^2}
方向由单位向量 $\mathbf{v} / |\mathbf{v}|$ 给出。例:用户特征 $\mathbf{u} = (\text{年龄}, \text{月消费}, \text{活跃天数}) = (28, 3500, 12)$ 是一个 3 维向量,模 $\sqrt{28^2 + 3500^2 + 12^2} \approx 3500.1$,方向几乎由「月消费」一维决定——这正是后续降维的入口。
1.3 向量基本运算
import numpy as np
a = np.array([3.0, 4.0])
b = np.array([1.0, 2.0])
a + b # element-wise 加
2.5 * a # 标量乘
-a # 取反
np.linalg.norm(a) # L2 模:5.0
1.4 三种「范数」
| 范数 | 公式 | 几何 | 用途 |
|---|---|---|---|
| L1 | $\sum |v_i|$ | 曼哈顿距离 | 稀疏化、Lasso 正则 |
| L2 | $\sqrt{\sum v_i^2}$ | 欧氏距离 | 通用距离度量、权重衰减 |
| L∞ | $\max |v_i|$ | 最大分量 | 对抗样本最大扰动 |
2. 矩阵:批量数据 + 线性变换
2.1 定义
$m \times n$ 矩阵是 $m$ 行 $n$ 列的实数表:
A = \begin{bmatrix} a_{11} & a_{12} & \cdots & a_{1n} \\ a_{21} & a_{22} & \cdots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m1} & a_{m2} & \cdots & a_{mn} \end{bmatrix}
两种解读:
- 数据视角:行是样本,列是特征 —— $m$ 条样本、$n$ 维特征
- 变换视角:矩阵 $\mathbf{A}$ 是一个把 $\mathbb{R}^n$ 映到 $\mathbb{R}^m$ 的线性算子
2.2 矩阵运算清单
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
A + B # 逐元素加
A @ B # 矩阵乘
A.T # 转置
A * B # 逐元素乘,不是矩阵乘
np.linalg.inv(A) # 逆矩阵
np.linalg.det(A) # 行列式
2.3 矩阵乘法的本质:线性变换的复合
若 $A$ 是 $(m \times n)$、$B$ 是 $(n \times p)$,则 $AB$ 是 $(m \times p)$:
(AB)_{ij} = \sum_{k=1}^{n} A_{ik} B_{kj}
几何含义:先做 $B$ 把 $n$ 维空间映射到 $p$ 维,再做 $A$ 把 $p$ 维映射到 $m$ 维。神经网络一层的本质就是「左乘权重矩阵 $W$ + 加偏置 $b$ + 非线性 $\sigma$」。
2.4 神经网络一层
# 输入 X: (B, n), 权重 W: (n, k), 偏置 b: (k,)
# 输出: (B, k)
H = X @ W + b
H = np.maximum(H, 0) # ReLU 激活
$X$ 的每一行是一个样本,整批一起算就是矩阵乘 + 广播偏置。这是把 Day 6 线性回归扩展到神经网络的关键。
2.5 常用矩阵类型
| 类型 | 形状 | 性质 | AI 用途 |
|---|---|---|---|
| 单位矩阵 $I$ | $n \times n$ | $AI = A$ | 初始化、损失项 |
| 对角矩阵 | $n \times n$ | 非对角元素为 0 | 协方差矩阵、缩放 |
| 对称矩阵 | $n \times n$ | $A = A^T$ | 协方差、邻接矩阵 |
| 正交矩阵 | $n \times n$ | $A^T A = I$ | 旋转、QR 分解 |
| 稀疏矩阵 | $m \times n$ | 大部分元素为 0 | 词袋、邻接表 |
3. 点积:相似度的数学根
3.1 定义
\mathbf{a} \cdot \mathbf{b} = \sum_{i=1}^{n} a_i b_i = \|\mathbf{a}\| \|\mathbf{b}\| \cos\theta
3.2 两种解读
| 解读 | 公式 | 直观 |
|---|---|---|
| 代数 | $\sum a_i b_i$ | 对应位相乘再求和 |
| 几何 | $|\mathbf{a}| |\mathbf{b}| \cos\theta$ | 模的乘积 × 夹角余弦 |
最重要的性质:点积衡量「两个向量同向的程度」。同向 = 1,正交 = 0,反向 = -1。
3.3 点积的 5 个 AI 用途
- 相似度:$\text{cosine}(a,b) = \frac{a \cdot b}{|a| |b|}$ —— 推荐系统召回
- 注意力分数:$Q \cdot K$ 决定 token 之间的关联强度
- 线性回归:$\hat{y} = w \cdot x + b$
- 卷积:本质就是局部点积
- SVM 核:$\phi(a) \cdot \phi(b)$ 在高维空间做点积
3.4 矩阵形式
$n$ 个 $d$ 维向量堆成矩阵 $A \in \mathbb{R}^{n \times d}$,则两两相似度矩阵:
S = A A^T \in \mathbb{R}^{n \times n}
A = np.random.randn(5, 3) # 5 个 3 维向量
S = A @ A.T # (5, 5) 相似度矩阵
S_norm = S / (np.linalg.norm(A, axis=1, keepdims=True) ** 2) # cosine
4. 转置、广播与形状推演
4.1 转置的 4 条规则
| 规则 | 公式 |
|---|---|
| 双重转置 | $(A^T)^T = A$ |
| 加法转置 | $(A+B)^T = A^T + B^T$ |
| 乘积转置 | $(AB)^T = B^T A^T$ |
| 标量转置 | $c^T = c$ |
核心:乘积的转置 = 各自转置再交换顺序。Transformer QKᵀ、反向传播、协方差矩阵都依赖这条。
4.2 形状推演四则
# 例 1:线性层
X = np.random.randn(B, n) # (B, n)
W = np.random.randn(n, k) # (n, k)
b = np.random.randn(k) # (k,)
out = X @ W + b # (B, k) ← 广播: (B, k) + (k,) → (B, k)
# 例 2:多头注意力
B, n, h, d_k = 2, 10, 4, 8
Q = np.random.randn(B, n, h, d_k)
K = np.random.randn(B, n, h, d_k)
scores = Q @ K.transpose(0, 1, 3, 2) # (B, n, h, d_k) @ (B, n, d_k, h) → (B, n, h, h)
4.3 矩阵乘法维度匹配口诀
「内维相等,外维做结果」:(m, n) @ (n, p) → (m, p)。
5. 特征值与特征向量
5.1 定义
对 $n \times n$ 方阵 $A$,若存在非零向量 $\mathbf{v}$ 和标量 $\lambda$ 满足:
A \mathbf{v} = \lambda \mathbf{v}
则 $\mathbf{v}$ 是 $A$ 的特征向量,$\lambda$ 是对应的特征值。
5.2 几何含义
特征向量是矩阵作用时「不旋转、只拉伸」的方向;$\lambda$ 量化沿该方向拉伸倍数。
-
$ \lambda > 1$:沿该方向放大 -
$ \lambda < 1$:沿该方向缩小 - $\lambda = 0$:$A$ 奇异,不可逆
- $\lambda < 0$:反向拉伸(坐标系翻转)
5.3 求解过程
特征方程:$\det(A - \lambda I) = 0$。
import numpy as np
A = np.array([[2, 0], [0, 3]])
eigvals, eigvecs = np.linalg.eig(A)
# eigvals = [2., 3.]
# eigvecs = 单位正交特征向量
5.4 特征分解
对称矩阵总可对角化:
A = Q \Lambda Q^T
- $Q$:正交矩阵,列为特征向量
- $\Lambda$:对角矩阵,对角元素是特征值
几何含义:任何对称变换 = 旋转到主轴 + 各向异性缩放 + 转回去。
5.5 PCA 与最大特征值
数据协方差矩阵 $\Sigma = \frac{1}{N} X^T X$ 的最大特征值 $\lambda_1$ 对应方向 $\mathbf{v}_1$,就是数据最分散的方向 = 第一主成分。
直觉:$\Sigma \mathbf{v}_1 = \lambda_1 \mathbf{v}_1$ 意味着沿 $\mathbf{v}_1$ 方向上数据的方差正好是 $\lambda_1$;取最大 $\lambda$ 对应的方向就是方差最大的方向。
X = np.random.randn(100, 5)
Xc = X - X.mean(axis=0)
cov = Xc.T @ Xc / len(X)
eigvals, eigvecs = np.linalg.eigh(cov)
# eigvals 升序;PCA 第一主成分 = eigvecs[:, -1]
6. NumPy 手算实战
6.1 向量加法 / 点积 / 矩阵乘法(不调 np.dot)
import numpy as np
a = np.array([1.0, 2.0, 3.0])
b = np.array([4.0, 5.0, 6.0])
# 1) 向量加
c = a + b # 等价手算:循环逐位加
# 2) 点积手算
dot = 0.0
for i in range(len(a)):
dot += a[i] * b[i]
# 3) 矩阵乘手算
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
C = np.zeros((2, 2))
for i in range(2):
for j in range(2):
for k in range(2):
C[i, j] += A[i, k] * B[k, j]
print(np.allclose(A @ B, C)) # True
6.2 2×2 矩阵特征值手算
设 $A = \begin{bmatrix} a & b \ c & d \end{bmatrix}$,特征方程:
\lambda^2 - (a+d)\lambda + (ad - bc) = 0
解:
\lambda_{1,2} = \frac{(a+d) \pm \sqrt{(a+d)^2 - 4(ad-bc)}}{2}
例: $A = \begin{bmatrix} 2 & 1 \ 1 & 2 \end{bmatrix}$:
- 迹 $= 4$,行列式 $= 3$
- $\lambda = \frac{4 \pm \sqrt{16 - 12}}{2} = \frac{4 \pm 2}{2}$
- $\lambda_1 = 3, \lambda_2 = 1$
- $\lambda_1$ 对应 $\mathbf{v}_1 = (1, 1)/\sqrt{2}$,$\lambda_2$ 对应 $\mathbf{v}_2 = (1, -1)/\sqrt{2}$
A = np.array([[2, 1], [1, 2]], dtype=float)
eigvals = np.linalg.eigvals(A)
# array([3., 1.])
6.3 一句话 PCA
Xc = X - X.mean(axis=0)
cov = np.cov(Xc, rowvar=False)
eigvals, eigvecs = np.linalg.eigh(cov)
idx = np.argsort(eigvals)[::-1]
top_k = eigvecs[:, idx[:k]]
Z = Xc @ top_k # (N, k) 投影到前 k 主成分
6.4 PCA 二维 toy 数据可视化
import numpy as np
import matplotlib.pyplot as plt
# 生成有明显主轴的 2D 数据
theta = np.deg2rad(35)
R = np.array([[np.cos(theta), -np.sin(theta)],
[np.sin(theta), np.cos(theta)]])
X = np.random.randn(300, 2) @ R.T * [3.0, 0.5] # 各向异性
Xc = X - X.mean(axis=0)
cov = np.cov(Xc, rowvar=False)
eigvals, eigvecs = np.linalg.eigh(cov)
v1 = eigvecs[:, -1] # 主方向
plt.scatter(X[:, 0], X[:, 1], alpha=0.4)
plt.quiver(0, 0, v1[0], v1[1], scale=3, color="red", label="PC1")
plt.axis("equal"); plt.legend(); plt.show()
主成分方向总是沿数据云「最长的轴」,特征值量化沿该轴的方差(展开长度)。
6.5 SVD vs 特征分解
A = np.random.randn(5, 3)
U, s, Vt = np.linalg.svd(A, full_matrices=False)
# U: (5, 3) 左奇异向量; s: (3,) 奇异值; Vt: (3, 3) 右奇异向量
A_approx = U @ np.diag(s) @ Vt # 完全重构
A_lowrank = U[:, :2] @ np.diag(s[:2]) @ Vt[:2] # 截断到 rank=2
SVD 是矩形矩阵的「特征分解」:奇异值 $\sigma_i$ 平方后 = $A^T A$ 的特征值 $\lambda_i$。PCA 中若直接对 $X$ 做 SVD 再取右奇异向量,等价于先中心化再算 $X^T X$ 特征向量,但数值更稳。
7. 常见坑(8 条)
7.1 (m, n) @ (m, n) 失败
症状:ValueError: matmul: Input operand 1 has a mismatch in its core dimension
原因:内维不匹配,$(m, n) @ (n, p)$ 才行
修法:第一个矩阵的列数必须等于第二个矩阵的行数
7.2 * 当矩阵乘用
症状:神经网络 shape 对不上
原因:A * B 是 element-wise,要做矩阵乘写 @
修法:统一用 @ 或 np.matmul
7.3 把「列向量」写成行向量
症状:X @ w + b 结果 shape 错
原因:PyTorch / NumPy 都按行存矩阵,「列向量」实际是 $(N, 1)$,得用 .T 或 [:, None]
修法:保持 shape 一致,广播用 keepdims=True 或显式升维
7.4 协方差矩阵用 np.cov 还是手算
症状:np.cov(X, rowvar=False) 和 X.T @ X / N 数值差一个常数
原因:np.cov 默认除以 $N-1$ 做无偏估计,手算常除以 $N$
修法:用 np.cov 时记 .shape == (d, d);手算用 ddof=1 对齐
7.5 特征值分解前提是方阵
症状:np.linalg.eig(A) 在 $A$ 不是方阵时报错
原因:特征值只对方阵有定义
修法:矩形矩阵用 SVD np.linalg.svd(A),SVD 给出左奇异向量 / 奇异值 / 右奇异向量
7.6 数值不稳定的求逆
症状:矩阵条件数大时 np.linalg.inv(A) 结果离谱
原因:病态矩阵求逆放大误差
修法:永远优先用 np.linalg.solve(A, b) 解 $Ax = b$,只在显式需要 $A^{-1}$ 时再求逆
7.7 维度对齐搞混
症状:X @ W 后维度错了
原因:没有按矩阵乘规则画 shape
修法:动手前在纸上画 (B, n) × (n, k) → (B, k),标好每个张量的语义
7.8 转置后 batch 维错位
症状:Transformer 中 Q @ K.T 不对
原因:K 形状是 (B, n, d_k),直接 K.T 会把 batch 维也转置
修法:用 K.transpose(0, 2, 1) 或显式 np.swapaxes(K, -1, -2)
7.9 np.linalg.eig 返回的顺序
症状:eigvals 是复数,排序后结果混乱
原因:np.linalg.eig 不保证实部升序、不保证实数解
修法:对称矩阵用 np.linalg.eigh,返回实数 + 升序;非对称用 eig,手动 np.argsort(eigvals.real)[::-1]
7.10 协方差矩阵除以 N 还是 N-1
症状:np.cov(X) 和 X.T @ X / len(X) 数值差几个百分点
原因:前者除以 $N-1$ 做无偏估计,后者除以 $N$ 是 MLE
修法:要无偏用 np.cov,要 MLE 用 X.T @ X / N;两者在大 $N$ 下几乎等价
8. 自检三问
A. 点积 $\mathbf{a} \cdot \mathbf{b}$ 为 0 意味着什么?在 cosine 相似度和正交分解中各代表什么含义?
要点:$\mathbf{a} \cdot \mathbf{b} = 0$ 意味着 $|\mathbf{a}| |\mathbf{b}| \cos\theta = 0$。因为模非零,所以 $\cos\theta = 0$,即 $\theta = \pi/2$,两向量正交。在 cosine 相似度里它表示完全无关(相似度 = 0);在正交分解里表示 $\mathbf{b}$ 在 $\mathbf{a}$ 方向上分量为 0,可以独立处理。这是 PCA 把数据投影到正交主成分、Transformer 注意力权重正交稀疏的几何基础。
B. 矩阵左乘一个向量和右乘一个向量,在维度与几何含义上有什么区别?以 $X(m \times n) @ W(n \times k)$ 为例说明。
要点:矩阵左乘向量 $A \mathbf{x}$ 要求 $A$ 的列数 = $\mathbf{x}$ 的维数,几何上是「把向量 $\mathbf{x}$ 当作坐标系基的系数,做线性变换」。右乘向量 $\mathbf{y}^T A$ 要求 $\mathbf{y}$ 的维数 = $A$ 的行数,几何上是「对 $A$ 的行做线性组合」。$X @ W$ 中 $X$ 的每行是一个样本向量,左乘 $W$ 把每个样本从 $n$ 维特征空间映射到 $k$ 维隐藏空间;右乘 $X^T$ 则把「样本视角」变成「特征视角」,后续协方差矩阵就是 $X^T X$。
C. 协方差矩阵的最大特征值对应的特征向量,为什么就是 PCA 的第一主成分?请用一句话给出几何解释。
要点:协方差矩阵 $\Sigma$ 沿 $\mathbf{v}$ 方向的方差正好等于 $\mathbf{v}^T \Sigma \mathbf{v}$,当 $\mathbf{v}$ 是特征向量 $\Sigma \mathbf{v} = \lambda \mathbf{v}$ 时该方差 $= \lambda$。最大 $\lambda$ 对应方向就是方差最大、数据最分散的方向,即第一主成分。这是 PCA 投影方向选择的数学根据,几何上等于「数据云最长的轴」。
9. 推荐资源
视频
- 3Blue1Brown《线性代数的本质》 —— 系列 14 集,从向量到 SVD 全部几何可视化,Day 2 的几何直觉主要从这里来
- 李宏毅《机器学习》 —— 早期几集把矩阵乘法讲成神经网络一层的视角,初学者最直观
- StatQuest《Eigenvalues and Eigenvectors》 —— 主成分拆解步骤讲得最细
教科书
- 《线性代数的本质》(Sheldon Axler) —— 第 2-5 章覆盖本节所有概念,理论深度足够
- 《Deep Learning》(Goodfellow) —— 第 2 章「线性代数」专门为 ML 写的 30 页速成
- 《动手学深度学习》(d2l.ai) —— 附录「线性代数」每个概念配可运行代码
论文
- Pearson 1901《On Lines and Planes of Closest Fit to Systems of Points in Space》 —— PCA 原始论文
- Golub & Kahan 1965《Calculating the Singular Values and Pseudoinverse of a Matrix》 —— SVD 计算方法
博客 / 课程
- distill.pub《How to Use t-SNE Effectively》 —— 配合 Day 12 看
- Jay Alammar《Visualizing A Neural Machine Translation Model》 —— 用线性代数视角看 seq2seq
- Stanford CS231n《Linear Algebra Review》 —— 计算机视觉系最常用的速查表
代码
- numpy.linalg 模块官方文档 ——
numpy.org/doc/stable/reference/routines.linalg.html,所有矩阵分解 API 速查 - 《Matrix Cookbook》(Petersen & Pedersen) —— PDF 工具书,公式推导速查
10. 本节要点
- 向量:$\mathbb{R}^n$ 中的方向 + 大小;模 $|\mathbf{v}|_2$ 是 L2 距离的根。AI 中样本、权重、token embedding 都是向量。
- 矩阵:既是「行=样本、列=特征」的批量数据表,也是把一个向量映射到另一个向量的线性变换算子。神经网络一层的本质 = $X @ W + b$。
- 点积:$\mathbf{a} \cdot \mathbf{b} = |\mathbf{a}| |\mathbf{b}| \cos\theta$,度量同向程度;cosine 相似度、Transformer 注意力、卷积打分全部源于此。
- 转置:$(AB)^T = B^T A^T$,乘积转置 = 反序各自转置;反向传播、Transformer QKᵀ 全靠这条规则推导。
- 特征值 / 特征向量:$A\mathbf{v} = \lambda\mathbf{v}$,特征向量是「变换时只拉伸不旋转」的方向,$\lambda$ 是拉伸倍数。PCA 取最大 $\lambda$ 对应方向作为数据主轴。
- SVD 是矩形矩阵的「特征分解」,PCA 通常算的是数据中心化后 $X$ 的 SVD,等价于 $X^T X$ 的特征分解,数值更稳。
- NumPy 手算:向量加 / 点积 / 矩阵乘 / 2×2 特征值手算各 1 例,确认自己看得到
@下面的 C 循环;PCA 一行Xc @ eigvecs[:, idx[:k]]出结果。 - 形状推演:线性层 $(B, n) @ (n, k) \to (B, k)$;矩阵乘内维相等、外维做结果;任何写代码前的 shape 推演能省 50% 调试时间。
11. 下一节:Day 03 · 微积分与梯度
主题:偏导、链式法则、梯度下降直观理解。覆盖:
- 偏导作为「按住其它变量、看一个变量」的瞬时变化率;多元函数的 Jacobian
- 链式法则作为反向传播(BP)的数学骨架;$\frac{dy}{dx} = \frac{dy}{du} \cdot \frac{du}{dx}$ 在深度网络里的层层递推
- 梯度 $\nabla f = (\partial f/\partial x_1, \partial f/\partial x_2, \ldots)$ 作为「最陡上升方向」,$-\nabla f$ 是最陡下降
- 梯度下降 $\theta \leftarrow \theta - \eta \nabla f$ 的几何直觉;学习率 $\eta$ 过大/过小的现象
- SGD / Mini-batch / Adam 的差异;Momentum 的物理类比(给球加惯性)
产出物:f(x) = x^2 + 3x + 2 用纯 numpy 手写 gradient_descent,可视化不同 $\eta$ 下的收敛轨迹。