1 前言

在上一篇文章中笔者介绍了一种网络中的网络NiN模型,在接下来的这篇文章中将向大家介绍另外一种网络模型GoogLeNet[1]。从名字上看它似乎是Google与LeNet的结合,不过实际上它和LeNet并没有什么关系,仅仅是在向它致敬。GoogLeNet是Google公司和Magic Leap公司一起在CVPR2015上所发表的一篇论文,它的目的主要有两个:第一是用来分类,第二就是用来进行目标检测,如图1所示就是图像处理领域中常见的几种任务。GoogLeNet吸收了NiN模型中插入卷积的思想,并在此基础上做了很大的改进提出了一个名为Inception的模块。最后,通过多个相互堆叠的Inception模块构成了最后的GoogLeNet网络。


Inception:  Going deeper with convolutions_网络模型

图 1. 图像处理领域中常见的几类任务[2]

同样,笔者在写这篇文章之前也并没有看过这篇论文。因此笔者在第一眼看到论文时心里就默默念了一句“这篇幅,很谷歌”。谷歌发表的论文就像是武功秘籍里的独孤九剑、天山六阳掌和九阴真经一样,内容短小但却精悍,若是得道其中必定威力无穷,这一点我们在后面的文章中还会领略到。下面就让我们一起来解开这篇论文的庐山真面目。公众号后台回复“论文”即可获得下载链接!

2 动机

按照我们之前的习惯,解析一篇论文时一定要弄清楚论文的动机是什么?弄清楚作者为什么要这么做,目的是什么,以及解决了一个什么样的问题?只有了解清楚了这一过程,才有助于引导自己形成类似的思维模式,从而顺着这一思路想出自己的改进点,而不仅仅只是说会实现这个网络了,能跑通代码就完事。技术只是外功,思想与理念才是内功。

在论文的介绍部分作者提到,随着移动终端和可嵌入设备的兴起,我们所需要的应该是更加注重效率而不仅仅只是关注于结果的网络模型。下面我们就来看看作者所提出的两大主要问题。

2.1 面临问题

在深度学习中,两个最直接的提高模型精度的方法就是加深模型的深度(如网络的层数)和宽度(如每一层卷积核的个数),但是这些做法就带来了两个弊端:①更大的尺度意味着模型将拥有海量的参数,在标注数据不够的情况下及其容易产生过拟合;②仅仅只是匀速的增加网络的深度都会带来巨大的计算开销。例如第一个卷积层的参数为 [ 3 , 3 , 64 , 128 ] [3,3,64,128] [3,3,64,128],现在再加入一个参数为 [ 3 , 3 , 128 , 256 ] [3,3,128,256] [3,3,128,256]卷积层,虽然此时网络的性能可能有所提高,但这却带来了平方级参数量的增长。但更致命的是如果这些新加入的网络层并没有起到任何作用(训练完成参数趋于0),那么这样就浪费了大量的计算资源。

因此,作者认为一个解决上述问题的基本方法就是引入稀疏性(sparsity),例如通过某种稀疏结构来代替全连接方式;或者甚至是在卷积网络中也引入稀疏性。同时作者提到,之所以有这样的想法不仅仅在于这是在模仿生物的神经系统,其同样还有着Arora等人[3]坚实的理论基础作为支撑。Arora等人认为:如果某个数据集能够通过一个大的、稀疏的深度神经网络来进行表示,那么这个网络的最优拓扑结构就能够通过逐层聚类分析输出的激活值,然后推导得出


Their main result states that if the probability distribution of the dataset is representable by a large, very sparse deep neural network, then the optimal network topology can be constructed layer after layer by analyzing the correlation statistics of the preceding layer activations and clustering neurons with highly correlated outputs.


尽管这缺少严格的数学证明,但这一想法却与著名的赫布理论产生了共鸣,即”其中一个神经元先激活,然后另一个神经元马上跟着激活[5]“。


