跳到主要内容

一小块窗扫遍全图 — 卷积,它能吃图也能吃声

这一章讲三件事: 为什么图像不能像前四章那样直接拉成一串数喂进去; 卷积到底在算什么(它只是一个滑窗加乘法,没有任何玄机); 以及它凭什么用几百个参数干几百万个参数的活。 它在全书链条里的位置: 第 02~05 章的输入一直是「一排数」——文件大小、12 个房价特征、 30 个网站特征。这一章第一次换了输入的形状,而换形状逼出了一种全新的层。 更要紧的是:这一章的核心想法(同一组权重反复用在每个位置)会在第 12 章原样重演一次, 那次共享的不是空间,是时间。

1. 先看现象:把图拉直,就把「挨着」丢了

MNIST 是这一章的主角:六万张训练图、一万张测试图,全是 28×28 的灰度手写数字, 分成 0 到 9 十类,而且各类数量大致均衡1。它旧、小,却是这个领域的「Hello World」—— 新技术好不好用,常拿它先试一遍。

一张 28×28 的图有 784 个像素。按前四章的做法,你会把它拉成一个长度 784 的数列喂进去。

这一拉,有一样东西永久丢了。

原图(示意,把 28×28 缩成 4×4):
┌────┬────┬────┬────┐
│ 12 │ 90 │ 88 │ 3 │ ← 90 和 88 在图上是挨着的
├────┼────┼────┼────┤
│ 7 │ 95 │ 91 │ 1 │ ← 90 和 95 在图上是上下挨着的
├────┼────┼────┼────┤
│ 0 │ 2 │ 4 │ 9 │
├────┼────┼────┼────┤
│ 1 │ 0 │ 8 │ 6 │
└────┴────┴────┴────┘

拉直之后:
[12, 90, 88, 3, 7, 95, 91, 1, 0, 2, 4, 9, 1, 0, 8, 6]
└┬─┘ └┘
还挨着 90 和 95 隔了 3 个位置 —— 上下相邻这件事没了

图说:密集层对输入的顺序完全无感(第 12 章会证明这一点)。
所以「哪两个像素上下相邻」这个信息,拉直之后就再也回不来了。

书对这件事的评语很直接:这样会破坏颜色通道间的内在联系,以及像素之间的二维空间关系, 导致之后难以对这些关系加以利用2

所以图像要保持它的形状。 深度学习里图像用三维张量表示:高、宽、颜色通道, 简称 HWC 格式。彩色图三个通道(红绿蓝),灰度图一个通道。 一张 224×224 的彩色照片是 [224, 224, 3];一张 MNIST 图是 [28, 28, 1]3

一次喂一批的时候,前面再加一维图像编号,变成四维,简称 NHWC4所以这一章所有张量都是四维的,别被吓到:多的那一维就是第 02 章讲过的批次轴。

2. 顶层全景:一张「7」穿过七层

书搭的模型有七层。在拆开每一层之前,先看整条链5:

[28, 28, 1] 一张手写「7」
↓ conv2d:16 个 3×3 的窗,各扫一遍全图
[26, 26, 16] 十六张「特征图」,每张标出一种局部花样出现在哪儿
↓ maxPooling2d:每 2×2 取最大值
[13, 13, 16] 高和宽减半
↓ conv2d:32 个 3×3 的窗
[11, 11, 32]
↓ maxPooling2d
[ 5, 5, 32]
↓ flatten:拉成一长串
[800] ← 到这一步才拉直。此时空间关系已经被榨完了
↓ dense 64,ReLU
[64]
↓ dense 10,softmax
[10] 十个概率,加起来是 1 —— 第 05 章那套配方

图说:整个模型可以看成两截 —— 前五层是「特征提取器」,后两层是第 04 章那种普通的多层感知机。
这个「提取器 + 感知机」的搭法,后面还会在音频、文本上重复出现。

⚠ 上面这些形状是我们按代码清单 4-1 一步步推的,不是照抄书里的。 原因见本章第 8 节:原书第 4 章的数字来自两个不同版本的模型,互相对不上。 我们统一到代码清单 4-1(读者真能跑起来的那份代码)那一版。

3. 承重节:卷积到底在算什么

这一节是本章的地基。它听起来吓人,做的事却只有「滑一格、乘一遍、加起来」。

先打个比方,说完就拆

书借了一个说法:把它想成一串 Photoshop 滤镜——模糊、锐化那些效果6。 它们的做法都是拿一个小方块在图上滑过去,每停一处按方块里的数把附近像素混一混。

