跳到主要内容

张量 — 神经网络摆弄的东西到底是什么

这一章讲三件事: 神经网络吃进嘴里的数据长什么样(张量); Dense 层内部其实只有三个运算;以及为什么说每一层都是一次几何变换。 这一章是全书的数学地基——作者立了一条方法论:这一章不出现数学符号, 「对数学运算而言,最精确无误的描述就是它的可执行代码」1。我们也照这个口径讲: 所有运算都落到具体的数和形状上。

1. 顶层全景:一张手写数字的旅程

本章的主走查,是原书第一个完整例子——MNIST 手写数字识别。MNIST 是一个公开数据集: 6 万张 28×28 像素的灰度手写数字照片(0 到 9 共 10 类),80 年代由美国国家标准与技术研究院收集, 书里叫它「深度学习的 Hello World」2

一张写着「5」的照片,从进电脑到被认出来,全程是这样的:

28×28 像素网格(每个像素 0~255 的灰度值)
│ reshape:拉直成一行

784 个数的一维数组,再除以 255 → 全部落在 [0, 1]
│ Dense(512, relu):第一层变换

512 个数
│ Dense(10, softmax):第二层变换

10 个数,和为 1,比如 [0.001, 0.002, …, 0.97, …]
│ 最大的那个在第 6 个位置 → 模型答「5」

图说:这就是全书第一个神经网络的全部。这些百分数不是书里的真实输出,
是为演示编的;书里的真实结果是:训练精度 98.9%,测试精度 97.8%。

下面每一节拆开这条链:第 2 节讲「装数的容器」,第 3 节讲「Dense 层的三个运算」, 第 4 节讲「为什么这三个运算是几何变换」,第 5 节讲那张著名的纸团。

2. 张量:装数的多维容器

张量就是装数字的容器——更准一点,它是矩阵向任意维度数的推广。你早就见过它的特例: 一个单独的数是标量(0 阶张量);一串数排成一行是向量(1 阶张量);数排成一个表格是矩阵(2 阶张量); 把表格再叠成一摞、再叠成一格一格的柜子,就是 3 阶、4 阶、5 阶张量3

张量有几个(也叫阶):向量有 1 个轴,矩阵有 2 个轴(行和列),MNIST 整个训练集 (60000, 28, 28) 有 3 个轴4。书里特别警告一个常见的口误:「5 维向量」和「5 阶张量」是两回事—— 前者是一行 5 个数(1 个轴,轴上有 5 个元素),后者是有 5 个轴的庞然大物5

拿到任何一个张量,用三个属性就能把它说全6:

属性意思MNIST 训练集的例子
轴的个数(ndim)几阶3
形状(shape)每个轴上各有多少个元素(60000, 28, 28)
数据类型(dtype)里面装的是什么数整数 0~255,预处理后变 float32 小数

回到那张照片:走查第 ① 步

那张 28×28 的照片自己是一个 2 阶张量;6 万张叠起来,变成形状 (60000, 28, 28) 的 3 阶张量。 这里有一条贯穿全书的约定:第一个轴永远是样本轴——轴 0 上每一个位置是一张完整的照片7

训练时并不是一次喂 6 万张,而是一次抓一小把(比如 128 张)算一次、调一次。 这一小把叫一个批量;因此第一个轴也叫批量轴8

现实中的数据各是几阶

书里给了一张对照表,值得整表记住9:

数据形状(批量轴之后)几阶
表格数据(每个样本一行数)(样本, 特征)2
序列数据(文本、股价)(样本, 时间步, 特征)3
图像(样本, 高, 宽, 通道)4
视频(样本, 帧, 高, 宽, 通道)5

「特征」指一个样本的单个属性(房价数据里的「房间数」就是一个特征);「通道」指颜色的层数—— 彩色照片有红绿蓝 3 个通道,灰度图只有 1 个。书里举了两个量级感十足的例子:100 万条推文, 每条编码成 (280, 128),整个数据集是 (1000000, 280, 128) 的 3 阶张量; 而一段 60 秒 144×256 的 YouTube 视频,4 段就要占 405 MB10

3. Dense 层:只有三个运算

3.1 拆开那行代码

第 01 章说过,每一层是一次由权重决定的变换。全书第一层是 Dense(512, relu), 书里把它拆成了一个公式——别怕,只有三件事11:

output = relu( dot(input, W) + b )

图说:输入先和权重 W 做点积,加上偏置 b,最后过一遍 relu。
W 和 b 就是这一层的全部权重——「学习」学的就是它们。

