October 25, 2018
by Frank
现在很多的网络设计在计算复杂度方面都只考虑了非直接度量(比如 FLOPs),而对于直接度量(如速度等)并不只是由 FLOPs 来决定的,包括 MAC(内存访问消耗)和平台特性都对速度有一定的影响。本文意在特定平台下进行直接度量,比仅仅考虑 FLOPs 要更好,并且在基于一系列控制实验下提出了一些对于高效率网络的指导准则,根据这些准则提出了 ShuffleNetV2 这样一种新的网络结构,全面的 a...
现在很多的网络设计在计算复杂度方面都只考虑了非直接度量(比如 FLOPs),而对于直接度量(如速度等)并不只是由 FLOPs 来决定的,包括 MAC(内存访问消耗)和平台特性都对速度有一定的影响。本文意在特定平台下进行直接度量,比仅仅考虑 FLOPs 要更好,并且在基于一系列控制实验下提出了一些对于高效率网络的指导准则,根据这些准则提出了 ShuffleNetV2 这样一种新的网络结构,全面的 ablation experiments 表明该模型在性能和精度的权衡上达到了 state-of-the-art。
自从 AlexNet 在 ImageNet 上取得了很好的成绩之后,ImageNet 上的分类准确度又被一些新型的神经网络进一步改善,比如 VGG,GoogLeNet,ResNet,DenseNet,ResNeXt,SE-Net 等,而且还有自动网络结构搜索。除了精度之外,计算复杂度也是另外一个需要考虑的因素,现实世界的应用通常会受到很多平台的限制,这促进了很多轻量级神经网络结构的设计,以及更好的速度-精度平衡,比如 Xception,MobileNet,MobileNetV2,ShuffleNet 和 CondenseNet 等。在这些工作里面,group conv 和 depth-wise conv 是至关重要的。
为了评价计算复杂度,常用的评价标准就是 FLOPs(在本文中的定义是 mult-adds 的数量),然而 FLOPs 只是一个近似的间接度量,而不是我们所关心的直接度量,例如速度,延迟等。这样的矛盾在最近的工作中已经被注意到了。比如 MobileNetV2 和 NASNET-A 有相近的 FLOPs 但是 MobileNetV2 的速度要快得多。下图说明模型有近似的 FLOPs 但是可能有不同的速度,因此仅仅使用 FLOPs 作为度量是不够的,并且有可能导致次优设计。
在间接度量(FLOPs)和直接度量(速度)之间的矛盾主要来自于两个方面(度量和平台):一是很多关键的影响速度的因素没有考虑进来,比如 MAC(memory access cost,group conv 是其中一个重要的组成,对于 GPU 这样强大的运算单元来说这可能会变成其瓶颈),还有就是 DOP(degree of parallelism,在同样的 FLOPs 下,高 DOP 的模型可能要比低 DOP 的模型快很多)。第二个原因就是对于平台的依赖,比如张量分解这样的操作,尽管能够减少 75%的 FLOPs,但是在分解后 CPU 上的运行速度甚至比 GPU 更慢,后来发现这是由于最近的 CUDNN 库对于 3x3 卷积有特殊的优化,不能简单地认为 3x3 conv 就比 1x1 conv 要慢 9 倍。
通过这些观察,发现在高效的神经网络设计中应该遵循两条原则,一是要使用直接度量而非间接度量,二是要在特定的平台上进行度量。基于这两条准则提出了更加有效的神经网络结构。在第二章中我们首先分析了两个代表性的 state-of-the-art 神经网络(ShuffleNetV1,MobileNetV2)的运行时性能,之后我们提出了高效网络设计的四条准则,比只考虑 FLOPs 更进一步。然而这些准则是平台独立的,我们进行了不同的控制实验来在两个平台上(GPU 和 ARM)验证它们(带有代码优化),来保证我们的结论是 state-of-the-art。
在第三章节中设计了 ShuffleNetV2,通过第四章完整的验证实验,证明其在两个平台上都比之前的网络要更加准确和快速。
本研究是基于两个带有工业级优化的 CNN 库的被广泛应用的硬件平台上进行。注意到我们的 CNN 库要比大多数开源库更加高效,因此我们的观察和结论是牢固的并且在工业上是有实践价值的。GPU(单个 GTX1080TI,卷积库是 CUDNN7.0,并且激活了 CUDNN 的 benchmarking 函数来对于不同的卷积选择最快的算法),ARM(高通骁龙 810,基于 Neon 实现,利用单线程来进行验证),其他的一些设置:开启全优化(张量融合之类的),输入图片尺寸:224x224,所有网络进行随机初始化,并且评估 100 次取平均运行时间。
对于刚开始的研究我们选取 MobileNetV2 和 ShuffleNetV1,尽管只有两个,但是这代表了最近的趋势,这两个网络的核心是 group conv 和 depth-wise conv,这也同样是其他 state-of-the-art 网络的核心。整个运行时分解图如下:,FLOPs 只算了卷积部分,尽管其占了大部分时间,但是一些其他的内容比如:数据 I/O,data shuffle 和 element-wise 操作也占了很大一部分,因此 FLOPs 用作时间的估计是很不准确的。基于以上观察,我们对运行时间从几个方面进行了分析,并且得出了对于高效神经网络设计的一些实际经验。
很多现代网络都采用 depth-wise conv,其中 1x1 卷积占了大部分复杂度,其 FLOPs 为,假设内存够大足够存储输入输出的特征和卷积核权重,MAC 为,即为输入特征+输出特征+卷积核权重。通过均值不等式可以得到,当时该不等式取等号,即当输出通道数等于输入通道数时 MAC 最小。当然这只是理论上的,利用重复堆积 10 个 block 来作为评价网络,通过调整通道数来使整个 FLOPs 保持不变,实际的实验结果如下:
group conv 是很多现代网络的核心,可以通过 channel 之间的稀疏连接来减少 FLOPs,一方面可以在固定 FLOPs 下使用更多的 channel,以此增加网络容量(从而改善精度),另一方面增加 channel 也会增加 MAC。根据上一条里面的公式可以得到 1x1 conv 的 FLOPs 和 MAC 之间的关系为:,其中 g 为组数,可以看到在 h,w,c1,c2,B 固定的情况下,增加 g 会增加 MAC。通过堆积 10 个 1x1 group conv 来构造评价网络,结果证明一味选取很大的 group 数并不好,其带来的精度提升的好处可能会被增加的计算消耗所抵消掉。实验结果如下:。
在 GoogLeNet 系列和自动生成结构系列,“多路径”结构在每个网络 block 被广泛应用,许多小操作(fragmented operators)在这里被应用,而不是少量的大操作。比如在 NASNET-A 中 fragmented ops(比如某个 block 中单独的卷积/池化操作)是 13,而在一些正则化结构中(比如 ResNet)是 2 或 3。这样的碎片结构已经表明对准确度有利,但是可能会降低效率因为这些操作对于一些高度并行计算的设备比如 GPU 很不友好。也会导致核的启动/同步等额外开销。为了对此影像进行量化,设计了实验 block 如下:,每个 block 重复 10 次。试验结果表明碎片化会明显降低了 GPU 上的速度,相对 GPU,ARM 上的速度降低更轻微一些。实验结果如图:
。
如之前的图片所示,element-wise 操作(张量相加,bias,ReLU 等)占据了相当的时间,尤其是在 GPU 上面,它们具有比较小的 FLOPs 但是具有较大的 MAC,尤其是 depthwise conv 作为 element-wise 操作,因为其具有较大的 MAC/FLOPs 比率。在 bottleneck 结构上进行了实验,针对 ReLU 和 shortcut:
总结:1)应该使用尽量平衡的卷积(输入输出通道相等),2)了解 group-conv 的消耗,3)减少网络的碎片度,3)减少逐点操作。而且相比理论上而言,更应该考虑到网络在平台上的特性,并且应用在实际网络设计当中。之前的很多网络违背了这些规则,例如 ShuffleNetV1 太依赖 group conv 违背了 G2,其瓶颈结构设计违背了 G1,MobileNetV2 的瓶颈设计违背了 G1,在太厚的特征图上使用 ReLU 等违背了 G4,自动生成的网络结构太过碎片化违背了 G3。
轻量级网络设计的主要挑战是给定计算量下的有限的通道数。想在有限的 FLOPs 下增加通道数的办法有两个:1)pointwise group conv,2)瓶颈结构。之后又引出了 channel shuffle 这样的结构来增加不同 channel 的通讯。但是 pointwise group conv 和瓶颈结构都有违背之前的准则,现在的问题在于如何维持大量的平均匀分布的 channel 数,而不至于太密的卷积或者太多的组数。
对于以上的需求做了一些设计:刚开始就对 channel 进行分割,然后在 1x1 conv 中不再使用 group,也不使用瓶颈结构,而是让输入输出 channel 相等,并且只在一个支路上进行 ReLu 和 depthwise conv。最后进行 concat 和 channel shuffle。并且将 concat,channel shuffle,split 合并成一个 element-wise 操作。与 V1 相同可以利用 s 来对网络进行缩放,通过改变通道数,另外在进行 split 的时候为了简单起见采用了对半分的方式。ShuffleNetV2 block 的结构如下:
ShuffleNetV2 很高效,因此可以具有更多的通道数和模型容量,另外特征的对半分可以看作一种 feature reuse,类似于 DenseNet 和 CondenseNet。DenseNet 和 ShuffleNetV2 在 feature reuse 上面的模式对比如下图:ShuffleNetV2 在 feature reues 上获取了和 DenseNet 同样的好处,却相比更加高效,后续的实验可以说明。
实验所使用的超参数和协议与 ShuffleNetV1 完全相同,在这里先放上实验结果,后面再对实验进行总结:
Accuracy vs. FLOPs:ShuffleNetV2 明显可以超过其他所有网络,但是在 40MFLOPs,224x224 图像尺寸的时候由于通道数太少表现也欠佳。该模型和 DenseNet 相比,都有 reuse features,但是本模型更高效。
Inference Speed vs. FLOPs/Accuracy:MobileNetV2 在小 FLOPs 的时候非常慢,可能是由于具有过高的 MAC。尽管 MobileNetV1 在准确度上欠佳,但是其在 GPU 上的面的速度很快,已经超过了 ShuffleNetV2,可能是其更加满足之前的设计准则,尤其是 G3,MobileNetV1 的 fragments 是比 ShuffleNetV2 还要更小的。另外,IGCV2 和 IGCV3 都很慢,可能是由于使用了过多的 group conv,然后这些现象都与我们的设计准则相符合。目前的自动搜索出的神经网络结构都比较慢,应该是具有较多的 fragments,这违背了 G3,不过这个研究方向仍然是充满前景的。在 accuracy vs. speed 这个方面,ShuffleNetV2 在 GPU 和 CPU 两个平台上都是表现最好的。
Compatibility with other methods:将 ShuffleNetV2 和其他结构相结合的时候,比如 SE(squeeze and excitation),分类准确率有所提升,应该说明了其良好的兼容性。
Generalization to Large :当 ShuffleNetV2 用作大模型的时候性能也很好,只不过在做得很深的时候为了加快收敛速度而增加了残差连接
Object Detection:在 COCO 数据集上来评估其泛化性能,使用 state-of-the-art 的轻量级检测器 Light-Head RCNN 来作为框架,在 ImageNet 上进行了训练然后在 finetuned 用作检测任务。后来发现 Xception 比较擅长检测任务,可能是由于 block 更大的接受域,收到这个的启发,我们在第一个 1x1 conv 之前加入了 3x3 的 depthwise conv,最后在增加了一点 FLOPs 的情况下更好的改善了性能。另外在检测任务下,不同模型之间的速度差要小于分类任务(除去数据拷贝的开销和检测特有的开销)。ShuffleNetV2*有最好的精度并且比其它方法都要快,这启发出了另一个实际问题:如何让增加接受域的大小,这在高分辨率图像的目标检测中是至关重要的。
网络设计应该考虑直接度量而非间接度量,提供了结构设计的有效准则和一种高效的神经网络 ShuffleNetV2,全面的实验充分证明了模型的有效性,希望这项工作能引出对于平台相关而且更加实际的网络设计。