原文链接:
ShuffleNet V2 论文阅读笔记blog.csdn.net
论文链接:
Practical Guidelines for Efficient CNN Architecture Designarxiv.org
我自己基于 caffe 框架的复现:
anlongstory/ShuffleNet_V2-caffegithub.com
本文主要是对目前一些主流网络进行多组对比实验,并从这些对比实验中进行一定的理论分析和总结,最后得出4条关于 CNN 网络结构设计的准则来帮助神经网络可以更高效。下面先贴出文中观点:
接下来就基于以上4条准则进行分开描述,最后文章基于上述准则在shuffleNet的基础上,提出了 shuffleNet V2,并通过大量实验验证了网络结构的有效性。
首先在了解文章之前需要清楚的是目前一些有效网络的主要手段是通过分离卷积(depth-wise convolution)和 分组卷积(Group convolution),而且文章中主要对网络计算复杂性的标准是 浮点运算操作的数量 (即 FLOPs),但是文中通过实验发现,FLOPs 并不能和 网络的计算速度成正比。
上图就是表示在 4 种网络都有相近的 FLOPs 但是网络的速度在不同的平台上都不相同。所以仅通过 FLOPs 来衡量不是很准确。因为一些因素并没有考虑进去,一个就是内存访问成本(memory access cost,MAC),例如当框架在执行分组卷积等操作时,运算能力强劲时可能可以忽略,但是在一些计算能力有限的平台上面就无法忽略了;还有一个就是网络的并行化程度,在相同的 FLOPs 下,网络并行化程度更高的网络速度更快。
相同 FLOPs 的不同网络在在不同平台下的运行时间也是不一样的:
如上图,可以看到相同的网络在不同的平台上各个部分消耗的时间比例也是不一样的(即有些操作对GPU结构友好但是对ARM结构并不友好,反之亦然),所以为了更准确的衡量网络的效率,网络也应该针对自己的目标平台来进行对比和测量。本文也基于此,所有的实验都在 GPU 和 ARM 两个平台上进行测试,来全方面表现 shuffleNet V2 的有效性。
本文实验硬件条件: GPU 为一块 GeForce GTX 1080Ti; ARM 结构为 高通骁龙 810 芯片。(Tips: Table 1,2,3,4 中的 Batches/sec 栏数值都是越大越好 )
这个准则是在探索输入通道与输出通道间的比例关系对网络速度的影响。通过在 GPU 和 ARM 平台上对比 shuffleNet 和 MobileNet v2 两个网络中 1x1 卷积层不同的输入输出通道比例所得到的数据得出的结论:
这里首先设输入通道为 c1,输出通道为 c2,输出特征图尺寸为 hxw,所以每一个 1x1 卷积层的 FLOPs 就是: B=hw*c1c2
。这里内存访问成本 MAC = hw(c1+c2)+c1c2
,所以经过如下推导就可以得到:
即:
所以c1和c2值相等的得到上式的最小值,基于实验和理论得到准则1(G1):当输入通道与输出通道比例为 1:1 时, MAC最小,可以使网络的速度更快。
这个准则探索分组卷积的分组数对网络速度的影响。 其中对于分组卷积,这里的 FLOPs 为:B=hw*c1c2/g
,这里的 g
表示为分组数。
由上面推导可得,h,w,c1,B都是固定的,随着分组数g
的增加, MAC 也会随之增加。并通过实验验证:
所以得到以上准则2: 分组数越多,MAC 就会越大,网络结构就会越慢。
所以文章中也给出建议:分组数应该根据实际课题以及应用的平台谨慎选择。单纯的通过增加分组卷积来增加通道数从而增加精确度是一个不明智的选择。
这个准则是探索网络的分支数以及每个基本结构包含的卷积层个数对网络速度的影响。
以上是在实验中使用的基本网络结构,分别将它们重复10次,然后进行实验。实验结果如下:
可以看到 在 GPU 上只包含 1-fragment 的速度是 4-fragment 的3倍。
由上面的饼状图可以看见,例如一些 ReLU ,Tensor 相加,Bias相加的操作,甚至是分离卷积(depthwise convolution)都定义为 element-wise 操作的话,这些操作的时间也是不可忽略。并且通过除去跨层链接和 ReLU,在 GPU 和 ARM 结构上都获得了接近 20% 的提速。
基于以上的对比实验,可以得到一个有效的网络应该包含:
(1) 卷积层使用相同的输入输出通道数
(2) 意识到使用大的分组数所带来的坏处
(3) 降低网络结构的离散程度(减少分支以及所包含的基本单元)
(4) 减少 element-wise 操作
所以本文基于上述的4条准则,以及shuffleNet,提出了 ShuffleNet V2的网络结构。
首先指出 shuffleNet 存在的问题:
depthwise convolution 和 瓶颈结构增加了 MAC,用了太多的 group,跨层连接中的 element-wise Add 操作也是可以优化的点。所以在 shuffleNet V2 中增加了几种新特性。
所谓的 channel split
其实就是将通道数一分为2,化成两分支来代替原先的分组卷积结构(G2),并且每个分支中的卷积层都是保持输入输出通道数相同(G1),其中一个分支不采取任何操作减少基本单元数(G3),最后使用了 concat 代替原来的 elementy-wise add,并且后面不加 ReLU 直接(G4),再加入channle shuffle 来增加通道之间的信息交流。 对于下采样层,在这一层中对通道数进行翻倍。 在网络结构的最后,即平均值池化层前加入一层 1x1 的卷积层来进一步的混合特征。
最后文章把精度与准确度归结为2点,一个符合上述提升网络有效性的准则,来更好的利用特征以及增加网络的容量,还有一个就是直接跨层连接相当于特征的重利用,并通过图示对比,说明了自己网络重利用,但是没有很大的增加网络的冗余性。
最后通过大量的对比实验,包括将上述的准则直接对现有的一些 start-of-the-art 模型进行修改,验证所提出的4个准则的正确性,还有就是 ShuffleNet V2 的有效性,和包括在目标检测方面的良好的泛化特性。 这里就不多赘述,具体可以参见论文。
看完论文不得不佩服,文中所做的对比实验真的很充足,不论是文章开始每个准则的提出(且不论是先有理论想法再进行的实验,还是先进行实验发现了部分特性然后再展开研究,提出理论的),还是最后的有效性的对比实验。 文中部分技巧,例如 channel split 然后其中一半通道直接 concat 到结尾来保持最后的通道数不变,然后对另一半通道进行一些操作; 还有将通道 concat 起来以后进行 group=2 的 channel shuffle 的操作,来增加通道之间的混合,我都有在自己尝试的网络结构中试验过,不过都是在不同情境下独立的去添加进网络进行实验,碍于种种原因,效果都不尽如人意,现在自己得网络也没有一个满意的结果。现在在这个文中看到这么熟悉的操作,奈何自己还是才疏学浅,不免很是心痛。而且文中很多准则的验证,完全是抛弃准确率的前提下,测试速度对比数据就行,设计一些简单的但是具有代表性的结构就可以去实验来佐证或者是验证自己的一些想法,不用思维总局限于从复杂的网络或者基于别人的网络开始实验,那样不确定因素还是有很多,很容易得到得结果就不是自己想要得。 Anyway ,感慨良多,还是要加油啊!