比方到此为止。下面用正式说法。

那个滑动的小方块叫卷积核

输入图的一小块(3×3): 核(3×3,里面的数是训练出来的):
┌───┬───┬───┐ ┌────┬────┬────┐
│ 0 │ 0 │ 0 │ │ -1 │ -1 │ -1 │
├───┼───┼───┤ ├────┼────┼────┤
│ 8 │ 9 │ 8 │ │ 2 │ 2 │ 2 │
├───┼───┼───┤ ├────┼────┼────┤
│ 0 │ 1 │ 0 │ │ -1 │ -1 │ -1 │
└───┴───┴───┘ └────┴────┴────┘

对位相乘,再全部加起来:
0×(−1) + 0×(−1) + 0×(−1)
+ 8× 2 + 9× 2 + 8× 2
+ 0×(−1) + 1×(−1) + 0×(−1) = 0 + 50 − 1 = 49

这个 49 就是输出图上的一个像素。

图说:这个核在找「中间一横亮、上下两行暗」的花样 —— 也就是一条水平边。
窗里正好有这种花样,所以它给了个大数 49。
⚠ 这九个像素和这九个核值是为演示编的,不是书里的数;
「对位相乘再求和」这个动作和「一格一格滑」是书里的。

滑完全图,你得到一整张新图,上面每个像素记的是「这个位置有多像那种花样」。 书管这张新图叫特征图——注意它不是颜色,是模型自己学出来的视觉特征7

一层里有很多个核,每个核找一种花样。 核的数量在代码里叫 filters(过滤器数), 它等于输出图的通道数8。第一层用了 16 个,所以输出是 [26, 26, 16]

为什么 28 变成了 26? 因为 3×3 的窗不能滑出图的边缘:横着只有 26 个落脚点, 竖着也只有 26 个。窗越大,边上损失越多9

卷积的两个性质,和它们各自换来什么

书把 conv2d 的全部本事归结成两条10:

性质它是什么意思和密集层的对比
局部性输出图上一个像素,只受输入图上那一小块(3×3)的影响密集层里每个输出都受全部输入影响,所以叫「密集」;卷积层是「稀疏连接」的
参数共享窗滑到每一个位置用的都是同一组 9 个数密集层里每一对输入输出各有自己的权重

这两条合起来,就是卷积省参数的全部原因。

主走查的关键一步:160 对 848 万

同样一件事——把一张 28×28 的灰度图变成一层 16 通道的特征——两种做法的账:

用卷积层:
核的形状 [3, 3, 1, 16] 3×3 的窗、1 个输入通道、16 个核
参数 3 × 3 × 1 × 16 = 144 再加 16 个偏差
合计 160 个

用密集层做同一件事:
输入 28 × 28 × 1 = 784 个数
输出 26 × 26 × 16 = 10816 个数
参数 784 × 10816 = 8 479 744 个(不含偏差)
合计 约 848 万个

差距:848 万 ÷ 160 ≈ 五万三千倍

图说:这就是卷积的全部卖点。而且注意 —— 这 160 个数和图有多大**完全无关**:
换成 224×224 的照片,还是 160 个。密集层那一边会涨到几亿。

⚠ 这两个数是我们按代码清单 4-1 自己算的。 原书在讲这笔账时用的是另一版模型 (5×5 的窗、8 个核、输出 24×24×8),给的数是 200 对 361 万,约 18000 倍11。 结论完全一样,只是模型不同。我们统一到代码清单 4-1,因为那是书里真正跑起来的模型。

书还补了一句值得记住的话: 局部性加参数共享这套设计,和视网膜的工作方式很像—— 每个神经元只看视野里的一小块(这一小块叫它的感受野), 而两个处在不同位置的神经元,对各自感受野里的光照模式反应几乎一样12

4. 池化:换来两件事,一件反直觉

第二种新层叫最大池化,它比卷积简单得多:拿一个 2×2 的窗,每次跳两格, 取窗里最大的那个数。没有核,没有可调的参数13

输入(4×4) 输出(2×2)
┌───┬───┬───┬───┐
│ 1 │ 3 │ 2 │ 0 │ ┌───┬───┐
├───┼───┼───┼───┤ │ 8 │ 4 │ ← 左上那 2×2 里最大的是 8
│ 8 │ 2 │ 4 │ 1 │ ├───┼───┤
├───┼───┼───┼───┤ ────► │ 9 │ 7 │
│ 0 │ 9 │ 5 │ 7 │ └───┴───┘
├───┼───┼───┼───┤
│ 6 │ 1 │ 3 │ 2 │
└───┴───┴───┴───┘