点积是三个运算里唯一陌生的。先看最朴素的版本:两个一样长的向量做点积, 就是对应位置两两相乘、再全部加起来,得到一个数12:

[1, 2, 3] · [4, 5, 6] = 1×4 + 2×5 + 3×6 = 32

图说:两个向量的点积是一个数。它量的是「这两个向量方向上有多少重合」。

矩阵和向量做点积,就是矩阵的每一行分别和那个向量做点积,结果还是一个向量。 两个矩阵做点积有一个硬条件:左边矩阵的列数必须等于右边矩阵的行数; 结果的形状是 (左行数, 右列数)13。所以 Dense(512) 里那个 W,形状恰好是 (784, 512)—— 784 个数进去,和 784 行各自点积一遍,512 个数出来。这就是「784 维变 512 维」的全部。

剩下的两个运算一句话一个:

逐元素运算:对张量里每个数单独做同一操作。relu 就是逐元素的——负数归零,正数原样; 加法(两个形状相同的张量对应位置相加)也是14。自己用 for 循环写一遍 relu 要跑 2.45 秒, NumPy 的实现只要 0.02 秒——差了 100 多倍,因为底层是并行化的 BLAS 例程15

广播:形状不同的两个张量做逐元素运算时,小的那个会被「撑大」来匹配——先补轴,再沿新轴复制。 比如形状 (32, 10) 加形状 (10,),后者先变成 (1, 10),再沿第一个轴复制 32 份,逐元素相加。 (实际实现并不会真的造出那份复制品,只是逻辑上这么理解16。)

回到那张照片:走查第 ② 步

现在能看懂主走查的中间两步了。那张拉直后的 784 维向量:

  1. Dense(512, relu):和 (784, 512) 的 W 做点积 → 512 个数;加上 512 个偏置(广播); 负数归零 → 还是 512 个数;
  2. Dense(10, softmax):和 (512, 10) 的 W 做点积 → 10 个数;加偏置; 最后过一个 softmax——它把任意 10 个数变成 10 个和为 1 的正数,最大的输入对应最大的输出, 因此输出可以直接当「每个数字的可能性」读17

整条链的输入输出形状:(128, 784) → (128, 512) → (128, 10)——128 是批量大小。

4. 几何解释:每层一次平移加一次线性变换

4.1 张量运算的几何面孔

这一节回答一个看似玄学的问题:这些运算和「几何」有什么关系?

把向量看成平面上的一个点(或从原点指向那个点的箭头),那么18:

  • 向量加法 = 平移:把点整体挪一段距离,形状不变;
  • 和矩阵做点积 = 线性变换:旋转、缩放、倾斜都属于这一类——点之间的关系被整齐地重新排布;
  • 两者合起来(点积再加一个向量)叫仿射变换——这正是不带 relu 的 Dense 层做的事: output = dot(input, W) + b,一次线性变换加一次平移。

4.2 全书最重要的一句推论

上面那句「不带 relu 的 Dense 层 = 仿射变换」有一个致命推论19:

重复应用多次仿射变换,仍相当于一次仿射变换。

也就是说,如果网络里没有 relu 这类函数,叠两层 Dense 和叠一百层 Dense 完全等价—— 都可以合并成单独一层。层数再多,假设空间也并没有变大,模型能表达的变换永远只是「一次线性变换加一次平移」。

这就是激活函数存在的理由。 激活函数就是加在仿射变换之后的那道非线性工序 (relu 的「负数归零」就是非线性——它不是一条直线能描述的)。 有了它,叠层才不再是摆设:每多一层,模型能表达的变换族就复杂一分20

回到那张照片:走查第 ③ 步

把这句话贴回主走查:如果 MNIST 网络的两层都没有激活函数, 那么「784 → 512 → 10」就等于一个「784 → 10」的单层—— 而手写数字的弯弯绕,单层线性变换根本分不开。 加上 relu 之后,第一层可以把平面「折叠」,第二层在折好的形状上切直线, 两层合力就能完成单层做不到的分割,测试精度 97.8%。

(补充(不在书里,来自通用知识):去掉激活函数之后剩下的那个东西, 就是教科书里的线性分类器;它在 MNIST 上通常停在九成出头, 和上面那个 97.8% 之间那七八个百分点,就是 relu 这一道工序换来的。 书里没有做这个对照实验,只给出了「叠多少层都等于一层」这个数学结论。)

5. 纸团:整本书的几何直觉

书里用一个比喻给全书画了像,这个比喻后面第 06 章、第 14 章还会反复回来21:

