文献阅读3|EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks

Intrudoction

在论文中,作者介绍了放大卷积神经网络是一种常见的提高模型准确率的方法。但是在传统的方法中,通常只是在某单一维度上进行放大(宽度width深度depth图片分辨率resolution),宽度就是网络中的过滤器的数量,因为增加了过滤器的数量,该层的输出的通道数就相应变大了,深度可以理解为整个网络结构的长度,即网络中layer的数量。那么为什么在这几个维度上进行放大可以提高准确率?因为增加了图片的分辨率或则增加了网络的宽度,网络就能够捕获到更过细节的特征,而增加网络的深度能够捕获到更丰富和更复杂的特征。
虽然也可以任意的放大两个或三个维度,但是因为维度变多,设计空间也随之变大,因此随意的放大多个维度需要耗费较大的人力来调整,并且也通常会一个次优的精度和效率。因此作者通过研究实验提出了一种新的缩放方法——复合缩放方法(compound scaling method)。

在一些手工设计网络中(如AlexNET、VGG、ResNet等),我们常常会有这样的疑问:为什么输入图像分辨率要固定为224,为什么卷积的个数要设置为这个值?为什么网络的深度设为这么深?这些问题你要问设计作者的话,估计回复就四个字——工程经验。
这篇论文使用NAS(Neural Architecture Search)技术来搜索网络的图像输入分辨率r,网络的深度depth,以及channel的宽度width三个参数的合理化配置。
EfficientNetB0到B7与其他网络的对比如下图所示:

为什么在这几个维度上进行放大可以提高准确率呢?因为增加了图片的分辨率或则增加了网络的宽度,网络就能够捕获到更过细节的特征,而增加网络的深度能够捕获到更丰富和更复杂的特征。

虽然也可以任意的放大两个或三个维度,但是因为维度变多,设计空间也随之变大,因此随意的放大多个维度需要耗费较大的人力来调整,并且也通常会有一个次优的精度和效率。因此作者通过研究实验提出了一种新的缩放方法——**复合缩放方法(compound scaling method)**。
下图所展示的便是放大神经网络的几种方法:

在之前的论文中,有的会通过增加网络的width即增加卷积核的个数(增加特征矩阵的channels)来提升网络的性能(上图b),有的会通过增加网络的深度使用更多的层结构来提升网络的性能(上图c),有的会通过增加输入网络的分辨率来提升网络的性能(上图d)。而在本篇论文中会同时增加网络的width、网络的深度以及输入网络的分辨率来提升网络的性能(上图e)

但是因为网络结构的缩放并不会改变具体某一层的卷积操作,所以一个良好的基线网络是必须的,作者在论文中也提出了一种新的基线网络结构——EfficientNet

compound scaling method

论文思想

  • Depth(d):缩放网络深度是许多卷积网络中最常用的方法。更深的卷积网络能够捕获到更丰富和复杂的特征,但是更深的网络由于存在梯度消失的问题而难以训练。尽管有一些方法可以解决梯度消失(例如 跨层连接skip connections和批量归一化 batch normalization),但是对于非常深的网络所获得的准确率的增益会减弱。例如ResNet-1000和ResNet-101有着相近的准确率尽管depth相差很大。下图的中间的曲线图表示用不同的深度系数d缩放模型的准确率曲线,并且表明了对于非常深的网络,准确率的增益会减弱。

    The intuition is that deeper ConvNet can capture richer and more complex features, and generalize well on new tasks. However, deeper networks are also more difficult to train due to the vanishing gradient problem

  • Width(w):缩放网络宽度对于小规模的网络也是很常用的一种方式。更宽的网络更能够捕捉到更多细节的特征,也更容易训练。很宽但很浅的网络结构很难捕捉到更高层次的特征。下图中左边的曲线图则是作者的不同宽度系数实验结果曲线,当w不断增大的时候,准确率很快就饱和了。

    wider networks tend to be able to capture more fine-grained features and are easier to train. However, extremely wide but shallow networks tend to have difficulties in capturing higher level features.

  • Resolution(r):使用更高分辨率的图像,网络能够捕获到更细粒度的特模式。增加输入网络的图像分辨率能够潜在得获得更高细粒度的特征模板,但对于非常高的输入分辨率,准确率的增益也会减小,并且大分辨率图像会增加计算量下图中右边的曲线图则是作者的不同分辨率系数实验结果曲线,对于非常高分辨率的图像,准确率的增益会减弱。(r=1.0表示224x224,r=2.5表示560x560)。

    With higher resolution input images, ConvNets can potentially capture more fine-grained patterns. but the accuracy gain diminishes for very high resolutions.

下图展示了在基准EfficientNetB-0上分别增加widthdepth以及resolution后得到的统计结果。通过下图可以看出大概在Accuracy达到80%时就趋于饱和了。