图说:高和宽各减半,元素总数变成四分之一;通道数不变。
⚠ 这些数是为演示编的;「取窗里最大值、窗每次跳两格」是书里的。

它换来两件事14:

第一件:位置挪一点也照样认。 池化只关心「这一小块里有没有出现那种花样」, 不关心它出现在这一小块的哪个角落。所以数字往左挪一两个像素,输出几乎不变。 这个性质叫位置不变性。书很诚实地补了一句:一个池化层的效果有限, 要叠好几个才有质的飞跃——所以几乎所有实用的 convnet 都有两个以上池化层14

第二件,这一件反直觉:它让后面的层看得更宽。 书做了个思想实验15:

两个 3×3 卷积层直接叠在一起:
第二层的一个输出像素 ← 回溯到最原始的输入,覆盖 5×5 的范围

中间插一个池化层:
第二层的一个输出像素 ← 回溯到最原始的输入,覆盖 11×11 的范围

图说:同样两层卷积,插不插池化,视野差一倍多。
「一个输出像素能看到原图多大一块」就是它的感受野;
池化压缩了尺寸,于是同样大的窗覆盖了更大的原始面积。

顺带,它还把后面所有层的计算量砍到四分之一——但这只是副产品,不是主要理由。

5. 「深层认出的是猫」——这句话现在只能信

书在这里给了一张很有名的图:convnet 靠近输入的层提取直线、曲线、边角这些低阶几何特征; 往上几层,这些低阶特征被组合成猫的眼睛、鼻子、耳朵;最顶上的层才提取出「这是不是一只猫」16

这个说法是对的,而且它就是第 01 章那句「学的是表示」在图像上的具体样子。

但请注意:书在这一章没有给出任何证据。 它给的是一张示意图和一段描述, 不是一次实测。你此刻只能选择相信它。

这笔债在第 10 章还: 那一章会拿一张真的猫照片,把每一层的输出真的打印出来给你看—— 第 1 组卷积层的输出还看得出边缘和色块,第 5 组只剩几块亮斑。 到那时你会看到「越深越抽象」是一个能验证的现象,不只是一句说法。

6. 主走查:一张「7」,从 784 个像素到十个概率

这一章的每个承重机制,在这条走查上各占一步。 形状和参数量是我们按代码清单 4-1 推的;准确率是书里的实测值。

发生了什么具体的数 / 状态
1一张手写「7」进来[28, 28, 1],共 784 个像素
216 个 3×3 的核各扫一遍全图(每停一处:对位相乘再求和)输出 [26, 26, 16]只用了 160 个参数——同样的事密集层要 848 万个
3每个数过一遍 ReLU(负数归零)形状不变。没有这一步,两个卷积层会塌成一个(第 04 章的老规矩,对卷积同样成立)
4最大池化,2×2 取最大[13, 13, 16],元素数变成四分之一;数字挪一两像素也照样认
532 个 3×3 的核再扫一遍[11, 11, 32]
6再池化一次[5, 5, 32]此刻第二个卷积层的每个输出,已经能看到原图 11×11 的范围
7扁平化:多维压成一维[800]到这一步才拉直——空间信息已经榨完了,拉直不再有损失
8密集层 64 个单元,ReLU[64]
9密集层 10 个单元,softmax十个概率,加起来是 1。第 8 个位置(代表数字 7)最大
10训 10 轮,拿一万张测试图考它准确率 99.0%(随机猜是 10%)
11对照:同样的参数量,换成纯密集层97.0% —— 只差两个点,但错误率是 3% 对 1%,差三倍

第 2 步和第 11 步是这条走查的两端: 一头是「为什么卷积省」,一头是「省完还更准」。

书对第 11 步补了一句很硬的话: 你可以试着把那个纯密集模型再加宽, 你会发现即使模型变大了,它仍然赶不上 convnet17

7. 模型一大就开始背答案:dropout

书接着搭了一个更强的版本,在 Node.js 上训:四个卷积层、隐藏密集层 512 个单元, 总共 594 922 个参数,20 轮之后测试准确率 99.6%18

但容量一大,风险就来了。 第 04 章说过加层能加容量; 现在你要知道容量的代价:模型会开始记住训练集里那些无关的细枝末节(这叫过拟合)。

书给的对策叫 dropout,它做的事简单到不可思议 —— 就是在训练时随机丢掉一部分输出19:

