跳到主要内容

十二个特征,和一次不骗自己的评估

这一章讲三件事: 输入从一个数变成十二个数之后会冒出哪些新麻烦; 「差多远」这把尺子该怎么挑,以及挑不同的尺子会让模型偏向什么; 还有——你凭什么说这个模型好它在全书链条里的位置: 第 02 章教了「怎么训」,这一章教「怎么判」。 从这里开始,每训完一个模型你都要问同一个问题;而第 11 章会把这个问题再问一遍—— 那一章管的是反复评估时怎么不骗自己,这一章管的是一次评估怎么做才不骗自己。

1. 换个问题:十二个数预测一个数

第 02 章那个例子只有一个特征(文件大小)。现实里几乎不是这样: 你手上通常有一堆特征,而且事先并不知道哪个有用1

书换的这个问题是波士顿房价数据集——1970 年代末波士顿及周边约五百笔房产成交记录, 几十年来一直是统计学和机器学习的入门标准数据2。每条记录有 12 个描述性的数, 要预测第 13 个数:这个片区自住房价值的中位数,以千美元计

这 12 个特征长这样(书里给了一整张表,这里只挑出后面会用到的五个)3:

特征它是什么全数据集的平均值这一列的跨度(最大减最小)
CRIM城镇人均犯罪率3.6288.9
NOX一氧化氮浓度(每一千万份)0.5550.49
RM住宅平均房间数6.285.2
TAX每一万美元地产所交的税率408524
LSTAT未接受高中教育的已就业男性比例12.736.2

训练数据是三份 CSV 文件,不再写死在代码里;训练集约占三分之二,共 333 行4

下面这条真实记录,这一章从头走到尾:

{ crim: 0.3237, zn: 0, indus: 2.18, chas: 0, nox: 0.458, rm: 6.998,
age: 45.8, dis: 6.0622, rad: 3, tax: 222, ptratio: 18.7, lstat: 2.94 }

图说:12 个数,一个片区。犯罪率 0.3237,而税率 222 —— 记住这两个数挨在同一行里,
下一节整节都在讲它们挨在一起会出什么事。

2. 顶层全景

① 12 个数,量纲全不一样 crim 0.3237 挨着 tax 222
↓ 标准化:每一列各自减去自己的均值、除以自己的标准差
② 12 个数,全部落在 0 附近 大家站到同一把尺子上
↓ 一层密集层(13 个可调的数:12 个核 + 1 个偏差)
③ 一个数:预测的房价

④ 拿一把尺子量它离真值多远 —— 这一章换成「均方误差」

⑤ 先算基准:永远猜平均房价 85.58
⑥ 再算模型: 25.32 ← 只有摆在 85.58 旁边,这个数才有意义

图说:③ 和第 02 章一模一样,只是宽了 12 倍。真正的新东西全在 ①④⑤⑥ 四步上。

3. 第一个新麻烦:十二把不同的尺子

这一节回答:为什么不能把 12 个数原样喂进去。

看第 1 节那条记录:crim 是 0.3237,tax 是 222,相差近七百倍。 再看整个数据集的跨度:NOX 在 0.385 到 0.871 之间晃,TAX 在 187 到 711 之间晃5

为什么这是个问题? 回想第 02 章:模型给每个特征配一个可调的数,乘起来加总。 如果 tax 那一路的输入天然就比 crim 那一路大几百倍,那么同样把两个权重挪动 0.01, tax 那一路对输出的影响也大几百倍。于是训练一步下去,总有一个方向动得特别猛、 另一个方向几乎没动——书里的说法是「加剧训练方面的不稳定性,而且难以拟合模型」6

办法叫标准化(书里的正式说法是标准变换,或者 z-score 标准化): 每一列各自减去自己的均值,再除以自己的标准差(标准差:这一列的数普遍偏离自己的平均值多远, 一个衡量「散得开不开」的量)7。做完之后每一列的平均值是 0、上下浮动大约是 1。

书给了个能验算的小例子:原来是 [10, 20, 30, 40],标准化之后约是 [-1.3, -0.4, 0.4, 1.3]8

回到我们那条记录。 书打印过训练集这 12 列各自的均值9:

