本系列是基于像素分割的语义分割算法,谷歌团队提出来的,目前分为4个版本。
DeepLabV1 和DeepLabV2
问题
作者认为语义分割需要解决三个问题:
- 过多的pool导致图片分辨率降低。
- 不同分辨率的分割对象(多尺度问题)。
- 由于pool使得DCNN(深度卷积圣经网络)具有不变性(图片翻转后类别不变),有利于分类任务,但是不利于稠密的预测任务比如语义分割,会损失定位精度。
解决
1 过多的pool导致图片分辨率降低。
去掉最后几个axpool(s=2->1)将接下来的卷积层转为膨胀卷积。
- 膨胀卷积的作用: 在没有加入参数和多余的计算情况下,扩大感受野。
假设一维条件下,膨胀卷积的示意图如下所示:
DeepLabV1具体作法如下图所示,以vgg16为baseline。
图中蓝色框使用的是膨胀卷积,从图中可以看出,经过pool5后,从原来的缩小32倍,变为缩小8倍左右。
2 目标的大小变化。
multi_input 或者aspp(proposed)
- multi_input:缩放某一张图片,然后输入到多个DCNN,最后将某一层的特征图放大到原图并融合所有的结果。但是这种做法计算量大。
- 文中受spp的启发提出一种新的做法叫做ASPP即使用膨胀卷积的spp,实验结果表明,使用ASPP-L: four branches, r = {6, 12, 18, 24}的效果最好。ASPP如下图。
具体作法如下图所示:
在图b中,这些通道都是独立的,并行进行的。
3 由于DCNN(深度卷积圣经网络)具有不变性(图片翻转后类别不变),有利于分类任务,但是不利于稠密的预测任务比如语义分割,会损失定位精度。
提高模型掌握细粒度特征的能力。
- 通常的做法是skip-layers,FCN中提出的。
- 文的方法是使用fully connected Conditional Random Field (CRF) 。因为DCNN具有不变性,所以用于分类,FC-CRF对DCNN的输出进一步去噪细化,用于定位,使分割边界更加清晰。
其他提高精度的方法
- 更改学习策略:由固定step更新lr转为使用某个函数计算lr,提高1.17%。
- 数据增强:使用随机缩放输入图片的方式(0.5-1.5),提高1.59%。
缺点
- 不能端到端进行训练。===>需要整合DCNN和FC-CRGF。
DeepLabV3
继续提高模型精度,根据一些现有的有利探索或是创新,优化之前的模型,与之前的不同之处:
问题
不同分辨率的分割对象(多尺度问题)。
解决
- 提出一种新的cascade模型,增加了baseline(resnet)的网络深度。
- 修改了ASPP结构,将图片级的信息加入到ASPP当中,称作ASPP模型。
总体来说就是提出一种新的cascade模型和在原有ASPP模型上做了一个小小的改动。
文中提出了四种网络结构用于解决multiscale问题,如下图:
图a中,在V2中已经使用过,缺点是计算量大而且由于GPU内存的限制不能适应更大的scale。
图b中,相当于FPN,在其他文章中已经证明了是一种有效的方法。
图c中,属于cascade模型,接下来会详细介绍。
图d中,是ASPP模型,接下来会详细介绍。
Cascade模型
图a是没有使用膨胀卷积的模型。图b使用膨胀卷积的模型。每个block块都是由3个3x3卷积层构成(包括bn层),按照resnet的方式,每个block内的最后一层卷积的stride设为2除下采样的最后一个block(对应于图中的block3)。
- 采用multi_grid方法,即每个block内3个卷积作为一组使用固定的rate值。设
o
u
t
p
u
t
_
s
t
r
i
d
e
output\_stride
output_stride表示输入图片降低分辨率的倍数,当
o
u
t
p
u
t
_
s
t
r
i
d
e
=
16
output\_stride=16
output_stride=16时,令
m
g
=
(
1
,
2
,
4
)
mg=(1, 2, 4)
mg=(1,2,4),
m
g
mg
mg表示在每个block内rate/hole值,当
o
u
t
p
u
t
_
s
t
r
i
d
e
=
8
output\_stride=8
output_stride=8时,
m
g
=
2
∗
(
1
,
2
,
4
)
mg=2*(1, 2, 4)
mg=2∗(1,2,4),以此类推。
- 通过实验发现,当rate的值很大时,卷积核退化为1x1,因为中央的权重值起作用。
实验结果
- 测试mg值
mg被使用到block4及以后的block中。
从图中可以看出当达到block7时,mg=(1,2,1)时效果最好,当达到block4时,mg=(1,2,4)时效果最好,通常rate值取前一个值的两倍。 - 测试output_stride值
当达到block7时,如下图。
从图中可以看到,当output_stride=8时效果最好。 - test
表中的结果默认没有使用COCO 预训练。
ms表示multi_scale,在测试时使用multi_scale,最后融合结果。flip表示训练时使用flip,数据增强。
ASPP模型
模型如下图所示:
同样地,block3最后一层卷积核的stride=1。ASPP与DeepLabV2不同的是
- 增加了图像级的信息,由image pooling计算所得,image pooling使用GAP,将fmp---->1x1的fmp---->经过1x1卷积---->upsample
- 增加了bn层。
- 增加了1x1Conv。
实验结果
- test
COCO表示是否使用COCO预训练模型。
训练细节
- 使用COCO数据集预训练模型
因为只在VOC2012数据集训练的模型在某些数量少的类别上或一些难以区分的类别上分割效果不太好。所以先在COCO数据集上预训练。
在COCO上只训练与VOC上相同的类别,不同类别都置为背景。
test结果图
DeepLab3+
使用一些当前先进技术改进之前的版本。
问题
当output_stride=8时,之前的网络才能取得很好的效果,但是由于GPU内存的限制,当baseline是resnet101时,需要将78层卷积层改为膨胀卷积,因此计算量很大,不是说膨胀卷积不会增加参数和计算量吗????。
解决
- 提高速度:使用atrous separable convolution。减少参数和计算量。
- 提高精度:
- 将ASPP的结果与之前的fmp相融合,类似于skip-layers。
- 修改baseline Xception结构。
atrous separable convolution
将膨胀卷积应用于深度可分离卷积(depthwise separable convolutions),首先逐通道使用kxk卷积核卷积,然后使用1x1卷积核做正常的卷积,来融合各个通道的信息,以减少参数数量。
模型结构
encoder负责提取图像特征,decoder使用low-level features恢复边界信息。
修改后的Xception结构
- 使用更多的层。
- 全部的最大池化层被stride=2的depthwise separable convolutions代替。
- 使用conv-bn-relu结构。