【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

 

posted @ 2019-07-16 12:42  HongmingYou  阅读(343)  评论(0编辑  收藏  举报