[3.36, 10.69, 11.29, 0.06, 0.557, 6.27, 68.2, 3.71, 9.63, 409.3, 18.45, 12.52]
↑ ↑
crim 的均值 3.36 tax 的均值 409.3

我们那条记录减去均值之后:
crim: 0.3237 − 3.36 = −3.04 (这个片区犯罪率远低于平均)
tax: 222 − 409.3 = −187.3 (税率也远低于平均)
rm: 6.998 − 6.27 = +0.73 (房间数略高于平均)

图说:减完之后每一列都以 0 为中心。**但量纲还没统一** —— −3.04 和 −187.3 还是差了六十倍。
所以还要各自除以这一列的标准差,除完两者才真的可比。
⚠ 书打印了均值,但没有打印各列的标准差,所以最后那个数我们给不出确切值。

顺带两个张量动作

上面那句「一次算出 12 个列平均」和「一个 12 长的东西减到 333×12 的表上」, 在代码里各只是一个调用。它们后面每一章都在用,值得就地讲清:

按轴归约: data.mean(0) 里的 0 指「沿第 0 个轴求平均」。 第 0 个轴是样例轴,所以这句话的意思是把 333 行压掉,每一列留下一个平均值, 结果是 12 个数。如果写成 mean(1),压掉的就是特征轴,得到「每一行 12 个特征的平均」—— 对这个任务毫无意义。书里特意提醒:轴用错是最常见的错误来源之一10

广播: data.sub(dataMean),左边形状 [333, 12],右边形状 [12], 形状不一样却能相减。TensorFlow.js 自动把那 12 个数复制了 333 遍去对齐。 书里点破了实现细节:这个复制是虚拟的,只发生在算法层面,不会真的在内存里造一份11

4. 承重节:换一把尺子,答案会变

这一节是本章的地基。「模型好不好」这个问题,答案取决于你拿什么去量。

先看现象:两种错法,哪种更糟?

假设一个模型预测 10 套房子的价格,有两种错法:

错法 A: 10 套全都差 3(千美元) —— 稳定地不太准
错法 B: 9 套一分不差,第 10 套差 30 —— 大部分神准,偶尔离谱

用第 02 章那把尺子(平均绝对误差)量:
A: (3×10) / 10 = 3
B: (0×9 + 30) / 10 = 3
← 两种错法,量出来一模一样

平均绝对误差认为这两种错法一样糟。 可它们在现实里显然不一样: B 那种「偶尔离谱」的模型,你拿它去挂牌卖房会出大事。

换成均方误差

办法是不取绝对值,取平方——差得越多,平方之后放大得越厉害:

错法 A: 10 套各差 3 平方和 = 3² × 10 = 90 平均 = 9
错法 B: 1 套差 30 平方和 = 30² = 900 平均 = 90

图说:同一份误差,换一把尺子,B 从「和 A 一样」变成「比 A 糟十倍」。
⚠ 书里印的是 90 和 900,那是平方和;除以 10 之后的平均值是 9 和 90。倍数关系不变。

这就是均方误差(mean squared error,常缩写成 MSE): 把每个误差平方,再求平均。它的性质一句话说完——它对离群的大错特别敏感12

所以选哪把尺子是个真决定,而且没有标准答案。 书给的判据很实用: 如果你的应用对个别离谱的预测特别敏感,就选均方误差13。 预测房价属于这一类,所以这一章换成了它。

一个必须记住的细节: 均方误差算出来的数不是「差几千美元」,而是「差几千美元的平方」。 想变回能理解的单位,得开平方。这一步后面每次报数都要做。

5. 基准:上一章那个动作,升级成一条纪律

第 02 章你已经做过一次这个动作了:训 10 轮得到 0.318,拿它去和「永远猜平均下载时间」的 0.220 一比,发现模型还不如那个笨办法

这一章把它从一次灵机一动变成一道开工前的手续。 书的原话是: 在继续之前,应该先找到针对损失的基准估计;如果不知道简单预测的误差, 那就不具备使用更复杂的模型进行预测的前提条件14

而且这一次你会看到:换了任务、换了尺子,基准得重新算。

