第2章
神经网络架构
本章我们将介绍在深度学习应用中常用的深度学习架构。深度学习旨在解决真实世界的各种任务。每种类型的应用经常需要在特定场景下选择合适的模型结构。
卷积神经网络(CNN)架构擅长解决图像识别问题。因为卷积和池化操作的行为有点像图像过滤器应用于输入图片的不同尺度。而由于循环 cell(recurrent cell)的递归行为循环神经网络(RNN)架构常用来解决自然语言处理问题,比如,语音{文字的转化、语义模型等。
只有掌握深度学习模型和它们应用的领域,才能创建高效的深度学习应用。本章介绍的深度学习模型有 CNN、RNN 和增强学习的深度神经网络。
2.1 卷积神经网络
解决图像识别的深度神经网络是卷积神经网络(CNN)。CNN的主要架构是一个卷积层,卷积层可以抽取图片的高级特征(抽象特征),训练过程学习到图片的边、曲线、块和对比度。通过图像的原始特征,多个卷积层堆叠形成一个高级特征的探测器,比如激活纹理、表面或者动物的过滤器。值得注意的是,这些高级特征对于移位操作的影响是健壮的,这意味着,即使图片上的一个对象移动到其他位置,CNN 仍然能识别出该特征。
该特性称之为平移不变性或者空间不变性。由于CNN 的健壮性,CNN能在图像识别领域有着杰出的精确度。所以CNN是现代图像识别应用事实上的标准。
分析多个现代深度学习架构,你会发现网络的大体结构有许多相似之处。接下来你将看到的大部分网络,都跟20世纪80年代Yann LeCun开发的模型的抽象结构类似。该网络模型包含一个输入层,一个前端(输入降维和特征抽取)和后端(分类器或者回归)。前端的输出是一个特征图,或者用特征空间表示的输入图像。依据应用或者任务的不同,模型网络可能有多个后端或者单个网络用来进行年龄和性别分类。
深度学习架构的相似性是模型网络高水平组件的设计选择。我们经常会发现引入用参数的组件相比于特征表示的要高效,比如GoogLeNet的Inception模块和SqueezeNet的Fire模块用卷积层代替全连接层,或者用AveragePool后端替代softmax分类器。模型设计的第二个动机是梯度在模型之间的传递。我们将在 ResNet 模型的残差块(residual block)进行更细致的讲解。
许多高水平的深度学习模型都是由杰出的、拥有大量资金和资源的组织或者公司开发的。因此,非常强烈地推荐你使用成熟的模型,而不是去创造你自己的 CNN 模型(除非你是一个深度学习研究者)。在应用中使用成熟的模型会减少开发的时间并使预测的准确性可以接受。
2.1.1 AlexNet
AlexNet是在2012年的ImageNet大规模视觉识别挑战赛(ImageNet Large Scale Visual Recognition Competition,ILSVRC)上提出来的,top-5(前5位)预测的错误率为15.3%,远超其他选手。AlexNet 采用8层的神经网络,其中大部分是卷积层。图2-1显示了AlexNet架构概览。
正如你所见,该网络模型由卷积层、池化层和全连接层交叉出现组成,包含6000 万个可训练的参数。它也使用了一个softmax分类器作为后端,包含两个全连接层和一个softmax激活函数。其响应了模型参数中的 96%。最后的全连接层效率不高,却要求大量的参数。
这个模型是由 SuperVision 组设计的,该组包括 Alex Krizhevsky、Geofirey Hinton和Ilya Sutskever。AlexNet 模型将参数化拟合放入两个并行的GPU内存中,这在当时是非常牛的设计。在并行GPU上训练模型花费了两周时间。由于AlexNet 模型在图片分类挑战赛上的突出表现,我们可以说 AlexNet模型是深度学习技术突破性发展的起点。
2.1.2 GoogLeNet
GoogLeNet是2014 年ILSVRC的冠军,top-5 预测的错误率达到6.7%,却只用了不到 AlexNet模型参数的十分之一。其模型性能非常接近人类识别的水平。
GoogLeNet是一个具有22层的卷积神经网络,但是它引入了宽度模块,其比纯卷积层效率要高。GoogLeNet 的高级结构在图 2-2 中展示。
GoogLeNet的开创性观点是提出Inception模块,它包含并行的1×1、3×3和5×5的卷积过滤器,并同时增加一个池化过滤器。接着紧跟一个深度连接层。
Inception 模块比单个卷积层效率高,因为它可以捕捉不同尺度的特征。Inception模块重度使用 1×1的卷积核,即所谓的bottleneck convolution。该操作沿着深度(depth)维度将输入数据的权重求和,当进行卷积连接时,这种特性很巧妙地减少了深度维度的数目,并且减少了各激活之间的相关性。如图2-3所示。
另一个急剧减小模型参数的技术是使用平均池化操作代替耗时的含有全连接层的softmax分类器。因此,GoogLeNet模型的可训练参数的数量不到700万。
GoogLeNet模型最大的创新点是提出Inception 模块和bottleneck convolution的使用。Google最近开发的模型,比如,Chollet开发的 Xception模型或者AutoML,发现更多复杂的类 Inception的宽模型以提升性能。从宽度模型得到的主要一点是,不需要顺序堆叠卷积层也能提升网络模型性能和准确度。
2.1.3 ResNet
ResNet,也叫作残差神经网络,是由微软的 Kaiming He提出的。在ILSVRC 2015比赛中该模型达到令人难以置信的3.6%的误差率,比人类的图像分类准确度要高。需要注意的是,ResNet模型共有152层,是本节介绍的层最多的神经网络。ResNet 神经网络的skip connection结构也是创新点,它创建新的连接,忽略一些层。这个skip block也称为残差块。如图2-4所示。
众所周知,简单地增加层深度会造成梯度消失的问题。虽然使用更多的层数会提高准确度,但是太多的层数会让模型变差。当堆叠太多的卷积层时,梯度将会随着反向传播而消失,所以训练模型变得困难。神经网络的层数要进行平衡选择。
ResNet 的核心概念,或者说残差模块,是用来解决上述问题的。从上图可以看出,identity connection会忽略一些卷积层。在这个模块中,训练的神经网络的参数预测输入值到目标值的残差。ResNet试图学习残差本身,而不是学习目标输出。残差对输入的微小变化都较为敏感。相同的想法应用于梯度。残差连接的良好特性是,梯度传入残差模块,直接作为残差模块的输入。
这就是为什么ResNet可以以较少的网络参数获得最好的深度层的性能。因为有许多 ResNet的优化版本,它可能是最有前途的神经网络架构。
2.1.4 SqueezeNet
SqueezeNet 模型是一个小型的深度学习模型,是专为移动端、嵌入式或者物联网设备设计的。其原始的论文标题是《AlexNet-level accuracy with 50x fewer parameters and <0.5MB model size》。
SqueezeNet模型的设计目标是在不损失准确度的情形下使用更少的模型参数。表2-1显示了 SqueezeNet模型能够节省的内存空间。与压缩的 AlexNet模型相比,SqueezeNet模型比AlexNet 模型小得多,但是没有损失准确度。
SqueezeNet模型引入三种不错的策略:
1.使用1×1 bottleneck convolution替代 3×3过滤器,因为前者只用了九分之一的参数。
2.使用1×1 bottleneck convolution来减少输入通道的数量,所以会减少后续的计算量。
3.采用下采样保留大的特征图,提高神经网络模型的性能。
策略1和策略2可以减小模型的大小,策略3用来保证准确度。SqueezeNet神经网络模型的构建基础是 flre模块,它是由squeeze层和expand层组成,如图2-5所示。
Squeeze层减少到下一个expand层的输入通道的数量,对应于策略2。expand层用1×1层和3×3层过滤输入。1×1过滤器用来较少层的参数数量,对应于策略1。使用flre 块减小了SqueezeNet模型的大小。SqueezeNet模型有池化层,可以进行下采样,见策略3。这些池化层放在卷积层之后。图2-6展示了 SqueezeNet模型的整个架构。
你可以看到在层之间使用一系列的flre模块。SqueezeNet模型能在减小模型大小的同时保证达到 AlexNet模型同样的效果。它常用在像移动端或者物联网设备一样的客户端。
2.2 循环神经网络
因为CNN擅长抽取图像的特征,所以主要用在图像识别领域。但是你不能用CNN处理像时序数据或者自然语言的序列数据,因为这样效率不高。而循环神经网络(RNN)是用来解决该类问题的模型。它基于历史数据来保留前面的状态以预测接下来的输出。假如我们来预测一句话的下一个单词。比如,我们说,“I am learning deep learning.”很自然会认为最后一个单词“learning”是依赖前面的词语“I am learning deep”。简而言之,它需要记住前面的一些词语来让深度学习网络输出合适的单词。U、W和V 是权重矩阵。x是输入向量,h是隐藏层。隐藏层是 RNN的中间状态。图2-7显示RNN的样子。
RNN的隐藏层的输出是下一时刻的输入。在上面的图中,t-1时刻的隐藏状态 h(t-1) 将是t时刻的 h(t)的输入。RNN从序列数据接收一个输入,然后预测输出结果。隐藏层的输出是作为中间状态。它将作为下一时刻隐藏层的输入。中间状态是由所有先前的状态计算获得的。所以RNN能用来解决数据的序列问题。
虽然RNN在20世纪80年代就开发出来了,但是当时的神经网络的准确度不够。RNN 模型的训练都是由随时间的反向传播算法(BackPropagation Through Time,BPTT)计算的,该算法是与正常的前馈神经网络模型的反向传播算法相似。RNN 的循环可以看作是一个神经网络的可变长度的链。你可以打开循环看到一个常见的神经网络。
使用前面的方式,梯度会随着网络的加深而消失,这意味着层的权重不能继续更新。训练一个深度的 RNN 到合适的准确度是相当困难的,因为不常考虑太远的输入之间的依赖。
为了解决RNN的梯度消失问题,提出了LSTM和GRU模型。
2.2.1 LSTM
长短记忆内存模型(Long-Short Term Memory,LSTM)是在1997年由Hochreiter和Schmidhuber提出的,大约在2007年应用于深度 RNN架构,在语音识别问题上取得了很明显的效果。LSTM为RNN添加一个新的单元来学习长距离依赖。该单元用来学习一个序列什么时候保留内部状态、什么时候丢弃内部状态。LSTM是由四个单元组成:CEC、输入门(input gate)、输出门(output gate)和遗忘门(forget gate),而RNN只有单个神经网络层。
- CEC:它是常数误差传送带(Constant Error Carousel,CEC)的首字母缩写。该单元保留上一个状态。LSTM模块的CEC仅仅对输入乘以1并在下一时刻返回该值。这是LSTM的核心组件。得益于 CEC,层的梯度不再随着神经网络的深度而消失。
- 输入门和输出门:这些单元控制开放CEC单元的时机。如果这些时间之间没有依赖,则CEC会让所有前面的值通过到下一状态。这就是为什么这种门是必要的。输入门和输出门只有当需要时才打开。在其他情况下,这些门会关闭。输入门和输出门与其他层一样是可训练的,在合适的时间关闭或者打开。
- 遗忘门:通过引入CEC和输入/输出门,这时就可以考虑长期依赖的问题。另一方面,有一种情况是你不需要过去存储的记忆,因为数据模式已经改变了。在这种情况下,LSTM应该高效地清除存储的值。遗忘门负责管理CEC中值的重置时机。遗忘门基于输入值和过去的状态决定清除值的时机。
图2-8显示LSTM的各模块。上部的圈依次代表输入门、遗忘门和输出门。它们对给定输入值进行神经元激活。点线输入表示从过去传入的值,其存储历史状态。
图2-8的四个单元构成了一个LSTM模块,管理过去历史的状态。请记住,LSTM也是一个可训练的模块,所以我们不必考虑存储多长的过去历史状态或者什么时间清除它。这些都是通过优化过程学习到的。
2.2.2 GRU
LSTM是一个学习长依赖项的好方法。但是它的模型参数太多,计算过程很耗时。如果你可以用一个单元能以更少的计算成本获得相同水平的性能,那一定更好。在2014年由Kyunghyun Cho等提出了 GRU(Gated Recurrent Unit),它是一个能替代LSTM的单元。GRU只有两个门组成:重置门和更新门。
图2-9所示,GRU比LSTM更简单。
重置门和更新门都是从输入值和过去的状态计算自己的输出。重置门的输出用来决定是否使用之前的状态。更新门的输出作为一个权重决定过去的状态和当前状态的比例。GRU训练的参数比LSTM少很多。你能看到GRU在训练状态和推断状态时速度更快。
2.3 深度强化学习
CNN和RNN经常用在监督学习中,这意味着需要给定一些目标值和相应的输入。强化学习是另外一个领域的机器学习。它需要给出一个模型激励和状态。所以强化学习模型(智能体)强调如何基于环境而执行动作,以取得最大化的预期利益,见图2-10。
所有的智能体都知道给每个智能体动作的激励和周围的环境。例如,在迷宫中有一个智能体。智能体不知道如何到达迷宫的目的地。每走一步给一个激励。在智能体到达目的地的过程中激励的百分比越来越高。对于智能体来说,通过最大化总的激励从而搜索到正确到达目的地的路线。其中的挑战是,智能体不知道它在将来获得的激励,因为这依赖智能体的动作。理论上讲,这种问题可以描述成一个马尔科夫决策过程(Markov Decision Process ,MDP)。
- 有限的状态集合:在迷宫中,智能体可能的位置。
- 每步骤可能的动作集合:如果没有墙存在,智能体可以向上/向下/向左/向右移动。
- 根据智能体的动作进行状态的转移:如果智能体向上移动,智能体周围的墙以及到目的地的距离相应地变化。
- 激励的折扣因子为 0»1 之间的值:它会控制时序中激励的重要性。在将来获得的激励往往不如当前获得激励的重要。
所以智能体的目标可以表述为:
激励R依赖于智能体的动作和t时刻的状态。激励的折扣因子为。所以智能体学习需要最大化其总激励G。它被称为折扣总激励。最大化总激励的最出名的算法是Q-learning。 Q-learning算法基于映射函数(动作{激励值函数)学习选择哪个动作。动作激励值函数在给定状态和动作时,会返回期望的总激励。智能体应该选择一个动作函数返回最大化估计的总激励。
公式2表示在给定状态和动作时,会返回期望的总激励。S是状态,A是t时刻的动作。这种总激励经常用大写的Q表示,所以也称为 Q-learning算法。看起来相当简单,但是我们如何得到这种魔法函数呢?
这种函数最初不能正常工作。它总是返回相同的值或者一个随机值。该函数必须根据下面的公式基于智能体,通过探索得到的实际激励进行更新。
在每一步中,函数基于上面的公式进行更新。α 是学习率,γ是乘以激励的折扣因子。这里我们不去深挖细节,但是众所周知,Q-learning算法最终能够在任意有限的MDP找到优化的方案。使用优化函数,智能体为每个可能的状态找到最优化的动作。智能体不必每次都选择最优的动作。随机选择次最优的动作能够让搜索空间更宽,所以智能体有更多的时间探索。
有另外一种方法实现 Q-learning 算法,代替动作{激励值函数。你可能注意到,我们有一个函数可以直接从当前的状态预测下一个动作,这种方法称为策略学习。这是一种更直白的方式来推断下一个动作,而不是仅仅计算期望的总激励。
但是如果输入状态太复杂不能高效地推断下一个动作,怎么办?这时可以使用深度神经网络进行强化学习。
DQN 算法
深度Q网络(Deep Q Network,DQN)是深度神经网络在 Q-learning算法上的应用。它在2015年由 DeepMind提出,并在许多雅达利游戏(Atari game)上打败人类,比如街机Pong。DQN 接收输入图片(比如,游戏的一帧)的像素,为每个动作返回一个估计的激励。因为一个深度神经网络擅长识别图片的字符,DQN 能找到必要的信息来提供更好的总激励的估计。但是 DQN 的贡献不限于使用深度神经网络进行强化学习。在强化学习中深度神经网络的学习并不稳定。有两种方法来解决 DQN 中的这种问题。
- 经验回放(experience replay):为了避免过拟合到特定的状态转移,智能体所有的状态转移经验被存储。它被用来在后续 mini-batch 方法中训练 DQN。它不仅能提高准确度,也可以通过 mini-batch 算法加速学习。
- 忽略帧(skipping frame):雅达利游戏环境每秒钟有 60 帧图片,但是人类在一秒钟并不能输入许多动作。所以这种方法会在每小时的帧上计算 DQN 的估计。它能在不降低准确度的情况下显著地减少计算成本。
表2-2 显示了各种学习算法玩雅达利游戏的平均总激励。从上表可以看出DQN明显在一些游戏上超越人类。基本上,DQN获得了人类控制雅达利游戏的水平。最著名的深度强化学习的应用是AlphaGo。AlphaGo打败世界上不少棋手,它让机器像人类一样思考复杂概念,这是一个重大里程碑。
2.4 本章小结
在本章中,我们介绍深度学习模型的几种情况。每种模型都是为了解决特定领域的问题而设计的。CNN 用来解决图像识别,比如物体探测。这种模型擅长从原始的图片数据集抽取有用的特征。你可以使用 RNN 处理时序数据,包括自然语言处理。这种模型已经用在许多著名的机器翻译系统上,比如 Google 翻译。最后但同样重要的是,深度强化学习模型显示了里程碑式的结果,特别是在游戏领域,打败了人类。深度强化学习提醒我们人工智能的到来。一定要多留意新深度学习架构。