Inception V2-V3
论文:Rethinking the Inception Architecture for Computer Vision
Szegedy 在2015年发表了论文 Rethinking the Inception Architecture for Computer Vision,该论文对之前的 Inception V1 结构提出了多种优化方法,来达到尽可能高效的利用计算资源的目的。作者认为随意增大Inception的复杂度,后果就是Inception的错误率很容易飙升,还会成倍的增加计算量,所以必须按照一套合理的规则来优化Inception结构,即一套尚未被证伪的“炼金法则”。
通用设计准则
规则1:慎用Bottleneck。所谓的 特征描述瓶颈(representational bottleneck)就是中间某层对特征在某空间维度进行较大比例的压缩(比如使用pooling时),导致很多特征丢失。所以出于模型分类精度考虑,应尽量避免使用bottleneck,尤其是不应当在模型的早期使用。作者们认为CNN模型本质上是一个DAG(有向无环图),其上信息自底向上流动,而 每一个bottleneck的使用都会损失一部分信息,因此当我们出于计算和存储节省而要使用bottleneck时,一定要下手轻一点(如:不要一下子使用1x1 conv 缩减过多的feature map的channels数目,如果一定要使用reduction模块也尽量在模型较靠后的几层使用)。

规则2:conv层宽一点有好处。每个conv层的kernels数目增加(尽管增加kernels数目会有增加计算和内存开销的负面因素),可以使模型更好的处理局部信息,增加表达能力。因为相互独立的特征越多,输入的信息就被分解的越彻底,分解的子特征间的相关性低,子特征内部的相关性高,把相关性强的聚集在了一起,会更容易收敛(整体所需的迭代次数会减少,并非整体训练时间)。
规则3:可以压缩特征维度,来减少计算量。这条规则也是通过大量实验得出的结论。Inception V1中在3x3的卷积前添加1x1的卷积块进行特征维度压缩,就是利用这条规则。其中1x1卷积块的使用,不仅不会影响模型的精度,还能使收敛速度加快。作者们给出的猜测性解释是:不同维度的信息有相关性,降维可以理解成一种无损或低损压缩,即使维度降低了,仍然可以利用相关性恢复出原有的信息。尤其是在神经网络的后期,feature maps上的相邻channels之间具有很高的关联性(即冗余信息不少),因此可以将输出的channels变少而不担心信息丢失。
规则4:平衡网络的宽度和深度。只有等比例的增大深度和维度才能最大限度的提升网络的性能。作者们们认为(也是通过实验后总结)一个成功的CNN网络设计一定要将深度与宽度同时增加,瘦高或矮胖的CNN网络都不如一个身材匀称的网络的效果好。
优化方法
既然我们可以用稀疏的 inception V1 模块来有力地表达多维度信息,那么干吗不再进一步将其中大的kernel size的conv层再进一步分解展开呢。根据上文提出的设计准则,作者们又给出了一些神经网络的优化方法:
方法1:可以将大尺度的卷积分解成多个小尺度的卷积来减少计算量。举个栗子!如下图所示,将1个5x5的卷积分解成两个3x3的卷积串联,从图中可以看出两级3x3的卷积的覆盖范围就是5x5,两者的覆盖范围没有区别。假设5x5和两级3x3卷积输出的特征数相同,那两级3x3卷积的计算量就是前者的(3x3+3x3)/5x5=72%的计算开销。

方法2:可以使用非对称卷积。将nxn的卷积分解成1xn和nx1卷积的串联。例如n=3,将一个3x3的conv分解为了1x3与3x1的conv计算,分解后只使用约(1x3 + 3x1) / (3x3) = 67%的计算开销。 作者通过测试发现非对称卷积用在网络中靠中间的层级才有较好的效果(特别是feature map的大小在12x12~20x20之间时)。

方法3:更高效的下采样方案。深度CNN网络中一般会不断使用Pool层来减少feature maps size。这必然意味着传递信息的不断丢失。一般为了减少信息的过度丢失,在加入Pool层减少feature maps size的同时都会同比例扩大它的channels数目。
传统的实行方法有两个:
1.先将channels数目扩大(一般使用1x1 conv),然后再使用pool层来减少feature map size。不过其中1x1 conv的计算显然会有非常大的计算开销;
2.先做Pooling减少feature map size,然后再使用1x1 conv对其channels数目放大。不过显然首先使用Pooling的话会造成信息丢失(违反规则1),在此之后再使用1x1 conv去增加channels数目的做法已经有些亡羊补牢之嫌了。
下图反映了这两种较为传统的做法。

所以作者提出了他们的办法,确实比较新颖。即分别使用pool与conv直接减少feature map size的做法分别计算,完了后再将两者算出的feature maps组合起来!使用conv计算和使用pool提取的特征尽管都有信息丢失,但计算不同,丢失不同,提取的特征也是不同的,所以可以在不增加大量的计算量的情况下,实现feature maps的size减少,channels增多。
下图是此一方法的表示。

方法4:使用Label Smoothing来对网络输出进行正则化。作者认为softmax loss过于注重使模型学习分类出正确的类别(label),而过于地试着偏离其它的非正确labels。如此的话可能使得训练得到的模型在新的数据集上扩展性不好(即易陷入overfitting的困局)。为此他们认为有必要使用label的先验分布信息对其loss进行校正。如下为他们最终使用的loss。

此外,作者还重新分析了分类层的作用:regularization。之前的GoogLeNet(本文没提GoogLeNet而是主要集中说明Inception结构,所以分类层也就简单提一下,看不懂的读者可以跳过,没关系),作者为了减少深度模型中反向传播时梯度消失的问题,而提出了在模型的中间与较底部增加了两个extra 分类loss层的方案。在inception v2中,作者同样使用了extra loss层。不过他们反思了之前说过的话,觉着不大对了,果断以今日之我否定了昨日之我。他们现在(当时是2015年)觉着extra loss的真正意义在于对训练参数进行regularization。为此他们试着在这些extra loss的FC层里添加了BN或者dropout层,果然发现分类结果好了些。

Inception V2
将上述的方法1~方法4组合到一起,就有了 inception V2 的3种 Inception 结构,如下图所示:(左)第一级inception结构,(中)第二级inception结构,(右)第三级inception结构。

Inception V3
inception-v2的基础上,如果在辅助分类器上也加上BN(实验证明效果确实更好),就成了inception-v3。
总结
Inception V2-V3总结
inception V2-V3结构的主要贡献有四个:
一是给出了四条“炼金法则”;
一是将大尺寸的卷积分解成多个小尺度的卷积减少计算;
三是提出了一种更高效的下采样方案;
四是加入了BN层。
参考文献
Rethinking the Inception Architecture for Computer Vision
卷积神经网络之GoogleNet:inceptionV3模型学习
Inception v2与Inception v3
Inception-v2/v3结构解析(原创)