用感知机构建神经网络
学习如何通过组合感知机来设计神经网络。
回顾
本课程的第一部分:从第1章(机器学习原理)到第8章(感知机),核心内容是感知机。第二部分:从第9章(设计网络)到第15章(让我们开始开发),则介绍了机器学习中的进阶概念,其中最重要的思想是神经网络。神经网络比感知机强大得多。在“感知机的局限性”一节中我们了解到,感知机只能处理简单的线性可分数据;而神经网络能够处理非结构化的数据,例如现实世界物体的照片。
即便是像MNIST这样简单的数据集,我们的感知机表现也仅勉强及格,大约每识别10个字符就会出错一次。而使用神经网络,我们可以将准确率提升一个数量级。在本章节中,我们将构建一个MNIST分类器,使其准确率达到99%,即每100个字符才出现一次错误。
现在,让我们来设计一个用于分类MNIST数字的神经网络。
组装感知机
我们来看看如何从已有的感知机构建神经网络。回顾一下,感知机的本质是:对输入进行加权求和,然后通过Sigmoid函数:
在本章前半部分,我们并未直接单独使用感知机,而是以两种方式组合了多个感知机:第一,我们一次性用大量MNIST图像训练感知机;第二,我们使用了十个感知机来分别判断十种可能的数字。我们已经将这两种操作分别类比为感知机的堆叠和并行化。
需要明确的是,我们并没有真正地物理堆叠或并行连接感知机,而是通过矩阵运算实现了类似效果。我们的感知机输入是一个矩阵,每行对应一张图像;输出也是一个矩阵,每列对应一个类别。所谓“堆叠”和“并行”的说法,只是便于理解这些基于矩阵计算的抽象概念。
现在,我们将这些扩展形式(即经过堆叠和并行化处理的)感知机作为基本构件,用来搭建神经网络。
串联感知机
我们可以通过将两个感知机串行连接的方式来构建神经网络,如下图所示:
如图所示,每个感知机都有自己的权重和Sigmoid操作,但第一个感知机的输出成为了第二个感知机的输入。为了避免混淆,我们用字母 表示中间值,并用 表示其数量。这里的 代表“隐藏”,因为这些值既不属于网络的输入,也不属于最终输出。
在过去,这种结构被称为多层感知机(Multilayer Perceptron)或人工神经网络(Artificial Neural Network)。如今,大多数人直接称之为神经网络。网络中的圆形灰色节点称为“节点”(nodes),它们按层次排列,如下图所示:
该网络包含三层:
- 输入层
- 隐藏层
- 输出层
我们也可以串联超过两个感知机,从而得到超过三层的网络结构。这部分内容将在本章后续部分讨论。目前,我们专注于三层神经网络。
隐藏层中的节点由输入层的节点计算得出,但有一个特殊节点除外,叫做偏置节点(bias)。当我们把两个感知机连接起来形成网络时,两个感知机各自的偏置节点都被保留下来。因此,现在输入层有一个偏置节点,隐藏层也有一个。这些偏置节点的值固定为 。(如果你不记得为什么是 ,可以回顾之前的“告别偏置”相关内容。)
我们需要澄清一点:当我们说“这一层有10个节点”时,并不意味着神经网络内部真的用一个包含10个元素的数组来表示这一层。实际上,它是以矩阵形式表示的——具有10列,以及足够多的行数。例如,如果我们用5000个样本训练网络,那么这一层就表示为一个形状为 (5000, 10) 的矩阵。就像感知机示意图一样,神经网络的图示通常假设每次只处理一个样本,以便于阅读理解。请记住我们的“堆叠”比喻:当观察这些图示时,应想象有多个网络实例垂直堆叠在一起,每个对应一个训练样本。
有时人们也将神经网络中的节点称为神经元(Neurons)。更准确地说,一个神经元不仅包括节点本身,还包括直接影响其值的组件——即前一层的节点以及它们之间的运算过程,如下图所示:
最后,正如前面提到的,层与层之间的函数被称为网络的激活函数。在当前网络中,我们两个层都使用Sigmoid函数作为激活函数——但这并非必须,稍后我们会看到其他选择。
至此,我们已经了解了一个典型的三层神经网络的基本结构。然而,我们尚未确定每一层具体需要多少个节点。接下来我们就来确定这一点。
各层节点数量?
我们来看一看输入层、隐藏层和输出层分别需要多少节点。
首先看输入节点的数量。和感知机一样,网络的每个输入变量对应一个输入节点,再加上一个偏置节点。我们要分类的是MNIST的 像素图像,因此共有 个输入节点。输入矩阵每行对应一张图像,共 列,这与感知机相同。
输出节点的数量也与感知机一致。MNIST共有 个类别,所以我们需要 个输出节点。输出矩阵每行对应一张图像,共 列。
那隐藏层的节点数量呢?这个由我们自行决定。在接下来的几章中,我们会学习如何做出更明智的选择。目前,我们采用一个简单的经验法则:隐藏层节点数通常介于输入层和输出层节点数之间。因此我们先设定为200个隐藏节点,加上偏置后变为201个。
你可能会疑惑:为何要选择像 这样具体的数值?毕竟多一个或少一个节点,网络性能可能相差无几。为什么不从199个隐藏节点开始,加偏置后接近200?其实这样做也是完全可以的。选择 的原因是为了提醒我们:其中一个隐藏节点是特殊的——它的值固定为 ,用于处理偏置项。
最后,谈谈权重。我们通过串联两个感知机构建了网络,每个感知机都有自己的一组权重矩阵。因此,整个神经网络包含两个权重矩阵:
- 一个连接输入层与隐藏层
- 另一个连接隐藏层与输出层
我们可以用一条通用规则确定它们的维度:神经网络中每个权重矩阵的行数等于其输入元素的数量,列数等于其输出元素的数量。也就是说, 的维度是 , 的维度是 。你可以验证这条规则是否适用于感知机:感知机的权重矩阵每行对应一个输入变量,每列对应一个类别。
网络中的计算流程如下:
H = sigmoid(X ⋅ W1)
Ŷ = sigmoid(H ⋅ W2)
请回忆矩阵乘法的相关规则,并注意Sigmoid函数的输出与其输入具有相同的维度。
让我们在神经网络图上标出各层节点数量及矩阵维度。用字母 表示输入样本的数量,这个值是可变的:在MNIST训练集中为60,000,但在分类单张图像时可能仅为1:
整体方案看起来已经很清晰了。接下来我们可能想要将其转化为代码实现。但在那之前,还有一项最后的调整需要完成。