DenseNet模型讲解

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)来提升网络性能的定式思维,从特征的角度考虑。
DenseBlock
整个网络主要包含了三个核心结构:

  • DenseLayer/bottleneck层:模型中的原子单元,利用卷积完成一次最基础的特征提取
  • DenseBlock:整个模型密集连接的基础单元,由多个原子单元构成,整个网络最核心的部分
  • Transition层:通常用于两个相邻的DenseBlock之间,主要的两个作用是减小特征图的大小和特征图的数量

实际上主要由DenseBlock+Transition组成。
DenseNet模型组成

  • 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} xl1,第l层的特征输出记作 x l x_l xl

  • 对于传统的网络: x l = H l ( x l − 1 ) x_l = H_l(x_{l-1}) xl=Hl(xl1),其中 H l H_l Hl是一个组合函数,通常包括BN、ReLU、Pooling、Conv操作。
    在这里插入图片描述

  • 对于ResNet: x l = H l ( x l − 1 ) + x l − 1 x_l = H_l(x_{l-1}) + x_{l-1} xl=Hl(xl1)+xl1
    ResNets

  • 对于DenseNet: x l = H l ( [ x 0 , x 1 , ⋯   , x l − 1 ] ) x_l = H_l([x_0,x_1,\cdots,x_{l-1}]) xl=Hl([x0,x1,,xl1])
    在这里插入图片描述
    其中[]代表拼接操作,既将第0层 到 l-1层的所有输出特征图在通道维度上组合在一起。这里所用到的非线性变换 H l H_l Hl为BN +ReLU+3×3Conv的组合。

DenseNet的前向过程如下图所示,可以更直观地理解其密集连接方式,如 h 3 h_3 h3的输入不仅包括来自 h 2 h_2 h2 x 2 x_2 x2,还包括前面两层的 x 0 x_0 x0 x 1 x_1 x1,它们是在channel维度上连接在一起的。
​​​​​​Densenet前向传播过程
在这里插入图片描述

因为是直接跨通道直接做concat,所以要求不同层concat之前他们的特征图大小应当是相同的,
所以DenseNet分为了好几个Dense Block,每个Dense Block内部的feature map的大小相同,
而每个Dense Block之间使用一个Transition模块来进行下采样过渡连接。 

3.2 增长率

DenseBlock中各个层卷积之后均输出 k 个特征图,即得到的特征图的channel数为 k,或者说采用 k 个卷积核。 k 在DenseNet称为growth rate,这是一个超参数。论文表明一般情况下使用较小的 k,就可以得到较佳的性能。

假定输入层的特征图的channel数为 k 0 k_0 k0 ,Dense Block中各个层卷积之后均输出 k 个特征图,即每层得到的特征图的channel数为k。那么l层输入的channel数为 k 0 + k × ( l − 1 ) k_0 + k \times (l − 1) k0+k×(l1)
在这里插入图片描述
注:
每一层都可以访问其块中的前面所有的特征图,即可以访问网络的全局知识。如果将特征图视为网络的全局状态,每一层都将自己的k个特征图添加到全局状态中。
增长率控制了每一层向全局状态贡献的新信息的数量。
一旦写入全局状态,就可以从网络中的任何地方访问它,并且与传统的网络体系结构不同,无需将其逐层复制。

3.3 Bottleneck层

目的:随着层数增加,concat后的通道数会增加到上千。尽管 k 设定得较小,但DenseBlock的输入会非常多,DenseBlock内部可以采用bottleneck层来减少计算量

方法:主要是在原有的结构(下图第一张)前面增加1x1 Conv,即BN+ReLU+1x1 Conv + BN+ReLU+3x3 Conv,称为DenseNet-B结构(下图第二张)。
原有结构
在这里插入图片描述
其中 1 × 1 1 \times 1 1×1 Conv得到 4 × k 4 \times k 4×k 个特征图,目的是减少输入的feature map数量,既能降维减少计算量,又能融合各个通道的特征。

如果不增加1×1的卷积来降维,后续3×3卷积所需的参数量会急剧增加。