拿两张不同颜色的纸叠在一起,揉成一个皱巴巴的纸团。 这个纸团就是你的输入数据,每张纸是一个类别。 神经网络要做的,是找到让纸团恢复平整的变换—— 每一层对纸团做一个简单动作(像手指拨一下),许多层连起来, 就把高度折叠的纸团逐步展平了。

揉皱的纸这类「高维空间里的连续表面」,书里叫流形—— 先记住这个画面:数据不是随便散布的,而是挤在一个被揉皱了的低维表面上; 学习的目的是把这个表面展平。流形是第 06 章「泛化」一章的顶梁柱,到那里会给它正式的定义22

6. 作者的判断与证据

作者的明确主张: 「对数学运算而言,最精确无误的描述就是它的可执行代码」—— 所以这一章用 NumPy 代码代替数学符号讲完了全部内容1。这是本书的标志性风格,也是作者身为 框架作者(Keras 之父)的方法论:读得懂代码,就读得懂数学。

证据: 全章的结论(逐元素、广播、点积、仿射变换)都是数学事实,不存在争议; 98.9% 训练精度与 97.8% 测试精度是代码跑出来的实测值23。 书里还顺带记录了第一个值得注意的现象:测试精度比训练精度低—— 这就是过拟合的第一次露面(模型在见过无数次的数据上表现更好;这个词第 06 章会整章展开)24

7. 边界与局限

  • 这一章只讲了 Dense 层(每个输入单元和每个输出单元都相连,所以也叫全连接层); 卷积层、循环层各有自己的运算,第 08、10 章再讲。
  • softmax 的具体算式(指数再归一)书里正文没展开,只讲了它的效果(和为 1、可当可能性读); 需要算式时查任何一家框架文档即可——本文保持和原书相同的海拔。
  • 「流形」这里只是画面,没有定义;第 06 章才给它正式定义并用它解释泛化。

8. 可带走的

  1. 张量 = 装数的多维容器;标量、向量、矩阵是它的 0、1、2 阶特例;
  2. 三属性说清任何张量:轴的个数、形状、数据类型;
  3. 第一个轴永远是样本轴/批量轴;向量/序列/图像/视频分别是 2/3/4/5 阶;
  4. Dense 层只有三个运算:点积、加偏置、激活函数(relu(dot(x, W) + b));
  5. 点积的形状条件:左列数 = 右行数;广播 = 补轴再复制,不是真复制;
  6. 没有激活函数,叠多少层都等于一层——这是激活函数存在的全部理由;
  7. 每层 = 一次仿射变换(线性变换 + 平移)+ 一次非线性;
  8. 神经网络的几何画像:把揉皱的纸团(数据流形)一层一层展平

9. 原文地图

