图像的语义分割

欢饮达旦,大醉,作此篇,兼怀Offer。

这几天面试,给面试官讲语义分割,面试官好像都不是很懂似的(希望不是我搞错了吧☯)。几乎上每次都得先探讨一下什么是语义分割。

总结

需要掌握以下方面:

  • 掌握一个过程:从粗略到精细的过程。
  • 掌握三种改进方向:卷积模块的设计(Inception、Res模块、Xception)、编解码的设计、上下文信息的整合(多尺度聚合、特征融合、空洞卷积级联、金字塔池化模块)。
  • 掌握三种架构/结构/模块:编码解码架构、空洞卷积结构、金字塔池化模块。
  • 掌握三个架构图:FCN、PSPNet、DeepLab。

基本概念

图像语义分割可以说是图像理解的基础技术,在自动驾驶系统(街景识别与理解)、无人机(着陆点判断)以及穿戴设备中举足轻重。

图像由许多像素组成,而“语义分割”就是将像素按照图像中表达“语义”含义的不同进行“分割”(Segmentation)。

街景识别示例:

语义分割示例

实例分割示例:
语义分割示例

前DL时代的语义分割

DL之前的语义分割工作多是根据图像“像素自身的低阶视觉信息”来进行图像分割。这样的算法复杂性不高,在较困难的分割任务上的分割效果不好。

常见算法:

  • 像素级别的“阈值”分割法
  • 基于“像素聚类”的分割方法
  • 基于“图划分”的分割方法

DL时代的语义分割

在计算机视觉进入深度学习时代之后,语义分割进入了全新的发展阶段。

以全卷积神经网络(Fully convolutional networks,FCN)为代表的一系列基于卷积神经网络的语义分割方法相继提出,屡屡刷新图像语义分割的精度。

深度学习早期

“图像块”分类:利用像素周围的图像块对每一个像素进行分类。

缺点:因为卷积分类网络有全连接层,所以输入图片需要有固定的大小。

全卷积神经网络(FCN)

“全卷积神经网络”可以说是深度学习在“图像语义分割”任务上的开创性工作。

端到端的卷积网络

“FCN”直接进行“像素级”“端到端”的“语义分割”。基于主流的深度卷积神经网络模型来实现,主要是修改ImageNet预训练模型。

卷积成替换全连接层

一般来说,对ImageNet进行分类的卷积分类网络的后三层是全连接。

在FCN中,将含有全连接的卷积网络的前两个全连接层替换为两个卷积层,将最后一个全连接层替换为有21个1×1卷积核的卷积层。

但是,由于pool的下采样,使得最后的特征图大小比原图小,这就给训练带来了问题。为了解决下采样的问题,FCN利用双线性插值将网络的特征图上采样到原图大小。

FCN

引入跳跃连接改善上采样的粒度

另外,为了更好地预测图像中的细节部分,FCN还将网络的pool4和pool3的浅层特征图也考虑近来,分别作为FCN-16s和FCN-8s的输出,与原来FCN-32s的输出结合在一起做最终的语义分割结果。

FCN

由于池化操作造成了信息损失,上采样只能生成粗略的分割结果,所以从高分辨率的特征图中引入“跳跃连接”改善上采样的精度。

结果比较

从结果中可以看出,由于池化层的下采样倍数的不同导致不同的语义分割精细程度。FCN-32s利用了最后一层池化的输出,下采样倍数较高,对应的语义分割结果最为粗略。FCN-8s因下采样倍数较小可以取得较为精细的分割结果。

FCN

任意图像大小

由于没有全连接,所以可以对“任意大小的图像”进行“语义分割”,且比“图像块”方法快很多。

SegNet

FCN网络中使用了“解卷积层”(或双线性插值)和“少量的跳跃连接”,因此,输出的分割结果比较粗糙。

SegNet引入了更多的“跳跃连接”。

SegNet没有使用FCN中“编码器”产生的特征图,而是使用了“最大池化层的索引”。

SegNet

Dilated Convolutions

通过空洞卷积进行多尺度上下文聚合。

FCN的问题

由于池化层的存在,特征图的大小越来越小。FCN的设计初衷是需要和输入大小一致的输出,因此FCN做了上采样。但是上采样并不能将丢失的信息全部无损地找回来。

去掉池化层

Dilated Convolution是一种很好的解决方案:既然池化的下采样操作会带来信息损失,那么就把池化层去掉。

但是池化层去掉随之带来的是网络各层的感受野(Receptive field)变小,这样会降低整个模型的预测精度。

Dilated Convolution的主要贡献是,如何在去掉池化下采样操作的同时,而不降低网络的感受野。