① 在训练集上求出房价的平均值 22.77(千美元)
② 造一个假模型:不管输入什么,一律答 22.77
③ 拿测试集去考这个假模型,用均方误差量 85.58
④ 开平方,变回能理解的单位 √85.58 ≈ 9.25(千美元)

图说:一个连数据都不看的模型,平均差 9250 美元。
这就是「及格线」—— 你训出来的东西必须明显好过它,否则这活儿不该用机器学习干。

书在这里补了一句很实在的话:如果这个常量预测已经能满足需求,那就可以到此为止了—— 真正掌握机器学习的人懂得及时避免不必要的复杂度15

注意第 ① 步的细节:平均值是在训练集上算的,评估却在测试集上做。 书专门点出这一点,理由是避免「用同一份数据既训练又评估」带来的偏差16

6. 主走查:那条记录,从 12 个数走到一个判决

这一章的每个承重机制,在这条走查上各占一步。除了标注为我们推算的那一处,数字全部来自书里。

发生了什么具体的数 / 状态
1拿到一条记录crim 0.3237tax 222lstat 2.94,共 12 个数
2发现量纲不统一0.3237 和 222 差近七百倍;整列跨度 NOX 0.3850.871 对 TAX 187711
3标准化:每列减自己的均值、除自己的标准差crim 减完是 −3.04,tax 减完是 −187.3(均值来自书;标准差书里没打印)
4喂进一层密集层12 个核 + 1 个偏差 = 13 个可调的数;输出一个数
5选尺子换成均方误差——因为房价预测怕的是偶尔离谱那种错
6先算基准一律答训练集平均房价 22.77 千美元,测试集上的均方误差 85.58
7训练 200 轮笔记本上约 11 秒
8训练集损失 / 验证集损失21.99 / 31.14
9拿测试集考它25.32
10判决:换算成能理解的单位基准 √85.58 ≈ 9250 美元;模型 √25.32 ≈ 5030 美元误差少了将近一半

第 6 步和第 10 步就是这一章的全部要点: 25.32 这个数,单独看什么也不说明; 只有当 85.58 站在它旁边的时候,它才叫「好」。

顺带看第 8 步那两个数: 训练集 21.99,验证集 31.14 —— 验证集明显更差。 这一章不展开,但请把这个现象记住,第 11 章整章都在讲它

7. 第三个新麻烦:两份数据不够,要三份

这一节回答:第 8 步那个「验证集」是从哪冒出来的。

第 02 章只有两份数据:训练集用来训,测试集藏起来当考卷。 听起来很干净——可它有个漏洞,而且这个漏洞你一定会踩。

台阶是这样的:

  1. 你训了一版模型,拿测试集一考,不太好;
  2. 于是你把隐藏层单元数从 50 改成 100,再训一遍,再拿同一份测试集考;
  3. 你重复了二十次,最后挑了考得最好的那一版;
  4. 现在这份测试集还算「模型没见过的数据」吗?

不算了。你每一次「拿它考完再回去改」,都等于把它的信息漏进了模型的选型决定里。 书的说法是:等超过一定次数之后,其实就相当于根据验证集来调整参数, 再拿它评估,评出来的数就不能反映模型在没见过的数据上的表现了—— 而「在没见过的数据上还准不准」这个性质,正式说法叫泛化17

所以要三份18:

数据集干什么用在 TensorFlow.js 里怎么用
训练集用梯度下降去拟合权重model.fit(x, y, ...) 的前两个参数
验证集挑模型结构、挑各种设定fit() 配置里的 validationSplit: 0.2(从训练集里切两成出来)或 validationData
测试集最后无偏地评估一次model.evaluate(x, y)

「最后一次」这四个字是字面意思。 书自己也承认现实中不总是这么规矩: 快速探索性的项目常常只分训练集和验证集,这不够严谨,但在数据有限时是一种取舍19

顺带:训练过程中怎么看见数字

fit() 允许你挂几个回调函数,在特定时刻被调用:每轮开始、每轮结束、每批开始、每批结束20。 波士顿房价那个网页就是靠 onEpochEnd 把每一轮的训练损失和验证损失画成曲线的。

这个机制现在只是个小工具,但它在第 10、11 章会变成主角—— 那两章的全部内容就是「把训练过程中的数字画出来看」。

8. 训完之后:这 13 个数能读出什么

