第 3 章 · 前向与损失:为误差定价 本章要回答的三个问题:几万条数据怎么喂给网络才不撑爆内存?一个 batch 进网络到吐出预测值,中间每一步发生了什么?"错得离谱"怎么变成一个可以优化的数字?这三个问题分别由数据装载、前向传播、损失函数作答。 为什么会有这一章 第 2 章末尾,远征队集结完毕——模型能做前向了。但请注意一个尴尬的事实:到现在为止,我们喂给网络的还是凭空造出来的随机张量。真正的训练要从真实数据开始,而真实数据有三个麻烦:装不进内存、形状五花八门、标签格式和损失函数的期待对不上。 本章是远征正式开拔的一章。队伍的行进路线在本章变成一条清晰的流水线:数据从磁盘被分批装车(3.1),装车的批次推过网络得到预测(3.2),预测与标准答案的差距被折算成一个标量损失(3.3)。
本章要回答的三个问题:几万条数据怎么喂给网络才不撑爆内存?一个 batch 进网络到吐出预测值,中间每一步发生了什么?"错得离谱"怎么变成一个可以优化的数字?这三个问题分别由数据装载、前向传播、损失函数作答。
第 2 章末尾,远征队集结完毕——模型能做前向了。但请注意一个尴尬的事实:到现在为止,我们喂给网络的还是凭空造出来的随机张量。真正的训练要从真实数据开始,而真实数据有三个麻烦:装不进内存、形状五花八门、标签格式和损失函数的期待对不上。
本章是远征正式开拔的一章。队伍的行进路线在本章变成一条清晰的流水线:数据从磁盘被分批装车(3.1),装车的批次推过网络得到预测(3.2),预测与标准答案的差距被折算成一个标量损失(3.3)。这个标量是整场远征的"军情简报"——它告诉队伍离目标还有多远,也是第 4 章反向传令的起点。
很多人写训练代码写到能跑就停了,于是 loss 不降时束手无策。本章的目标是让你对流水线的每一段都能单独搭出来、单独验证——数据管道坏了能查数据,前向坏了能查形状,损失异常能查标签。
本章知识点清单:
__len__ 与 __getitem__ 各自被谁在什么时机调用;| 节 | 回答哪个问题 | 关键产出 |
|---|---|---|
| 3.1 数据装载 | 数据怎么分批进网络 | 一个能跑的自定义 Dataset 加 DataLoader |
| 3.2 前向传播 | 一个 batch 如何变成预测 | 逐层追踪的形状流水账 |
| 3.3 损失函数 | 误差如何折算成标量 | 选型表与标签格式对照 |
三节串起来就是训练闭环的前半圈:装车、行进、清点。
问:为什么验证集、测试集要分开,一个不够吗? 验证集参与你的决策——你按它的成绩调参、选模型、定早停,它已经被"用"过了。测试集要做的只有一次:所有决策做完之后的最终裁决。混用两者的后果是指标虚高,上线后现出原形。
问:batch size 是不是越大越好? 不是。大 batch 的梯度估计更稳、GPU 利用率更高,但泛化性能在过大时可能受损,而且 4.3 节会讲到它牵动学习率的重调。本册的建议始终是:从显存放得下的中等值起步,把它当联动参数调,而不是当性能旋钮猛拧。
问:合成数据能学到真东西吗? 装载、前向、定价的机制与数据真假无关,本册的贯穿案例刻意用合成数据换取"人人可跑、秒级复现"。等你把机制吃透,把数据源换成真实图像只是改一个 Dataset 类的事——3.1 节的两个角色拆分,就是为这一天的无缝替换设计的。
本章结束时,你手里有了一条完整的前向流水线和一个标量 loss。但 loss 目前只是个数字,没人知道该把每个参数挪多少。第 4 章反向传令:autograd 顺着 1.2 节埋下的"记账凭证"逐层回溯,把"每个参数该怎么改"算出来。前向与反向一接上,训练闭环就差最后一个环节——更新,那是第 5 章的事。