ShuffleNet的pytorch实现
1.概述
ShuffleNet
是一个专门为移动设备设计的CNN模型,主要有两个特性:
1.pointwise( 1 × 1 1\times1 1×1) group convolution
2.channel shuffle
它能够在减少计算量的同时保持精度。
剪枝(pruning),压缩(compressing),低精度表示(low-bit representing)
使用pointwise group convolution
来降低 1 × 1 1\times1 1×1卷积的计算复杂度。为了克服分组卷积(group conv)
的副作用(side effect),提出了一种高效的操作——通道混洗(channel shuffle)来提高信息在特征层面的流动。
fig.1. (a)分组卷积(GConv);(b)、(c)通道混洗
1.1通道混洗
通道混洗:通道混洗可以直接通过换轴
来实现。😄
为什么要通道混洗
在ResNeXt
中,只有 3 × 3 3\times3 3×3的卷积使用了分组卷积,导致最终pointwise conv,也就是 1 × 1 1\times1 1×1卷积占用了 93.4 % 93.4\% 93.4%的的乘加操作。在小型网络中,pointwise conv将会限制网络的复杂度,最终导致精度降低。为了解决这个问题,当然可以直接对 1 × 1 1\times1 1×1卷积使用分组卷积甚至通道分离卷积。但是,这将会带来一个副作用:当多个分组卷积堆叠到一起时,后面的卷积层的某个通道的输入将只会来源于一小部分浅层网络的输出。这将会削弱通道层面的信息流通,弱化模型表征能力。
1.2 ShuffleNet Unit
fig.2 (a)使用分离卷积的瓶颈层(DWConv),(b)使用pointwise group卷积和通道混洗的ShuffleNet层;(c)步长为2的ShuffleNet层。
(a)是一个残差块, 3 × 3 3\times3 3×3使用分离卷积(ShuffleNet不使用);(b)是将 1 × 1 1\times1 1×1卷积换为分组卷积,后面跟着一个通道混洗的残差块;(c)是步长为2加了AVG Pool的最后将两个输出cat到一起的单元(dense block?),这里特征图H,W变为一半。而对于瓶颈层,将通道设为每个ShuffleNet单元输出通道的1/4;
在这里插入图片描述
根据上面的信息,我们可以得到ShuffleNet
设计模式的基本信息:
1️⃣卷积中, 1 × 1 1\times1 1×1 使用分组卷积,而 3 × 3 3\times3 3×3使用通道分离卷积,即groups=inchannel/outchannel;
2️⃣‘add‘的时候由于使用的是残差结构,所有特征图大小输入等于输出,即stride=1,padding=1,’cat‘的时候由于特征图变为原来的一半,stride=2,padding=1;所以残差结构是用来提取特征,而’cat’的结构是用来下采样的。
3️⃣通道混洗前 1 × 1 1\times1 1×1分组卷积后面是BN+ReLU,剩下的都只是BN,而ReLU都是在’add’和‘cat’之后。
4️⃣