signed

QiShunwang

“诚信为本、客户至上”

[论文阅读] | DenseNet(侧重网络结构分析和特征图尺寸计算)

2020/12/27 21:27:34   来源:

每一个安安静静或匆匆忙忙的日子,其实都熠熠生辉呢 ——August.H

本文目录

        • 写在前面
        • 1. DenseNet设计思想
        • 2. DenseNet基本结构
        • 3. 基于ImageNet数据集的DenseNet结构
        • 4. 基于CIFAR数据集的DenseNet结构
        • 写在后面

写在前面

这周设计的网络结构是基于DenseNet的,由于采用的数据集图片的尺寸与CIFAR10数据集图片大小(32*32)接近,便想借鉴基于CIFAR10数据集的DenseNet结构。不过原论文中只给出了基于ImageNet数据集的网络结构(DenseBlcok的个数,每个DenseBlock中卷积的层数等),于是只能翻作者给出的代码来梳理基于CIFAR10的网络结构。
 
 一周的工作结束,周末想着整理一下这段时间对DenseNet的学习,主要内容包括:
 
 * 整理 DenseNet设计思想和基本结构组成;
 * 基于ImageNet数据集整理特征图尺寸的计算过程。
 
Tips:
 
  本篇博客比较适合稍微了解一些CNNs的读者,大致知道DenseNet是继ResNet之后一脉相承的深度神经网络,如果了解ResNet的设计理念,那么理解DenseNet就会很轻松。
 
 

1. DenseNet设计思想

给定符号表示:
  x l − 1 \boldsymbol{x}_{l-1} xl1: 神经网络第 l − 1 l-1 l1层的输出
  H l ( ⋅ ) H_l(\centerdot) Hl(): 神经网络第 l l l层的非线性运算
 
传统CNN
x l = H l ( x l − 1 ) (1) \boldsymbol{x}_{l} = H_l(\boldsymbol{x}_{l-1}) \tag{1} xl=Hl(xl1)(1)
   ⇒ \Rightarrow 网络第 l − 1 l-1 l1层的输出作为第 l l l层的输入,经过第 l l l层的非线性运算之后得到该层的输出;
  
ResNet
x l = H l ( x l − 1 ) + x l − 1 (2) \boldsymbol{x}_{l} = H_l(\boldsymbol{x}_{l-1})+ \boldsymbol{x}_{l-1}\tag{2} xl=Hl(xl1)+xl1(2)
   ⇒ \Rightarrow 在传统CNN的基础上添加了skip-connection,但两项是数值上的加和运算,这是与DenseNet有所不同的一点。
  
DenseNet:
x l = H l ( [ x 0 , x 1 , . . . , x l − 1 ] ) (3) \boldsymbol{x}_{l} = H_l([\boldsymbol{x}_0, \boldsymbol{x}_1, ...,\boldsymbol{x}_{l-1}]) \tag{3} xl=Hl([x0,x1,...,xl1])(3)
   ⇒ \Rightarrow 网络第 l l l层的输入来自之前所有层计算得到的特征图,把第 0 0 0层一直到第 l − 1 l-1 l1层的特征图在channel维度上拼接,然后送入第 l l l层进行运算。这就是DenseNet最大的设计特点,作者把这种连接方式称之为密集连接,即Dense Connectivity
  
   举个例子:如下图 网络第3层的输入是前两层输出特征图在 c h a n n e l channel channel维度上进行拼接得到的。
在这里插入图片描述
  密集连接示意图: x l x_l xl表示第 l l l层的输入,箭头表示产生的特征图的传递方向,可以看到第0层产生的输出传递给了后续的第1、2、3、4层,第4层的输入来自第0、1、2、3层的输出。
在这里插入图片描述 

2. DenseNet基本结构

2.1 Dense Layer(每层最基本的运算 H l H_l Hl)

有两种可以选择:
Basic:
B a t c h N o r m a l i z a t i o n ( B N ) → R e l u → C o n v 1 ∗ 1 Batch Normalization(BN) \rightarrow Relu \rightarrow Conv 1*1 BatchNormalization(BN)ReluConv11

Bottleneck :
B a t c h N o r m a l i z a t i o n ( B N ) → R e l u → C o n v 1 ∗ 1 → B a t c h N o r m a l i z a t i o n ( B N ) → R e l u → C o n v 3 ∗ 3 Batch Normalization(BN) \rightarrow Relu \rightarrow Conv 1*1 \rightarrow Batch Normalization(BN) \rightarrow Relu \rightarrow Conv 3*3 BatchNormalization(BN)ReluConv11BatchNormalization(BN)ReluConv33
 
 - 无论是哪一种,每层神经元产生的特征图数量相同,即每个 H l ( ⋅ ) H_l(\centerdot) Hl()函数产生 k k k个特征图,所以第 l l l层的输入特征图个数为:
k 0 + k ∗ ( l − 1 ) (4) k_{0} + k * (l -1) \tag{4} k0+k(l1)(4)
  k 0 k_0 k0表示输入层的维度, k k k在整个网络中为固定的数值,例如取 k = 12 k=12 k=12
 
 - Bottleneck的设计是考虑到当前层接收其之前所有层的输出作为输入,这使得当前层输入特征图的维度会比较大,所以在每层使用 3 ∗ 3 3*3 33的卷积提取特征之前,使用 1 ∗ 1 1*1 11的卷积降低输入特征图的数量,以提升计算效率。
 

2.2 Dense Blcok(多个Dense Layer连接形成)

 
在这里插入图片描述
 DenseNet采用的密集连接是将每层产生的特征图在 c h a n n e l channel channel维度上进行拼接,这就要求特征图的尺寸要相同。因此作者将整个网络划分成多个密集连接块,称之为Dense Block。如上图包含3个Dense Block。
 每个Dense Block包含n层 Dense Layer,在Dense Blcok内,各层神经元产生尺寸大小相同的特征图( W ∗ H ∗ k W * H * k WHk),各层之间采用密集连接的形式。
 
 

