论文:《ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design》
目录
摘要
目前,网络架构设计主要由计算复杂度的间接度量(如FLOPs)测量。然而,直接度量(例如,速度)还取决于诸如存储器访问成本和平台特性的其他因素。因此,这项工作建议评估目标平台上的直接度量,而不仅仅考虑FLOPs。基于一系列对照实验,这项工作为高效的网络设计提供了几个实用指南。此外,提出了一种称为ShuffleNetV2的新架构。利用消融实验验证了我们的模型在速度和准确度方面是最好的。
前言
1. 什么是FLOPs?
FLOPs:英文命名为floating point operations,注意s是小写,指浮点运算数,理解为计算量。可以用来衡量算法/模型的复杂度。
FLOPS:全大写,指每秒浮点运算次数,可以理解为计算的速度。是衡量硬件性能的一个指标。(硬件)
对于卷积层来说,FLOPs计算公式如下:
简化形式为:
这里推荐一个工具包:torchstat,可以用来计算pytorch构建的网络的参数,空间大小,MAdd,FLOPs等指标,简单好用。例如我想知道alexnet的网络的一些参数,代码如下:
from torchstat import stat
import torchvision.models as models
model = models.alexnet()
stat(model, (3, 224, 224))
打印结果如下:
[MAdd]: AdaptiveAvgPool2d is not supported!
[Flops]: AdaptiveAvgPool2d is not supported!
[Memory]: AdaptiveAvgPool2d is not supported!
[MAdd]: Dropout is not supported!
[Flops]: Dropout is not supported!
[Memory]: Dropout is not supported!
[MAdd]: Dropout is not supported!
[Flops]: Dropout is not supported!
[Memory]: Dropout is not supported!
module name input shape output shape params memory(MB) MAdd Flops MemRead(B) MemWrite(B) duration[%] MemR+W(B)
0 features.0 3 224 224 64 55 55 23296.0 0.74 140,553,600.0 70,470,400.0 695296.0 774400.0 52.34% 1469696.0
1 features.1 64 55 55 64 55 55 0.0 0.74 193,600.0 193,600.0 774400.0 774400.0 5.13% 1548800.0
2 features.2 64 55 55 64 27 27 0.0 0.18 373,248.0 193,600.0 774400.0 186624.0 11.05% 961024.0
3 features.3 64 27 27 192 27 27 307392.0 0.53 447,897,600.0 224,088,768.0 1416192.0 559872.0 1.12% 1976064.0
4 features.4 192 27 27 192 27 27 0.0 0.53 139,968.0 139,968.0 559872.0 559872.0 0.00% 1119744.0
5 features.5 192 27 27 192 13 13 0.0 0.12 259,584.0 139,968.0 559872.0 129792.0 0.33% 689664.0
6 features.6 192 13 13 384 13 13 663936.0 0.25 224,280,576.0 112,205,184.0 2785536.0 259584.0 0.22% 3045120.0
7 features.7 384 13 13 384 13 13 0.0 0.25 64,896.0 64,896.0 259584.0 259584.0 0.11% 519168.0
8 features.8 384 13 13 256 13 13 884992.0 0.17 299,040,768.0 149,563,648.0 3799552.0 173056.0 0.33% 3972608.0
9 features.9 256 13 13 256 13 13 0.0 0.17 43,264.0 43,264.0 173056.0 173056.0 0.00% 346112.0
10 features.10 256 13 13 256 13 13 590080.0 0.17 199,360,512.0 99,723,520.0 2533376.0 173056.0 0.33% 2706432.0
11 features.11 256 13 13 256 13 13 0.0 0.17 43,264.0 43,264.0 173056.0 173056.0 0.11% 346112.0
12 features.12 256 13 13 256 6 6 0.0 0.04 73,728.0 43,264.0 173056.0 36864.0 0.00% 209920.0
13 avgpool 256 6 6 256 6 6 0.0 0.04 0.0 0.0 0.0 0.0 8.04% 0.0
14 classifier.0 9216 9216 0.0 0.04 0.0 0.0 0.0 0.0 0.00% 0.0
15 classifier.1 9216 4096 37752832.0 0.02 75,493,376.0 37,748,736.0 151048192.0 16384.0 19.09% 151064576.0
16 classifier.2 4096 4096 0.0 0.02 4,096.0 4,096.0 16384.0 16384.0 0.11% 32768.0
17 classifier.3 4096 4096 0.0 0.02 0.0 0.0 0.0 0.0 0.00% 0.0
18 classifier.4 4096 4096 16781312.0 0.02 33,550,336.0 16,777,216.0 67141632.0 16384.0 0.56% 67158016.0
19 classifier.5 4096 4096 0.0 0.02 4,096.0 4,096.0 16384.0 16384.0 0.00% 32768.0
20 classifier.6 4096 1000 4097000.0 0.00 8,191,000.0 4,096,000.0 16404384.0 4000.0 1.12% 16408384.0
total 61100840.0 4.19 1,429,567,512.0 715,543,488.0 16404384.0 4000.0 100.00% 253606976.0
=======================================================================================================================================================
Total params: 61,100,840
-------------------------------------------------------------------------------------------------------------------------------------------------------
Total memory: 4.19MB
Total MAdd: 1.43GMAdd
Total Flops: 715.54MFlops
Total MemR+W: 241.86MB
2. FLOPs和Speed
回到论文中,作者认为FLOPs是一种简介的测量指标,是一个近似值,并不是我们真正关心的。我们需要的是直接的指标,比如速度和延迟。如下图(c)和(d),横轴代表FLOPs,纵轴表示速度,可以看出四种不同的模型在FLOPs近似相等时,模型的运行速度是不相等的。因此,作者认为,使用FLOP作为计算复杂度的唯一指标是不充分的。
FLOPs和速度的不一致,作者认为有两个原因
- 首先影响速度的不仅仅是FLOPs,如内存使用量(memory access cost, MAC),这不能忽略,对于GPUs来说可能会是瓶颈。另外模型的并行程度也影响速度,并行度高的模型速度相对更快。
- 另外一个原因,模型在不同平台上的运行速度(runninng time)是有差异的,如GPU和ARM,而且采用不同的库也会有影响。
四个高效网络设计指南
针对以上的问题,作者在特定的平台下研究ShuffleNetv1和MobileNetv2的运行时间,并结合理论与实验得到了4条实用的指导原则:
(G1)相同的通道宽度大小最小化内存访问量
对于轻量级CNN网络,常采用深度可分离卷积(depthwise separable convolutions),其中点卷积( pointwise convolution)即1x1卷积复杂度最大。这里假定输入和输出特征的通道数分别为 和 ,特征图的空间大小为 ,那么1x1卷积的FLOPs为 ,对应的MAC为 (这里假定内存足够)。
由均值不等式可知:
当且仅当c1 = c2 时MAC取得最小值。
作者也做了实验来进行验证以上想法,实验网络是由10个block堆叠组成,每个block包含2个1×1卷积层,第一个卷积层的输入输出通道分别是c1和c2,第二个卷积层相反(c2,c1)。4行结果分别表示不同的c1:c2比例,但是每种比例的FLOPs都是相同的。
可以看出当c1和c2比例越接近时,速度越快,尤其是在c1:c2比例为1:1时速度最快。这与G1所提出的当c1和c2相等时MAC达到最小值相所对应。
(G2)过多的分组卷积操作会增大MAC,从而使模型速度变慢
分组卷积操作会减少参数,这样一来网络的计算量也就减少了。但是呢,认为网络的计算量减少,不代表模型的速度也会减少。MAC主要的消耗来源就来自分组卷积,分组卷积一多,MAC消耗的越多,模型速度也就变慢了。
带group操作的1×1卷积的FLOPs如下所示,多了一个除数g,g表示分组数量。这是因为每个卷积核都只和c1/g个通道的输入特征做卷积。
MAC和B(FLOPs)的关系如下,可以看出在B固定不变时,g越大,MAC也越大。
作者做实验也论证了以上想法,太强了!!!
由上图可以看到,g越小,速度越快。因此,作者建议应根据目标平台和任务仔细选择组号。虽然组卷积能增加模型的准确度,但是作者认为盲目使用较大的组号是不明智的,因为这将会使得计算成本增加带来的缺点大于准确度增加带来的优点。
(G3)模型中的分支数量越少,模型速度越快
作者认为,模型中的网络结构太复杂(分支和基本单元过多)会降低网络的并行程度,模型速度越慢。
同样,作者还是做了实验验证以上猜想。每个模型由block组成,每个block由1×1卷积组成,分别将它们重复10次。可以看出在相同FLOPs的情况下,单卷积层(1-fragment)的速度最快。
至于上表中的x-fragment可在论文结尾附录第一张图找到,series表示串联,parallel表示并联,如下图:
(G4)Element-wise操作不能被忽略
Element-wise包括Add/Relu/short-cut/depthwise convolution等操作。
元素操作类型操作虽然FLOPs非常低,但是带来的时间消耗还是非常明显的,尤其是在GPU上。元素操作操作虽然基本上不增加FLOPs,但是所带来的时间消耗占比却不可忽视。也即Small FLOPs heavy MAC。
最后一个猜想了,作者做了一个实验,采用的是Resnet50的瓶颈结构(bottleneck),除去跨层链接short-cut和 ReLU:
实验结果如下:
由上表可以看出,移除ReLU和shortcut后,在GPU和ARM上都获得了约20%的加速。
总结一下四大设计指南:
- G1:卷积层使用相同的输入输出通道数;
- G2:避免使用过多的分组卷积操作;
- G3:减少模型中的串并联分支数;
- G4:减少Element-wise操作,如ReLU,short-cut等;
最后,作者还点评了下“ShufflfflffleNet v1”和“MobileNet v2”:
- ShufflfflffleNet v1 严重依赖分组卷积,有违G2;多处使用bottleneck结构块,有违G1;
- MobileNet v2 使用inverted bottleneck structure,有违G1;在多通道feature map上使用DW卷积和ReLU,有违G4;自动生成的结构多分支(highly fragmented),有违G3.
ShuffleNet V2模型
1. 引入ShuffleNet V1
在讲ShuffleNet V2结构之前,作者先回顾ShuffleNet V1的缺点,用ShuffleNet V1来引出ShuffleNet V2。
ShuffleNet V1的两个创新点:
- pointwise group convolution 逐点分组卷积
- channel shuffle 通道混洗
Group Conv虽然能减少参数量和计算量,但Group Conv中不同组之间信息没有交流,,将输入特征分成g个互不相干的组,各走各走,组间没有交流,会降低网络的特征提取能力。为了解决这个问题,ShuffleNet V1给出的方法为“交换通道”。
因为在同一组中不同的通道蕴含的信息可能是相同的,如果不进行通道交换的话,学出来的特征会非常局限。如果在不同的组之后交换一些通道,那么就能交换信息,使得各个组的信息更丰富,能提取到的特征自然就更多,这样是有利于得到更好的结果。如图c所示,每组中都有其他所有组的特征。
上图中(a)是普通的DW卷积块(MobileNet V2)提出的。(b)是ShuffleNet unit,两个1×1的卷积是GConv,在第一个GConv后加了一个Channel Shuffle,残差连接为Add操作,针对步长为1的。(c)跟(b)类似,只是步长为2,另外残差连接为Concat操作。
但是,论文中也指出ShuffleNet V1的缺陷:
分组卷积增加了MAC,有违G2准则。
残差结构违背了G1,多块串联违背了G3
Add操作是元素级加法操作,违反了G4。
论文中提到“为了实现高的模型容量和效率”,关键问题是如何在不密集卷积和不太多分组的情况下保持大量的、同等宽的channels。
2. ShuffleNet V2模型
ShuffleNet V2中引入了新操作:channel split,
- 在每个unit的开始处,通过Channel Split将c特征通道的输入被分为两支,分别带有 c−c' 和c'个通道(为简单起见,论文中作者令 c'=c/2)。根据G3,一个分支的结构仍然保持不变。另一个分支由三个卷积组成, 为满足G1,令输入和输出通道相同。与 ShuffleNet V1 不同的是,两个 1×1 卷积不再是组卷积(GConv),因为Channel Split分割操作已经产生了两个组。
- 卷积之后,把两个分支拼接(Concat)起来,从而通道数量保持不变 (G1),而且也没有Add操作(element-wise操作)(G4)。然后进行与ShuffleNetV1相同的Channel Shuffle操作来保证两个分支间能进行信息交流。
- 保留DW Conv。
上述构建模块被重复堆叠以构建整个网络,被称之为 ShuffleNet V2。基于上述分析,本文得出结论:由于对上述四个准则的遵循,shuffleNetV2架构设计非常的高效。
ShuffleNet V2结构图如下:
文中提到,v2的整体网络结构相比v1仅有一点不同,在全局平均池化之前添加了一个额外的1×1卷积层,以混合特征,这在v1中是没有的。
文中也用到了v1中用到的对对每个block中的通道数进行缩放,0.5×,1×等。
回顾一下ShuffleNet V1的 整体网络结构:
模型的效果怎么样?(Experiences)
在两个硬件平台上测试,Shufflenet V2的性能明显比其它三个更好。
在图像分类上,加入了SE module的Shufflenet v2更出色,虽然FLOPs涨了一些,但错误率减少了很多。
在目标检测上,作者新引入了 ShufflfflffleNet v2* 新版本,在每一个block的第一个pointwise卷积之前加上一个 3×3的DW卷积,加大了感受野(受到Xception的启发),虽然增加了额外的FLOPs,但却进一步提高了检测精度。
另外,作者在实验中发现,在分类精度排行上,.
在检测精度排行上,,作者猜测是因为Xception 能得到更大的感受野。
总结
- 网络架构设计应该直接考虑速度,而不是FLOPs,像论文中的图1,就显示了模型有着相同的FLOPs,但却有着不同的速度;
- 在设计网络架构时,应该考虑上面你提到的四大设计指南G1~G4.
References
ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design
ShuffleNet: An Extremely Efficient Convolutional Neural Network for Mobile Devices
https://zhuanlan.zhihu.com/p/67009992