ShuffleNet v1 自用笔记
CVPR 2018 ShuffleNet: An Extremely Efficient Convolutional Neural Network for Mobile Devices
Abstract
We introduce an extremely computation-efficient CNNarchitecture named ShuffleNet, which is designed speciallyfor mobile devices with very limited computing power.The new architecture utilizes two newoperations, pointwise group convolution and channel shuf-fle, to greatly reduce computation cost while maintainingaccuracy.
商汤、旷视、依图、云从是我国的AI四小龙企业,而shuffleNet正是由旷世科技提出来的模型,在边缘设备上占据了非常重要的地位,主要手段即分组卷积Group Pointwise Convolution,和通道重排Channel Shuffle。
Model
Group Convolution
分组卷积其实和深度可分离卷积很相似。普通的卷积是n*n*depth的尺寸,有多少个卷积核就有多少个输出channel。分组卷积的卷积尺寸则是n*n*(depth/k),其中k的值是人为设定的。举个例子,原先的特征图是64*64*90的,要生成一个64*64*180的新特征图,传统做法可以用180个1*1*90的卷积去生成,而对于3个组的分组卷积,只需要3*60(180)个1*1*30的卷积,这样在保证生成特征图尺寸与深度不变的情况下,直接缩减了3倍的参数量。其中60个1*1*30的卷积核去对原特征图的前30层(也就是形状为64*64*30的原特征图的1/3)做卷积生成64*64*60的特征图,中间60个生成60张,后面60张,最后将这180做concat堆叠,生成64*64*180的特征图。可以参见下图。

Channel Shuffle Operation
众所周知,近亲繁殖是个不合适的行为,在ShuffleNet也是如此,试想一下,若一直按照上述的方式做卷积,那么最后是不是就会出现类似这一个组永远之和自己这一个组里的人做卷积,特征融合呢?为了避免这种情况出现,ShuffleNet在每次分组卷积完成后,对所有的channel进行了一次重排操作,具体参见下图的(b)(c),这个看起来很直观,不过多解释!

shuffleNet基本由下述的ShuffleNet Unit构成:(b)图对应不改变特征图的size的时候的操作,左边的shortcut为普通的残差连接,直接用add,右边的分支的第一层就是1*1的分组卷积层,和上面我举得例子一样的操作;第二层就是shuffle操作,将不同组之间的channel进行重排,使各个维度的特征能充分做特征融合;第三层是一个深度可分离的使用了BottleNeck结构的卷积,大概就是先使用普通1*1卷积降维,然后用深度可分离卷积3*3*1的卷积核进行卷积,再使用1*1*depth的卷积还原到原来的维度,具体参见之前的MobileNet和ResNet。需要注意的是这里对于特征的提取非常的具象了,所以在使用激活函数的时候需要小心,在大规模神经网络中使用relu这种很"粗犷"的激活函数可能不会有副作用,但是在这种很精简,每一个数值都可能很有意义的轻量化网络中,应当尽量避免信息的丢失,更为谨慎的选择激活函数与使用非线性激活函数,在这里可以看到并不是在每一次卷积后都使用了激活函数。
(c)图对于将特征图的size减半,深度加深一倍时候的操作,这里通过stride=2的AVGpooling将原特征图进行size的减半;同时通过与(b)类似的卷积操作,但是在3*3卷积时将stride设置为2来完成size的减半;在最后将两个size减半后的特征图进行concat来完成深度的加倍。可以看到这里借鉴了googleNet中Inception模块的思路。

总结
ShuffleNet的性能是不错的,速度很快。其实这个分组卷积的操作早在AlexNet的时候就用了,当时是因为算力限制而不得不进行分组卷积来降低计算量。后续的研究基本算力上来了,就没人分组了。时过境迁,现在为了做边缘计算,轻量化网络盛行,又重新做了这个工作,shufflenet则提出了shuffle channel这个操作来解决了分组卷积的一个副作用,还是不错的。