美文网首页tensorflow相关GoogleNet
GoogLeNet的心路历程(二)

GoogLeNet的心路历程(二)

作者: Traphix | 来源:发表于2016-07-21 16:39 被阅读5228次

    本文介绍关于GoogLeNet第一篇正式论文,习惯称为inception v1,如下:

    在开始介绍论文之前,先说一些题外话,GoogLeNet这个名字的诞生由两方面促成,一是设计者在Google工作,二是向LeNet致敬。GoogLeNet只是一个名字,它的核心内容是发明了Inception Architecture(以下简称IA),发明IA的灵感来自于2013年的一篇论文《Provable Bounds for Learning Some Deep Representations》,这篇论文读起来非常困难,需要很多的数学知识,有兴趣的可以看看。

    一、inception v1的主要贡献

    • 1、提出inception architecture并对其优化
    • 2、取消全连层
    • 3、运用auxiliary classifiers加速网络converge

    接下来对以上几点分别介绍。

    二、Inception architecture

    首先得说一下Szegedy发明IA的动机,他估计是在某天阅读了Provable Bounds for Learning Some Deep Representations这篇论文,又结合自己多年来在深度学习界摸爬滚打的经验,发现传统的提高网络精度的方法是一条邪路(P.S. 传统的方法指的是 扩大网络规模 或 增大训练数据集),而想从本质上提高网络性能,就得用sparsely connected architectures,即“稀疏连接结构”。

    我自己对“稀疏连接结构”的理解是这样的,用尽可能的“小”、“分散”的可堆叠的网络结构,去学习复杂的分类任务,怎么体现“小”、“分散”呢?如下图:


    Inception Architecture,naive version

    原来造神经网络,都是一条线下来,我们可以回想一下AlexNet、VGG等著名网络,而IA是“分叉-汇聚”型网络,也就是说在一层网络中存在多个不同尺度的kernels,卷积完毕后再汇聚,为了更好理解,“汇聚”的tensorflow代码写出来是这样的:

    net = tf.concat(3, [branch1x1, branch5x5, branch3x3, branch_pool])
    

    就是简单的在kernel维度把矩阵concatenate起来。但是这么做有一个问题,会产生“维度爆炸”,什么意思呢?假如branch1x1、branch3x3、branch5x5都有256个kernels,加上branch_pool的kernels(假定为256),经过tf.concat操作,最终的kernels是256×4=1024个kernels!这没法接受啊!如果多层IA叠加起来,那kernels的数量岂不上天!!于是Szegedy就改进了一下,如下图:

    Inception module with dimension reductions
    他加入了kernels数量控制方式,就是那些1×1的卷积层,这些1×1的卷积层输出kernels会比上一层要少,这样即便在经过tf.concat以后,总kernels数量不会增加太多。另外,这些1×1的卷积层还增加了网络的非线性程度。

    关于IA的结构就介绍完了,可是,为什么?这样的结构有啥用?Szegedy在论文里解释过一点点:IA之所以能提高网络精度,可能就是归功于它拥有多个不同尺度的kernels,每一个尺度的kernel会学习不同的特征,把这些不同kernels学习到的特征汇聚给下一层,能够更好的实现全方位的深度学习!

    三、取消全连层

    为什么VGG网络的参数那么多?就是因为它在最后有两个4096的全连层!Szegedy吸取了教训,为了压缩GoogLeNet的网络参数,他把全连层取消了!其实我个人也认为全连层作用确实没那么大,取消了也好,GoogLeNet网络详细配置如下:


    GoogLeNet详细配置

    从上图就可以看出,网络的最后几层是avg pool、dropout、linear和softmax,没有看到fully connect的影子。现在取消全连层貌似是个大趋势,近两年的优秀大型神经网络都没有全连层,可能是全连层参数太多,网络深度增加了以后,难以接受吧

    四、Auxiliary classifiers

    搞机器学习的都知道,梯度消散是所有深层网络的通病,往往训练到最后,网络最开始的几层就“训不动了”!于是Szegedy加入了auxiliary classifiers(简称AC),用于辅助训练,加速网络converge,如下图画红框部分:

    GoogLeNet
    以上图片摘自此文,因为网络太深了,竖着太长,就把它横过来看了。可以看到,笔者在网络中间层加入了两个AC,这两个AC在训练的时候也跟着学习,同时把自己学习到的梯度反馈给网络,算上网络最后一层的梯度反馈,GoogLeNet一共有3个“梯度提供商”,先不说这么做有没有问题,它确实提高了网络收敛的速度,因为梯度大了嘛。另外,GoogLeNet在做inference的时候AC是要被摘掉的。

    AC这种加速收敛训练方式与ResNet表面上看不太一样,但是我感觉本质上应该是类似的。ResNet也很深,但是它先是通过构建浅层网络学习参数,再把浅层网络的参数应用到较深网络中,从而尽可能减少梯度消散的影响。GoogLeNet是直接把浅层网络的训练和深层网络的训练揉到一起了。关于这个问题还有待深究。

    相关文章

      网友评论

      • 会飞的咸鱼Tank:好文,实质性地解决了一些疑问
      • d63569e90e60:请问,googlenet v1的输入是文中的224×224么?怎么看有的代码是227×227
      • 9c0ecdf615c9:原文写的是We found that a move from fully connected layers to average pooling improved the top-1 accuracy by about 0.6%.
        比如对比AlexNet,是两个全连接(中间有个dropout),Inception的这个去除FC只是去掉一个全连接,用最后一个pooling代替。
        而且看例图如Fig.3 最后在softmax前已经标注好有FC的。
        我的理解是 linear就是FC,请看parameters个数,上接1*1*1024 的 1*1 *1000 的参数个数是1000K(1000*1024),不是FC是啥捏?
        torch里的 nn.linear 我认为就是FC。
        cab5beaee3a4:对呢,我也是觉得这里有待商榷呢,从参数的数量来看感觉就像是一个FC呢
      • Horan_Cai:就算在之前加入了1*1的卷积层, 如果不减少3*3, 5*5的kernel数 最后的concate kernel数还是会爆炸的所以不是这个原因吧
        会飞的咸鱼Tank:@贰拾贰画生 第一个,用 1*1 去卷积输入的特征组,相较于用 3 * 3 ,大幅度的减少了计算量。第二,1*1 算是把各层的特征一定程度上糅合到一起了。可以自定义 1*1 的输出特征数(可以较少)。最后,将输出的特征组作为 3*3 等的输入,这样就减少了3*3的输出特征数。因为,直接使用 3*3 的话,需要保持原有的特征,还需要抽象更高层的特征,一般需要更多的通道数。逐层增加通道数,是会出现特征数的爆炸式增长的。
        贰拾贰画生:@不离不弃芳龄永继 1*1可以降维是不是因为1*1的kernels个数少于后边2*2或5*5的kernel个数?
        9c0ecdf615c9:1*1可以进行降维,降维后3*3 , 5*5的kernel数(维度)就已经减少了。
        所以不是为了加1*1而加1*1,1*1在这里最大的作用是降维,然后才是提高网络深度。
      • 義傑:好文~~感谢分享
        Traphix:@義傑 谢谢!

      本文标题:GoogLeNet的心路历程(二)

      本文链接:https://www.haomeiwen.com/subject/ovvvjttx.html