购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.3 卷积神经网络的组成细节

1.2节介绍了一些神经网络的基础知识,读者对神经网络的基本特性应该已经有所了解。但随着近几年相关研究的发展,神经网络的结构变得越来越复杂,原本只由卷积层和激活层组成的神经网络,如今发展出了五花八门的各种网络层。

图1-11所示为一个简单的语义分割(Semantic Segmentation)神经网络,RGB彩色图片从左侧输入,右侧输出语义分割图。 语义分割的任务是对原图的每一个像素分类, 例如,图中的像素被分成了三个类别,即黑色部分是背景,深色部分是摩托车,浅色部分是人。数字代表特征图的通道数,高度代表特征图的尺寸,每一个箭头都包括了卷积层、激活层、归一化层和用于缩放特征图的插值采样层。

· 图1-11 语义分割神经网络模型

在本节里,笔者会详细介绍卷积神经网络的常用网络层以及这些网络层的适用范围。

1.3.1 卷积神经网络的输入层

卷积神经网络的输入以图片为主,RGB图片被看作是一个三维张量。但这个三维张量不能直接输入到神经网络中,需要对其进行预处理(Preprocessing)。

1.输入归一化

和传统的机器学习一样,卷积神经网络也要对输入进行归一化(Normalization)。归一化的方法有很多种,最终目的是把数据的取值范围压缩到一个较小的区间。

最简单的预处理方法是最小最大归一化(Min-Max Normalization)。假设第 i 个输入数据是 X i ,整个数据集用 X 表示,最大最小归一化的计算方法如下:

如果输入数据是图像,图像数据的RGB值一般是0~255之间,所以只需把输入的图像数据除以255,归一化就完成了。通过最大最小归一化,输入数据将被压缩到0和1之间。

另一种归一化方法也称标准归一化(Standardization),这种标准归一化方法需要计算整个数据集的平均值和标准差,计算方法为:

式中, μ 是整个数据集的平均值,对于图像数据而言就是所有RGB值的平均值; σ 是整个数据集的标准差,也就是所有像素点RGB值的标准差。标准化后的数据均值为0,最小值和最大值则会根据输入数据的分布变化,一般在-3和3之间。

为什么要归一化?解释有很多种,其中一种是从优化算法的角度来考虑。图1-12所示是一个机器学习模型的损失面等高线,横轴和纵轴代表的是模型的两个参数。这两个参数可以有无数种可能性,每一组参数形成的模型都可以算出一个损失值,这就形成了一个损失曲面。图中从外围浅色的部分到内部深色的部分,损失值逐渐减小,而优化算法的目标就是要找到一组让损失最小的参数,也就是图中深色区域的参数。图1-12a所示是直接使用原始数据作为输入产生的损失面,图1-12b所示是使用归一化数据作为输入产生的损失面。箭头代表使用梯度下降法进行优化时参数更新的方向,因为使用了梯度下降法,参数的更新总是朝着梯度最大的方向,也就是垂直于等高线的方向进行。

· 图1-12 梯度下降算法在不同输入数据下的表现

显然,要从初始位置到达损失值较小的目标区域,使用归一化后损失曲面更规则,优化起来速度更快,绕的弯路更少。而原始数据输入参数的两个维度尺度差异很大,导致其相应的权重差异也很大,损失面就产生了扭曲。

还可以从另一个角度出发来理解,后文会介绍,模型最终的输出一般都位于-3到3之间。如果输入数据的范围是0~255,那么神经网络的一个任务就是要把0~255的数据投射到-3到3之间。不进行输入归一化的话,神经网络就需要通过优化去完成这个任务。而神经网络的参数是有限的,交给模型去完成的任务当然越少越好,既然已经知道这个先验知识,何不直接代劳,帮模型完成这个任务。使用最大最小归一化,相当于帮模型完成了一部分任务,使用标准归一化,则可以认为是完全代劳了。相较于最大最小归一化,使用标准归一化的做法可以提高大约0.5%的精确度。

2.数据扩增(Data Augmentation)

输入数据预处理的另外一项重要任务就是数据扩增。图1-13所示很好地展示了图像数据扩增到底是做什么的。图中左上角是原始图片,其他图片都是扩增的图片。

· 图1-13 数据扩增