训练时: 输入张量里随机挑一部分元素,直接置成 0
比如丢弃率 0.25、输入是 [0.7, −0.3, 0.8, −0.4]
输出可能是 [0.7, −0.3, 0.0, −0.4] ← 四分之一被丢掉了
反向传播时,梯度张量也照样被随机置零

推断时: 什么都不做,原样穿过去

图说:训练时故意加噪声,用完就撤。这是全书第一次出现「训练和推断行为不同」的层。

为什么这么土的办法有用? 发明它的 Geoffrey Hinton 说灵感来自银行20:

我每次去银行,接待我的柜员都不同……我猜想这肯定是银行采取的一种措施, 为了防止员工之间相互勾结,共同欺诈银行。这使我意识到, 如果对每个样例随机地移除神经元中的不同子集,就能避免神经元之间相互勾结,从而减少过拟合。

翻译成正式说法:给某一层的输出加噪声,能打乱那些纯属巧合形成的模式—— 如果这些巧合模式存在,它们会妨碍模型找到数据里真正的规律20

dropout 的机制全书只讲这一次。 第 11 章会把它摆进「治过拟合的武器表」里, 但那时只回指,不重讲。

8. 原书第 4 章的数来自两版模型,一次说清

这一节是我们加的,书里没有。 但不说清楚,你按书里的数去核代码会核不上。

原书第 4 章的正文里混着两个不同的模型: 一个是代码清单 4-1 那份能跑的代码 (3×3 的核、16/32 个过滤器),另一个是讲解卷积原理时用的示范模型 (5×5 的核、8 个过滤器)。三处对不上:

书里写的属于哪一版按代码清单 4-1 算应该是
「有且只有 5×5×1×8 = 200 个参数……密集层需要 3 612 672 个」115×5 / 8 个核那一版1608 479 744
「输入扁平化层的三维张量形状为 [3, 3, 32]」;同一节前面又说是 [4, 4, 16]21[4,4,16] 对应 5×5 那一版;[3,3,32] 两版都对不上[5, 5, 32][800]
「非卷积模型的参数总数和 convnet 大致相等(约 33 000)」22与代码清单 4-1 对不上按清单 4-1 数,convnet 约 5.7 万 个参数

我们的处理:整章统一到代码清单 4-1。 结论一处也没变—— 卷积省几万倍参数、准确率还更高,这两件事在哪一版模型上都成立。

判断(我们的,不是书里的): 这类矛盾多半来自成书过程中模型被改过、 而讲解文字没有同步更新。它不影响这一章的任何结论,但影响读者的信心—— 一个照着书自己算的人,会在这里怀疑是自己错了。所以我们选择当场摆出来。 如果错,会错在: 如果原书另有一处我们没读到的说明(比如英文原版的勘误表) 交代了这两版模型的关系,那么这就不是矛盾,而是我们漏读。

9. 训好的模型怎么存下来

模型训完只活在内存里,关掉就没了。存出来是两个文件23:

文件里面是什么
model.json模型的结构:有哪些层、每层的配置(核多大、丢弃率多少)、层之间怎么连;外加一份权重清单(每个权重叫什么、什么形状、什么类型、存在哪儿)
weights.bin一大坨二进制的权重数值,它自己不带任何分隔标记——从哪到哪是哪个权重,全靠上面那份清单说明

加载回来用 tf.loadLayersModel(),给它 model.json 的地址就行。 在 Node 里地址以 file:// 开头;在浏览器里不能用 file://—— 出于安全,浏览器不让网页碰本机文件系统,所以要么走 http://, 要么存进浏览器自己的存储里24

这一节现在看只是个存取操作,但它是下一章的前提: 第 07 章要「借用别人训好的模型」,借的就是这样一对文件。

10. 同一套东西,拿去听声音

这一节是这一章真正的主张:卷积不是图像专用的。

声音本来是一串气压变化,数字化之后是一长串数——一维的。 看起来和二维卷积不沾边。可有一种画法能把它变成一张图。

一秒钟的录音「stop」
↓ 每 20 毫秒切一小段
一串小段
↓ 对每一小段做傅里叶变换:把它拆成各个频率上各有多少能量
每小段变成一竖条(每一格是一个频段的能量)
↓ 把这些竖条从左到右排开
一张图:横轴是时间(43 格),纵轴是频率(232 格)

图说:这张图叫时频谱。深色的地方表示那个时刻、那个频段能量高。
它和 MNIST 那张 28×28 的手写数字图,在模型眼里是同一类东西 —— 一张有二维结构的灰度图。

