DenseNet学习笔记
论文题目:Densely Connected Convolutional Networks
论文作者:Gao Huang, Zhuang Liu, Kilian Q. Weinberger, Laurens van der Maaten
论文地址:https://arxiv.org/abs/1608.06993
论文代码:liuzhuang13/DenseNet
前言
DenseNet是2016年提出来的新的网络结构,它受到ResNet、Highway Net的启发,提出了将每个卷积层网络的输入变为前面所有网络的输出的拼接。这样稠密的连接方式可以使得每一层都可可以利用之前学习到的所有的特征,不需要重复学习。同时由于仿照ResNet的这种结构可以使得梯度更好的传播,使得训练深层网络更加方便。
网络结构
图1 Dense Block结构
由上图可以看出,该示例网络中每一条细线都代表着数据的流动,左上角是输入,右下角是输出,中间每一层网络的输出都由它前面所有的网络组成,这里的组成代表concat。在resnet中shortcut与某一层的输出是相加的(element wise addition),但是这里仅仅是将来自不同层的输出按照channal的方向拼接起来(和inception结构中最终将每个branch拼接起来是一样的操作,在tensorflow中通常使用 tf.concat() 函数来进行拼接)。
与Resnet的不同
将 记作第
层的输出,
记作第
层的输出,
表示第
层的非线性映射。
Resnet可以写作下面的式子(其中加号代表 和
对应位置的元素相加):
Desnet则可以写为:
可以看出Denset是将前面 到
层输出的所有feature map进行拼接,然后作为第
层的输入。
图2 Desnet 结构示意图
由于在进行feature map拼接的过程中要求每个feature map的长、宽相同。因此作者仿照ResNet,设计了Dense Block结构。如图1所示,在Dense Block 内部,通过padding使得feature map的长宽不变,然后将来自前面几层的拼接起来。
图3 Dense Block 结构图
如图3所示,Dense Block 内部的结构图。其中BN代表Batch normalization。这里的k代表k个feature map,在论文中作者也把k称作增长率(growth rate),k的大小控制了在dense bolck中每一层输出多少feature map,也就是将多少信息传递下去。同时也决定了dense bolck中位于后面的网络的输入信息量大小。
由图3可以看出,在Dense block内部所采用的结构为BN->RELU->CONV(1x1)->BN->RELU->CONV(3x3),使用了这种结构的网络,作者在文章中记为DenseNet-B。在Dense block内部,采用的bottleneck结构(1*1卷积)进行降维,这里作者将1*1卷积层输出的feature map数量设置为4k个,1*1卷积层输出的feature map数量设置为k个。
在不同的Dense block之间,作者采用了1*1的卷积和pooling层进行降维操作。假设上一个Dense block输出的feature map有m个,经过1*1卷积之后,feature map数量变为 个。在实验中作者取了
,即将feature map的数量降低一半,并且将使用了这种设置的网络记为DenseNet-C。DenseNet-BC就是同时满足DenseNet-B和DenseNet-C设置的网络。
图4 用于ImageNet数据集上的DesNet结构图
上图就是作者基于Imagenet数据集搭建的各种深度的网络。具体结构细节可以使用Netscope查看shicai/DenseNet-Caffe。
实验
图5 实验结果
实验结果中所展示的是在CIFAR和SVHN数据集上的错误率(%)。k表示网络的增长率。其中加粗的是超越了其他方法的结果,用蓝色标出的是最好的结果。"+"表示标准的数据增加(翻转和镜像)。*表示结果运行由作者自己复现的结果。 没有数据增强(C10,C100,SVHN)的Densenet的所有结果都使用了Dropout。 相比于Resnet,Densetnet使用了更少的参数,同时错误率要低于Resnet。
图6 参数量与误差率与ResNet对比