如果神经网络的任务是识别第一张图片中的鹦鹉,那么这个模型也应该能识别出其他图片中的鹦鹉。这对于人类而言是很轻松的任务,而神经网络的目标是赶超人类。也就是说, 数据扩增是通过对图片进行受限制的随机处理,生成新的数据。 标注数据的成本很高,通过数据扩增,相当于免费获得了新的数据。如图1-13所示,一共使用了11种不同的数据扩增方法,等于把数据集扩大了11倍。数据扩增还能让神经网络更加健壮(Robust),如果不进行数据扩增,神经网络很可能只会学到“鹦鹉就是红色的鸟”这样的特征,但哪怕图中的鹦鹉是绿色的或是黑白的,人类仍然可以识别出来这是一只鹦鹉。 数据扩增可以防止神经网络学习到错误的,或者说过于简单的特征。

1.3.2 神经网络的输出层

神经网络的输出根据具体的任务来确定,大部分任务都可以归为两种:分类(Classification)任务和回归(Regression)任务。顾名思义,分类任务就是对输入进行分类,例如,区分输入的图片是人还是车,根据摄像头拍摄的图片区分阴、晴、雨、雪、雾五种天气等。因此,分类任务输出的值是离散的。

回归任务的范围就大多了。当神经网络需要预测某一个特定的值时,就是在做一个回归任务。例如,预测明天的气温具体有几度,通过摄像头预测距离前面的汽车有多少米等。回归任务输出的值是连续的。

1.分类任务的输出

分类任务输出的值一般理解为将输入分类为某一个类别的概率。最简单的例子莫过于二分类任务,也就是只有两个类别。例如,识别一幅图片是不是汽车就是一个二分类问题。对于二分类问题,只需要一个输出值就可以了,这个输出值代表的是其中一个类别的概率。网络直接输出的值是任意大小的数值,而概率却必须是0到1之间的值,所以需要将神经网络的输出通过一个函数映射到0到1之间。一般使用Sigmoid激活函数完成这个任务,Sigmoid函数可表示为:

Sigmoid函数使用 σ (Sigma)符号表示,这是因为 σ 的一个变体是∫(Esh),Sigmoid函数的图形特别像∫,如图1-14所示。

从图1-14中可以看出,负无穷到正无穷的实数会被Sigmoid函数映射到0到1之间,输出的数值可以理解为某一个类别的概率 P 。因为这是一个二分类问题,那另一个类别的概率自然就是(1 -P )了。进行预测的时候,如果输出代表的是“图片为汽车的概率”,那么当输出概率>0.5时,就意味着图片是一张汽车图片,输出概率<0.5则不是。

如果是一个多分类问题,例如,要识别一张图片到底是行人、小汽车、自行车还是其他,就需要输出四个类别。最直观的想法是输出四个值,每一个值都连接一个Sigmoid函数,不就有四个概率了?这样当然也是可以的,但很容易发现,每一张图片都只可能是这四个类别中的一种,根据概率论的知识,神经网络预测的各类别概率加起来必须等于1。如果简单地输出四个值,每个值连接一个Sigmoid的函数,最后四个概率加起来不能保证刚好等于1。为了让各个分类的概率加起来等于1,多分类问题一般使用Softmax函数,其原理很简单,表达式为:

· 图1-14 Sigmoid激活函数图形

式中, P j 是指第 j 个类别的概率; x j 是神经网络的第 j 个直接输出值;一共有 k 个类别,所以神经网络一共有 k 个输出值。为了观察两者的区别,图1-15中展示了一个具体的例子进行对比。

· 图1-15 Sigmoid和Softmax激活函数区别

图1-15a使用了Sigmoid激活函数,各类别概率相加不等于1;图1-15b使用了Softmax激活函数,所有类别的概率加起来等于1。进行预测的时候,四个类别里概率最大的那个类别就是模型预测的识别结果了。既然神经网络输出了四个概率,那么进行训练的时候,训练数据也应该有四个概率,例如,某张图片里包含了自行车,训练的时候给出的标签就是1,0,0,0四个数,除了自行车类别为1,其余均为0。这种只有一个类别概率是1,其他都是0的编码方式,被称之为独热编码(One-hot Encoding),图1-15很形象地展示了独热编码:只有概率最大的那个类别是“热”的。

读到这里读者们一定很疑惑,为什么Sigmoid和Softmax都不约而同地使用自然常数e?如果仅仅是用于损失函数,那么使用2或者10之类的数字作为底数都是可以的,不会对结果产生显著的影响。但自然常数e能带来很多便利,如导数和积分等于其自身,统计学中常用的正态分布是自然常数的幂等。选择自然常数e能让和损失函数有关的微积分运算变得更加简洁直观。