书给了三条理由说明为什么这种画法是对的25:

  1. 省空间。 原始波形里的数比时频谱里的多好几倍;
  2. 和人耳的工作方式很像。 人的内耳有个结构叫耳蜗,它做的就是生物版的傅里叶变换—— 把声音拆成不同频段,交给不同的听觉神经处理;
  3. 不同的音在图上长得明显不同。 「z」「s」这类咝音的能量集中在 2~3kHz 以上; 「e」「o」这类元音在低频段有几条横亮带(声学上叫共振峰),不同元音的位置不同。 几十年前还没有机器学习时,研究者就是靠人工规则去这张图上找这些花样的。

于是任务变成了一个熟悉的多分类问题:20 个类别(0~9 十个数字、 up/down/left/right/go/stop/yes/no,外加「不认识的词」和「背景噪声」两类)26。 模型结构和 MNIST 那个几乎一样:卷积加池化重复四次,扁平化,dropout,两个密集层,softmax。 训完的评估准确率约 94%27

唯一一处针对声音改过的地方值得注意:核不是正方形的,是长方形的(比如 [2, 8])—— 因为时频谱本身是长方形的,频率那一维比时间那一维大得多28

这是同一个想法的第二次出现。 第一次是「图像有二维结构」, 第二次是「声音画成图之后也有二维结构」。第三次会在第 13 章: 一句话也能被一个一维的窗滑过去。

11. 作者的判断与证据

书里给了证据的:

  • 卷积比同等参数量的密集层更准。 有对照实验:99.0% 对 97.0%,而且书说明了 那个纯密集模型是特意造得参数量差不多,为的是公平1722
  • 加宽密集模型也追不上。 书把这个当成实战练习让读者自己验17
  • 加强版 convnet 能到 99.6%。 有 20 轮的实测数18
  • 音频 convnet 能到约 94%。 有实测数27
  • dropout 有效。 书把「删掉 dropout 层再训一遍」列成了练习题,让读者自己看差别29

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

  • 「浅层认边角、深层认猫」那张分层图。 这一章只给了示意图和描述, 实测证据要到第 10 章才出现16
  • 卷积和视网膜感受野「有异曲同工之妙」。 这是一个类比,不是神经科学结论12
  • Hinton 那个银行柜员故事。 这是发明者对灵感来源的自述,不是对 dropout 为何有效的证明20
  • 「99.0% 从实用角度可接受,但绝不是顶尖水平。」 这是一句行业经验判断30

12. 边界与局限

  • 99.0% 不是上限。 书说要到 99.5% 得加更多卷积层、池化层和过滤器, 而那样的模型在浏览器里训不动——所以书把它搬到了 Node 上30怎么装 tfjs-node、怎么用显卡(GPU 版比 CPU 版快 5 倍),这一章不讲,见第 21 章。
  • 这一章没讲填充和步长。 3×3 的窗为什么把 28 变成 26、能不能让它保持 28, 书里只在图的说明中带过。
  • 深度可分离卷积没讲。 第 01 章提过名字,第 22 章会再提一次,机制全书没有。
  • 音频那部分只做单个词。 书自己说得很清楚:这不是语音识别器,是口令识别器; 真正的连续语音要靠能处理序列的结构,那在第 12 章31
  • 过拟合只给了 dropout 一件武器。 怎么发现过拟合、还有哪些对策,整个留到第 11 章。
  • 训练数据和推断数据必须做同样的预处理。 书在这里点了一句: 训练时图像归一化到 01,推断时若拿 0255 的原始像素喂进去就会出偏差32这个坑第 09 章会正式展开。

13. 可带走的

  1. 图像不能拉直再喂。 一拉直,「谁挨着谁」就永久丢了;
  2. 图像用三维张量:[高, 宽, 通道](灰度图通道是 1);一批就是四维,多的那一维是批次;
  3. 卷积 = 一小块窗在图上滑,每停一处把窗里的数和窗上的数对位相乘再相加。 一层有很多个窗,每个找一种花样;输出是一叠「特征图」;
  4. 关键不在窗小,在同一块窗扫遍全图。 这两条性质叫局部性和参数共享;
  5. 省参数的账: 同样把一张 28×28 图变成 16 通道特征,卷积 160 个参数, 密集层 848 万个;而且卷积那 160 个和图有多大无关;
  6. 池化 = 每 2×2 取最大值。 换来位置不变性(数字挪几像素也认得), 以及后面的层看得更宽(两层卷积中间插一个池化,感受野从 5×5 变成 11×11);
  7. 扁平化要放在最后。 空间信息榨完了再拉直,就不再有损失;
  8. 实测账: 卷积 99.0% 对同参数量密集层 97.0%(随机猜 10%)—— 看着只差两点,错误率差三倍;
  9. 模型大了会背答案,插 dropout: 训练时随机把一部分输出置零,推断时原样穿过。 Hinton 的说法是「防止神经元互相勾结」;
  10. 卷积不是图像专用的。 把一秒声音画成 43×232 的时频谱,同一套结构认 20 个口令能到 94%。 第 13 章还会再用同一个想法处理文字。

