如何理解扩张卷积(dilated convolution)

扩张卷积原理

扩张卷积(Dilated Convolution)也被称为空洞卷积或者膨胀卷积,是在标准的卷积核中注入空洞,以此来增加模型的感受野(reception field)。相比原来的正常卷积操作,扩张卷积多了一个参数: dilation rate,指的是卷积核的点的间隔数量,比如常规的卷积操作dilatation rate为1。它的论文是:《MULTI-SCALE CONTEXT AGGREGATION BY
DILATED CONVOLUTIONS》

前言

CNN结构中,大部分的layer是靠Conv和Pooling完成的,这两个层是CNN中非常重要的两个组件。一般情况下对于一个图像分类任务,一个靠Conv和Pooling堆叠起来的backbone都是具有不错的特征提取能力的,这种堆叠最经典的就是结构就是VGG。在图像输出网络后,Conv做特征的抽取,而Pooling做特征的聚合,并且让模型具有一定程度上的平移不变性,还可以降低后面卷积层的算力。最后到全连接层输出分类结果就好了。
但是这种结构对目标检测和图像分割来说,就会存在一些问题:

  • 目标检测和图像分割中感受野很重要,比如目标检测一般情况下要在最后一层特征图上做预测,那么特征图上的一个点能过映射到原图的多少像素,决定了网络能检测到的尺寸上限,而保证感受野就要靠下采样,下采样的结果就是小目标不容易被检测到;
  • 针对上面的问题,多层特征图拉取分支能改善这个问题,因为小目标在越靠前的特征图上越容易体现,但是前面的特征图语义信息不够,比如在SSD中就存在这个问题;
  • 不做下采样,只增加卷积层的数量,首先会增大网络的计算量,其次不做Pooling的聚合最后的特征提取效果也会受到影响,而且感受野不会变化。
    所以有没有一种可以不牺牲特征图尺寸的情况下增加感受野的方式呢?
    扩张卷积就能做到这点。

原理

在这里插入图片描述
扩张卷积操作还是很好理解的,上图中(a)是基础的卷积核,扩张卷积就是在这个基础卷积核加入间隔,上图(b)对应 3 × 3 3\times3 的dilation rate=2的卷积,但是间隔为1,也就是相当于对应 7 × 7 7\times7 的图像块,可以理解为kernel size还是变成了 7 × 7 7\times7 ,但是却只有9个点有参数,其余的位置参数都是0,和输入特征图对应位置的像素进行卷积计算,其余的位置都略过。图©和图(b)是类似的,只是dilation rate=4,相当于变成了 15 × 15 15\times15 的卷积核。
而卷积核尺寸变大了,感受野也就自然变大:
R F i = R F i 1 + ( k 1 ) × s RF_{i}=RF_{i-1}+(k-1)\times s
R F i 1 RF_{i-1} 是上一层的感受野, k k 是卷积核的尺寸, s s 是步长。

存在的问题

扩张卷积虽然在不损失特征图尺寸的情况下增大了感受野,但是也会带来新的问题,主要是体现在卷积的输入,由于卷积核是有间隔的,这意味着不是所有的输入都参与计算,整体特征图上体现出一种卷积中心点的不连续,尤其是当叠加的卷积层都是用相同的dilation rate的时候:
在这里插入图片描述
上图中示例是三个dilation rate=2扩张卷积层连续卷积后的结果,蓝色的标识是参与计算的卷积中心,而颜色的深度表征次数。可以看到,由于3次的dilation rate是一致的额,所以卷积的计算中心会呈现出一种网格状向外扩展,有一些点不会成为计算的中心点。

解决方法

解决这个问题最直接的方法当然就是不使用连续的dilation rate相同的扩展卷积,但是这还不够,因为如果dilation rate是成倍数的,那么问题还是存在。所以最好的方式是将连续排布的扩张卷积的dilation rate设置为“锯齿状”,比如分别是[1,2,3],那么卷积中心的分布就会变成下面这样,不在有遗漏的情况。
在这里插入图片描述

应用实例

扩张卷积在图像分割领域使用是比较多的,因为本身扩张卷积的原文就用来做分割,此外,它在目标检测领域也有些应用,比如SSD,在新增的Conv6层卷积使用了dilation rate=6的卷积,为了进一步增大感受野。
此外,扩张卷积已经在caffe原始代码中实现了,就是dilation参数。

layer {
  name: "conv1"
  type: "Convolution"
  bottom: "data"
  top: "conv1"
  convolution_param {
    num_output: 64
    bias_term: false
    pad: 1
    kernel_size: 3
    group: 1
    stride: 2
    weight_filler {
      type: "xavier"
    }
    dilation: 1
  }
}

上面这种情况就是一个基础的卷积层,它的dilation=1。

发布了203 篇原创文章 · 获赞 1355 · 访问量 146万+

猜你喜欢

转载自blog.csdn.net/chaipp0607/article/details/99671483