卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度学习(deep learning)的代表算法之一。本文旨在介绍CNN的基本概念和结构,以及CNN网络架构设计的基本思路。
一、卷积神经网络介绍
1. 什么是卷积神经网络?
卷积神经网络是多层感知机(MLP)的变种,由生物学家休博尔和维瑟尔在早期关于猫视觉皮层的研究发展而来,视觉皮层的细胞存在一个复杂的构造,这些细胞对视觉输入空间的子区域非常敏感,称之为感受野。
CNN由纽约大学的Yann Lecun于1998年提出(LeNet-5),其本质是一个多层感知机,成功的原因在于其所采用的局部连接和权值共享的方式:一方面减少了权值的数量使得网络易于优化;另一方面降低了模型的复杂度、减小了过拟合的风险。 当网络的输入为图像时,这些优点将表现地更加明显。
2006年,Hinton提出了深度学习,其主要的观点是:多隐层的人工神经网络具有优异的特征学习能力,学习到的数据更能反映数据的本质特征有利于可视化或分类。大数据和计算机硬件的发展使得深度学习得以推广和应用。
2012年AlexNet取得ImageNet比赛的分类任务的冠军,使得卷积神经网络真正爆发。如今的卷积神经网络(CNN)是一种带有卷积结构的深度神经网络,卷积结构可以减少深层网络占用的内存量,其三个关键的操作——局部感受野、权值共享、pooling层,有效地减少了网络的参数个数,缓解了模型的过拟合问题。
2. 卷积神经网络的特点
当使用全连接神经网络处理大尺寸图像时,有三个非常明显的缺点:(1)将图像展开为向量会丢失空间信息;(2)参数过多效率低下,训练困难;(3)大量的参数也很快会导致网络过拟合。卷积神经网络则可以很好地解决以上三个问题。
与常规神经网络不同,卷积神经网络的各层中的神经元是3维排列的:宽度、高度和深度。对于输入层来说,宽度和高度指的是输入图像的宽度和高度,深度代表输入图像的通道数,例如,对于RGB图像有R、G、B三个通道,深度为3;而对于灰度图像只有一个通道,深度为1。对于中间层来说,宽度和高度指的是特征图(feature map)的宽和高,通常由卷积运算和池化操作的相关参数决定;深度指的是特征图的通道数,通常由卷积核的个数决定。全连接神经网络中的主要运算为矩阵相乘,而卷积神经网络中主要为卷积计算,文章第三部分将对卷积运算及其变种进行介绍。
二、基本概念
0. 卷积(Convolution)
要理解后续内容,首先要大致了解什么是卷积运算(这里指最常用的标准卷积运算),以及多核卷积和深度卷积是什么?这些比较入门,且要介绍清楚需要大量的篇幅,这里不具体赘述,可以参考下面这篇文章:知乎:原来卷积是这么计算的 。这里仅从文章里引借两个动画来帮助大家直观地理解卷积运算的大致形式。
卷积运算演示动画:
在卷积神经网络中,对于输入的图像,需要多个不同的卷积核对其进行卷积,来提取这张图像不同的特征;同时也需要多个卷积层进行卷积,来提取深层次的特征。
1. 感受野(Receptive Field)
(1) 什么是感受野
感受野指的是卷积神经网络每一层输出的特征图(feature map)上每个像素点映射回输入图像上的区域大小。神经元感受野的范围越大表示其能接触到的原始图像范围就越大,也意味着它能学习更为全局,语义层次更高的特征信息;相反,范围越小则表示其所包含的特征越趋向局部和细节。因此感受野的范围可以用来大致判断每一层的抽象层次。并且我们可以很明显地知道网络越深,神经元的感受野越大。由此可知,深度卷积神经网络中靠前的层感受野较小,提取到的是图像的纹理、边缘等局部的、通用的特征;靠后的层由于感受野较大,提取到的是图像更深层次、更具象的特征。因此在迁移学习中常常会将靠前的层的参数冻结(不参与训练,因为他们在迁移到新的场景之前已经具备了提取通用特征的能力),来节省训练的时间和算力消耗。
(2) 如何计算CNN的感受野
首先回顾一下从输入特征图到输出特征图尺寸的计算公式(其中
n
i
n
n_{in}
nin为输入size,
p
p
p为padding大小,
f
f
f为卷积核size,
s
s
s为卷积步长):
假设输入大小为5×5,f=3×3,padding为1×1,卷积步长为2×2,那么输出特征图size根据公式可计算为3×3。
下面给出感受野的计算公式:
其中
R
F
l
+
1
RF_{l+1}
RFl+1为当前特征图对应的感受野大小,也就是我们要计算的目标感受野,
R
F
l
RF_l
RFl为上一层特征图对应的感受野大小,
f
l
+
1
f_{l+1}
fl+1为当前卷积层卷积核大小,最后一项连乘项则表示之前卷积层的步长乘积。
2. 权值共享
在卷积运算中采用权值共享可以有效减少需要求解的参数。权值共享是基于这样的一个合理的假设:如果一个特征在计算某个空间位置 (x1,y1)(x1,y1) 的时候有用,那么它在计算另一个不同位置 (x2,y2)(x2,y2) 的时候也有用。通俗地来讲,在一个卷积核在和一个n通道的特征图(为方便理解,这里可以暂时理解为3通道的RGB输入图像)进行卷积运算时,可以看作是用这个卷积核作为一个滑块去“扫”这个特征图,卷积核里面的数就叫权重,这个特征图每个位置是被同样的卷积核“扫”的,所以权重是一样的,也就是共享。同时,这个卷积核在去“扫”n通道特征图的时候,可以看作由一个二维的“片状结构”通过复制n次堆叠成为一个n通道的“块状结构”去“扫”这个n通道的特征图。
3. 分辨率(Resolution)
分辨率指的是输入模型的图像尺寸,即长宽大小。通常情况会根据模型下采样次数n和最后一次下采样后feature map的分辨率k×k来决定输入分辨率的大小,即:
从输入r×r到最后一个卷积特征feature map的k×k,整个过程是一个信息逐渐抽象化的过程,即网络学习到的信息逐渐由低级的几何信息转变为高级的语义信息,这个feature map的大小k×k可以是3×3,5×5,7×7,9×9等等,k太大会增加后续的计算量且信息抽象层次不够高,影响网络性能,k太小会造成非常严重的信息丢失,如原始分辨率映射到最后一层的feature map有效区域可能不到一个像素点,使得训练无法收敛。
在ImageNet分类任务中,通常设置5次下采样,并且考虑到其原始图像大多数在300分辨率左右,所以把最后一个卷积特征大小设定为7×7,将输入尺寸固定为224×224×3。在目标检测任务中,很多采用的是416×416×3的输入尺寸,当然由于很多目标检测模型是全卷积的结构,通常可以使用多尺寸训练的方式,即每次输入只需要保证是32×的图像尺寸大小就行,不固定具体数值。但这种多尺度训练的方式在图像分类当中是不通用的,因为分类模型最后一层是全连接结构,即矩阵乘法,需要固定输入数据的维度。
4. 网络深度(Depth)
神经网络的深度决定了网络的表达能力,它有两种计算方法,早期的backbone设计都是直接使用卷积层堆叠的方式,它的深度即神经网络的层数,后来的backbone设计采用了更高效的module(或block)堆叠的方式,每个module是由多个卷积层组成,它的深度也可以指module的个数,这种说法在神经架构搜索(NAS)中出现的更为频繁。通常而言网络越深表达能力越强,但深度大于某个值可能会带来相反的效果,所以它的具体设定需要不断调参得到。
5. 网络宽度(Width)
宽度决定了网络在某一层学到的信息量,但网络的宽度指的是卷积神经网络中最大的通道数,由卷积核数量最多的层决定。通常的结构设计中卷积核的数量随着层数越来越多的,直到最后一层feature map数量达到最大,这是因为越到深层,feature map的分辨率越小,所包含的信息越高级,所以需要更多的卷积核来进行学习。通道越多效果越好,但带来的计算量也会大大增加,所以具体设定也是一个调参的过程。通常各层通道数会按照8×的倍数来确定,这样有利于GPU的并行计算。
6. 下采样(Down-Sample)
下采样层有两个作用,一是减少计算量,防止过拟合,二是增大感受野,使得后面的卷积核能够学到更加全局的信息。下采样的设计有两种:
(1) 采用步长(stride)为2的池化层,如Max-pooling或Average-pooling,目前通常使用Max-pooling,因为它计算简单且最大响应能更好保留纹理特征;
(2) 采用步长(stride)为2的卷积层,下采样的过程是一个信息损失的过程,而池化层是不可学习的,用stride为2的可学习卷积层来代替pooling可以得到更好的效果,当然同时也增加了一定的计算量。
7. 上采样(Up-Sampling)
在卷积神经网络中,由于输入图像通过卷积神经网络(CNN)提取特征后,输出的尺寸往往会变小,而有时我们需要将图像恢复到原来的尺寸以便进行进一步的计算(如图像的语义分割),这个使图像由小分辨率映射到大分辨率的操作,叫做上采样,它的实现一般有三种方式:
- 插值,一般使用的是双线性插值,因为效果最好,虽然计算上比其他插值方式复杂,但是相对于卷积计算可以说不值一提;
- 转置卷积又或是说反卷积,通过对输入feature map间隔填充0,再进行标准的卷积计算,可以使得输出feature map的尺寸比输入更大;
- Max Unpooling,在对称的max pooling位置记录最大值的索引位置,然后在unpooling阶段时将对应的值放置到原先最大值位置,其余位置补0。
8. 参数量(Params)
参数量指的网络中可学习变量的数量,包括卷积核的权重weight,批归一化(BN)的缩放系数γ,偏移系数β,有些没有BN的层可能有偏置bias,这些都是可学习的参数,即在模型训练开始前被赋予初值,在训练过程根据链式法则中不断迭代更新。整个模型的参数量主要由卷积核的权重weight的数量决定,参数量越大,则该结构对运行平台的内存要求越高,参数量的大小是轻量化网络设计的一个重要评价指标。
9. 计算量(FLOPs)
神经网络的前向推理过程基本上都是乘累加计算,所以它的计算量也是指的前向推理过程中乘加运算的次数,通常用FLOPs(即“每秒浮点运算次数”)来表示,即floating point operations(浮点运算数)。计算量越大,在同一平台上模型运行延时越长,尤其是在移动端/嵌入式这种资源受限的平台上想要达到实时性的要求就必须要求模型的计算量尽可能地低,但这个不是严格成正比关系,也跟具体算子的计算密集程度(即计算时间与IO时间占比)和该算子底层优化的程度有关。
三、卷积结构类型
卷积结构是CNN的重要组成单元,随着卷积神经网络的发展,在标准卷积结构的基础上衍生出许多其它的卷积结构类型,该部分将分别对他们进行介绍。
1. 标准卷积 (Convolution)
在神经网络架构设计中,标准卷积是最常见的结构,在文章第二部分的一开始已经做了简要介绍并提供了参考文献。假设其输入feature map的维度是(1, iC, iH, iW),每个卷积核的维度是(1, iC, k, k),一次卷积滤波得到一层feature map的维度为(1,1, oH, oW),一共有oC个卷积核,则输出feature map的维度是(1, oC, oH, oW),计算量为iC×k×k×oC×oH×oW,计算过程如下图所示。
上图中输入feature map的(iC, iH, iW)为(3, 6, 6),卷积核的维度(iC, k, k)为(3, 3, 3),卷积核的数量oC为2。
2. 深度卷积 (Depthwise Convolution)
深度卷积与标准卷积相比,顾名思义是在深度上做了文章,而这里的深度跟网络的深度无关,它指的通道。标准卷积中每个卷积核都需要与feature map的所有通道进行计算,所以每个卷积核的通道数等于输入feature map的通道数,同时通过设定卷积核的数量可以控制输出feature map的通道数。而深度卷积每个卷积核都是单通道的,维度为(1,1,k,k) ,卷积核的个数为iC(须和feature map的通道数保持一致),即第i个卷积核与feature map第i个通道进行二维的卷积计算,最后输出维度为(1,iC,oH,oW),它不能改变输出feature map的通道数,所以通常会在深度卷积后面接上一个(oC,iC,1,1)的标准卷积来代替3×3或更大尺寸的标准卷积。总的计算量为k×k×iC×oH×oW+iC×1×1×oH×oW×oC,是普通卷积的1/oC+1/(k×k),大大减少了计算量和参数量,又可以达到相同的效果,这种结构被称为深度可分离卷积(Depthwise Separable Convolution),在MobileNet V1被提出,后来渐渐成为轻量化结构设计的标配。
3. 分组卷积 (Group Convolution)
分组卷积最早在AlexNet中出现,当时作者在训练模型时为了减少显存占用而将feature map分组然后给多个GPU进行处理,最后把多个输出进行融合。具体计算过程是,分组卷积首先将输入feature map分成g个组,每个组的大小为(1, iC/g, iH, iW),对应每组中一个卷积核的大小是(1,iC/g,k,k),每组有oC/g个卷积核,所以每组输出feature map的尺寸为(1,oC/g,oH,oW),最终g组输出拼接得到一个(1,oC,oH,oW)的大feature map,总的计算量为iC/g×k×k×oC×oH×oW,是标准卷积的1/g,参数量也是标准卷积的1/g。
但由于feature map组与组之间相互独立,存在信息的阻隔,所以ShuffleNet提出对输出的feature map做一次channel shuffle的操作,即通道混洗,打乱原先的顺序,使得各个组之间的信息能够交互起来。
4. 空洞卷积 (Dilated Convolution)
空洞卷积也叫扩张卷积或者膨胀卷积,是针对图像语义分割问题中下采样会降低图像分辨率、丢失信息而提出的一种卷积思路。空洞卷积有两种理解,一是可以理解为将卷积核扩展,如图下图卷积核为3×3,但是这里将卷积核变为5×5,即在卷积核每行每列中间加0;二是理解为在特征图上每隔1行或一列取数与3×3卷积核进行卷积。通过间隔取值扩大感受野,让原本3x3的卷积核,在相同参数量和计算量下拥有更大的感受野。
这里面有个扩张率(dilation rate)的系数,这个系数定义了这个间隔的大小,标准卷积相当于dilation rate为1的空洞卷积。dilation rate为1、2、4的时候卷积核感受野如下图所示:
5. 转置卷积 (Transposed Convolutions)
转置卷积又称反卷积(Deconvolution),它和空洞卷积的思路正好相反,是为上采样而生,也应用于语义分割当中,而且他的计算也和空洞卷积正好相反,先对输入的feature map间隔补0,卷积核不变,然后使用标准的卷积进行计算,得到更大尺寸的feature map。
6. 可变形卷积 (Deformable Convolution)
以上的卷积计算都是固定的,每次输入不同的图像数据,卷积计算的位置都是完全固定不变,即使是空洞卷积/转置卷积,0填充的位置也都是事先确定的。而可变形卷积是指卷积核上对每一个元素额外增加了一个h和w方向上偏移的参数,然后根据这个偏移在feature map上动态取点来进行卷积计算,这样卷积核就能在训练过程中扩展到很大的范围。而显而易见的是可变性卷积虽然比其他卷积方式更加灵活,可以根据每张输入图片感知不同位置的信息,类似于注意力,从而达到更好的效果。
在上面这张图里面,左边传统的卷积显然没有提取到完整绵羊的特征,而右边的可变形卷积则提取到了完整的不规则绵羊的特征。
7. 1×1卷积(Pointwise Convolution)
有些论文里用到了尺寸为1×1的卷积核,人们刚开始见到1×1卷积可能会比较困惑——对于二维的图像数据,1×1卷积似乎是没有意义的。但是在卷积神经网络中,卷积核通常是对三维feature map进行操作,这时,1×1卷积可以看作对某个局部的加权求和。1×1卷积最早出现在Network In Network的论文中 ,使用1×1卷积是想加深加宽网络结构。
1*1卷积通常有两方面作用:
- 降维:比如一张500×500且通道数为100的图片在20个filter上做1×1的卷积,输出特征图的尺寸变为500×500×20。当filter数量为200时,输出特征图的尺寸会变为500×500×200,这时实现了网络加宽,或者说是升维。
- 增加网络层的非线性:它的卷积过程其实相当于全连接层的计算过程,并且还加入了非线性的激活函数(relu等),从而使网络结构变得更加的复杂。
四、其他组成结构
1. 池化(pooling)层
(1) 最大池化(Max Pooling)和平均池化(Mean Pooling)
通常在连续的卷积层之间会周期性地插入一个池化层(也称“汇聚”层)。它的作用是逐渐降低数据体的空间尺寸,这样的话就能减少网络中参数的数量,使得计算资源耗费变少,也能有效控制过拟合。池化这个操作比较简单,一般在上采样和下采样的时候用到,没有参数,不可学习。
普通池化操作常见的有最大池化(Max Pooling)和平均池化(Mean Pooling)。 其中,最常用的是最大池化,最常见的形式是使用尺寸2x2的滤波器,以步长为2来对每个深度切片进行降采样,将其中75%的激活信息都丢掉。对更大感受野进行池化需要的池化尺寸也更大,而且往往对网络有破坏性。平均池化历史上比较常用,但是现在已经很少使用了。因为实践证明,最大池化的效果比平均池化要好。尺寸为2×2、步长为2的最大池化核平均池化的示例如下图所示:
- 关于池化层的反向传播: 对于最大池化来说,max(x,y)函数的反向传播可以简单理解为将梯度只沿最大的数回传。因此,在向前传播经过汇聚层的时候,通常会把池中最大元素的索引记录下来(有时这个也叫作道岔(switches)),这样在反向传播的时候梯度的路由就很高效。
- 关于弃用池化层: 很多人不喜欢汇聚操作,认为可以弃用它。比如在Striving for Simplicity: The All Convolutional Net一文中,提出使用一种只有重复的卷积层组成的结构,抛弃汇聚层。通过在卷积层中使用更大的步长来降低数据体的尺寸。有发现认为,在训练一个良好的生成模型时,弃用汇聚层也是很重要的。比如变化自编码器(VAEs:variational autoencoders)和生成性对抗网络(GANs:generative adversarial networks)。现在看起来,未来的卷积网络结构中,可能会很少使用甚至不使用汇聚层。
(2) 全局平均池化(Global Average Pooling)
全局平均池化的操作是对一个维度为(C,H,W)的feature map,在H和W方向整个取平均,然后输出一个长度为C的向量,这个操作一般在分类模型的最后一个feature map之后出现,然后接一个全连接层就可以完成分类结果的输出了。早期的分类模型都是把最后一个feature map直接拉平成C×H×W的向量,然后再接全连接层,可以明显看出这样计算量极大,甚至有的模型最后一个全连接层占了整个模型计算量的50%以上,之后由研究人员发现对这个feature map做一个全局平均池化,然后再加全连接层可以达到相似的效果,且计算量降低到了原来的1/HW。
2. 全连接(Full Connected)层
全连接层和常规神经网络中一样,它的本质其实就是矩阵乘法再加上偏差,输入一个(B, iC)的数据,权重为(iC, oC),那么输出为(B, oC),在多层感知机和分类模型最后一层常常见到。
3. Addition / Concatenate分支
Addition和Concatenate分支操作统称为shortcut,如下图所示,操作极为简单。Addition是在ResNet中提出,两个相同维度的feature map相同位置点的值直接相加,得到新的相同维度feature map,这个操作可以融合之前的特征,增加信息的表达,Concatenate操作是在Inception中首次使用,被DenseNet发扬光大,和addition不同的是,它只要求两个feature map的HW相同,通道数可以不同,然后两个feature map在通道上直接拼接,得到一个更大的feature map,它保留了一些原始的特征,增加了特征的数量,使得有效的信息流继续向后传递。
4. Channel shuffle
channel shuffle是ShuffleNet中首次提出,主要是针对分组卷积中不同组之间信息不流通,对不同组的feature map进行混洗的一个操作,如下图所示,假设原始的feature map维度为(1,9,H,W),被分成了3个组,每个组有三个通道,那么首先将这个feature map进行reshape操作,得到(1,3,3,H,W),然后对中间的两个大小为3的维度进行转置,依然是(1,3,3,H,W),最后将通道拉平,变回(1,9,H,W),就完成了通道混洗,使得不同组的feature map间隔保存,增强了信息的交互。
5. 常用激活函数
激活函数的非线性是神经网络发挥作用最重要的因素之一,而对于实际部署,激活函数的实现也是很重要的一个方面,实现的不好对加速效果影响很大,这里主要讲几个部署当中常见的激活函数。
(1) ReLU系列
这里主要指常用的ReLU,ReLU6和leaky ReLU。ReLU比较好部署,小于0的部分为0,大于0的部分为原始值,只需要判断一下符号位就行;ReLU6与ReLU相比也只是在正向部分多了个阈值,大于6的值等于6,在实现时多了个比较也不算麻烦;而leaky ReLU和ReLU正向部分一样,都是大于0等于原始值,但负向部分却是等于原始值的1/10,浮点运算的话乘个0.1就好了,如果因为量化要实现整数运算,这块可以做个近似,如0.1用13>>7来代替,具体实现方法多种多样 ,还算简单。
(2) Sigmoid系列
sigmoid函数也叫Logistic函数,其公式如下:
sigmoid函数的有点是平滑、易于求导,缺点是激活函数计算量大,反向传播求误差梯度时,求导涉及除法,反向传播时,很容易就会出现梯度消失的情况,从而无法完成深层网络的训练。
为了解决sigmoid计算量大对低性能硬件不友好的问题,有研究人员针对此专门设计了近似的硬件友好的函数h-sigmoid和h-swish函数,这里的h指的就是hardware的意思。
6. Dropout
Dropout是指在深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃。注意是暂时,对于随机梯度下降来说,由于是随机丢弃,故而每一个mini-batch都在训练不同的网络。当进行测试和推理时,Dropout将不起作用。
Dropout是CNN中防止过拟合提高效果的一个重要方法。Dropout为什么有效?Dropout背后理念和集成模型很相似。在Dropout层,不同的神经元组合被关闭,这代表了一种不同的结构,所有这些不同的结构使用一个的子数据集并行地带权重训练,而权重总和为1。如果Dropout层有
n
n
n个神经元,那么会形成
2
n
2^n
2n个不同的子结构。在预测时,相当于集成这些模型并取均值。这种结构化的模型正则化技术有利于避免过拟合。Dropout有效的另外一个视点是:由于神经元是随机选择的,所以可以减少神经元之间的相互依赖,从而确保提取出相互独立的重要特征。
这里顺便例举一下深度学习中抑制过拟合的方法有哪些:
- 加入正则化项——L1和L2正则化(不了解的可以参考文章: L1正则化和L2正则化 )
- 提前终止(early stopping)训练(当验证集上的效果变差的时候)
- 参数绑定与参数共享(如CNN和RNN中都有用到参数共享)
- Dropout
- Batch Normalization
- bagging等集成方法
7. Batch Normalization
- (1)问题引出 在引入BN之前,以前的model training有一些系统性的问题,导致很多算法收敛速度都非常慢,甚至根本就不能工作,尤其在使用sigmoid激活函数时。在机器学习中我们通常会对输入特征进行标准化或归一化,因为直接输入的数据每个维度量纲可能不同、数值差别很大,导致模型不能很好地从各个特征中学习。神经网络是一个多层结构,每层神经元是会受到它之前所有神经元影响的,因为每一层的输出都是下一层的输入,所以一个神经元输出的数据分布发生改变一定会使其他神经元跟着改变,这样相互影响的调参很容易使调参过程乱套,这个被称作Internal Covariate shift(ICS)。此外,当上一层输出值太大或太小,其经过sigmoid激活函数时会落在饱和区域,反向传播会有梯度消失的问题。
- (2)BN层功效BN层通常添加在每个神经网络层和激活层之间,对神经网络层输出的数据分布进行统一和调整,变成均值为0方差为1的标准正态分布,使输出位于激活层的非饱和区,达到加快收敛的效果。BN层的效果演示如下图:
- (3)BN算法 BN算法的公式如下图:
前三个公式表述的标准化工序并不难理解,但最后还有一个反标准化工序,即对标准化后的数据再扩展和平移,其中涉及到扩展参数γ和平移参数β,这两个参数是可学习的,能够让模型在训练过程中自己去修改,这样神经网咯就能够自己琢磨出前面的标准化工序有没有起到优化的作用,如果没有,就可以通过调整γ和β参数来在一定程度上抵消标准化操作。
- (4)BN和LN 除了Batch Normalization外,常见的深度学习标准化方法还有Layer Normalization(LN)等。BN和LN的主要区别在于Normalize的方向不同,大致可以参考下面这张图:
这里不对LN做详细介绍,因为LN用于RNN效果比较明显,但是在CNN上最常用的还是BN。
五、经典CNN网络简介
经典的CNN网络有LeNet-5、AlexNet、VGG、GoogleNet、ResNet、DenseNet等。这些经典CNN网络结构中总是包含一些对于神经网络架构设计有巨大启发性的东西。该部分仅对这些网络做简单的介绍,同时给出其论文原文和一些博客文章的链接,供感兴趣的同学深入学习这些网络。
1. LeNet
论文地址:LeNet-5, convolutional neural networks
LeNet-5是第一个成功的卷积神经网络应用,是Yann LeCun在上世纪90年代实现的。它由两个卷积层组成和三个全连接层组成,组合使用卷积层、非线性激活函数和汇聚层。
2. AlexNet
论文地址:ImageNet Classification with Deep Convolutional Neural Networks
因为虽然LeNet在小数据集上取得了很好的效果,但是在更大、更真实的数据集上训练卷积神经网络的性能和可行性还有待进一步提升。AlexNet是第一个在大规模视觉竞赛中击败传统计算机视觉模型的大型神经网络,它使得卷积神经网络在计算机视觉领域中备受欢迎。
结构特点:
- 这个网络的结构和LeNet非常类似,但是更深更大,并且使用了层叠的卷积层来获取特征(之前通常是只用一个卷积层并且在其后马上跟着一个汇聚层);
- AlexNet由八层组成——五个卷积层、两个全连接隐藏层和一个全连接输出层;
- AlexNet使用ReLU而不是sigmoid作为其激活函数;
- 此外,AlexNet在全连接层处使用了Dropout来抑制过拟合。
3. VGG
论文地址:Very Deep Convolutional Networks for Large-Scale Image Recognition
虽然 AlexNet 证明深层神经网络卓有成效,但它没有提供一个通用的模板来指导后续的研究人员设计新的网络。 在下面的网络中,将介绍一些常用于设计深层神经网络的启发式概念。使用块的想法首先出现在牛津大学的视觉几何组(visualgeometry Group)(VGG)的VGG网络中。通过使用循环和子程序,可以很容易地在任何现代深度学习框架的代码中实现这些重复的结构。
结构特点:
- VGG16相比AlexNet的一个改进是采用连续的几个3x3的卷积核代替AlexNet中的较大卷积核(11x11,5x5)。对于给定的感受野(与输出有关的输入图片的局部大小),采用堆积的小卷积核是优于采用大的卷积核,因为多层非线性层可以增加网络深度来保证学习更复杂的模式,而且代价还比较小(参数更少),即深层且窄的卷积(即3×3)比较浅层且宽的卷积更有效。
- VGG使用可复用的卷积块构造网络。不同的VGG模型可通过每个块中卷积层数量和输出通道数量的差异来定义。块的使用导致网络定义的非常简洁。使用块可以有效地设计复杂的网络。
4. NiN(Network in Network)
论文地址:Network in Network
NiN指的是论文《Network in Network》提出的网络结构。先前的LeNet、AlexNet 和 VGG 都有一个共同的设计模式:通过一系列的卷积层与汇聚层来提取空间结构特征;然后通过全连接层对特征的表征进行处理。 AlexNet 和 VGG 对 LeNet 的改进主要在于如何扩大和加深这两个模块。NiN 提供了一个非常简单的解决方案:在每个像素的通道上分别使用多层感知机。
Network in Network这篇文章的重要之处在于它提出了1×1卷积和**全局平均池化(GAP)**,对后续卷积神经网络的设计产生重大影响。
结构特点:
- NiN使用由一个卷积层和多个1×1卷积层组成的块。该块可以在卷积神经网络中使用,以允许更多的每像素非线性;
- NiN去除了容易造成过拟合的全连接层,将它们替换为全局平均池化层(即在所有位置上进行求和)。移除全连接层可减少过拟合,同时显著减少NiN的参数。
5. GoogleNet
论文地址:Going deeper with convolutions
在2014年的ImageNet图像识别挑战赛中,一个名叫GoogLeNet的网络结构大放异彩。GoogLeNet吸收了NiN中串联网络的思想,并在此基础上做了改进。 这篇论文的一个重点是解决了什么样大小的卷积核最合适的问题。毕竟,以前流行的网络使用小到1×1,大到11×11的卷积核。本文的一个观点是,有时使用不同大小的卷积核组合是有利的。
GoogleNet设计了一种称为 Inception 的基本卷积模块,作为GoogleNet的基本卷积模块。Inception块由四条并行路径组成。前三条路径使用窗口大小为 1X1、3X3 和5X5 的卷积层,从不同空间大小中提取信息。中间的两条路径在输入上执行 1X1卷积,先减少通道数,从而降低模型的复杂性。然后使用3X3(5×5)卷积增加通道数。这四条路径都使用合适的填充来使输入与输出的高和宽一致,最后将每条线路的输出在通道维度上连结,并构成Inception块的输出。在Inception块中,通常调整的超参数是每层输出通道的数量。每条路径的通道数不尽相同。
GoogLeNet 一共使用 9 个Inception块和全局平均汇聚层的堆叠来生成其估计值。Inception块之间的最大汇聚层可降低图片大小维度。 第一个模块类似于 AlexNet 和 LeNet,Inception块的栈从VGG继承,全局平均汇聚层避免了在最后使用全连接层。
结构特点:
- Inception 块相当于一个有4条路径的子网络。它通过不同窗口形状的卷积层和最大汇聚层来并行抽取信息,并使用 1×1卷积层减少每像素级别上的通道维数从而降低模型复杂度。
- GoogleNet在最后使用了全局池化层,来代替全连接层(最后的全连接输出层仍保留),减少模型的参数量,抑制过拟合。
- GoogLeNet将多个设计精细的Inception块与其他层(卷积层、全连接层)串联起来。其中Inception块的通道数分配之比是在 ImageNet 数据集上通过大量的实验得来的。
- GoogLeNet 和它的后继者们一度是 ImageNet 上最有效的模型之一:它以较低的计算复杂度提供了类似的测试精度。
6. ResNet
论文地址:Deep Residual Learning for Image Recognition
从前面可以看到,随着网络深度增加,网络的准确度应该同步增加,但网络深度的进一步增加存在很多问题:一个是随着层数的增加出现的梯度消失问题,因为梯度是从后向前传播的,增加网络深度后,比较靠前的层梯度会很小,导致着这些层的学习基本停滞;二是网络更深时意味着参数空间更大,优化问题变得更难,因此简单地去增加网络深度反而出现更高的训练误差。残差网络ResNet设计一种残差模块让我们可以训练更深的网络。
何恺明等人提出的残差网络(ResNet)在2015年的ImageNet图像识别挑战赛夺魁,并深刻影响了后来的深度神经网络的设计。 残差网络的核心思想是:每个附加层都应该更容易地包含原始函数作为其元素之一。在残差块中,输入可通过跨层数据线路更快地向前传播。
ResNet 沿用了 VGG 完整的3×3卷积层设计。 残差块里首先有 2 个有相同输出通道数的3×3卷积层。 每个卷积层后接一个批量归一化层和 ReLU 激活函数。 然后我们通过跨层数据通路,跳过这 2 个卷积运算,将输入直接加在最后的 ReLU 激活函数前。 这样的设计要求 2 个卷积层的输出与输入形状一样,从而可以相加。 如果想改变通道数,就需要引入一个额外的1×1卷积层来将输入变换成需要的形状后再做相加运算。
ResNet 的前两层跟之前介绍的 GoogLeNet 中的一样: 在输出通道数为 64、步幅为 2 的7×7卷积层后,接步幅为 2 的3×3的最大汇聚层。不同之处在于 ResNet 每个卷积层后增加了批量归一化层。
ResNet 接着使用 4 个由残差块组成的模块,每个模块使用若干个同样输出通道数的残差块。 第一个模块的通道数同输入通道数一致。由于之前已经使用了步幅为 2 的最大汇聚层,所以无须减小高和宽。 之后的每个模块在第一个残差块里将上一个模块的通道数翻倍,并将高和宽减半。
最后,ResNet 加入全局平均汇聚层,以及全连接层输出。每个模块有 4 个卷积层(不包括恒等映射的1×1卷积层)。加上第一个7×7卷积层和最后一个全连接层,共有 18 层。
结构特点:
- 利用残差块(residual blocks)可以训练出一个有效的深层神经网络:输入可以通过层间的残余连接更快地向前传播。
- ResNet在每个卷积层和ReLU激活层之间添加了Batch Normalization层,缓解梯度消失问题,加快模型收敛。
- 学习嵌套函数(nested function)是训练神经网络的理想情况。在深层神经网络中,学习另一层作为恒等映射(identity function)较容易(尽管这是一个极端情况)。
- 残差映射可以更容易地学习同一函数,例如将权重层中的参数近似为零。
7. DenseNet
论文地址:Densely Connected Convolutional Networks
稠密连接网络(DenseNet)在某种程度上是 ResNet 的逻辑扩展。ResNet 和 DenseNet 的关键区别在于,DenseNet 输出是连接(用图中的[,]表示)而不是如 ResNet 的简单相加。
DenseNet 这个名字由变量之间的“稠密连接”而得来,最后一层与之前的所有层紧密相连,稠密网络主要由 2 部分构成:稠密块(dense block)和过渡层(transition layer)。 前者定义如何连接输入和输出,而后者则控制通道数量,使其不会太复杂。
结构特点:
- 在跨层连接上,不同于 ResNet 中将输入与输出相加,稠密连接网络(DenseNet)在通道维上连结输入与输出。
- DenseNet 的主要构建模块是稠密块和过渡层。
- 在构建 DenseNet 时,我们需要通过添加过渡层来控制网络的维数,从而再次减少信道的数量。
8. 经典CNN总结
- AlexNet,它是第一个在大规模视觉竞赛中击败传统计算机视觉模型的大型神经网络;
- 使用重复块的网络(VGG)。它利用许多重复的神经网络块和小卷积核的有效性;
- 网络中的网络(NiN)。它重复使用由卷积层和1×1卷积层来构建深层网络;同时使用全局平均池化层替代全连接层;
- 含并行连结的网络(GoogLeNet)。它使用并行连结的网络,通过不同窗口大小的卷积层和最大汇聚层来并行抽取信息;
- 残差网络(ResNet)。它通过残差块构建跨层的数据通道,是计算机视觉中最流行的体系结构;
- 稠密连接网络(DenseNet)。它的计算成本很高,但给我们带来了更好的效果。
六、CNN网络架构设计思路
卷积神经网络架构设计,又指backbone设计,主要是根据具体任务的数据集特点以及相关的评价指标来确定一个网络结构的输入图像分辨率,深度,每一层宽度,拓扑结构等细节。
公开发表的论文大多都是基于ImageNet这种大型的公开数据集来进行的通用结构设计,早期只以其分类精度来证明设计的优劣,后来也慢慢开始对比参数量(Params)和计算量(FLOPs),由于ImageNet的数据量十分巨大且丰富,所以通常在该数据集上获得很好精度的网络结构泛化到其他任务性能也都不会差。
但在很多特定任务中,这种通用的结构虽然效果还可以,却并不算最好,所以一般在实际应用时通常是基于已公开发表的优秀网络结构再根据任务特点进行适当修改得到自己需要的模型结构。
下面介绍一些卷积神经网络结构的设计经验和规律:
1. 层的排列规律
卷积神经网络最常见的形式就是将一些卷积层和ReLU层放在一起,其后紧跟汇聚层,然后重复如此直到图像在空间上被缩小到一个足够小的尺寸,在某个地方过渡成成全连接层也较为常见。最后的全连接层得到输出,比如分类评分等。换句话说,最常见的卷积神经网络结构如下:
其中*指的是重复次数,POOL?指的是一个可选的汇聚层。其中N >=0,通常N<=3,M>=0,K>=0,通常K<3。例如,下面是一些常见的网络结构规律:
- INPUT -> FC ,实现一个线性分类器,此处N = M = K = 0。
- INPUT -> CONV -> RELU -> FC,单层的卷积神经网络
- INPUT -> [CONV -> RELU -> POOL]×2 -> FC -> RELU -> FC,此处在每个汇聚层之间有一个卷积层,这种网络就是简单的多层的卷积神经网络。
- INPUT -> [CONV -> RELU -> CONV -> RELU -> POOL]×3 -> [FC -> RELU]×2 -> FC,此处每个汇聚层前有两个卷积层,这个思路适用于更大更深的网络(比如说这个思路就和VGG比较像),因为在执行具有破坏性的汇聚操作前,多重的卷积层可以从输入数据中学习到更多的复杂特征。
进一步的优化:当前比较流行的CNN模型很多都是在这些结构规律上做进一步的改进和优化。有的是做一些层级的修改,比如在CONV层和RELU层之间添加BN层,或是将全连接层替换成全局平均池化层,再或是使用1*1卷积、Depthwise卷积等比较特殊的卷积层,等等。有的是设计新的模型基本模块,比如Inception模块、残差模块等。这些修改通常不是盲目的,而是面向任务需求或已经发现的问题进行针对性的修改。其中很多改进的想法、思路是来源于别的优秀论文。
2. 卷积层的大小选择
几个小滤波器卷积层的组合比一个大滤波器卷积层好。假设你一层一层地重叠了3个3x3的卷积层(层与层之间有非线性激活函数)。在这个排列下,第一个卷积层中的每个神经元都对输入数据体有一个3x3的视野。第二个卷积层上的神经元对第一个卷积层有一个3x3的视野,也就是对输入数据体有5x5的视野。同样,在第三个卷积层上的神经元对第二个卷积层有3x3的视野,也就是对输入数据体有7x7的视野。假设不采用这3个3x3的卷积层,二是使用一个单独的有7x7的感受野的卷积层,那么所有神经元的感受野也是7x7,但是就有一些缺点。首先,多个卷积层与非线性的激活层交替的结构,比单一卷积层的结构更能提取出深层的更好的特征。其次,假设所有的数据有C个通道,那么单独的7x7卷积层将会包含 个参数,而3个3x3的卷积层的组合仅有 个参数。直观说来,最好选择带有小滤波器的卷积层组合,而不是用一个带有大的滤波器的卷积层。前者可以表达出输入数据中更多个强力特征,使用的参数也更少。唯一的不足是,在进行反向传播时,中间的卷积层可能会导致占用更多的内存。
3. 层的尺寸设置规律
- 输入层 ,应该能被2整除很多次。常用数字包括32(比如CIFAR-10),64,96(比如STL-10)或224(比如ImageNet卷积神经网络),384和512。
- 卷积层 ,应该使用小尺寸滤波器(比如3x3或最多5x5),使用步长S=1。还有一点非常重要,就是对输入数据进行零填充,这样卷积层就不会改变输入数据在空间维度上的尺寸。比如,当F=3,那就使用P=1来保持输入尺寸。当F=5,P=2,一般对于任意F,当P=(F-1)/2的时候能保持输入尺寸。如果必须使用更大的滤波器尺寸(比如7x7之类),通常只用在第一个面对原始图像的卷积层上。
- 汇聚层 ,负责对输入数据的空间维度进行降采样。最常用的设置是用用2x2感受野(即F=2)的最大值汇聚,步长为2(S=2)。注意这一操作将会把输入数据中75%的激活数据丢弃(因为对宽度和高度都进行了2的降采样)。另一个不那么常用的设置是使用3x3的感受野,步长为2。最大值汇聚的感受野尺寸很少有超过3的,因为汇聚操作过于激烈,易造成数据信息丢失,这通常会导致算法性能变差。
上文中展示的两种设置(卷积层F=3,P=1,汇聚层F=2,P=2)是很好的,因为所有的卷积层都能保持其输入数据的空间尺寸,汇聚层只负责对数据体从空间维度进行降采样。如果使用的步长大于1并且不对卷积层的输入数据使用零填充,那么就必须非常仔细地监督输入数据体通过整个卷积神经网络结构的过程,确认所有的步长和滤波器都尺寸互相吻合,卷积神经网络的结构美妙对称地联系在一起。
为何使用零填充?使用零填充除了前面提到的可以让卷积层的输出数据保持和输入数据在空间维度的不变,还可以提高算法性能。如果卷积层值进行卷积而不进行零填充,那么数据体的尺寸就会略微减小,那么图像边缘的信息就会过快地损失掉。
因为内存限制所做的妥协:在某些案例(尤其是早期的卷积神经网络结构)中,基于前面的各种规则,内存的使用量迅速飙升。例如,使用64个尺寸为3x3的滤波器对224x224x3的图像进行卷积,零填充为1,得到的激活数据体尺寸是[224x224x64]。这个数量就是一千万的激活数据,或者就是72MB的内存(每张图就是这么多,激活函数和梯度都是)。因为GPU通常因为内存导致性能瓶颈,所以做出一些妥协是必须的。在实践中,人们倾向于在网络的第一个卷积层做出妥协。例如,可以妥协可能是在第一个卷积层使用步长为2,尺寸为7x7的滤波器。在AlexNet中,滤波器的尺寸的11x11,步长为4。
Reference
- 综述:轻量级 CNN 架构设计
- 卷积神经网络超详细介绍
- 卷积神经网络(CNN)详解
- 经典卷积神经网络总结
- ResNet, AlexNet, VGG, Inception: 理解各种各样的CNN架构
版权归原作者 本初-ben 所有, 如有侵权,请联系我们删除。