从0训练LLM · 现代大模型体系 阅读 + 实验 ≈ 35 分钟 页内实验 ×2
D 深度学习地基:机器怎么从例子里学会规律 第 6 课

训练越来越好,新数据却越来越差?

过拟合与验证集
我们自己的 3.7M 参数模型在 50 万 token 上训 1,500 步:训练 loss 从 3.90 降到 0.70,验证 loss 却在第 300 步见底(4.771)后一路升到 6.906。只看训练 loss 会把一个正在背书的模型当成越来越好。留出验证集、在最低点停下、加权重衰减、多给数据——四种办法都在浏览器里真训练一遍。
❓

本课一问:第 5 课加了非线性,四句组合题的训练 loss 降到 0.0006。模型越强,训练 loss 就能压得越低。可训练 loss 低,就等于模型学好了吗?

这一课先不碰:dropout(我们的项目模型没有用它);验证集怎么切(C0 章首页);模型该多大、数据该多少(C6);评测集被训练数据污染(C14)。

从已有出发

第 1 课的迷你模型训练 400 步,7 个例子全对,平均 loss 0.030;第 5 课 4 句话 loss 0.0006。可那 7 句、4 句就是它见过的全部——「小猫 喜欢 吃 ___」答对,可能是学到了「猫爱吃鱼」,也可能只是把这 7 句背下来了。例子只有这么几句时,分不清这两种情况,所以这一课换到真语料:要有大量「没见过」的文本,才量得出区别。

从已有出发 · 从例子里学的一整圈(点任一环节看它在迷你模型和 Qwen/Qwen3.8-27B 里多大) 本课本章后面的课
训练一个网络要的东西,是一件一件被真数字逼出来的(点名字去那一课;完整版在章首页)
  1. 手写规则 / 把例子背成一张表
  2. 带参数的模型:用例子调数字
  3. 交叉熵:正确答案概率的负对数
  4. 梯度下降
  5. 反向传播(反向模式自动微分)
  6. 非线性多层网络
  7. 验证集、早停与正则化
  8. 深度学习为什么是经验性的
  9. 词向量:按编号查表
第六代验证集、早停与正则化早停 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 课)。
数字口径:one-hot 维数与乘加次数由锚点 Qwen3.8 的 config 构建时现算;迷你模型(种子 3)、四句组合题(种子 3)、真语料小网络(种子 1)的数字来自本章各课组件的默认设置,浏览器里现场复算;4.771 / 6.906 来自项目真实日志 d00-foundations.json。年份按原始文献核对(2026-09-26)。

先自己设计:训练 loss 越低越好

最自然的做法:训练 loss 还在降,就继续训。下面是我们自己从 0 训练的 3.7M 参数模型(04-实践项目),和基线配置完全相同,只把步数从 400 拉长到 1,500。训练 loss 和验证 loss 都在固定的 228 个窗口上评估,口径完全一样:

  1. ① 朴素方案
  2. ② 它在哪失败
  3. ③ 改进方案
朴素方案只看训练 loss,一直训下去
项目实测 · 训练 loss 与验证 loss(同口径,每 50 步评估一次)

🎯

试三件事:① 先在紫色框里猜,再看完整曲线;② 把指针移到第 300 步和第 1,500 步,读训练与验证的差:0.87 → 6.20;横轴下面紫色的是 epoch——1,500 步时 50 万 token 已经被看了 24.5 遍;③ 勾上「小批次训练 loss」:训练时实际优化的是这条毛糙的线,它和固定窗口评估的训练 loss 走势一致。

它在背什么:浏览器里再做一次

项目模型太大,不能在页面里重训。换回真语料小网络,故意只给它 2,000 字训练,训 3,000 步,再看验证集上发生了什么:

训练集越小越会背书:早停与权重衰减 字级 MLP · 24,896 参数 · 《三國志演義》24,000 字 · 浏览器内真训练
等待开始(滚动到这里会自动开始)

数字来源:浏览器实时训练(纯 JS,Float64)。模型、语料、种子写在上方;同一组对照里所有 run 共用初始化和取批顺序,只改被比较的那一项。换种子重跑能看到噪声多大——差异小于种子间波动时不下结论。

🎯

试三件事:① 默认(2,000 字、λ = 0):验证 loss 在第 100 步最低(3.935),3,000 步时升到 11 以上;看表格最后一列,「九成把握却猜错」从 0.3% 涨到三成以上;把指针移到曲线上,提示框里是那一步模型对两个验证集上下文的前 3 名,越往后越自信、越离谱;② 训练集换成 6,000 字、再换成全部 23,865 字:过拟合来得越来越晚、越来越轻(全部数据时 3,000 步 3.646);③ 回到 2,000 字,λ 依次换成 0.001、0.003、0.01:3,000 步后的验证 loss 分别是 5.503、4.064、3.789,训练 loss 也不再降到很低。

