这里有个可视化、直观的图:https://github.com/vdumoulin/conv_arithmetic
https://zhuanlan.zhihu.com/p/50369448
https://www.zhihu.com/question/54149221/answer/192025860
https://www.zhihu.com/question/54149221/answer/323880412
https://blog.csdn.net/qq_21997625/article/details/87080576
deconved:https://www.zhihu.com/question/43609045/answer/132235276
图来自:如何理解空洞卷积(dilated convolution)? - 梁思远的回答 - 知乎 https://www.zhihu.com/question/54149221/answer/547315413
增大感受野:可以设置普通卷积的stride>1,但是stride大于1就会导致downsampling,卷积后图像尺寸减小、分辨率降低。
Dilated convolutional layer (also called as atrous convolution in DeepLab) allows for exponential increase in field of view without decrease of spatial dimensions.
注意:解决办法大概就是:使得卷积前后的每组结果能进行相互交错,相互依赖,解决空洞卷积局部信息丢失问题。或者捕获多尺度信息、获得局部信息依赖,以此解决局部信息不一致的问题。
在Deeplab_v3中对dilation rate的使用提出一个思考,当dilation rate过大时,由于图像的边缘效应导致long range information并没有被学习到。 * 个人思考:在网络的底层,不适合使用较大的dilation rate(貌似很多都是用标准卷积),因为底层网络层更多包含底维信息,如果引入大的dilation rate,会导致部分细节的底层信息被忽略掉。
1.例如[1, 2, 5, 1, 2, 5]这样的循环结构;dilated rate[1, 2, 5] with 3*3 kernel;
2.太繁琐,部分看不懂;
3.在最后生成的4组卷积结果之后,经过一层组交错层;第二种方法为在空洞卷积之前进行局部信息依赖,即增加一层分离卷积操作;
4.增加图像级特征,使用全局池化获取图像全局信息,没有仔细说明,需要补充学习;
5.ESPNet利用分解卷积的思想,先用1*1卷积将通道数降低减少计算量,后面再加上基于空洞卷积的金字塔模型,捕获多尺度信息。所有卷积后都使用BN和PReLU(PReLU(Parametric Rectified Linear Unit)。很多实时分割小网络都使用了PReLU;使用Adam训练,很多小网络使用这个;消融实验表明,在一维卷积之间加入BN+PReLU,精度会增加1.4%;
6.Kronecker convolution,参数量是不增加的,总体效果mIOU提升了1%左右。提出了一个TFA模块,利用树形分层结构进行多尺度与上下文信息整合。结构简单,但十分有效,精度提升4-5%。没有仔细说明,需要补充学习、
7.看不懂。
8.未细说。
;
目录
dilation conv
空洞卷积的作用
空洞卷积gridding问题
解决方案
1. Panqu Wang,Pengfei Chen, et al.Understanding Convolution for Semantic Segmentation.//WACV 2018
2. Fisher Yu, et al. Dilated Residual Networks. //CVPR 2017
3. Zhengyang Wang,et al.Smoothed Dilated Convolutions for Improved Dense Prediction.//KDD 2018.
4. Liang-Chieh Chen,et al.Rethinking Atrous Convolution for Semantic Image Segmentation//2017
5. Sachin Mehta,et al. ESPNet: Efficient Spatial Pyramid of DilatedConvolutions for Semantic Segmentation.//ECCV 2018
6. Tianyi Wu,et al.Tree-structured Kronecker Convolutional Networks for Semantic Segmentation.//AAAI2019
7. Hyojin Park,et al.Concentrated-Comprehensive Convolutionsfor lightweight semantic segmentation.//2018
8. Efficient Smoothing of Dilated Convolutions for Image Segmentation.//2019
首先空洞卷积的目的是为了在扩大感受野的同时,不降低图片分辨率和不引入额外参数及计算量(一般在CNN中扩大感受野都需要使用s>1的conv或者pooling,导致分辨率降低,不利于segmentation。而如果使用大卷积核来增加感受野,会引入额外的参数及计算量)。可以代替降采样(pooling或s2/conv),标准卷积可以看做空洞卷积的特殊形式。
空洞卷积(Dilated/Atrous Convolution),广泛应用于语义分割与目标检测等任务中
而dilated conv不是在像素之间padding空白的像素,而是在已有的像素上,skip掉一些像素,或者输入不变,对conv的kernel参数中插一些0的weight,达到一次卷积看到的空间范围变大的目的。
空洞卷积可以任意扩大感受野,且不需要引入额外参数,但如果把分辨率增加了,算法整体计算量肯定会增加。
空洞卷积实际卷积核大小:
d为空洞卷积参数空洞率dilation rate;(d - 1) 的值则为塞入的空格数,假定原来的卷积核大小为 k,那么塞入了 (d - 1) 个空格后的卷积核大小 n 为:
因此输出feature map尺寸是
感受野从k*k变为[k+(r-1)*(k+1)]*[k+(r-1)*(k+1)]
same的话需要pad的像素点是(new_width-1)*S + k - W_ori
以三个r=2的3*3/s1空洞卷积为例计算感受野:
K=k+(k-1)(r-1)=3+2*1=5
R=1+4+4+4=13
而语义分割由于需要获得较大的分辨率图,因此经常在网络的最后两个stage,取消降采样操作,之后采用空洞卷积弥补丢失的感受野。
以语义分割中常使用的VGG和ResNet50为例,计算其空洞前与空洞后的感受野。
VGG16:将FC6层使用7*7卷积替换,其他不变,此版本我们称为VGG_Conv,根据deeplabv1的设置,我们使用DeepLab-CRF-7x7,即取消pool4和pool5的降采样操作,改为了3*3/s1,同时将 conv5_1-conv5_3使用r=2的空洞卷积。FC的空洞率r=4。
VGG_Conv:R=1+6)*2+2+2+2)*2+2+2+2)*2+2+2+2)*2+2+2)*2+2+2=404
DeepLab-CRF-7x7:R=1+24)+2+4+4+4)+2+2+2+2)*2+2+2+2)*2+2+2)*2+2+2=412
两者和感受野近似相等,从deeplab实验结果可以看出,感受野不一定和之前完全一样,但感受野大了效果会好一些。表中结果和自己计算的不一样,不知道表中感受野怎么计算的。。
空洞卷积得到的某一层的结果中,邻近的像素是从相互独立的子集中卷积得到的,相互之间缺少依赖。
通过图a解释了空洞卷积存在的问题,从左到右属于top-bottom关系,(从右依次卷积到左)三层卷积均为r=2的dilatedConv,可以看出最上层的红色像素的感受野为13且参与实际计算的只有75%,很容易看出其存在的问题。
使得卷积前后的每组结果能进行相互交错,相互依赖,解决空洞卷积局部信息丢失问题。或者捕获多尺度信息、获得局部信息依赖,以此解决局部信息不一致的问题。
论文地址:https://arxiv.org/abs/1702.08502
代码地址:https://github.com/TuSimple/TuSimple-DUC
使用HDC(混合膨胀卷积)的方案解决该问题,不同于采用相同的空洞率的deeplab方案,该方案将一定数量的layer形成一个组,然后每个组使用连续增加的空洞率,其他组重复。如deeplab使用rate=2,而HDC采用r=1,r=2,r=3三个空洞率组合,这两种方案感受野都是13。但HDC方案可以从更广阔的像素范围获取信息,避免了grid问题。同时该方案也可以通过修改rate任意调整感受野。
考虑到一个N个的size为K×K的扩张卷积,对应的扩张率为[r1,…,ri,..,rn],HDC的目标是让最后的接收野全覆盖整个区域(没有任何空洞或丢失边缘)。
对比膨胀卷积,主要包含以下三方面的特征:
1)叠加的膨胀卷积的膨胀率dilated rate不能有大于1的公约数(比如[2, 4, 6]),不然会产生栅格效应;
2)膨胀率dilated rate设计成了锯齿状结构,例如[1, 2, 5, 1, 2, 5]这样的循环结构;
3)膨胀率dilated rate需要满足:,其中是第i层的膨胀率dilated rate,Mi是指在i层的最大dilation rate,假设总共有n层,那么,设计的目标是让M2≤K,比如:dilated rate[1, 2, 5] with 3*3 kernel
如果特征map有比空洞率更高频的内容,则grid问题更明显。
提出了三种方法:
Removing max pooling:由于maxpool会引入更高频的激活,这样的激活会随着卷积层往后传播,使得grid问题更明显。
Adding layers:在网络最后增加更小空洞率的残参block, 有点类似于HDC。(todo ?????)
Removing residual connections:去掉残参连接,防止之前层的高频信号往后传播。
空洞卷积的分解观点,在原始特征图上周期性采样形成4组分辨率降低的特征图,然后使用原始的空洞卷积参数(去掉了空洞0)分别进行卷积,之后将卷积的结果进行上采样组合。从该分解观点可以看出,卷积前后的4个组之间没有相互依赖,使得收集到不一致的局部信息。
从上面分解的观点出发:
(1) 在最后生成的4组卷积结果之后,经过一层组交错层,类似于ShuffleNet,使得每组结果能进行相互交错,相互依赖,以此解决局部信息不一致的问题。(变异的全连接?)
(2) 第二种方法为在空洞卷积之前进行局部信息依赖,即增加一层卷积操作,卷积利用了分离卷积,并且所有通道共享参数。
在处理多尺度物体分割时,常会有以下几种方式来操作:
deeplabv2中的aspp如上图所示,在特征顶部映射图使用了四中不同采样率的空洞卷积。这表明以不同尺度采样时有效的,在Deeolabv3中向ASPP中添加了BN层。不同采样率的空洞卷积可以有效捕获多尺度信息,但会发现随着采样率的增加,滤波器有效权重(权重有效的应用在特征区域,而不是填充0)逐渐变小。如下图
当我们以不同采样率的3*3卷积核应用在65*65的特征映射上,当采样率接近特征映射大小时,3*3滤波器不是捕获全图像上下文,而是退化为简单的1*1滤波器,只有滤波器中心起作用。
即:ASPP存在的问题,当使用的空洞率增大时,atrous rate
在极限的情况下(等于特征图的大小),有效的滤波参数数量逐渐减小。极端的,当r等于特征图大小时,该卷积没有捕获整幅图像的上下文信息,3×3的卷积退化成为了1×1的卷积(只有一个权重(中心)是有效的)。
为了解决这个问题,考虑使用图片级特征,并且将全局的上下文信息合并到模型中。即在模型最后得到的特征图中采用全局平均池化,再给256个1×1的卷积(BN),然后双线性地将特征图 上采样 到所需的空间维度。最后,改善的ASPP由一个1×1的卷积,三个3×3的卷积,且rate=(6,12,18)的空洞卷积,滤波器数量为256,包含BN层。
1)如下图(a)部分Atrous Spatial Pyramid Pooling;
2)图像级特征,即将特征做全局平均池化,经过卷积再融合。如下图(b)部分Image Pooling。
针对output_stride=16的情况,cat后再将所有特征通过1x1级联到一起,生成最终的分数。
class ASPP(nn.Module):
def __init__(self, in_channel=512, depth=256):
super(ASPP,self).__init__()
# global average pooling : init nn.AdaptiveAvgPool2d ;also forward torch.mean(,,keep_dim=True)
self.mean = nn.AdaptiveAvgPool2d((1, 1))
self.conv = nn.Conv2d(in_channel, depth, 1, 1)
# k=1 s=1 no pad
self.atrous_block1 = nn.Conv2d(in_channel, depth, 1, 1)
self.atrous_block6 = nn.Conv2d(in_channel, depth, 3, 1, padding=6, dilation=6)
self.atrous_block12 = nn.Conv2d(in_channel, depth, 3, 1, padding=12, dilation=12)
self.atrous_block18 = nn.Conv2d(in_channel, depth, 3, 1, padding=18, dilation=18)
self.conv_1x1_output = nn.Conv2d(depth * 5, depth, 1, 1)
def forward(self, x):
size = x.shape[2:]
image_features = self.mean(x)
image_features = self.conv(image_features)
image_features = F.upsample(image_features, size=size, mode='bilinear')
atrous_block1 = self.atrous_block1(x)
atrous_block6 = self.atrous_block6(x)
atrous_block12 = self.atrous_block12(x)
atrous_block18 = self.atrous_block18(x)
net = self.conv_1x1_output(torch.cat([image_features, atrous_block1, atrous_block6,
atrous_block12, atrous_block18], dim=1))
return net
针对output_stride=8的情况,rate=2×(6,12,18).并行处理后的特征图在集中通过256个1×1卷积(BN),最后就是输出了,依旧是1×1卷积。
deeplabv3在v2基础上进一步探索空洞卷积,分别研究了级联ASPP与并联ASPP两种结构。
deeplabv3不同于deeplabv2,在resnet101基础上级联了更深的网络,随着深度的增加,使用了不同的空洞率的卷积,这些卷积保证分辨率不降低的情况下,感受野可以任意控制,一般让空洞率成倍增加。同时使用了Multigrid策略,在同一个blocks的不同层使用分层的空洞率,如2,4,8,而不是都使用2,这样使得感受野相比原来的有所增加。但这样同样会存在grid问题。
解决方案:增加图像级特征,使用全局池化获取图像全局信息,而其他部分的卷积为了捕获多尺度信息,这里的卷积不同于deeplabv2,加了batch normalization。
https://blog.csdn.net/qq_21997625/article/details/87080576 是cat的
ESPNet利用分解卷积的思想,先用1*1卷积将通道数降低减少计算量,后面再加上基于空洞卷积的金字塔模型,捕获多尺度信息。
之前的方法都是通过引入新的计算量,学习新的参数来解决grid问题。而这里直接使用了特征分层的思想直接将不同rate的空洞卷积的输出分层sum,其实就是将不同的感受野相加,弥补了空洞带来的网格效应。从结果上看效果不错。
训练技巧:
所有卷积后都使用BN和PReLU(PReLU(Parametric Rectified Linear Unit), 顾名思义:带参数的ReLU。很多实时分割小网络都使用了PReLU;使用Adam训练,很多小网络使用这个;如果ai=0,那么PReLU退化为ReLU;如果ai是一个很小的固定值(如ai=0.01),则PReLU退化为Leaky ReLU(LReLU)。 有实验证明,与ReLU相比,LReLU对最终的结果几乎没什么影响。
(1) PReLU只增加了极少量的参数,也就意味着网络的计算量以及过拟合的危险性都只增加了一点点。特别的,当不同channels使用相同的ai时,参数就更少了。
(2) BP更新ai时,采用的是带动量的更新方式,如下图:
上式的两个系数分别是动量和学习率。
需要特别注意的是:更新ai时不施加权重衰减(L2正则化),因为这会把ai很大程度上push到0。事实上,即使不加正则化,试验中ai也很少有超过1的。
(3) 整个论文,ai被初始化为0.25。
使用Kronecker convolution来解决空洞卷积局部信息丢失问题,以r1=4、r2=3为例,KConv将每个标准卷积的元素都乘以个相同的矩阵,该矩阵由0,1组成,这样参数量是不增加的。该矩阵为:
这样每个元素乘以矩阵后变为上面右图所示的图。因此,可以看出r1控制空洞的数量,也即扩大了感受野,而r2控制的是每个空洞卷积忽视的局部信息。当r2=1时,其实就是空洞卷积,当r2=r1=1时就是标准卷积。
总体效果mIOU提升了1%左右。除此之外,提出了一个TFA模块,利用树形分层结构进行多尺度与上下文信息整合。结构简单,但十分有效,精度提升4-5%。
针对实时语义分割提出的网络结构,深度分离卷积与空洞卷积的组合,在ESPNet上做的实验。并且说明简单的组合会带来精度的降低,由于局部信息的丢失。为此,在深度分离空洞卷积之前,使用了两级一维分离卷积捕获局部信息。
网络结构上与ESPNet保持一致,其中,并行分支结果直接Cat,不需要后处理,每个分支不需要bn+relu。消融实验表明,在一维卷积之间加入BN+PReLU,精度会增加1.4%。