本文假设你已经对DenseNet的网络结构有一定的认识,不需要进行详细的结构介绍,本文重心在与如何使用DenseNet、参数细节介绍,以及作者是如何训练得到令人惊讶的结果的。卷积网络目前发展分为两类,以inception为典型的并行结构与ResNet为典型的串行结构,作者以一个新颖的思路发明了一种新的网络结构,比其他经典网络参数更少,更容易收敛。
超参数
DenseNet的作者认为ResNet的恒等函数与输出H通过加法联系到一起,可能会阻碍信息的流动。而DenseNet的这个结构正好可以改善这种情况。
如果把DenseNet当做黑盒子来使用的话,你需要了解一些重要的参数,growth_rate与depth。增长率与深度,增长率的大小决定了当前层的输出维度。而depth很显然代表了你创建的网络深度。如果你了解ResNet的基础知识话,就会知道残差网络是以残差块为一个单位进行组织,DenseNet同样如此,total_blocks参数代表将会有多少block。
这里写图片描述
通过此图,我们可以看到有3个block,growth_rate为5。DenseNet通过卷积与平均池化,接连两个block。keep_prob是dropout的参数,不仅使用了dropout正则化,而且还使用了BN正则化。记得inception-v3网络中使用的BN代替了dropout,理由是BN已经有正则化效果了,不需要dropout,此外作者还用到了L2正则化。从此点来看,作者明显没有受到前人的约束勇于创新。结构如下,BN+Relu+Conv+Dropout
weight_decay是BN中的权重衰减系数,一般设置为0.9、0.95。nesterov_momentum参数是动量梯度下降的参数,但是我查看论文作者使用的还是SGD,这让我想起了之前有个争论,Adam到底好不好?有的科研人员验证出Adam是最好的梯度下降方法,也有另外一派,找出了Adam失效的特殊情况。果然还是SGD最靠谱。model_type参数是使用DenseNet还是使用DenseNet-BC,这两个网络的区别还是要从原文中来看,作者为了使得模型更加的紧凑,如果denseblock有k个特征映射,也就是维度数,把连接两个block的层我们称为transition层,通过这个层进行特征降维,输出Qk 维,Q
训练细节
除了 ImageNet数据集,作者训练其他的数据集使用3个dense blocks,并且每个block中层数相同,在第一个dense block之前的第一层卷积网络输出16个channel(或者两倍的增长率,使用DenseNet-BC网络),核的大小为33,使用11卷积后接22的平均池化作为连接两个block 的transition层。对于L(深度)与k(增长率),作者使用的有(40,12)、(100,12)、(100、24)。对于DenseNet-BC参数设置为(100,12),(250,24),(190,40)。对于ImageNet数据集,作者训练的方式如下:使用4个dense block ,input大小为224224,初始化第一层卷积是由输出维度为2k,卷积核大小为7*7,步长为2,剩下的featrue-maps(特征映射大小设置为k)
这里写图片描述
,此外还有一处区别,就是红框画出的部分,并不是每个block层数都相同。这个可能需要你自己设置。我翻阅了基于tensorflow DenseNet 论文源码实现,写的最好的还是这篇,这篇将DenseNet-BC考虑进去了,所有的tensorflow实现中所有的block的层数都相同,所以如果你发现了不要困惑,因为非ImageNet数据集都使用这种方式,这也许给了我们一些启示,如果你做迁移学习的时候,类别并不是很多,图像也不是很复杂,那就完全没有必要使用上面的复杂结构。我测试了MINST数据集,2个block,效果能达到98%,还真是令人吃惊不是吗?点击下载论文
总结
觉得很有必要一起研读网络实现源码,从中体会到更特别的感触,总的来说DenseNet的网络实现,还是比较简单的,与Inception不同,inception不仅要考虑分支,还要考虑辅助节点,确实很复杂,与ResNet搭建一样简单,封装好block之后就可以happy的搬砖了,遗憾的是我并没有找到DenseNet已经训练好的模型参数,如果有模型参数的话可能几次epoch就能收敛到不错的效果。下面是整个网络的构建过程,逻辑比较清晰没有复杂的结构,点击我查看DenseNet源码。如果还比较困惑可以对照着论文,一目了然,本人能力有限,如果有瑕疵请指出,欢迎与我讨论学习
领取专属 10元无门槛券
私享最新 技术干货