通过以上实验得出结论1:对网络深度、宽度和分辨率中的任一维度进行缩放都可以提高精度,但是当模型非常大时,这种放大的增益都会减弱

接着作者又做了一个实验,采用不同的d , r 组合,然后不断改变网络的width就得到了如下图所示的4条曲线,通过分析可以发现在相同的FLOPs下,同时增加d和r的效果最好。

复合缩放Compound Scaling

作者通过实验发现缩放的各个维度并不是独立的。直观上来讲,对于分辨率更高的图像,我们应该增加网络深度,因为需要更大的感受野来帮助捕获更多像素点的类似特征。为了证明这种猜测,作者做了一下相关实验:比较宽度缩放在不同深度和分辨率之下对准确率的影响。

通过上图的结果我们可以看到d=2.0,r=1.3时宽度缩放在相同flops下有着更高的准确率。
得到结论2:为了达到更好的准确率和效率,在缩放时平衡网络所有维度至关重要。

为了方便后续理解,我们先看下论文中通过NAS(Neural Architecture Search)技术搜索得到的EfficientNetB0的结构,如下图所示,整个网络框架由一系列Stage,$\widehat{Fi}$表示对应stage的运算操作,$\widehat{Li}$表示在该stage中重复$\widehat{Fi}$的次数:

作者在论文中对整个网络的运算进行抽象:$N(d,\omega,r) = ^{\bigodot}{i=1…s}F_i^{L_i}(X{})$

其中:

  • $ ^{\bigodot}_{i=1…s}$表示连乘运算
  • $F_i$表示一个运算操作(如上图中的operator),那么$F_i^{L_i}$表示在Stage_i中$F_i$运算被重复执行$L_i$次。
  • X表示输入Stage_i的特征矩阵(input tensor)
  • $<H_i,W_i,C_i>$表示X的高度,宽度以及Channels(shape)。

为了探究d,r,w这三个因子对最终准确率的影响,作者将d,r,w加到公式中,我们可以得到抽象化后的优化问题(在指定资源限制下),其中s.t.代表限制条件:

Our target is to maximize the model accuracy for any given resource constraints, which can be formulated as an optimization problem:

其中:

  • d用来缩放深度$\widehat{Li}$
  • r用来缩放分辨率即影响$\widehat{Hi}$和$\widehat{Wi}$
  • $\omega$用来缩放特征矩阵的channel即$\widehat{Ci}$
  • target_memory为memory限制
  • target_flops为FlOPs限制

然后,作者又提出了一种新的复合缩放方法使用了一个复合系数ϕ ,通过这个系数按照以下原则来统一的缩放网络深度宽度分辨率

这里:

  • FLOPs(理论计算量)与depth的关系是:当depth翻倍,FLOPs也翻倍。
  • FLOPs与width的关系是:当width翻倍(即channel翻倍),FLOPs会翻4倍,因为卷积层的FLOPs约等于$feature_\omega \times feature_h \times feature_c \times kernel_\omega \times kernel_h \times kernel_{number}$(假设输入输出特征矩阵的高宽不变),当width翻倍,输入特征矩阵的channels($feature_c$)和输出特征矩阵的channel或卷积核的个数($kernel_{number}$)都会翻倍,所以FLOPs会翻4倍。
  • FLOPs与resolution的关系是:当resolution翻倍,FLOPs也会翻4倍,和上面类似因为特征矩阵的宽度$feature_\omega$和特征矩阵的高度$feature_h$都会翻倍。

所以总的FLOPs倍率可以近似用($({\alpha \cdot \beta^2 \cdot \gamma^2})^\phi$)来表示,当限制${\alpha \cdot \beta^2 \cdot \gamma^2} \approx 2$,对于任意一个$\phi$而言FLOPs想当增加了$2^\phi$倍

接下来作者在基准网络EfficientNetB-0上使用NAS来搜索$\alpha,\beta,\gamma$这三个参数。

  1. 首先固定$\phi = 1$,并基于上面给出的公式(2)和(3)进行搜索,作者发现对于EfficientNetB-0最佳参数为
  2. 接着固定$\alpha=1.2,\beta=1.1,\gamma=1.15$,在EfficientNetB-0的基础上使用不同的$\phi$分别得到EfficientNetB-1至EfficientNetB-7。

需要注意的是,对于不同的基准网络搜索出的α , β , γ 也不一定相同。还需要注意的是,在原论文中,作者也说了,如果直接在大模型上去搜索α , β , γ 可能获得更好的结果,但是在较大的模型中搜索成本太大,所以这篇文章就在比较小的EfficientNetB-0模型上进行搜索的。

Notably, it is possible to achieve even better performance by searching for α, β, γ directly around a large model, but the search cost becomes prohibitively more expensive on larger models. Our method solves this issue by only doing search once on the small baseline network (step 1), and then use the same scaling coefficients for all other models (step 2).

