线性代数
核心目标:把"张量计算"升级为"线性代数视角",理解向量、矩阵和它们的乘法规则。
1. 概述
线性代数是深度学习的数学语言:
- 用向量和矩阵表达数据(特征、权重、批次样本)
- 用点积和矩阵乘法表达计算(线性变换、全连接层)
- 用范数衡量大小(正则化、梯度裁剪)
在 PyTorch 中,标量、向量、矩阵都由 Tensor 类型承载,分别对应 0 维 / 1 维 / 2 维张量。
2. 基本对象与记法
2.1 数学对象与张量表示
| 数学对象 | 数学示例 | 张量示例 | 阶 |
|---|---|---|---|
| 标量(scalar) | 3.0 |
torch.tensor(3.0) |
0 |
| 向量(vector) | [1, 2, 3] |
torch.tensor([1., 2., 3.]) |
1 |
| 矩阵(matrix) | [[1,2],[3,4]] |
torch.tensor([[1.,2.],[3.,4.]]) |
2 |
| 张量(tensor) | 更高维数组 | 3 维及以上 | ≥3 |
2.2 数学记法
| 对象 | 记号 |
|---|---|
| 标量 | 普通小写字母,如 xxx、yyy、zzz |
| 向量 | 粗体小写,如 x∈Rn\mathbf{x} \in \mathbb{R}^nx∈Rn |
| 矩阵 | 粗体大写,如 A∈Rm×n\mathbf{A} \in \mathbb{R}^{m \times n}A∈Rm×n |
python
import torch
num_t = torch.tensor(3.0) # 标量张量,0 维
v_t = torch.tensor([1., 2., 3.]) # 向量张量,1 维
A_t = torch.tensor([[1., 2.], [3., 4.]]) # 矩阵张量,2 维
3. 行列向量
在线性代数里,真正需要关心的是:向量参与矩阵乘法时,行/列方向决定形状能否对齐、结果是什么。
| 类型 | shape | 含义 |
|---|---|---|
| 1 维(方向未定) | (n,) |
不区分行/列 |
| 行向量 | (1, n) |
1 行 n 列 |
| 列向量 | (n, 1) |
n 行 1 列 |
升维写法:v.reshape(1, 3) / v.unsqueeze(0) → 行向量;v.reshape(3, 1) / v.unsqueeze(1) → 列向量。
python
import torch
A = torch.tensor([[1., 2., 3.],
[4., 5., 6.]]) # (2, 3)
v = torch.tensor([1., 2., 3.]) # (3,)
col = v.reshape(3, 1) # 列向量 (3, 1)
# 矩阵 × 列向量:(2, 3) @ (3, 1) → (2, 1)
print(A @ col)
# tensor([[14.],
# [32.]])
# 1 维向量参与 matmul 时框架自动适配,结果等价
print(A @ v) # tensor([14., 32.]),shape (2,)
# 行向量左乘:v @ A.T → (3,) @ (3, 2) → (2,)
print(v @ A.T) # tensor([14., 32.])
# 注意:row @ A 即 (1,3) @ (2,3) 内维不匹配,会报错
4. 转置与对称矩阵
- 转置(transpose) :行列互换,记为 A⊤\mathbf{A}^\topA⊤。
- 矩阵 A\mathbf{A}A 形状
(m, n),转置后 A⊤\mathbf{A}^\topA⊤ 形状(n, m)。 - 对称矩阵 :A=A⊤\mathbf{A} = \mathbf{A}^\topA=A⊤(必须是方阵)。
python
import torch
A = torch.arange(12, dtype=torch.float32).reshape(3, 4)
AT = A.T
print(A.shape, AT.shape) # [3,4] → [4,3]
B = torch.tensor([[1., 2., 3.],
[2., 0., 4.],
[3., 4., 5.]])
print(torch.allclose(B, B.T)) # True → 对称矩阵
5. 点积(Dot Product)
给定两个同长度向量 x,y\mathbf{x}, \mathbf{y}x,y:
x⊤y=∑ixiyi \mathbf{x}^\top \mathbf{y} = \sum_i x_i y_i x⊤y=i∑xiyi
直觉:先对应位相乘 ,再整体求和。前提:两向量长度必须相同。
python
import torch
x = torch.tensor([1., 2., 3.])
y = torch.tensor([4., 5., 6.])
print(torch.dot(x, y)) # tensor(32.)
print((x * y).sum()) # 同样是 tensor(32.)
6. 矩阵乘法
6.1 形状规则
| 运算 | 形状规则 | 结果形状 |
|---|---|---|
| 矩阵 × 向量 | (m,n)×(n,)→(m,)(m, n) \times (n,) \rightarrow (m,)(m,n)×(n,)→(m,) | mmm 维向量 |
| 向量 × 矩阵 | (m,)×(m,n)→(n,)(m,) \times (m, n) \rightarrow (n,)(m,)×(m,n)→(n,) | nnn 维向量 |
| 矩阵 × 矩阵 | (m,k)×(k,n)→(m,n)(m, k) \times (k, n) \rightarrow (m, n)(m,k)×(k,n)→(m,n) | (m,n)(m, n)(m,n) 矩阵 |
一维向量张量在 matmul 中可视为行向量或列向量,框架自动适配。
6.2 @ vs *(核心口诀)
| 运算符 | 含义 | 判断条件 |
|---|---|---|
@ / matmul |
矩阵乘法(线性代数乘法) | 看内维是否相等 |
* |
按元素乘(Hadamard 积) | 看形状是否相同或可广播 |
python
import torch
A = torch.randn(5, 4)
B = torch.randn(4, 3)
x = torch.randn(4)
C = A @ x # (5, 4) × (4,) → (5,)
D = A @ B # (5, 4) × (4, 3) → (5, 3)
E = x @ B # (4,) × (4, 3) → (3,)
H = A * torch.ones_like(A) # 按元素乘,不是矩阵乘
print(torch.allclose(A, H)) # True
7. 范数(Norm)
范数是"大小"的度量,不同对象适用不同范数。
7.1 数学定义
向量 x=x1,...,xn\mathbf{x} = x_1, \\dots, x_nx=x1,...,xn:
∥x∥1=∑i=1n∣xi∣(L1 范数:绝对值之和) \|\mathbf{x}\|1 = \sum{i=1}^{n} |x_i| \qquad \text{(L1 范数:绝对值之和)} ∥x∥1=i=1∑n∣xi∣(L1 范数:绝对值之和)
∥x∥2=∑i=1nxi2(L2 范数:欧氏长度) \|\mathbf{x}\|2 = \sqrt{\sum{i=1}^{n} x_i^2} \qquad \text{(L2 范数:欧氏长度)} ∥x∥2=i=1∑nxi2 (L2 范数:欧氏长度)
矩阵 A=aijA = a_{ij}A=aij:
∥A∥F=∑i∑jaij2(Frobenius 范数:拉直后求 L2) \|A\|F = \sqrt{\sum_i \sum_j a{ij}^2} \qquad \text{(Frobenius 范数:拉直后求 L2)} ∥A∥F=i∑j∑aij2 (Frobenius 范数:拉直后求 L2)
7.2 PyTorch 计算
torch.linalg.norm 是通用范数函数:
| 范数类型 | 参数 | 代码示例 |
|---|---|---|
| 向量 L1 | ord=1 |
torch.linalg.norm(v, ord=1) |
| 向量 L2 | ord=2 或默认 |
torch.linalg.norm(v) |
| 矩阵 Frobenius | ord='fro' 或默认 |
torch.linalg.norm(m) |
python
import torch
u = torch.tensor([3., -4.])
print(torch.abs(u).sum()) # L1 = 7
print(torch.linalg.norm(u, ord=1)) # L1 = 7
print(torch.linalg.norm(u)) # L2 = 5
M = torch.tensor([[1., 2.], [3., 4.]])
print(torch.linalg.norm(M)) # Frobenius = sqrt(30) ≈ 5.477
8. NumPy 与 PyTorch 线代 API 对照
深度学习线代运算两个库 API 高度相似,PyTorch 额外支持 GPU 与自动求导。
python
# ──── NumPy ──── # ──── PyTorch ────
import numpy as np import torch
np.sum(A, axis=0) A.sum(dim=0)
np.mean(A, axis=1) A.mean(dim=1)
np.concatenate([A, B], axis=0) torch.cat([A, B], dim=0)
np.matmul(A, B) # 或 A @ B torch.matmul(A, B) # 或 A @ B
np.linalg.inv(A) torch.linalg.inv(A)
np.linalg.matrix_rank(A) torch.linalg.matrix_rank(A)
np.linalg.det(A) torch.linalg.det(A)
np.linalg.svd(A) torch.linalg.svd(A)
np.linalg.solve(A, b) torch.linalg.solve(A, b)
np.linalg.norm(x, ord=2) torch.linalg.norm(x, ord=2)
| 场景 | 建议 |
|---|---|
| 数据清洗、统计分析 | NumPy(常配合 Pandas) |
| 简单矩阵验证 | NumPy 更轻量 |
| 神经网络训练/推理 | PyTorch |
| 同一训练流程内 | 尽量全程 PyTorch,避免类型来回转换 |
9. 易错点速查
| 易错点 | 正确理解 |
|---|---|
把 * 当成矩阵乘法 |
* 是按元素乘;矩阵乘法用 @ 或 matmul |
matmul 维度不匹配 |
检查内维是否相等,如 (m,k)@(k,n) |
| 混淆"向量长度"与"张量阶数" | [1,2,3] 数学上 3 维向量,张量上 1 维 |
| 1 维向量当行/列向量 | 用 reshape(1,n) 或 reshape(n,1) 明确 |
| NumPy 与 PyTorch 混算 | 先 torch.tensor() 或 .numpy() 统一类型 |
10. 小结
线性代数在深度学习里就是:用向量和矩阵表达数据,用点积和矩阵乘法表达计算,用范数衡量大小。