01. 模型怎样从例子中学习
快递系统拿到包裹重量后,需要给出运费。如果价格表已经明确规定“每千克 2 元,固定费用 1 元”,程序直接计算即可。如果只有一批过去的重量和运费记录,希望找出一个能近似这些记录的关系,就可以从一个小模型开始。
这是系列的起点,不要求先懂神经网络或导数。本篇先分清数据、模型和参数,读完应能解释训练改变了什么,以及什么情况下没有必要训练模型。
先观察同一条预测怎样改变
以下三条记录是按已知公式构造的教学数据,不是物流报价。实际计费还可能受首重、地区、体积和折扣影响。
| 重量 / 千克 | 目标运费 / 元 |
|---|---|
| 1 | 3 |
| 2 | 5 |
| 3 | 7 |
先选一个简单关系:预测运费 = w × 重量 + b。可以把它看成一个有两个旋钮的计算器:w 控制每增加 1 千克,运费增加多少;b 控制与重量无关的固定费用。这两个可以调整的数称为参数。用这个计算关系来近似重量与运费的联系,就是建立了一个模型。
w、b 只是给两个数起的名字,并没有神秘含义。这里用字母,是因为接下来要反复改变它们;如果一直把数字写死,就不容易讨论“哪一个数应该怎样改”。
把 w 和 b 都设成 0,输入 2 千克,模型预测 0 元;改成 w=2,b=1,同一输入得到 5 元。数据没变,计算形式没变,变化的是模型使用的参数。图中的竖向虚线显示预测与记录中的运费相差多少。后面会把这些偏差变成一个“错误得分”,称为损失:在同一套评分规则下,分数越低,模型越贴近这些记录。
让模型的输出贴近已有记录,称为拟合。在这三条人为构造的记录上,参数 2,1 恰好完全匹配数据。真实计费是否也能用这条线描述,还需要更多记录和实际计费规则来检验。
训练和使用是两个过程
刚才是人把旋钮直接调到 2,1。如果记录有成千上万条、参数也远不止两个,人就很难逐个试出合适数值。训练就是让程序代劳:同时读取重量和目标运费,先预测,再比较偏差,按一定方法修改 w 和 b。不断重复,就得到一组更符合这些记录的参数。这里的“学习”,具体发生在参数数值的变化上。
使用模型时,只需给它新的重量,让它按已有参数计算。这个过程称为推理,通常不需要提供这次预测的真实运费,也不会因为收到一条输入就自动更新参数。
把输入顺着计算式变成预测,叫前向计算;再从预测的错误出发,寻找各个参数应怎样调整的线索,就是图中的“反向求梯度”。梯度记录局部变化的方向和程度,优化器按选定规则利用这些线索修改参数。现在先沿箭头看这一圈怎样接起来,到第 07 篇再计算它们。
这一圈重复的是“预测、比较、调整”,每次都用上次改完的参数。旁边的验证分支像做一次检查,只观察表现,不在这个分支里修改参数。
训练程序负责决定修改方法。模型文件保存已经得到的参数。推理程序读取文件并执行计算。这三个对象可以分别运行,因此模型训练完成后,另一个程序也能加载它,而不必重新训练。
图片识别为什么也是这个思路
把一张数字图片放大,会看到许多小格子,这些格子称为像素。程序可以用数字记录每格的明暗,把整张图作为输入;输出则给 0—9 各一个分数,表示当前模型更倾向于哪个数字。分数最高的类别就是它这次的判断。
要把许多像素组合起来判断形状,通常需要比一条直线更丰富的计算。把多层带参数的计算连接起来,就得到后面要学的神经网络。先把眼前两个参数怎样学习弄清楚,再增加层数和参数,基本问题仍是:输入什么、期望得到什么、错了以后怎样改。
图片里写了一个“3”,训练时把正确答案 3 和图片一起提供,这个答案称为标签。模型先按当前参数打分,再根据正确答案调整。空白图片、未见过的书写方式或拍摄背景,都可能让它出错;即使输入空白图,十个分数中仍会有一个最高。后续需要专门检查它对新图片的判断,不能只看它是否给出了答案。
什么时候直接写规则
运费已经有正式价格表时,应按价格表计算。训练出一个近似公式,反而可能违反真实计费规则。训练更适合目标关系难以完整写成规则、同时有代表性数据和可验证目标的任务。
模型形式规定计算,参数决定当前输出,训练用样例修改参数,推理使用已有参数。接下来先准备一个能执行和修改代码的环境:02. 准备运行第一个实验。之后用这三条运费记录,逐步完成一次真实可运行的训练循环。
