目录
- 1 研究背景
- 1.1 提出的动机
- 1.2 同期的模型
- 2 网络模型
- 2.1 模型架构
- 2.2 模块与参数
- 2.3 瓶颈层和压缩率
- 2.4 小结
- 3 实验结果
- 4 优点与缺点
- 4.1 DenseNet 的优点
- 4.2 DenseNet 的缺点
前言:本博客仅为组会总结,如有谬误,请不吝指出!
DenseNet 论文地址:https://arxiv.org/pdf/1608.06993
1 研究背景
1.1 提出的动机
DenseNet 在 2017 年被提出,与 Transformer 处于同一时期
卷积网络在加深的过程会出现两个主要问题:
- ① 正向传播的信息流在向更深层网络的传递过程中会逐渐消失,深层网络没有得到有效利用;
- ② 深层网网络中,反向传播的梯度会消失或爆炸,导致训练困难深层权重难以更新。
ResNet (2015) 提出了残差连接机制用于解决以上两个问题:
x l = H l ( x l − 1 ) + x l − 1 \mathrm{x}_{l}=H_{l}(\mathrm{x}_{l-1})+\mathrm{x}_{l-1} xl=Hl(xl−1)+xl−1
该机制通过引入直接路径,显著缓解了反向传播中的梯度消失问题,也一定程度上通过直接引入原始输入解决了信息流的正向传播中的信息流失问题。
继 2015 年 ResNet 被提出后,神经网络的研究重点从加深网络转向提高网络效率。
DenseNet 其实采用的也是残差连接的思想,只是觉得 ResNet 做得不够好。
1.2 同期的模型
ResNet (2015) 表明,如果卷积网络在靠近输入的层和靠近输出的层之间包含更短的连接,那么它们可以更深入、更准确、更有效地训练。
在 ResNet 被提出后,同时期的神经网络都采用了类似残差连接的思想来加深,建立了从早期层到后期层的直接连接路径,包括:
- Highway Network:同样采用了残差连接,只是还应用了门控机制。
- Stochastic Depth:对 ResNet 实施随机丢弃网络层的方法,加强信息流的传递和反向传播。
- FractalNet:通过构建多个并行的卷积层序列,按分形结构并行递归组合,不同深度的路径交织在一起,形成了许多从输入到输出的短路径。
好奇 FractalNet 的模型架构:
2 网络模型
2.1 模型架构
DenseNet 采用密集连接、特征重用的方式来解决在神经网络加深时遇到的两个问题
Dense Block:
- DenseNet 在具有相同特征图大小的任何两个层之间引入了直接连接;
- 对于含 L L L 层的传统卷积网络,层之间有 L L L 条连接(算上了用于输出的连接);
- 对于含 L L L 层的 DenseBlock,层之间有 ( L + 1 ) ∗ L / 2 (L+1)*L/2 (L+1)∗L/2 条连接(算上了用于输出的连接)。
C L + 1 2 = ( L + 1 ) × L 2 × 1 C_{L+1}^{2}=\frac{(L+1)\times L}{2\times 1} CL+12=2×1(L+1)×L
说明:计算结果中包含了 DenseBlock 到过渡层的连接。
2.2 模块与参数
- DenseBlock:包含批量归一化、ReLU 和卷积,以及将之前层的输出拼接到当前的输入中。
- Transition Layer:过渡层,位于 DenseBlock 之间,包含 1×1 卷积和池化。其中,1×1 卷积用于在保持空间特征的前提下减少特征通道数,池化用于缩小特征图的大小。
- Growth Rate k:成长率,表示每一层生成的特征图(通道)的数量。之所以叫作成长率,是因为 DenseNet 采用特征拼接的方式,每经过一层网络,输出通道数就会增加 k 层。
和 ResNet 的残差连接机制不同,DenseNet 直接对输入进行拼接而不是相加,这是因为 DenseNet 认为直接相加其实在一定程度上破坏了信息传播中的完整性。
比如,第 l l l 层的输出为:
x l = H l ( [ x 0 , x 1 , . . . , x l − 1 ] ) \mathrm{x}_{l}=H_{l}(\left [ \mathrm{x}_{0},\mathrm{x}_{1},...,\mathrm{x}_{l-1} \right ]) xl=Hl([x0,x1,...,xl−1])
由上式可知,第 l l l 层的原始输入为 x l − 1 \mathrm{x}_{l-1} xl−1,特征拼接后的输入为 [ x 0 , x 1 , . . . , x l − 1 ] \left [ \mathrm{x}_{0},\mathrm{x}_{1},...,\mathrm{x}_{l-1} \right ] [x0,x1,...,xl−1],而第 l l l 层的输出 x l \mathrm{x}_{l} xl 将作为第 l + 1 l+1 l+1 层的原始输入。
更进一步地,第 l l l 层的输入通道数为:
C i n l = C i n l − 1 + k = C i n l − 2 + 2 k = . . . = C i n 0 + ( l − 1 ) × k \begin{alignat}{2} \nonumber \mathrm{Cin}_{l} &=\mathrm{Cin}_{l-1}+k \\ \nonumber &=\mathrm{Cin}_{l-2}+2k \\ \nonumber &= ... \\ \nonumber &=\mathrm{Cin}_{0}+(l-1)\times k \end{alignat}{} Cinl=Cinl−1+k=Cinl−2+2k=...=Cin0+(l−1)×k
其中 C i n l \mathrm{Cin}_{l} Cinl 是指原始输入, k k k 是指每层的输出通道数为固定值 k k k 。也就是说,当前层的输入,等于上一层的输入(通道数为 C i n l − 1 \mathrm{Cin}_{l-1} Cinl−1)和上一层的输出(通道数为 k k k)的拼接结果。
说明:一个特征图就是一个通道,输出的特征图的个数就是输出的通道的个数。
下图展示了一个 5 层的 DenseBlock,其中成长率设置为 4,即每层的输出通道数为 4:
说明:之所以图中第一层的通道数为 5,是因为包含了最原始的输入 (Input),其通道数为 1 。
- 第 0 0 0 层 H 0 H_{0} H0 的输入为 I n p u t \mathrm{Input} Input,通道数为 1 1 1,输出为 x 0 \mathrm{x}_{0} x0;
- 第 1 1 1 层 H 1 H_{1} H1 的输入为 [ I n p u t , x 0 ] \left [ \mathrm{Input}, \mathrm{x}_{0} \right ] [Input,x0],通道数为 5 5 5,输出为 x 1 \mathrm{x}_{1} x1;
- 第 2 2 2 层 H 2 H_{2} H2 的输入为 [ I n p u t , x 0 , x 1 ] \left [ \mathrm{Input}, \mathrm{x}_{0}, \mathrm{x}_{1} \right ] [Input,x0,x1],通道数为 9 9 9,输出为 x 2 \mathrm{x}_{2} x2;
- 第 3 3 3 层 H 3 H_{3} H3 的输入为 [ I n p u t , x 0 , x 1 , x 2 ] \left [ \mathrm{Input}, \mathrm{x}_{0}, \mathrm{x}_{1}, \mathrm{x}_{2} \right ] [Input,x0,x1,x2],通道数为 13 13 13,输出为 x 3 \mathrm{x}_{3} x3;
- 第 4 4 4 层 H 4 H_{4} H4 的输入为 [ I n p u t , x 0 , x 1 , x 2 , x 3 ] \left [ \mathrm{Input}, \mathrm{x}_{0}, \mathrm{x}_{1}, \mathrm{x}_{2}, \mathrm{x}_{3} \right ] [Input,x0,x1,x2,x3],通道数为 17 17 17,输出为 x 4 \mathrm{x}_{4} x4;
- 过渡层的输入为 [ I n p u t , x 0 , x 1 , x 2 , x 3 , x 4 ] \left [ \mathrm{Input}, \mathrm{x}_{0}, \mathrm{x}_{1}, \mathrm{x}_{2}, \mathrm{x}_{3}, \mathrm{x}_{4} \right ] [Input,x0,x1,x2,x3,x4],通道数为 21 21 21 。
2.3 瓶颈层和压缩率
- 瓶颈层:Bottleneck Layer
- 压缩率:Compression
瓶颈层和压缩率均通过 1×1 卷积来减少特征的通道数
1)瓶颈层
如下图红框所示的是一个瓶颈层:
- 处理流程:Input→(1×1) Conv (Reduce Channels)→(3×3) Conv (Extract Features)→Output
- 降低计算复杂度:1×1 卷积减少了 3×3 卷积的输入通道数,从而减少了计算成本。
- 提高网络表达能力:3×3 卷积进一步提取了局部特征。
2)压缩率
如下图红框所示的是一个压缩率:
- 处理流程:Input→(1×1) Conv (Compression)→(2×2) Avg Pool (Reduce Resolution)→Output
- 减少模型内存占用:1×1 卷积控制 DenseBlock 输出的通道数量,防止通道数膨胀。
- 提升参数效率:池化操作用于压缩冗余特征,保留更有用的信息。
后面实验中用到的 DenseNet-BC 是指应用了瓶颈层和 0.5 倍压缩率的 DenseNet 。
2.4 小结
- 从信息流层面看:通过特征拼接,DenseNet 的每一层都能直接访问之前所有层的输出,每一层都能直接利用之前层提取的特征,避免了特征在传递过程中的丢失,保证了特征的高效复用。
- 从梯度流层面看:由于密集连接中的短路径,DenseNet 的每一层都直接与损失函数相连,使梯度能直接从损失函数高效传播到网络深层,深层网络每一部分都能接收到强梯度信号。
3 实验结果
实验使用了三个图像分类数据集,分别是:CIFAR、SVHN 和 ImageNet
1)CIFAR 和 SVHN
可以看出,拿来做对比的都是离 2017 年最近的模型。
2)ImageNet
相较于 ResNet,DenseNet 通常以更少的参数和较低的计算成本(FLOPS)实现相同或更好的准确率。注意这里 FLOPs 的含义,它是在验证时测量的,也就是说不涉及反向传播(训练)的计算成本。
说明写论文的时候要学会避重就轻。
4 优点与缺点
4.1 DenseNet 的优点
- 左图说明:瓶颈层和压缩率能够在保证效果接近的情况下,减少 DenseNet 的参数量;
- 右图说明:与 ResNet 相比,DenseNet 模型更加紧凑,实现相同效果所需的参数更少。
下图计算结果是 DenseNet 卷积层的平均绝对权重,不同的颜色表示第 l l l 层对之前的第 s s s 层的依赖性大小,即第 l l l 层分配给第 s s s 层的平均绝对权重:
三个子图中的第一行表示的是每个 DenseBlock 的输入。
上图表明:
- ① 早期层的特征有被复用,用于提高网络表示能力。
- ② 过渡层保留了特征,同时存在许多冗余信息,所以 DenseNet-BC 有效。
- ③ 分类层采用的大多是较高层的信息,而较高层提取的是高级特征。
4.2 DenseNet 的缺点
1)正向传播的内存消耗
- 对于含 L L L 层的网络,假设每层输出的特征图大小为 F F F,那么 DenseNet 对特征图的存储需求为 O ( F × L ) O(F×L) O(F×L),这是因为 DenseNet 需要使用前面所有层的特征图,而 ResNet 约为 O ( F ) O(F) O(F) 。
- 缩小特征图的内存消耗其实是过渡层的主要作用,但论文主要强调的是其去除冗余层的作用。
过渡层的 1×1 卷积减少了通道(特征图)数,从而缩小了特征图的内存消耗。
2)训练时的计算成本
- 论文计算的是 FLOPs 消耗,即验证推理时的计算消耗,而没有讨论训练时反向传播的计算消耗。然而 DenseNet 的特征复用特点意味着,反向传播时需要考虑所有特征图被纳入计算的对应层,很吃运行内存。
- 本文考虑的是较为简单的图像分类任务,比 ResNet 好的前提是实验环境中的计算资源(如内存)足够支持 DenseNet 的运行。
DenseNet 默认的 k=32,因此 DenseBlock 块中特征图数量的增长其实相当快,比如 24×32,即一个 DenseBlock 块中有 24 层。