网络详细结构

下表为EfficientNet-B0的网络框架(B1-B7就是在B0的基础上修改ResolutionChannels以及Layers),可以看出网络总共分成了9个Stage,第一个Stage就是一个卷积核大小为3x3步距为2的普通卷积层(包含BN和激活函数Swish),Stage2~Stage8都是在重复堆叠MBConv结构(最后一列的Layers表示该Stage重复MBConv结构多少次),而Stage9由一个普通的1x1的卷积层(包含BN和激活函数Swish)一个平均池化层和一个全连接层组成。表格中每个MBConv后会跟一个数字1或6,这里的1或6就是倍率因子n即MBConv中第一个1x1的卷积层会将输入特征矩阵的channels扩充为n倍,其中k3x3或k5x5表示MBConvDepthwise Conv所采用的卷积核大小。Channels表示通过该Stage后输出特征矩阵的Channels。

MBConv

MBConv其实就是MobileNetV3网络中的InvertedResidualBlock,但也有些许区别。一个是采用的激活函数不一样(EfficientNet的MBConv中使用的都是Swish激活函数),另一个是在每个MBConv中都加入了SE(Squeeze-and-Excitation)模块。

以下结构图为B站UP主霹雳吧啦Wz绘制的MBConv结构。

如图所示,MBConv结构主要由一个1x1的普通卷积(升维作用,包含BNSwish),一个kxkDepthwise Conv卷积(包含BNSwishk的具体值可看EfficientNet-B0的网络框架主要有3x3和5x5两种情况,一个SE模块,一个1x1的普通卷积(降维作用,包含BN),一个Droupout层构成。搭建过程中还需要注意几点:

  • 第一个升维的1x1卷积层,它的卷积核个数是输入特征矩阵channel的n倍, $n \in \left{1, 6\right}$(n∈{1,6})。
  • 当n = 1时,不要第一个升维的1x1卷积层,即Stage2中的MBConv结构都没有第一个升维的1x1卷积层(这和MobileNetV3网络类似)。
  • 关于shortcut连接,仅当输入MBConv结构的特征矩阵与输出的特征矩阵shape相同时才存在(代码中可通过$stride==1 and inputc_channels==output_channels$条件来判断)。
  • SE模块如下所示,由==一个全局平均池化==,==两个全连接层==组成。第一个全连接层的节点个数是输入该MBConv特征矩阵channels的$\frac{1}{4}$ 且使用Swish激活函数。第二个全连接层的节点个数等于Depthwise Conv层输出的特征矩阵channels,且使用Sigmoid激活函数。
  • Dropout层的dropout_rate在tensorflow的keras源码中对应的是drop_connect_rate后面会细讲(注意,在源码实现中只有使用shortcut的时候才有Dropout层)。

EfficientNet(B0-B7)参数

Model input_size width_coefficient depth_coefficient drop_connect_rate dropout_rate
EfficientNetB0 224x224 1.0 1.0 0.2 0.2
EfficientNetB1 240×240 1.0 1.1 0.2 0.2
EfficientNetB2 260x260 1.1 1.2 0.2 0.3
EfficientNetB3 300x300 1.2 1.4 0.2 0.3
EfficientNetB4 380x380 1.4 1.8 0.2 0.4
EfficientNetB5 456x456 1.6 2.2 0.2 0.4
EfficientNetB6 528x528 1.8 2.6 0.2 0.5
EfficientNetB7 600x600 2.0 3.1 0.2 0.5
  • input_size代表训练网络时输入网络的图像大小
  • width_coefficient代表channel维度上的倍率因子,比如在 EfficientNetB0Stage1的3x3卷积层所使用的卷积核个数是32,那么在B6中就是32 × 1.8 = 57.6 32 \times 1.8=57.632×1.8=57.6接着取整到离它最近的8的整数倍即56,其它Stage同理。
  • depth_coefficient代表depth维度上的倍率因子(仅针对Stage2Stage8),比如在EfficientNetB0Stage7的 $\widehat L_i=4$,那么在B6中就是4 × 2.6 = 10.4 4 \times 2.6=10.44×2.6=10.4接着向上取整即11。
  • drop_connect_rate是在MBConv结构中dropout层使用的drop_rate,在官方keras模块的实现中MBConv结构的drop_rate是从0递增到drop_connect_rate的(具体实现可以看下官方源码,注意,在源码实现中只有使用shortcut的时候才有Dropout层)。还需要注意的是,这里的Dropout层是Stochastic Depth,即会随机丢掉整个block的主分支(只剩捷径分支,相当于直接跳过了这个block)也可以理解为减少了网络的深度。
  • dropout_rate是最后一个全连接层前的dropout层(在stage9的Pooling与FC之间)的dropout_rate

最后是原论文中关于EfficientNet与当时主流网络的性能参数对比: