本文共 3278 字,大约阅读时间需要 10 分钟。
DenseNet是2017年CVPR的最佳论文,它不同于ResNet中的残差结构,也不同于GoogLetNet中的Inception网络结构。DenseNet提出了一种新的提升性能的思路,即作者通过对特征层的极致利用,使模型有了更好的性能,并且相比ResNet进一步减少了参数,提高了性能,特征层的极致利用表现在更密集的特征连接,密集连接也是本篇文章的核心。让我们一起来学习它吧。
论文地址:
下图为DenseNet网络结构简单描述,我们可以看出它由多个DenseNet Block组成。
分析:图中X0,X1,X2,X3,Xi-1表示特征图,Hi表示非线性变换,非线性变换H是BN+ReLU+Conv(1×1)+Conv(3×3)的组合,[]表示将所有输出的特征层按通道组合拼接在一起,在一个卷积模块乃至整个Dense Block中,特征尺寸不变,这是为了拼接Concat时方便,1×1与3×3卷积,借鉴了以前的经典网络中减少参数的办法,算是一个小trick,现在网络基本都会用1×1和3×3来降低参数。
def dense_block(x, blocks, name): for i in range(blocks): x = conv_block(x, 32, name=name + '_block' + str(i + 1)) return xdef conv_block(x, growth_rate, name): bn_axis = 3 x1 = layers.BatchNormalization(axis=bn_axis, epsilon=1.001e-5, name=name + '_0_bn')(x) x1 = layers.Activation('relu', name=name + '_0_relu')(x1) x1 = layers.Conv2D(4 * growth_rate, 1, use_bias=False, name=name + '_1_conv')(x1) x1 = layers.BatchNormalization(axis=bn_axis, epsilon=1.001e-5, name=name + '_1_bn')(x1) x1 = layers.Activation('relu', name=name + '_1_relu')(x1) x1 = layers.Conv2D(growth_rate, 3, padding='same', use_bias=False, name=name + '_2_conv')(x1) x = layers.Concatenate(axis=bn_axis, name=name + '_concat')([x, x1]) return x
代码中有个for循环,表示由多少个卷积模块组成。即卷积模块重复多少次。
对比ResNet
ResNet公式如下Transition layer由BN + Conv(1×1) +2×2 average-pooling组成。Transition Layer将不同DenseBlock之间进行连接的模块,主要功能是整合上一个DenseBlock获得的特征,缩小上一个DenseBlock的宽高,达到下采样效果,特征图的宽高减半。
注:再次重申一下,作者希望各个Dense Block内的 feature map 的大小统一,这样做concatenation就直接堆叠即可,不必考虑size问题。也就是每一个Dense Block中的feature map 尺寸一样。
实现代码:
def transition_block(x, reduction, name): bn_axis = 3 x = layers.BatchNormalization(axis=bn_axis, epsilon=1.001e-5, name=name + '_bn')(x) x = layers.Activation('relu', name=name + '_relu')(x) x = layers.Conv2D(int(backend.int_shape(x)[bn_axis] * reduction), 1, use_bias=False, name=name + '_conv')(x) x = layers.AveragePooling2D(2, strides=2, name=name + '_pool')(x) return x
有了前面的知识,我们可以分析整个DenseNet网络结构了。
整个结构由一开始的卷积Convolution(7×7卷积核,步长为2),再接一个池化Pooling,之后就是多个DenseBlock和Transition Layer,DenseBlock进行密集连接,而Transition Layer进行整合,并下采样average pool。最后7×7average pool后,加一个全连接fully-connected,这个全连接用softmax作为激活函数,也可以视为softmax层。
转载地址:http://qjip.baihongyu.com/