0%

ShuffleNet V2

目前,CNN网络在图像识别领域大放异彩,从最初的AlexNet到后面的GoogLeNet,ResNet,识别精度越来越高,但是除了精度之外,模型的计算复杂度也越来越引起大家的思考,如何降低网络的复杂度,以使网络可以高效的运行在诸如手机登移动端设备,也得到了众多研究者的研究。本文便主要在这方面发力,提出了提高网络速度设计的4个准则,并基于此设计了shuffleNet v2,在速度、精度均超过了目前的主流轻量级网络(shuffleNet v1, mobileNet v2等),本文是Face++提出,发表于ECCV2018.


论文名称:ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design

论文地址:https://arxiv.org/abs/1807.11164


下面详细介绍一下这篇文章

作者在开篇首先指出,目前评价一个网络的复杂度的指标往往是FLOPs(FLOPs简单解释就是网络执行了多少的multiply-adds操作),但是这种评价指标往往是不正确的,因为FLOPs可能不能反映出网络模型的执行速度或者时延,如下图所示:

通过观察可以发现图中(c,d)可以发现,具有相似的FLOPs的网络,执行的速度却不一样。

那么,为什么会出现这个矛盾呢?作者解释有两个原因:

  • 一些严重影响速度的因素没有考虑在FLOPs中。比如MAC(memory access cost内存访问成本)。比如分组卷积(group convolution)就会消耗较大的MAC。并行度,如果网络的并行度较高,那么速度就会有显著的提升。
  • 计算平台的不同,比如tensor运行的使用会提高计算速度,(但是最近发现,即使通过分解(decomposition)可以减少75%的FLOPs,但是计算速度却便慢了,究其原因是因为最近吃的cudnn加强了对3*3conv计算的优化,3*3卷积并不是1*1卷积计算速度的9倍这么简单)

基于以上的分析,作者提出了2个需要考虑的网络执行效率对比的设计准则:

  • 使用正确的速度度量方式去掉FLOPs
  • 并且要在目标计算平台上计算,不然结果不具有代表性。

如下这张图是作者分别在GPU(1080ti, cudnn7.0)以及ARM(高通骁龙810)环境下的网络运行时间展示,可以发现,除了卷积部分,还有很大部分时间在做其他的事情,这也说明,仅仅使用FLOPs是不够的。并且从该图可可以看出ARM相比较于GPU确实慢了一些,假设读取数据时间一致,GPU中卷积操作只占到将近一半,而ARM中已经占到了约90%。

基于此,作者做了如下的分析?

G1:输入输出具有相同channel的时候,内存消耗是最小的

为什么这么说:

由于目前主流网络均使用的depthwise separable convolutions,其中pointwise convolution占据了很大一块的运算量,这个在shuffleNet V1中有说明详细参见博客:shuffleNet V1,作者以1*1网络为例,假设feature map的大小为h*w输入输出channel分别为c1和c2,那么:

FLOPs:

$$B=hw(c_1*1*1*c_2)=hwc_1c_2$$

MAC:

$$MAC=hw(c_1+c_2)+c_1*c_2$$

(这里解释一下这个是怎么计算的:因为特征图大小为hw,在计算1*1卷积过程中我们需要将将所有的输入特征图和卷积核载入cache一次,这样需要$hwc_1+c_1c_2$次访存;然后需要将计算结果返回到内存,需要$hwc_2$次访存。)

利用均值不等式($c_1+c_2 >= 2\sqrt{c_1c_2}$)化简可以得到:

1
MAC>=2\sqrt{hwB}+\frac{B} {hw}

根据这个结果可以发现,当$c_1,c_2$相等的时候,可以取到最小值。

得证

下图的结果是作者的实验,实验结果同样支持G1结论。

G2: Excessive group convolution increases Map

group convolution最大的作用在于改变了所有channel间的dense convolution变为sparse卷积,(解释一下:如果没有group,每个output feature的每个cell是上层所有channel的feature map对应的cell的卷积结果,而分组之后,只需要计算组内的cell卷积结果,计算量就自然少了很多)

在固定的FLOPs条件下,采用group convolution可以使用更多的channel,这也是为什么采用group convolution提高精度的主要手段,但是增加了channel的同时,也增加了更多的MAC

采用分组卷积的MAC计算如下:

1
2
3
4
5
MAC=hw(c_1+c_2)+\frac{c_1c_2}{g}

MAC=hwc_1+\frac{Bg}{c_1}+\frac{B}{hw}

B = \frac{hwc_1c_2}{g}