2.回归任务的输出

回归任务的输出范围要广得多。最简单的处理方式就是使用神经网络的直接输出,不连接任何激活函数,这样就能保证覆盖从负无穷到正无穷的整个取值范围。但很多时候,回归任务的目标取值范围是很明确的,如果不限制输出数值的取值范围,神经网络可能会输出不合常理的数值。例如,回归的目标是温度,那肯定要高于绝对零度,但如果不设限制,模型就有可能输出低于绝对零度的值。又比如回归目标是汽车的速度,一般不会超过200km/h。这些先验知识,神经网络是不知道的,最终都得通过训练来学习。如果能直接把输出数值的范围限定在指定范围,相当于帮助模型减轻了学习负担,模型的表征能力(Representation Power)就可以用在提高精确度上了。

根据不同的回归任务,可以使用不同的激活函数来限制输出数值的取值范围。例如,要输出一个0°~360°的角度,就可以使用ReLU作为激活函数,这样至少可以保证输出肯定>0。为了得到不超过360°的输出角度,还可以截断超过360°的输出值,也就是为ReLU激活函数设置一个最大输出值,这也是常见的做法。如果取值范围比较随机,可以在ReLU函数之后加一个偏置值来实现。例如,目标取值范围是4~20,就可以在最后连接一个最大值为16的ReLU函数然后加上4,这样输出数值的取值范围就是4~20了。也可以使用Sigmoid代替ReLU达到同样的目的。

甚至还可以把回归任务转换成分类任务。例如,回归任务目标是一个取值范围在0°~360°的角度,可以在输出端连接一个有360个类别的Softmax函数,分别代表360个角度。把回归任务转换成分类任务的好处是任务变得更容易了,原本模型需要预测0~360范围内的任意一个实数,可能性是无限的,如今只剩下了360种可能性,难度大大降低。但很显然,模型输出的误差必然>0.5°,如果回归目标是12.5°,模型将无法输出这个数值,只能输出12°或13°,这就存在一个0.5°的误差。

3.不同维度的输出

前文提到的图片分类任务也好,角度和速度的回归任务也好,都属于一维输出,而卷积神经网络的特征图都是二维的,所以在输出层之前,只能将二维的特征图整平(Flatten)为一维向量,然后通过一个全连接层输出一维向量。

在计算机视觉领域,二维的输出也是很常用的。例如,语义分割(Semantic Segmentation)就是自动驾驶领域必备的二维输出。语义分割的目的是为相片的每一个像素分类,常用的类别有汽车、行人、植被等。图1-16所示是语义分割的真实值(Ground Truth),训练好的语义分割模型也应像这张标注图片一样,能为图片中的每一个像素分类。

· 图1-16 语义分割的真实值

为了完成语义分割任务,模型要输出一张二维的分类图。卷积神经网络的特征图本来就是二维的,输出二维分类图反而简单。卷积神经网络一维和二维分类输出的计算方法如图1-17所示。

· 图1-17 一维和二维分类输出的区别

1.3.3 卷积层和转置卷积层

卷积层已经在本章卷积神经网络简介中做过介绍,读者想必对简单的卷积计算已经很熟悉了。但近几年发展出来的各种卷积层变体应用得越来越广泛,不同卷积层的用途和特性都不一样。图1-18所示为四种卷积层的计算方法。

1.卷积核尺寸

卷积核的大小是可以调节的,一般使用奇数作为卷积核的尺寸,这样卷积核会有一个中心像素,方便对齐。卷积核的中心对准图片像素的中心,然后一个像素一个像素地平移经过每一个像素,就能输出一张和原图片一样分辨率的特征图。如前文所述,当卷积核的中心对准图片边缘像素时,卷积核的一部分会露在图片外面,要使用零填充(Zero Padding)来完成计算。最常用的卷积核是3×3卷积,几乎是最小的卷积核了。当然还有更小的1×1卷积核,但这个一般有特殊用途,后文会介绍。卷积核的大小决定了卷积运算感受野(Receptive Field)的大小,所谓感受野,就是卷积运算时单个卷积核覆盖的空间大小,卷积核尺寸越大,感受野也越大。为了增加感受野,往往会把卷积核的尺寸增加到5×5,不同大小的卷积核在实际运算过程中的对比如图1-18a、b所示。

· 图1-18 四种卷积层的计算方法

