目录
参考资料
论文:
Multi-Scale Context Aggregation by Dilated Convolutions
博客:
第1章 感受野
1.1 定义
在卷积神经网络中,**感受野(Receptive Field)**是指特征图上的某个点能看到的输入图像的区域,即特征图上的点是由输入图像中感受野大小区域的计算得到的。
- 神经元感受野越大,表示能接触到的原始图像范围就越大,它蕴含更为全局、语义层次更高的特征;
- 神经元感受野越小,表示其所包含的特征越趋向局部和细节。
因此感受野的值可以用来大致判断每一层的抽象层次。
1.2 感受野的计算
卷积层(conv) 和 池化层(pooling) 都会影响感受野,而激活函数层通常对于感受野没有影响,当前层的步长并不影响当前层的感受野,感受野和填补(padding)没有关系,计算当层感受野的公式如下:
R
F
i
+
1
=
R
F
i
+
(
k
−
1
)
×
S
i
RF_{i+1}=RF_i+(k−1)×S_i
RFi+1=RFi+(k−1)×Si
其中,
R
F
i
+
1
RF_{i+1}
RFi+1 表示当前层的感受野,
R
F
i
RF_i
RFi 表示上一层的感受野,
k
k
k 表示卷积核的大小,例如
3
×
3
3\times3
3×3 的卷积核,则
k
=
3
k=3
k=3 ,
S
i
S_i
Si 表示之前所有层的步长的乘积(不包括本层),公式如下:
S
i
=
∏
i
=
1
i
S
t
r
i
d
e
i
S_i=\prod_{i=1}^{i}Stride_i
Si=i=1∏iStridei
以AlexNet举个例子:
我的一部分计算过程:
R
a
w
=
1
C
o
n
v
1
=
1
+
(
11
−
1
)
×
1
=
11
P
o
o
l
1
=
11
+
(
3
−
1
)
×
4
=
19
C
o
n
v
2
=
19
+
(
5
−
1
)
×
4
×
2
=
51
Raw=1 \\ Conv1=1+(11−1)×1=11 \\ Pool1=11+(3−1)×4=19 \\ Conv2=19+(5−1)×4×2=51
Raw=1Conv1=1+(11−1)×1=11Pool1=11+(3−1)×4=19Conv2=19+(5−1)×4×2=51
第2章 空洞卷积
2.1 前言
空洞卷积中文名也叫膨胀卷积或者扩张卷积,英文名也叫Atrous Convolution。
空洞卷积最初的提出是为了解决图像分割的问题而提出的,常见的图像分割算法通常使用池化层和卷积层来增加感受野(Receptive Filed),同时也缩小了特征图尺寸(resolution),然后再利用上采样还原图像尺寸,特征图缩小再放大的过程造成了精度上的损失,因此需要一种操作可以在增加感受野的同时保持特征图的尺寸不变,从而代替下采样和上采样操作,在这种需求下,空洞卷积就诞生了。
当然,如果不用空洞卷积这种方案,那怎么去弥补经过下采样而造成信息损失呢?其实,这是另一个思路了,于是才有了我们熟知的skip connection,它可以为上采样弥补信息,像FCN、U-Net这种典型的拓扑网络,如下图所示,其实我个人认为,如果一个问题如果从不同的思路去想的话,就会出现不同的解决方案。
其实说白了,就是池化可以扩大感受野,可以降低数据维度,可以减少计算量,但是会损失信息,而对于语义分割来说,这造成了发展瓶颈。而空洞卷积可以在扩大感受野的情况下不损失信息,但其实,空洞卷积的确没有损失信息,但是却没有用到所有的信息。
2.2 空洞卷积的原理
与正常的卷积不同的是,空洞卷积引入了一个称为 “扩张率(dilation rate)”的超参数(hyper-parameter),该参数定义了卷积核处理数据时各值的间距。扩张率中文也叫空洞数(Hole Size)。
在此以 3×3 卷积为例,展示普通卷积和空洞卷积之间的区别,如图所示:
图中从左到右分别为a、b、c子图,三幅图是相互独立进行卷积的,大框表示输入图像(感受野默认为1),黑色的圆点表示3×3的卷积核,灰色地带表示卷积后的感受野(后面有相关计算公式,这里都是一层卷积的,直接可以看出来):
- a是普通的卷积过程(dilation rate = 1),卷积后的感受野为3;
- b是dilation rate = 2的空洞卷积,卷积后的感受野为5;
- c是dilation rate = 3的空洞卷积,卷积后的感受野为7;
可以这么说,普通卷积是空洞卷积的一种特殊情况。
空洞卷积可以增大感受野,但是可以不改变图像输出特征图的尺寸(分辨率,resolution),这句话怎么理解?为了更好地理解这一点,我们从一维去分析容易理解点:
从b和c可以看出,有无空洞卷积,并不影响输出特征图的尺寸,也就是说输出特征图的尺和空洞数无关,因此可以利用空洞卷积增大感受野,而输出特征图的尺寸可以保持不变。
2.3 空洞卷积的感受野
从上图可以看出,同样一个
3
×
3
3×3
3×3 的卷积,却可以起到
5
×
5
5×5
5×5 、
7
×
7
7×7
7×7 等卷积的效果,空洞卷积在不增加参数量的前提下(参数量=卷积核大小+偏置),却可以增大感受野,假设空洞卷积的卷积核大小为
k
k
k ,空洞数为
d
d
d ,则其等效卷积核大小
k
′
k'
k′,例如
3
×
3
3×3
3×3 的卷积核,则
k
=
3
k=3
k=3 ,公式如下:
k
′
=
k
+
(
k
−
1
)
×
(
d
−
1
)
k'=k+(k−1)×(d−1)
k′=k+(k−1)×(d−1)
当前层的感受野计算公式如下,其中,
R
F
i
+
1
RF_{i+1}
RFi+1 表示当前层的感受野,
R
F
i
RF_i
RFi 表示上一层的感受野,
k
k
k 表示卷积核的大小,例如
3
×
3
3\times3
3×3 的卷积核,则
k
=
3
k=3
k=3 ,
S
i
S_i
Si 表示之前所有层的步长的乘积(不包括本层),公式如下:
R
F
i
+
1
=
R
F
i
+
(
k
−
1
)
×
S
i
S
i
=
∏
i
=
1
i
S
t
r
i
d
e
i
RF_{i+1}=RF_i+(k−1)×S_i \\ S_i=\prod_{i=1}^{i}Stride_i
RFi+1=RFi+(k−1)×SiSi=i=1∏iStridei
同样的,当前层的步长并不影响当前层的感受野,感受野和填补(padding)没有关系!
2.4 空洞卷积和普通卷积对比
为什么空洞卷积的感受野偏大?那是因为空洞卷积串行组团起来后,感受野变大很多。这也是空洞卷积设计的核心思路。
(a)图对应 3x3 的 1-dilated conv
,和普通的卷积操作一样;
(b)图对应 3x3 的 2-dilated conv
,实际的卷积kernel size还是 3x3 ,但是空洞为1,也就是对于一个7x7的图像patch,只有9个红色的点和3x3的kernel发生卷积操作,其余的点略过。也可以理解为kernel的size为7x7,但是只有图中的9个点的权重不为0,其余都为0。 可以看到虽然kernel size只有3x3,但是这个卷积的感受野已经增大到了7x7(如果考虑到这个2-dilated conv的前一层是一个1-dilated conv的话,那么每个红点就是1-dilated的卷积输出,所以感受野为3x3,所以1-dilated和2-dilated合起来就能达到7x7的conv);
(c)图是 4-dilated conv
操作,同理跟在两个 1-dilated
和 2-dilated conv
的后面,能达到15x15的感受野。
计算过程如下:
(0)原始图像感受野为:1
(1)前一层为3x3的卷积,,空洞为1,等效的k’变为: k’ = 3 +(3-1)x(1-1)= 3
感受野为:1+(3-1)x1=3
(2)当前层为3x3的卷积,空洞为2,等效的k’变为: k’ = 3 +(3-1)x(2-1)= 5
感受野为:3+(5-1) x 1 = 7
(3)当前层为3x3的卷积,空洞为4,等效的k’变为: k’ = 3 +(3-1)x(4-1)= 9
感受野为:7+(9-1) x 1 = 15
对比传统的conv操作,3层3x3的卷积加起来,stride为1的话,只能达到(kernel-1)*layer+1=7的感受野,也就是传统的conv操作得到的感受野和层数layer成线性关系,而dilated conv的感受野是指数级的增长。
第3章 空洞卷积的潜在问题
3.1 The Gridding Effect
假设我们仅仅多次叠加 dilation rate=2
的 3 x 3 kernel 的话,则会出现 栅格效应
:
由于空洞卷积的计算方式类似于棋盘格式,某一层得到的卷积结果,来自上一层的独立的集合,没有相互依赖,因此该层的卷积结果之间没有相关性,即局部信息丢失。这对 pixel-level dense prediction 的任务来说是致命的。
3.2 Long-ranged information might be not relevant
远距离获取的信息没有相关性:由于空洞卷积稀疏的采样输入信号,使得远距离卷积得到的信息之间没有相关性,影响分类结果。
我们从 dilated convolution 的设计背景来看就能推测出这样的设计是用来获取 long-ranged information。然而光采用大 dilation rate 的信息或许只对一些大物体分割有效果,而对小物体来说可能则有弊无利了。如何同时处理不同大小的物体的关系,则是设计好 dilated convolution 网络的关键。
3.3 通向标准化设计:Hybrid Dilated Convolution (HDC)
对于上个 section 里提到的几个问题,图森组的文章对其提出了较好的解决的方法。他们设计了一个称之为 HDC 的设计结构。
(1)第一个特性是,叠加卷积的 dilation rate 不能有大于1的公约数。比如 [2, 4, 6] 则不是一个好的三层卷积,依然会出现 gridding effect。
(2)第二个特性是,我们将 dilation rate 设计成 锯齿状结构,例如 [1, 2, 5, 1, 2, 5] 的循环结构。
(3)第三个特性是,我们需要满足一下这个式子:
其中 r i r_i ri 是 i i i 层的 dilation rate 而 M i M_i Mi 是指在 i i i 层的最大dilation rate,那么假设总共有 n n n 层的话,默认 M n = r n M_n=r_n Mn=rn 。假设我们应用于 kernel 为 k x k k x k kxk 的话,我们的目标则是 M 2 ≤ k M_2≤k M2≤k ,这样我们至少可以用 dilation rate 1 即 standard convolution 的方式来覆盖掉所有洞。
一个简单的例子: dilation rate [1, 2, 5] with 3 x 3 kernel (可行的方案)
而这样的锯齿状本身的性质就比较好的来同时满足小物体大物体的分割要求:
- 小 dilation rate 来关心近距离信息;
- 大 dilation rate 来关心远距离信息;
这样我们的卷积依然是连续的也就依然能满足VGG组观察的结论,大卷积是由小卷积的 regularisation 的 叠加。以下的对比实验可以明显看出,一个良好设计的 dilated convolution 网络能够有效避免 gridding effect.
第4章 Pytorch中的空洞卷积
Pytorch中的空洞卷积是通过Conv2d函数(Tensor通道排列顺序是:[batch, channel, height, width]
)实现的,设置 dilation
参数的值即可:
注意:dilation = 1等同于没有dilation的标准卷积。
torch.nn.Conv2d(in_channels, # 输入通道
out_channels, # 输出通道
kernel_size, # 卷积核大小
stride=1, # 步长
padding=0, # 填充
dilation=1, # 空洞数,默认为1
groups=1, # 分组卷积的组数
bias=True, # 是否需要偏置
padding_mode='zeros') # 填充方式:0填充