论文:《ImageNet Classification with Deep Convolutional Neural Networks》
在线阅读地址为:https://pdfs.semanticscholar.org/09b8/120cbc52e7df46122e8e608146289fddbdfa.pdf
第一个典型的CNN是LeNet5网络结构,但是第一个引起大家注意的网络却是AlexNet。AlexNet是2012年ImageNet竞赛冠军获得者Hinton和他的学生Alex Krizhevsky设计的,以一作Alex Krizhevsky命名。也是在那年之后,更多的更深的神经网路被提出,比如优秀的vgg,GoogleLeNet。其官方提供的数据模型,准确率达到57.1%,top 1-5 达到80.2%. 这项对于传统的机器学习分类算法而言,已经相当的出色,所以这也是引起大家注意的主要原因。
AlexNet网络结构在整体上类似于LeNet,都是先卷积然后在全连接。但在细节上有很大不同。AlexNet更为复杂。AlexNet有60 million个参数和65000个 神经元,五层卷积,三层全连接网络,最终的输出层是1000通道的softmax。
AlexNet是在LeNet的基础上加深了网络的结构,学习更丰富更高维的图像特征。AlexNet的特点:
在最初的感知机模型中,输入和输出的关系如下:
只是单纯的线性关系,这样的网络结构有很大的局限性:即很多这样结构的网络层叠加,其输出和输入仍然是线性关系,无法处理有非线性关系的输入输出。因此,对每个神经元的输出做个非线性的转换也就是将上面的加权求和
的结果输入到一个非线性函数,也就是激活函数中。这样由于激活函数的引入,多个网络层的叠加就不再是单纯的线性变换,而是具有更强的表现能力。激活函数的作用就是为了为神经网络增加非线性因素,使其可以拟合任意的函数。
在最初,sigmoid和tanh函数最常用的激活函数。
在网络层数较少时,sigmoid函数的特性能够很好的满足激活函数:它把一个实数压缩至0到1之间,当输入的数字非常大的时候,结果会接近1;当输入非常大的负数时,则会得到接近0的结果。这种特性,能够很好的模拟神经元在受到刺激后,是否被激活向后传递信息(输出为0,几乎不被激活;输出为1,完全被激活)。
sigmoid一个很大的问题就是梯度饱和。观察sigmoid函数的曲线,当输入的数字较大(或较小)时,其函数值趋于不变,其导数变的非常的小。这样,在层数很多的网络结构中,进行反向传播时,由于很多个很小的sigmoid导数累成,导致其结果趋于0,权值更新较慢。
针对sigmoid梯度饱和导致训练收敛慢的问题,在AlexNet中引入了ReLU。
ReLU是一个分段线性函数,小于等于0则输出为0;大于0的则恒等于输出。相比于sigmoid,ReLU有以下优点:
这里有个问题,前面提到,激活函数要用非线性的,是为了使网络结构有更强的表达的能力。那这里使用ReLU本质上却是个线性的分段函数,是怎么进行非线性变换的。
说白了一句话:ReLu虽然在大于0的区间是线性的,在小于等于0的部分也是线性的,但是它整体不是线性的,因为不是一条直线。线性、非线性是针对函数的整个定义域来决定的,所以ReLU是非线性函数,但是其中的两段都是线性的。
对于浅层的机器学习,比如经典的三层神经网络,用它作为激活函数的话,那表现出来的性质肯定是线性的。但是在深度学习里,少则几十,多则上千的隐藏层,虽然,单独的隐藏层是线性的,但是很多的隐藏层表现出来的就是非线性的。线性和非线性,举个简单的例子,一条曲线无限分段,每段就趋向直线,反过来,很多这样的直线就可以拟合曲线。类似,大规模的神经网络,包含很多这样的线性基本组件,自然也可以拟合复杂的非线性情况。
这里把神经网络看做一个巨大的变换矩阵M,其输入为所有训练样本组成的矩阵A,输出为矩阵B。
这里的M是一个线性变换的话,则所有的训练样本A进行了线性变换输出为B。
那么对于ReLU来说,由于其是分段的,0的部分可以看做神经元没有激活,不同的神经元激活或者不激活,其神经元组成的变换矩阵是不一样的。
设有两个训练样本,其训练时神经网络组成的变换矩阵为。由于变换对应的神经网络中激活神经元和是不一样的,这样实际上是两个不同的线性变换。也就是说,每个训练样本使用的线性变换矩阵是不一样的,在整个训练样本空间来说,其经历的是非线性变换。
简单来说,不同训练样本中的同样的特征,在经过神经网络学习时,流经的神经元是不一样的(激活函数值为0的神经元不会被激活)。这样,最终的输出实际上是输入样本的非线性变换。
单个训练样本是线性变换,但是每个训练样本的线性变换是不一样的,这样整个训练样本集来说,就是非线性的变换。
神经网络由于训练的参数多,表达能力强,所以需要比较多的数据量,不然很容易过拟合。当训练数据有限时,可以通过一些变换从已有的训练数据集中生成一些新的数据,以快速地扩充训练数据。对于图像数据集来说,可以对图像进行一些形变操作:
AlexNet中对数据做了以下操作:
1.随机裁剪,对256*256的图片进行随机裁剪到227*227,然后进行水平翻转
2.测试的时候,对左上、右上、左下、右下、中间分别做了5次裁剪,然后翻转,共10个裁剪,之后对结果求平均。
3.对RGB空间做PCA(主成分分析),然后对主成分做一个(0,0,1)的高斯扰动,也就是对颜色、光照做变换,结果使错误率又下降了1%。
在LeNet中池化(使用的是平均池化)是不可叠加的,即池化的窗口的大小和步长是相等的,即f=2,s=2
在AlexNet中使用的池化(Pooling)却是可重叠的,也就是说,在池化的时候,每次移动的步长s小于池化的窗口长度f。AlexNet池化的大小为3*3的正方形,每次池化移动步长为2,这样就会出现重叠。重叠池化可以避免过拟合,这个策略贡献了0.3%的Top-5错误率。与非重叠方案s=2,f=2相比,输出的维度是相等的,并且能在一定成都上抑制过拟合。
ReLU具有让人满意的特性,它不需要通过输入归一化来防止饱和。如果至少一些训练样本对ReLU产生了正输入,那么那个神经元上将发生学习。然而,我们仍然发现接下来的局部响应归一化有助于泛化。表示神经元激活,通过在(x,y)位置应用核i,然后应用ReLU非线性来计算,响应归一化激活通过下式给定:
其中,N是卷积核的个数,也就是生成的FeatureMap的个数;k,α,β,n是超参数,论文中使用的值是
输出和输入的上标表示的是当前值所在的通道,也即是叠加的方向是沿着通道进行。将要归一化的值所在附近通道相同位置的值的平方累加起来
这个是比较常用的抑制过拟合的方法。
引入Dropout主要是为了防止过拟合。在神经网络中Dropout通过修改神经网络本身结构来实现,对于某一层的神经元,通过定义的概率将神经元置为0,这个神经元就不参与前向和后向传播,就如同在网络中被删除不存在了一样,同时保持输入层与输出层神经元的个数不变,然后按照神经网络的学习方法进行参数更新。在下一次迭代中,又重新随机删除一些神经元(置为0),直到训练结束。
Dropout应该算是AlexNet中一个很大的创新,现在神经网络中的必备结构之一。Dropout也可以看成是一种模型组合,每次生成的网络结构都不一样,通过组合多个模型的方式能够有效地减少过拟合,Dropout只需要两倍的训练时间即可实现模型组合(类似取平均)的效果,非常高效。
如下图:
上上图所示是caffe中alexnet的网络结构,首先这幅图分为上下两个部分的网络,论文中提到这两部分网络是分别对应两个GPU,只有到了特定的网络层后才需要两块GPU进行交互,这种设置完全是利用两块GPU来提高运算的效率,其实在网络结构上差异不是很大。图中的输入是224*224,不过经过计算(224-11)/4 +1=54.25,这样经过卷积输出的特征图并不是 55*55,而使用227*227作为输入,则(227-11)/4 +1=55。下边把AlexNet的网络结构示意一下(下面这张网络结构图看着简单清晰一些):
如上图所示:网络包含8个带权重的层;前5层是卷积层,剩下的3层是全连接层。最后一层全连接层的输出是1000维softmax的输入,softmax会产生1000类标签的分布。
该层的处理流程是:卷积 -> ReLU -> 池化 -> 归一化
卷积:输入是227*227*3,使用96个11*11*3的卷积核,步长为4,得到的特征图的维度为 55*55*96( ).
ReLU:将卷积层输出的特征图输入到ReLU函数中
池化:使用3*3步长为2的池化单元(重叠池化,步长小于池化单元的宽度),输出为27*27*96( )
局部响应归一化:使用k=2, n=5, α=,β=0.75进行局部归一化,输出的仍然为27*27*96,输出分为两组,每组的大小为27*27*48
总共的参数:(11*11*3+1)*96=34944
该层的处理流程是:卷积 -> ReLU -> 池化 -> 归一化
卷积( same conv,输入长宽维度等于输出长宽维度 ):输入是2组27*27*48,即27*27*96。使用2组,每组128个尺寸为5*5*48的卷积核,并作了边缘填充padding=2,卷积的步长为1,,则输出的特征图为2组,每组的大小为27*27*128( ),即总的输出为 27*27*256
ReLU: 将卷积层输出的特征图输入到ReLU函数中
池化:使用3*3步长为2的池化单元,池化后输出图像的尺寸为13*13*256( )
局部相应归一化:使用k=2, n=5, α=,β=0.75进行局部归一化,输出的仍然为13*13*256,输出分为2组,每组的大小为13*13*128,即总的输出为13*13*256.
总共的参数:(5*5*48+1)*128*2=307456
注:这里我们如果按照一般的(不分组):输入维度27*27*96,卷积核为5*5*96*256,输出为13*13*256,参数为(5*5*96+1)*256=614656
该层的处理流程为:卷积 -> ReLU
卷积( same conv,输入长宽维度等于输出长宽维度 ):输入为13*13*256,使用2组数量总共为384个3*3*256的卷积核,做了边缘填充padding=1,卷积的步长为1,则输出的特征图为13*13*384( )
ReLU: 将卷积层输出的特征图输入到ReLU函数中
总共的参数:(3*3*256+1)*384=885120
2.4 卷积层C4:
该层的处理流程为:卷积 -> ReLU
该层和C3类似。
卷积(same conv,输入长宽维度等于输出长宽维度 ):输入是13*13*384(分为2组,每组为13*13*192),使用2组,每组192个尺寸为3*3*192的卷积核,做了边缘填充padding=1,卷积的步长为1,则输出的特征图为13*13*384( )
ReLU:将卷积层输出的特征图输入到ReLU函数中
总共的参数:(3*3*192+1)*192*2=663936
该层处理流程为:卷积 -> ReLU -> 池化
卷积:输入为 13*13*384,分为两组,每组为13*13*192。使用2组,每组为128个尺寸为3*3*192的卷积核,做了边缘填充padding=1,卷积的步长为1,则输出的特征图为13*13*256( )
ReLU: 将卷积层输出的特征图输入到ReLU函数中
池化:池化运算的尺寸为3*3,步长为2,池化后图像的尺寸为6*6*256( )
总共的参数:(3*3*192+1)*128*2=442624
该层的流程为:(卷积) 全连接 -> ReLU -> Dropout
卷积->全连接: 输入为6*6*256,该层有4096个卷积核,每个卷积核的大小为6*6*256。由于卷积核的尺寸刚好与待处理特征图(即本层输入图像)的尺寸相同,即卷积核中的每个系数只与特征图(输入)尺寸的一个像素值相乘,一一对应(不需要在输入图像中滑动卷积核),因此,该层被称为全连接层。由于卷积核与特征图的尺寸相同,卷积运算后只有一个值,因此,卷积后的像素层尺寸为4096*1*1,即有4096个神经元。
ReLU:这4096个运算结果通过ReLU激活函数生成4096个值
Dropout: 抑制过拟合,随机的断开某些神经元的连接或者是不激活某些神经元
总共的参数:(6*6*256+1)*4096=37752832
该层的流程为:全连接 -> ReLU -> Dropout
全连接:输入为4096的向量
ReLU: 这4096个运算结果通过ReLU激活函数生成4096个值
Dropout:抑制过拟合,随机的断开某些神经元的连接或者是不激活某些神经元
总共的参数:4096*4096+4096=16781312(每个神经元除了权值,还有一个偏置)
第七层输出的4096个数据与第八层的1000个神经元进行全连接,经过训练后输出1000个float型的值,这就是预测结果。
总共的参数:4096*1000+1000=4097000(每个神经元除了权值,还有一个偏置)
所有的参数加起来总数为:60965224,其中卷积层参数:2334080,占比总参数的3.83%;由此可见卷积神经网络对比全连接层的优势了,所花费的参数比全连接层少太多了,提高了训练速度以及运行效率。
参考博文:
卷积神经网络之AlexNet
详解深度学习之经典网络架构(二):AlexNet
深入理解AlexNet网络