暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

细品EfficientNet

Techdemic 2020-04-29
685

在之前的比赛和项目中,EfficientNet的效果出乎意料地好,加之后续的一些项目可能会跟EfficientDet打交道,所以上周我抽了一些时间来完整地看了EfficientNet/EfficientDet的论文,并打算出一个【细品Efficient】的系列,希望对大家有所帮助。尤其是对那些没时间看原文的同学,我会尽量用最简练的语言来解释这篇文章。

EfficientNet是Google Research 发表在ICML 2019的工作。EfficientNet根据网络从小到大,分为了B0到B7共8个网络,其中EfficientNet-B0尺寸最小,速度最快,精度相对最低;EfficientNet-B7尺寸最大,精度最高,速度也相对最慢。目前EfficientNet也是ImageNet数据集的SOTA(最近又出了一个ResNeSt,指标也很好,不过先让子弹飞一会)。

总的来说,这篇文章做了2件事情:

  1. 提出一个新的网络尺寸缩放的方法(Propose a new scaling method).

  2. 使用NAS搜索最优的网络结构(Use NAS).

动机很简单,一般对于分类网络来说,网络的拓扑结构和网络尺寸是网络表现的关键因素。EfficientNet就是抓住这两个点展开的。先用NAS搜一个较小的拓扑结构(基础网络),然后用一定的方法增大网络尺寸。这样,当基础网络表现超越其他同等尺寸网络时,增大网络尺寸后的表现也应该能够超越其他同等尺寸的网络。这样就得到了EfficientNet从B0到B7的backbone家族。

01
关于scaling method

什么是scaling?经常听说大型网络,小型网络,网络的尺寸大小,其实就是scaling。那么如何衡量网络尺寸呢,最直观的当然是网络中的参数量,如下图所示,横轴为网络中参数量,纵轴为网络的精度。当网络的参数量越少,精度越高时,性能就越好。

参数量又是由什么决定的呢?一般来说,对于CNN网络,决定参数量的有3个因素:网络深度(Depth),网络宽度(width),输入图片的大小(resolution)。EfficientNet文章中对网络的scaling有了一个比较全面且清晰地阐述,如下图所示:

图(a)中的5个矩形块表示网络的layer,layer数量越多,网络深度越深;每个矩形块的高度表示当前feature map的高宽(H,W),也就是feature map的resolution;而每个矩形块的宽度表示feature map的通道数,一般把最后输出的feature map的通道数作为网络的宽度。所有关于网络尺寸的参量都离不开这三个变量,万变不离其宗。图b-d分别展示了,将网络加宽,加深,增加resolution后的变化。图e展示了同时增加这三个维度,网络的变化。

我们都知道,增加网络尺寸一般会带来精度的增益,但是同时也会消耗更多的计算资源。在EfficientNet之前,没有一个准则来决定如何增加网络尺寸可以用最少的计算资源来换取最大程度的增益。

Our empirical study shows that it is critical to balance all dimensions of network width/depth/resolution, and surprisingly such balance can be achieved by simply scaling each of them with constant ratio.

而且,以往的研究中多数是仅增加这三个维度中的一个维度,来观察网络精度提升情况,但是单独增加哪一个维度,到一定程度都会精度饱和:

开始增加某一维度时,我们可以用很少的FLOPS换取很大的精度提升,但是进一步增加某一维度尺寸,会发现精度提升一点,需要用很大的FLOPS作为代价。那么很容易想到的方案是,以一个准则,同时增加3个维度,就可以用最少的FLOPS代价换取最大的精度提升。

our method uniformly scales network width, depth, and resolution with a set of fixed scaling coefficients.

EfficientNet的贡献之一就是,通过实验观察得到了一种scaling方法。用这个方法,就可以最有效地增加网络尺寸。具体是什么方法呢?

