思想来源

现代的网络设计中通常会次堆叠类似结构,如VGG,Inception,Resnet等,从而减少网络中超参数的数量,简化网络设计。

Inception使用了split-transform-merge策略,即先将输入分成几部分,然后分别做不同的运算,最后再合并到一起。这样可以在保持模型表达能力的情况下降低运算代价。

但是Inception的结构还是过于复杂了,人工设计的痕迹太重了。

然后,站得更高,分析了神经网络的标准范式就符合这样的split-transform-merge模式。以一个最简单的普通神经元为例(比如FC中的每个神经元):

CNN进行特征提取 需要进行哪些_卷积

就是先对输入的m个元素,分配到m个分支,进行权重加权,然后merge求和,最后经过一个激活。

由此归纳出神经网络的一个通用的单元可以用如下公式表示:

CNN进行特征提取 需要进行哪些_卷积_02

Ti代表任意一种变换,C是要聚合的一组转换的大小。我们称C为基数,并且指出,基数C对于结果的影响比宽度和深度更加重要。

在卷积分组也可以应用。

作者想,我直接暴力均分输入,卷积层结构都是一样的,然后再merge。这样的话我只需要告诉网络分成几组就可以了,不就不需要再设计那么精巧的Inception了吗?

CNN进行特征提取 需要进行哪些_CNN进行特征提取 需要进行哪些_03

图3中的三种结构实际上是等价的。a是ResNeXt基本单元,如果把输出那里的1x1合并到一起,得到等价网络b拥有和Inception-ResNet相似的结构,而进一步把输入的1x1也合并到一起,得到等价网络c则和通道分组卷积的网络有相似的结构。

到这里,可以看到本文的野心很大,相当于在说,Inception-ResNet和通道分组卷积网络,都只是ResNeXt这一范式的特殊形式而已,进一步说明了split-transform-merge的普遍性和有效性,以及抽象程度更高,更本质一点。

因此现在几乎所有的神经网络框架的conv层都有group这个参数,但在作者之前就是没人把这个group作为超参数调一下(这是个很有意思的问题,明明框架里有,为啥大家不试试呢)。作者后来提到之前做网络压缩的人提出过group的方法,但是却极少有人研究其精度,这篇文章是从模型表达和精度的方向上写的。

ResNeXt

具体结构

如表一中显示的,两边的网络具有相同的参数和计算量,但是右侧会有更好的精度。

CNN进行特征提取 需要进行哪些_卷积_04

分组卷积参数量计算

对输入的通道分为g组,卷积核的通道和个数都分为g组来分别对输入做卷积,最后的结果就是g组的输出,通道合并(concatenate)否就是总通道的输出。卷积核的通道分组是为了对应输入,卷积核的个数分组是为了让输出的通道分组。如图
每组,输入数据为H1×W1×C1/g,卷积核大小为h1×w1×C1/g,一共有C2/g个,输出数据为H2×W2×C2/g。

分组的方式能够增加卷积核之间的对角相关性,而且能够减少训练参数(不需要分别做33卷积了,整体做一次33,再通道切分即可),不容易过拟合,这类似于正则的效果。

举例:分组卷积极大减少了参数,比如当输入通道为256,输出通道也为256,kernel size为3×3,不做Group conv参数为256×3×3×256。实施分组卷积时,若group为8,每个group的input channel和output channel均为32,参数为8×32×3×3×32,是原来的八分之一。其实是卷积核对输入做卷积时少做了7/8的通道,局部通道。


code

nn.Conv2d中包含group参数

nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=stride, padding=1, groups=C, bias=False)

ref