ResNeXt 学习——ResNeXt50

  Github:https://github.com/windandscreen/deepmodel

  本文是在讲解如何实现ReNeXt50网络,并未讲述其原理,想要了解其原理,请查阅相关论文。

ResNeXt 学习——ResNeXt50_第1张图片

  上图是ResNet50和ResNeXt50结构的比较,在conv2_x这一行,kernel_filters的数量分别是128,128,256,ResNeXt提出了cardinality=32和depth=4,意思是,将残差块分为32个paths进行卷积,结构对比如下图

ResNeXt 学习——ResNeXt50_第2张图片

  上图是一种结构,还要两种等价的结构,如下图,我的代码在用的是第三种结构,这种方式叫做分组卷积。

ResNeXt 学习——ResNeXt50_第3张图片

  第三种方式,是将残差块的中间那个卷积分组进行卷积,如何拼接起来,在进行下一个卷积,代码的实现也非常简单,值得注意的是,卷积核的数量和ResNet不是完全一样,可以好好看看第一幅图片。

def block3(x, filters, stride=1, cardinality=32, conv_shortcut=True, name=None):
    bn_axis = 3 if backend.image_data_format() == 'channels_last' else 1

    if conv_shortcut is True:
        shortcut = layers.Conv2D(2 * filters, 1, strides=stride,
                                 name=name + '_0_conv')(x)
        shortcut = layers.BatchNormalization(axis=bn_axis, epsilon=1.001e-5,
                                             name=name + '_0_bn')(shortcut)
    else:
        shortcut = x

    x = layers.Conv2D(filters, 1, strides=stride, name=name + '_1_conv')(x)
    x = layers.BatchNormalization(axis=bn_axis, epsilon=1.001e-5,
                                  name=name + '_1_bn')(x)
    x = layers.Activation('relu', name=name + '_1_relu')(x)

    input = x
    group_list = []
    grouped_channels = filters // cardinality
    for c in range(cardinality):
        x = layers.Lambda(lambda z: z[:, :, :, c * grouped_channels:(c + 1) * grouped_channels])(input)

        x = layers.Conv2D(grouped_channels, 3, padding='same', use_bias=False, name=name + '_2_conv_path' + str(c+1))(x)

        group_list.append(x)

    group_merge = layers.concatenate(group_list, axis=-1)

    x = layers.BatchNormalization(axis=bn_axis, epsilon=1.001e-5,
                                  name=name + '_2_bn')(group_merge)
    x = layers.Activation('relu', name=name + '_2_relu')(x)

    x = layers.Conv2D(2 * filters, 1, name=name + '_3_conv')(x)
    x = layers.BatchNormalization(axis=bn_axis, epsilon=1.001e-5,
                                  name=name + '_3_bn')(x)

    x = layers.Add(name=name + '_add')([shortcut, x])
    x = layers.Activation('relu', name=name + '_out')(x)
    return x

  实现了残差块后,其它代码就方便许多了,我已经上传到Github。 

你可能感兴趣的:(深度神经网络)