2D 语义分割——DeepLabV3plus 复现

文章目录

  • 语义分割简介
  • DeepLabV3plus
    • 模型结构
    • 基础知识点
    • 模型实现
  • Backbone 设计
  • 实验结果

语义分割简介

语义分割结合了图像分类、目标检测和图像分割,其通过一定的方法将图像分割成具有一定语义含义的区域块,并识别出每个区域块的语义类别,实现从底层到高层的语义推理过程,最终得到一幅具有逐像素语义标注的分割图像。图像语义分割方法有传统方法和基于卷积神经网络的方法,而传统的语义分割方法又可分为基于统计的方法和基于几何的方法。随着深度学习的发展,语义分割技术得到很大的进步,基于卷积神经网络的语义分割方法与传统的语义分割方法最大不同是,网络可以自动学习图像的特征,进行端到端的分类学习,大大提升语义分割的精确度

基于候选区域的语义分割方法首先从图像中提取自由形式的区域并对他们的特征进行描述,然后再基于区域进行分类,最后将基于区域的预测转换为像素级别预测,并使用包含像素最高得分的区域来标记像素。该方法虽然为语义分割的发展带来很大的进步,但是它需要生成大量的候选区域,此过程要花费大量的时间和内存空间。此外,不同算法提取的候选区域集的质量也千差万别,这将直接影响了最终的语义分割效果。

基于全卷积的深度语义分割模型,主要特点是没有使用全连接层,全部由卷积层构成。该类模型又可细分为基于全卷积的对称语义分割模型、基于全卷积的扩张卷积语义分割模型和基于全卷积的残差网络语义分割模型。目前,基于全卷积的对称语义分割模型主要有 FCNSegNetUnet 及其各种变体等,但该类模型得到分割结果较粗糙,其忽略了像素与像素之间的空间一致性关系。于是 Google 提出了一种新的扩张卷积语义分割模型,考虑了像素与像素之间的空间一致性关系,可以在不增加参数量的情况下增加感受野,该类语义分割模型主要有 DeepLab 系列、RefineNet 等。此外,基于全卷积的残差网络语义分割模型主要有 PSPNet 等。其中,DeepLab 系列中的 DeepLabV3plus 的复现为本次大作业的主要工作。

目前流行的深度网络,比如 VGGResNet等,由于 pooling 操作和卷积步长的存在,其特征图会越来越小,从而导致损失一些细粒度的信息。对于分类问题而言,只需要深层的强语义信息就能表现较好,但是对于稠密预测问题,比如逐像素的图像分割问题,除了需要强语义信息之外,还需要较高的空间分辨率。针对这些问题,很多方法都提出了解决方案:

  1. 针对 pooling 下采样过程中的分辨率损失,可采用 deconvolution 恢复。但是却很难恢复位置信息
  2. 使用空洞卷积保持分辨率,增大感受野,但是这么做会明显增加了计算代价,且空洞卷积是一种 coarse sub-sampling,因此容易损失重要信息
  3. 通过 skip connection 来产生高分辨率的预测。

DeepLabV3plus

模型结构

DeepLabV3plus 是一个用于语义分割的模型,它提出了一种新的 encoder-decoder 结构,采用 DeepLabv3 作为编码器模块,并使用一个简单而有效的解码器模块。该模型可通过 atrous 卷积(空洞卷积)来控制所提取的编码器特征的分辨率,从而权衡精度和运行时间。此外,该网络还将 Xception 模型用于分割任务,并将 Depthwise Separable Convolution 应用于 ASPP 模块和解码器模块,从而得到更快更强的 encoder-decoder 网络。其网络结构如下:

2D 语义分割——DeepLabV3plus 复现_第1张图片

  1. 将图像 A 送进改造过后的主流深度卷积网络 B(其中使用了空洞卷积)提取特征,从而得到高级语义特征 C 和低级语义特征 E
  2. 高级语义特征 C 进入到空洞金字塔池化模块 ASPP,分别与四个空洞卷积层和一个池化层进行卷积和池化(需上采样),得到五个特征图(大小一致),然后将这些特征图拼接起来并送入一个 1x1 的卷积层进行运算后得到 D(通道数为原先的 1/5),D 再经过上采样得到 G(方便后面拼接操作)
  3. 低级语义特征 E 经过 1x1 卷积进行降通道数得到 F(大小与 G 一致),将这两者拼接起来通过卷积层得到 H(降低通道数)。将 H 送入 3x3 卷积层中并上采样至与原图大小一致后输出预测结果 I

基础知识点

  1. 对于语义分割,空间金字塔池化(spatial pyramid pooling)模块可通过池化不同分辨率的特征图来捕获丰富的上下文信息,而 encoder-decoder 结构可以得到清晰的物体边界。通常情况下,encoder 减少特征图的大小并捕捉更高层次的语义信息,而 decoder 用来恢复空间信息。尽管丰富的语义信息存在于最后的特征图中,但由于 backbone 内部的池化或卷积操作,使得与对象边界相关的详细信息缺失。为了缓解这一问题,DeepLabV3plus 引入空洞卷积这一比较特殊的卷积操作。以下是 SPP、encoder-decoder 以及 SPP+encoder-decoder+atrous conv 的结构示意图:

