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

一、背景

论文:Multi-Scale Context Aggregation by Dilated Convolutions

  大部分图像分割的框架都是经历一系列的卷积和下采样的模块之后,再不断与之前卷积结果跨层融合经历一系列卷积和上采样模块的过程,只不过大家融合的方式不尽相同,FCN是逐像素直接相加U-NET是通道维度拼接DFAnet是矩阵相乘,但大体框架是一样的,主要还是因为之前的下采样降低了图片的分辨率,而我们只能采用这种方法既能及时补充细节信息又能恢复原始图片分辨率。论文在介绍中,大胆提出这些问题的根源在于池化、下采样层的存在而它们的存在并不是必要的

创新点:

 (1)丢掉池化、下采样模块;
2)构建一种新的卷积网络结构 — 膨胀卷积;
3)提出了一种既可以结合上下文信息,又不降低分辨率的模型。

 二、原理

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

相当于实际普通个卷积核:K=3+(3-1)(2-1)=5; 卷积后得出的尺寸为w=(w-K+2P)/S+1=3

 1.连续使用几个膨胀系数不同的空洞卷积,有如下的结果:

aF1F0通过1-dilated(相当于普通卷积)扩张卷积产生的;F1中每个元素具有3x3的感受野。

bF2F1通过2-dilated扩张卷积产生的;F2中每个元素具有7x7的感受野。

cF3F2通过4-dilated扩张卷积产生的;F3中每个元素具有15x15的感受野。

   上图可以看出,卷积核参数量没有发生改变,只是被0填充大小发生变化,随着空洞系数的增大,感受野 ( receptive field ) 也逐渐变大,而他们训练的参数是完全相同的。文章当中给出了上面三种情况感受野的计算公式:

 2.连续使用几个膨胀系数相同的空洞卷积,有如下的结果:

相比于前面使用连续不同膨胀系数的空洞卷积而言:

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

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

3.全部使用普通的卷积 

可以发现:

  • 在相同层对应的感受野:普通卷积(7x7)要小于膨胀卷积(13x13)。
  • 这说明使用膨胀卷积可以大幅度增加感受野。

 三、膨胀卷积使用的方法

1.论文第一个建议:连续使用多个膨胀卷积时应该如何设计它的膨胀系数如下:

         针对于几个膨胀系数相同的空洞卷积和几个膨胀系数的空洞卷积连接卷积产生的不同结果,论文给出了相应的解决方法:  Hybird Dilated Convolution (HDC)

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

 针对第一个建议给出的两个例子:(其中最大距离Mn = rn)

kernel_size (K)=3 时,对于膨胀系数 r=[1, 2, 5] 来说, M 2 =max[M 3 − 2r 2 , 2r i −M i+1 , r 2 ] =max[5-4, 4-5, 2]=2 (K= ) 3, 所以 满足 设计要求。
kernel_size (K)=3 时,对于膨胀系数 r=[1, 2, 9] 来说,M 2 =max[M 3 − 2r 2 , 2r i −M i+1 , r 2 ] =max[9-4, 4-9, 2]=5 (K=)3, 所以 不满足 设计要求,所以这组参数时不合适的。

设计对应的效果图对比:

 明显可以看出r=[1, 2, 9], 中间丢失了一部分信息,而r=[1,2,5]没有丢失。

  提问:为什么例子中的 r都是从1开始的?

        我们希望在高层特征图的每个像素可以利用到底层特征图的感受野内的所有像素,那么M1应该等于1 M1=1意味着非零元素之间是相邻的(没有间隙的),而M1的计算公式如下:

M1  = max[M2−2r1 , 2r1 − M2,r1] = max[正, 负, ri]

       既然我们希望M1=1而且M1且取3个中最大的数,那么M1应该 r1 ,即1 ≥ r1所以r1等于1。

2.论文第二个建议:将膨胀系数设置为锯齿形状。

3.论文第个建议:公约数不能大于1的。

 设计对应的效果图对比:

 明显可以看出r=[2, 4, 8],有公约数2而且中间丢失了一部分信息,而r=[1,2,5]公约数为1且没有丢失任何信息。

四、 膨胀卷积用途

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

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

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

对于神经网络构建而言:

如果我们简单粗暴地将MaxPooling去掉的话,会引入新的问题:

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

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

增大特征图的感受野
•通过修改padding的大小,可以 保证输入输出特征图的 shape 不变

五、膨胀卷积各种设计效果比较 

可以发现,使用HDC设计的膨胀卷积对于全局信息的捕获更齐全。

六、代码:

 上面对应每个r=[x,x,x]生成图像的代码如下,只需改动dilated_rates = [1,2,3]中的值即可测试其他数据。这里参考了(空洞卷积(膨胀卷积)的相关知识以及使用建议(HDC原则)_Le0v1n的博客-CSDN博客_空洞卷积的作用)

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap


def dilated_conv_one_pixel(center: (int, int),
                           feature_map: np.ndarray,
                           k: int = 3,
                           r: int = 1,
                           v: int = 1):
    """
    膨胀卷积核中心在指定坐标center处时,统计哪些像素被利用到,
    并在利用到的像素位置处加上增量v
    Args:
        center: 膨胀卷积核中心的坐标
        feature_map: 记录每个像素使用次数的特征图
        k: 膨胀卷积核的kernel大小
        r: 膨胀卷积的dilation rate
        v: 使用次数增量
    """
    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] += v


def 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_map


def 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 bar
    plt.colorbar()

    # 在图中标注数量
    thresh = 5
    for 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',
                    font={'size':6},
                    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 top
    dilated_rates = [1,2,3]
    # init feature map
    size = 31
    m = np.zeros(shape=(size, size), dtype=np.int32)
    center = size // 2
    m[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_map
    print(m)
    plot_map(m)


if __name__ == '__main__':
    main()

七、总结

1.在不做pooling损失信息和相同的计算条件下的情况下,加大了感受野,让每个卷积输出都包含较大范围的信息。空洞卷积经常用在实时图像分割中。当网络层需要较大的感受野,但计算资源有限而无法提高卷积核数量或大小时,可以考虑空洞卷积。

2.使用HDC设计的膨胀卷积通过卷积后能够保留更多原始的信息。

3.最后,如果你觉得上面的内容能给您带来一点作用的话,可以给我点个👍,谢谢

八、参考

1.膨胀卷积(Dilated convolution)详解_哔哩哔哩_bilibili

2.空洞卷积(膨胀卷积)的相关知识以及使用建议(HDC原则)_Le0v1n的博客-CSDN博客_空洞卷积的作用

3.一文详解什么是空洞卷积?_Mr.Jk.Zhang的博客-CSDN博客_空洞卷积 

4.图像分割—— 膨胀卷积的应用_清水河小小龙虾的博客-CSDN博客 

  • 43
    点赞
  • 120
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: 扩张卷积dilated convolutions)是一种卷积神经网络中的操作,它可以在不增加参数数量的情况下增加感受野(receptive field),从而提高模型的性能。扩张卷积通过在卷积核中插入空洞(dilation)来实现感受野的扩大,这样可以在不增加卷积核大小的情况下增加感受野。扩张卷积在图像分割、语音识别等领域中得到了广泛的应用。 ### 回答2: 扩张卷积dilated convolutions)是一种在计算机视觉和图像处理等领域广泛应用的卷积方法。与传统的卷积方法不同,扩张卷积能够通过增加滤波器中间的空隙,对输入信号进行更加密集和丰富的特征提取,从而提高模型的效果和性能。 扩张卷积的实现方法是,在常规卷积滤波器中间插入一些空隙,这些空隙被称为dilation rate或dilation factor,即扩张率或膨胀系数。扩张率默认为1,表示滤波器的每个元素都依次作用于输入信号上,计算出对应的输出特征。而当扩张率大于1时,滤波器中间的空隙就会增加,使得每个元素的作用范围扩大,能够同时捕捉到更远距离的特征。 因此,扩张卷积能够提高模型学习到的感受野,加强对输入信号不同尺度和不同特征间关系的理解和表达能力。此外,扩张卷积还能够有效地减少模型卷积层的参数数量和计算负荷,提高模型的可训练性和泛化能力。 总的来说,扩张卷积是一种非常有用的卷积方法,可以应用于多种深度学习任务,包括图像分割、语音识别、自然语言处理等,为模型提供更精准、高效和全面的特征提取支持。 ### 回答3: 扩张卷积Dilated convolutions)是一种卷积神经网络(CNN)中的重要技术,它可以在保持卷积层输出形状不变的情况下增加感受野(receptive field),从而更好地处理输入图像中的局部特征。 传统卷积操作通常使用固定大小的滤波器,以缩小图像尺寸和提取特征。然而,这种方法有一个问题,就是当滤波器尺寸变大时,卷积层输出的尺寸会减小,这将导致丢失一些重要的信息,例如一些全局特征。扩张卷积正是为了解决这个问题而应运而生的。 扩张卷积中,使用的滤波器与传统卷积相同,但是在卷积计算时,滤波器中的元素不再相邻,而是跳过某些位置(空洞或dilation),这样能够增加滤波器的有效感受野大小,而不影响输出的尺寸。因此,使用扩张卷积可以在保持尺寸不变的情况下使用更大的滤波器,这有助于提取更丰富的特征,使网络能够更好地处理图像。 扩张卷积的一个很好的应用场景是在语义分割任务中。在语义分割中,需要将输入图像的每个像素分配到不同的类别中。为了实现这个任务,需要使用具有大有效感受野的滤波器,以识别图像中更广泛的上下文信息。扩张卷积可以帮助实现这个目标,同时不必调整卷积层的输出尺寸,从而提高了卷积神经网络的性能。 总之,扩张卷积是一种增加感受野的有效方法,可以提高CNN网络的性能,特别适用于语义分割等视觉任务。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值