当前位置: 首页 > 科技观察

【深度学习系列】用PaddlePaddle和Tensorflow实现GoogLeNetInceptionV2-V3-V5

时间:2023-03-12 19:59:09 科技观察

上一篇我们介绍了GoogLeNetInceptionV1的网络结构。在这篇文章中,我们将详细谈谈InceptionV2/V3/V4的开发。以及他们的网络结构和亮点。GoogLeNetInceptionV2GoogLeNetInceptionV2出现在《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》。亮点是BatchNormalization方法,它有以下作用:使用更大的学习率,而不用特别关注梯度爆炸或消失等优化问题;减少模型的效果取决于初始权重;可以加快收敛速度??,在一定程度上可以不用Dropout这种降低收敛速度的方法,但是起到了正则化的作用,提高了模型的泛化能力;即使不使用ReLU,也可以缓解激活函数饱和的问题;可以学习从当前层到下一层的分布缩放(scaling(variance),shift(expectation))系数。在机器学习中,我们通常会做一个假设:训练样本独立同分布(iid)且训练样本的分布与测试样本的分布一致。如果真实数据符合这个假设,模型效果可能就不错,反之亦然。这在学术上被称为CovariateShift,所以从样本(外部)的角度来看,神经网络也是如此。从结构(内部)的角度来看,由于神经网络是由多层组成的,因此样本在层与层之间提取特征的同时向前传播。如果每一层的输入分布不一致,必然导致要么模型效果不好,要么学习速度变慢,学术上这叫做InternalCovariateShift。假设:yy为样本标签,X={x1,x2,x3,...}X={x1,x2,x3,...}为神经网络输入经过几层后的样本xx;理论上:p(x,y)p(x,y)的联合概率分布应该与集合XX中任意层输入的联合概率分布一致,如:p(x,y)=p(x1,y)p(x,y)=p(x1,y);但是:p(x,y)=p(y|x)?p(x)p(x,y)=p(y|x)·p(x),其中条件概率p(y|x)p(y|x)是一致的,即p(y|x)=p(y|x1)=p(y|x1)=......p(y|x)=p(y|x1)=p(y|x1)=……,但是由于神经网络的每一层都改变了输入分布,导致边际概率不一致,即p(x)≠p(x1)≠p(x2)......p(x)≠p(x1)≠p(x2)......,即使随着网络深度的加深,前面层的小变化也会导致后面层的大变化层。  BN整个算法过程如下:batch模式训练,计算m个样本的期望和方差,然后对训练数据进行白化。通过白化操作,可以去除特征相关性,将数据在球体上进行缩放。的好处不仅可以加快优化算法的优化速度,还可以提高优化精度。一个直观的解释:    左边是没有白化的原始可行域,右边是有白化的可行域;当原始输入对模型学习更有利时,可以还原原始输入(类似于残差网络):    这里的参数γγ和σσ是需要学习的。  卷积神经网络BN  卷积网络采用权值共享策略,每个featuremap只有一对γγ和σσ需要学习。GoogLeNetInceptionV3GoogLeNetInceptionV3是在《Rethinking the Inception Architecture for Computer Vision》中提出的(注意,在这篇论文中,作者称网络结构为v2版本,我们以论文最终的v4版本为准)。这篇论文的亮点是:提出通用的网络结构设计指南引入卷积分解以提高效率引入高效的特征图降维网络结构设计指南如前所述,深度学习网络的探索更多是一门实验科学。在实验中,人们总结了一些结构设计指南,但老实说,我认为它不一定实用:避免特征表示的瓶颈,尤其是在神经网络的前几层。神经网络包含自动特征提取过程,如多层卷积,直观且符合常识理解:如果网络初始阶段特征提取过于粗糙,细节已经丢失,没有后续再细的结构,也无法有效表示;举个极端的例子:要区分宇宙中的一颗行星,一般是通过距离从近到远,从房屋、树木到海洋,从大陆板块到整个星球,然后进入整个宇宙。如果我们从头直接拉远到宇宙,你会发现所有的行星都是球体,分不清哪个是地球哪个是水星。因此,特征图的大小应该随着层数的加深逐渐减小,但是为了保证特征能够得到有效的表示和组合,通道的数量会逐渐增加。  下图违反了这个原则。一开始直接从35×35×320采样到17×17×320,特征细节丢失很多,即使后面有Inception做各种特征提取和组合。它也没有用。对于神经网络的某一层,更多的激活输出分支可以产生相互解耦的特征表示,从而产生高阶稀疏特征,从而加速收敛。注意下图中1×3和3×1的激活输出:合理使用降维不会破坏网络特征表示能力,但可以加快收敛速度??。通常,用两个3×3代替一个5×5的降维策略,不考虑padding,用两个3×3代替一个5×5,可以节省1-(3×3+3×3)/(5×5)=28%计算消耗。并用一个n×n的卷积核对两个1×n和n×1顺序相连的进行降维(有点像矩阵分解)。如果n=3,计算性能可以提升1-(3+3)/9=33%,但是如果考虑高性能计算性能,这种分解可能会导致L1cachemissrate增加。通过合理平衡网络的宽度和深度来优化网络计算消耗(这句话特别不实用)。采样降维。传统的采样方式是池化+卷积操作。为了防止特征表示的瓶颈,往往需要更多的卷积核。比如输入是n个d×d的featuremap,总共有k个卷积核。Pooling当stride=2时,为了避免特征表示瓶颈,k的取值往往是2n。通过引入初始模块结构,可以在没有特征表示瓶颈的情况下降低计算复杂度。实现方式有两种:  平滑样本标注一般是one-hot,用于多类样本标注,比如[0,0,0,1]。使用类似于交叉熵的损失函数,会使得模型学习中给groundtruth标签赋予过多置信度的概率,并且由于groundtruth标签的logit值与其他标签的logit值差距较大,导致过拟合,导致减少泛化。一种方案是加入一个正则项,即调整样本标签的概率分布,让样本标签变得“软”,比如[0.1,0.2,0.1,0.6],这种方法减少topin实验-1和top-5的错误率为0.2%。  网络结构GoogLeNetInceptionV4GoogLeNetInceptionV4/和ResNetV1/V2这三种结构在《Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning》一文中提出。论文的亮点在于:提出了更好的GoogLeNetInceptionv4网络结构;它与残差网络相结合,提出了一种不逊色于v4但训练速度更快的结构。GoogLeNetInceptionV4网络结构GoogLeNetInceptionResNet网络结构代码实践  Tensorflow代码在slim模块下有完整的实现,paddlepaddle可以参考上一篇写的inceptionv1代码来写。总结   这篇文章比较偏理论。主要讲了GoogLeNet的inception模块的发展,包括v2提出的batchnormalization,v3提出的volumeintegrationlevel和更通用的网络结构准则,v4提出的residual。不同的网络组合等。在实际应用过程中,可以将相同的数据用不同的网络结构跑起来看结果,实际体验不同网络结构的损失降低率和准确率提升。