这一节是这本书里唯一一次,你能把模型内部的每个数都解释清楚。 后面再也不行了。

模型算的东西写出来是这样21:

预测房价 = kernel · features + bias

「·」这个点叫内积(又叫点积):把两个等长的数列对位相乘,再全部加起来。
写成代码就是:
output = 0;
for (i = 0; i < a.length; i++) output += a[i] * b[i];

图说:12 个特征,12 个核。第 i 个核只跟第 i 个特征打交道 —— 所以它们能一一对应地读。

书打印出了训完之后那 12 个核的实际值22按特征名对上之后是这样:

特征学到的核读出来是什么意思合理吗
RM 住宅平均房间数+3.39房间越多,房价越高合理
LSTAT 未接受高中教育的已就业男性比例−3.80这个比例越高,房价越低合理
DIS 到五个就业中心的加权距离−3.04通勤越远,房价越低合理
NOX 一氧化氮浓度−1.65空气越差,房价越低合理
RAD 进出城镇主干道易达度+1.43交通越方便,房价越高合理

读法只有两条23:正负号说方向(这个特征变大,房价是涨还是跌); 绝对值说分量(这个特征对结果影响有多大)。 注意:绝对值能这么比,前提是第 3 节做过标准化——大家已经在同一把尺子上了24

但书立刻泼了两盆冷水

第一盆:两个特征强相关时,权重会乱窜。 书假设了一个极端情况: 同一个特征不小心在数据里出现了两次,叫 FEAT1FEAT2。 训出来的权重可能是 +10−5。你会以为一个正相关一个负相关—— 可它们明明是同一列数据。把两个权重对调,预测结果一模一样25

第二盆:相关不是因果。 书的例子很好记:你可以用房顶的湿度预测「刚才下没下雨」, 而且预测得很准。但你往传感器上浇水,天不会下雨26

判断(我们的,不是书里的): 这一节的真正作用不是教你读权重,而是给你一个对照物。 第 04 章加上一个隐藏层之后,同样的动作会打印出 900 个数,而那 900 个数一个也读不出来。 只有先见过「能读」长什么样,你才会真的意识到那是一次交易,而不是一句口号。 如果错,会错在: 如果读者的任务本来就只用得上线性模型,那么这一节是终点而不是对照—— 对他来说「可解释性」根本没有被换掉。

9. 作者的判断与证据

书里给了证据的:

  • 标准化确实必要。 书把它做成了一道练习:把标准化那段删掉再训, 你会发现有时仍能训起来,有时根本不收敛27
  • 线性模型明显好过基准。 25.32 对 85.58,折回美元是 5030 对 925028
  • 权重的正负号和常识对得上。 房间数为正、辍学率与通勤距离为负,书当场对照了29
  • 两个强相关特征会让权重解释失效。 书给了 FEAT1 / FEAT2 那个可以自己验证的构造25

属于作者判断、书里没给证据的:

  • 「相比平均绝对误差,均方误差更适用于解决当前的问题。」 这是一个取舍建议, 书自己也说「还有一些其他技术原因……但是对目前的示例而言,它们并不重要」13
  • 「真正掌握机器学习的技术人员能够及时避免不必要的复杂度。」 这是经验之谈,不是结论15
  • 「我们的大脑喜欢讲故事,会过度解读眼前的信息。」 这是作者对读者心理的判断, 用来引出后面那两盆冷水30

10. 边界与局限

  • 这一章只做了一次评估。 真正的麻烦在你反复评估、反复改模型的时候—— 验证集会被你「训脏」,曲线会分叉。这些全部留到第 11 章。
  • 本章的模型仍然是一条直线(只是在 12 维空间里)。它拟合不了弯的关系, 书在末尾直接预告了下一章:引入非线性能算得更准31
  • 可解释性只对线性模型成立。 一旦加了隐藏层就不成立了——第 04 章会当场演示。
  • 数据集本身有年代局限。 这是 1970 年代的波士顿数据,书里也只是拿它当教学载体; 书甚至开玩笑说「如果只有我们知道这些房价信息,就可以成为 1978 年波士顿房地产投资者中的翘楚」28
  • 书没有讲怎么挑特征。 哪些特征该留、哪些是噪声,书只把它放进了练习题32