neurons that fire together, wire together


其实这里笔者也没有弄清楚稀疏性和这个赫布理论有什么联系,不过这也没关系。我们只需要知道解决上述问题的核心是给网络引入稀疏性就行了(其实不加这一段生物神经系统的论证似乎也能理解通过引入稀疏性来解决参数冗余问题)。那怎么才能加入这种稀疏性呢?

2.2 解决思路

在论文第三节的后半部分,作者就开始一步一步地隐晦的给出了解决这一问题的思路。因此这部分内容真的是非常的晦涩难懂,描述方式很不直接,需要读者自己来理清楚里面的逻辑关系。

首先作者说到,不幸的是现有的计算设备在处理非均匀的稀疏数据(non-uniform sparse data structures)时是非常低效的;并且在对稀疏数据进行计算时,即使将其中计算的步骤减少100倍,通过现有的计算设备来计算依旧十分低效。同时,随着现有的计算库对CPU和GPU的优化,它们将会更加的擅长在密集矩阵(dense matrices)上进行计算。因此,这两者(现有计算设备对于稀疏矩阵和密集矩阵的计算速度)之间的差距就会月来越大。言外之意就是作者并不希望通过基于稀疏矩阵计算的方式来稀疏化网络模型。

接着作者提到,非均匀的稀疏模型(non-uniform sparse models)需要更复杂的工程实现以及更多的计算资源。虽然现在有很多的网络模型通过卷积网络来实现模型的稀疏性,但是在底层实现的时候卷积操作采用的依旧是基于密集矩阵的计算方式。注意,其实作者在这里是在为卷积的优点做铺垫,因为卷积网络既能够使得模型更加稀疏,同时在现有的计算设备上还能高效的进行运算。


Inception:  Going deeper with convolutions_网络模型_02

图 2. 卷积计算图

最后作者提出疑问,是否能够在卷积的层面(filter-level)实现模型的稀疏性,同时还能通过密集矩阵计算来充分的利用现有的设备呢?答案当然是肯定的,而这也是论文里所给出的解决方案。同时,作者进一步讲到,现有的很多关于稀疏矩阵计算的文献都认为可以将一个稀疏矩阵分解成多个相对密集的子矩阵来完成计算,以此来提高稀疏矩阵的计算效率。


The vast literature on sparse matrix computations suggests that clustering sparse matrices into relatively dense submatrices tends to give competitive performance for sparse matrix multiplication.


到此,作者很含蓄的就介绍完了整个问题的解决思路,即**希望通过多个基于密集矩阵计算的组件(component)来构造一个稀疏的组件。**相信很多朋友读到这里肯定还是云里雾里的,有种朦朦胧胧的感觉。那接下来我们就来看看作者是用什么样的技术手段来实现这一动机的。

3 技术手段

3.1 Inception的形成

在论文第四部分内容伊始,作者就开门见山的提出了Inception的核心思想。作者说到,Inception结构的核心思想就是去考虑如何得到一个基于卷积网络的最优局部稀疏结构(optimal local sparse structure),并且这一稀疏结构还能简单的通过现在已有的密集组件(实际上指的就是密集矩阵乘法)来实现。同时,作者也强调到,为了保持图像平移不变性,Inception将会以卷积作为bolck进行构建。

作者继续重复到Arora等人的观点,如果是以逐层(layer-by-layer)的方式来构建一个网络模型,那么就需要通过分析每一层的输出值,然后将那些具有高相关性(high correlation)的神经元划分到一个group里面。


Inception:  Going deeper with convolutions_网络模型_03

图 3. Inception形成图


a layer-by layer construction where one should analyze the correlation statistics of the last layer and cluster them into groups of units with high correlation.


那这句话什么意思呢?如图3所示,按照作者的设想,存在一种稀疏的操作能够对前一层的输出进行处理,然后根据高相关性的原则可以将处理后的结果聚类到多个group中,而每且个group中的神经元都具有类似的相关性,接着这些神经元再根据某种组合得到网络下一层的输入。

