1 引入
DenseNet是2017年计算机视觉顶会的年度最佳论文。 论文链接:DenseNet论文 代码的github链接:DenseNet代码
DenseNet想法的由来在很大程度上是来自随机深度网络(Deep networks with stochastic depth),当时提出了一种类似于 Dropout 的方法来改进ResNet。在训练过程中的每一步都随机地「扔掉」(drop)一些层,可以显著的提高 ResNet 的泛化性能。这个方法的成功至少带给DenseNet两点启发:
首先,它说明了神经网络其实并不一定要是一个递进层级结构,也就是说网络中的某一层可以不仅仅依赖于紧邻的上一层的特征,而可以依赖于更前面层学习的特征。
其次,在训练的过程中随机扔掉很多层也不会破坏算法的收敛,说明了 ResNet 具有比较明显的冗余性,网络中的每一层都只提取了很少的特征(即所谓的残差)。实际上,我们将训练好的 ResNet 随机的去掉几层,对网络的预测结果也不会产生太大的影响。既然每一层学习的特征这么少,能不能降低它的计算量来减小冗余呢?
——>DenseNet 的设计正是基于以上两点观察。
我们让网络中的每一层都直接与其前面层相连,实现特征重用;
同时把网络的每一层设计得特别「窄」,即只学习非常少的特征图(最极端情况就是每一层只学习一个特征图),达到降低冗余性的目的。
2 DenseNet模型结构
DenseNet:以前馈的方式,将层与层都连接起来(so需要具有匹配的feature-map大小),它建立的是前面所有层与后面层的密集连接(dense connection)。如下图所示。
DenseNet脱离了加深网络层数(ResNet)和加宽网络结构(Inception)来提升网络性能的定式思维,从特征的角度考虑。 整个网络主要包含了三个核心结构:
DenseLayer/bottleneck层:模型中的原子单元,利用卷积完成一次最基础的特征提取
DenseBlock:整个模型密集连接的基础单元,由多个原子单元构成,整个网络最核心的部分
Transition层:通常用于两个相邻的DenseBlock之间,主要的两个作用是减小特征图的大小和特征图的数量
实际上主要由DenseBlock+Transition组成。
DenseBlock(定义了输入输出如何连接) 是包含很多层的模块,每个层的特征图大小相同,层与层之间采用密集连接方式。
Transition模块(控制通道数) 是连接两个相邻的Dense Block,并且通过Pooling使特征图大小降低。
3 DenseBlock
DenseBlock模块其实就是堆叠一定数量的DenseLayer层,不同DenseLayer层之间会发生密集连接。 在一个DenseBlock内部(即特征图大小都相同),将所有的DenseLayer层都进行连接,即第一层的特征会直接传输给后面的所有的层,后面的层会接受前面所有层的输出特征。
3.1 公式
假设输入为一个图片 x 0 x_0 x0,经过一个L层的神经网络,第l层的输入特征图记作 x l − 1 x_{l-1} xl−1,第l层的特征输出记作 x l x_l xl。
对于传统的网络: x l = H l ( x l − 1 ) x_l = H_l(x_{l-1}) xl=Hl(xl−1),其中 H l H_l Hl