11. 可带走的

  1. 多个特征进来之前,先看它们的量纲。 同一行里 crim 0.3237 挨着 tax 222, 不处理就会让训练被大数那一路带跑;
  2. 标准化 = 每列减自己的均值、除自己的标准差。 做完每列平均值 0、上下浮动约 1;
  3. 两个张量动作值得记牢: 按轴归约(mean(0) 压掉样例轴,得到每列一个数)、 广播(形状不同也能相减,小的那个被虚拟复制);
  4. 误差函数是一个真决定。 平均绝对误差一视同仁;均方误差把大错平方放大, 十个各差 3 是 90,一个差 30 是 900;
  5. 均方误差的数要开平方才能读。 85.58 → 9250 美元,25.32 → 5030 美元;
  6. 开工前先算基准。 这一章的基准是「一律答训练集平均房价 22.77」,得分 85.58; 不算它,你手上那个 25.32 什么也不说明;
  7. 换任务、换尺子,基准就要重算。 第 02 章的基准是 0.220(平均绝对误差、下载时间), 这一章是 85.58(均方误差、房价)——不是同一个数,也不能互相引用;
  8. 数据要分三份,不是两份。 训练集拟合权重、验证集挑设定、测试集只用一次;
  9. 线性模型的权重能读:正负说方向,绝对值说分量——前提是标准化过;
  10. 但两条警告: 特征强相关时权重会乱窜;而且相关不是因果(房顶湿度预测下雨)。

12. 原文地图

主题原书章原文位置
多特征场景、事先不知哪个有用第 2 章text/13-ch02-2-tensorflow-js.txt:396(搜「自动分析出输入特征与目标的关联性」)
波士顿房价数据集与特征表第 2 章text/13-ch02-2-tensorflow-js.txt:410(搜「20世纪70年代末」) · text/13-ch02-2-tensorflow-js.txt:430(搜「城镇人均犯罪率」)
四个 CSV 文件、训练集约三分之二第 2 章text/13-ch02-2-tensorflow-js.txt:606(搜「三分之二」)
一条真实记录第 6 章text/18-ch06.txt:573(搜「crim: 0.3237」)
取值范围差异会加剧训练不稳定第 2 章text/13-ch02-2-tensorflow-js.txt:692(搜「加剧训练方面的不稳定性」)
标准化公式与 [10,20,30,40] 算例第 2 章text/13-ch02-2-tensorflow-js.txt:694(搜「z-score标准化」) · text/13-ch02-2-tensorflow-js.txt:697(搜「-1.3, -0.4, 0.4, 1.3」)
12 列均值的实际打印值第 2 章text/13-ch02-2-tensorflow-js.txt:743(搜「3.3603415」)
按轴归约:mean(0) 与用错轴第 2 章text/13-ch02-2-tensorflow-js.txt:734(搜「常见的错误来源」)
广播机制(含虚拟复制)第 2 章text/13-ch02-2-tensorflow-js.txt:748(搜「广播机制」) · text/13-ch02-2-tensorflow-js.txt:769(搜「完全虚拟的」)
均方误差与平均绝对误差的取舍第 2 章text/13-ch02-2-tensorflow-js.txt:658(搜「平等处理误差」) · text/13-ch02-2-tensorflow-js.txt:662(搜「离群值」) · text/13-ch02-2-tensorflow-js.txt:664(搜「对预测值中的离群值非常敏感」)
基准估计的必要性、22.77 与 85.58、开平方 9.25第 2 章text/13-ch02-2-tensorflow-js.txt:666(搜「基准估计」) · text/13-ch02-2-tensorflow-js.txt:685(搜「85.58282470703125」) · text/13-ch02-2-tensorflow-js.txt:688(搜「9250美元」)
验证集为什么必须独立于测试集第 2 章text/13-ch02-2-tensorflow-js.txt:822(搜「相当于根据验证集来调整参数」) · text/13-ch02-2-tensorflow-js.txt:828(搜「利用梯度下降算法拟合模型权重」)
fit() 回调函数的六个时机第 2 章text/13-ch02-2-tensorflow-js.txt:805(搜「onEpochEnd」)
训练 / 验证 / 测试三个损失与耗时第 2 章text/13-ch02-2-tensorflow-js.txt:860(搜「11秒」) · text/13-ch02-2-tensorflow-js.txt:876(搜「21.9864」) · text/13-ch02-2-tensorflow-js.txt:884(搜「5.03」)
内积、权重的读法、打印出的核值第 2 章text/13-ch02-2-tensorflow-js.txt:903(搜「内积」) · text/13-ch02-2-tensorflow-js.txt:916(搜「非常重视对应特征」) · text/13-ch02-2-tensorflow-js.txt:933(搜「Float32Array(12)」)
标准化是权重可比的前提第 2 章text/13-ch02-2-tensorflow-js.txt:918(搜「预先对特征数据进行了标准化处理」)
强相关特征失效、相关不是因果第 2 章text/13-ch02-2-tensorflow-js.txt:966(搜「FEAT1」) · text/13-ch02-2-tensorflow-js.txt:968(搜「房顶的湿度」)
删掉标准化会怎样(练习 2)第 2 章text/13-ch02-2-tensorflow-js.txt:974(搜「删掉标准化部分」)

