1. 空洞卷积的介绍

空洞卷积(Atrous Convolution)又名膨胀卷积(Dilated Convolution)。

dilated 英[daɪˈleɪtɪd][daɪˈleɪtɪd]
v. 扩大; (使)膨胀,扩张;
[词典] dilate的过去分词和过去式;

atrous
adj. 深黑的; 暗灰色的; 纯黑色的;

1.1 空洞卷积和普通卷积的对比

下面是普通的卷积:

kernel_size=3, stride=1, padding=0

下面是空洞卷积:

kernel_size = 3, dilated_ratio = 2, stride = 1, padding = 0

二者的卷积核大小都是一样的(滑窗的实际大小是一样的),但空洞卷积的滑窗(kernel)元素之间是存在一些间隙的,这些间隙在空洞卷积中成为膨胀因子(dilated ratio)。

如果dilated ratio=1时,空洞卷积就是普通卷积。

1.2 空洞卷积的作用

  1. 增大感受野
  2. 保持原输入特征图的高度和宽度

上面的空洞卷积示意图中,因为没有设置padding,所以特征图变小了。而在实际使用中,一般都会对padding进行设置(将padding设置为1),这样就能保证输入特征图的高度和宽度不变。

1.3 为什么要使用空洞卷积

在语义分割中,通常会使用分类网络作为backbone。通过backbone之后会对特征图进行一系列的下采样,之后再进行一系列的上采样还原原图的大小。

在分类网络中,一般都会对图片的高度和宽度下采样32倍,由于后续需要通过上采样还原到原来的尺寸。如果下采样的倍率很大时,即便使用上采样还原回原来的尺寸,那么信息丢失是比较严重的。

以VGG16为例,该网络通过MaxPooling层对特征图进行下采样:

  • 通过MaxPooling会降低特征图的shape
  • MaxPooling会丢失特征图的一些细节信息(毕竟是用最大值代替局部值,丢失信息是肯定的)
  • 丢失的信息和目标是无法通过上采样进行还原的

这就导致在语义分割任务的效果不理想。

思考
Q:既然MaxPooling会损失信息,那么直接不用MaxPooling不就行了?
A:如果我们简单粗暴地将MaxPooling去掉的话,会引入新的问题:

  • 特征图对应原图的感受野变小了
  • 为后面的卷积层带来影响(感受野不变,卷积层就无法获取深层的信息)

此时,空洞卷积就可以解决上面的问题,因为空洞卷积:

  • 增大特征图的感受野
  • 保证输入输出特征图的shape不变

Q:既然空洞卷积有这样的好处,那我们是否可以简单粗暴地堆叠空洞卷积层呢?
A:很明显,不行!

2. gridding effect问题

在空洞卷积使用的过程中经常会遇到一个名叫 gridding effect 的问题。

2. 1 什么是gridding effect —— 连续使用几个膨胀系数相同的空洞卷积