2.3 Transition Layer

 
-计算: B N BN BN → \rightarrow C o n v 1 ∗ 1 Conv 1*1 Conv11 → \rightarrow A v e r a g e P o o l i n g 2 ∗ 2 Average Pooling 2*2 AveragePooling22
-作用:连接两个Dense Block,采用 2 ∗ 2 2*2 22的平均池化将前一个Dense Block产生的特征图的尺寸( W ∗ H W*H WH)减半;并采用 1 ∗ 1 1*1 11的卷积降低特征图的维度,如果Dense Block输出 m m m个特征图,则Transition Layer以 m m m个特征图为输入,计算输出 θ m \theta m θm个特征图,通常 θ = 0.5 \theta=0.5 θ=0.5,因此经过Transition Layer, W ∗ H ∗ m W * H* m WHm的特征图会变成 W 2 ∗ H 2 ∗ m 2 \frac{W}{2} * \frac{H}{2} * \frac{m}{2} 2W2H2m

回顾一下整体框架:
在这里插入图片描述
 

3. 基于ImageNet数据集的DenseNet结构

Dense Blcok和Transition Layer的堆叠组成了DenseNet,具体实现中,整个网络可以由不同数量的Dense Block块组成,每个Dense Block内也可以有不同数量的Dense Layer,但每个Dense Layer均产生 k k k个特征图,Dense Block内的各层之间采用密集连接的形式。
  
  论文中给出了针对ImageNet数据集设计的DenseNet的详细结构:首层卷积 C o n v 7 ∗ 7 Conv 7*7 Conv77–>4个Dense Block块–>最后的分类层。由于每个Dense Block块内Dense Layer的层数不同,所以形成了总体层数不同的DenseNet,对应121、169等。
  
  层数的计算以121为例:
   每个Dense Layer包含两层卷积,4个Dense Block块分别包含6、12、24、16个Dense Layer;
   每个Transition Layer包含一层卷积,共3个Transition Layer;
   首层包含一层卷积;
   最后分类器包含一个全连接层;
   所以总计 ( 6 + 12 + 24 + 16 ) ∗ 2 + 3 + 1 + 1 = 121 (6+12+24+16)*2 + 3 + 1 + 1 = 121 (6+12+24+16)2+3+1+1=121层。
   
  特征图尺寸的计算:
   Dense Block不改变特征图的宽和高,特征图维数的计算按照公式(4)计算;经过Transition Layer,特征图的宽高和维度都会减半(维度减少的数量由 θ \theta θ控制,但一般 θ = 0.5 \theta=0.5 θ=0.5)。
   
在这里插入图片描述
 

4. 基于CIFAR数据集的DenseNet结构

1.论文给出的针对CIFAR数据集设计的DenseNet结构为:
  首层卷积:产生 2 k 2k 2k个特征图,不改变宽高
  三个Dense Block:特征图宽高分别为: 32 ∗ 32 32*32 3232 16 ∗ 16 16*16 1616 8 ∗ 8 8*8 88
  两个Transition Layer: C o n v 1 ∗ 1 → A v e r a g e P o o l 2 ∗ 2 Conv 1*1 \rightarrow Average Pool 2*2 Conv11AveragePool22
  最后的分类器层: A v e r a g e P o o l → F C Average Pool \rightarrow FC AveragePoolFC

2.网络整体层数 L L L和每个Dense Layer产生的特征图个数 k k k的取值可以有:
   L = 40 , k = 12 L=40, k=12 L=40,k=12
   L = 100 , k = 12 L=100, k=12 L=100,k=12
   L = 100 , k = 24 L=100, k=24 L=100,k=24
  等等
3.那每个Dense Block块内Dense Layer的个数如何计算呢?这里我参考了作者给出的代码:

[1] https://github.com/liuzhuang13/DenseNet
[2] https://github.com/andreasveit/densenet-pytorch

[1]为论文中给出的连接,[2]为对应的Pytorch版本,根据代码:
在这里插入图片描述
可以看到:网络整体深度减去首层卷积、两个Transition Layer的卷积、最后的全连接层之后除去了Dense Block的数量,所以在针对Dense Net设计的网络中,每个Dense Block含有相同数量的Dense Layer。

 

写在后面

来给自己加个油:

  • 最近发生了很多很多很多事情,学业上好久没有静下心来梳理一下自己用的东西。不过没有关系,不用对自己要求太严格,这段时间其他方面确实成长了很多呀。慢慢地想明白了一些事情、也慢慢地能处理凌乱的事情,已经很棒啦。
  • 遛弯的时候发现,内心开始渐渐地回归好久没有体会过的安静,像是保研后那段时间自己一个人安安静静的时候,每次的思考都让自己更有收获。
  • 2020年马上要结束了,这一年,家里发生了点不大不小的事情,这一年,同行的人不知不觉走散了。有时候会想,如果没有今年的疫情该多好,感觉像是被生活捉弄了一次。可冥冥之中一切安排都有其深意吧,现在我也可以平静地告诉自己说:失去未必是一件坏事,在失去的难过中我体会到了珍惜这两个字的分量,也看到了自己每一次思考后的成长和转变。
  • 其实,接下来的2021才是更不平凡的一年呢,好奇,明年的这个时候,人生的下一个十字路口,我又会去往哪里。但无论选择是什么样子的,只要自己觉得有意义自己开心就好啦。
  • 所以去努力和期待一切美好的如约而至呀,小菜鸡,你真的要好好加油呢。
    在这里插入图片描述