由上面公式可以很清楚的看出来,MAC会随着g的增加而增加,同样的,作者进行了实验,验证这个结论,如下:

可见,随着group的增大,速度在明显减慢。

G3: Network fragmentation reduces degree of parallelism

比如googLeNet等网络,每个单元有很多的分支(multi-path),包括横向的和竖向的,如下图所示:

虽然这种分支结构对于提升精度有一定效果,但是却影响了模型的效率,主要原因在于影响了模型计算的并行度

为了证明这种multi-path对于网络执行速度的影响,作者分别设计了不同的multi-path并进行实验,实验结果如下:

观察实验结果可以发现,在GPU上多个fragment的网络的时间消耗增加明显,在CPU上增加不明显但是同样在增加。

G4: Element-wise operations are non-negligible

element-wise operation包括比如:ReLU,addtensor,addbias等,根据Fig2,我们可以发现,element操作的耗时也是挺大的,这波操作不容忽视。

注:另外作者在这提到,depthwise convolution(group数等于通道数,每个卷积核只卷积一个channel)也认为是一种element-wise操作

为了证明这个观点,作者利用resnet的一个block进行实验,将ReLU以及short-cut作为elemet-wise进行实验对比,实验结果如下图所示:

根据实验结果可以发现,ReLU以及short-cut操作如果都是no,速度为2842 batches/s,加入后为2427 batches/s,速度下降的还是挺明显的,CPU中,也是一样的趋势。

所以,一个高效的网络应该具备这些因素:

  • use balance convolution,input channel == output channel
  • consider of group convolution
  • reduce the degree of fragmentation
  • reduce element-wise operation

基于此,作者在shuffleNet的基础上,设计了shuffleNet V2:一个轻量级的速度高精度也高的网络结构。

下面介绍一下shuffleNet V2

在了解shuffleNet V2之前,可以先了解一下shuffleNet V1

先show一张shuffleNet V2 与shuffleNet的对比图

其中图(a,b)是shuffleNet的结构,图(c,d)是shuffleNet的改进结构,比较(a)与(c),可以发现,读了一个split操作,这也是shuffleNet V2的创新点,全称是channel split,其做法就是,首先将channel分成两个分支,c-c’和c’,为了满足G3,减少多分支计算,一个分支直接传下来,另一个分支包含了3个卷积,并且都是input-channel== output-channel的(符合G1),并且两个point-wise convolution不再使用group操作(满足G2),最终,两个分支进行concat操作(满足G4),后面的shuffle操作用来进行两个分支的信息交流。

对于需要down sampling的模块,如图(d)所示,将split操作去除,然后stride=2进行操作,这样输出的维度便增加了一倍。

最终,通过该block的堆叠,得到shuffleNet V2,结构如下图所示:其中repeat对应不同block的个数。本文中c’ = c/2

整体结构与shuffleNet V1基本一致,shuffleNet V1结构如下图所示:

唯一不同的是在global pooling的前面增加了Conv5(1*1的卷积层),来进行特征的融合。

shuffleNet V2不仅仅efficient同时具有很高的精度,这主要有如下两个原因:

  • 第一个原因是:由于高效,可以增加更多的channel,增加网络的容量。
  • 另外采用split使得一部分特征直接与下面block相连,这可以被看做是一种特征复用

下图是作者在多个模型的测试对比结果(包括mobileNet,CondenseNet,IGCV2,IGCV3等):

根据该图可以发现,MobileNet v1在GPU上面的速度是最快的,甚至超过了shuffleNet V2,mobileNet V1主要使用了depthwise conv以及pointwise conv,其fragment较少,符合G3的标准,另外IGCV2与IGCV3的速度较慢主要是因为使用了较多的group

另外,作者提到,利用SE-Net操作,分类精度会提升大约0.5%左右。将shuffleNet-V2堆叠50层,与shuffleNet v1以及resnet-50相比,精度有一定的提升,如下图:

另外,作者在COCO数据集上进行检测的测试,采用Light-Head框架,检测结果如下图所示:

可见,shuffleNet V2在相同FLOPs下,其精度最高,同时作者也指出:对于分类精度:ShuffleNet v2 > MobileNet V2 > ShuffleNet v1 > Xception, 但是对于检测的结果是:ShuffleNet v2 > Xception > ShuffleNet v1 > MobileNet v2,为什么会出现这种情况呢?作者解释到,可能是由于Xception较大的感受野,基于此为了增大感受野,作者在每个block的第一个pointwise convolution前面加入了一个3*3的depthwise convolution ,为shuffleNet v2,可见上图的v2确实在精度上有所提升。