Neil Zhu,简书ID Not_GOD,University AI 创始人 & Chief Scientist,致力于推进世界人工智能化进程。制定并实施 UAI 中长期增长战略和目标,带领团队快速成长为人工智能领域最专业的力量。
作为行业领导者,他和UAI一起在2014年创建了TASA(中国最早的人工智能社团), DL Center(深度学习知识中心全球价值网络),AI growth(行业智库培训)等,为中国的人工智能人才建设输送了大量的血液和养分。此外,他还参与或者举办过各类国际性的人工智能峰会和活动,产生了巨大的影响力,书写了60万字的人工智能精品技术内容,生产翻译了全球第一本深度学习入门书《神经网络与深度学习》,生产的内容被大量的专业垂直公众号和媒体转载与连载。曾经受邀为国内顶尖大学制定人工智能学习规划和教授人工智能前沿课程,均受学生和老师好评。
在上一章,我们学习了深度神经网络通常比浅层神经网络更加难以训练。我们有理由相信,若是可以训练深度网络,则能够获得比浅层网络更加强大的能力,但是现实很残酷。从上一章我们可以看到很多不利的消息,但是这些困难不能阻止我们使用深度神经网络。本章,我们将给出可以用来训练深度神经网络的技术,并在实战中应用它们。同样我们也会从更加广阔的视角来看神经网络,简要地回顾近期有关深度神经网络在图像识别、语音识别和其他应用中的研究进展。然后,还会给出一些关于未来神经网络又或人工智能的简短的推测性的看法。
这一章比较长。为了更好地让你们学习,我们先粗看一下整体安排。本章的小结之间关联并不太紧密,所以如果读者熟悉基本的神经网络的知识,那么可以任意跳到自己最感兴趣的部分。
本章主要的部分是对最为流行神经网络之一的深度卷积网络的介绍。我们将细致地分析一个使用卷积网络来解决 MNIST 数据集的手写数字识别的例子(包含了代码和讲解):
我们将从浅层的神经网络开始来解决上面的问题。通过多次的迭代,我们会构建越来越强大的网络。在这个过程中,也将要探究若干强大技术:卷积、pooling、使用GPU来更好地训练、训练数据的算法性扩展(避免过匹配)、dropout 技术的使用(同样为了防止过匹配现象)、网络的 ensemble 使用 和 其他技术。最终的结果能够接近人类的表现。在 10,000 幅 MNIST 测试图像上 —— 模型从未在训练中接触的图像 —— 该系统最终能够将其中 9,967 幅正确分类。这儿我们看看错分的 33 幅图像。注意正确分类是右上的标记;系统产生的分类在右下:
深度神经网络在 MNIST 实验中的性能可以发现,这里面的图像对于正常人类来说都是非常困难区分的。例如,在第一行的第三幅图。我看的话,看起来更像是 “9” 而非 “8”,而 “8” 却是给出的真实的结果。我们的网络同样能够确定这个是 “9”。这种类型的“错误” 最起码是容易理解的,可能甚至值得我们赞许。最后用对最近使用深度(卷积)神经网络在图像识别上的研究进展作为关于图像识别的讨论的总结。
本章剩下的部分,我们将会从一个更加宽泛和宏观的角度来讨论深度学习。概述一些神经网络的其他模型,例如 RNN 和 LSTM 网络,以及这些网络如何在语音识别、自然语言处理和其他领域中应用的。最后会试着推测一下,神经网络和深度学习未来发展的方向,会从 intention-driven user interfaces 谈道 深度学习在人工智能的角色。
这章内容建立在本书前面章节的基础之上,使用了前面介绍的诸如 BP,正规化、softmax 函数,等等。然而,要想阅读这一章,倒是不需要太过细致地掌握前面章节中内容的所有的细节。当然读完第一章关于神经网络的基础是非常有帮助的。本章提到第二章到第五章的概念时,也会在文中给出链接供读者去查看这些必需的概念。
需要注意的一点是,本章所没有包含的那一部分。这一章并不是关于最新和最强大的神经网络库。我们也不是想训练数十层的神经网络来处理最前沿的问题。而是希望能够让读者理解深度神经网络背后核心的原理,并将这些原理用在一个 MNIST 问题的解决中,方便我们的理解。换句话说,本章目标不是将最前沿的神经网络展示给你看。包括前面的章节,我们都是聚焦在基础上,这样读者就能够做好充分的准备来掌握众多的不断涌现的深度学习领域最新工作。
本章仍然在Beta版。期望读者指出笔误,bug,小错和主要的误解。如果你发现了可疑的地方,请直接联系 mn@michaelnielsen.org。
卷积网络简介
在前面的章节中,我们教会了神经网络能够较好地识别手写数字:
MNIST 手写数字我们在深度神经网络中使用全连接的邻接关系。网络中的神经元与相邻的层上的所有神经元均连接:
全连接深度神经网络特别地,对输入图像中的每个像素点,我们将其光强度作为对应输入层神经元的输入。对于 28*28 像素的图像,这意味着我们输入神经元需要有 784(=28 * 28) 个。接着我们训练网络的权重和偏差,使得最后网络可以正确识别输入图像: '0', '1', '2', ..., '8', 或者 '9'。
我们前面使用的网络效果已经不错了:我们使用来自MNIST handwritten digit data set训练数据和测试数据获得了超过 98% 准确度的分类结果。但是,仔细看看,使用全连接层来分类图像其实是很奇怪的。因为,这样的网络结构并没有考虑图像本身的空间结构。例如,对输入像素,网络将离得很远和很近的像素都同等看待。这样的空间结构概念必须从训练数据中推断出来。但是如果我们不从一个简单的网络开始,而使用一个针对空间结构的网络,效果会怎么样?本节,我们会介绍 卷积神经网络。这些网络使用一种特定的结构,主要适配于图像的分类。使用这种结构让卷积网络训练速度有所提升。这样也能够帮助我们训练深层的、多层的适用图像分类的网络。现在深度卷及网络或者类似的变体在图像识别中用得最为频繁。
卷积神经网络的诞生要回到 1970 年代。但是建立起现代卷积网络的开创性论文出现在 1998 年,"Gradient-based learning applied to document recognition" 这篇由 Yann LeCun, Léon Bottou, Yoshua Bengio, 和 Patrick Haffner 合作的论文。LeCun 已经给出了关于卷积网络模型所受到的生物学上的启发:“诸如卷积网络受到(生物)神经学的启发还是很微小的。这也是我们称此为卷积网络而不是卷积神经网络的原因,其中的节点我们也叫做单元(unit)而不是神经元(neuron)。”尽管有此说明,卷积网络也使用了大量我们之前讲述的神经网络中的想法:如 BP、梯度下降、正规化、非线性激活函数等等。所以我们会遵循通常的实践,将卷积网络看成是神经网络的一种类型。后面卷积网络和卷积神经网络会交换使用。当然 (人工)神经元和单元 也是换着使用的。
卷积神经网络拥有三个基本特性:局部感知区、共享权重和pooling。下面详细讨论这三个概念。
局部感知区:在全连接层中,输入被看做是竖直方向的神经元列。在卷积网络中,可以将输入看做是 28 * 28 的神经元的正方形,其中每个神经元对应于输入图像的像素。
正如往常那样,我们将输入像素连接到隐藏层上。但是我们不会将每个输入像素连接到每个隐藏元上。而是仅仅在输入图像上做一个局部小规模的连接。
更加准确地说,在第一隐藏层的每个神经元将会被连接到输入神经元的小区域上,例如,一个 5 * 5 的局域,对应于 25 个输入像素。所以,对一个特定的隐藏元,我们可能会有如下的连接:
在输入图像中的那个区域被称为隐藏元的局部感知区。这是在输入像素上的一个小窗口。每个连接学习一个权重。隐藏元同样会学习一个整体的偏差。你可以将这种特定的隐藏元看做是在学习分析其对应的局部感知区。
接着我们将窗口在整个输入图像上进行滑动。对每个局部感知区,在第一隐藏层,存在一个不同的隐藏元。为形象地解释这个过程,我们给出一个例子:
Paste_Image.png以此下去,可以构建出整个第一隐藏层。注意,如果我们有一个 28 * 28 的图像作为输入,然后局部感知区为 5 * 5,那么最后在隐藏层就有 24 * 24 个神经元。这是因为我们只能移动局部感知区 23 次(或者向下移动 23 次),直到抵达最右侧(或者最底部)。
我已经展示了移动一次局部感知区的效果。实际上,有时候会有不同的步长。例如,我们可以每次移动局部感知区 2 个像素。称步长为 2。本章几乎所有例子都使用 1 的步长,但最好要知道这个值是可以进行调整的。
正如我们在前面章节所讲的,如果我们对不同步长感兴趣,就可以使用验证数据,在不同步长上实验不同的效果,最终选择最优的步长。可以参考这里 了解神经网络中超参数的选择。同样的方法也可以用来选择局部感知区的大小上。一般来说,更大的局部感知区在输入图像明显大于 28 * 28 的 MNIST 图像时更有用。
共享权重和偏差:我已经提到每个隐藏元有一个偏差和一个连接在其局部感知区的 5 * 5 的矩阵。而没有提及的则是,我们将会使用同样的权重和偏差对所有 24 * 24 个隐藏元。换言之,对 j,k 隐藏元,输出是
$$\sigma(b + \sum_{l=0}{4}\sum_{m=0}{4} w_{l,m}a_{j+l, k+m})$$
这里,$$\sigma$$ 是神经元的激活函数——可能是 sigmoid 函数。$$b$$是共享的偏差。$$w_{l,m}$$ 是 5 * 5 的共享权重矩阵。最后,使用 $$a_{x,y}$$ 表示在 $$x,y$$ 处的输入激活值。
这意味着所有第一隐藏层的神经元检测除了同样的特征,只是在输入图像不同的位置而已。我们来看看为何这样是合理的,假设权重和偏差可以让神经元能够获取特定的局部感知区的竖直线。这个能力同样可以用在图像中其他的地方。所以,应用同样的特征检测器在图像中的每个地方。用更为抽象一点的术语就是,卷积网络可以适应图像的转化不变性:移动一点点猫的图像,仍然保证得到的是猫的图像。
实际上,对 MNIST 数字分类问题,图像处于正中央,大小也是规范化了的。所以 MNIST 不大会有在其他图像中发现的变化不变性。诸如边和角这样的特征可能在大部分输入空间上都有用。
因此,我们有时候将输入层到隐藏层的映射称为 特征映射。我们称定义了这个映射的权重为 共享权重。而相应的偏差就叫做 共享偏差 了。共享权重和偏差常常被称为 核(Kernel)或者 过滤器(filter)。在文献中,人们使用这些术语会存在一些差异,所以我这里不会在细化;而是会讨论一些具体的例子。
目前描述的网络结构可以检测出一种单一的局部特征。为了进行图像识别,我们需要更多的特征映射。所以,完整的卷积层包含一些不同的特征映射:
Paste_Image.png在上面的例子中,存在 3 个特征映射。每个特征映射使用一个 5 * 5 的共享权重和一个共享偏差定义。结果就得到了一个可以检测三个不同的特征的网络,每个特征是在全图范围内得到的。
我这里为了让图很简单就展示了 3 个特征映射。然而,在实际情况中,卷积网络可能使用很多很多特征映射。早期的卷积网络,如 LeNet-5,使用了 6 个特征映射,每个关联于 5 * 5 的局部感知区,来识别 MNIST 数字。所以,上面展示的例子很接近 LeNet-5。本章后面的例子中我们会使用拥有 20 和 40 个特征映射的卷积层。让我们看看这些例子学到的特征吧:
Paste_Image.png来自我们最终版的卷积网络的特征映射,参见这里
这 20 幅图对应 20 个不同的特征映射(过滤器或者核)。每个映射表示为 5 * 5 的块图,对应于局部感知区中的 5 * 5 的权重。稍白的块表示略小的权重,这样特征映射更少地对相应的输入像素产生反应。更黑的块表示略大的权重,这样特征映射更多地对相应的输入像素产生反应。粗略地说,上面的图像展示了卷积层对应的特征类型。
所以我们从这些特征映射中能够得到什么结论呢?很显然,这里有一种并非是随机的空间结构:很多特征有明显的亮暗子区域。这表明,我们的网络真的在学习与空间结构相关的知识。不过,看明白这些特征检测器究竟在学习什么是很困难的。可以肯定的是,我们并没有在学习(打个比方)Gabor 过滤器,这种用在很多传统的图像识别方法中的技术。实际上,现在有很多的努力都花费在更好地理解卷积网络学到的东西上。如果你对此感兴趣,我推荐你看看 Matthew Zeiler 和 Rob Fergus 在 2013 年的这篇文章:Visualizing and Understanding Convolutional Networks。
共享权重和偏差的重要优势是他们大幅降低了参数的数量。对每个特征映射,我们需要 25 = 5 * 5 个共享变量和一个共享偏差。所以每个特征映射需要 26 个参数。如果我们有 20 个特征映射,那么对一个卷积层总共要学习 20 * 26 = 520 个参数。假设我们第一层用一个全连接层,共 784 = 28 * 28 个输入神经元,和一个相对少量 30 个隐藏元,跟前面的例子中保持一致。那就共有 784 * 30 个权重和 30 个偏差,总共就是 23, 550 个参数。换言之,全连接层会有超过卷积层 40 倍的参数量。
当然我们不能真的就对参数的个数进行直接对比,因为这两个模型是本质不同的。但是,直觉地看,看起来卷积层的变化不变性的使用相比于全连接模型达到同样的性能会降低需要学习的参数的个数。这样将会得到更快的训练的模型,最终能够帮助我们构建使用卷积层的深度网络。
巧合的是,卷积网络的命名来自方程(125)的操作,那个操作就叫做卷积。更准确地说,人们有时候会把那个公式写成 $$a^1 = \sigma(b + w * a^0)$$,其中 $$a^1$$ 表示从一个特征映射中输出的激活值,$$*$$ 表示卷积操作。我们不会再后面使用任何更难的卷积操作,所以不必担心这个关联。不过至少应该了解这个词的来源。
Pooling 层:在卷积网络中,还包含了一个叫做 pooling 的层。Pooling 层通常会立即用在卷积层后。而 pooling 层所做的实际上就是简化从卷积层得到的输出。
pooling 层使用卷积层的每个特征映射作为输出,并得到一个压缩了的特征映射。例如,pooling 层的每个单元可能会对上一层中的一个(如 22 大小) 的区域进行总结。用具体例子,一个通常使用的 pooling 操作是 max-pooling。在 max-pooling 中,pooling 单元就会输出 22 区域中最大的那个激活值,如下图所示:
Paste_Image.png注意,因为我们的卷积层输出是 24*24 神经元,pooling 之后就是 12 * 12 个神经元。
正如下面所述,卷积层通常包含超过一个特征映射。然后我们分别应用 max-pooling 到每个特征映射上。所以如果有三个特征映射,组合的卷积和max-pooling 层就是这样子:
Paste_Image.png我们可以见 max-pooling 看成是网络确认一个给定特征是否在图像区域中任何地方都存在的方法。接着会丢弃准确位置信息。这个直觉就是一旦特征被发现了,其准确的位置就相对于其他特征来说不那么重要了。最大的好处就是,这样会产生更少量的pooling后的特征,降低了在后面网络层的参数的数量。
max-pooling 不是 pooling 的唯一技术。另一个常用的方法是 L2 pooling。这里使用 2*2 区域内神经元的激活值的平方和的平方根。尽管细节不同,直觉上仍然和 max-pooling 相似:L2 pooling 是一种压缩来自卷积层的信息的方法。实际应用中,两种方法都广泛使用。有时候人们还会尝试别的 pooling 操作。如果你真的想优化性能,可能需要使用验证数据来比较不同的 pooling 技术,选择那些表现最好的。但是我们这里不会去详细讨论优化的细节。
整合所有这些方法:我们可以将这些方法整合起来形成一个完整的卷积神经网络。类似于我们刚刚看过的那些架构,不过会增加一个有 10 个输出神经元的层,对应于不同的 10 个数字:
Paste_Image.png这个网络以 28 * 28 输入神经元作为第一层,来编码 MNIST 图像的像素强度。接着跟随一个使用 5 * 5 的局部感知区和 3 个特征映射的卷积层。结构是一个 3 * 24 * 24 的隐藏特征神经元层。下一步就是加入一个 max-pooling 层,应用在 2*2 区域上,共有 3 个特征映射。最终就是一个 3 * 12 * 12 的隐藏特征神经元层。
最终层的连接是一个全连接方式。该层连接来自 max-pooling 层输出到这所有 10 个神经元上。注意这和我们之前介绍的一样。尽管图中只用了一根带箭头的线表示。这很容易想象补全。
这个卷积结构完全不同于我们之前使用的架构。不过整体的图结构类似:拥有多个简单输入段元的网络,网络的行为完全由权重及偏差确定。整体的目标也一致:使用训练数据来训练网络权重和偏差,这样让网络能够很好地对输入数字图像进行分类。
特别地,和本书前面章节中一样,我们会使用随机梯度下降和 BP 来进行训练。这个流程和我们前面介绍的都是一致的。然后,我们这里需要对 BP 进行一些修改。因为前面章节的 BP 推导都是在全连接的层下进行的。幸运的是,这里的修改是很直接的。如果你想理解这些细节,我希望你能够仔细研究一下下面的问题。需要注意的是该问题会花费一些时间,除非你对之前的推导已经非常熟悉了。
问题
- 卷积网络中的 Backpropagation:在全连接网络中的 BP 核心公式是 (BP1)-(BP4) (link)。那么在卷积网络中,这些公式将如何修改呢?
人工智能时代每个人都将面临挑战,想要了解更多相关知识和实践经验,请关注公众号“UniversityAI”。
UAI 人工智能
网友评论