验证 loss 升上去,主要不是模型「变笨」了:第一名猜对的比例从 33.6% 降到 22% 左右,降得不多;真正的变化在把握上——平均最大概率从 32.2% 涨到接近 80%,三分之一的验证位置上它九成把握押在一个错字上。第 2 课说过,−ln 对自信的错误罚得最重:押错时 p(正确答案)接近 0,−ln p 就爆炸。背下来的续写被自信地用在了新文本上。

一个旁注:2,000 字、λ = 0 这一组的终点在不同浏览器上会差零点几(作者的 Chrome 上 3,000 步时 11.46,node 上 11.27;前 1,300 步逐位相同)。训练把模型推到很尖锐的地方之后,浮点运算最后一位的差别会被一步步放大——所以页面上对这一组只说「11 以上」。其余几组(加了 λ、或数据更多)在两处逐位一致。

改进:三件对抗过拟合的事

  1. 验证集 + 早停:上面两张图的绿色竖线。它不改模型,只决定留哪一份参数。
  2. 更多数据:2,000 → 23,865 字,同样的模型背不下来,只好学共性。这是最根本的办法,也最贵(C6、C7)。
  3. 正则化:在 loss 里加一项,惩罚「参数太大」,让模型没法把每个例子都拟合得很细。最常用的是权重衰减:
L2 正则与权重衰减(本章的纯梯度下降下两者等价)
= + ⟹ θ ← − η·∇L
👆 公式里带下划线的每一项都可以点——点哪项,讲哪项。
用 Adam 这类优化器时,「加进 loss」和「每步直接缩小」不再等价,现代做法是后者(AdamW)——C5 第 3 课专门讲这个区别。

另一种常用的正则化是 dropout(训练时每次随机关掉一部分单元),我们的项目模型没有用它。

⚠

常见误解一:「验证 loss 上升,说明模型把学过的东西忘了。」

训练 loss 还在降,它没忘;它是在更细地记训练集,并把这些记忆自信地套到新文本上。上面的「九成把握却猜错」从 0.3% 涨到三成以上,就是这件事。

常见误解二:「过拟合 = 模型太大。」

模型太大、数据太少、训得太久,三者任何一个都会让它出现:项目模型 3.7M 参数不算大,是 50 万 token 被看了 24.5 遍。而且「更大的模型更容易过拟合」这条经典直觉在现代深度学习里经常不成立——模型大过某个程度之后,测试误差会再次下降(双下降)。岔路课展开。

常见误解三:「验证集可以反复用来挑超参数。」

每用验证集挑一次(学习率、λ、步数……),验证集的信息就漏进一点到你的选择里;挑得足够多,你会在验证集上也过拟合。所以要再留一份只在最后看一次的测试集。C14 讲评测数字该信几分。

常见误解四:「训练 loss 越低越好。」

训练 loss 只说明对训练集拟合得多好。要看的永远是验证 loss;两条线的差距越拉越大,就是警报。

🔍 这三种办法是谁提出的?

用一份独立数据决定何时停止迭代、防止「过度训练」,在 1989 年的神经网络论文里已经出现(Morgan 与 Bourlard,NIPS 2);Prechelt 1998 年的《Early Stopping — But When?》系统比较了各种停止准则。给权重加惩罚项在 1980 年代后期的反向传播研究里已在使用(如 Hanson 与 Pratt,NIPS 1988),Krogh 与 Hertz 1991 年从理论上解释了权重衰减为什么能改善泛化。Dropout 由 Hinton 等 2012 年提出、Srivastava 等 2014 年系统发表。「谁提出」与「谁解释了为什么有效」常常是两批人;写出处时分开写。

证据三问

问本课的回答
① 它解决什么问题?训练 loss 只量「背没背下来」;要一个量「在没见过的数据上怎么样」的读数,并据此决定何时停、要不要加约束
② 数学上为什么可能有效?L2 正则等价于给参数加一个高斯先验后的最大后验估计 ;「参数小 → 函数平滑 → 不容易贴着噪声走」是动机
③ 实验上呢?项目模型:验证最低在第 300 步,之后升到 6.906 ;浏览器里:数据越少越早过拟合,λ = 0.003 把 3,000 步后的验证 loss 从 11 以上拉回 4.064

一句话

📌

训练 loss 只说明背没背下例子;没见过的数据要用验证集单独量——验证 loss 开始上升的那一刻,就该停下或加正则。

🚦

先停在这里:记住「看验证 loss,不看训练 loss;最低点停下」。
再深一层:在组件里把 3 种数据量 × 4 个 λ 都跑一遍,画一张自己的表。然后去岔路课:为什么「模型越大越过拟合」这条直觉会失灵。

下一个缺口

前六课都在数上打转——可输入的是词,离散的词怎么进网络? → 第 7 课:离散的词怎么进网络?

岔路:深度学习为什么是经验性的?——这一课的每个结论(第 300 步最好、λ = 0.003 管用)都是跑出来的,不是算出来的。

你可能会问