举例:
以DenseNet-121(6,12,24,16)的Dense Block(1)为例,包含6个 1 × 1 1 \times 1 1×1 3 × 3 3 \times 3 3×3的卷积操作,也就是6个Bottleneck层。输入通道数 是64,增长率k=32。
经过6个Bottleneck,通道数输出是64+6*32=256。

如果不使用 1 × 1 1 \times 1 1×1 Conv,参数量是: 3 × 3 × 256 × 32 = 73 , 728 3\times3\times256\times32=73,728 3×3×256×32=73,728
如果使用 1 × 1 1 \times 1 1×1 Conv,代码中的 1 × 1 1 \times 1 1×1 Conv的输出channel是 4 × k 4 \times k 4×k,也就是128,然后再作为3*3卷积的输入。参数量是: 1 × 1 × 256 × 128 + 3 × 3 × 128 × 32 = 69 , 632 1\times1\times256\times128+3\times3\times128\times32=69,632 1×1×256×128+3×3×128×32=69,632。使用bottleneck就大大减少了计算量。

注:
DenseBlock中采用BN+ReLU+Conv的结构,平常我们常见的是Conv+BN+ReLU。
原因是:卷积层的输入包含了它前面所有层的输出特征,它们来自不同层的输出,因此数值分布差异比较大,所以它们在输入到下一个卷积层时,必须先经过BN层将其数值进行标准化,然后再进行卷积操作。

4 Transition

将DenseNet划分为多个Dense Blocks,而块之间的称为转换层,即Transition层,用于卷积和池化
transition layer用于两个Dense Block中间。

4.1 Pooling layers——池化层

Transition层主要包括一个1x1的Conv和2x2的AvgPooling。其结构为BN+ReLU+1x1 Conv + 2x2 AvgPooling。

  • 1 × 1 1 \times 1 1×1 Conv负责降低通道数。这是因为每个Dense Block结束后的输出channel个数很多,需要用1*1的卷积核来降维。
  • 2 × 2 2 \times 2 2×2 AvgPool负责改变特征图尺寸,减半。作用: 通过池化操作从而减少了特征和参数数量;实际上就是过滤掉那些作用小、信息冗余的特征,保留关键信息。

4.2 Compression——压缩

目的:为了进一步提高模型的紧凑性,可以减少转换层的特征图数量。
方法:引入一个压缩因子 θ \theta θ (0 < θ \theta θ ≤1),

  • θ \theta θ = 1 时,转换层的输入和输出特征数不变,也就是经过转换层后特征数不变;
  • θ \theta θ < 1 时,输入特征图数为m时,输出为⌊ θ m \theta_m θm⌋。将 θ \theta θ < 1 的DenseNet称为DenseNet-C (DenseNet论文中设置θ=0.5)。

将Dense Block+bottleneck+Translation的模型称为DenseNet-BC。

DenseNet-B已经压缩了,为什么还要提出DenseNet-C?
——>瓶颈层是指用于dense block内的 H ( ⋅ ) H(\cdot) H()压缩,而压缩是指在转换层进行压缩。

5 总结

DenseNet:

  • 密集块:DenseNet将网络分成多个密集块(Dense Block)。在每个密集块内,每一层都连接到前面所有的层。这种跳跃连接有助于解决梯度消失问题,因为每一层都可以直接访问之前层的梯度信息,使得训练更加稳定。
  • 过渡层:在密集块之间,通常会使用过渡层来控制特征图的大小,从而减少计算量。

优点:

  1. 网络可以更好地利用浅层特征信息,加强了特征传播,提高了特征重用的能力,从而提高网络的性能。
  2. 网络具有更强的特征重用能力,可以减少参数数量,降低过拟合风险。
  3. 网络训练更加稳定,可以缓解梯度消失和梯度爆炸等问题。
  4. 改善了整个网络中的信息流和梯度,由于密集连接方式,DenseNet提升了梯度的反向传播,使得网络更容易训练。每一层都可以直接访问损失函数和初始输入。
    在这里插入图片描述

缺点:

  1. 因为有稠密直连的过程,所以各个feature都要存下来,实际上很容易爆显存。
  2. 另外,这种密集连接也意味着反向传播计算梯度更加复杂,每一步训练并不一定会更快。
  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值