说来也简单,就是以一个固定比率统一增加网络width,depth以及resolution。例如,要把网络增大2倍,那就同时把网络宽度增加a倍,网络深度增加b倍,resolution增加c倍。这里的abc是用网格搜索方式计算出来的。如果不想看公式,我觉得看到这里也已经能够明白作者说的scaling method是什么了。

公式推导也很简单:

首先,可以把所有的CNN网络看作是如下公式:

其中,F就表示神经网络中的算子(可以是conv, relu, bn等),L就是在第i个stage,F算子重复的次数,X表示输入张量。stage的概念,如果熟悉resnet或者跑过CNN分类网络的迁移训练代码的同学应该非常熟悉,现在的Backbone网络设计时都会把一些block重复几次,例如ResNet的bottleneck block,更准确地说,这里的F就是指这种重复多次的block,每个block形成一个stage,最终得到整体的网络结构。

那么,我们可以把上述scaling问题描述成一个优化问题:

其中新出现的变量w, d, r,分别表示width,depth以及resolution的增加系数。目标函数就是最大化网络精度,约束条件则是计算资源的限制。这样问题就转化为了,在固定的计算资源下,找到网络尺寸scaling的最优w, d, r。

是不是很容易理解了。

上面的公式,变量太多,搜索空间太大,求解只能硬搜,很耗资源。因此,文章中采用了一个很容易想到的思路——缩小搜索空间。首先,固定F,也就是说,当我们做网络尺寸增加时,网络中基本的block是不变的,变化的仅仅是每个block重复的次数(网络深度),输入feature map大小(resolution)以及block输出的channel数量(网络宽度)。其次,FLOPS一般是正比于depth,正比于width^2,正比于resolution^2,也就是说,depth变为2倍,FLOPS变为2倍,width变为2倍,FLOPS变为4倍,resolution变为2倍,FLOPS也变为4倍。因此,直接提出如下约束条件来强行缩小搜索空间:

用φ来统一scaling倍数,因此只需要用一个小型网格搜索来确定α, β, γ的值即可。这样对于给定的φ,统一增加d, w, r 后,FLOPS会增加2^φ。

到此,就完全讲明白了文章第一部分所提出的一个scaling method了。

02
关于NAS

说实话,我不怎么想写NAS,因为这玩意过于消耗资源,跟我无关,他属于FAIR,Google Research那帮人。所以这里就不细说了(原文也没有用多少笔墨在这里)。既然scaling method能在不改变网络基本block的情况下通过增大网络来提升性能,那剩下的工作就是,用NAS以公式(2)为约束条件搜一个很小但是也比较准的网络结构:

这就是大名鼎鼎的EfficientNet-B0的网络结构了,一共18层,却达到了超越ResNet50的精度(真是qinshou)。

有了这个之后,利用scaling method提升网络尺度,即可得到相应的EfficientNet:B1-B7。最后看一眼这个系列的夸张表现:

最后,为了证明scaling method的有效性,作者还在ResNet和MobileNet上进行了实验,并且证明scaling method也同样可以增加ResNet和MobileNet的精度。至此,论文以非常严谨的逻辑证明了scaling method是有效的,并且NAS搜出来的EfficientNet网络结构也是有效的。无懈可击,完美!

03
总结

这篇文章是【细品Efficient】的第一篇文章,从scaling和NAS两个方面介绍了Efficient系列的backbone——EfficientNet。此前我在Kaggle DFDC挑战赛(附Top2% 解决方案)等比赛或者项目中都采用了EfficientNet作为backbone,实测效果也确实很好。随后的文章会继续细品EfficientDet,看看Efficient系列的目标检测效果如何。希望这篇文章对你有所帮助。

04
参考资料

[1] Tan, Mingxing, and Quoc V. Le. "Efficientnet: Rethinking model scaling for convolutional neural networks." arXiv preprint arXiv:1905.11946 (2019).

往期精彩回顾
Kaggle DFDC挑战赛(附Top2% 解决方案)
【分布式系统设计】实战Raft:主节点选举
【Python专题(二)】Python二三事
我就知道你“在看”




文章转载自Techdemic,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论