卷积对比

众所周知,“图像语义分割”需要获取“上下文信息”帮助提高准确率。

不使用空洞卷积的传统卷积通过“下采样(pooling)”来增大感受野,以此获取上下文信息。

  • 卷积核的大小不变
  • 减少了数据量
  • 有利于防止过拟合
  • 但是损失了分辨率,丢失了一些信息

空洞卷积通过膨胀卷积核来增大感受野,以此获取上下文信息。

  • 参数个数没有增加
  • 数据量没有减少
  • 分辨率没有损失(膨胀卷积支持以指数级扩增感受野且没有分辨率损失或者覆盖)
  • 但是计算量增大,内存消耗增大

空洞卷积感受野计算

从传统卷积的定义到膨胀卷积的定义:传统卷积是膨胀卷积的特例

Dilated

多尺度上下文信息聚集

使用膨胀卷积收集多尺度上下文信息且没有分辨率损失。

待补充。

PSPNet

主要贡献

  • 使用“空洞卷积”来改善“ResNet”
  • 提出“金字塔池化模块”帮助聚合上下文信息
  • 用了辅助损失(auxiliary loss,在主分支损失之外增加了辅助损失)

金字塔池化模块

金字塔池化模块通过“较大核的池化层”获取“全局的场景分类”信息,提供语义分割的“类别分布信息”。

金字塔池化模块连接“ResNet的特征图”和“并行池化层的上采样结果”。

信息全在图上了:

pspnet_architecture

DeepLab 系列

有待补充

  • 使用“带孔/空洞”卷积改进ResNet模型:在不增加参数的情况下扩大感受野。
  • 提出了“空洞金字塔模块”(ASPP模块):通过不同的rate产生一组特征图,从而捕获多个尺度的对象。
  • 采用了全连接CRF(条件随机场)
  • 在编码过程中获取上下文信息,因此不需要很大的解码网络。
  • V3:级联或者并行地应用atrous卷积模块。
  • V3++:以DeepLabv3作为encoder模块,并添加了一个简单却有效的decoder模块。
  • V3++:将Xception应用于分割任务中。

V2的ASPP模块:

DeepLab_ASPP

级联地应用atrous卷积模块:

DeepLab_V3_GoingDeeper

并行地应用atrous卷积模块(ASPP):

DeepLab_ASPP

V3++结合encoder-decoder架构:

DeepLab_V3++

捕获上下文信息的四种方式:

DeepLab_Capture_multi_scale_context

RefineNet

有待补充

后处理

条件随机场

通常CRF被用于后处理以改进分割结果(表示怀疑)。

CRFs是一种基于“底层图像的像素强度”进行“平滑分割”的“图模型”。相似强度的像素趋向于标记为同一类别。

发展

从粗略到精细的过程

图像的语义分割是一个从粗略到精细的过程。

图像分类 => 目标检测 => 语义分割 => 实例分割 => 关键点检测

Problem

三种改进方向

卷积模块

设计更有效的卷积模块,更好地提取特征。

  • 反卷积
  • Inception
  • Xception
  • Res模块
  • 空洞卷积

解码变种

设计更好的编码器和解码器,逐渐的获得清晰的物体边界。

  • 解码器和编码器的设计

整合上下文信息

整合不同空间尺度的上下文信息,对局部信息和全局信息进行平衡。

捕获上下文信息的四种方式:

  • 多尺度聚合:将图像resize到多个尺度分别分割,最后整合分割结果。
  • 特征融合:提取不同层的特征进行融合,包含了不同的局部上下文信息。例如跳跃连接。
  • 膨胀卷积:膨胀卷积核获得更大的感受野(带孔卷积)。例如PSPNet和DeepLab。
  • 金字塔池化:例如PSPNet和DeepLab

DeepLab_Capture_multi_scale_context

三种架构/结构/模块

Encoder-Decoder架构

“编码器”通过“池化层”逐渐“减少空间维度”,“解码器”逐渐“恢复物体的细节和空间维度”。

为了使“解码器”有更好的物体细节,通常会有“从编码器到解码器的shortcut连接”。

代表模型:

  • U-Net
  • SegNet/DeconvNet
  • RefineNet

Dilated/Atrous convolutions结构

使用“空洞”/“带孔”卷积代替“池化层”。

代表模型:

  • PSPNet
  • DeepLab V1/V2/V3

金字塔池化模块

整合特征图的上下文信息。

代表模型:

  • ASPP:DeepLab中的空间空洞金字塔池化模块。
  • PPM:PSPNet中的金字塔池化模块。