导言:
shuffleNet_v1在MobileNet_v1后,MobileNet_v2前提出。ShuffleNet系列也是针对移动端部署而提出的模型。
ShuffleNet_v1结合了深度可分离卷积和分组卷积,提出了包含pointwise group convolution 和channel shuffle两项操作的ShuffleNet Unit。其中depthwise separable convolution来源于Xception,分组卷积概念来源于AlexNet, 在ResNeXt和DeepRoots中得到很好的应用。
Shuffle channels for group convolution
在Xception和ResNeXt中使用了depthwise separable convolutions或group convolution来构建Block,以便平衡模型的表示能力和计算量。但这两者都没有完全考虑1x1卷积,因为它需要比较大的复杂性。例如,ResNeXt中group convolution只使用了3x3,这导致ResNeXt中的residual单元中的点卷积占了93.4%。在小网络中,由于内存限制,昂贵的点卷积只能使用有限的通道数,这可能会影响精度。
为了解决这个问题,shufflenet提出了通道稀疏连接。即在卷积过程中将通道数分成g组,每组只在子组内部进行连接。如下左图所示为正常的通道上的连接,右图为分组后的通道连接。
这样的分组会出现一个问题,如果分组太多,将导致输出层的每层通道都直接从上一层某一个或几个通道卷积而来(如下左图所示),这将会阻止通道组之间的信息流动并削弱模型的表示能力。解决的办法就是让不同组进行连接(如下图中所示),让不同通道组的信息充分流动。
而shuffleNet中提出更好的办法就是直接将组的顺序打乱(如上图右所示),再进行按组连接。注意:这样打乱顺序后仍然是可微的,因此这中结构可嵌入网络模型进行端到端训练。
ShuffleNet Unit
ShuffleNet中使用了残差连接,ShuffleNet Unit在残差连接的基础上调整而来。
左图为残差单元,shuffleNet Unit将1x1 卷积替代为1x1分组卷积,并在shortcut path上添加了3x3平均池化,并将逐元素相加代替为通道拼接,这样可以扩大通道数尺寸而不用增加计算成本。此外,shuffleNet Unit取消了Depthwise convolution后的ReLU, 最早是Xception中提出只能使用线性变换,而MobileNet_v2中解释了在Depthwise conv后使用ReLU会丢失较多的信息,我在公众号中详细介绍了MobileNet_v2关于使用ReLU会丢失信息的内容,可关注公众号了解。因此,最终的ShuffleNet Unit如右图所示。
ShuffleNet Unit相比于ResNet和ResNeXt,计算量减少了很多,因此在同样的计算量下,ShuffleNet可使用更宽的feature map。
如给定通道数为C, feature map大小为H x W, bottleneck channels为M, 则ResNet的计算量为HW( 2CM + 9M^2) FLOPs,ResNeXt的计算量为 HW( 2CM + 9M^2/g),而ShuffleNet Unit的计算量为 HW( 2CM/g + 9M) FLOPs,这里g是分组的数量。这里计算量可根据上方三个图来计算,如仍不知怎样得来的,可扫描文末二维码关注公众号,有一篇《FLOPS与FLOPs的区别》介绍了如何计算FLOPs。
此外,即便depthwise conv在理论上有较低的复杂性,但实际上它很难在低功耗移动设备上有效实施,这可能是由于与其他密集操作相比,计算/内存访问比更差。因此,在ShuffleNet Unit中depthwise conv仅仅在bottleneck上使用,以尽可能地减少开销。
ShuffleNet结构
最后一栏的Complexity是FLOPs,在Stage2,在第一个点卷积层没有使用分组卷积,这是因为输入通道数相当小。每一Stage都在上一Stage的通道数上加倍。g越大表示在有限的计算量中编码信息越多,但不能太大,否则会出现前面提到的问题。
结论
这里ShuffleNet后的数字表示卷积核数的比例因子s。这个比例因子s可用来控制模型大小。计算量会是原来的s^2倍。
实验证明分组数越多,错误率会越低,且有shuffle比没有shuffle错误率更低。
ShuffleNet比同计算量的其他模型错误率更低。
ShuffleNet2x比MobileNet_v1效果更好(计算量更少,且错误率更低)。
如有错误或疑问,欢迎留言指出。