先修工具箱:数学、张量与自动微分
这一页只装这本书真正会用到的数学与工程前置知识,按「哪里缺补哪里」的方式组织。不需要通读——遇到卡壳时回来查,每个条目都指向它在正文里的用处。
三条使用建议
- 先做入学诊断:得分决定你要不要完整读这一页。
- 公式不背,要看懂:所有公式后面都写了「它在第几讲用」,读那一段比背公式有用。
- 动手验一遍:每个小节末尾有 1–2 道两分钟小练习,做完再走。
一、线性代数:一切张量运算的语法
| 概念 | 记法与要点 | 用在哪 |
|---|---|---|
| 向量与矩阵 | (列向量)、 | 全书 |
| 矩阵乘 | ;形状规则: | 1.1 前向传播 |
| 转置 | ——顺序反转,这是反传公式里转置出现的原因 | 1.5 |
| 逐元素乘 | (Hadamard 积);反传里 就是它 | 1.5 |
| 范数 | ;矩阵范数见数值分析教程 1.3 节 | 正则化、梯度裁剪 |
| 内积与相似度 | ;cos 相似度 = 归一化内积 | 2.4 注意力的 |
| 特征值/特征向量 | ;对称矩阵可正交对角化 | 谱半径→梯度稳定性(2.2) |
| 奇异值分解 | ; 度量各方向的伸缩 | 低秩视角(LoRA 的动机,9.5) |
两分钟练习:、、——、、 里哪些能算、形状各是什么?(答案:;;。)
二、微积分与优化:梯度从哪来
| 概念 | 要点 | 用在哪 |
|---|---|---|
| 偏导与梯度 | ;指向增长最快方向 | 1.5 |
| 链式法则 | ——反向传播的全部数学 | 1.5 |
| 雅可比 | :向量函数的「导数矩阵」 | 2.2 BPTT |
| 向量-雅可比积(VJP) | 反向模式一次得到一个 VJP(),所以反传代价与输出维度无关而与参数维度相关 | 1.5 |
| 凸性 | 凸函数局部极小即全局极小;深度学习目标通常非凸 | 1.6 |
| 拉格朗日乘子 | 约束优化的标准工具 | 附录 C.13 DPO 推导 |
| 中心差分 | ,用于梯度检查 | 附录 C.2 |
两分钟练习:,求 。(答案:。)
三、概率:损失函数的来源
| 概念 | 要点 | 用在哪 |
|---|---|---|
| 期望与方差 | 、 | 批大小与梯度噪声(1.6) |
| 常见分布 | 伯努利/类别(分类)、高斯(回归与扩散)、均匀(初始化) | 1.4、4.5 |
| 条件概率与贝叶斯 | 4.3 后验 | |
| 最大似然 | 最小化负对数似然 = 最大化似然;它决定损失函数的形式 | 1.4 |
| 交叉熵与 KL | ;交叉熵 = 熵 + KL | 1.4、4.3 |
| 重参数化 | 从 采样写作 , | 4.3 |
| 重要性采样 | ;ELBO 就是它的应用 | 附录 C.6 |
两分钟练习: 服从 ,求 。(答案:——方差定义即得;这个结论在注意力的 论证里直接用到了。)
四、张量与形状:排错的第一技能
本书统一采用 「批优先」(batch-first) 约定:张量第 0 维永远是批维,且前向过程中批维不变。
广播(broadcasting):从右侧对齐形状,逐维比较:相等或其中一个为 1 才可广播,否则报错。
(32, 10) + (10,) # OK:后者被当作 (1, 10) 广播到 (32, 10)
(32, 1) + (32,) # ⚠️ 得到 (32, 32):容易静默出错
(32, 10) + (32,) # ❌ 报错
两分钟练习:、、—— 的形状?(答案:;偏置按最后一维广播。)
五、自动微分:为什么梯度能「一次算完」
计算图:把前向写成有向无环图(每个节点是一个算子),反向就在图上按拓扑逆序做链式法则。
| 模式 | 一次传递得到 | 何时用 |
|---|---|---|
| 前向模式 | 一个输入方向的 | 输入少、输出多 |
| 反向模式(深度学习默认) | 一个输出方向的 (全部参数的梯度) | 参数极多、输出是标量(损失) |
核心结论:深度学习「参数百万到千亿、输出是一个标量损失」,因此反向模式是唯一可行的选择;一次前向 + 一次反向即可拿到全部梯度(代价 ≈ 2–3 倍前向)。
为什么还要懂它:① 理解 detach()、no_grad()、requires_grad 的语义;② 理解为什么有些操作(如采样)必须重参数化才能传梯度(4.3);③ 理解激活重计算为什么能省显存(9.5)。
import torch
x = torch.tensor(2.0, requires_grad=True)
y = x**3 + 2*x # 前向:构建计算图
y.backward() # 反向:沿图做链式法则
print(x.grad) # dy/dx = 3x² + 2 = 14(x=2)
两分钟练习:把上式改成 y = (x**3 + 2*x).detach(),x.grad 会怎样?(答案:backward() 会报错——图被切断,没有可求导的路径。)
六、一张速查表:从数学到代码
| 数学写法 | PyTorch 写法 | 备注 |
|---|---|---|
x @ w + b | @ 是矩阵乘,* 是逐元素 | |
F.softmax(z, dim=-1) | 必须指定维度(常错点) | |
a * b | 逐元素 | |
| (沿某轴) | x.sum(dim=...) | 想清「对哪一维求和」 |
(x**2).sum() | 梯度裁剪用 clip_grad_norm_ | |
loss.backward() 后 p.grad | 记得 optimizer.zero_grad() | |
| 批维不变 | x.shape[0] 恒为 | 排错第一检查项 |
初学者最常卡的六处
dim写错:softmax/mean/sum不写dim会沿所有维度计算,结果往往形状不对且不报错。- 视图与转置混用:
transpose/permute后张量不再连续,直接view会报错或产生错误结果(用reshape或先contiguous())。 - 忘记清零梯度:PyTorch 默认累积梯度;不清零会让更新量越滚越大。
- 训练/推理模式未切换:
model.eval()影响 Dropout 与 BatchNorm 的行为;评估时不切换会得到错误的指标。 - 在
no_grad里做本该训练的事:评估时用torch.no_grad()省显存,但训练里误用会导致梯度为None。 - 把张量当标量:
if loss > 0.5在 0 维张量上可用,但if tensor_with_many_elements会报错——用.item()。
七、五分钟自测(做完即可开始第 1 讲)
- 、, 的形状? 呢?
- ,求 。
- 一句话说明「反向模式自动微分」为什么适合深度学习。
- 过
Linear(d, 4d)后形状?参数量(含偏置)? - 写出交叉熵的定义,并说明它和「最大似然」的关系。
- 为什么
softmax要指定dim?
自测答案
- 均为 。
- (Sigmoid 的导数形式,正是它在网络里好用的原因)。
- 参数极多而损失是标量:一次反向传播即可得到全部参数的梯度,代价与参数量成正比(前向模式的代价与输入维度成正比,无法承受)。
- 形状 ;参数量 。
- ;它等于负对数似然(离散情形),因此最小化交叉熵 = 最大似然估计。
- 因为 softmax 是「对哪一维做归一化」的选择:序列 logits 的最后一维才是类别/词表维,写错维度会得到错误分布且不一定报错。