紧接着作者说到,网络中靠前层的每个神经元都会对应到输入图片的某些区域(region),而这个靠前层同时又会被聚类成多个簇(filter banks),因此这些簇(correlated units)自然也会对应到输入图片中的某几个局部区域(local regions)。


Inception:  Going deeper with convolutions_卷积核_04

图 4. Inception推导图

什么意思呢?如图4所示,假设最下面为紧邻输入图片中的某个特征图 α \alpha α, α \alpha α在经过某种稀疏操作后得到了特征图 β \beta β,最后 β \beta β经过聚类后就得到了三个簇。作者认为, β \beta β中的每个神经元都会对应到 α \alpha α中某个局部区域(例如图3中 β \beta β左下角的神经元会对应到 α \alpha α中的区域B);而聚类后的每个簇又会对应到 β \beta β中的某些神经元,例如group 1可能就是由 β \beta β中的红色和棕色神经元组成,因此从本质上来讲group 1也就是由 α \alpha α中的A、B两个区域所构成。所以,作者认为,既然如此那我们为何不直接通过在 α \alpha α上作用不同尺度的卷积操作来得到最后的结果呢?

**因为卷积操作实质上也就等价于稀疏连接,而不同尺度卷积核就相当于不同的稀疏连接方式,最后将这些卷积后的结果组合起来也就等价于某种潜在的稀疏操作[6]。**而这,其实也就是作者想要寻找的基于卷积网络的最优局部稀疏结构。

同时,之所以能够直接这么做,作者在论文的相关工作部分提到,受到灵长类动物视觉皮层的启发,Serre 等人利用不同size的卷积核来处理多尺度的问题。因此,在GooLeNet中作者们也使用了相同的策略来设计网络结构。


Inspired by a neuroscience model of the primate visual cortex, Serre et al. used a series of fixed Gabor filters of different sizes to handle multiple scales. We use a similar strategy here.


并且在论文第四部分作者也再次强调到,这种设计理念也是非常符合实际的视觉感知,即通过以不同尺度的方式来对视觉信息进行处理,然后再将这些处理后的结果进行结合。


the design follows the practical intuition that visual information should be processed at various scales and then aggregated


3.2 Naive Inception module

如图5所示便是Inception的全部面貌,它通过不同尺度的卷积操作和一个池化操作对上一层的输出进行特征提取,然后再将得到结果组合到一起形成下一层网络的输入。接着,通过多个Inception模块的相互堆叠,就能得到最后的GoogLeNet网络了。


Inception:  Going deeper with convolutions_卷积_05

图 5. Naive Inception

不过虽然此时网络稀疏的问题解决了,但图5中的Incention结构却带来了另外一个问题,那就是计算量太大了,所以作者也将图5中的结构称之为Naive Inception。咦,不是说好的稀疏吗?怎么计算量还是这么大?注意,这里的稀疏指的并不是传统意义上的稀疏,而是通过多个稠密的component来近似的代替一个稀疏的component,所以本质上还是稠密计算。因此图4中的结构在一定程度上也会存在计算量大的问题。怎么解决呢?

3.3 Inception module

如图6所示,在Naive Inception中,假如上一层网络输出的形状为​​[28,28,192]​​​,然后使用一个形状为​​[5,5,32]​​​的卷积核进行卷积,其卷积后的形状为​​[28,28,32]​​。如果是完成这个卷积过程,需要计算多少次乘法操作呢?


Inception:  Going deeper with convolutions_卷积_06

图 6. 卷积操作数计算过程图

