它乍看上去像是蛮复杂的,但细看其结构就会发现它其实就是用一个个Inception module给堆起来的。它的设计充满了科学理论与工程实践的结合,是一个典型的data scientist与软件工程师结合搞出来的东东。
在此之前经典的CNN模型像LeNet/Alexnet/VGG等无不是一个模子即使用Conv/Pool/Normalization/Activation等层来不断累积而成。模型对数据集概率分布的表达能力则往往通过单纯增加模型的深度(层数)或宽度(层的channels数)来提高(当然这也亦是当下深度学习领域的共识)。但这样进行网络设计一般会等来巨量的计算开销,因为每一层channels数目的增加都会随着层深而指数级增加,这大大地限制了模型的实际应用。
GoogleNet团队在考虑网络设计时不只注重增加模型的分类精度,同时也考虑了其可能的计算与内存使用开销。他们借鉴了诸多前人的观点与经验(尤其是Network in Network中使用1x1 conv及AvgPool的idea),想通过一种spared layer architecture来实现较优的多维度特征表达,然后通过对这种结构进行叠加,中间不时再插入一些MaxPool层以减少参数数目(从而节省内存与计算开销),最终就行成了Inception v1分类模型。它作为2014年ILSVRC图像分类大赛中的最优选手,取得了非常大的成功。后来GoogleNet团队再接再厉接连提出了融入更新思想,同时分类精度也更高的Inception v2/Inception v3/Inception v4及Inception-Resnet等模型,从而将Inception的思想推至了当下的巅峰。此是后话,欲知Inception系列模型的渊源还是须从这个最早的Inception v1开始。
传统的CNN模型设计,其能力增加往往通过增加层数及增宽层的通道数来实现。但这会带来两个问题,首先这两种设计思路都是在高密度计算的单元上(如FC层/Conv层)实现的,它会带来大量的训练参数增加,而过多的参数往往意味着容易出现过拟合;其次单纯曾加密集计算单元的层数或每层宽度都会招至后须扩展的指数级的计算量增加。
显然通过使用一种稀疏的层次结构而非使用像FC/Conv这样的全级联式的结构有助于计算开销的降低。而且一旦这种稀疏的结构设计良好可以有效地扩大表达特征的范围,从而更有效地对图片信息进行表达。可过于稀疏的结构计算一般都不大高效(当下用于CPU/GPU上的一些高效加速库多是在密集计算上进行优化的),同时也会带来较多的cache miss及内存地址非连续搜索的overhead。最终GoogleNet团队选择了中间路线即使用由密集计算子结构组合而成的稀疏模块来用于特征提取及表达,这就是用于构建Inception v1的Inception module如下图中a所示。
其中1x1/3x3/5x5这三种Conv kernels的选择决定是基于方便(因为这几种kernels用的多啊,而且比较容易对齐,padding)来定的(汗)。
图a的这个基本module显然在计算开销上隐藏着重大问题即它的输出将每个不同尺度的conv的输出级连起来用于下一个module的输入。这势必会招至计算量的指数级增加。因此作者借鉴Network in Network中的idea,在每个子conv层里使用了1x1的conv来作上一层的输入feature maps的channels数缩减、归总。如此每个Inception module里的计算都由各自的1x1 conv来隔离,从而不会像传统CNN深度模型那样随着深度增加其计算量也指数级增加。这就是最终用于构建Inception 网络的基础模块inception即图b。
上表即为GoogleNet的网络结构设计概况。可以看出并非整个网络都是由Inception module来组成。它的前面几层采用了类似于经典网络的那种单尺度Conv/Pool/ReLu的设计,这主要是出于用于进行模型计算的系统架构的实际考虑。
作者表明我们可以灵活地根据自己所有的硬件/软件/系统等情况来选择Inception网络中各模块的使用(modules数目及其上的conv的channels数)。而上表所列的这个有着22个参数层的GoogleNet只是在作者他们实验所用的机器上得到的较优网络。因此我们不必过于拘泥于它的具体实现细节,只需了解它的本质设计思想即可。
模型的最后会选通过一个AvgPool层来处理最终的feature maps,然后再由FC层汇总生成1000个输出,进而由Softmax来得到1000类的概率分布。随着CNN模型的加深,它最终表达的特征也愈加地抽象,只使用最后层次的特征可能会招至对小尺度目标的忽略,因此作者分别在中间及较靠后层的地方插入了两个独立的分类层以在训练时协同发挥影响。下图即为最终的GoogleNet模型。
这算是当时最为复杂的模型了,多达22层。它的训练难度显然也是空前的。作者使用他们内部的DistBelief分布式系统对模型进行训练,中间使用了模型并行与数据并行两种多节点并行方式(这个难度其实还是蛮高的,玩过多节点训练的人都懂!)。另外他们还使用了Async sgd的方式进行模型参数更新(这使得模型的训练难度更是增加了,没办法估计他们当时也是觉着训练时间实在太久了,所以才会选择使用Async sgd这种加速收敛的方式吧)。
此外作者使用了集成多个模型(6个结构相同,1个略不同;相用相同的初始化,只是不同的shuffle过的数据集)来提高分类准确率的做法。同时也使用了像resize/不同scales/镜像及color distortation等多种数据增强的方式。
下表中即为GoogleNet网络与其它模型的结果对比。
当下大多数的经典模型都已经在Intel caffe里面有了良好实现。我们甚至不需要GPU,单单用自己家datacenter里面的CPUs也能玩转下模型训练及推理。
下面为data layer层,与VGG等的并无差别。
以下数层则为网络中inception_3a 模块的组成情况。
最后则是其AvgPool/DropOut/FC的使用。及最终所生成的loss与accuracy top-1/top-5实现。
LeNet:最早用于数字识别的CNN
C1层是一个卷积层
6个特征图,每个特征图中的每个神经元与输入中5 5的邻域相连,特征图大小为28 28
每个卷积神经元的参数数目:5*5=25个weight参数和一个bias参数
链接数目:(5 5+1) 6 (28 28)=122304个链接
参数共享:每个特征图内共享参数,因此参数总数:共(5 5 1)*6=156个参数
S2层是一个下采样层
6个14 14的特征图,每个图中的每个单元与C1特征图中的一个2 2邻域相连接,不重叠。
和max pooling和average pooling不一样,在S2层中每个单元的4个输入相加,乘以一个可训练参数w,再加上一个可训练偏置b,结果通过sigmoid函数计算得到最终池化之后的值。
连接数:(2 2+1) 1 14 14*6=5880个
参数共享:每个特征图内共享参数,因此有2*6=12个可训练参数
C3层是一个卷积层
16个卷积核,得到16张特征图,特征图大小为10*10
每个特征图中的每个神经元与S2中某几层的多个5*5的邻域相连;
例如:对于C3层第0张特征图,其每一个节点与S2层的第0~2张特征图,总共3个5*5个节点相连接。
S4层是一个下采样层(和S2一样)
由16个5 5大小的特征图构成,特征图中的每个单元与C3中相应特征图的2 2邻域相连接。
连接数:(2 2+1) 5 5 16=2000个
参数共享:特征图内共享参数,每个特征图中的每个神经元需要1个因子和一个偏置,因此有2*16个可训练参数。
C5层是一个卷积层
120个神经元,可以看作120个特征图,每张特征图的大小为1*1
每个单元与S4层的全部16个单元的5*5邻域相连(S4和C5之间的全连接)
连接数=可训练参数:(5 5 16+1)*120=48120个
F6层是一个全连接层
有84个单元,与C5层全连接。
F6层计算输入向量和权重向量之间的点积,再加上一个偏置(wx+b),最后将加权值做一个sigmoid转换。
连接数=可训练参数:(120+1)*84=10164
这里选择84作为神经元的数目从论文中可以认为是:ASCII字符标准的打印字符,是用7 12大小的位图,这里希望每一维特征分别体现标准7 12大小位图上每一个像素点的特性。
F7层是一个输出层
输出层是由欧式径向基函数(RBF)组成。每一个输出对应一个RBF函数,每一个RBF函数都有84维的输入向量,RBF的函数公式如下。每一个RBF函数都会有一个输出,最后输出层会输出一个10维的向量。
AlexNet:2012年ILSVRC比赛冠军,远超第二名的CNN,比LeNet更深,用多层小卷积叠加来替换单个的大卷积
**AlexNet结构优化 **
非线性激活函数:ReLU
使用Max Pooling,并且提出池化核和步长,使池化核之间存在重叠,提升了特征的丰富性。 防止过拟合的方法:Dropout,Data augmentation(数据增强)
大数据训练:百万级ImageNet图像数据
GPU实现:在每个GPU中放置一半核(或神经元),还有一个额外的技巧:GPU间的通讯只在某些层进行。 LRN归一化:对局部神经元的活动创建了竞争机制,使得其中响应比较大的值变得相对更大,并抑制其它反馈较小的神经元,增强了模型的泛化能力。本质上,LRN是仿造生物学上活跃的神经元对于相邻神经元的抑制现象(侧抑制)
ZF Net:2013ILSVRC冠军
基于AlexNet进行微调
修改窗口大小和步长
使用稠密单GPU的网络结构替换AlexNet的稀疏双GPU结构
Top5错误率11.2%
使用ReLU激活函数和交叉熵损失函数
GoogleNet:2014ILSVRC冠军
Top5错误率6.7%;使用9个inception模块,改变CNN原串行结构,并行,共22层;使用平均池化替代FC层;参数量仅为AlexNet的1/12;使用softmax获取平均结果;网络结构的更新,性能比AlexNet要好;2014年ILSVRC冠军
Inception-v1
橙色框是 stem(左边的方框),包含一些初始卷积。紫色框是辅助分类器。较宽的部分是 inception 模块
由于网络较深,为了阻止该网络中间部分梯度的「消失」问题,V1引入了两个辅助分类器(上图紫色框)。它们对其中两个 Inception 模块的输出执行 softmax *** 作,然后在同样的标签上计算辅助损失。总损失即辅助损失和真实损失的加权和。该论文中对每个辅助损失使用的权重值是 0.3。
辅助loss只用于训练,不用于推理。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)