Footnotes

  1. 出处:「第 2 章」第 396 段(text/13-ch02-2-tensorflow-js.txt:396,搜「自动分析出输入特征与目标的关联性」)。原文:更常见的场景是问题涉及多个输入特征,并且事先不知道其中哪些预测能力最强。

  2. 出处:「第 2 章」第 410 段(text/13-ch02-2-tensorflow-js.txt:410,搜「20世纪70年代末」)。原始出处是 David Harrison 与 Daniel Rubinfeld 的论文 "Hedonic Housing Prices and the Demand for Clean Air"。

  3. 出处:「第 2 章」表 2-1,第 414~555 段(text/13-ch02-2-tensorflow-js.txt:430,搜「城镇人均犯罪率」;text/13-ch02-2-tensorflow-js.txt:520,搜「每1万美元地产所交税率」)。表里共 13 行,前 12 行是特征,最后一行 MEDV(自住房价值中位数,以每千美元计)是要预测的目标。

  4. 出处:「第 2 章」第 606 段(text/13-ch02-2-tensorflow-js.txt:606,搜「三分之二」)。333 这个行数出现在广播那一段的形状说明里(text/13-ch02-2-tensorflow-js.txt:748,搜「[333, 12]」)。

  5. 出处:「第 2 章」第 692 段(text/13-ch02-2-tensorflow-js.txt:692,搜「0.385」)。

  6. 出处:「第 2 章」第 692 段(text/13-ch02-2-tensorflow-js.txt:692,搜「加剧训练方面的不稳定性」)。原文的原话是:「在一个方向上做出的非常小的改变,会比其他方向上的非常大的改变造成的输出变化更大。」

  7. 出处:「第 2 章」第 694 段(text/13-ch02-2-tensorflow-js.txt:694,搜「z-score标准化」)。

  8. 出处:「第 2 章」第 697 段(text/13-ch02-2-tensorflow-js.txt:697,搜「-1.3, -0.4, 0.4, 1.3」)。

  9. 出处:「第 2 章」第 743 段(text/13-ch02-2-tensorflow-js.txt:743,搜「3.3603415」)。原文说这组均值和整个数据集的均值非常接近,说明训练样本有代表性。本章把它们四舍五入到两位小数,减法的结果是我们算的。

  10. 出处:「第 2 章」第 734 段(text/13-ch02-2-tensorflow-js.txt:734,搜「常见的错误来源」)。原文明确说明:沿另一条轴求平均会得到「每个样本的特征的平均值」,对本示例而言没有意义。

  11. 出处:「第 2 章」第 748 段与信息栏 2-4,第 761~769 段(text/13-ch02-2-tensorflow-js.txt:748,搜「广播机制」;text/13-ch02-2-tensorflow-js.txt:769,搜「完全虚拟的」)。

  12. 出处:「第 2 章」第 662 段(text/13-ch02-2-tensorflow-js.txt:662,搜「离群值」)。注意: 原文写的是「当每个样例误差都是 3 时,最终损失将是 90;比单个样例误差为 30 导致的损失 900 要小得多」——这两个数是平方和(原书的公式图片在转码时丢了);除以样例数 10 之后的平均值是 9 和 90。倍数关系不变。

  13. 出处:「第 2 章」第 664 段(text/13-ch02-2-tensorflow-js.txt:664,搜「对预测值中的离群值非常敏感」)。 2

  14. 出处:「第 2 章」第 666 段(text/13-ch02-2-tensorflow-js.txt:666,搜「基准估计」)。

  15. 出处:「第 2 章」第 688 段(text/13-ch02-2-tensorflow-js.txt:688,搜「避免不必要的复杂度」)。 2

  16. 出处:「第 2 章」第 686 段(text/13-ch02-2-tensorflow-js.txt:686,搜「不合理偏差」)。

  17. 出处:「第 2 章」第 822 段(text/13-ch02-2-tensorflow-js.txt:822,搜「相当于根据验证集来调整参数」)。

  18. 出处:「第 2 章」第 828~838 段(text/13-ch02-2-tensorflow-js.txt:828,搜「利用梯度下降算法拟合模型权重」)。validationSplitvalidationData 两种写法见第 834 段(text/13-ch02-2-tensorflow-js.txt:834,搜「validationSplit」)。

  19. 出处:「第 2 章」第 826 段(text/13-ch02-2-tensorflow-js.txt:826,搜「这种做法可能不够严谨」)。

  20. 出处:「第 2 章」第 805 段(text/13-ch02-2-tensorflow-js.txt:805,搜「onEpochEnd」)。可用的六个时机是 onTrainBegin、onTrainEnd、onEpochBegin、onEpochEnd、onBatchBegin、onBatchEnd。

  21. 出处:「第 2 章」第 902~915 段(text/13-ch02-2-tensorflow-js.txt:903,搜「内积」)。伪代码见代码清单 2-16(text/13-ch02-2-tensorflow-js.txt:909,搜「function innerProduct」)。

  22. 出处:「第 2 章」第 933~937 段(text/13-ch02-2-tensorflow-js.txt:933,搜「Float32Array(12)」)。这 12 个数按表 2-1 的特征顺序排列,本章把它们与特征名对上并四舍五入到两位小数;书里的图 2-13 只画了绝对值最大的五个,没有列出全部数值。 因为初始化是随机的,重跑会得到不同的值。

  23. 出处:「第 2 章」第 916 段(text/13-ch02-2-tensorflow-js.txt:916,搜「非常重视对应特征」)。

  24. 出处:「第 2 章」脚注 15,第 918 段(text/13-ch02-2-tensorflow-js.txt:918,搜「预先对特征数据进行了标准化处理」)。

  25. 出处:「第 2 章」第 966 段(text/13-ch02-2-tensorflow-js.txt:966,搜「FEAT1」)。 2

  26. 出处:「第 2 章」第 968 段(text/13-ch02-2-tensorflow-js.txt:968,搜「房顶的湿度」)。

  27. 出处:「第 2 章」练习(2),第 974 段(text/13-ch02-2-tensorflow-js.txt:974,搜「删掉标准化部分」)。原文:「你会发现有时仍能正常训练模型,有时训练无法收敛。」

  28. 出处:「第 2 章」第 884 段(text/13-ch02-2-tensorflow-js.txt:884,搜「5.03」)。三个损失值(21.9864 / 31.1396 / 25.3206)见第 876~880 段(text/13-ch02-2-tensorflow-js.txt:876,搜「21.9864」);200 轮约 11 秒见第 860 段(text/13-ch02-2-tensorflow-js.txt:860,搜「11秒」)。 2

  29. 出处:「第 2 章」图 2-13 说明,第 920 段(text/13-ch02-2-tensorflow-js.txt:920,搜「本地居民的辍学率」)。

  30. 出处:「第 2 章」第 964 段(text/13-ch02-2-tensorflow-js.txt:964,搜「大脑喜欢讲故事」)。

  31. 出处:「第 2 章」第 886 段(text/13-ch02-2-tensorflow-js.txt:886,搜「非线性深度模型」)。

  32. 出处:「第 2 章」练习(3),第 976 段(text/13-ch02-2-tensorflow-js.txt:976,搜「预测能力最强」)。