由于卷积核的大小是​​[5,5]​​​,且输入形状是​​[28,28,192]​​​,所以一个卷积核每移动一次便需要计算 5 × 5 × 192 5\times5\times192 5×5×192次乘法;同时这里有32个卷积核,且输出的大小也是​​​[28,28]​​,因此完成整个卷积过程所需要的乘法次数为: 5 × 5 × 192 × 28 × 28 × 32 ≈ 120 5\times5\times192\times28\times28\times32\approx 120 5×5×192×28×28×32≈120 million,也就是需要1.2亿次。

因此在论文中,作者又使用了大小为​​[1,1]​​的卷积核来对上一层的输出进行降维处理,这样就得到了最后真正的Inceptionm结构:


Inception:  Going deeper with convolutions_卷积_07

图 7. Inception

如图6所示就是采用降维处理后的Inception结构,可以看到在对于使用超过​​[1,1]​​​的卷积核进行卷积之前都先进行了降维处理,然后将降维后的结果进行较大尺度的卷积处理。此时可能有朋友会问,​​[1,1]​​的卷积是如何进行降维的呢?


Inception:  Going deeper with convolutions_网络模型_08

图 8. 降维卷积操作数计算图

如图8所示,我们在对原始的输入进行​​[5,5]​​​的卷积之前,先用​​[1,1]​​​的卷积进行降维处理;然后再进行​​[5,5]​​的卷积处理,并且保持最后输出的形状同图5中的一致。那么在这一过程中,第一次卷积过程中所需要的乘法数为: 1 × 1 × 192 × 28 × 28 × 16 ≈ 2.4 1\times1\times192\times28\times28\times16\approx2.4 1×1×192×28×28×16≈2.4 million;第二次卷积过程所需要的乘法数为: 5 × 5 × 16 × 28 × 28 × 32 ≈ 10 5\times5\times16\times28\times28\times32\approx10 5×5×16×28×28×32≈10 million。因此整个计算过程所需要执行的乘法数为 12.4 12.4 12.4million,可以看到其计算量只有先前的十分之一。

以上就是整个Inception模块的设计理念,这也是按照作者的思路来理解的Inception。不过网络上更多其他人的理解角度便是,与其纠正或者调试应该选择那种尺寸的卷积核进行卷积,不如将不同卷积尺寸的卷积核结合起来,并且也不会考虑到什么稀疏性的问题。当然,严格来说Inception这种结构到底有没有解决网络稀疏性的问题,作者也说这需要严格的证明与验证。不过单从写论文的角度来说,从作者的角度来进行切入显然就高大上多了,整个故事也非常有深度。而如果是从另外一种角度来说的话,顶多也就算是一个trick,怎么能够写成一篇论文,你说对吧?

各位读者需要注意的是,以上都是笔者自己的理解,可能有的地方也并不正确,还请各自斟酌!

4 总结

在这篇文章中,笔者首先按照论文的思路介绍了深度学习中面临的两大主要问题;然后介绍了解决这两大问题的主要思路;接着详细介绍了论文作者所提出来的基于卷积操作的最优局部稀疏结构Inception;最后还介绍了如何通过​​[1,1]​​卷积的方式来降低Inception中的计算量。说了这么多,总算是在一定程度上把Inception这一结构给理清楚了。不过由于篇幅实在太长,关于GoogLeNet的内容我们就放到下一篇文章中再进行介绍。

本次内容就到此结束,感谢您的阅读!如果你觉得上述内容对你有所帮助,青山不改,绿水长流,我们月来客栈见!

引用

[1] Szegedy C, Liu W, Jia Y, et al. Going deeper with convolutions[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2015: 1-9.

[2]https://leonardoaraujosantos.gitbook.io/artificial-inteligence/machine_learning/deep_learning/object_localization_and_detection

[3]S. Arora, A. Bhaskara, R. Ge, and T. Ma. Provable bounds for learning some deep representations. CoRR, abs/1310.6343, 2013

[4]https://zhuanlan.zhihu.com/p/19939960

[5]https://www.youtube.com/watch?v=1OCsi0krPgg&t=29s

[6]https://www.programmersought.com/article/4186752331/