Zhangzhe's Blog

The projection of my life.

0%

Semantic Segmentation Algorithms Survey

Topic

  • 本文汇总多种 语义分割算法 decode head 结构和 部分分割专用 backbone,用于理解语义分割算法的演进过程

  • decode head 模型来源: mmsegmentaion decode head

  • 本文的语义分割 decode head 是指满足如下要求的网络结构:

    1. 输入为 backbone / neck 提取的 feature mapfeature map list
    2. 输出为 segmentation 结果

语义分割推理过程

1. 原始特征处理

  • 输入的原始特征包括两类:
    • backbone 输出的 feature map(例如 PSPNet 输出)
    • backbone 不同阶段 / neck (例如 FPN) 输出的不同尺度的 feature map list
  • 对于 feature map,可以 resize 到输出大小再送入 decode head,也可以直接送入 decode head,根据具体算法选择
  • 对于 feature map list,一般有两种做法,根据具体算法选择:
    1. resize concat: 将所有 feature map 全部 resize 到输出大小后再 concat(例如 FCN-8s
    2. multiple select: 根据 indexfeature map list 中索引并输出对应的 feature map sub list

2. 特征解码

  • 1 中输出的 feature map / feature map list 转化成与输出 宽高一致feature map,也是本文具体展开讲的内容

3. 特征映射到分割任务空间

  • 2 中输出的特征映射到分割空间,具体通道数与任务定义相关(例如:二分类的语义分割输出通道为 12N 分类的语义分割输出通道数为 N

演进过程

第一代:在 CNN 结构上创新

  • FCN: 2014年,出自 UC Berkeley,分割算法起点
  • PSP: 2016年,出自商汤,FCN + 多尺度
  • ASPP: 2017年,出自 GooglePSP 的优雅实现版(DeepLab V2DeepLab V3
  • FPN: 2018年,出自 FAIRUNet 多尺度的升级版
  • UperNet: 2018年,出自旷视,PSP + FPN 更暴力的多尺度
  • DepthwiseSeparableASPP: 2018年,出自 GoogleDeepLab V3 结构的小改动(DeepLab V3+
  • DepthwiseSeparableFCN: 2019年,出自东芝 + 剑桥,FCN 的轻量化改造(Fast-SCNN
  • PointRend: 2019年,出自 FAIR,在其他 decode head 基础上级联了一个 subnetwork 实现了图像分割边缘的细化

第二代:Self-Attention (Non-local / Channel Attention)

  • Non-Local: 2017年,出自 FAIRSelf Attention 经典
  • PSANet: 2018年,出自商汤,Non-local 的二维 狗尾续貂
  • CCNet: 2018年,出自地平线,Non-local 的低算力版,使用两个低算力的 Attention 替代 Non-local Attention
  • DANet: 2018年,出自京东,两路 Non-local,一路 attention to postion 一路 attention to channel
  • EncNet: 2018年,出自商汤 + Amazon,优化了 SENet 中的暴力编码方式,在分割任务中额外加入了分类辅助监督。
  • EMANet: 2019年,出自北大,attention to channelattention to postion 可分离的 attention
  • ANN 2019年,出自华中科技大学,简化 Non-local 同时引入 PPM,极大的降低了 matmulsoftmax 两类算子的耗时
  • GCNet: 2019年,出自 MSRA,简化版 Non-local + SENet 的缝合怪
  • OCRNet: 2019年,出自 MSRA,级联结构,在其他 decode head 的输出结果上做了 Self-Attention,并在论文中从 Transformer 角度解释了 Self-Attention(Transformer 开始觉醒)
  • APCNet: 2019年,出自商汤,复杂网络结构 + 简化矩阵乘实现的 Attention
  • DMNet: 2019年,出自商汤,根据输入特征的全局信息动态生成卷积核,本质也是 Attention
  • LRASPP: 2019年,出自 Google,全局 scale 实现的 AttentionMobileNet V3
  • ISANet: 2019年,出自 MSAR,使用 feature map shuffle 实现长范围和短范围的稀疏注意力机制
  • DNLNet: 2020年,出自 MSAR,改进 Non-local,加入了归一化和一元分支
  • BiSeNet: 2019年,出自旷视,在 backbone 之外加入了一个 context branch,将特征提取和 attention 解耦,降低了 attention 恐怖的计算量
  • BiSeNet V2: 2020年,出自腾讯,BiSeNet 的改进
  • SDTC: 2021年,出自美团,BiSeNet 系列的改进版,但由于融合了两路分支到一处,不再 Bilateral,所以用特征提取 SDTC block 命名…

第三代:Transformer

  • SETR: 2020年,出自腾讯,Vitbackbone + FCN / FPN decode head
  • DPT: 2021年,出自 IntelSETR 的升级版,backbone 不变,decode headFPN 了一些
  • Segmenter: 2021年,出自法国 INRIA 研究所,用了纯 Transformer 架构而不是像 SETR / DPT 一样用 Transformer Encoder + CNN Decoder 架构
  • SegFormer: 2021年,出自 NVIDIASETR 的高效版
  • KNet: 2021年,出自商汤,decode head 融合了 Channel Attention + Multi-head Attention + RNN,统一了语义分割、实例分割、全景分割框架

Algorithms

1. FCN

1.1 原始特征处理

  • 原始特征处理使用了 resize concat 方式,将多个不同尺度(backbone 不同阶段)的 feature map resize concat 到输出尺寸,如下图所示:

FCN1.png

FCN2.png

实验证明越多尺度融合分割效果越好

1.2 特征解码

  • 特征解码只使用了几层普通 Conv + 可选择的 concat inputshortcut)结构

2. PSP

2.1 原始特征处理

  • PSPNet 的原始特征是 backbone 最后一层的输出,所以无需原始特征处理

2.2 特征解码

  • PSPNet 将输入特征通过 Pyramid Pooling Module 结构做了 feature map 不同尺度 down sample + up sample,如下图所示:

PSP.png

3. ASPP

3.1 原始特征处理

  • DeepLabV3 输入为单个单尺度 feature map,所以此步骤可省略

3.2 特征解码

ASPP.png

PSPNet 很像,PSPNet 是使用普通 Conv 去卷积多种尺度的 Pooled feature mapASPP 是不改变 feature map 而是使用 不同空洞系数的 Conv

4. FPN

FPN.png

5. UperNet

5.1 原始特征处理

  • 本算法在 decode head 中内嵌使用 FPN(而不是以网络 neck 方式使用),所以 feature map list 格式的原始特征无需处理,直接透传到特征解码部分

5.2 特征解码

UperNet.png

本文只讨论图中蓝色框部分

UperNet_2.png

只需要看蓝色框为输出的通路,算法:

  1. 在最小尺度 feature map 上使用 PPM(全称 Pyramid Pooling Module,来自于 PSPNet
  2. 使用 FPN 融合多尺度特征

6. DepthwiseSeparableASPP

DASPP.png

相较于 DeepLab V3 在 8 倍下采样的 feature map 上使用 ASPP,DeepLab V3+ 在更小尺度(16 倍下采样) feature map 上使用 DepthwiseSeparable ASPP
同时为了解决小尺度预测的问题,加入了一个 vanilla FPN 做不同尺度特征融合

7. DepthwiseSeparableFCN

FastSCNN.png

图中的 DWConv 是指 Depthwise Convic == oc == group
图中的 DSConv 是指 Depthwise Separable ConvDSConv 不是一个 Conv 而是 Depthwise ConvPointwise Convkernel_size == 1 and group == 1) 以及激活函数 / BN 一起组成的一个 block

8. PointRend

point.png

  • 渲染:渲染(render)是指在电脑中使用三维制作软件将制作的模型经过纹理、绑定、动画、灯光处理后得到模型和动画的图像。三维渲染是使用计算机从数字三维场景中生成二维影像的过程
  • 细分表面算法:细分表面算法(subdivision surface algorithm)在3D计算机图形中使用,通过递归完善基本级多边形网格来创建弯曲表面

point2.png

  • 本文的核心思想:
    • 将计算机图形学中的 Subdivision render 思想用于分割,使用 coarse-to-fine 思想,逐级细分,提高分割效果
    • 使用非均匀采样方法,越高频的区域使用越多的采样点,提高边缘分割效果

point3.png

point4.png

  • Inference 过程(以 FCN 作为 prev_decode_head 为例):

    • 输入:
      • backbone 的输出 xshape = [batch, channels, height, width]
      • FCN 的输出 prev_outputshape = [batch, num_cls, height, width]
    • 输出:refine 后的输出,shape = [batch, num_cls, 2 * subdivision_steps * height, 2 * subdivision_steps * width]
    1. prev_output copy 一份作为 refined_seg_logits
    2. refined_seg_logits 插值放大两倍,shape = [batch, num_cls, 2 * height, 2 * width]
    3. refined_seg_logits 上挑选最 hardN 个点(hard 的定义是:如果一个像素的 top1_cls_logitistop2_cls_logits 越接近,则该点越 hard),输出相对坐标,shape = [batch, N, 2]
    4. 根据选出的 N 个点的坐标在 x 中找到对应的点(需要插值找出),作为 fine_grained_point_featsshape = [batch, channels, N]
    5. 根据选出的 N 个点的坐标在 prev_output 中找到对应的点(需要插值找出),作为 coarse_point_featsshape = [batch, num_cls, N]
    6. fine_grained_point_featscoarse_point_feats concat 后经过 Subnetwork(几层 MLP)映射到类别空间 point_logitsshape = [batch, num_cls, N]
    7. 根据 3 中的 point index,将 6 输出的 point_logits 替换到 1 中的 refined_seg_logits 对应位置
    8. 重复 2 ~ 7 subdivision_steps 次,输出最终的 refined_seg_logitsshape = [batch, num_cls, 2 * subdivision_steps * height, 2 * subdivision_steps * width]
  • Train 过程:

    • 输入:
      • backbone 的输出 xshape = [batch, channels, height, width]
      • FCN 的输出 prev_outputshape = [batch, num_cls, height, width]
      • gt_semantic_segshape = [batch, num_cls, height, width]
    • 输出:loss
    • Train 过程与 Inference 过程基本相同,区别在于:
      • 由于 topk 运算对梯度反向传播不友好,所以在 Train 的过程中使用随机采样点的策略,没有挖掘 hard case
      • Train 不会引入多尺度,只会在同一尺度学习 subnetworkpoint 的分类

9. Non-Local

nl.png

用于 2 维图像,所以 T == 1,通过增加 (HW, HW) 的特征相关性矩阵给特征带来全局相关性(Attention

  • decode head 前后处理和 FCN 一致

10. PSANet

PSA.png

借鉴于 Non-local,强行给了比较牵强的数学解释,推理过程复杂到需要调用 CUDA 而不是使用 pure pytorch

11. CCNet

CC1.png

使用两个十字交叉注意力模块的串联替代 Non-local,降低算力

CC2.png

整体流程平平无奇

  • decode head 前后处理和 FCN 一致

12. DANet

DANet.png

DANet2.png

13. EncNet

EncNet.png

对于 SE-loss: 监督图中包含哪些类别的像素,使用交叉熵实现
对于 Encode:

  • 从本质上看:
    • 上图使用的 EncodeSENet (Squeeze and Excitation Network) 对 feature map per channel 编码没有区别
  • 从实现层面看:
    1. Encode 使用了更在数学上更好解释的编码方式(而不是 SENet 粗暴的 Global Average Pooling 编码方式)
    2. Encode 编码空间比 SENet 更大(SENet 每个通道使用 $\mathbb{R}$ 空间编码,Encode 每个通道使用 $\mathbb{R}^d$ 空间编码)

14. EMANet

EMA.png

15. ANN

ANN.png

key / value 上对特征进行了降维 N -> S,由下图可知,上图的 sample 方法具体是指 PPMPyramid Pooling Module

ANN2.png

AFNB 全称是 Asymmetric Fusion Non-local Block
APNB 全称是 Asymmetric Pyramid Non-local Block
二者对 Non-localSelf-Attention 进行简化,例如 share key value

16. GCNet

GC2.png

Non-local 结构的化简

GC.png

作者认为一个全局上下文建模结构如图 (a) 所示
图 (b) 为简化后的 Non-local 结构
图 (c) 是 SENet 结构
图 (d) 是本文提出的 GC 结构

  • decode head 前后处理和 FCN 一致

17. OCRNet

  • OCR 的全称是 Object Contextual Representations(目标上下文表征)而不是 Optical Character Recognition(光学字符识别),和前面的模型结构不同,OCRNet 是一种 Cascade Encoder Decoder 结构的 decode head ,该算法依赖于其他算法输出的分割结果,如下图所示(OCRNet 依赖于 FCN 的输出):

OCR.png

上图中粉红色的部分即为 OCRNet decode head

OCR2.png

论文中给出的算法架构图,给中间结果赋予了可解释的含义

18. APCNet

APC.png

19. DMNet

DMNet2.png

之前的网络结构都是通过空洞卷积或大卷积核实现多尺度
DMNet 通过输入特征的 Adaptive Pooling 生成动态卷积核实现多尺度

DMNet.png

20. LRASPP

LRASPP.png

21. ISANet

ISANet.png

  • 利用 feature map 重排实现长范围或短范围的稀疏注意力。

22. DNLNet

DNL.png

DNL 结构(图 d)在原始 Non-local 结构(图 a)上做了如下改动:

  1. 加入了一元 Non-local 分支 Unary Non-local
  2. 在二元分支矩阵乘之前加入了白化操作( H*W 维度减均值,相当于 instance norm

DNL2.png

由于减了均值,所以二元分支上 “+” 这一点在 Attention map $\in \mathbb{R}^{HW\times HW}$ 上的索引 heat map $\in \mathbb{R}^{H\times W}$ 变干净很多(相当只学习残差)
这张图也从侧面反映了 Non-local 还是很强的,Attention 不是在讲故事

23. BiSeNet

BiSenet2.png

  • backbone 主要分成两个分支 spatial pathcontext path,本质就是在基础 backbone 的基础上加入了一个计算量(通道数)非常小的 attention branch 增加上下文信息,最后融合两通道特征送入 decode head
  • decode head 就是基础的 FCN

24. BiSeNet V2

BiSenet_v2_1.png

BiSeNet 主要改进有:

  • context branch 上增加了更多更复杂的模块,可更好收集上下文信息
  • context branch 上增加了更多监督,每个尺度上都有监督损失
  • 分支融合模块设计的更加复杂

25. SDTC

SDTC.png

很新颖的 Loss 设计,效果和计算量都优于 BiSeNet 系列

SDTC2.png

这就是 SDTC 模块

26. SETR

SETR.png

  • 本质是 Vit(vision transformer)backboneFCN / 类似 FPNdecode head 的分割算法
  • 为了缩减计算量,Vit 会将原图剪成多个 patchworth 16x16 words...),每个 patch 单独输入到 24 层 Transformer Encoder 中,每个 patch 内部独立做全局 attention
  • patch 带来的问题是:与其他 CNN backbone + decode head 结构不同,Transformer backbone + decode head 结构中 decode head 需要顺序 inference 每个 patch feature(注意图a Decoder 输入为多个 patch feature),最后拼回到整张图大小
  • SETR_UPU decode head == sequence FCN
  • SETR_MLA decode head == sequence FPNAttention 不改变输入宽高,所以不存在严格意义上的 多尺度,只是不同网络深度的特征)

27. DPTNet

DPT.png

  • 本质和 SETR 一样都是使用 Vitbackbone
  • SETR 不同的地方在于:
    • 不同 backbone 深度特征融合方式更复杂,更接近 FPN
    • decode head 不再是输入 sequence patch feature,而是输入融合后的全图 feature

28. Segmenter

Segmenter.png

  • 用了纯 Transformer 架构(Transformer Encoder + Decoder),SETRDPT 都是 Transformer Encoder + CNN Decoder

29. SegFormer

SegFormer.png

  • backbone 不再是标准 Transformer Encoder(Vit),而是改成了更轻量化的 MixVisionTransformer(Mit)
    • Mit 使用了更大的 patchpatch 之间存在 overlap
    • Mit 使用了 coarse-to-fine 的特征表示,随着 Transformer Encoder 变深 feature map 宽高变小
    • Mit 使用了更简单的 Self-Attention 公式
    • Mit 去掉了 position embeding,使用了 Mix-FFN
  • decode head 使用了纯 MLP,且很自然的融合了多尺度(真.多尺度

30. KNet

KNet2.png

从框架上统一了三种分割方式

KNet.png

红字标出的是每个张量的 shape
绿字标出的是每个计算过程实际是在做什么
上述过程会像 RNN 一样循环多次去更新 kernel,使得结果更好(重复使用 backbone 的输出)