14. 原文地图

主题原书章原文位置
图像用三维张量、HWC 与 NHWC第 4 章text/15-ch04-4-convnet.txt:27(搜「颜色通道」) · text/15-ch04-4-convnet.txt:33(搜「NHWC」)
拉直会破坏空间关系第 4 章text/15-ch04-4-convnet.txt:29(搜「二维空间关系」)
MNIST 数据集第 4 章text/15-ch04-4-convnet.txt:37(搜「hello world」) · text/15-ch04-4-convnet.txt:41(搜「60 000个图像」)
七层模型的代码第 4 章text/15-ch04-4-convnet.txt:58(搜「createConvModel」)
convnet = 特征提取器 + 多层感知机第 4 章text/15-ch04-4-convnet.txt:89(搜「采用卷积层和池化层预处理输入数据的MLP」) · text/15-ch04-4-convnet.txt:173(搜「两个模型的级联」)
滤镜比喻、滑窗点积、过滤器数第 4 章text/15-ch04-4-convnet.txt:95(搜「Photoshop滤镜」) · text/15-ch04-4-convnet.txt:101(搜「kernelSize决定了形状中的前两个数字」) · text/15-ch04-4-convnet.txt:105(搜「习得的输入图像的不同视觉特征」)
为什么 28 变 26(窗不能滑出边缘)第 4 章text/15-ch04-4-convnet.txt:107(搜「不能超出输入图像的边缘」)
卷积层也要非线性第 4 章text/15-ch04-4-convnet.txt:113(搜「和只使用单个二维卷积层加一个更大的卷积核」)
局部性与参数共享;省参数的账;视网膜类比第 4 章text/15-ch04-4-convnet.txt:117(搜「局部性」) · text/15-ch04-4-convnet.txt:123(搜「3 612 672」) · text/15-ch04-4-convnet.txt:125(搜「感受野」)
最大池化、位置不变性、感受野 5×5→11×11第 4 章text/15-ch04-4-convnet.txt:131(搜「最大池化」) · text/15-ch04-4-convnet.txt:139(搜「位置不变性」) · text/15-ch04-4-convnet.txt:141(搜「11 × 11」)
层次特征提取(那张猫的图)第 4 章text/15-ch04-4-convnet.txt:152(搜「层次特征提取」)
扁平化与它的排序规则第 4 章text/15-ch04-4-convnet.txt:163(搜「打平」)
训练配置与 99.0%第 4 章text/15-ch04-4-convnet.txt:226(搜「categoricalCrossentropy」) · text/15-ch04-4-convnet.txt:236(搜「99.0%」)
对照实验:纯密集层 97.0%、参数约 33 000第 4 章text/15-ch04-4-convnet.txt:244(搜「createDenseModel」) · text/15-ch04-4-convnet.txt:271(搜「误差率是convnet的3倍」)
随机猜的准确率是 10%第 4 章text/15-ch04-4-convnet.txt:242(搜「碰巧猜中的准确率」)
训练与推断数据不能有偏斜第 4 章text/15-ch04-4-convnet.txt:306(搜「偏斜」)
加强版模型:594 922 参数、99.6%第 4 章text/15-ch04-4-convnet.txt:381(搜「99.6%」) · text/15-ch04-4-convnet.txt:447(搜「594922」)
dropout 的机制与 Hinton 的银行柜员故事第 4 章text/15-ch04-4-convnet.txt:467(搜「丢弃率」) · text/15-ch04-4-convnet.txt:477(搜「柜员」) · text/15-ch04-4-convnet.txt:479(搜「相互勾结」)
模型存取:model.json + weights.bin第 4 章text/15-ch04-4-convnet.txt:528(搜「model.json是一个JSON文件」) · text/15-ch04-4-convnet.txt:532(搜「weights.bin」) · text/15-ch04-4-convnet.txt:543(搜「浏览器中进行基于HTTP的模型加载」)
时频谱、傅里叶变换、耳蜗、共振峰第 4 章text/15-ch04-4-convnet.txt:571(搜「时频谱」) · text/15-ch04-4-convnet.txt:573(搜「耳蜗」) · text/15-ch04-4-convnet.txt:575(搜「共振峰」)
口令数据集 20 类、43×232、约 94%第 4 章text/15-ch04-4-convnet.txt:577(搜「20种类别」) · text/15-ch04-4-convnet.txt:579(搜「43 × 232」) · text/15-ch04-4-convnet.txt:652(搜「94%」)
长方形卷积核第 4 章text/15-ch04-4-convnet.txt:632(搜「长方形的」)
浏览器训不动、要换 Node第 4 章text/15-ch04-4-convnet.txt:240(搜「99.5%」) · text/15-ch04-4-convnet.txt:337(搜「负荷过大且训练速度过慢」)

