见另一篇文章,这里不一一阐述:
https://blog.csdn.net/weixin_39589455/article/details/114949533
LeNet5 这个网络虽然很小,但是它包含了深度学习的基本模块:卷积层,池化层,全链接层。是其他深度学习模型的基础, 这里我们对LeNet5进行深入分析。同时,通过实例分析,加深对与卷积层和池化层的理解。
LeNet-5共有7层,不包含输入,每层都包含可训练参数;每个层有多个Feature Map,每个FeatureMap通过一种卷积滤波器提取输入的一种特征,然后每个FeatureMap有多个神经元。
各层参数详解:
首先是数据 INPUT 层,输入图像的尺寸统一归一化为32*32。
注意: 本层不算LeNet-5的网络结构,传统上,不将输入层视为网络层次结构之一。
输入图片:32*32
卷积核大小:5*5
卷积核种类:6
输出featuremap大小:28*28 (32-5+1)=28
神经元数量:28286
可训练参数:(55+1) * 6(每个滤波器55=25个unit参数和一个bias参数,一共6个滤波器)
连接数:(55+1)62828=122304
详细说明: 对输入图像进行第一次卷积运算(使用 6 个大小为 55 的卷积核),得到6个C1特征图(6个大小为2828的 feature maps, 32-5+1=28)。我们再来看看需要多少个参数,卷积核的大小为55,总共就有6(55+1)=156个参数,其中+1是表示一个核有一个bias。对于卷积层C1,C1内的每个像素都与输入图像中的55个像素和1个bias有连接,所以总共有1562828=122304个连接(connection)。有122304个连接,但是我们只需要学习156个参数,主要是通过权值共享实现的。
输入:28*28
采样区域:2*2
采样方式:4个输入相加,乘以一个可训练参数,再加上一个可训练偏置。结果通过sigmoid
采样种类:6
输出featureMap大小:14*14(28/2)
神经元数量:14146
连接数:(22+1)61414
S2中每个特征图的大小是C1中特征图大小的1/4。
详细说明: 第一次卷积之后紧接着就是池化运算,使用 22核 进行池化,于是得到了S2,6个1414的 特征图(28/2=14)。S2这个pooling层是对C1中的2*2区域内的像素求和乘以一个权值系数再加上一个偏置,然后将这个结果再做一次映射。同时有5x14x14x6=5880个连接。
输入:S2中所有6个或者几个特征map组合
卷积核大小:5*5
卷积核种类:16
输出featureMap大小:10*10 (14-5+1)=10
C3中的每个特征map是连接到S2中的所有6个或者几个特征map的,表示本层的特征map是上一层提取到的特征map的不同组合
存在的一个方式是:C3的前6个特征图以S2中3个相邻的特征图子集为输入。接下来6个特征图以S2中4个相邻特征图子集为输入。然后的3个以不相邻的4个特征图子集为输入。最后一个将S2中所有特征图为输入。
则:可训练参数:6*(355+1)+6*(455+1)+3*(455+1)+1*(655+1)=1516
连接数:10101516=151600
详细说明: 第一次池化之后是第二次卷积,第二次卷积的输出是C3,16个10x10的特征图,卷积核大小是 55. 我们知道S2 有6个 1414 的特征图,怎么从6 个特征图得到 16个特征图了? 这里是通过对S2 的特征图特殊组合计算得到的16个特征图。具体如下:
C3的前6个feature map(对应上图第一个红框的6列)与S2层相连的3个feature map相连接(上图第一个红框),后面6个feature map与S2层相连的4个feature map相连接(上图第二个红框),后面3个feature map与S2层部分不相连的4个feature map相连接,最后一个与S2层的所有feature map相连。卷积核大小依然为55,所以总共有6(355+1)+6*(455+1)+3*(455+1)+1*(655+1)=1516个参数。而图像大小为10*10,所以共有151600个连接。
C3与S2中前3个图相连的卷积结构如下图所示:
上图对应的参数为 355+1,一共进行6次卷积得到6个特征图,所以有6*(355+1)参数。 为什么采用上述这样的组合了?论文中说有两个原因:1)减少参数,2)这种不对称的组合连接的方式有利于提取多种组合特征。
输入:10*10
采样区域:2*2
采样方式:4个输入相加,乘以一个可训练参数,再加上一个可训练偏置。结果通过sigmoid
采样种类:16
输出featureMap大小:5*5(10/2)
神经元数量:5516=400
连接数:16*(2*2+1)55=2000
S4中每个特征图的大小是C3中特征图大小的1/4
详细说明: S4是pooling层,窗口大小仍然是2*2,共计16个feature map,C3层的16个10x10的图分别进行以2x2为单位的池化得到16个5x5的特征图。有5x5x5x16=2000个连接。连接的方式与S2层类似。
输入:S4层的全部16个单元特征map(与s4全相连)
卷积核大小:5*5
卷积核种类:120
输出featureMap大小:1*1(5-5+1)
可训练参数/连接:120*(1655+1)=48120
详细说明: C5层是一个卷积层。由于S4层的16个图的大小为5x5,与卷积核的大小相同,所以卷积后形成的图的大小为1x1。这里形成120个卷积结果。每个都与上一层的16个图相连。所以共有(5x5x16+1)x120 = 48120个参数,同样有48120个连接。C5层的网络结构如下:
输入:c5 120维向量
计算方式:计算输入向量和权重向量之间的点积,再加上一个偏置,结果通过sigmoid函数输出。
可训练参数:84*(120+1)=10164
详细说明: 6层是全连接层。F6层有84个节点,对应于一个7x12的比特图,-1表示白色,1表示黑色,这样每个符号的比特图的黑白色就对应于一个编码。该层的训练参数和连接数是(120 + 1)x84=10164。ASCII编码图如下:
F6层的连接方式如下:
8、Output层-全连接层
Output层也是全连接层,共有10个节点,分别代表数字0到9,且如果节点i的值为0,则网络识别的结果是数字i。采用的是径向基函数(RBF)的网络连接方式。假设x是上一层的输入,y是RBF的输出,则RBF输出的计算方式是:
上式w_ij 的值由i的比特图编码确定,i从0到9,j取值从0到7*12-1。RBF输出的值越接近于0,则越接近于i,即越接近于i的ASCII编码图,表示当前网络输入的识别结果是字符i。该层有84x10=840个参数和连接。
上图是LeNet-5识别数字3的过程。
总结
由于受到计算机性能的影响,虽然LeNet在图像分类中取得了较好的成绩,但是并没有引起很多的关注。 知道2012年,Alex等人提出的AlexNet网络在ImageNet大赛上以远超第二名的成绩夺冠,卷积神经网络乃至深度学习重新引起了广泛的关注。
AlexNet是在LeNet的基础上加深了网络的结构,学习更丰富更高维的图像特征。AlexNet的特点:
在最初的感知机模型中,输入和输出的关系如下:
只是单纯的线性关系,这样的网络结构有很大的局限性:即使用很多这样结构的网络层叠加,其输出和输入仍然是线性关系,无法处理有非线性关系的输入输出。因此,对每个神经元的输出做个非线性的转换也就是,将上面就加权求和
的结果输入到一个非线性函数,也就是激活函数中。 这样,由于激活函数的引入,多个网络层的叠加就不再是单纯的线性变换,而是具有更强的表现能力。
在最初,sigmoid和tanh函数最常用的激活函数。
1)sigmoid
在网络层数较少时,sigmoid函数的特性能够很好的满足激活函数的作用:它把一个实数压缩至0到1之间,当输入的数字非常大的时候,结果会接近1;当输入非常大的负数时,则会得到接近0的结果。这种特性,能够很好的模拟神经元在受刺激后,是否被激活向后传递信息(输出为0,几乎不被激活;输出为1,完全被激活)。
sigmoid一个很大的问题就是梯度饱和。 观察sigmoid函数的曲线,当输入的数字较大(或较小)时,其函数值趋于不变,其导数变的非常的小。这样,在层数很多的的网络结构中,进行反向传播时,由于很多个很小的sigmoid导数累成,导致其结果趋于0,权值更新较慢。
1)ReLu
针对sigmoid梯度饱和导致训练收敛慢的问题,在AlexNet中引入了ReLU。ReLU是一个分段线性函数,小于等于0则输出为0;大于0的则恒等输出。相比于sigmoid,ReLU有以下有点:
这里有个问题,前面提到,激活函数要用非线性的,是为了使网络结构有更强的表达的能力。那这里使用ReLU本质上却是个线性的分段函数,是怎么进行非线性变换的。
这里把神经网络看着一个巨大的变换矩阵M,其输入为所有训练样本组成的矩阵A,输出矩阵B。
这里的M是一个线性变换的话,则所有的训练样本A进行了线性变换输出为B。
那么对于ReLU来说,由于其是分段的,0的部分可以看着神经元没有激活,不同的神经元激活或者不激活,其神经玩过组成的变换矩阵是不一样的。
设有两个训练样本 a1,a2,其训练时神经网络组成的变换矩阵为M1,M2。 由于M1变换对应的神经网络中激活神经元和M2是不一样的,这样M1,M2实际上是两个不同的线性变换。也就是说,每个训练样本使用的线性变换矩阵Mi是不一样的,在整个训练样本空间来说,其经历的是非线性变换。
简单来说,不同训练样本中的同样的特征,在经过神经网络学习时,流经的神经元是不一样的(激活函数值为0的神经元不会被激活)。这样,最终的输出实际上是输入样本的非线性变换。
神经网络由于训练的参数多,表能能力强,所以需要比较多的数据量,不然很容易过拟合。当训练数据有限时,可以通过一些变换从已有的训练数据集中生成一些新的数据,以快速地扩充训练数据。对于图像数据集来说,可以对图像进行一些形变操作:
AlexNet中对数据做了以下操作:
在LeNet中池化是不重叠的,即池化的窗口的大小和步长是相等的,如下
在AlexNet中使用的池化(Pooling)却是可重叠的,也就是说,在池化的时候,每次移动的步长小于池化的窗口长度。AlexNet池化的大小为3×3的正方形,每次池化移动步长为2,这样就会出现重叠。重叠池化可以避免过拟合,这个策略贡献了0.3%的Top-5错误率。与非重叠方案s=2,z=2相比,输出的维度是相等的,并且能在一定程度上抑制过拟合。
ReLU具有让人满意的特性,它不需要通过输入归一化来防止饱和。如果至少一些训练样本对ReLU产生了正输入,那么那个神经元上将发生学习。然而,我们仍然发现接下来的局部响应归一化有助于泛化。表示神经元激活,通过在(x,y)位置应用核i,然后应用ReLU非线性来计算,响应归一化激活通过下式给定:
这个是比较常用的抑制过拟合的方法了。
引入Dropout主要是为了防止过拟合。在神经网络中Dropout通过修改神经网络本身结构来实现,对于某一层的神经元,通过定义的概率将神经元置为0,这个神经元就不参与前向和后向传播,就如同在网络中被删除了一样,同时保持输入层与输出层神经元的个数不变,然后按照神经网络的学习方法进行参数更新。在下一次迭代中,又重新随机删除一些神经元(置为0),直至训练结束。
Dropout应该算是AlexNet中一个很大的创新,现在神经网络中的必备结构之一。Dropout也可以看成是一种模型组合,每次生成的网络结构都不一样,通过组合多个模型的方式能够有效地减少过拟合,Dropout只需要两倍的训练时间即可实现模型组合(类似取平均)的效果,非常高效。
上图中的输入是224×224,不过经过计算(224−11)/4=54.75并不是论文中的55×55,而使用227×227作为输入,则(227−11)/4=55
网络包含8个带权重的层;前5层是卷积层,剩下的3层是全连接层。最后一层全连接层的输出是1000维softmax的输入,softmax会产生1000类标签的分布网络包含8个带权重的层;前5层是卷积层,剩下的3层是全连接层。最后一层全连接层的输出是1000维softmax的输入,softmax会产生1000类标签的分布。
1)卷积层C1
该层的处理流程是: 卷积–>ReLU–>池化–>归一化。
2)卷积层C2
该层的处理流程是:卷积–>ReLU–>池化–>归一化
3)卷积层C3
该层的处理流程是: 卷积–>ReLU
4)卷积层C4
该层的处理流程是: 卷积–>ReLU
该层和C3类似。
5)卷积层C5
该层处理流程为:卷积–>ReLU–>池化
6)全连接层FC6
该层的流程为:(卷积)全连接 -->ReLU -->Dropout
7)全连接层FC7
流程为:全连接–>ReLU–>Dropout
8)输出层
第七层输出的4096个数据与第八层的1000个神经元进行全连接,经过训练后输出1000个float型的值,这就是预测结果
卷积层的参数 = 卷积核的数量 * 卷积核 + 偏置
论文下载:http://www.cs.toronto.edu/~fritz/absps/imagenet.pdf
2014年,牛津大学计算机视觉组(Visual Geometry Group)和Google DeepMind公司的研究员一起研发出了新的深度卷积神经网络:VGGNet,并取得了ILSVRC2014比赛分类项目的第二名(第一名是GoogLeNet,也是同年提出的).论文下载 Very Deep Convolutional Networks for Large-Scale Image Recognition。论文主要针对卷积神经网络的深度对大规模图像集识别精度的影响,主要贡献是使用很小的卷积核(3×3)构建各种深度的卷积神经网络结构,并对这些网络结构进行了评估,最终证明16-19层的网络深度,能够取得较好的识别精度。 这也就是常用来提取图像特征的VGG-16和VGG-19。
VGG可以看成是加深版的AlexNet,整个网络由卷积层和全连接层叠加而成,和AlexNet不同的是,VGG中使用的都是小尺寸的卷积核(3×3)。
结构简洁,如下图VGG-19的网络结构
对比,前面介绍的AlexNet的网络结构图,是不是有种赏心悦目的感觉。整个结构只有3×3的卷积层,连续的卷积层后使用池化层隔开。虽然层数很多,但是很简洁。
小卷积核和连续的卷积层
VGG中使用的都是3×3卷积核,并且使用了连续多个卷积层。这样做的好处:
使用连续的的多个小卷积核(3×3),来代替一个大的卷积核(例如(5×5)。
使用小的卷积核的问题是,其感受野必然变小。所以,VGG中就使用连续的3×3卷积核,来增大感受野。VGG认为2个连续的3×3卷积核能够替代一个5×5卷积核,三个连续的3×3能够代替一个7×7。
小卷积核的参数较少。3个3×3的卷积核参数为3×3×=27,而一个7×7的卷积核参数为7×7=49
由于每个卷积层都有一个非线性的激活函数,多个卷积层增加了非线性映射。
例如7×7×512的层要跟4096个神经元的层做全连接,则替换为对7×7×512的层作通道数为4096、卷积核为1×1卷积。
这个“全连接转卷积”的思路是VGG作者参考了OverFeat的工作思路,例如下图是OverFeat将全连接换成卷积后,则可以来处理任意分辨率(在整张图)上计算卷积,这就是无需对原图做重新缩放处理的优势。
VGG网络相比AlexNet层数多了不少,但是其结构却简单不少。
VGG论文主要是研究网络的深度对其分类精度的影响,所以按照上面的描述设计规则,作者实验的了不同深度的网络结构
所有网络结构都遵从上面提到的设计规则,并且仅是深度不同,也就是卷积层的个数不同:从网络A中的11个加权层(8个卷积层和3个FC层)到网络E中的19个加权层(16个卷积层和3个FC层)。卷积层的宽度(通道数)相当小,从第一层中的64开始,然后在每个最大池化层之后增加2倍,直到达到512。
上图给出了各个深度的卷积层使用的卷积核大小以及通道的个数。最后的D,E网络就是大名鼎鼎的VGG-16和VGG-19了。
AlexNet仅仅只有8层,其可训练的参数就达到了60M,VGG系列的参数就更恐怖了,如下图(单位是百万)
由于参数大多数集中在后面三个全连接层,所以虽然网络的深度不同,全连接层确实相同的,其参数区别倒不是特别的大
VGG优点
VGG缺点
PS:有的文章称:发现这些全连接层即使被去除,对于性能也没有什么影响,这样就显著降低了参数数量。
注:很多pretrained的方法就是使用VGG的model(主要是16和19),VGG相对其他的方法,参数空间很大,最终的model有500多m,AlexNet只有200m,GoogLeNet更少,所以train一个vgg模型通常要花费更长的时间,所幸有公开的pretrained model让我们很方便的使用。
这是GoogLeNet的最早版本,出现在2014年的《Going deeper with convolutions》。之所以名为“GoogLeNet”而非“GoogleNet”,文章说是为了向早期的LeNet致敬。
深度学习以及神经网络快速发展,人们不再只关注更给力的硬件、更大的数据集、更大的模型,而是更在意新的idea、新的算法以及模型的改进。
一般来说,提升网络性能最直接的办法就是增加网络深度和宽度,这也就意味着巨量的参数。但是,巨量参数容易产生过拟合也会大大增加计算量。
文章认为解决上述两个缺点的根本方法是将全连接甚至一般的卷积都转化为稀疏连接。一方面现实生物神经系统的连接也是稀疏的,另一方面有文献1表明:对于大规模稀疏的神经网络,可以通过分析激活值的统计特性和对高度相关的输出进行聚类来逐层构建出一个最优网络。这点表明臃肿的稀疏网络可能被不失性能地简化。 虽然数学证明有着严格的条件限制,但Hebbian准则有力地支持了这一点:fire together,wire together。
早些的时候,为了打破网络对称性和提高学习能力,传统的网络都使用了随机稀疏连接。但是,计算机软硬件对非均匀稀疏数据的计算效率很差,所以在AlexNet中又重新启用了全连接层,目的是为了更好地优化并行运算。
所以,现在的问题是有没有一种方法,既能保持网络结构的稀疏性,又能利用密集矩阵的高计算性能。大量的文献表明可以将稀疏矩阵聚类为较为密集的子矩阵来提高计算性能,据此论文提出了名为Inception 的结构来实现此目的。
Inception 结构的主要思路是怎样用密集成分来近似最优的局部稀疏结构。
作者首先提出下图这样的基本结构:
对上图做以下说明:
1 . 采用不同大小的卷积核意味着不同大小的感受野,最后拼接意味着不同尺度特征的融合;
2 . 之所以卷积核大小采用1、3和5,主要是为了方便对齐。设定卷积步长stride=1之后,只要分别设定pad=0、1、2,那么卷积之后便可以得到相同维度的特征,然后这些特征就可以直接拼接在一起了;
3 . 文章说很多地方都表明pooling挺有效,所以Inception里面也嵌入了。
4 . 网络越到后面,特征越抽象,而且每个特征所涉及的感受野也更大了,因此随着层数的增加,3x3和5x5卷积的比例也要增加。
但是,使用5x5的卷积核仍然会带来巨大的计算量。 为此,文章借鉴NIN2,采用1x1卷积核来进行降维。
例如:上一层的输出为100x100x128,经过具有256个输出的5x5卷积层之后(stride=1,pad=2),输出数据为100x100x256。其中,卷积层的参数为128x5x5x256。假如上一层输出先经过具有32个输出的1x1卷积层,再经过具有256个输出的5x5卷积层,那么最终的输出数据仍为为100x100x256,但卷积参数量已经减少为128x1x1x32 + 32x5x5x256,大约减少了4倍。
具体改进后的Inception Module如下图:
GoogLeNet的整体结构如下图:
对上图做如下说明:
1 . 显然GoogLeNet采用了模块化的结构,方便增添和修改;
2 . 网络最后采用了average pooling来代替全连接层,想法来自NIN,事实证明可以将TOP1 accuracy提高0.6%。但是,实际在最后还是加了一个全连接层,主要是为了方便以后大家finetune;
3 . 虽然移除了全连接,但是网络中依然使用了Dropout ;
4 . 为了避免梯度消失,网络额外增加了2个辅助的softmax用于向前传导梯度。文章中说这两个辅助的分类器的loss应该加一个衰减系数,但看caffe中的model也没有加任何衰减。此外,实际测试的时候,这两个额外的softmax会被去掉。
GoogLeNet是谷歌团队为了参加ILSVRC 2014比赛而精心准备的,为了达到最佳的性能,除了使用上述的网络结构外,还做了大量的辅助工作:包括训练多个model求平均、裁剪不同尺度的图像做多次验证等等。详细的这些可以参看文章的实验部分。
本文的主要想法其实是想通过构建密集的块结构来近似最优的稀疏结构,从而达到提高性能而又不大量增加计算量的目的。GoogleNet的caffemodel大小约50M,但性能却很优异。
GoogLeNet凭借其优秀的表现,得到了很多研究人员的学习和使用,因此Google团队又对其进行了进一步发掘改进,产生了升级版本的GoogLeNet。这一节介绍的版本记为V2,文章为:《Rethinking the Inception Architecture for Computer Vision》。
14年以来,构建更深的网络逐渐成为主流,但是模型的变大也使计算效率越来越低。这里,文章试图找到一种方法在扩大网络的同时又尽可能地发挥计算性能。
首先,GoogLeNet V1出现的同期,性能与之接近的大概只有VGGNet了,并且二者在图像分类之外的很多领域都得到了成功的应用。但是相比之下,GoogLeNet的计算效率明显高于VGGNet,大约只有500万参数,只相当于Alexnet的1/12(GoogLeNet的caffemodel大约50M,VGGNet的caffemodel则要超过600M)。
GoogLeNet的表现很好,但是,如果想要通过简单地放大Inception结构来构建更大的网络,则会立即提高计算消耗。此外,在V1版本中,文章也没给出有关构建Inception结构注意事项的清晰描述。因此,在文章中作者首先给出了一些已经被证明有效的用于放大网络的通用准则和优化方法。这些准则和方法适用但不局限于Inception结构。
下面的准则来源于大量的实验,因此包含一定的推测,但实际证明基本都是有效的。
1 . 避免表达瓶颈,特别是在网络靠前的地方。 信息流前向传播过程中显然不能经过高度压缩的层,即表达瓶颈。从input到output,feature map的宽和高基本都会逐渐变小,但是不能一下子就变得很小。比如你上来就来个kernel = 7, stride = 5 ,这样显然不合适。
另外输出的维度channel,一般来说会逐渐增多(每层的num_output),否则网络会很难训练。(特征维度并不代表信息的多少,只是作为一种估计的手段)
2 . 高维特征更易处理。 高维特征更易区分,会加快训练。
3. 可以在低维嵌入上进行空间汇聚而无需担心丢失很多信息。 比如在进行3x3卷积之前,可以对输入先进行降维而不会产生严重的后果。假设信息可以被简单压缩,那么训练就会加快。
4 . 平衡网络的宽度与深度。
上述的这些并不能直接用来提高网络质量,而仅用来在大环境下作指导。
大尺寸的卷积核可以带来更大的感受野,但也意味着更多的参数,比如5x5卷积核参数是3x3卷积核的25/9=2.78倍。为此,作者提出可以用2个连续的3x3卷积层(stride=1)组成的小网络来代替单个的5x5卷积层,(保持感受野范围的同时又减少了参数量)如下图:
然后就会有2个疑问:
1 . 这种替代会造成表达能力的下降吗?
后面有大量实验可以表明不会造成表达缺失;
2 . 3x3卷积之后还要再加激活吗?
作者也做了对比试验,表明添加非线性激活会提高性能。
从上面来看,大卷积核完全可以由一系列的3x3卷积核来替代,那能不能分解的更小一点呢。文章考虑了 nx1 卷积核。
如下图所示的取代3x3卷积:
于是,任意nxn的卷积都可以通过1xn卷积后接nx1卷积来替代。实际上,作者发现在网络的前期使用这种分解效果并不好,还有在中度大小的feature map上使用效果才会更好。(对于mxm大小的feature map,建议m在12到20之间)。
总结如下图:
(1) 图4是GoogLeNet V1中使用的Inception结构;
(2) 图5是用3x3卷积序列来代替大卷积核;
(3) 图6是用nx1卷积来代替大卷积核,这里设定n=7来应对17x17大小的feature map。该结构被正式用在GoogLeNet V2中。
1)ResNets要解决的是深度神经网络的“退化”问题。
什么是“退化”?
我们知道,对浅层网络逐渐叠加layers,模型在训练集和测试集上的性能会变好,因为模型复杂度更高了,表达能力更强了,可以对潜在的映射关系拟合得更好。而“退化”指的是,给网络叠加更多的层后,性能却快速下降的情况。
训练集上的性能下降,可以排除过拟合,BN层的引入也基本解决了plain net的梯度消失和梯度爆炸问题。如果不是过拟合以及梯度消失导致的,那原因是什么?
按道理,给网络叠加更多层,浅层网络的解空间是包含在深层网络的解空间中的,深层网络的解空间至少存在不差于浅层网络的解,因为只需将增加的层变成恒等映射,其他层的权重原封不动copy浅层网络,就可以获得与浅层网络同样的性能。更好的解明明存在,为什么找不到?找到的反而是更差的解?
显然,这是个优化问题,反映出结构相似的模型,其优化难度是不一样的,且难度的增长并不是线性的,越深的模型越难以优化。
有两种解决思路,一种是调整求解方法,比如更好的初始化、更好的梯度下降算法等;另一种是调整模型结构,让模型更易于优化——改变模型结构实际上是改变了error surface的形态。
ResNet的作者从后者入手,探求更好的模型结构。将堆叠的几层layer称之为一个block,对于某个block,其可以拟合的函数为F(x),如果期望的潜在映射为H(x),与其让F(x) 直接学习潜在的映射,不如去学习残差H(x)−x,即F(x):=H(x)−x,这样原本的前向路径上就变成了F(x)+x,用F(x)+x来拟合H(x)。作者认为这样可能更易于优化,因为**相比于让F(x)学习成恒等映射,让F(x)学习成0要更加容易——后者通过L2正则就可以轻松实现。**这样,对于冗余的block,只需F(x)→0就可以得到恒等映射,性能不减。
下面的问题就变成了F(x)+x 该怎么设计了。
F(x)+x构成的block称之为Residual Block,即残差块,如下图所示,多个相似的Residual Block串联构成ResNet
一个残差块有2条路径F(x)和x,F(x)路径拟合残差,不妨称之为残差路径,x路径为identity mapping恒等映射,称之为”shortcut”。图中的⊕为element-wise addition,要求参与运算的F(x)和x的尺寸要相同。所以,随之而来的问题是,
在原论文中,残差路径可以大致分成2种,一种有bottleneck结构,即下图右中的1×1 卷积层,用于先降维再升维,主要出于降低计算复杂度的现实考虑,称之为**“bottleneck block”,另一种没有bottleneck结构,如下图左所示,称之为“basic block”**。basic block由2个3×3卷积层构成,bottleneck block由1×1
shortcut路径大致也可以分成2种,取决于残差路径是否改变了feature map数量和尺寸,一种是将输入x原封不动地输出,另一种则需要经过1×1卷积来升维 or/and 降采样,主要作用是将输出与F(x)路径的输出保持shape一致,对网络性能的提升并不明显,两种结构如下图所示,
至于Residual Block之间的衔接,在原论文中,F(x)+x经过ReLU后直接作为下一个block的输入x。
对于F(x)路径、shortcut路径以及block之间的衔接,在论文Identity Mappings in Deep Residual Networks中有更进一步的研究,具体在文章后面讨论。
ResNet为多个Residual Block的串联,下面直观看一下ResNet-34与34-layer plain net和VGG的对比,以及堆叠不同数量Residual Block得到的不同ResNet。
论文Identity Mappings in Deep Residual Networks进一步研究ResNet,通过ResNet反向传播的理论分析以及调整Residual Block的结构,得到了新的结构,如下
注意,这里的视角与之前不同,这里将shortcut路径视为主干路径,将残差路径视为旁路。
新提出的Residual Block结构,具有更强的泛化能力,能更好地避免“退化”,堆叠大于1000层后,性能仍在变好。具体的变化在于
令h(xl)为shortcut路径上的变换,f为addition之后的变换,原Residual Block中f=ReLU,当h和f均为恒等映射时,可以得到任意两层xL和xl之间的关系,此时信息可以在xl和xL间无损直达,如下前向传播中的xl以及反向传播中的1。
反向传播中的这个1具有一个很好的性质,**任意两层间的反向传播,这一项都是1,可以有效地避免梯度消失和梯度爆炸。**如果h和f不是恒等映射,就会让这一项变得复杂,若是令其为一个大于或小于1的scale因子,反向传播连乘后就可能导致梯度爆炸或消失,层数越多越明显,这也是ResNet比highway network性能好的原因。需要注意的是,BN层解决了plain net的梯度消失和爆炸,这里的1可以避免short cut 路径上的梯度消失和爆炸。
shortcut路径将反向传播由连乘形式变为加法形式,让网络最终的损失在反向传播时可以无损直达每一个block,也意味着每个block的权重更新都部分地直接作用在最终的损失上。看上面前向传播的公式,可以看到某种ensemble形式,信息虽然可以在任意两层之间直达,但这种直达其实是隐含的,对某个block而言,它只能看到加法的结果,而不知道加法中每个加数是多数,从信息通路上讲尚不彻底——由此也诞生了DenseNet。
对于残差路径的改进,作者进行了不同的对比实验,最终得到了将BN和ReLU统一放在weight前的full pre-activation结构。
ResNet的动机在于解决“退化”问题,残差块的设计让学习恒等映射变得容易,即使堆叠了过量的block,ResNet可以让冗余的block学习成恒等映射,性能也不会下降。所以,网络的“实际深度”是在训练过程中决定的,即ResNet具有某种深度自适应的能力。
深度自适应能解释不会“退化”,但为什么可以更好?
通过可视化error surface,我们看到了shortcut的平滑作用,但这只是结果,背后的根由是什么?
也许彻底搞懂ResNet还需要进一步地研究,但已有很多不同的理解角度,
微分方程的角度,A Proposal on Machine Learning via Dynamical Systems
ensemble的角度,Residual Networks Behave Like Ensembles of Relatively Shallow Networks
信息/梯度通路的角度,Identity Mappings in Deep Residual Networks
类比泰勒展开、类比小波……
以上现在流行的CNN,如AlexNet、VGG、ResNet,虽然识别效果不错,但是模型的参数量和计算量巨大,不适合在移动端、嵌入式设备上运行。所以就出现了更轻量级更快速的的CNN设计,这里要讲述的是谷歌的MobileNet系列工作。
paper https://arxiv.org/abs/1704.04861
MobileNet 由谷歌在 2017 年提出,是一款专注于在移动设备和嵌入式设备上的 轻量级 CNN神经网络,并 迅速 衍生了 v1 v2 v3 三个版本;
相比于传统的 CNN 网络,在准确率小幅降低的前提下,大大减小模型参数和运算量;一句话概括,V1 就是 把 vgg 中标准卷积层 换成了 深度可分离卷积;
模型亮点:
深度可分离卷积,大大减少参数量
增加超参 α、β
可分离卷积
可分离卷积大致可以分为 空间可分离 和 深度可分离;
空间可分离
顾名思义,就是把一个 大卷积核 换成两个 小卷积核,例如;
非本文重点,简单介绍;
深度可分离
深度可分离 由 深度卷积 + 逐点卷积 组成;
深度卷积:
论文中称为 DW 卷积,就是 把 卷积核 变成 单通道,输入有 M 个通道数,就需要 M 个卷积核,每个通道 分别进行卷积,最后做叠加,如下图
逐点卷积:
论文中称为 PW 卷积,就是用 1x1 的卷积核进行卷积,作用是 对深度卷积后的 特征 进行 升维;
上面两步实现的效果如下图
可以看到输出 的 shape 是一样的;
下面我们看看在 输入输出 shape 一样时各自的参数量
标准卷积
params:Dk x Dk x M x N
计算量:Dk x Dk x M x Dh x Dw x N
可分离卷积
params:Dk x Dk x M + M x N
计算量:Dk x Dk x M x Dh x Dw + M x Dh x Dw x N
N 为 输出通道数, Dk 为 卷积核 size,如果 size 为 3,减小了 1/9 左右,厉害了;
V1 卷积结构
把 vgg 的标准卷积 和 V1 的深度可分离卷积 对比看下
看到了 深度卷积 (3x3 Depthwise)和逐点卷积 (1x1 conv);同时看到了 Relu6,什么鬼?
Relu6
上图,一看便知
Relu6 对 大于 0 的部分做了一个边界,作者认为,在模型精度要求不是很高的情况下,边界使得模型鲁棒性更强;
强行压缩数值比较大的特征,避免了 个性特征,也相当于 规范了特征,防止过拟合,玄学要自己体会;
V1 网络结构
Conv 代表标准卷积,Conv dw 代表深度可分离卷积,s2 代表步长为2,s1 代表步长为1;
V1 模型效果
标准卷积是在 原特征 上进行多次卷积,而 深度可分离卷积 是在 卷积后的 特征上 进行 多次卷积,直观的感觉是,后者提取的特征不如前者,性能应该差点;
为了验证 V1 的效果,作者做了各种实验;
分别用 标准卷积 和 深度可分离卷积 实现 MobileNetV1
可以看到 效果确实不如 标准卷积,但是 ACC 相差不大, 可喜的是 参数量和计算量 大大降低,约 1/9;
把 V1 和 其他经典网络比较
ACC 优于 GoogleNet,差于 VGG16,但相差都不太大,但是参数量和计算量大大降低;
总结一句话,就是 V1 效果不输其他网络,但计算量和参数量大大降低;
paper https://arxiv.org/abs/1801.04381
MobileNetV2 是由 谷歌 在 2018 年提出,相比 V1,准确率更好,模型更小;
模型亮点:
Inverted Residuals(倒残差结构)
Linear bottlenecks
倒残差结构
一看到 残差,就想到 resnet 了,先来看看 resnet 的 residual block(上文有介绍)
我们看右边的 block,在 resnet 中 这个 block 专为 深层网络设计,可大大减少 参数量;它先 通过 1x1 把 256 channel 变成 64 做降维,然后是 3x3 conv,再接着 1x1 还原为 256 channel 做升维;
总结一句就是先降维再升维,两头胖,中间瘦;
而 倒残差结构就是 两头瘦,中间胖;
如下图
在具体网络设计时,经过试验,作者并不是把 所有 block 都加上了 残差结构,所以 V2 中有两种 block;
只有 Stride=1 时,才有 残差结构;
Linear bottlenecks
我们看到上面的 残差结构 末尾 是 Linear 而不是 Relu,为什么呢?
作者经过研究,发现在 V1 中 depthwise 中有 0 卷积的原因就是 Relu 造成的,换成 Linear 解决了这个问题;
Relu 为什么被换掉
作者做了如下实验
作者把一个 二维 流形 数据【图1】 作为 输入, 然后 用不同维度的矩阵 T 把它映射到 高维,然后经过 Relu 输出,再把 输出 经过 T-1 还原成 二维,发现,在 低维 【图2 3】 时,Relu 对信号的损失非常大,随着维度增加,损失越来越小;
结论就是 Relu 对低维信号 损失很大;
回想一下 深度卷积,深度卷积是单通道卷积,只有 1 维,经过 relu 后,即使是 融合后再 Relu 也只有 3 维,信号损失很大,如果学到的信号完全没有用,那就不用学了, w 自然是 0 ;
问题又来了,既然 depthwise 时 relue 造成了信号损失,为什么不换 DW 的 relue,而是把 逐点卷积 的 激活函数 换成 Linear 了?
首先 dw 的 relu 造成 大量损失是因为 Input 的 channel 太少了,如果 Input 的 channel 不少呢,就不损失了,那就没问题了,所以重点不是换不换 relue,是解决 低 channel 的问题;
既然 channel 少,我给你增加 channel 不就好了,就是 1x1 升维咯;
升完了,我再降回来,将回来之后, channel 就少了,那就换成 linear 咯;
于是 倒残差结构 形成咯,再就是画道线的事,参考 resnet 而已;