2D 语义分割——DeepLabV3plus 复现_第2张图片

  1. Depthwise separable convolution 是一个可以减少计算量和参数量,并保持与普通卷积类似(或略好)性能的操作,其相当于 Depthwise 卷积 + Pointwise 卷积

2D 语义分割——DeepLabV3plus 复现_第3张图片

  • Depthwise 卷积一个通道由一个卷积核负责(即第n个通道由第n个卷积核来处理),其输出通道数与输入通道数一致

  • Pointwise 卷积:卷积核大小为 1x1xc,其中 c 为输入通道数,输出通道数与卷积核个数一致

  • Atrous卷积:显式地控制深度卷积神经网络中计算的特征图的分辨率,并调整卷积核的感受野(field-of-view)以捕获多尺度信息

  • Atrous depthwise卷积:DW 卷积中的卷积核改为空洞卷积,deeplabv3+ 中使用的膨胀率为 2,如图中 (c) 所示

模型实现

DeepLabV3plus 模型主体在 deeplabv3plus.py 中实现,该文件包含3个类:

  1. 继承自 nn.Sequential 的 CBR 类,其包含卷积、批归一化和激活函数,在卷积中通过参数 dilation 来指定卷积核的膨胀率

2D 语义分割——DeepLabV3plus 复现_第4张图片

  1. 继承自 nn.Module 的 ASPP 类,该模块包含五个分支。branch1 卷积核大小为 1x1,而 branch5 通过池化操作可得到全局性的特征,但需通过上采样及卷积操作使特征图大小、通道大小与其他分支一致;branch2-branch4 的卷积核大小为 3,膨胀率分别为6rate、12rate、18rate,其 rate 根据 output stride 来确定,可分为 12

2D 语义分割——DeepLabV3plus 复现_第5张图片

  1. 继承自 nn.Module 的 DeepLabV3plus 类,该类的 backbone 支持 Xception、ResNet 和 MobileNetV2。其中,由于 MobileNetV2 比较轻量级,所以其输入通道(高级语义特征通道数)和低级语义特征通道数相对较小,分别为 320 和 24;骨干网络 ResNet 中参数 layers 的最后一个值在代码中并没有被我所使用,其通过一个长度等于 3 的数组代替;downsample_factor 其实就是论文中的 output stride,大小为 168。处理低级语义特征的 shortcut_conv 的输出通道根据论文中的建议使用 48

2D 语义分割——DeepLabV3plus 复现_第6张图片
2D 语义分割——DeepLabV3plus 复现_第7张图片

Backbone 设计

  1. Xception:DeepLabV3plus 所改进的 Xception 拥有更多的 layers,其在 Middle flow 中重复使用 16 次,而原始网络仅重复 8 次。此外,所有的 max pooling 操作都改为 deepwise separable convolution 并且在 3x3 的 DW 卷积操作后添加 batch normalization 和 ReLU 激活函数。该骨干网络在 xception.py 中实现,其网络结构如下:

2D 语义分割——DeepLabV3plus 复现_第8张图片
2D 语义分割——DeepLabV3plus 复现_第9张图片

  1. ResNet101:DeepLabV3plus 使用的 ResNet101 在网络层数上与原始 ResNet101 相同,只是后面的卷积操作使用了 dilation 来指定膨胀率。该骨干网络在 resnet.py 中实现,其网络结构如下:

2D 语义分割——DeepLabV3plus 复现_第10张图片
2D 语义分割——DeepLabV3plus 复现_第11张图片

  1. MobileNetV2:该骨干网络使用倒残差结构,相对于残存结构,其将降维和升维的顺序进行了调换,并且将 3x3 卷积换为 3x3 的 DW 卷积。此外,网络中的激活函数使用 ReLU6。为了得到适用于 DeepLabV3plus 的骨干网络,可将 MobileNetV2 卷积核的膨胀率根据 output stride 来修改,但由于该网络比较轻量级,所以最后得到的低级语义特征和高级语义特征的通道数相对于 Xception 和 ResNet101 会比较小。该网络在 mobilenetv2.py 中实现,其网络结构如下:

2D 语义分割——DeepLabV3plus 复现_第12张图片
2D 语义分割——DeepLabV3plus 复现_第13张图片
2D 语义分割——DeepLabV3plus 复现_第14张图片

实验结果

本次实验采用数据集为 VOC2012,损失函数为交叉熵损失或 Focal loss,训练集加载时仅做随机旋转、随机翻转和修改大小操作。由于本人计算机显存不足以支持较大规模训练,训练过程使用的 output stride 采用16(训练效果相对于 8 会较差),batch size 为 8(MobileNetV2)和 4(Xception 和 ResNet101)。以下是实验所使用 backbone 相应的 mIOU 值以及骨干网络为 Xception 的部分预测结果:

Backbone Xception ResNet101 MobileNetV2
mIOU 80.3 78.5 76.1
  • xception 的部分预测结果

  • mobilenetv2 的部分预测结果

若需要代码可以下载我上传的资源,不需要积分,但本资源不包含训练后的权重,仅供参考

你可能感兴趣的:(pytorch,计算机视觉,深度学习,pytorch)