EfficientNet 和 EfficientDet
EfficientNet (CVPR 2020) 是一个单级检测框架,构建在 EfficientNet (ICML 2019) Backbone 之上,加上以下两点 Detector 部分的创新:
BiFPN (weighted bi-directional feature pyramid network):融合多尺度特征。以往的 FPN 相关研究中,特征融合是通过简单相加来融合,意味着每个特征图的权重相等。然而不同分辨率的特征对结果的贡献不同,这里引入一个可学习权重。此外,通过重复的 top-down 和 bottom-up 结构使特征更有效流动。
Scaling method:对所有的 backbone、neck、head 联合调整特征图大小、宽度、深度。且以往一般通过更大的 backbone 和更大的 input size 来提高精度,但是发现增大 neck 和 head 同样很关键。
注重速度,同时注重提供大范围内的速度—精度调整。精度最好结果为 52.2 AP (COCO test-dev) 52M 325B FLOPs。这篇文章以 Detector 的各个部分来看 EfficientDet 这篇文章,在 backbone 部分会分析 EfficientNet 这篇文章。
Table of Contents
Neck - BiFPN
先简要介绍 PANet,如下图,PANet 主要在 neck 部分增加了自下而上的一支(Bottom-up path augmentation);以及改进了特征重采样的方式(Adaptive feature pooling),聚合每个特征层次上的每个 RoI,避免任意分配的结果;以及使用一个小型 fc 层用于补充 mask 预测,互补作用。
增加 Bottom-up 分支是为了 low-layer information 更容易传播,以往需要穿过整个 backbone(红色箭头),经过的层数非常多,现在可以通过绿色箭头的路径经过几层就达到深层,使得特征可以更有效流动。连接方式是纵向 3 × 3, s = 2
卷积 -> 横向相加 -> 纵向 3 × 3
卷积。
在FPN中,依据 RoI 的大小将 RoI 分配到不同特征层次。这样小面积的 RoI 分配到 low-level,大的 RoI 分配到 high-level,虽然简单有效,但可能会产生非最优结果。例如两个具有 10 个像素差的 RoI 可能分配到不同特征层次,而实际上这两个 RoI 非常相似。特征的重要性可能与他们所属的特征层次没有太大关系:high-level 特征具有大的感受野并捕获了丰富的上下文信息,允许小 RoI 获取这些特征,能更好地使用上下文信息做预测;low-level 特征具有许多微小细节和高定位精度,允许大 RoI 获取这些特征显然也是有益的。融合操作可以采用 element-wise max or sum。注意融合不是在 RoIAlign 之后立即进行,而是经过一个 fc(box head) 或一个 conv(mask head) 之后才进行。
对于 fc mask pred,从 mask head 的 conv3 引出。fc 对于位置敏感而 conv 基于一个局部信息,它们是互补的,所以引入 fc 有助于提升 mask 精度。
下图 (f)是 BiFPN 的结构图,它与 PANet(b)同样有一条额外的 bottom-up path,使得特征可以双向流动(bi-directional)而不是原始 FPN 中的单向流动。比起 PANet,BiFPN 有以下几个区别:
去掉了只有一个输入 edge 的节点(共两个):如果某一个节点只有一条输入 edge,那么它对特征融合(网络)中贡献较小。
增加了从原始输入到输出节点的 edge:融合更多的特征,又不增大太多开销。
虚线框内的部分是可重复的,根据整个网络的规模叠加不同的个数。
下图中(c)是 NAS-FPN,它的结构是通过网络自动学习设计生成的,虽然它的计算量相对 PANet 较小,但是计算出这样一个结构需要花费大量的时间,同时结果不规则且难以解释。图(d/e)是作者探索的两种其它结构。
同时,如最开始提到,与上面各种其它方法均不同的是,BiFPN 中特征图加和是带有权重的。也就是 w_i
可以是一个标量(对应于每个特征图一个不同权重)或是一个矢量(对应于每个通道一个不同权重)或是一个张量(对应于每个像素一个不同权重)。实验发现使用标量效果就比较好了,但是直接使用的话由于 w_i
没有限制,容易造成训练不稳定。比较直接的想法是对所有权重使用 Softmax,这样权重之和为 1
,但是实验发现 Softmax 会使 GPU 计算时间增大,性能下降。所以作者提出了一种快速 normalize 方法:
为保证每个权重值 >0
,所以每个权重需要使用 ReLU,epsilon = 0.0001
。实验得到这种方法精度与 Softmax 相同但是速度提高 30%。
具体的连接方式如下,以 P6
为例,其它类似。其中
为了节省计算量,这里的卷积是 depthwise separable convolution,即把正常卷积(N×C×K×K)拆分为 Depthwise Conv(C×1×K×K) 和 Pointwise Conv(N×C×1×1)。前者卷积核通道数均为 1
。每个卷积后有激活层和 BN 层。
Backbone - EfficientNet
EfficientNet 是同样的作者提出的一个 backbone。作者在这篇文章里探讨了两件事:
- Backbone 三个不同方面的缩放:width、depth、resolution。以往为了提高精度或速度,研究一般会专注于单一的尺度上,比如 ResNet 只加深了 depth。此文作者指出三者的共同缩放更加有效,提出了缩放的平衡准则,以 ResNet 和 MobileNet 为基准进行了测试。
- 上述放大网络的方法显然很依赖于 baseline 的表现,除了现有网络,作者以 精度 和 真实移动设备上的速度 为优化目标,使用 reinforce learning (neural architecture search) 搜索出了一个小模型 EfficientNet-B0,该模型的 ImageNet Top-1 Acc 为
77.3%
,Params~FLOPS 为5.3M
和0.39B
,对比 ResNet-50 为76.0%~26M~4.1B
。以该模型为基准,同样使用 <1> 中研究的放大网络方法,构建了 EfficientNet-B0~B7,测试结果如下图。
总结:Neural Architecture Search 是一种很有用的设计高效网络的方法,但是只能使用在搜索域比较小的移动设备小网络上。为了增加搜索得到的小网络的精度,作者寻求于网络映射关系不变,但同时增加 width、depth、resolution 获得更大网络的方法。
compound scaling method
理论和实验:如果输入图像更大,那么网络应该更深以得到更大的感受野,同时需要更多的通道以捕捉更多精细的信息,所以三者是相关的,以前的一些研究中这种关系的存在但是没有给出定量结果。
上图给出了 EfficientNet-B0 为基准,单独增加 width 或 depth 或 resolution 网络的精度和计算量变化,可以看到三者在一定倍数后精度就饱和了。
对于 width,这是由于虽然 wider 的网络更容易捕捉细节的特征且更容易训练,但 wide but shallow 的网络很难捕捉 higher level 特征;
对于 depth,这是由于更深网络的梯度消失;
对于 resolution 这种现象也存在,更高分辨率的输入图像并不会提供无限多的有效信息。
所以,我们需要同时缩放三者,可以使用一个复合系数 Φ
,按照下面的公式计算出放大后的 w, d, r
。
α, β, γ
可以通过 Grid Search 得到,是定值。Φ
是人工指定的将网络计算量增大的参数,由于卷积的计算量与 d, w2, r2 正相关,且卷积网络的 FLOPS 由卷积层主导,满足上述限制条件后,通过 Φ
即可将网络计算量调整到 2Φ 倍。
architecture search
Neural Architectrue Search 是近些年一种热门的获得网络结构的方法,需要一些 reinforce learning 的知识,在这里不细说。简单介绍,它需要搜索空间、优化目标,然后使用某种优化算法比如 Proximal Policy Optimization 来更新采样参数。
对于搜索空间,意思是我们需要定义一下网络大概的样子,限制越多则搜索空间越小。在早期,搜索的空间通常只是一个小 Block,然后通过重复人工堆叠这个 Block 来构造一个网络。限制越小,则搜索难度更大但理论上得到的网络更优。但是,有一些非常通用、广泛采用的映射关系,我们是可以加入限制的,例如:
一个网络应当是由几个 Block 组成,在一个 Block 内,我们重复使用一些结构;
图像应当被逐步下采样,且如果一个 Block 中的分辨率与上一个不同,那么下采样应当在这个 Block 中的第一个卷积中使用 stride=2 完成;
所以说,我们可以设定一个网络大致骨架,然后去搜索诸如层数、卷积核大小、残差结构等等,如下图所示是本文使用的搜索空间。
优化目标为 ACC(m) × [FLOPS(m) / T]w,m 表示模型,T 表示目标 FLOPS,w=-0.07 是一个超参数用于平衡 ACC 和 FLOPS。我们希望在计算量限制的情况下得到最高准确率。
这样搜索得到的网络为 EfficientNet-B0,网络结构如下表。
Stage | Operator | Resolution | #Channels | #Layers |
---|---|---|---|---|
1 | Conv 3×3 | 224 × 224 | 32 | 1 |
2 | MBConv1, k3×3 | 112 × 112 | 16 | 1 |
3 | MBConv6, k3×3 | 112 × 112 | 24 | 2 |
4 | MBConv6, k5×5 | 56 × 56 | 40 | 2 |
5 | MBConv6, k3×3 | 28 × 28 | 80 | 3 |
6 | MBConv6, k5×5 | 14 × 14 | 112 | 3 |
7 | MBConv6, k5×5 | 14 × 14 | 192 | 4 |
8 | MBConv6, k3×3 | 7 × 7 | 320 | 1 |
9 | Conv1×1 & Pooling & FC | 7 × 7 | 1280 | 1 |
其中 MBConv 是 MobileNetV2 中的 Inverted Residuals and Linear Bottlenecks,原始结构如下。
1 | Input ──────┐ Input |
Inverted Residuals:Dwise Conv 提取得到的特征受限于输入的通道数,若是采用以往的 residual block,先压缩通道再卷积提特征,那么 Dwise Conv 可提取得特征就太少了。MobileNetV2 反其道而行,一开始先扩张,原文中实验扩张倍数为
6
。所以通常 residual block 里面是「压缩→卷积提特征→扩张」,MobileNetV2 变成了「扩张→卷积提特征→压缩」,称为 Inverted Residuals。Linear Bottlenecks:当采用上述 Inverted Residuals 时,在压缩之后会碰到一个问题,那就是 Relu 会破坏特征:Relu对于负的输入,输出全为零。而本来特征就已经被 Conv 压缩,再经过 Relu 的话,又要损失一部分特征,因此这里不采用 Relu,称为 Linear bottlenecks。
Relu6 在
x>6
时值为6
不变。
此外,在 EfficientNet 的 MBConv 中,作者还加入了 squeeze-and-excitation optimization。
scaling up baseline model
得到 baseline 之后,现在需要进行的是放大这个网络得到更高精度,通过以下两步进行。
固定放大复合系数
Φ=1
,即目标将网络计算量放大两倍,进行 Grid Search,找到对于 EfficientNet-B0 的最佳系数α=1.2, β=1.1, γ=1.15
。固定
α=1.2, β=1.1, γ=1.15
,使用不同的Φ
放大整个网络,得到 EfficientNet-B1~B7。
Model | Top-1 Acc. | Top-5 Acc. | #Params | #FLOPS |
---|---|---|---|---|
EfficientNet-B0 | 77.3% | 93.5% | 5.3M | 0.39B |
EfficientNet-B1 | 79.2% | 94.5% | 7.8M | 0.70B |
EfficientNet-B2 | 80.3% | 95.0% | 9.2M | 1.0B |
EfficientNet-B3 | 81.7% | 95.6% | 12M | 1.8B |
EfficientNet-B4 | 83.0% | 96.3% | 19M | 4.2B |
EfficientNet-B5 | 83.7% | 96.7% | 30M | 9.9B |
EfficientNet-B6 | 84.2% | 96.8% | 43M | 19B |
EfficientNet-B7 | 84.4% | 97.1% | 66M | 37B |
Scaling up EfficientDet
回到 detection 中,EfficientDet 的结构图如下,Head 部分对于所有 BiFPN 层级是共享参数的。
同样,下面来看如何放大这个网络得到更高的检测精度。
Backbone
这里直接使用 B0~B6 网络,以直接使用 ImageNet 预训练好的模型。
BiFPN
depth:线性增加,因为它是一个较小的整数
width:与 backbone 一样指数形式增加。在
{1.2, 1.25, 1.3, 1.35, 1.4, 1.45}
进行 Grid Search,得到最好结果是1.35
。
即
Head
depth:
width:与它的 BiFPN 相同
Input Resolution
因为 P7 缩小了 128 倍,所以输入应当能被 128 整除,线性增加输入尺寸:
综上,我们可以得到 D0~D7,如下表所示(D6 和 D7 只有输入尺寸的差别)。
Input Size | Backbone | BiFPN #channels | BiFPN #layers | Head #layers | |
---|---|---|---|---|---|
D0 ( Φ = 0) | 512 | B0 | 64 | 3 | 3 |
D1 ( Φ = 1) | 640 | B1 | 88 | 4 | 3 |
D2 ( Φ = 2) | 768 | B2 | 112 | 5 | 3 |
D3 ( Φ = 3) | 896 | B3 | 160 | 6 | 4 |
D4 ( Φ = 4) | 1024 | B4 | 224 | 7 | 4 |
D5 ( Φ = 5) | 1280 | B5 | 288 | 7 | 4 |
D6 ( Φ = 6) | 1280 | B6 | 384 | 8 | 5 |
D7 ( Φ = 7) | 1536 | B6 | 384 | 8 | 5 |
对于精度和计算量如下图。