卷积核尺寸增加了,计算量当然也相应增加。如果将3×3卷积核用于一张640×480分辨率的图片,一共要进行3×3×640×480次乘法和加法。如果是5×5卷积核,就需要5×5×640×480次乘法和加法,计算量差距是非常大的,因此一般不会使用5×5卷积核。

2.空洞卷积

增加卷积核尺寸扩大感受野,就得承受翻倍的计算量,于是研究人员开始思考,如何在不增加计算量的情况下扩大感受野?空洞卷积(Dilated Convolution)就是为了这个目的而设计的。空洞卷积的思路非常巧妙,卷积核被理解为对图片进行信息采样的工具,最原始的卷积核相当于对图片进行密集采样(Dense Sampling),而空洞卷积则是对图片进行稀疏采样(Sparse Sampling)。如图1-18c所示,空洞卷积的卷积核张得很开,中间跳过了几个像素,在卷积核里留下了空洞,所以称为空洞卷积。空洞卷积通过牺牲信息的密度来获得更大的感受野。如图1-18c中所示的空洞卷积,只有9个参数,却获得了和5×5卷积核一样大小的感受野。考虑到图片的信息密度非常高,使用空洞卷积进行稀疏采样就变得非常合理了。空洞卷积特别适合高分辨率图片和大物体的识别。对于高分辨率图片而言,信息密度已经很大了,牺牲一点无伤大雅。如果在感知图片中的大物体时使用普通卷积,感受野太小,无法将大物体的整体信息纳入感知范围,而使用空洞卷积则可以解决这个问题。

3.卷积的步长

除了调节卷积核的尺寸和排布方式,还可以调整卷积运算时的平移量。普通的卷积是将卷积核中心对准某一个像素,计算卷积,然后平移到下一个像素,如此循环直至覆盖整张图片。不难想到,平移的时候让卷积核跳过两个像素直接平移到第三个像素也是可以的,平移卷积核时跳过的像素数目称为步长(Stride)。直接跳到下一个像素,卷积的步长为1;每次平移跨过一个像素,卷积的步长就是2。通过设置卷积步长为2,卷积层会输出一张长宽均减半的特征图,可以认为这是一种对特征细节的浓缩,或者对特征的进一步抽象。具体的计算方式如图1-18d所示,图中的小箭头显示卷积核平移的步长为2。

4.转置卷积

卷积神经网络除了对细节进行浓缩和抽象,有时候也要利用特征重建细节。前文提到的语义分割模型就是需要重建细节的模型。例如,输入特征图的分辨率为128×128,最终需要得到256×256,甚至512×512的高清晰度输出,此时就需要使用转置卷积(Transposed Convolution)了。

进行卷积计算时,图片上3×3的小区域和3×3的卷积核进行点积运算,得到的是特征图上的一个点。而转置卷积则是将特征图上的一个点和3×3卷积核相乘后累加到特征图上。如图1-19a所示,右侧特征图中第一行第二列的值2和卷积核相乘,然后累加到左侧的输出特征图中,就完成了一次转置卷积操作。和卷积一样,通过平移卷积核的位置反复进行转置卷积运算,每一次运算的结果都直接累加到输出特征图中,最后可以得到一张和输入特征图一样大小的输出特征图。读者朋友们可以计算一下图1-19b所示的例子是否和结果相吻合。

· 图1-19 转置卷积计算过程

看起来,除了计算方法不同,似乎输入、输出和计算量都是一样大的,那转置卷积有什么特殊的用途?如图1-19c所示,使用步长为2的转置卷积可以生成输入特征图两倍大的输出特征图。简而言之,转置卷积可以让特征图分辨率变大。但转置卷积也有缺陷,观察图1-19c会发现,输入特征图中的3和1是紧紧挨着的,而输出的高分辨率特征图中3和1在中间隔了个空白列,这就是所谓的棋盘格效应。图1-20所示是一张使用了转置卷积的语义分割预测图,观察前方行人和右侧路灯杆上的棋盘格纹理,会发现棋盘格效应对语义分割的质量影响很大,出于该原因,工程师们越来越倾向于 用卷积和下采样的组合来取代转置卷积。

· 图1-20 转置卷积导致的棋盘格效应

1.3.4 激活层

和MLP网络一样,卷积神经网络每一个卷积层后面都会连接一个激活层来引入非线性变换。激活层的激活函数仍然遵循这样的仿生规律:小的输入值不产生或者只产生微弱的神经冲动,大的输入能产生大的神经冲动。激活函数曾经不受重视,最近几年有越来越多的激活函数被发明出来。激活函数大致可以分为三类,即类Sigmoid激活函数、类ReLU激活函数和类Mish激活函数。不同类型的激活函数有着不同的用途,下面分别介绍各类激活函数的特点。

1.类Sigmoid激活函数

类Sigmoid激活函数的形态如图1-21所示。

Sigmoid函数可以用于输出概率,换言之,使用Sigmoid函数的激活层其实并不是对神经网络的输出进行激活操作,而是输出一个概率图。概率图的每一个像素点都代表了一个0到1之间的概率,这个概率的含义可以自由定义。例如,一个摩托车的语义分割任务,要把图1-22a所示图像中的摩托车分割出来,就可以使用Sigmoid激活函数作为输出层,输出概率图中概率越大的像素越可能是摩托车。经过训练之后,神经网络最后就能输出如图1-22b所示的概率图,颜色偏浅的像素代表摩托车,颜色偏深的像素则代表不是摩托车。因为这种对概率图进行编码的方式和温度图很类似,所以也被称之为热力图(Heat Map)。由Sigmoid激活层输出的概率图不仅可以作为输出,也可以在神经网络中作为注意力图(Attention Map)使用,可以引导神经网络对感兴趣的区域赋予更高的重要性,在后面的章节中笔者会详细解释注意力图的应用。

· 图1-21 Sigmoid和Tanh激活函数的图形

· 图1-22 输入图片及其神经网络输出的语义分割概率图

除了用于生成概率图,Sigmoid激活函数已经不再作为普通的激活函数使用。主要原因是Sigmoid函数的两端太扁平。从图1-21所示的Sigmoid图形可以看出来,当输入值>5或<-5时,Sigmoid函数几乎是平的,反向传播时Sigmoid产生的梯度接近于零,导致学习速度变得很慢,这就是所谓的梯度消失问题(Vanishing Gradient Problem)。Sigmoid函数即便是在梯度最大的位置(也就是零附近)梯度也只有0.25,于是研究人员发明了Tanh激活函数。Tanh激活函数输出值的范围是-1~1,零偏置的输出让训练更稳定。此外Tanh的梯度比Sigmoid要大,作为激活函数表现优于Sigmoid。但很明显Tanh也存在梯度消失问题,所以现在用得不多了。此外,Sigmoid和Tanh都需要进行幂运算和除法运算,效率低。

2.类ReLU激活函数

类ReLU激活函数是使用最广泛的激活函数,其形态如图1-23所示。

· 图1-23 类ReLU激活函数图形

ReLU激活函数的逻辑完全按照人类神经元的逻辑设计,输入<0就截断并输出零,相当于不激活;输入>0则直接将输入传递到下一个神经元,模仿了人类神经元的神经电信号传导过程。前向传播时,ReLU只需要判断输入特征的正负即可;反向传播时,其梯度不是0就是1,也就是说不需要计算梯度,因而其计算效率极高。现在ReLU几乎成了卷积神经网络的默认激活函数,读者们设计自己的神经网络时,都是从使用ReLU开始。

ReLU函数也有缺陷,一个重要缺陷是ReLU函数<0的部分梯度为零,这也意味着如果输入为负值的话,反向传播的梯度都会被截断,导致之前的卷积层无法学到东西。为了解决这一问题,研究人员发明了Leaky ReLU激活函数。如图1-23所示,在<0的部分,Leaky ReLU函数会有一个很小的梯度(一般设置为0.1),如此便可以保证即便处于未激活状态,在反向传播的时候也能向上一层的卷积层泄漏一定比例的梯度,保证学习的活跃度。此外还有研究人员发明了CELU激活函数,其形态如图1-23所示。据试验表明CELU在0附近的平滑曲线能提高神经网络输出的质量和健壮性,而且其输出的均值也会更靠近零一些,有助于训练的稳定,但CELU的计算复杂度要高一些。

3.类Mish激活函数

类Mish激活函数是近年来最为流行的激活函数,根据实践,基本上只要换上Mish,精度就能提升。其形态如图1-24所示。

· 图1-24 类Mish激活函数图形

Mish是最新发表的激活函数,各方面的表现都要优于其他激活函数。随着激活函数形态的越来越复杂,对其性能的解释也越来越困难了。研究人员发现在训练中梯度能更顺畅地在使用Mish的神经网络中流动,但这只是根据观察产生的猜想。在具体的工作中,读者们可以多尝试几种激活函数,然后根据具体项目对计算复杂度和精确度的要求选择最符合的激活函数。

1.3.5 归一化层

前文提到,神经网络的输入是很随机的,其均值和标准差也是随机的,不规则的数据会产生不规则的损失曲面,对优化算法不利,因此需要进行输入归一化让损失面变成一个更为对称的曲面,让训练变得更快。归一化的计算可用式(1-21)表达:

式中, X i 是归一化的对象, μ 是平均值, σ 是标准差。显然,平均值和标准差都是统计量,需要积累许多的 X i 才能计算出平均值和标准差,于是就诞生了各种各样的归一化方法。

这些归一化方法的计算公式都是式(1-21),只是统计平均值和标准差时选取的样本空间各不相同。批归一化(Batch Normalization)是对一个批次内同一个通道的特征图进行归一化;组归一化(Group Normalization)是对一个批次内相邻若干个通道的特征图进行归一化;层归一化是对某一个卷积层输出的属于单个样本的所有特征图进行归一化;实例归一化(Instance Segmentation)则是对卷积层输出的每一个通道进行独立的归一化,如输入图像的归一化就可以认为是对输入层的实例归一化。

图1-25所示为几种常用的归一化方法。假设一个批次有三个输入样本,每个样本输出五张特征图。同一个灰度值的特征图代表的是归一化的样本空间,也就是说同一灰度值的特征图会根据这个灰度的均值和标准差进行归一化。

1.批归一化

最常用的归一化方法是批归一化(Batch Normalization)。研究者发现,不但整个神经网络输入数据的均值和标准差是随机的,神经网络每一层的输入也都会产生随机的均值和标准差。 如果不对神经网络每一层的输出进行控制,在训练过程中,每一层输出的均值和标准差会各不相同,从而给后续网络层的学习带来了额外的负担,这就是所谓的内部协方差漂移 (Internal Covariate Shift)问题 [3]

为了解决这个问题,很自然的想法就是仿照输入归一化,对神经网络每一层的输入进行归一化处理。如图1-25a所示,和输入归一化的做法一样,批归一化按照通道(Channel)进行。使用随机梯度下降法训练时每一次迭代都只加载一个批次,所以只能对该批次的特征图进行归一化,故称“批归一化”。假设一个批次有三个样本,那么同一个通道就会输出三张特征图,这三张特征图就形成了归一化的样本空间,因此在图中被涂上了同一种颜色。

训练的时候存在批次,可以计算每一个批次的均值和标准差,但使用训练好的模型进行推断的时候却没有批次,只有一个单一的数据样本,那如何应用批归一化呢?为了在推断的时候也能使用具有统计意义的均值和标准差进行归一化,训练的时候每一层输入的均值和标准差都会被记录下来。在下一个批次的数据投入训练的时候,各层输入特征图的均值和标准差都会进行更新,使之能够反映整个数据集的统计特性。也就是说,每一层输入特征图的均值和标准差也是通过不断学习得到的,训练结束后这两个值也会被记录并固定下来,成为模型的一部分。之后对新的数据样本进行推断的时候,就直接使用之前学习到的均值和标准差对单个样本进行归一化。

2.层归一化

批归一化一经发表便成了深度神经网络的标准,训练的速度和健壮性都因此大大提高。但很快就出现了新的问题,在训练某些大模型的时候,因为GPU数目有限,一个批次只能容纳极少的样本,极端情况下一个批次甚至只有一个样本。但批归一化依赖于对同一批次中的多个样本进行统计,如果只有一个样本,统计也就失去了意义。研究者发现 一个批次中样本越少,训练的稳定性就越差,最终的精度也越低。 于是就发明了层归一化(Layer Normalization)。如图1-25b所示,层归一化即对同一个卷积层输出的所有特征图进行归一化,因此一个批次中有多少个样本也就不重要了 [4]

3.组归一化

组归一化(Group Normalization)则兼具两者之长。批归一化重视通道的独特性,每一个通道单独进行归一化,却需要大批次;层归一化不考虑批次,却对所有的通道一视同仁,没有考虑各个通道的独特性。组归一化同时解决了这两个问题,归一化的对象不针对整个批次,也不针对所有的通道,而是对通道分组之后进行组内归一化,因此被称为组归一化。如图1-25c所示,组归一化的对象是单个样本的相邻特征图,于是相邻特征图的数目就成了一个需要设置的参数,如图1-25c所示,就是两个通道一组。实际项目中一般会设置为16或者32,也就是16张特征图或者32张特征图一组。组归一化的目的是在不同通道的独特性和相关性之间取得平衡。

· 图1-25 几种常用的归一化

4.实例归一化

实例归一化(Instance Normalization)的计算方法如图1-25d所示,每一张特征图单独进行归一化就是实例归一化。实例归一化比较特殊,研究者不是为了提高训练的速度和健壮性才使用实例归一化的,而是发现在训练生成模型(Generative Model)时,实例归一化能产生质量更高的图片。生成模型在自动驾驶中一般用于迁移学习,这不是本书的重点,但读者们 在使用生成模型时,可以尝试使用实例归一化,可能能获得更高质量的结果 [5]

1.3.6 上采样层和下采样层

在1.3.3节提到可以使用步长为2的卷积来让特征图缩小,使用转置卷积来让特征图扩大,但工程师们在实践中发现,使用这两种方法对特征图进行缩放很容易产生如图1-20所示的棋盘格效应,这对输出结果的质量影响很大,因此上采样(Up Sample)和下采样(Down Sample)就变得越来越流行了。

上采样和下采样是图像处理的常用工具,日常生活中对相片进行缩小就是下采样,对相片进行放大就是上采样。上采样和下采样都是通过插值(Interpolation)完成的,有许多种插值算法,其中最常用的就是线性插值(Linear Interpolation)和最近邻居插值(Nearest Neighbor Interpolation)。所谓线性插值,可简单地理解为对原始图片的局部进行平均,而最近邻居插值则是在原始图片中寻找距离最接近的像素点。图1-26a所示为原始图片,图1-26b、c所示分别为使用线性插值法放大的图片和使用最近邻居插值法放大的图片。

· 图1-26 线性插值上采样和最近邻居插值上采样效果对比

两种插值方法的区别是很明显的。在轮廓线附近,线性插值法能得到更柔和的过渡,但显得模糊,这是因为线性插值法是对图片进行局部平均,产生了模糊化的效果;而最近邻居插值法得到的图片边缘呈锯齿状,但更加清晰。下采样是将原始图片缩小,使用这两种不同的采样算法也会有和上采样类似的效果。

在卷积神经网络的应用中,具体使用哪一种采样算法需要根据具体任务而定。 最近邻居插值法能获得更清晰的边缘线,缺陷是会有信息损失;线性插值法边缘模糊,但不会漏掉信息。

1.3.7 池化层

池化层(Pooling Layer)常被用于缩小特征图,作用和下采样类似。常用的池化层有三种,分别是最大池化(Max Pooling)、平均池化(Average Pooling)和全局平均池化(Global Average Pooling)。三种池化层的计算方法如图1-27所示。

· 图1-27 几种池化层的运算过程

最大池化层曾经是最流行的池化层,其计算方法是提取图像局部的最大值。最大池化具有平移不变性的特点,原图右上角值为1的像素点无论出现在四个像素的哪个位置,最大池化后都会得到1,这对于捕捉图像中的重要信息会很有用。平均池化和最大池化类似,区别是采用局部平均值而不是最大值。但越来越多的实践经验显示,通过最大池化来缩小特征图会造成信息损失,因为最大值以外的值可能也是很重要的信息,使用最大池化等于舍弃了这些信息。此外,最大池化还会破坏空间关系,如图1-27a中所示的1和2挨得很近,而3和4隔得很远,这种相对的空间关系可能是很重要的。因此,下采样层(平均地化层)用得越来越多,而不是池化层,当然读者需要在实践中根据最终的精度选择最适合的网络层。

全局平均池化层一般用于产生一维输出。1.3.2节谈到,卷积神经网络的特征图是二维的,需要一维输出的时候,可以把特征图压扁成一维向量,然后连接一个全连接层输出。这种计算方法的缺陷是特征图尺寸必须固定,例如,输入一张10×10的特征图,整平之后就形成一个长度为100的一维向量作为全连接层的输入。如果输入特征图的大小是12×12,整平后就变成了长度144的向量,输入为100的全连接层就不能用了,而全局平均池化层就能解决这个问题。所谓全局平均池化其实就是对整张特征图求平均值,无论特征图有多大,经过全局平均池化之后就只输出一个值,所以全局平均池化层输出的一维向量长度和特征图的数目是一样的,而特征图的数目是固定的,不随图片大小的变化而变化。具体的计算过程如图1-28所示。

· 图1-28 全局平均池化的运算过程

1.3.8 跳跃、空间注意力等特殊的连接方式

