五步固定动作:把原理变成一个跑得起来的项目
这一章讲三件事: 第 08 章那些式子今天由谁来算; 一个深度学习项目从头到尾的五个固定格子长什么样; 以及两笔欠账 —— 归一化对训练到底有什么好处、分类任务为什么换一把尺子。 它在全书链条里的位置是第 8 级台阶:原理讲完了,这一章把原理变成工程。 从这一章起,后面每一个项目(斑马线、巡航、检测)都是这五个格子的一次填空。 遇到的生词都在当场解释。
1. 顶层全景
第 08 章走完的地方:你已经会手算一个十参数网络的每一次更新
│
│ 可是第 13 章那个巡航网络有几十万个参数,
│ 第 11 章讲到的一个模型有 1.38 亿个 —— 手算是不可能的
▼
① 有人替你算 ──────────── 深度学习框架(第 2 节)
│ 你写下的每个运算它都记进第 08 章那张计算图,
│ 你说一句「回传 」,它沿着图倒着走一遍
▼
② 有一套固定流程 ──────── 五步固定动作(第 3 节)
│
├─ 第一步「数据处理」是五件小事 ────────── 第 4 节
│ 其中归一化最容易被跳过、后果最大
│
├─ 第三步「训练」要先挑一把尺子 ────────── 第 5 节
│ 分类任务不用平方误差,用交叉熵
│
├─ 走一遍:一张汽车图从进来到吐出答案 ──── 第 6 节
│
└─ 第四步「评估」看什么 ───────────────── 第 7 节
一条随训练次数下降的曲线,以及一句老实话
图说:这一章的主走查是第 6 节那张汽车图。
第 4 节的归一化、第 5 节的交叉熵,都在那条走查上各占一步。
一条口径先写死,因为它和第 08 章那条差一个字,混了后面全乱:
| 说法 | 意思 | 谁在用 |
|---|---|---|
| 更新一次 | 拿一批数据算一次梯度、改一次参数 | 第 08 章全章 |
| 一轮(epoch) | 整个训练集完整过一遍 | 本章起,第 13、15 章一律这么说 |
这两个数差得非常远。 举个具体的:训练集有 10000 张图,一次拿 32 张来算 —— 那么一轮 = 313 次更新(10000 ÷ 32,最后一批不满也算一次)。
那两个数是为演示编的,不是书里的数。 书从头到尾没说过任何一个项目一次拿几张来算, 第 13 章那个巡航项目连训练集有多少张图都没交代。
所以后面看到「训了 300 轮」时(第 13 章那个巡航模型就是 300 轮), 你只知道整批数据被翻来覆去过了 300 遍,换算不出它到底改了多少次参数。
2. 你不用自己写第 08 章那些式子
现象先行:一行,和一整页
第 08 章第 6、7 节那一堆「三项相乘」,你自己算过一遍,应该有体会: 十个参数就写了一整页。
书对这件事的态度很干脆:借用现成的开源工具, 「复杂的反向传播算法只需要一行调用误差反向传播的程序语句就能完成」1。
这类工具叫「深度学习框架」
框架这个词在软件里到处都是,意思是:一套写好的骨架,你只往里面填自己那部分。 深度学习框架填的是三样东西 —— 网络长什么样、拿什么数据喂、用哪个优化器。 其余的(前向怎么算、梯度怎么回传、显卡怎么调度)它全包了。
它靠什么包的?就是第 08 章最后那张计算图。 你写下的每一个运算,它都悄悄往图上添一条边,外加一个存放这一步结果的节点; 你说一句「反向传播」,它沿着图从后往前走一遍,把所有梯度算出来。 你不用写那些式子,是因为图替你记住了每一条边。
(「节点是数据、边是运算」沿用第 08 章第 9 节定下的口径。 那一节也点明了: 框架自己的文档里,「节点」指的是运算,方向正好反过来。)
书介绍的三个
先解释两个词,不然三个框架的名字和定位都读不懂。第一个是「张量」 —— 第 08 章末尾一句话带过它是「一堆按维度码好的数」,这里按书自己的阶梯完整走一遍。
书在讲第一个框架的名字来历时,给了一道很好懂的阶梯: 一个数叫标量(比如转角 0.5);一排数叫矢量(也叫向量,比如 [0.5, 0.7]); 一个方阵那样的表格叫矩阵(第 04 章那张写满 0—255 的灰度图就是)2。
沿着这道阶梯再往上推 —— 按任意多个维度码好的一堆数,统称张量。 一张 128×128 的彩色图,就是一个 128×128×3 的三维张量。 这正是第 04 章讲的「图像是一个数组」,换了个正式的名字。
第二个词是 GPU,书从头到尾没解释过它。 它本来是显卡里画图用的芯片,里面有成千上万个小计算单元, 特点是「同一件事同时做几千遍」。
神经网络那些乘加恰好就是这个形状,所以显卡被拿来算模型 —— 这就是为什么训练模型要抢显卡,而不是抢 CPU。(补充:不在书里,来自通用知识。)
现在看这三个框架:
| 框架 | 书给的关键事实 |
|---|---|
| TensorFlow | Google 大脑小组开发,是谷歌基于 DistBelief 研发的第二代;2015 年 11 月 9 日开源。名字直译就是「张量在数据流图上流动」—— 而「数据流图」正是第 08 章那张计算图的另一个叫法(按第 08 章定下的口径:节点是数据,边是运算;书在介绍这个框架的组件时换成了相反的叫法,那一处第 08 章第 9 节已判过)3 |
| PyTorch | 前身是 torch,由 torch7 团队开发。书给的定位很好记:「可以看作是加入了 GPU 支持的 numpy」,也可以看成「一个拥有自动求导功能的深度神经网络」4 |
| PaddlePaddle(飞桨) | 百度出品,书称它是**「中国首个自主研发、功能完备、开源开放的产业级深度学习平台」;书列的四大优势里最实的一条是官方模型库超过 270 个**5 |
本书为什么只用飞桨:两个理由要分开
这是「三个声音」必须分开的一处。
| 理由 | 属于哪个声音 |
|---|---|
| 这是百度冠名的赛项,组委会规定必须用(第 01 章讲过) | 主办方的规则 —— 和技术优劣无关 |
| 书说它「虽然起步较晚,但发展速度非常迅速……相信它会为我国自主产权的人工智能技术发展奠定更好的基础」6 | 编者的价值判断 —— 不是技术论证 |
判断(我们的,不是书里的): 这三个框架在本书用到的这些功能上几乎没有差别 —— 定义网络、算损失、调优化器、保存模型,三家的写法都是一一对应的。 所以「这本书用飞桨」这件事不该影响你读它的技术内容, 但它确实影响了另一件事:书里所有的项目链接、部署工具、标注平台都锁在同一家的生态上, 你不用那一家,后半本的操作步骤就照搬不了。 如果错,会错在: 如果某个功能在飞桨上有而别家没有(比如某块国产芯片的部署支持), 那这条选择就不只是规则,也是技术约束。判据是:换成另外两个框架, 第 13、16 章那两条部署路线还走不走得通。
3. 五步固定动作
这是本章的骨架,后面七章都挂在它上面。
现象先行:每个项目都得从头设计吗
书的回答是 不用:「无论是图像分类、目标检测还是文字识别,尽管任务不同, 但是利用深度学习完成这些任务的基本框架都是相似的」7。
① 数据处理 ── 把原始数据变成模型能吃的东西(第 4 节展开)
▼
② 模型设计 ── 选网络类型、几层、怎么连
▼
③ 模型训练 ── 喂数据 → 算损失 → 优化器改参数;这一步要挑超参数
▼
④ 评估调优 ── 用没训过的数据考它;不行就回 ② 或 ③(第 7 节展开)
▼
⑤ 部署应用 ── 装到硬件或服务器上真的用起来(第 13、16 章展开)
图说:注意 ④ 有一条回头箭头 —— 这五步不是一条直线,是一个圈。
「不行就回去改」是常态,不是意外。
「超参数」这个词书用了没解释,就地补上: 模型里那些学出来的数叫参数(第 05 章那些权重和偏置); 而学之前由人拍板定下、学习过程中不会自己变的数,叫超参数。
学习率(第 06 章)、一次拿多少张来算(批大小)、总共训多少轮,都是超参数。 一句话记住:参数是机器定的,超参数是人定的。
书给了两个例子:第三步要选的超参数是学习率和批量大小8, 第四步不行的时候,可以「调整模型架构、优化算法或超参数」再来一遍9。
这五步在这本书里各走了几遍
| 项目 | 在哪一章 | 任务 |
|---|---|---|
| 车辆三分类 | 原书 §8.4,本章第 6 节 | 汽车 / 摩托车 / 货车 |
| 斑马线二分类 | 原书 §9.4,我们的第 10 章 | 有斑马线 / 没有 |
| 自动巡航 | 原书 §10.3,我们的第 13 章 | 吐一个 −1 到 1 的转角 |
| 目标检测 | 原书 §11.3—11.5,我们的第 15、16 章 | 框出来 + 认出来 |
4. 第一步是五件小事,其中一件最容易被跳过
这是本章第一个承重点。
书给的清单
书把「数据处理」拆成五件10:
| # | 做什么 | 在这本书的别处 |
|---|---|---|
| ① 数据导入 | 从硬盘把文件读进来 | 第 03 章讲过句柄和逐行读 |
| ② 形状变换 | 把图统一成同一个尺寸 | 第 04 章讲过 resize |
| ③ 数据集划分 | 切成训练集和测试集 | 第 03 章讲过四步(含为什么必须先乱序) |
| ④ 归一化 | 把每个数压到 0—1 之间 | 第 05 章讲过它最朴素那一层 |
| ⑤ 数据封装 | 把样本打包成一批一批的 | 第 08 章讲过「一次拿一小批 」 |
书对第三件给了一句口径: 训练集用于训练确定模型参数, 测试集用于测试评判模型效果10。这和第 03 章那四步是同一件事,这里不重讲。
第五件还了第 03 章那笔账。 那一章讲过大文件必须分行读入、逐行处理,
因为 read() 和 readlines() 会把整个文件一次搬进内存。
「数据封装」是同一个道理在训练这一头的样子:
❌ 一次把 16000 张图全读进内存,再喂给模型
—— 一张 224×224×3 的图占 15 万个数;16000 张就是 24 亿个数,内存装不下
✅ 打包成一批一批的:每次只把 32 张读进来、算完、扔掉,再读下一批
—— 内存里同时只有 32 张,不管数据集有多大都一样
图说:所以「封装成批」不是为了写起来方便,是**内存逼出来的**。
这也正是第 08 章那三档梯度下降里「一小批」那一档在工程上的落地方式。
(24 亿这个数是我们按 16000 × 224 × 224 × 3 算的;这个图片尺寸是我们假设的。)
第四件:归一化,以及它对训练的两个好处
第 05 章讲过它最朴素的那一层:把量程不同的数按同一把尺子压到同一个区间 —— 那里是把摇杆能转的幅度压成 −1 到 1 之间的小数。 这一节还的是当时欠的账:它对训练本身有什么好处。
书给的两条都很具体10:
好处一:让不同参数的损失曲线变规则,于是学习率能设成统一的一个值。
这条得掰开讲,不然只是一句好听话。回想第 06 章那个「蒙眼下山」—— 学习率决定每一步迈多大。 现在设想两个参数的量程差得很远:
❌ 不归一化:
参数 A 对应的输入是「像素值」,范围 0—255
参数 B 对应的输入是「图片宽高比」,范围 0.5—2
同一个学习率迈下去:
对 A 来说这一步太大 —— 在谷底两边来回振荡,收不住
对 B 来说这一步太小 —— 挪了半天几乎没动
⇒ 一个学习率伺候不了两个参数
✅ 归一化之后:
两个输入都被压到 0—1
⇒ 同一个学习率对谁都合适,一个数就够了
图说:这就是书说的「loss 是一个较为规则的曲线」——
规则的意思是「各个方向的陡峭程度差不多」,不是「好看」。
(0—255 和 0.5—2 这两个范围是我们为演示举的例子,不是书里的数。)
好处二:每个特征的权重大小可以直接当作这个特征的贡献度。
「特征」这个词在这里首现,就地讲清: 特征就是你喂给模型的那一项项输入。 预测一辆车的续驶里程时,「电池容量」是一个特征、「整车质量」是另一个特征; 在图像任务里,每一个像素值就是一个特征。
为什么归一化之后权重才能当贡献度看:
❌ 不归一化:
特征 A(电池容量,单位 kWh)取值 60,权重 0.5 → 贡献 30
特征 B(整车质量,单位 kg) 取值 1800,权重 0.02 → 贡献 36
权重 0.5 比 0.02 大二十五倍,但贡献其实是 B 更大 ——
**权重大小完 全说明不了谁更要紧。**
✅ 归一化之后(两个都压到 0—1):
两个特征的量程一样了,谁的权重大谁就真的更要紧。
图说:书只给了「可以直接代表贡献度」这个结论,
中间这笔账是我们算的,数字是为演示编的。
为什么这一步最容易被跳过
因为跳过它模型照样能跑。 它不报错、不崩溃,只是训得慢、训不好, 而且看起来像是学习率没调对。 所以书才把这五件事并列写出来 —— 它是清单里最不像必需品的一件,却是后果最大的一件。
5. 分类任务换一把尺子:交叉熵
这是本章第二个承重点,还的是第 07 章 Softmax 那一节和第 08 章第 2 节 欠下的账。
现象先行:平方误差在分类上会给出奇怪的分数
第 06 章那把平方尺子量的是「两个数隔多远」。这在预测转角这种题上很自然: 真值 0.5,你答 0.4,差 0.1。
可分类题的答案不是一个数,是「哪一类」。 第 07 章讲过,分类模型最后一层是 Softmax —— 它把一串数压成加起来等于 1 的一组可能性。三分类的输出长这样:
模型说: 汽车 0.7 摩托车 0.2 货车 0.1 (加起来 = 1)
正确答案:汽车 (写成 1, 0, 0)
现在问题来了:这次答得算好还是不好? 「0.7 和 1 差 0.3」这种量法当然也能算,但它有个毛病: 答错得非常笃定的时候,它罚得不够狠。
比如模型咬定「货车 0.99」而正确答案是汽车 —— 按平方尺子, 每一项最多也就差 1,总账封了顶。而这种错误明明比「三个都是 0.33 分不清」要严重得多。
做法:换一类尺子,量的是「两组可能性差多远」
第 08 章第 2 节提过一句:损失函数分两大流派,一派量两个数隔多远, 另一派量两组可能性差多远11。交叉熵就是第二派里最常用的那一个, 分类任务基本都用它。 书在讲 Softmax 时也点了这对搭档: 「Softmax 层常和交叉熵损失函数一起结合使用」12。
它怎么算(书没给算法,这一段是补充,来自通用知识): 只看正确答案那一项,把模型给它的可能性取对数,再加个负号。
模型说「汽车 0.7」,正确答案就是汽车
罚分 = −ln(0.7) = 0.357
同一道题,换几种答法看罚分怎么变:
答 0.99(几乎确定,而且对了) → −ln(0.99) = 0.010 几乎不罚
答 0.70(有点把握,对了) → −ln(0.70) = 0.357 小罚
答 0.33(三个都分不清) → −ln(0.33) = 1.109 中罚
答 0.05(几乎排除了正确答案) → −ln(0.05) = 2.996 重罚
答 0.01(咬定不是它) → −ln(0.01) = 4.605 往上没有头
图说:一条规律就够记住 —— **答对得越有把握罚得越轻,答错得越笃定罚得越狠,
而且往上不封顶。** 这正是平方尺子给不了的那一半。
(「对数」是这么一件事:ln(x) 回答「e 连乘几次得到 x」;
我们只用到它的一个性质 —— x 越接近 0,−ln(x) 越大,而且大得没有上限。)
「交叉熵」这个名字里的两个字要分开看 —— 它和「 熵」不是同一件事。 熵量的是一组可能性自己有多不确定; 交叉熵量的是「你猜的那组可能性」和「真实的那组」差多远。 本书从头到尾只用到后者。(补充:不在书里,来自通用知识。)
边界:它只在「答案是类别」的时候好用
回归任务不能用它。 第 13 章那个巡航模型要吐一个 −1 到 1 的连续数, 那里用的仍然是平方误差 —— 而且书在那一章专门解释了为什么(第 13 章讲)。
6. 主走查:一张汽车图走完五步
这是本章的主走查。上面每个机制都在这条链上占一步。
书里这个项目的任务: 三分类 —— 1 = 汽车、2 = 摩托车、3 = 货车, 数据来源是 2005 年 PASCAL 视觉类挑战赛(VOC2005) 那批数据筛选处理来的13。
━━ ① 数据处理 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
导入: 从压缩包里解出图片,一张 500×375 的汽车照片
读进来是一个 375×500×3 的张量(高 × 宽 × 三个颜色通道)
↑ 这就是第 04 章那句「图像是一个数组」
形状变换:统一 resize 到 224×224
⇒ 张量变成 224×224×3,一共 150528 个数
划分: 全部样本先用 shuffle 打乱,再按 9:1 切成训练集和验证集 ← 书给的比例
(**为什么必须先打乱**,第 03 章讲过:解压出来同类型基本挨着排,
不打乱模型会连着看几百张汽车再连着看几百张货车)
归一化: 每个像素除以 255
某个像素原来是 178 → 变成 0.698
⇒ 150528 个数全部落在 0—1 之间 ← 第 4 节那两个好处在这里生效
封装: 把样本打包成一批 32 张
⇒ 送进模型的东西是一个 32×150528 的张量
━━ ② 模型设计 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
书用的是全连接网络(第 07 章那种,每层每个神经元都连到上下层全部神经元)
输入层 150528 个数 → 若干隐藏层 → 输出层 3 个神经元(三个类别)
最后过 Softmax,把 3 个数压成加起来等于 1 的三个可能性
⚠ 这里埋着一颗雷:150528 个输入接一个全连接层,参数量会爆炸。
**这正是第 10 章要解决的问题** —— 书自己在下一章开头就把这笔账算给你看。
━━ ③ 模型训练 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
尺子: 交叉熵 ← 书给的
优化器:Adam ← 书给的(第 08 章讲过:每个参数各自调步长)
学习率:0.1 ← 书给的
第 1 轮第 1 次更新(这一批 32 张里第一张是汽车):
模型说 汽车 0.31 摩托车 0.36 货车 0.33
罚分 −ln(0.31) = 1.171
⇒ 反向传播算出每个参数该往哪挪(第 08 章那套)
⇒ Adam 照方向改一次参数
一轮 = 训练集全部过一遍。假设训练集 900 张、一批 32 张,
那么**一轮 = 29 次更新**;训完 50 轮 = 1450 次更新。
第 50 轮的同一张图:
模型说 汽车 0.97 摩托车 0.02 货车 0.01
罚分 −ln(0.97) = 0.030 ← 从 1.171 降到 0.030
━━ ④ 评估调优 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
拿那 10% 没参与训练的图去考它,记下答对的比例;
同时把每一轮的损失和准确率画成两条曲线(第 7 节讲怎么看)
━━ ⑤ 部署应用 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
这个项目到此为止。真正的部署在第 13、16 章 —— 那里要塞进车上那块小板子。
━━ 最后:拿一张全新的图问它 ━━━━━━━━━━━━━━━━━━━━━━━━━━━
书给的结果是:**汽车 1.00,摩托车 0.00,货车 0.00**
上面这条走查的骨架全部有出处: 模型是全连接网络14, 9:1 的划分、交叉熵、Adam、学习率 0.1 是书给的训练配置15, 末尾那三个数是书给的预测结果16。
这条走查里哪些数是书给的、哪些是我们编的:
| 书给的 | 我们为演示编的 |
|---|---|
| 三个类别、数据来源、9:1 划分、交叉熵、Adam、学习率 0.1、最终预测 1.00 / 0.00 / 0.00 | 图的原始尺寸、224×224、批大小 32、训练集 900 张、50 轮、以及中间那两组可能性(0.31 / 0.97) |
编的那些是为了让每一步有具体的数可看。书里这个项目不附代码, 只给了一个在线项目链接17—— 所以中间过程的数字书里本来就没有。
7. 怎么知道模型好不好
第一条:必须用没参与训练的数据
书说得很直接:模型用训练集训完之后,要用与训练集不同的验证集数据来评估18。
为什么(第 03 章埋过这个账,这里还): 拿训练过的数据去考它, 等于让学生做他刚背过的那套卷子。分数漂亮,说明不了任何事。 这就是第 07 章讲的过拟合会藏起来的地方 —— 模型把训练那批背下来了, 只有在没见过的数据上才露馅。
第二条:看曲线,不看单个数
这一节把第 06 章欠的那个账也还了:训练什么时候该停。
书在讲绘图库的时候给了这条曲线的定义: 「loss 是指模型预测结果与真实结果之间的差距,通常情况下,模型的 loss 越小越好; accuracy 是指模型的准确率……通常情况下,accuracy 越高越好」19。 配套的数据文件三列:参数更新次数、损失值、准确率20。
画它用的是一个叫 matplotlib 的绘图库。 它有两个概念是父子关系, 书特意讲清了21:
| 叫什么 | 是什么 |
|---|---|
| figure | 画板 —— 整张图 |
| axes | 画板上的一张子图 —— 一个真正画东西的方框 |
书还专门澄清了一处容易读岔的地方:axes 从字面看是「坐标轴」的复数, 但它的意思远不止两条坐标轴 —— 它是画板上的一块子图区域, 里面除了坐标轴还有曲线、图例22。
损失
↑
0.9│●
│ ●
0.6│ ●
│ ●
0.3│ ● ●
│ ● ● ● ● ● ● ● ← 从这里开始几乎不动了
0.0└──────────────────────────→ 轮次
0 10 20 30 40 50
图说:这条曲线就是「该不该停」的依据。
前面陡、后面平 —— 平了之后再训,损失还会降一点点,但降得越来越没意义。
(这些点是我们为演示画的,不是书里的数。)
但曲线平了不等于就该停。 第 13 章有一个更狠的教训: 那个巡航模型训到 400 轮时损失比 300 轮更低,实车跑起来反而更差。 曲线只告诉你「还在不在学」,不告诉你「学到的东西有没有用」。
第三条:书自己的一句老实话
书在给出「汽车 1.00」这个漂亮结果之后,立刻自己泼了盆冷水: 「单张图片的结果并不能准确反映出模型的效果」, 一般要有一个测试集,靠多样本的预测准确率才反映得出模型的真实水平16。
这句话值得单独记住。 演示里挑一张答对的图给你看,是所有教程的通病; 书在自己的演示后面点破这一点,是诚实的。
指标不止「准确率」一个
书在第四步里提到要看准确性、精确度、召回率三类指标9。 这三个词后面两个在这一章还用不上,第 15 章会讲透 —— 那里会给一个具体的陷阱:正样本占 99% 的时候,无脑全答「有」也能拿到 0.99 的准确率。
8. 作者的判断与证据
| 说法 | 是哪一类 |
|---|---|
| 五步固定动作的划分 | 有证据(而且是全书后半段的实际骨架) —— 第 9、10、11 章的项目确实都按这五步走 |
| 数据处理的五件事、归一化的两个好处 | 有证据,而且写得很具体 —— 这是书里少见的「给了理由不只给结论」的地方 |
| 三个框架的事实(年份、出品方、名字来历) | 有证据,与公开资料一致 |
| 「飞桨……相信它会为我国自主产权的人工智能技术发展奠定更好的基础」 | 编者的价值判断,不是技术论断。 全书唯一的框架选择来自赛事规定,这一点第 01 章已经说清 |
| 飞桨的「四大优势」与那些规模数字(千亿稀疏特征、万亿参数、270 个模型) | 厂商口径的转述。 书没有给对比对象,也没有给测试条件 —— 当宣传材料读,不要当横向评测读 |
| 「单张图片的结果并不能准确反映模型的效果」 | 有证据,而且是作者的坦白 —— 这类自我泼冷水在教材里不多见 |
| 交叉熵怎么算、为什么答错得笃定罚得更狠 | 不在书里。 书只给了名字和「常和 Softmax 配对」,算法与那组罚分是我们补的通用知识 |
| 归一化那两笔账的具体数字 | 不在书里。 书给了两条结论,中间的推演是我们补的 |
9. 边界与局限
- 这一章对应原书 §8.3—8.4,外加第 7 章讲绘图库的那一节(§7.3.3—7.3.4)。 绘图库原来在第 7 章,离深度学习隔了一章;我们挪到这里,因为这是第一次真的需要靠曲线做判断。
- 书没有讲交叉熵怎么算。 它只出现在一张公式表格图片里,正文只说了名字和搭档关系。 第 5 节那套罚分是我们补的。
- 书没有讲批大小该取多少。 只说它是个超参数,没给任何选取依据。
- 书没有讲「训练集 / 验证集 / 测试集」三者的分工。 五步里说的是「训练集和测试集」,项目里做的是「训练集和验证集」, 最后又说「一般会有一个测试集」—— 三个词混着用,没有统一口径。 按通用做法:验证集用来调超参数、决定什么时候停,测试集只在最后用一次。(补充:不在书里,来自通用知识。)
- 书没有讲怎么防止过拟合。 第 07 章讲了这个病,治法要到第 11 章(Dropout)和第 13 章(数据这一侧)。
- 这个项目一行代码都没有。 书明说「由于代码篇幅较长,书中只做简单的步骤介绍,不附代码」, 给的是一个在线项目链接17。全书的代码、公式、表格都是图片,清洗出来的文本里一行都没有 —— 所以本章那段走查的中间数值全部是我们编的,已在当场标明。
10. 可带走的
全章主走查一行写完:
一张汽车图 → 读成 375×500×3 的张量 → resize 到 224×224 → 打乱后按 9:1 切 → 每个像素除以 255(178 → 0.698)→ 32 张打成一批 → 送进全连接网 + Softmax,第一次答「汽车 0.31」,罚分 1.171 → 交叉熵 + Adam(学习率 0.1)训 50 轮 → 同一张图答「汽车 0.97」,罚分 0.030 → 拿没训过的图考它 → 一张新图上书给的结果是 汽车 1.00 / 摩托车 0.00 / 货车 0.00。
上面加粗的六项里,9:1、学习率 0.1、以及最后那三个预测值(1.00 / 0.00 / 0.00)是书给的; 0.698、1.171、0.030 是我们按假设的图片尺寸和批大小算出来演示用的(明细见第 6 节那张表)。
- 第 08 章那些式子今天没人手写 —— 框架把你写的每个运算记进计算图, 一句「回传」就沿图倒着走完;
- 张量 = 一堆按维度码好的数 —— 一张彩色图就是一个三维张量, 这就是第 04 章「图像是数组」的正式说法;
- 五步固定动作:数据处理 → 模型设计 → 训练 → 评估调优 → 部署。 第四步有一条回头箭头,「不行就回去改」是常态;
- 参数是机器学出来的,超参数是人拍板定的 —— 学习 率、批大小、训多少轮都属后者;
- 一轮(epoch)= 整个训练集完整过一遍,和第 08 章的「更新一次」差得非常远: 训练集 10000 张、一批 32 张时,一轮 = 313 次更新;
- 数据处理是五件事,最容易被跳过的是归一化 —— 它不报错,只是让你以为是学习率没调对;
- 归一化的两个好处: 各个方向的陡峭程度拉平,一个学习率就够用; 量程统一之后,权重大小才真的代表这个特征有多要紧;
- 分类任务换一把尺子:交叉熵。 规律只有一条 —— 答对得越有把握罚得越轻,答错得越笃定罚得越狠,而且往上不封顶;
- 评估必须用没参与训练的数据 —— 否则等于让学生做他刚背过的卷子;
- 看曲线,不看单个数 —— 但曲线只告诉你「还在不在学」, 不告诉你「学到的东西有没有用」(第 13 章那个教训);
- 书自己的老实话:单张图片的结果不能反映模型的效果。
11. 原文地图
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| 框架的动机:反向传播只需一行调用 | 第8章 深度学习基础及车辆识别项目实践 | text/09-ch08.txt:335(搜「只需要一行调用误差反向传播」) |
| 张量:标量 / 矢量 / 矩阵一路往上推 | 第8章 深度学习基础及车辆识别项目实践 | text/09-ch08.txt:343(搜「张量是矢量概念的推广」) |
| TensorFlow:出品方、开源日期、四个组件 | 第8章 深度学习基础及车辆识别项目实践 | text/09-ch08.txt:341(搜「2015年11月9日」) · text/09-ch08.txt:345(搜「session(会话)」) |
| PyTorch:「加入了 GPU 支持的 numpy」 | 第8章 深度学习基础及车辆识别项目实践 | text/09-ch08.txt:349(搜「加入了GPU支持的numpy」) |
| 飞桨的定位与四大优势、270 个模型 | 第8章 深度学习基础及车辆识别项目实践 | text/09-ch08.txt:355(搜「中国首个自主研发」) · text/09-ch08.txt:367(搜「270个以上」) |
| 编者的价值判断(要与技术分开看) | 第8章 深度学习基础及车辆识别项目实践 | text/09-ch08.txt:337(搜「相信它会为我国自主产权」) |
| 五步固定动作 | 第8章 深度学习基础及车辆识别项目实践 | text/09-ch08.txt:373(搜「基本框架都是相似的」) · text/09-ch08.txt:377(搜「数据导入、数据形状变换」) |
| 归一化的两个好处 | 第8章 深度学习基础及车辆识别项目实践 | text/09-ch08.txt:377(搜「每个特征的权重大小可以直接代表」) |
| 训练要选的超参数;评估不佳怎么办 | 第8章 深度学习基础及车辆识别项目实践 | text/09-ch08.txt:381(搜「学习率、批量大小」) · text/09-ch08.txt:383(搜「准确性、精确度、召回率」) |
| 车辆三分类:三个类别与数据来源 | 第8章 深度学习基础及车辆识别项目实践 | text/09-ch08.txt:387(搜「2005PASCAL视觉类挑战赛」) |
| 书不附代码,只给在线项目链接 | 第8章 深度学习基础及车辆识别项目实践 | text/09-ch08.txt:393(搜「书中只做简单的步骤介绍」) |
| 训练轮数是个要先定的参数 | 第8章 深度学习基础及车辆识别项目实践 | text/09-ch08.txt:403(搜「训练轮数num_epochs」) |
| 9:1 划分;交叉熵 + Adam + lr 0.1 | 第8章 深度学习基础及车辆识别项目实践 | text/09-ch08.txt:407(搜「9:1的训练集与验证集」) · text/09-ch08.txt:417(搜「学习率lr定为0.1」) |
| 用验证集评估;「单张图片的结果并不能准确反映」 | 第8章 深度学习基础及车辆识别项目实践 | text/09-ch08.txt:423(搜「利用与训练集不同的验证集」) · text/09-ch08.txt:427(搜「单张图片的结果并不能准确反映」) |
| Softmax 常和交叉熵配对 | 第8章 深度学习基础及车辆识别项目实践 | text/09-ch08.txt:89(搜「Softmax层常和交叉熵损失函数」) |
| 损失函数两大流派 | 第8章 深度学习基础及车辆识别项目实践 | text/09-ch08.txt:109(搜「基于概率分布的损失函数」) |
| figure 与 axes 的父子关系;axes 不只是坐标轴 | 第7章 Python计算生态及机器学习概述 | text/08-ch07-7-python.txt:295(搜「figure是axes的父容器」) · text/08-ch07-7-python.txt:301(搜「远非2个或多个坐标轴那么简单」) |
| loss 与 accuracy 的定义;曲线数据的三列 | 第7章 Python计算生态及机器学习概述 | text/08-ch07-7-python.txt:313(搜「loss是指模型预测结果与真实结果之间的差距」) · text/08-ch07-7-python.txt:317(搜「第一列是模型训练参数更新次数」) |