ResNeXt
ResNext
改进点
准确率的提高
在计算量相同的情况下,错误率更低
使用了分组卷积
普通卷积
上图为普通卷积示意图,为方便理解,途中只有一个卷积核,此时输入输出数据集为:
输入特征图尺寸:\(W\times H\times C\),分别对应特征图的宽、高和通道数
单个卷积核尺寸:\(K\times K\times C\),分别对应单个卷积核的宽、高和通道数
输出特征图尺寸:\(W'\times H'\),输出通道数等于卷积核数量,输出的宽和高与卷积步长有关
参数量:\(params=K^2C\)
运算量:\(FLOPs=K^2CW'H'\)
分组卷积
将图中卷积的输入特征图分成组,每个卷积核也对应的分成组。如图所示,上面一组特征图只与上面一组卷积核做卷积,下面一组特征图只与下面的一组卷积核做卷积。每组卷积都生成一个特征图,总共生成C个特征图。
输入每组特征图尺寸:\(W\times H\times\frac Cg\),总共有\(g\)组;
单个卷积核每组尺寸:\(K\times K\times\frac Cg\),卷积核被分成了\(g\)组
输入特征图尺寸:\(W'\times H'\times g\),共生成了\(g\)个特征图
参数量\(params=K^2\times\frac Cg\times g=K^2C\)
运算量\(FLOPs=K^2\times \frac Cg\times W'\times H'\times g=K^2CW'H'\)
roup conv常用在轻量型高效网络中,因为它用少量的参数量和运算量就能生成大量的feature map,大量的feature map意味着能够编码更多的信息!
从分组卷积的角度来看,分组数就像一个控制旋钮,最小值是1,此时的卷积就是普通卷积;最大值是输入feature map的通道数\(C\),此时\(g=C\)的卷积就是depthwise sepereable convolution,即深度分离卷积,又叫逐通道卷积。
深度分离卷积
如上图所示,深度分离卷积是分组卷积的一种特殊形式,其分组数,其中是feature map的通道数。即把每个特征图一组,分别在组内做卷积,每组内的单个卷积核尺寸为,组内一个卷积核生成一个特征图。这种卷积形式是最高效的卷积形式,相比普通卷积,用同等的参数量和运算量就能够生成个特征图,而普通卷积只能生成一个特征图。
下面的block模块,它们在数学计算上完全等价
构建模型代码
def resnext50_32x4d(**kwargs: Any) -> ResNet:
# 使用32组
# 每组4个
# 最后输出通道为 int(planes * (width_per_group / 64.0)) * groups即 planes * 2
# 此时输出通道为输入通道的两倍
groups = 32
width_per_group = 4
return _resnet(Bottleneck, [3, 4, 6, 3], groups=groups, width_per_group=width_per_group, **kwargs)
def resnext101_32x8d(**kwargs: Any) -> ResNet:
# 使用32组
# 每组8个
# 输出通道为int(planes * (width_per_group / 64.0)) * groups即 planes * 4
groups = 32
width_per_group = 8
return _resnet(Bottleneck, [3, 4, 23, 3], groups=groups, width_per_group=width_per_group, **kwargs)