Footnotes

  1. 出处:「第 4 章 用convnet识别图像和音频」第 37~41 段(text/15-ch04-4-convnet.txt:37,搜「hello world」;text/15-ch04-4-convnet.txt:41,搜「60 000个图像」)。MNIST 的名字来自美国国家标准与技术研究所(NIST)的数据集,M 表示「经过改进」。

  2. 出处:「第 4 章」脚注 3,第 29 段(text/15-ch04-4-convnet.txt:29,搜「二维空间关系」)。

  3. 出处:「第 4 章」第 27 段(text/15-ch04-4-convnet.txt:27,搜「颜色通道」)。

  4. 出处:「第 4 章」第 33 段(text/15-ch04-4-convnet.txt:33,搜「NHWC」)。原文说明 TensorFlow.js 两种格式都能处理,书统一用默认的 NHWC。

  5. 出处:「第 4 章」代码清单 4-1,第 58~84 段(text/15-ch04-4-convnet.txt:58,搜「createConvModel」)与第 85 段的架构概述(text/15-ch04-4-convnet.txt:85,搜「特征提取」)。本章列出的每一层输出形状是我们按这份代码逐层推的,理由见第 8 节。

  6. 出处:「第 4 章」第 95 段(text/15-ch04-4-convnet.txt:95,搜「Photoshop滤镜」)。原书脚注说明这个比喻来自 Ashi Krishnan 2018 年在欧洲 JavaScript 开发者大会上的演讲。

  7. 出处:「第 4 章」第 105 段(text/15-ch04-4-convnet.txt:105,搜「习得的输入图像的不同视觉特征」)。原文强调:输出张量的通道不一定和颜色有关,它们是从训练集中习得的视觉特征。

  8. 出处:「第 4 章」第 101 段(text/15-ch04-4-convnet.txt:101,搜「kernelSize决定了形状中的前两个数字」)。核是一个四维张量,四个维度依次是:窗高、窗宽、输入通道数、过滤器数。

  9. 出处:「第 4 章」第 107 段(text/15-ch04-4-convnet.txt:107,搜「不能超出输入图像的边缘」)。

  10. 出处:「第 4 章」第 117~121 段(text/15-ch04-4-convnet.txt:117,搜「局部性」;text/15-ch04-4-convnet.txt:121,搜「参数共享」)。

  11. 出处:「第 4 章」第 123 段(text/15-ch04-4-convnet.txt:123,搜「3 612 672」)。原文用的是 [5, 5, 1, 8] 的核,给出 200 对 3 612 672、约 18 000 倍。本章的 160 与 8 479 744 是我们按代码清单 4-1 的 [3, 3, 1, 16] 自己算的,详见第 8 节。 2

  12. 出处:「第 4 章」第 125 段(text/15-ch04-4-convnet.txt:125,搜「感受野」)。 2

  13. 出处:「第 4 章」第 131 段与图 4-5 说明,第 131 段(text/15-ch04-4-convnet.txt:131,搜「最大池化」)。注意原文这一句「maxPooling2d 的转换要比 maxPooling2d 的转换更简单」是个笔误,按上下文应是「比 conv2d 的转换更简单」。

  14. 出处:「第 4 章」第 139 段(text/15-ch04-4-convnet.txt:139,搜「位置不变性」)。原文:单个池化层的增强有限,多个叠起来才有质的飞跃。 2

  15. 出处:「第 4 章」第 141 段(text/15-ch04-4-convnet.txt:141,搜「11 × 11」)。计算量减到四分之一见第 143 段(text/15-ch04-4-convnet.txt:143,搜「1/4」)。

  16. 出处:「第 4 章」第 152 段与图 4-6 说明,第 152 段(text/15-ch04-4-convnet.txt:152,搜「层次特征提取」)。原文明确说这些特征「不是手动找出的,而是通过监督式学习自动从数据中提取的」,并回指第 1 章那句「深度学习的本质就是逐层地对表示进行转换」。 2

  17. 出处:「第 4 章」第 271 段(text/15-ch04-4-convnet.txt:271,搜「误差率是convnet的3倍」)。原文的实战建议是:增大 createDenseModel() 里隐藏密集层的 units,「你会发现,即使模型的尺寸增加了,仍无法使非卷积模型达到和 convnet 相当的水平」。 2 3

  18. 出处:「第 4 章」第 381 与 447 段(text/15-ch04-4-convnet.txt:381,搜「99.6%」;text/15-ch04-4-convnet.txt:447,搜「594922」)。 2

  19. 出处:「第 4 章」第 465~469 段(text/15-ch04-4-convnet.txt:467,搜「丢弃率」)。原文给的正是 [0.7, -0.3, 0.8, -0.4] 这个例子(书里印的输出末位是 0.4,按上下文应为 -0.4,置零的是第三位)。

  20. 出处:「第 4 章」第 475~479 段(text/15-ch04-4-convnet.txt:477,搜「柜员」;text/15-ch04-4-convnet.txt:479,搜「相互勾结」)。 2 3

  21. 出处:「第 4 章」第 158 与 163 段(text/15-ch04-4-convnet.txt:158,搜「[4, 4, 16]」;text/15-ch04-4-convnet.txt:163,搜「[3, 3, 32]」)。同一节里这两个形状互相矛盾,而且都与代码清单 4-1 对不上。

  22. 出处:「第 4 章」第 244 段与拓扑结构报告,第 256~270 段(text/15-ch04-4-convnet.txt:244,搜「createDenseModel」;text/15-ch04-4-convnet.txt:267,搜「Total params: 33400」)。原文说这个纯密集模型的参数量是特意造得和 convnet 大致相等的。按代码清单 4-1 逐层数,convnet 约有 5.7 万个参数,和 33 400 对不上——这是第 8 节列出的第三处版本混用。 2

  23. 出处:「第 4 章」第 524~532 段(text/15-ch04-4-convnet.txt:528,搜「model.json是一个JSON文件」;text/15-ch04-4-convnet.txt:532,搜「weights.bin」)。

  24. 出处:「第 4 章」第 517 与 539 段(text/15-ch04-4-convnet.txt:517,搜「浏览器出于安全考量」;text/15-ch04-4-convnet.txt:543,搜「浏览器中进行基于HTTP的模型加载」)。

  25. 出处:「第 4 章」第 571~575 段(text/15-ch04-4-convnet.txt:571,搜「时频谱」;text/15-ch04-4-convnet.txt:573,搜「耳蜗」;text/15-ch04-4-convnet.txt:575,搜「共振峰」)。

  26. 出处:「第 4 章」第 577 段(text/15-ch04-4-convnet.txt:577,搜「20种类别」)。数据集来自谷歌大脑团队的 Pete Warden(text/15-ch04-4-convnet.txt:634,搜「Pete Warden」)。注意: 书在第 5 章又说这个识别器「只能识别 18 个不同的单词」(text/16-ch05.txt:343,搜「18个不同的单词」)——两处的数不一致,差别在于「不认识的词」和「背景噪声」这两个特殊类算不算进去。

  27. 出处:「第 4 章」第 652 段(text/15-ch04-4-convnet.txt:652,搜「94%」)。 2

  28. 出处:「第 4 章」第 632 段(text/15-ch04-4-convnet.txt:632,搜「长方形的」)。

  29. 出处:「第 4 章」练习(3),第 702 段(text/15-ch04-4-convnet.txt:702,搜「删除dropout层」)。

  30. 出处:「第 4 章」第 240 段(text/15-ch04-4-convnet.txt:240,搜「99.5%」)。原文:99.0%「从实用的角度而言,这是可接受的,但绝不是顶尖水平」;更大的 convnet 在浏览器里训练要久得多,所以要换到 Node.js。 2

  31. 出处:「第 4 章」第 561 段(text/15-ch04-4-convnet.txt:561,搜「口令识别器」)与第 688 段(text/15-ch04-4-convnet.txt:688,搜「带语法的连续语音」)。注意: 原文这里写「这些将在第 8 章中介绍」,但按本书实际章序,能处理序列的循环神经网络在第 9 章

  32. 出处:「第 4 章」第 306 段(text/15-ch04-4-convnet.txt:306,搜「偏斜」)。