主题原书章原文位置
方法论宣言(代码即数学)神经网络的数学基础text/09-ch02.txt:14(搜「可执行代码」)
MNIST 与第一个网络神经网络的数学基础text/09-ch02.txt:30(搜「Hello World」) · text/09-ch02.txt:53(搜「60000」)
预处理与训练结果神经网络的数学基础text/09-ch02.txt:106(搜「取值范围是 [0, 1]」) · text/09-ch02.txt:153(搜「97.8%」)
张量定义、阶、5 维向量警告神经网络的数学基础text/09-ch02.txt:168(搜「任意维度的推广」) · text/09-ch02.txt:191(搜「5 维向量」)
三关键属性神经网络的数学基础text/09-ch02.txt:228(搜「3 个关键属性」)
样本轴与批量轴神经网络的数学基础text/09-ch02.txt:301(搜「样本轴」) · text/09-ch02.txt:315(搜「批量轴」)
现实数据张量、推文与视频量级神经网络的数学基础text/09-ch02.txt:328(搜「视频数据」) · text/09-ch02.txt:358(搜「推文数据集」)
Dense 层三运算神经网络的数学基础text/09-ch02.txt:410(搜「relu(dot」)
逐元素运算与 100 倍差距神经网络的数学基础text/09-ch02.txt:422(搜「逐元素」) · text/09-ch02.txt:464(搜「0.02 秒」)
广播两步神经网络的数学基础text/09-ch02.txt:476(搜「广播」)
点积的形状条件神经网络的数学基础text/09-ch02.txt:542(搜「元素个数相同」) · text/09-ch02.txt:568(搜「x.shape[1] == y.shape[0]」)
几何解释:平移/线性/仿射神经网络的数学基础text/09-ch02.txt:684(搜「平移」) · text/09-ch02.txt:702(搜「线性变换」) · text/09-ch02.txt:704(搜「仿射变换」)
无激活叠层=单层神经网络的数学基础text/09-ch02.txt:722(搜「重复应用多次仿射」)
纸团与流形神经网络的数学基础text/09-ch02.txt:741(搜「纸团」) · text/09-ch02.txt:746(搜「流形」)

Footnotes

  1. 出处:「神经网络的数学基础」第 14 段(text/09-ch02.txt:14,搜「可执行代码」)。原文:「对数学运算而言,最精确无误的描述就是它的可执行代码」。这是作者为全章定下的方法论。 2

  2. 出处:「神经网络的数学基础」第 30 段(text/09-ch02.txt:30,搜「Hello World」)与第 28 段(text/09-ch02.txt:28,搜「美国国家标准与技术研究院」)。MNIST 包含 60000 张训练图像和 10000 张测试图像,28×28 灰度,10 个类别。

  3. 出处:「神经网络的数学基础」第 168 段(text/09-ch02.txt:168,搜「任意维度的推广」)。

  4. 出处:「神经网络的数学基础」第 169 段(text/09-ch02.txt:169,搜「轴」)。

  5. 出处:「神经网络的数学基础」第 191 段(text/09-ch02.txt:191,搜「5 维向量」)。

  6. 出处:「神经网络的数学基础」第 228 段(text/09-ch02.txt:228,搜「3 个关键属性」)。

  7. 出处:「神经网络的数学基础」第 301 段(text/09-ch02.txt:301,搜「样本轴」)。

  8. 出处:「神经网络的数学基础」第 315 段(text/09-ch02.txt:315,搜「批量轴」)。

  9. 出处:「神经网络的数学基础」第 322 段(text/09-ch02.txt:322,搜「向量数据」)至第 328 段(text/09-ch02.txt:328,搜「视频数据」)。

  10. 出处:「神经网络的数学基础」第 358 段(text/09-ch02.txt:358,搜「推文数据集」)与第 397 段(text/09-ch02.txt:397,搜「405 MB」)。推文例子里每条推文是 280 个字符、每字符 128 维 one-hot 向量。

  11. 出处:「神经网络的数学基础」第 410 段(text/09-ch02.txt:410,搜「relu(dot」)。

  12. 出处:「神经网络的数学基础」第 530 段(text/09-ch02.txt:530,搜「两个向量 x 和 y 的点积」)与第 542 段(text/09-ch02.txt:542,搜「元素个数相同」)。

  13. 出处:「神经网络的数学基础」第 568 段(text/09-ch02.txt:568,搜「x.shape[1] == y.shape[0]」)。

  14. 出处:「神经网络的数学基础」第 422 段(text/09-ch02.txt:422,搜「逐元素」)。

  15. 出处:「神经网络的数学基础」第 464 段(text/09-ch02.txt:464,搜「0.02 秒」)。手写 Python 版 2.45 秒,NumPy BLAS 版 0.02 秒。

  16. 出处:「神经网络的数学基础」第 476 段(text/09-ch02.txt:476,搜「广播」)与第 492 段(text/09-ch02.txt:492,搜「并不会创建新的」)。

  17. 出处:「神经网络的数学基础」第 88 段(text/09-ch02.txt:88,搜「10 路 softmax 分类层」)。第一个网络的第二层就是 Dense(10, activation="softmax")。

  18. 出处:「神经网络的数学基础」第 684 段(text/09-ch02.txt:684,搜「平移」)、第 702 段(text/09-ch02.txt:702,搜「线性变换」)与第 704 段(text/09-ch02.txt:704,搜「仿射变换」)。

  19. 出处:「神经网络的数学基础」第 722 段(text/09-ch02.txt:722,搜「重复应用多次仿射」)。原文还给出了合并方式:两层无激活 Dense 等效于一层,核为 W2·W1,平移部分为 W2·b1+b2。

  20. 出处:「神经网络的数学基础」第 730 段(text/09-ch02.txt:730,搜「假设空间」)。

  21. 出处:「神经网络的数学基础」第 741 段(text/09-ch02.txt:741,搜「纸团」)。

  22. 出处:「神经网络的数学基础」第 749 段(text/09-ch02.txt:749,搜「流形是指一个连续的表面」)。原文:「流形是指一个连续的表面,比如揉皱的纸」。

  23. 出处:「神经网络的数学基础」第 123 段(text/09-ch02.txt:123,搜「98.9%」)与第 153 段(text/09-ch02.txt:153,搜「97.8%」)。

  24. 出处:「神经网络的数学基础」第 154 段(text/09-ch02.txt:154,搜「过拟合」)。这是原书第一次出现过拟合一词。