Inception模块之间互相堆放,它们的输出相关性统计一定会改变:高层次提取高抽象性的特征,空间集中性会降低,因此3x3和5x5的卷积核在更高层会比较多。采用这样的模块有一个大问题是在卷积层顶端由于滤波器太多,即使是5x5的卷积都会让计算开销过分昂贵。当pooling单元加入之后这个问题更加明显:输出滤波器的数量等于前一步中滤波器的数量。pooling层的输出和卷积层的输出融合会导致输出数量逐步增长。即使这个架构可能包含了最优的稀疏结构,还是会非常没有效率,导致计算没经过几步就崩。
因此有了架构的第二个主要思想:在计算要求增加很多的地方应用维度缩减和预测。即,在3x3和5x5的卷积前用一个1x1的卷积用于减少计算,还用于修正线性激活。技术上的做法是,保持低层为传统卷积方式不变,只在较高的层开始用Inception模块。
这种架构的两个主要优点:一是允许显著增加每一步的单元数目,计算复杂性不会不受控制。降维的普遍使用能保护最后一步到下一层的大量输入滤波器,在对它们用大的patch size卷积前首先降维。二是视觉信息在不同的尺度上进行处理然后聚合,这样下一步可以同时从不同尺度提取特征。
采用了Inception模块的网络要比没有采用Inception模块的同样架构的网络快2~3倍。总体结构:
1.包括Inception模块的所有卷积,都用了修正线性单元(ReLU);2.网络的感受野大小是224x224,采用RGB彩色通道,且减去均值;
3.#3x3 reduce和#5x5 reduce分别表示3x3和5x5的卷积前缩减层中1x1滤波器的个数;pool proj表示嵌入的max-pooling之后的投影层中1x1滤波器的个数;缩减层和投影层都要用ReLU;
4.网络包含22个带参数的层(如果考虑pooling层就是27层),独立成块的层总共有约有100个;
5.网络中间的层次生成的特征会非常有区分性,给这些层增加一些辅助分类器。这些分类器以小卷积网络的形式放在Inception(4a)和Inception(4b)的输出上。在训练过程中,损失会根据折扣后的权重(折扣权重为0.3)叠加到总损失中。
辅助分类器的具体细节:
1.均值pooling层滤波器大小为5x5,步长为3,(4a)的输出为4x4x512,(4d)的输出为4x4x528;2.1x1的卷积有用于降维的128个滤波器和修正线性激活;
3.全连接层有1024个单元和修正线性激活;
4.dropout层的dropped的输出比率为70%;
5.线性层将softmax损失作为分类器(和主分类器一样预测1000个类,但在inference时移除)。
Global Average Pooling的做法是将全连接层去掉。
全连接层的存在有两个缺点:1)全连接层是传统的神经网络形式,使用了全连接层以为着卷积层只是作为特征提取器来提取图像的特征,而全连接层是不可解释的,从而CNN也不可解释了
2)全连接层中的参数往往占据CNN整个网络参数的一大部分,从而使用全连接层容易导致过拟合。
而Global Average Pooling则是在最后一层,将卷积层设为与类别数目一致,然后全局pooling,从而输出类别个数个结果。
对于这个Inception,有两点需要注意:
1.层级越高,所对应的原始图片的视野就越大,同样大小的卷积核就越难捕捉到特征,因而层级越高,卷积核的数目就应该增加。2.1×1,3×3,5×5 只是随意想出来的,不是必须这样。
3.这个naive版的Inception,还有一个问题,因为所有的卷积核都在上一层的所有输出上来做,那5×5的卷积核所需的计算量就太大了。 因而,可以采用NIN中的方法对上一层的输出进行Merge。这样就衍生出了真正可用的Inception。(1*1 卷积核)
4.再同时,还具有不同的视野尺度,因为不同尺寸的卷积核和pooling是在一起使用的。
Rethinking这篇论文中提出了一些CNN调参的经验型规则,暂列如下:
1)避免特征表征的瓶颈。特征表征就是指图像在CNN某层的激活值,特征表征的大小在CNN中应该是缓慢的减小的。
2)高维的特征更容易处理,在高维特征上训练更快,更容易收敛
3)低维嵌入空间上进行空间汇聚,损失并不是很大。这个的解释是相邻的神经单元之间具有很强的相关性,信息具有冗余。
4)平衡的网络的深度和宽度。宽度和深度适宜的话可以让网络应用到分布式上时具有比较平衡的computational budget。
思考:使用3×3的已经很小了,那么更小的2×2呢?2×2虽然能使得参数进一步降低,但是不如另一种方式更加有效,那就是Asymmetric(非对称)方式,即使用1×3和3×1两种来代替3×3. 使用2个2×2的话能节省11%的计算量,而使用这种方式则可以节省33%。
注意:实践证明,这种模式的Inception在前几层使用并不会导致好的效果,在feature_map的大小比较中等的时候使用会比较好
在GoogLeNet中,使用了多余的在底层的分类器,直觉上可以认为这样做可以使底层能够在梯度下降中学的比较充分,但在实践中发现两条:
1)多余的分类器在训练开始的时候并不能起到作用,在训练快结束的时候,使用它可以有所提升。
2)最底层的那个多余的分类器去掉以后也不会有损失。
以为多余的分类器起到的是梯度传播下去的重要作用,但通过实验认为实际上起到的是regularizer的作用,因为在多余的分类器前添加dropout或者batch normalization后效果更佳。
Label Smoothing
除了上述的模型结构的改进以外,Rethinking那篇论文还改进了目标函数。
原来的目标函数,在单类情况下,如果某一类概率接近1,其他的概率接近0,那么会导致交叉熵取log后变得很大很大。从而导致两个问题:
1.过拟合
2.导致样本属于某个类别的概率非常的大,模型太过于自信自己的判断。
所以,使用了一种平滑方法,可以使得类别概率之间的差别没有那么大,用一个均匀分布做平滑,该项改动可以提升0.2%
为什么有三个分类器:
浅层中的额外的分类器,能增加bp的梯度信号和额外的正则化。这些分类器将小的卷积网络放在4a和4b的输出上,在训练过程中,损失会根据权重叠加,而在测试时丢弃。
辅助分类器解决了梯度爆炸和梯度消失的问题。
GoogLeNet用节省空间的稀疏结构来替代AlexNet中稠密的连接层,但这也导致了其时间开销增大,但GoogLeNet的精度要高。