卷积神经网络CNN里经典网络模型之 AlexNet全网最详解(理论篇)
1.背景
2. AlexNet模型结构
3. 特点(创新及新知识点)
一、背景
第一个典型的CNN是LeNet5网络,而第一个大放异彩的CNN却是AlexNet。2012年在全球知名的图像识别竞赛 ILSVRC 中,AlexNet 横空出世,直接将错误率降低了近 10 个百分点,这是之前所有机器学习模型无法做到的。
在计算机视觉领域目标检测和识别 通常用机器学习的方法来解决。为了提高识别的效果,我们以通过收集更多的可训练的数据来让模型的泛化性能提高。目前,在以一万为单位的数量级层面的数据(称为简单的识别任务)已经获得了非常好的性能,例如:MNIST 手写数字识别任务,最好的性能已经达到了<0.3%的误差。但是现实中的物体存在相当多的变化属性,所以学习识别它们需要更多的数据。事实上,小的图像训练数据有很多的缺点,无论以我们的直觉想还是理论证明都是有依据的,所以就有组织去收集这些现实中事物的图像并进行标记和分割。例如LabelMe包含了成百上千的全分割图像。 ImageNet包含15 million 标记的高分辨率图像,包含超过了22000种现实中的事物。ImageNet这样大的数据集也不能完美地解决这个问题,所以我们的模型也需要使用很多先验知识来弥补我们数据集不足的问题。**卷积神经网络(CNN)**就构成了一类这样的模型。它们的容量可以通过改变它们的深度和宽度来控制,并且它们也对图像的性质(即统计量的定态假设以及像素局部依赖性假设)做出准确而且全面的假设。因此,与具有相同大小的层的标准前馈神经网络相比,CNN具有更少的连接和参数,因此它们更容易训练,而其理论最优性能可能稍微弱一些。尽管CNN具有很好的质量,并且尽管其局部结构的效率相对较高,但将它们大规模应用于高分辨率图像时仍然显得非常昂贵。幸运的是,当前的GPU可以用于高度优化的二维卷积,能够加速许多大型CNN的训练,并且最近的数据集(如ImageNet)包含足够多的标记样本来训练此类模型,而不会出现严重的过度拟合。
ImageNet是一个拥有超过1500万个已标记高分辨率图像的数据集,大概有22,000个类别。图像都是从网上收集,并使用Amazon-Mechanical Turk群智工具人工标记。从2010年起,作为Pascal视觉对象挑战赛的一部分,这是每年举办一次的名为ImageNet大型视觉识别挑战赛(ILSVRC)的比赛。 ILSVRC使用的是ImageNet的一个子集,每1000个类别中大约有1000个图像。总共有大约120万张训练图像,50,000张验证图像和150,000张测试图像。ILSVRC-2010是ILSVRC中的唯一可以使用测试集标签的版本,因此这也正是我们进行大部分实验的版本。由于我们也在ILSVRC-2012比赛中引入了我们的模型,因此在第6部分中,我们也会给出此版本数据集的结果,尽管这个版本的测试集标签不可用。在ImageNet上,习惯上使用两种错误率:top-1和top-5,其中top-5错误率是正确标签不在被模型认为最可能的五个标签之中的测试图像的百分率。ImageNet由可变分辨率的图像组成,而我们的系统需要固定的输入尺寸。因此,我们将图像下采样到256×256的固定分辨率。给定一个矩形图像,我们首先重新缩放图像,使得短边长度为256,然后从结果中裁剪出中心的256×256的图片。除了将每个像素中减去训练集的像素均值之外,我们没有以任何其他方式对图像进行预处理。所以我们在像素的(中心)原始RGB值上训练了我们的网络。
二、AlexNet模型结构
1.原文网址:https://proceedings.neurips.cc/paper/2012/file/c399862d3b9d6b76c8436e924a68c45b-Paper.pdf
2.上面图AlexNet采用两路GTX 580 3GB GPU并行训练。也就是说把原先的卷积层平分成两部分FeatureMap分别在两块GPU上进行训练(例如卷积层55x55x96分成两个FeatureMap:55x55x48)
3.原论文中,AlexNet的输入图像尺寸是224x224x3。但是实际图像尺寸为227x227x3。据说224x224可能是写paper时候的手误?还是后来对网络又做了调整?具体不知道。下面是按我们在自己电脑上用一个GPU训练,所以核数量合在一起。
网络层中新的知识点在第三部分补出说明。
(1)网络结构层:该网络配置结构中各个层进行详细的解读(训练阶段)
网络层简介 | 输入 | 核数量----卷积窗口----填充—步长 | 输出----->激活函数 | 核数量x池化窗口----步长 | 在输出---->归一化 | 抑制过拟合的方法 |
---|---|---|---|---|---|---|
conv1层 | 227x227x3 彩色图像 | 使用96个(2组48个)11x11x3的卷积核进行卷积,padding=0,stride=4 | 55x55x96(两组48个) --卷积层输出的FeatureMap输入到ReLU函数中 | 最大池化3x3----步长2 | 27×27×96–>LRN局部响应归一化,尺度5x5 | 无 |
conv2层 | 27×27×96 | 使用256个(2组128个)5x5x48的卷积核进行卷积,padding=2,stride=1 | 27x27x256(两组128个) --卷积层输出的FeatureMap输入到ReLU函数中 | 最大池化(重叠池化)3x3----步长2 | 13×13×256–>LRN局部响应归一化,尺度5x5 | 无 |
conv3层 | 13×13×256 | 使用384个(2组192个)3x3x256的卷积核进行卷积,padding=1,stride=1 | 13x13x384(两组192个) --卷积层输出的FeatureMap输入到ReLU函数中 | 无池化 | 无归一化 | 无 |
conv4层 | 13×13×384 | 使用384个(2组192个)3x3x384的卷积核进行卷积,padding=1,stride=1 | 13x13x384(两组192个) --卷积层输出的FeatureMap输入到ReLU函数中 | 无池化 | 无 归一化 | 无 |
conv5层 | 13×13×384 | 使用256个(2组128个)3x3x256的卷积核进行卷积,padding=1,stride=1 | 13×13×256(两组128个) --卷积层输出的FeatureMap输入到ReLU函数中 | 最大池化(重叠池化)3x3----步长2 | 6×6×256–>无归一化 | 无 |
fc6全连接层 | 6×6×256 | 使用4096个(两组2048)6×6×256的卷积核进行卷积 | 1x1x4096(两组2048个)—4096个神经元的运算结果通过ReLU激活函数中 | 无池化 | 无归一化 | Dropout:随机的断开全连接层某些神经元的连接,通过不激活某些神经元的方式防止过拟合。drop运算后输出4096个本层的输出结果值 |
fc7全连接层 | 4096×1(4096个神经元) | 无 | 无-----4096个神经元的运算结果通过ReLU激活函数中 | 无池化 | 无归一化 | 4096个数据与第七层的4096个神经元进行全连接,然后经由relu7进行处理后生成4096个数据,再经过dropout7处理后输出4096个数据 |
Output(输出层) | 4096×1(4096个神经元) | 无 | 无—输出是1000个神经元 ,这1000个神经元即对应1000个检测类别。这1000个神经元的运算结果通过Softmax函数中,输出1000个类别对应的预测概率值。 | 无池化 | 无归一化 | 无 |
(2)网络参数
层数 | 定义 | 数量 |
---|---|---|
C1 | C1层的FeatureMap的神经元个数 | 55x55x48x2=290400 |
C2 | C2层的FeatureMap的神经元个数 | 27x27x128x2=186624 |
C3 | C3层的FeatureMap的神经元个数 | 13x13x192x2=64896 |
C4 | C4层的FeatureMap的神经元个数 | 13x13x192x2=64896 |
C5 | C5层的FeatureMap的神经元个数 | 13x13x128x2=43264 |
FC6 | FC6全连接层神经元个数 | 4096 |
FC7 | FC7全连接层神经元个数 | 4096 |
Output layer | 输出层神经元个数 | 1000 |
整个AlexNet网络包含的神经元个为:
290400 + 186624 + 64896 + 64896 + 43264 + 4096 + 4096 + 1000 = 659272
大约65万个神经元。
(3)AlexNet参数数量
层数 | 定义 | 数量 |
---|---|---|
C1 | 卷积核11x11x3,96个卷积核,偏置参数 | (11x11x3+1)x96=34944 |
C2 | 卷积核5x5x48,128个卷积核,2组,偏置参数 | (5x5x48+1)x128x2=307456 |
C3 | 卷积核3x3x256,384个卷积核,偏置参数 | (3x3x256+1)x384=885120 |
C4 | 卷积核3x3x192,192个卷积核,2组,偏置参数 | (3x3x192+1)x192x2=663936 |
C5 | 卷积核3x3x192,128个卷积核,2组,偏置参数 | (3x3x192+1)x128x2=442624 |
FC6 | 卷积核6x6x256,4096个神经元,偏置参数 | (6x6x256+1)x4096=37752832 |
FC7 | 全连接层,4096个神经元,偏置参数 | (4096+1)x4096=16781312 |
Output layer | 全连接层,1000个神经元 | 1000x4096=4096000 |
整个AlexNet网络包含的参数数量为:
34944 + 307456 + 885120 + 663936 + 442624 + 37752832 + 16781312 + 4096000 = 60964224
大约6千万个参数。
三、特点(创新点,新知识点)
AlexNet的特点:
1.使用ReLu作为激活函数
2.数据增广(Data Augmentation增强)抑制过拟合
3.使用Dropout抑制过拟合
4.重叠池化
5.局部归一化(Local Response Normalization,简称 LRN)
6.多GPU训练
1.使用ReLu作为激活函数
传统的神经网络普遍使用 Sigmoid 或者 tanh 等非线性函数作为激励函数,然而它们容易出现梯度弥散或梯度饱和的情况。以 Sigmoid 函数为例,当输入的值非常大或者非常小的时候,这些神经元的梯度接近于 0(梯度饱和现象),如果输入的初始值很大的话,梯度在反向传播时因为需要乘上一个 Sigmoid 导数,会造成梯度越来越小,导致网络变的很难学习。在最初的感知机模型中,输入和输出的关系如下:y=∑i wixi+b只是单纯的线性关系,这样的网络结构有很大的局限性:即使用很多这样结构的网络层叠加,其输出和输入仍然是线性关系,无法处理有非线性关系的输入输出。因此,对每个神经元的输出做个非线性的转换也就是,将上面就加权求和∑i wixi+b的结果输入到一个非线性函数,也就是激活函数中。 这样,由于激活函数的引入,多个网络层的叠加就不再是单纯的线性变换,而是具有更强的表现能力。
在网络层数较少时,sigmoid函数的特性能够很好的满足激活函数的作用:它把一个实数压缩至0到1之间,当输入的数字非常大的时候,结果会接近1;当输入非常大的负数时,则会得到接近0的结果。这种特性,能够很好的模拟神经元在受刺激后,是否被激活向后传递信息(输出为0,几乎不被激活;输出为1,完全被激活)。
sigmoid一个很大的问题就是梯度饱和。 观察sigmoid函数的曲线,当输入的数字较大(或较小)时,其函数值趋于不变,其导数变的非常的小。这样,在层数很多的的网络结构中,进行反向传播时,由于很多个很小的sigmoid导数累成,导致其结果趋于0,权值更新较慢。
针对sigmoid梯度饱和导致训练收敛慢的问题,在AlexNet中引入了ReLU。ReLU是一个分段线性函数,小于等于0则输出为0;大于0的则恒等输出。相比于sigmoid,ReLU有以下有点:
(1)计算开销下。sigmoid的正向传播有指数运算,倒数运算,而ReLu是线性输出;反向传播中,sigmoid有指数运算,而ReLU有输出的部分,导数始终为1.
(2)梯度饱和问题
(3)稀疏性。Relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生。
这里有个问题,前面提到,激活函数要用非线性的,是为了使网络结构有更强的表达的能力。那这里使用ReLU本质上却是个线性的分段函数,是怎么进行非线性变换的。
这里把神经网络看着一个巨大的变换矩阵M,其输入为所有训练样本组成的矩阵A,输出为矩阵B。B=M⋅A这里的M是一个线性变换的话,则所有的训练样本A进行了线性变换输出为B。那么对于ReLU来说,由于其是分段的,0的部分可以看着神经元没有激活,不同的神经元激活或者不激活,其神经玩过组成的变换矩阵是不一样的。设有两个训练样本 a1,a2,其训练时神经网络组成的变换矩阵为M1,M2。 由于M1变换对应的神经网络中激活神经元和M2是不一样的,这样M1,M2实际上是两个不同的线性变换。也就是说,每个训练样本使用的线性变换矩阵Mi是不一样的,在整个训练样本空间来说,其经历的是非线性变换。简单来说,不同训练样本中的同样的特征,在经过神经网络学习时,流经的神经元是不一样的(激活函数值为0的神经元不会被激活)。这样,最终的输出实际上是输入样本的非线性变换。单个训练样本是线性变换,但是每个训练样本的线性变换是不一样的,这样整个训练样本集来说,就是非线性的变换。
ReLU函数是一个分段线性函数,小于等于0则输出0;大于0的则恒等输出。反向传播中,ReLU有输出的部分,导数始终为1。而且ReLU会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生。
2.数据增广(Data Augmentation增强)抑制过拟合
早期最常见的针对图像数据减少过拟合的方法就是人工地增大数据集,AlexNet中使用了两种增大数据量的方法(镜像反射、随机剪裁和改变训练样本RGB通道的强度值)
神经网络由于训练的参数多,表能能力强,所以需要比较多的数据量,不然很容易过拟合。当训练数据有限时,可以通过一些变换从已有的训练数据集中生成一些新的数据,以快速地扩充训练数据。对于图像数据集来说,可以对图像进行一些形变操作:翻转、随机裁剪、平移、颜色光照的变换
如AlexNet中对数据做了以下操作:
(1)随机裁剪,对256×256的图片进行随机裁剪到227×227,然后进行水平翻转。
(2)测试的时候,对左上、右上、左下、右下、中间分别做了5次裁剪,然后翻转,共10个裁剪,之后对结果求平均。
(3)对RGB空间做PCA(主成分分析),然后对主成分做一个(0, 0.1)的高斯扰动,也就是对颜色、光照作变换,结果使错误率又下降了1%。
先对图像做镜像反射
然后在原图和镜像反射的图(256×256)中随机抽取227×227的块.
3.使用Dropout抑制过拟合
Dropout也是经常说的一个概念,能够比较有效地防止神经网络的过拟合。 相对于一般如线性模型使用正则的方法来防止模型过拟合,而在神经网络中Dropout通过修改神经网络本身结构来实现。对于某一层神经元,通过定义的概率来随机删除一些神经元,同时保持输入层与输出层神经元的个数不变,然后按照神经网络的学习方法进行参数更新,下一次迭代中,重新随机删除一些神经元,直至训练结束。
4.重叠池化
在以前的CNN中普遍使用平均池化层(average pooling),AlexNet全部使用最大池化层 max pooling。一般的池化(Pooling)是不重叠的,池化区域的窗口大小与步长相同.在LeNet中池化是不重叠的,即池化的窗口的大小和步长是相等的,如下图
在 AlexNet 中使用的池化(Pooling)却是可重叠的,也就是说,在池化的时候,每次移动的步长小于池化的窗口长度。AlexNet 池化的大小为 3×3 的正方形,每次池化移动步长为 2,这样就会出现重叠。重叠池化可以避免过拟合,这个策略贡献了 0.3% 的 Top-5 错误率。
5.局部归一化(Local Response Normalization,简称 LRN)
在神经生物学有一个概念叫做 “侧抑制”(lateral inhibitio),指的是被激活的神经元抑制相邻神经元。归一化(normalization)的目的是 “抑制”,局部归一化就是借鉴了 “侧抑制” 的思想来实现局部抑制,尤其当使用 ReLU 时这种 “侧抑制” 很管用,因为 ReLU 的响应结果是无界的(可以非常大),所以需要归一化。使用局部归一化的方案有助于增加泛化能力。
(2)训练时使用Dropout随机忽略一部分神经元,以避免模型过拟合。Dropout虽有单独的论文论述,但是AlexNet将其实用化,通过实践证实了它的效果。在AlexNet中主要是最后几个全连接层使用了Dropout。
(3)在CNN中使用重叠的最大池化。此前CNN中普遍使用平均池化,AlexNet全部使用最大池化,避免平均池化的模糊化效果。并且AlexNet中提出让步长比池化核的尺寸小,这样池化层的输出之间会有重叠和覆盖,提升了特征的丰富性。
(4)提出了LRN层,对局部神经元的活动创建竞争机制,使得其中响应比较大的值变得相对更大,并抑制其他反馈较小的神经元,增强了模型的泛化能力。
(5)使用CUDA加速深度卷积网络的训练,利用GPU强大的并行计算能力,处理神经网络训练时大量的矩阵运算。AlexNet使用了两块GTX 580 GPU进行训练,单个GTX 580只有3GB显存,这限制了可训练的网络的最大规模。因此作者将AlexNet分布在两个GPU上,在每个GPU的显存中储存一半的神经元的参数。因为GPU之间通信方便,可以互相访问显存,而不需要通过主机内存,所以同时使用多块GPU也是非常高效的。同时,AlexNet的设计让GPU之间的通信只在网络的某些层进行,控制了通信的性能损耗。
6.多GPU训练
AlexNet 当时使用了 GTX580 的 GPU 进行训练,由于单个 GTX 580 GPU 只有 3GB 内存,这限制了在其上训练的网络的最大规模,因此他们在每个 GPU 中放置一半核(或神经元),将网络分布在两个 GPU 上进行并行计算,大大加快了 AlexNet 的训练速度。