【DeepLearning】AlexNet
在前文中,我们介绍了LeNet的相关细节,它是由两个卷积层、两个池化层以及两个全链接层组成。卷积都是5*5的模板,stride =1,池化为MAX。整体来说它有三大特点:局部感受野,权值共享和池化。2012年ALex发布了AlexNet,他比LeNet5更深,而且可以学习更复杂的图像高维特征。接下来,我们就将一起学习AlexNet模型。
论文原文: ImageNet Classification with Deep Convolutional Neural Networks
论文翻译:AlexNet论文翻译——中文版
## AlexNet模型的trick
AlexNet之所以能够成功,跟这个模型设计的特点有关,主要有:
- 使用了非线性激活函数:ReLU
- 重叠池化
- 防止过拟合的方法:Dropout,数据扩充(Data augmentation)
- 多GPU训练
- LRN局部归一化
【ReLU激活函数】
通俗上讲,激励函数的作用就是将多个线性输入转换为非线性的关系。通过激励函数引入非线性因素后,使神经网络的表示能力更强了。在前人的模型中,常常使用Sigmoid或tanh等非线性函数作为激活函数,然而他们容易出现梯度弥散或梯度爆炸的问题。
ReLU是修正线性单元(The Rectified Linear Unit)的简称,其函数图像如下,该函数的公式为:f(x)=max(0,x),当输入信号<0时,输出都是0,当输入信号>0时,输出等于输入,如下图所示:
运用ReLU函数可以有效的缓解梯度弥散的问题,相对于sigmoid和tanh激励函数,对ReLU求梯度非常简单,计算也很简单,可以非常大程度地提升随机梯度下降的收敛速度。实验结果表明,要将深度网络训练至training error rate达到25%的话,ReLU只需5个epochs的迭代,但tanh单元需要35个epochs的迭代,用ReLU比tanh快6倍。
【重叠的最大池化】
在LeNet中,池化使不重复的,池化的窗口大小与步长相等,大小直接减半。但在AlexNet中使用的池化(Pooling)却是可重叠的,也就是说,在池化的时候,每次移动的步长小于池化的窗口长度。AlexNet池化的大小为3×3的正方形,每次池化移动步长为2,这样就会出现重叠。重叠池化可以避免过拟合。
此外,此前CNN中普遍使用平均池化,AlexNet全部使用最大池化,避免平均池化的模糊化效果。
【避免过拟合——数据扩充】
数据量的增加可以有效的提升算法的准确度,避免过拟合;也可以适应更大更深的网络结构。而AlexNet在训练时,就按照下述的方法进行数据扩充:
(1)随机裁剪,对256×256的图片进行随机裁剪到224×224,然后进行水平翻转,相当于将样本数量增加了((256-224+1)^2)×2倍;(感谢 路人丙二十六 的指正)在测试的时候,对左上、右上、左下、右下、中间分别做了5次裁剪,然后翻转,共10个裁剪,之后对结果求平均。
(2)对RGB空间做PCA(主成分分析),然后对主成分做一个(0, 0.1)的高斯扰动,也就是对颜色、光照作变换,结果使错误率又下降了1%。
【避免过拟合——Dropout】
一般而言,解决的过拟合主要方法有:增加训练数据量、减少模型的复杂度、添加正则项等。在深度学习中,以上方法都可以使用,但是dropout是一个更加高效、简单的防止过拟合的方法。
dropout是指在深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃。Dropout也可以看成是一种模型组合,每次生成的网络结构都不一样,通过组合多个模型的方式能够有效地减少过拟合。
但值得注意的是,dropout对于具有大量参数的全连接效果最好,而且一般人为设置为0.5或者0.3(链接讲不同层代码试验),而在卷积隐藏层由于卷积自身的稀疏化以及稀疏化的ReLu函数的大量使用等原因,Dropout策略在卷积隐藏层中使用较少。
【局部响应归一化(Local Response Normalization,简称LRN)】
LRN是借鉴生物学中“侧抑制”的思想来实现局部抑制,尤其对于RELU函数,这样的侧抑制是很管用的,因为RELU是无界的,这样的归一化有助于增强泛化能力,LRN的公式如下,核心思想就是利用邻近的数据进行归一化。
【多GPU训练】
AlexNet当时使用了GTX580的GPU进行训练,由于单个GTX 580 GPU只有3GB内存,这限制了在其上训练的网络的最大规模,因此他们在每个GPU中放置一半核(或神经元),将网络分布在两个GPU上进行并行计算,大大加快了AlexNet的训练速度。
## 整体架构
整体架构是本文的精髓,废话不多说,直接莽。
总体概述如下:
AlexNet网络结构共有8层,前面5层是卷积层,后面3层是全连接层,最后一个全连接层的输出传递给一个1000路的softmax层,对应1000个类标签的分布。
由于AlexNet采用了两个GPU进行训练,因此,该网络结构图由上下两部分组成,一个GPU运行图上方的层,另一个运行图下方的层,两个GPU只在特定的层通信。例如第二、四、五层卷积层的核只和同一个GPU上的前一层的核特征图相连,第三层卷积层和第二层所有的核特征图相连接,全连接层中的神经元和前一层中的所有神经元相连接。
卷积核大小数量、trick的使用情况如下:
- conv1: 96@11*11*3
- conv2: 256@5*5*48
- conv3: 384@3*3*256
- conv4: 384@3*3*192
- conv5: 256@3*3*192
- ReLU、双GPU运算:提高训练速度。(应用于所有卷积层和全连接层)
- 重叠pool池化层:提高精度,不容易产生过度拟合。(应用在第一层,第二层,第五层后面)
- 局部响应归一化层(LRN):增强泛化能力。(应用在第一层和第二层后面)
- Dropout:减少过度拟合。(应用在前两个全连接层)
接下来就逐层解释AlexNet的结构:
【第一层 conv1】
1. 卷积
第一层输入数据为原始的227×227×3的图像,在本层中被96个11×11×3的卷积核进行卷积运算。由于采用两个GPU并行运算,因此上下两部分分别承担48个卷积核的运算。卷积核移动的步长是4个像素,no-padding。因此,conv1输出的每一个特征图有(227-11)/4+1=55个像素,一共96层。
2. ReLU
卷积后的55×55像素层经过ReLU单元的处理,生成激活像素层,尺寸仍为2组55×55×48的像素层数据。
3. Pooling
池化层的核尺寸为3×3,步长为2,故池化后的规模为 (55-3)/2+1=27,即池化后像素的规模为27×27×96。
4. 归一化(LRN)
池化后的像素层再进行归一化处理,归一化运算的尺寸为5×5,归一化后的像素规模不变,仍为27×27×96,这96层像素层被分为两组,每组48个像素层,分别在两个独立的GPU上进行运算。
【第二层 conv2】
该层与第一层类似,处理流程为:卷积-->ReLU-->池化-->归一化
1. 卷积
第二层的输入数据为第一层输出的27×27×96的像素层,padding =2 。第二层的卷积核大小为5×5,移动步长为1个像素,经卷积核计算后的像素层大小变为 (27+2+2-5)/1+1=27,即卷积后大小为27×27。本层使用了256个5×5×48的卷积核,同样也是被分成两组,每组为128个,分给两个GPU进行卷积运算,结果生成两组27×27×128个卷积后的像素层。
2. ReLU
卷积后的27×27像素层经过ReLU单元的处理,生成激活像素层,尺寸仍为2组27×27×128的像素层数据。
3. Pooling
池化层的核尺寸为3×3,步长为2,故池化后的规模为 (27-3)/2+1=13,即池化后像素的规模为13×13×128。
4. 归一化(LRN)
池化后的像素层再进行归一化处理,归一化运算的尺寸为5×5,归一化后的像素层的规模为2组13×13×128的像素层,分别由2个GPU进行运算。
【第三层 conv3】
第三层的处理流程是:卷积-->ReLU
1. 卷积
第三层输入数据为第二层输出的2组13×13×128的像素层,padding=1。使用192个3×3×256的卷积核,对两组像素层的所有数据进行卷积运算,卷积的步长为1,经过卷积运算后的尺寸为(13+1+1-3)/1+1=13,即每个GPU中共13×13×192个卷积核,2个GPU生成13×13×384的像素层。
2. ReLU
卷积后的像素层经过ReLU单元的处理,生成激活像素层,尺寸仍为2组13×13×192的像素层,分配给两组GPU处理。
【第四层 conv4】
与第三层类似,第四层的处理流程是:卷积-->ReLU
1. 卷积
第四层输入数据为第三层输出的2组13×13×192的像素层,padding=1。每个CPU使用192个3×3×192的卷积核,在该层中没有GPU之间的通信,卷积的步长为1,经过卷积运算后的尺寸为(13+1+1-3)/1+1=13,即每个GPU中共13×13×192个卷积核,2个GPU生成13×13×384的像素层。
2. ReLU
卷积后的像素层经过ReLU单元的处理,生成激活像素层,尺寸仍为2组13×13×192的像素层,分配给两组GPU处理。
【第五层 conv5】
第五层的处理流程为:卷积-->ReLU-->池化
1. 卷积
第五层输入数据为第四层输出的2组13×13×192的像素层,padding = 1,该层上每个CPU都有28个卷积核,每个卷积核的尺寸为3×3×192,步长为1,卷积后每个CPU共有13×13×128个卷积核,2个GPU卷积后生成13×13×256的像素层
2. ReLU
卷积后的像素层经过ReLU单元处理,生成激活像素层,尺寸仍为2组13×13×128像素层,由两个GPU分别处理。
3.Pooling
2组13×13×128像素层分别在2个不同GPU中进行池化运算处理,池化运算的尺寸为3×3,步长为2,池化后图像的尺寸为 (13-3)/2+1=6,即池化后像素的规模为两组6×6×128的像素层数据,共有6×6×256的像素层数据。
【第六层 fc6】
第六层的处理流程为:卷积(全连接)-->ReLU-->Dropout
1. 全连接
第六层输入数据是第五层的输出,尺寸为6×6×256。本层共有4096个卷积核,每个卷积核的尺寸为6×6×256,由于卷积核的尺寸刚好与待处理特征图(输入)的尺寸相同,即卷积核中的每个系数只与特征图(输入)尺寸的一个像素值相乘,一一对应,因此,该层被称为全连接层。由于卷积核与特征图的尺寸相同,卷积运算后只有一个值,因此,卷积后的像素层尺寸为4096@1×1,即有4096个神经元。
2.ReLU
这4096个运算结果通过ReLU激活函数生成4096个值。
3.Dropout
然后再通过Dropout运算,输出4096个结果值。
【第七层 fc7】
第六层输出的4096个数据与第七层的4096个神经元进行全连接,然后经由relu7进行处理后生成4096个数据,再经过dropout7处理后输出4096个数据。
【第八层 fc8】
第七层输出的4096个数据与第八层的1000个神经元进行全连接,经过训练后输出被训练的数值。
## Tensorflow实现
在Tensorflow的示例中有该模型的实现,链接如下:https://github.com/tensorflow/models/blob/master/tutorials/image/alexnet/alexnet_benchmark.py