前文中介绍的各个网络层都是对输入特征图进行某种运算,然后输出特征图,通过这些网络层,已经可以构建一个最简单的卷积神经网络了。后来研究者发现,使用一些特殊的连接方式能大大提高输出结果的质量,因此这些连接方式也变得越来越重要起来。

1.跳跃式级联

跳跃式连接(Skipping Connection)用于连接低级特征(Low Level Feature)和高级特征(High Level Feature)。所谓的低级特征是指更接近输入图像本身的特征,如图像中的边缘线等。而高级特征是指更接近输出结果的特征,这些特征包含了更接近人类认知的高级语义信息,如摩托车轮子的特征。卷积神经网络的主要任务,就是对低级特征进行抽象得到高级特征,但在某些任务中,低级特征也非常重要。例如,对于语义分割而言,输出的语义分割图边缘线就越精确越好,而经过一层一层地抽象之后,图像的低级特征所剩无几。因此研究者想到,不如直接把低级特征图保留下来,直接叠加到高级特征图上,这样两种信息就都得到了保留,最后的输出结果不但分类准确,边缘线也更清晰。这种将两组相同尺寸的特征图叠加在一起的做法,称作级联(Concatenation)。如图1-29所示,靠近输入图像端,具有64个通道的低级特征直接通过跳跃连接叠加到了高级特征上,产生了一个128个通道的特征,这就是所谓的跳跃式级联。

· 图1-29 带有跳跃式级联的语义分割神经网络

2.跳跃式相加

跳跃式相加和跳跃式级联类似,作用也是把低级特征和高级特征融合起来,但不是采用叠加的方式,而是把两个特征相加。如图1-30所示,64个通道的低级特征和64个通道的高级特征直接相加,得到一个64个通道的融合特征,然后输入到下一个网络层。

· 图1-30 带有跳跃式相加的语义分割神经网络

使用相加而不是级联的方式,是为了防止融合之后的特征图通道数膨胀,既节约了计算量,又达到了融合的目的。代价是特征图能承载的信息变少了,影响最终的分类精确度。具体使用哪一种方式来融合高级和低级特征,需要模型设计者在平衡计算量和精确度之后来决定。

3 .空间注意力模块

空间注意力模块(Spatial Attention Module)简称为SAM,其原理和人类的认知习惯类似,为图像不同的区域赋予不同的权重。比较重要的部分权重高,次要的部分则权重低。计算方法如图1-31所示,具有128个通道的特征图通过一个卷积层之后被压缩成一个通道,然后连接一个Sigmoid激活函数就生成了一张注意力图。这张注意力图的值位于0~1之间,代表的是特征图中每一个像素的重要性。注意力图接下来会和特征图相乘,等于在引导神经网络把注意力放到更重要的像素上。图1-31中从Sigmoid激活函数输出的小图便是注意力图的可视化图像了,读者们会发现神经网络会把更多的注意力集中在摩托车和人上,这也非常符合人类的认知习惯。

· 图1-31 带有空间注意力模块的语义分割神经网络

空间注意力模块是作用于图像平面的,所以称之为“空间注意力”。也有通道注意力模块(Channel Attention Module),把注意力集中在输入特征不同的通道上,相当于给不同的通道赋予不同的权重,原理和实现方法与空间注意力模块类似,可参考提出空间注意力和通道注意力的论文CBAM: Convolutional Block Attention Module [6]

1.3.9 构建一个复杂的卷积神经网络

神经网络如同一个建筑,是由本节中提及的各种网络层搭建起来的。作为练习,读者可以想象一下如何搭建图1-32所示的BiSeNet V2语义分割神经网络 [7] 。BiSeNet V2使用了巧妙的双向注意力模块,让一个轻量级的语义分割神经网络也获得了很高的精度。

· 图1-32 BiSeNet V2语义分割神经网络

值得注意的是,BiSeNet V2中双向注意力模块输出的注意力图不止一个通道,而是和输入特征图的通道数相同,最终和输入特征图进行逐元素(Element-wise)相乘。因此,图1-32中使用到的注意力模块已经不是简单的空间注意力模块了,而是整个特征图的注意力模块。进行上、下采样时,特征图变化的倍数为四倍,而不是常用的两倍。可见在构建神经网络时,破除常规往往会收到意想不到的效果。 c6HxkyXLCBeyh5EIAiFTRrfBs8yU9n0mcmr6IhVP8B3Fq9TBg9rovXw+UTjMPKxU

点击中间区域
呼出菜单
上一章
目录
下一章
×