如下图所示,连续使用3个空洞卷积层(卷积核大小都为3×3,膨胀系数均为2


我们先看一下 Layer2 上,每一个pixel利用到了 Layer1 上的哪些pixels。


我们可以看到,膨胀系数是2表示卷积核每两个数据之间都间隔一行或一列0。
所以Layer2 上一个pixels会使用Layer1的9个pixels。


我们再看一下Layer3

当我们连续使用2个膨胀系数为2的空洞卷积时,Layer3上一个pixel利用到了Layer1上25个pixels的信息。

每个pixel上的数字表示:通过累加得到Layer3上一个pixel利用到Layer1上该像素的次数


看一下Layer4


当我们连续使用3个膨胀系数为2的空洞卷积时,Layer4上一个pixel利用到了Layer1上的数据并不是连续的!在每个非零元素之间都存在一定的间隔 —— 这就是gridding effect现象。

也就是说Layer4上的一个像素并没有利用到范围内的所有像素值,而是一部分。

因为没有利用到所有的像素值,所以一定会丢失一部分细节信息 —— 和MaxPooling一样(但是比MaxPooling要轻微)

所以在使用空洞卷积时要尽可能避免gridding effect问题

2.2 连续使用几个膨胀系数不同的空洞卷积


膨胀系数设置为1就是普通的卷积


看一下Layer2:


因为是普通卷积,所以利用到了卷积核大小窗口内所有Layer1的像素。


看一下Layer3:


Layer3上的一个像素对应Layer1上7×7的区域,而且该区域中每一个像素的利用次数不同(但都利用到了


看一下Layer4:


Layer4上的一个像素对应Layer1上13×13的区域,而且该区域中每一个像素的利用次数不同(但都利用到了

2.3 两种使用方法的对比

  • 两种方法的参数数量是一样的
  • 仅仅是膨胀系数不同而已
  • 对于[2, 2, 2]的空洞卷积来说,Layer4的感受野也是13×13,但在这个视野下有很多像素值是没有利用到的

我们更加倾向于使用[1, 2, 3]这样的膨胀系数 —— 感受野下使用的区域是连续的

2.4 如果全部使用普通的卷积


我们发现:

  • 直接使用普通卷积Layer4的感受野和前面两种不同(前者为13×13),为7×7
  • 这说明使用膨胀卷积可以大幅度增加感受野

3. 空洞卷积使用方法 —— Hybird Dilated Convolution (HDC)

当我们要连续使用多个膨胀卷积时应该如何设计它的膨胀系数。

通过2.2和2.3的实验可以得出:使用[1, 2, 3]的膨胀系数和使用[2, 2, 2]膨胀系数的感受野是相同的,但前者对于输入信息的利用率高 —— 理论效果更好。

3.1 论文中第一个建议

假设我们连续堆叠NNN个空洞卷积(它的kernel_size都是等于K×KK \times KK×K的),每个空洞卷积的膨胀系数分别对应[r1,r2,...,rn][r_1, r_2, ..., r_n][r1​,r2​,...,rn​]。那HDC的目标是通过一系列空洞卷积之后可以完全覆盖底层特征层的方形区域,并且该方形区域中间是没有任何孔洞或缺失的边缘(withou any holes or missing edges)。作者定义了一个叫做"maximum distance between two nonzero values,两个非零元素之间最大的距离"的公式:

Mi=max⁡[Mi+1−2ri,Mi+1−2(Mi+1−ri),ri]=max⁡[Mi+1−2ri,2ri−Mi+1,ri]=max⁡[正,负,ri]\begin{aligned} M_i & = \max [M_{i+1} - 2r_i, M_{i+1} - 2(M_{i+1} - r_i), r_i] \\ & = \max[M_{i+1} - 2r_i, 2r_i - M_{i+1}, r_i] \\ & = \max[正, 负, r_i] \end{aligned} Mi​​=max[Mi+1​−2ri​,Mi+1​−2(Mi+1​−ri​),ri​]=max[Mi+1​−2ri​,2ri​−Mi+1​,ri​]=max[正,负,ri​]​

其中MiM_iMi​是第iii层两个非零元素之间的最大距离;rir_iri​为第iii层的膨胀系数。

  • 紧密挨着的距离为1
  • 像[2, 2, 2]中那样,两个非零元素之间的距离为2 —— 意味着二者之间间隔了一行或者一列。

对于最后一层,它的最大距离为Mn=rnM_n = r_nMn​=rn​,即最大距离为该层的膨胀率。这么设计的目的是让M2≤KM_2 \le KM2​≤K,即第二层的两个非零元素之间的最大距离小于等于该层卷积核的大小。

3.2 针对第一个建议给出的两个例子

  • 当kernel_size,即K=3K=3K=3时,对于膨胀系数r=[1,2,5]r=[1, 2, 5]r=[1,2,5]来说,M2=max⁡[M3−2r2,M3−2(M3−r2),r2]=max⁡[5−4,4−5,2]=max⁡[1,−1,2]=2≤3M_2 = \max [M_3 - 2r_2, M_3 - 2(M_3 - r_2), r_2] = \max [5-4, 4-5, 2] = \max [1, -1, 2] =2 \le 3M2​=max[M3​−2r2​,M3​−2(M3​−r2​),r2​]=max[5−4,4−5,2]=max[1,−1,2]=2≤3,所以满足设计要求。
  • 当kernel_size,即K=3K=3K=3,对于膨胀系数r=[1,2,9]r=[1, 2, 9]r=[1,2,9]来说,M2=max⁡[M3−2r2,M3−2(M3−r2),r2]=max⁡[9−4,4−9,2]=max⁡[5,−5,2]=5≥3M_2 = \max [M_3 - 2r_2, M_3 - 2(M_3 - r_2), r_2] = \max [9 - 4, 4-9, 2] = \max [5, -5, 2] = 5 \ge 3M2​=max[M3​−2r2​,M3​−2(M3​−r2​),r2​]=max[9−4,4−9,2]=max[5,−5,2]=5≥3,所以不满足设计要求,所以这组参数是不合适的。

代码如下:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormapdef dilated_conv_one_pixel(center: (int, int),feature_map: np.ndarray,k: int = 3,r: int = 1,v: int = 1):"""膨胀卷积核中心在指定坐标center处时,统计哪些像素被利用到,并在利用到的像素位置处加上增量vArgs:center: 膨胀卷积核中心的坐标feature_map: 记录每个像素使用次数的特征图k: 膨胀卷积核的kernel大小r: 膨胀卷积的dilation ratev: 使用次数增量"""assert divmod(3, 2)[1] == 1# left-top: (x, y)left_top = (center[0] - ((k - 1) // 2) * r, center[1] - ((k - 1) // 2) * r)for i in range(k):for j in range(k):feature_map[left_top[1] + i * r][left_top[0] + j * r] += vdef dilated_conv_all_map(dilated_map: np.ndarray,k: int = 3,r: int = 1):"""根据输出特征矩阵中哪些像素被使用以及使用次数,配合膨胀卷积k和r计算输入特征矩阵哪些像素被使用以及使用次数Args:dilated_map: 记录输出特征矩阵中每个像素被使用次数的特征图k: 膨胀卷积核的kernel大小r: 膨胀卷积的dilation rate"""new_map = np.zeros_like(dilated_map)for i in range(dilated_map.shape[0]):for j in range(dilated_map.shape[1]):if dilated_map[i][j] > 0:dilated_conv_one_pixel((j, i), new_map, k=k, r=r, v=dilated_map[i][j])return new_mapdef plot_map(matrix: np.ndarray):plt.figure()c_list = ['white', 'blue', 'red']new_cmp = LinearSegmentedColormap.from_list('chaos', c_list)plt.imshow(matrix, cmap=new_cmp)ax = plt.gca()ax.set_xticks(np.arange(-0.5, matrix.shape[1], 1), minor=True)ax.set_yticks(np.arange(-0.5, matrix.shape[0], 1), minor=True)# 显示color barplt.colorbar()# 在图中标注数量thresh = 5for x in range(matrix.shape[1]):for y in range(matrix.shape[0]):# 注意这里的matrix[y, x]不是matrix[x, y]info = int(matrix[y, x])ax.text(x, y, info,verticalalignment='center',horizontalalignment='center',color="white" if info > thresh else "black")ax.grid(which='minor', color='black', linestyle='-', linewidth=1.5)plt.show()plt.close()def main():# bottom to topdilated_rates = [1, 2, 5]# init feature mapsize = 31m = np.zeros(shape=(size, size), dtype=np.int32)center = size // 2m[center][center] = 1# print(m)# plot_map(m)for index, dilated_r in enumerate(dilated_rates[::-1]):new_map = dilated_conv_all_map(m, r=dilated_r)m = new_mapprint(m)plot_map(m)if __name__ == '__main__':main()

3.2.1 r = [1, 2, 5]的效果图


很明显,这组参数最后一层的感受野包含了所有像素,输入的每一个像素都利用到了,不存在gridding effect问题。

3.2.2 r = [1, 2, 9]的效果图


这里并不是有9个感受野,实际上这9个小块合起来才是真正的感受野。很明显,两个小块之间非零元素的最大距离为3,这与我们的期望1不符,所以该组参数是不合适的。

3.3 为什么例子中的 rrr 都是从1开始的?

我们希望在高层特征图的每个像素可以利用到底层特征图的感受野内的所有像素,那么M1M_1M1​应该等于1。M1=1M_1 = 1M1​=1意味着非零元素之间是相邻的(没有间隙的),而M1M_1M1​的计算公式如下(就是MiM_iMi​的计算公式):
Mi=max⁡[Mi+1−2ri,Mi+1−2(Mi+1−ri),ri]=max⁡[Mi+1−2ri,2ri−Mi+1,ri]=max⁡[正,负,ri]\begin{aligned} M_i & = \max [M_{i+1} - 2r_i, M_{i+1} - 2(M_{i+1} - r_i), r_i] \\ & = \max[M_{i+1} - 2r_i, 2r_i - M_{i+1}, r_i] \\ & = \max[正, 负, r_i] \end{aligned} Mi​​=max[Mi+1​−2ri​,Mi+1​−2(Mi+1​−ri​),ri​]=max[Mi+1​−2ri​,2ri​−Mi+1​,ri​]=max[正,负,ri​]​

既然我们希望M1=1M_1 = 1M1​=1,那么M1M_1M1​应该≥r1\ge r_1≥r1​,即 1≥r11 \ge r_11≥r1​,所以r1r_1r1​被迫等于1。

所以在设计连续空洞卷积时,第一个膨胀率一般都是从1开始的

3.4 论文中第二个建议


第二个建议为:将膨胀系数设置为锯齿形状。如:

  • [1, 2, 3, 1, 2, 3]

3.4 论文中第三个建议


论文中的第三个建议:公约数不能大于1。如:

  • r=[1,2,3]r = [1, 2, 3]r=[1,2,3]:它们的公约数为111,符合①②③建议 -> 设计合理
  • r=[2,4,8]r=[2, 4, 8]r=[2,4,8]:它们的公约数为222,不符合③的建议 -> 设计不合理

4. 效果对比

  • 没有按照HDC设计准则的模型(第二行),它分割的效果不是很好
  • 符合HDC设计准则的模型(第三行)相比第二行来说,效果要层好不少。

5. 空洞卷积输出特征图计算公式

5.1 普通卷积

Oiconv/pool=Oiin+2pi−kisi+1O_i^{\mathrm{conv/pool}} = \frac{O_i^{\mathrm{in}} + 2p_i - k_i}{s_i} + 1 Oiconv/pool​=si​Oiin​+2pi​−ki​​+1

5.2 空洞卷积

Oidilatedconv=Oiin+2pi−di×(ki−1)si+1O_i^{\mathrm{dilated \ conv}} = \frac{O_i^{\mathrm{in}} + 2p_i - d_i \times (k_i-1)}{s_i} + 1 Oidilated conv​=si​Oiin​+2pi​−di​×(ki​−1)​+1

5.3 转置卷积

5.3.1 不带空洞卷积

Oitransconv=(Oiin−1)×si−2×pi+kiO_i^{\mathrm{trans \ conv}} = (O_i^{\mathrm{in}} - 1) \times s_i - 2 \times p_i + k_i Oitrans conv​=(Oiin​−1)×si​−2×pi​+ki​

5.3.2 带有空洞卷积

Oitransconv=(Oiin−1)×si−2×pi+di×(ki−1)+output_paddingi+1O_i^{\mathrm{trans \ conv}} = (O_i^{\mathrm{in}} - 1) \times s_i - 2 \times p_i + d_i \times (k_i - 1) + \text{output\_padding}_i + 1 Oitrans conv​=(Oiin​−1)×si​−2×pi​+di​×(ki​−1)+output_paddingi​+1

6. 总结

6.1 设计准则

对于最后一层,它的最大距离为Mn=rnM_n = r_nMn​=rn​,即最大距离为该层的膨胀率。这么设计的目的是让,即。

  1. 第二层的两个非零元素之间的最大距离小于等于该层卷积核的大小,即M2≤KM_2 \le KM2​≤K。
    其中Mi=max⁡[Mi+1−2ri,2ri−Mi+1,ri]M_i = \max [M_{i+1} - 2r_i, 2r_i - M_{i+1}, r_i]Mi​=max[Mi+1​−2ri​,2ri​−Mi+1​,ri​]
  2. 将膨胀系数设置为锯齿形状。如:[1,2,3,1,2,3][1, 2, 3, 1, 2, 3][1,2,3,1,2,3]
  3. 膨胀系数的公约数不能大于1,如:采用[1,2,3,][1, 2, 3,][1,2,3,],而不是[2,4,6][2, 4, 6][2,4,6]

6.2 实际使用

在使用膨胀卷积时,我们应该参考HDC的设计准则。

参考

  1. https://www.bilibili.com/video/BV1Bf4y1g7j8?spm_id_from=333.999.0.0
  2. https://github.com/vdumoulin/conv_arithmetic

空洞卷积(膨胀卷积)的相关知识以及使用建议(HDC原则)相关推荐

  1. DeepLabV3论文解读(空洞卷积/膨胀卷积 理解)

    DeepLabV3论文解读(空洞卷积/膨胀卷积 理解) 最近在做基础网络研究,设计的网络结构除了在分类数据集上测试,还需要在分割和检测网络上测试效果,故选择了DeepLabV3作为对比平台.本想直接替 ...

  2. 膨胀卷积(Dilated convolutions)(又叫空洞卷积、扩张卷积)

    一.背景 论文:Multi-Scale Context Aggregation by Dilated Convolutions   大部分图像分割的框架都是经历一系列的卷积和下采样的模块之后,再不断与 ...

  3. 语义分割|学习记录(4)膨胀卷积(空洞卷积 )

    文章目录 前言 一.膨胀卷积 二.gridding effect 三.使用多个膨胀卷积的时候,怎样设置膨胀系数? 四.膨胀系数设置建议 五.是否应用HDC设计准则的分割效果对比 六.总结 参考资料 前 ...

  4. 膨胀卷积(空洞卷积)学习篇

    文章目录 提出背景 感受野 膨胀卷积是什么 膨胀卷积的设计原理 膨胀卷积的优缺点 膨胀卷积的改进 膨胀卷积基于Pytorch的代码实现 总结 原论文链接: 2016ICLR<Multi-Scal ...

  5. 命名实体识别_用膨胀卷积进行命名实体识别 NER

    BiLSTM+CRF 是命名实体识别中最为流行的模型,但是 LSTM 需要按顺序处理输入的序列,速度比较慢.而采用 CNN 可以更高效的处理输入序列,本文介绍一种使用膨胀卷积进行命名实体识别的方法 I ...

  6. 深度学习-【语义分割】学习笔记4 膨胀卷积(Dilated convolution)

    文章目录 膨胀卷积 为什么需要膨胀卷积 gridding effect 连续使用三次膨胀卷积--1 连续使用三次膨胀卷积--2 连续使用三次膨胀卷积--3 Understanding Convolut ...

  7. 空洞卷积/扩张卷积(Dilated convolution)-笔记

    空洞卷积/膨胀卷积 (1)普通卷积操作 3*3的kernel,上方深绿色为输出特征图,下方蓝色为原输入图 (2)空洞卷积 其中r为扩张率,指的是卷积核的点的间隔数量.特别的,当r=1时,为普通卷积. ...

  8. 膨胀卷积(空洞卷积 dilated convolution)

    学习的B站大佬的视频大部分图片来自于课中,文章结尾有大佬视频链接,以及阅读<深度学习之pytorch物体检测实战>,刚开始学习可能有些错误,希望大佬指正 1.空洞卷积了解 空洞卷积最初是为 ...

  9. 膨胀卷积dilated convolution 相关

    [时间]2019.03.10 [题目]膨胀卷积dilated convolution 相关及keras实现 1.Dilated Convolution 2.Dilated Convolutions 空 ...

  10. 膨胀卷积 / 空洞卷积(Dilated convolution)

    视频学习链接:[https://www.bilibili.com/video/BV1Bf4y1g7j8] 1. 认识膨胀卷积 r 为间隙,r = 1 时,就是普通卷积 2. 为什么要使用空洞卷积 提出 ...

最新文章

  1. Ubuntu PyCharm cv2 无代码提示解决方法
  2. 邀请别人进入队伍rust_林俊杰组建DOTA2队伍,原Newbee五人被终身禁赛
  3. POJ 1724 二维费用最短路
  4. 非递归遍历求二叉排序树的深度
  5. 【职场】如何才能成功的创业,创业成功的本质是什么
  6. FPGA基础之LUT详解
  7. 第三方登录 人人php,人人网第三方登录接口方案
  8. SQLServer 事物与索引
  9. 在Kotlin中使用Gradle构建缓存
  10. r中gglot怎么组合多张图_最终版本Science级组合图表绘制
  11. KETTLE集群搭建
  12. 【软件工程】图书馆自习室及座位管理系统的分析与设计
  13. 新商用密码产品认证梳理——检测和认证机构篇
  14. 关于PC电脑微信进粉计数器的选择?
  15. linux宝塔怎么添加二级域名,如何绑定二级域名使用宝塔面板?
  16. 水调歌头.明月几时有 小儿拼音版
  17. 如何修改网络连接的网络位置
  18. log文件过大处理方法
  19. 东南大学计算机学院分数线,“东南大学”2019本一批次专业录取分数整理!计算机、建筑领域实力强,又是985、211、双一流名校!...
  20. fatal detected dubious ownership in repository at解决办法

热门文章

  1. 网络会议openmeetings下的openmeetings-util文件分析3
  2. supersu二进制更新安装失败_supersu 二进制更新解决方法
  3. mysql 关闭远程_禁止MySQL root远程访问
  4. html 输入框 大于0,【前端】input输入框只能输入大于等于0的正数
  5. 《牧羊少年奇幻之旅》之水晶店老板
  6. Unity,C#版的动画曲线,Tween:EaseIn,EaseOut,EaseInOut(编程语言翻译版本)
  7. java stringbuilder 构造函数_java---StringBuilder类的用法(转载)
  8. 关于本地mysql和小皮mysql两者不可同时存在
  9. 用友U8 cloud释放新动能,加速城投行业数智化转型
  10. CubieBoard7开发板(基于S700芯片)基于安卓系统固件编译