利用Pytorch实现ResNeXt网络

目  录

1 ResNeXt网络介绍

1.1 组卷积

1.2 block

1.3 网络搭建

2 利用Pytorch实现ResNet网络

2.1 模型定义

2.2 训练结果


1 ResNeXt网络介绍

ResNext网络将ResNet的block替换成了组卷积

利用Pytorch实现ResNeXt网络_第1张图片

从下图可以看出,ResNeXt网络比ResNet网络的效果更好:

利用Pytorch实现ResNeXt网络_第2张图片利用Pytorch实现ResNeXt网络_第3张图片


1.1 组卷积

利用Pytorch实现ResNeXt网络_第4张图片

输入特征矩阵channel为4,则每一个卷积核的层数为4;输出的channel为n,则需要n个卷积核来进行处理,需要的参数个数为(假设每个卷积核的高和宽为k,输入特征矩阵channel为C_{in},需要n个卷积核):k\times k\times C_{in}\times n

利用Pytorch实现ResNeXt网络_第5张图片

将输入特征矩阵的channel划分成两个组,对每个组分别进行卷积操作;假设将输入特征矩阵划分成g个组,则需要的参数个数为:

k\times k\times \frac{C_{in}}{g}\times \frac{n}{g}\times g= k\times k\times C_{in} \times n\times \frac{1}{g}

当分组的个数g和输入特征矩阵channel个数C_{in}保持一致,并且输出特征矩阵的channel个数n也与输入特征矩阵的channel个数C_{in}保持一致,相当于对输入特征矩阵的每一个channel都分配了一个channel为1的卷积核进行卷积,该卷积称为DW卷积


1.2 block

利用Pytorch实现ResNeXt网络_第6张图片

以上三个block模块在数学计算上是完全等价的,以c为例:通过1×1的卷积层将输入channel从256降为128,然后利用组卷积进行处理,卷积核大小为3×3组数为32,再利用1×1的卷积层进行升维,将输出与输入相加,得到最终输出。

再看b模块,就是将第一层和第二层的卷积分组,将第一层卷积(卷积核大小为1×1,每个卷积核有256层)分为32组,每组4个卷积核,这样每一组输出的channel为4;将第二层卷积也分为32组对应第一层,每一组输入的channel为4,每一组4个卷积核输出channel也为4,再将输出拼接为channel为128的输出,再经过一个256个卷积核的卷积层得到最终输出。

对于a模块,就是对b模块的最后一层进行拆分,就是将第二层的32组的输出再经过一层(卷积核大小为1×1,每个卷积核有4层,一共有256个卷积核)卷积,再把这32组输出相加得到最终输出。


从a推到b再推到c就得到了最终的结构,对于a结构:

利用Pytorch实现ResNeXt网络_第7张图片

假设将输入的channel分为两组,每一组两层,每一组用一个层数为2的大小为1×1的卷积核卷积,将输出相加,得到一个最终输出矩阵。

对于b结构:

利用Pytorch实现ResNeXt网络_第8张图片

将a中的矩阵进行拼接,用一个层数为4的大小为1×1的卷积核卷积,得到的输出和a相同。


1.3 网络搭建

利用Pytorch实现ResNeXt网络_第9张图片

ResNeXt-50(32×4d)中的32是group数,4对应conv2中组卷积每个group的卷积核个数,从上表可以看出改进后的网络结构基本只有组卷积的变化。对于为什么将group数设置为32:

利用Pytorch实现ResNeXt网络_第10张图片

以ResNet-50和101为例,对于相同的计算量,group数增加,错误率是越来越低的。

利用Pytorch实现ResNeXt网络_第11张图片

从上图可以看出,对于只有两层的block而言,拆分没有太大作用,文章中也给予了解释。


2 利用Pytorch实现ResNet网络

2.1 模型定义

从1.3的表中可以看出,ResNeXt网络每一个convx的第一层和第二层卷积的卷积核个数是ResNet网络的两倍,在代码中增加一下两个参数(即为group数和conv2中组卷积每个group的卷积核个数),并且根据这两个参数计算出第一层卷积的输出(为ResNet网络的两倍)。

    def __init__(self, in_channel, out_channel, stride=1, downsample=None,
                 groups=1, width_per_group=64):
        super(Bottleneck, self).__init__()
        
        # ResNeXt网络每一个convx的第一层和第二层卷积的卷积核个数是ResNet网络的两倍
        width = int(out_channel * (width_per_group / 64.)) * groups

实例化ResNeXt网络时,多输入两个参数即可:

def resnext50_32x4d(num_classes=1000, include_top=True):
    groups = 32
    width_per_group = 4
    return ResNet(Bottleneck, [3, 4, 6, 3],
                  num_classes=num_classes,
                  include_top=include_top,
                  groups=groups,
                  width_per_group=width_per_group)

2.2 训练结果

ResNet-50训练结果:

利用Pytorch实现ResNeXt网络_第12张图片

ResNeXt-50(32×4d)训练结果:

利用Pytorch实现ResNeXt网络_第13张图片

从上图可以看出,训练三次的正确率ResNeXt-50(32×4d)要优于ResNet-50。

你可能感兴趣的:(pytorch,深度学习,人工智能,图像处理)