深度学习地基:机器怎么从例子里学会规律
主线定位
- 上游:没有。这是整门课的起点,只需要中学数学(函数、导数、对数)。学过深度学习的读者可以跳过,遇到时回查。
- 本章:一个完整的训练循环——例子 → 词变向量 → 模型 → 预测 → loss → 梯度 → 更新,外加一个验证集。上面每一格点开,都能看到它在本章的迷你模型里多大、在锚点 Qwen3.8(27,781,427,952 个参数)里多大。
- 下游:C0 序章用这个循环训练「预测下一个词」,并解释为什么中间的模型是 Transformer;C1 把第 7 课的「查表」展开成真实 tokenizer 与 Embedding;C5 在第 3 课的梯度下降之上讲动量、Adam、Muon。
贯穿例句:「小猫 喜欢 吃 ___」,来自一次真实的学习对话。老师在那里说:模型猜错了就产生 loss,反向传播告诉参数往哪个方向改一点,「猫 = [0.20, 0.70] → [0.21, 0.68]」,一次只改一点点。这一章把这句话里的每个词都拆开,并在浏览器里把那组数真算一遍(第 3、7 课)。
本章问题链
每一课只回答一个问题;上一课的失败,逼出下一课的问题。
| 课 | 这一课的问题 | 朴素方案在哪个真数字上失败 | 一句话 |
|---|---|---|---|
| 第 1 课 | 机器怎么从例子里学到规律? | 把例子背成表:《三國志演義》验证集里,前 4 个字原样出现过的只有 2.9% | 模型是带着可调数字的函数,学习就是用例子调这些数字 |
| 第 2 课 | 怎么量「错了多少」? | 数错题:loss 降了 0.28,错题数还是 7/7;连乘 135 个 1/256 就是 0 | 交叉熵 = 正确答案概率的负对数,处处有坡度 |
| 第 3 课 | 往哪边改、改多少? | 随机方向和下坡方向的余弦只有约 0.004;η = 10 时 loss 不降反升 | 沿负梯度走,一次只改一点点 |
| 第 4 课 | 参数一多,梯度怎么算? | 逐个参数扰动:每步 49,792 次前向,约 12 秒 | 从 loss 往回传「本地导数 × 上游梯度」,一次算完 |
| 第 5 课 | 直线拟合不了怎么办? | 线性模型在组合题上永远停在 ln 2 = 0.693 | 线性层之间插非线性,空间才能被折叠 |
| 第 6 课 | 训练越来越好,新数据却越来越差? | 项目实测:训练 loss 降到 0.70,验证 loss 从 4.771 升到 6.906 | 看验证 loss,在它最低时停下或加正则 |
| 岔路 | 深度学习为什么是经验性的? | — | 能表示、梯度对是证明出来的;训得出、泛化好靠实验 |
| 第 7 课 | 离散的词怎么进网络? | one-hot 乘矩阵:Qwen3.8 每个 token 12.7 亿次乘加,只有 5,120 次不在乘 0 | 按编号查表取一行;梯度只回到用到的那几行 |
演进地图
- 解决了见过的例子,能一字不差地答出来。卡在《三國志演義》验证集 2,979 个位置里,前 4 个字在训练片段里原样出现过的只有 87 个(2.9%),其余查表答不出(第 1 课浏览器实算)。
- 解决了迷你模型的 60 个数一起调,训练里没出现过的「小猫 想 吃」也给「鱼」82.7%。卡在「调到多好」要一个数来量。数错题:训练第 1 步平均 loss 从 2.583 降到 2.306,错题数还是 7/7——台阶上没有坡度(第 2 课)。
- 解决了错得越离谱罚得越重:对话样本假设「鱼」拿到 5%,loss = 2.996;而且处处有坡度。卡在有了坡,往哪边走?24,896 个参数的小网络里,随机方向和下坡方向夹角余弦的中位数只有约 0.004(第 3 课浏览器实训)。
- 解决了沿 −∇L 小步走:真语料小网络 η = 1、600 步,验证 loss 5.550 → 3.606。卡在梯度要逐个参数去试:中心差分每步 49,792 次前向,作者机器上约 12 秒,反向传播约 0.7 毫秒(第 4 课在你的浏览器里现场计时)。
- 解决了一次前向加一次反向,约 3 倍前向的代价拿到全部精确梯度;与有限差分的相对误差约 10⁻⁸。卡在模型只会「各部分加起来再打分」:四句组合题的 loss 永远停在 ln 2 = 0.693(第 5 课)。
- 解决了2 个 ReLU 单元把平面折叠,四句组合题的 loss 降到 0.0006(种子 3)。卡在能力够了就会背书:项目模型训到 24.5 个 epoch,验证 loss 从第 300 步的 4.771 升到 6.906(第 6 课项目实测)。
- 第六代 验证集、早停与正则化 早停 Morgan & Bourlard 1989;权重惩罚 Hanson & Pratt 1988,Krogh & Hertz 1991 解释其原理;dropout 2012解决了在验证 loss 最低处停;2,000 字的训练集上,λ = 0.003 把 3,000 步后的验证 loss 从 11 以上拉回 4.06(浏览器实训)。卡在输入一直是数,可语言是一个个离散的词:Qwen3.8 每个 token 的 one-hot 有 248,320 维,直接乘矩阵要 1,271,398,400 次乘加(第 7 课)。
- 解决了按编号取出一行可学习的向量;反向传播只改用到的几行——迷你模型一步只有 3 行在动,9 行恰好不动。接下来接下来:词进了网络,「下一个词」的概率怎么算、为什么终点是 Transformer(C0);这些行学成什么样(C1)。
三层交互
| 层 | 本章里的组件 | 在哪一课 |
|---|---|---|
| 概念动画 | 训练一整圈的累计数据流(每课点亮一格);迷你模型的训练动画(参数平面上的轨迹);计算图的前向 / 反向逐格步进;四句组合题的「平面折叠」训练回放 | 每一课;第 1、4、5 课 |
| 算法模拟器(真算法、小数据) | 迷你模型「小猫 喜欢 吃」(60 个参数,教学构造):你调两个数 vs 机器调 60 个数、交叉熵与错题数、一步梯度下降、计算图与有限差分、one-hot 与梯度只回到用到的行;交叉熵曲线与两把朴素尺子;四句组合题的线性 / ReLU / 多种子 | 第 1–5、7 课与岔路 |
| 真模型 / 真数据 | 真语料小网络(《三國志演義》24,000 字,24,896 个参数)在浏览器里真训练:查表覆盖率、从例子学、随机方向 vs 梯度、学习率三幕、梯度检查与计时、ReLU vs 无激活、过拟合与权重衰减、embedding 行的梯度、换种子;我们自己从 0 训练的 3.7M 模型 1,500 步的真实日志 | 第 1、3–7 课与岔路 |
项目推进:训练循环与验证集
对应 04-实践项目/MILESTONES.md 的「D 深度学习地基(过拟合)」。分工照旧:代码 AI 来写,决策你来做。项目的训练循环(交叉熵、AdamW、固定窗口评估)已经跑通,1,500 步的对照 run 导出为本章读取的 d00-foundations.json。
你要拍板的三件事
- 训练目标用什么 loss?理由要引用第 2 课的三个失败数字(错题数不动、连乘下溢、平方差梯度弱)。
- 训多少步、留哪一份参数?依据验证集曲线的拐点,不依据训练 loss(第 6 课)。
- 改了模型结构之后,怎么确认梯度没写错?什么时候做梯度检查、h 取多大(第 4 课)。
验收标准(全部可测):
- 从下图读出验证 loss 最低的步数与 epoch(第 300 步、4.90 epoch、4.771),以及第 1,500 步的训练 / 验证 loss(0.704 / 6.906,差 6.20),并说出为什么不能拿基线 400 步的 4.626 和这条曲线的第 400 步直接比。
- 训练日志里的训练 loss 与验证 loss 同口径(项目已满足:都在 228 个固定窗口上评估)。
- 新增一个梯度检查测试:float64 的小 minillm 上
torch.autograd.gradcheck通过,或手写中心差分相对误差 < 10⁻⁶(项目tests/里目前还没有,需新增)。 - run 结束时保存验证 loss 最低的那份参数,并在 summary 里写明它的步数(项目已记录 best_val_step,但目前只保存最后一步的参数,需新增)。
坑与带走
| 坑 | 症状 | 后果 | 怎么办 |
|---|---|---|---|
| 拿错题率 / 准确率当训练目标 | loss 一格一格跳,大部分时候不动 | 梯度处处为 0,训练不动 | 用交叉熵训练,准确率只拿来看(第 2 课) |
| 把概率连乘当目标 | 结果变成 0 或 −∞ | 数值下溢,算不出来 | 取对数再平均,就是交叉熵(第 2 课) |
| 学习率太大 | 开局几步 loss 冲高,然后出现 NaN | 训练报废 | 减小 η,先用几百步扫几个值(第 3 课) |
| 学习率太小 | loss 几乎是一条缓坡 | 浪费算力,以为模型不行 | 同上,扫描(第 3 课);warmup 与衰减调度见 C5 第 4、5 课 |
| 手写的反向传播没检查 | loss 降得奇怪或不降 | 后面所有结论都建立在错梯度上 | float64 下与中心差分对照,h ≈ 10⁻⁵,相对误差应在 10⁻⁶ 以下(第 4 课) |
| 层与层之间忘了非线性 | 加深、加宽都没效果 | 整个网络等于一层线性 | 线性层之间放 ReLU 等激活(第 5 课) |
| 只看训练 loss 决定训多久 | 训练 loss 一路降 | 验证 loss 回升,模型在背书 | 看验证 loss,最低点停;加数据或正则(第 6 课) |
| 用验证集反复挑超参 | 验证分数越调越好,上线后变差 | 在验证集上过拟合 | 留一份最后才看的测试集(第 6 课、C14) |
| 只跑一个种子就下结论 | 两个配置差 0.05,据此选型 | 结论可能反过来 | 同一种子成对比较,多种子报告波动(岔路课) |
| 以为没出现的词也在学 | 罕见词的表示很差 | 模型在罕见词上不稳 | 它们的行很少收到梯度;词表与数据配比要考虑到(第 7 课、C1、C7) |
这一章你应该带走的(各课「一句话」):
- 模型是一个带着可调数字的函数;学习就是用例子去调这些数字——规律存在数字里,所以没见过的输入也有答案。
- 交叉熵 = 正确答案概率的负对数:把「例子被复现的概率」连乘变成连加;错得越离谱罚得越重,而且处处有坡度可以往下走。
- 梯度告诉你此处哪个方向下坡最陡;学习率决定沿它走多远——梯度只在附近可信,所以一次只改一点点,走一步再重新算。
- 反向传播 = 在计算图上从 loss 往回走,每一步把「本地导数 × 上游梯度」传下去;一次前向加一次反向,拿到所有参数的精确梯度。
- 线性模型只能按「各部分加起来」打分,判断不了「组合」;在线性层之间插一个非线性,空间被折叠,组合才分得开——少了它,叠多少层都还是一层。
- 训练 loss 只说明背没背下例子;没见过的数据要用验证集单独量——验证 loss 开始上升的那一刻,就该停下或加正则。
- 深度学习里「能表示」「梯度算得对」是证明出来的;「训得出来」「在新数据上好」主要靠实验——所以结论要连同种子、规模、数据一起报告。
- 词进网络 = 用编号去一张可学习的表里取一行向量;它就是 one-hot 乘矩阵、只是省掉了乘 0,反向传播只改这句话用到的那几行。
深入这一章
每条都实际打开核对过(2026-09-26):写清它讲清了什么、对应哪一课、为什么推荐。外部链接都需要联网;论文暂无本地 PDF,统一下载后改成本地链接。
🎮 想更直观 10–30 分钟
🔬 想吃透原理 1–3 小时
📄 想读原文 按需
排除了什么(也是筛选标准):① 各种同质化的「梯度下降可视化器」小站(8gwifi、gradientlab、deepml.dev 等)——没有作者或机构背书,本章组件和 TF Playground 已覆盖;② B 站「保姆级 / 全 300 集 / 2026 最新」类合集——没有授权标注、标题党,本章只给原作者的官方源,第三方字幕转载会注明;③ Welch Labs 视频的 B 站 AI 配音转载——都未见授权,给原片;④ losslandscape.com 一类损失地形艺术渲染——好看,但不能操作、不讲机制;⑤ 旧版课程的 LossChart——用正弦噪声冒充训练曲线,本章所有曲线来自浏览器真训练或项目日志;⑥ Nielsen《Neural Networks and Deep Learning》在线版——本次核实时证书与域名不匹配、打不开,它的「可视化证明」思路由 UDL 交互图覆盖。