参考: https://zhuanlan.zhihu.com/p/618226513
0. 图像分割概述
图像分割通过给出图像中每个像素点的标签,将图像分割成若干带类别标签的区块,可以看作对每个像素进行分类。图像分割是图像处理的重要组成部分,也是难点之一。随着人工智能的发展,图像分割技术已经在交通控制、医疗影像和人脸识别等多个领域获得了广泛的应用。
图像分割是预测图像中每一个像素所属的类别或者物体。基于深度学习的图像分割算法主要分为三类:
语义分割
(semantic segmentation):可以理解为一个分类任务,对图片上每个像素进行分类
。经典网络:FCN
实例分割
(Instance segmentation): 相比于语义分割对每个像素进行分类,比如所有飞机位置都用同一个颜色表示。但在实例分割
任务中,分割的结果
会更加精细
些。针对同一个类别的不同目标,也有不同的颜色进行区分
。经典网络:Mask R-CNN
全景分割
(Panoramic segmentation): 全景分割可以认为是语义分割+实例分割
。其实在我们实例分割任务中,我们并不关注背景情况,比如背景中可能有蓝天,草地
,在我们实例分割任务中我们是不会关注这些的,只是关注每个目标的分割边界。而在全景分割任务中,我们不仅需要将每个目标给分割出来,还需要将背景进行划分
,比如背景中的蓝天、草地、马路等等。 经典网络:Panoptic FPN
语义分割,实例分割,全景分割这三个分割任务的精细程度是逐级递增
的。
1.框架选型
1.1 MMSegmentation
地址: https://github.com/open-mmlab/mmsegmentation
MMSegmentation利用注册器
和config(配置文件
),实现了两大优点:可拓展性和易用性
。dataset,pipeline(这里特指数据的预处理流程)和model在定义的过程中都使用了注册器类。若要添加新的类,只要在定义类的时候使用注册器类,就能自动将新实现的类添加到字典中,这个字典保存了已定义的模型、数据集等,字典的键为类名,值为对应的类。
用户可以只通过配置文件,来修改或添加数据集、预处理流程、网络模型和训练流程。
具体流程可参考:具体流程可参考:超详细!带你轻松掌握 MMSegmentation 整体构建流程
支持的模型
Results and models are available in the model zoo.
Supported backbones:
- ResNet (CVPR'2016)
- ResNeXt (CVPR'2017)
- HRNet (CVPR'2019)
- ResNeSt (ArXiv'2020)
- MobileNetV2 (CVPR'2018)
- MobileNetV3 (ICCV'2019)
- Vision Transformer (ICLR'2021)
- Swin Transformer (ICCV'2021)
- Twins (NeurIPS'2021)
- BEiT (ICLR'2022)
- ConvNeXt (CVPR'2022)
- MAE (CVPR'2022)
- PoolFormer (CVPR'2022)
- SegNeXt (NeurIPS'2022)
Supported methods:
- SAN (CVPR'2023)
- VPD (ICCV'2023)
- DDRNet (T-ITS'2022)
- PIDNet (ArXiv'2022)
- Mask2Former (CVPR'2022)
- MaskFormer (NeurIPS'2021)
- K-Net (NeurIPS'2021)
- SegFormer (NeurIPS'2021)
- Segmenter (ICCV'2021)
- DPT (ArXiv'2021)
- SETR (CVPR'2021)
- STDC (CVPR'2021)
- BiSeNetV2 (IJCV'2021)
- CGNet (TIP'2020)
- PointRend (CVPR'2020)
- DNLNet (ECCV'2020)
- OCRNet (ECCV'2020)
- ISANet (ArXiv'2019/IJCV'2021)
- Fast-SCNN (ArXiv'2019)
- FastFCN (ArXiv'2019)
- GCNet (ICCVW'2019/TPAMI'2020)
- ANN (ICCV'2019)
- EMANet (ICCV'2019)
- CCNet (ICCV'2019)
- DMNet (ICCV'2019)
- Semantic FPN (CVPR'2019)
- DANet (CVPR'2019)
- APCNet (CVPR'2019)
- NonLocal Net (CVPR'2018)
- EncNet (CVPR'2018)
- DeepLabV3+ (CVPR'2018)
- UPerNet (ECCV'2018)
- ICNet (ECCV'2018)
- PSANet (ECCV'2018)
- BiSeNetV1 (ECCV'2018)
- DeepLabV3 (ArXiv'2017)
- PSPNet (CVPR'2017)
- ERFNet (T-ITS'2017)
- UNet (MICCAI'2016/Nat. Methods'2019)
- FCN (CVPR'2015/TPAMI'2017)
1.2 SSSegmentation
地址:https://github.com/SegmentationBLWX/sssegmentation
SSSegmentation 是一个基于 PyTorch 的开源强监督语义分割工具箱。仓库地址:https://github.com/SegmentationBLWX/sssegmentation, 。它为各种语义分割方法提供了一个统一的基准工具箱
。将语义分割框架分解为不同的组件,通过组合不同的模块可以轻松构建个性的语义分割框架。一些比较流行的分割网络开箱即用,如 ISNet, DeepLabV3, PSPNet, MCIBI
等。
安装步骤
- (1) 克隆 sssegmentation 存储库
shell
git clone https://github.com/SegmentationBLWX/sssegmentation.git
cd sssegmentation
- (2) 安装依赖
shell
pip install -r requirements.txt
- (3) 安装 mmcv-full 的 pre-build 包
shell
pip install mmcv-full -f https://download.openmmlab.com/mmcv/dist/{cu_version}/{torch_version}/index.html
- (4) 安装对应版本的 torch 和 torchvision
shell
# CUDA 11.0
pip install torch==1.8.0+cu111 torchvision==0.9.0+cu111 torchaudio==0.8.0 -f https://download.pytorch.org/whl/torch_stable.html
# CUDA 10.2
pip install torch==1.8.0 torchvision==0.9.0 torchaudio==0.8.0
- (5) 构建一些 api,例如 coco 数据集的 api(如果不使用 coco,则无需此操作
shell
cd ssseg/libs
sh make.sh
1.3 飞桨图像分割套件PaddleSeg
飞桨的PaddleSeg图像分割套件如同一个工具箱一样,涵盖了高精度和轻量级等不同方向的大量高质量分割模型,并提供了多个损失函数和多种数据增强方法等高级功能,用户可以根据使用场景从PaddleSeg中选择出合适的图像分割方案,从而更快捷高效地完成图像分割应用。
PaddleSeg的主要特点包括4点:一是提供了50+的高质量预训练模型
。二是提供了模块化的设计,支持模型的深度调优
;三是高性能计算和显存优化
;四是同时支持配置化驱动和API调用两种应用方式,兼顾易用性和灵活性。
(1)PaddleSeg模块化设计
- 支持15+主流 分割网络 ,结合模块化设计的 数据增强策略 、骨干网络、损失函数 等不同组件,开发者可以基于实际应用场景出发,组装多样化的训练配置,满足不同性能和精度的要求。
- 提供了不同的损失函数,如Cross Entropy Loss、Dice Loss、BCE Loss等类型,通过选择合适的损失函数,可以强化小目标和不均衡样本场景下的分割精度。
(2)高性能
PaddleSeg支持多进程异步I/O、多卡并行训练、评估等加速策略,结合飞桨核心框架的显存优化功能,可大幅度减少分割模型的训练开销,让开发者更低成本、更高效地完成图像分割训练。
(3)易用灵活
PaddleSeg提供了配置化驱动和API调用两种应用方式,配置化驱动比较简单、容易上手,API调用支持更加灵活地开发。
1.4 TorchSeg
地址:https://github.com/ycszen/TorchSeg
该框架也使用 PyTorch 为语义分割模型提供快速、模块化的参考实现。相对于 SSSegmentation,有下面几点优势:
模块化设计:
通过组合不同的组件,轻松构建定制的语义分割模型。此外,支持更多的语义分割数据集。分布式训练:
比多线程并行方法 nn.DataParallel 快 60%,我们使用多进程并行方法。多 GPU 训练和推理:
支持不同的推理方式。
2. 模型选择
可以根据使用场景选择合适的模型:
如果是图像分割的初学者,则推荐使用U-Net、FCN模型。 如果希望以较快的速度完成训练和预测,则推荐使用
Fast-SCNN、BiSeNetv2
模型。 如果希望获得最高的精度,则推荐使用OCRNet、GSCNN
或DeepLabv3+模型。
(1) DeepLabv3+
DeepLabv3+是DeepLab系列的最后一篇文章,其前作有DeepLabv1、DeepLabv2和DeepLabv3。在最新作中,作者结合编码器-解码器(encoder-decoder)结构和空间金字塔池化模块(Spatial Pyramid Pooling, SPP)的优点提出新的语义分割网络DeepLabv3+,在 PASCAL VOC 2012和Cityscapes数据集上取得新的state-of-art performance. 其整体结构如下所示,Encoder的主体是带有空洞卷积(Atrous Convolution)的骨干网络,骨干网络可采用ResNet等常用的分类网络,作者使用了改进的Xception模型作为骨干网络。紧跟其后的空洞空间金字塔池化模块(Atrous Spatial Pyramid Pooling, ASPP)则引入了多尺度信息。相比前作DeepLabv3,DeepLabv3+加入decoder模块,将浅层特征和深层特征进一步融合,优化分割效果,尤其是目标边缘的效果。此外,作者将深度可分离卷积(Depthwise Separable Convolution)应用到ASPP和Decoder模块,提高了语义分割的健壮性和运行速率。
具体细节参考: 图像分割:DeepLabV3网络讲解
(2) U-Net
U-Net [1] 起源于医疗图像分割,具有参数少、计算快、应用性强的特点,对于一般场景适应度很高。U-Net最早于2015年提出,并在ISBI 2015 Cell Tracking Challenge取得了第一。经过发展,目前有多个变形和应用。 原始U-Net的结构是标准的编码器-解码器结构。如下图所示,左侧可视为一个编码器,右侧可视为一个解码器。编码器由四个子模块组成,每个子模块包含两个卷积层,每个子模块之后又通过max pool进行下采样。编码器整体呈现逐渐缩小的结构,不断减少池化层的空间维度,缩小特征图的分辨率,以捕获上下文信息。 解码器呈现与编码器对称的扩张结构,逐步修复分割对象的细节和空间维度,实现精准的定位。解码器同样也包含四个子模块,分辨率通过上采样操作依次增大,直到与输入图像的分辨率基本一致。 该网络还使用了跳跃连接,即解码器每上采样一次,就以拼接的方式将解码器和编码器中对应相同分辨率的特征图进行特征融合,帮助解码器更好地恢复目标的细节。由于网络整体结构类似于大写的英文字母U,故得名U-Net。
具体原理,参考:图像分割UNet (1) : 网络结构讲解
(3)PSPNet
论文地址:https://arxiv.org/pdf/1612.01105.pdf
基于语义分割的场景解析是计算机视觉中一个基础话题。自动驾驶、机器人感知等潜在应用领域都十分看重场景解析。场景解析的难度与场景和标签的多样性密切相关。 Pyramid Scene Parsing Network(PSPNet)起源于场景解析(Scene Parsing)领域。如图3所示,普通FCN面向复杂场景出现三种误分割现象:
- 关系不匹配。将船误分类成车,显然车一般不会出现在水面上。
- 类别混淆。摩天大厦和建筑物这两个类别相近,误将摩天大厦分类成建筑物。
- 类别不显著。枕头区域较小且纹理与床相近,误将枕头分类成床。
图2 普通FCN误分割现象
PSPNet的出发点是在算法中引入更多的上下文信息来解决上述问题。为了融合图像中不同区域的上下文信息,PSPNet使用了特殊设计的全局均值池化操作(Global Average Pooling)和特征融合构造金字塔池化模块 (Pyramid Pooling Module)。PSPNet最终获得了2016年ImageNet场景解析挑战赛的冠军,并在PASCAL VOC 2012和Cityscapes数据集上取得了当时的最佳效果。
(4)HRNet
现有的大多数方法都是从高分辨率到低分辨率网络(high-to-low resolution network)产生的低分辨率表征中恢复高分辨率表征。但是HRNet(HighResolution Net)能够在整个过程中保持高分辨率表示
。如图5所示,HRNet以高分辨率子网开始作为第一阶段,逐个添加高到低分辨率子网以形成更多阶段,并且并行连接多分辨率子网。在整个过程中反复交换并行多分辨率子网络中的信息来进行重复的多尺度融合。在像素级分类、区域级分类和图像级分类中,证明了这些方法的有效性。 HRNet具有两个特点:
- 从高分辨率到低分辨率并行连接各子网络。
- 反复交换跨分辨率子网络信息。
这两个特点使HRNet网络能够学习到更丰富的语义信息和细节信息。 HRNet在人体姿态估计、语义分割和目标检测领域都取得了显著的性能提升
。具体原理细节请参考论文:Deep High-Resolution Representation Learning for Visual Recognition。
(5) Fast-SCNN
Fast-SCNN 是一个面向实时的语义分割网络
。在双分支的结构基础上,大量使用了深度可分离卷积和逆残差(inverted-residual)模块
,并且使用特征融合构造金字塔池化模块 (Pyramid Pooling Module)来融合上下文信息。这使得Fast-SCNN在保持高效的情况下能学习到丰富的细节信息。Fast-SCNN最大的特点是"小快灵"
,即该模型在推理计算时仅需要较小的FLOPs,就可以快速推理出一个不错的结果
。
论文: Fast-SCNN: Fast Semantic Segmentation Network
整个网络结构如下:
(6)BiSeNetv2 (速度较快)
2020年,相关学者基于可实现实时语义分割的双向网络BiSeNe
t(Bilateral Segmentation Network),建设性地提出了BiSeNetv2,以期望获得更好的语义分割精度。通常来说,语义分割任务既需要低级细节,也需要高级语义。就目前的语义分割模型而言,于精度相比,更多的是追求速度,因此存在着一定缺陷。而BiSeNetv2则是两方兼顾且行之有效的语义分割模型。其整体结构如下所示:
在骨干网络部分,作者设计了两个分支------细节分支(Detail Branch)
和语义分支(Semantic Branch)
。细节分支用来捕捉低级细节,语义分支用来获取高级语义内容。为了让两个分支的互补作用更强,模型中加入了聚合层(Aggregation Layer
),用来融合两个分支的特征表示。同时,作者还引入了增强训练策略
(Booster Training Strategy),提高模型的语义分割效果。 与BiSeNet比较,它的架构更为清晰明了、简单易懂,同时,该模型的网络结构、组件设计也有了较大的提升,从而保障细节部分。总而言之,BiSeNetv2保证速度的同时,也能保证精度
。
具体原理细节请参考BiSeNet V2: Bilateral Network with Guided Aggregation forReal-time Semantic Segmentation。
(7)OCRNet
FCN(Fully Convolutional Network for Semantic Segmentation)可以对图像进行像素级的分类,解决了语义级别的图像分割问题,因此现有的大多数语义分割方法都基于FCN。但这些方法也有一定缺陷,比如分辨率低、上下文信息缺失和边界错误
等。2020年,相关学者为解决语义分割上下文信息缺失难题
,建设性地提出OCRNet,即基于物体上下文特征表示(Object Contextual Representation
,以下简称OCR
)的网络框架。其整体结构如下所示:
算法对比
实现此OCR方法需要经历三个阶段------首先形成软物体区域(Soft Object Regions),然后计算物体区域表示(Object Region Representations),最后得到物体上下文特征表示和上下文信息增强的特征表示(Augmented Representation)。 与其他语义分割方法相比,OCR方法更加高效准确。因为OCR方法解决的是物体区域分类问题,而非像素分类问题
,即OCR方法可以有效地、显式地增强物体信息。从性能和复杂度来说,OCRNet也更为优秀。2020年,"HRNet + OCR + SegFix"版本在2020ECCV Cityscapes 获得了第一名。
具体原理细节请参考Object-Contextual Representations for SemanticSegmentation。
(8) GSCNN
色彩、形状和纹理等低级语义信息并不相同,仅用单一网络融合处理,无法突出需要识别的内容,使得识别效果较差
。为解决该问题,相关学者提出了用于语义分割的双流CNN结构
(Gated Shape CNNs,以下简称GSCNN)。其整体结构如下所示:
GSCNN包含了两个流------常规流(Regular Stream
)和形状流(Shape Stream)
。常规流可以是任意的骨干网络结构。形状流通过一系列残差块(residual block)、门控卷积层(Gated Convolutional Layers,GCL)和边界信息监督,从而保留较多的边界信息。从图可知,双流并列进行,而后共同作为融合层的输入。融合模型(Fusion Module)通过ASPP(Atrous Spatial Pyramid Pooling)模块,融合双流信息。双任务正则化(Dual Task Regularizer)的应用,能够提升边界信息的精度,从而让图像分割更准确。 该网络结构的亮点是引入了"门"概念,控制两个流的交互,使得形状流过滤掉其他杂质,只处理和边界相关信息。GSCNN在Cityspaces数据集合上表现良好,mIoU指标和F-score指标十分亮眼
。与其他方法相比,GSCNN是高效的、用于语义分割的结构。
具体原理细节请参考Gated-SCNN: Gated Shape CNNs for Semantic Segmentation。
(10)U-Net++
论文: UNet++: A Nested U-Net Architecture for Medical Image Segmentation
网络结构
U-Net++ 在于把不同尺寸的 U-Net 结构融入到了一个网络里。我们知道,在运用 CNN 的分割问题上,主要分为以 FCN 为基础的结构,和以 U-Net 为基础的结构。前者的 encoder-decoder 是非对称的,后者的 encoder-decoder 是对称的;另外两者的特征融合方式也有些差别。但本质上分割网络都是差不多的:先 encoder 再decoder。那么到底 encoder 应该多大,decoder 应该多大呢?
相对于原来的 U-Net网络,Unet++ 把 1~4 层的 U-Net 全给链接在一起了。这个结构的好处就是让网络自己去学习不同深度的特征的重要性。第二个好处是它共享了一个特征提取器,也就是你不需要训练一堆 U-Net,而是只训练一个 encoder,它的不同层次的特征由不同的 decoder 路径来还原。这个 encoder 依旧可以灵活的用各种不同的 backbone 来代替。
Unet++ 主要改进就是将原来空心的 U-Net 填满了,优势是可以抓取不同层次的特征,将它们通过特征叠加的方式整合,不同层次的特征,或者说不同大小的感受野,对于大小不一的目标对象的敏感度是不同的,比如,感受野大的特征,可以很容易的识别出大物体的,但是在实际分割中,大物体边缘信息和小物体本身是很容易被深层网络一次次的降采样和一次次升采样给弄丢的,这个时候就可能需要感受野小的特征来帮助。
性能对比
(11) V-Net
论文: V-Net: Fully Convolutional Neural Networks for Volumetric Medical Image Segmentation
V-Net 有几个需要重点关注的地方, 基本上网络架构就是 3D conv+residual Block
版的 U-Net
,池化用卷积代替,转置卷积上采样
。V-Net 的论文中提出了一个新的指标函数,类似 IoU、Pa,叫做 Dice coefficient
。下图是 V-Net 的网络架构。进行卷积的目的是从数据中提取特征,并在每个阶段的最后通过使用适当的步幅降低其分辨率。网络的左侧部分由编码路径组成,而右侧部分对信号进行解码,直到达到其原始大小为止。卷积全部使用适当的 padding 操作。
(12) nn-Unet
一种鲁棒的基于 2D UNe t和 3D UNet 的自适应框架。这个框架和目前的 STOA 方法进行了比较,且该方法不需要手动调参,nnUNet 都得到了最高的平均 dice 值。通过简单的使用U-Net一种结构,一棒子打死了近年来所有的新的网络结构。认为网络结构上的改进并没有什么用,应该更多的关注结构以外的部分,比如预处理、训练和推理策略、后处理等部分。
(13) Trans-Unet
在语义分割上,FCN 这类卷积的编码器-解码器架构衍生出的模型在过去几年取得了实质性进展,但这类模型存在两个局限。第一,卷积仅能从邻域像素收集信息,缺乏提取明确全局依赖性特征的能力;第二,卷积核的大小和形状往往是固定的,因此它们不能灵活适应输入的图像或其他内容。相反,Transformer architecture 由于自注意力机制具有捕获全局依赖特征的能力,且允许网络根据输入内容动态收集相关特征。
Transformer 建立在多头自注意机制 (MHSA) 模块上,MHSA 是由多个 Self-Attention 组成的。下图是 Self-Attention 的结构,在计算的时候需要用到矩阵 Q(查询),K(键值),V(值)。在实际中,Self-Attention 接收的是输入(单词的表示向量 x 组成的矩阵 X) 或者上一个 Encoder block 的输出。而 Q,K,V 是通过 Self-Attention 的输入进行线性变换得到的。
得到矩阵 Q, K, V 之后就可以计算出 Self-Attention 的输出了,计算的公式如下。其中 d 是 Q,K 矩阵的列数(向量维度),公式中计算矩阵 Q 和 K 每一行向量的内积,为了防止内积过大,因此除以 d 的平方根。将 Q, K, V 展平并转置为大小为 n × d 的序列,其中 n = HW。P ∈ Rn×n 被命名为上下文聚合矩阵,用作权重以收集上下文信息。
通过这种方式,self-attention 本质上具有全局感受野,擅长捕捉全局依赖。此外,上下文聚合矩阵可以适应输入内容,以实现更好的特征聚合。关于更细节的内容,这里就不多介绍了。需要关注的是,n×d 矩阵的点乘会导致 O(n2d) 复杂度。通常,当特征图的分辨率很大时,n 远大于 d,因此序列长度 n 在自注意力计算中占主导地位,这使得高分辨率特征图中应用自注意力是不可行的,例如对于 16 × 16 特征图,n = 256,对于 128 × 128 特征图,n = 16384。
回到 TransUNet 本身,它同时具有 Transformers 和 U-Net 的优点,是医学图像分割的强大替代方案。一方面,Transformer 将来自卷积神经网络(CNN)特征图的标记化图像块编码为提取全局上下文的输入序列。另一方面,解码器对编码的特征进行上采样,然后将其与高分辨率的 CNN 特征图组合以实现精确的定位。借助 U-Net 的组合,通过恢复局部的空间信息,可以将 Transformers 用作医学图像分割任务的强大编码器。
3 常用 trick 介绍
(1)从 Loss 上解决数据集imbalance 的方法
比如小目标图像分割任务(医疗方向),往往一幅图像中只有一个或者两个目标,而且目标的像素比例比较小,使网络训练较为困难,一般可能有三种的解决方式:
- 选择合适 Loss function,对网络进行合理的优化,关注较小的目标。
- 改变网络结构,使用 attention 机制(类别判断作为辅助)。
- 与上面的根本原理一致,类属 attention,即:先检测目标区域,裁剪之后进行分割训练。
值得注意的是,通过使用设计合理的 Loss function,相比于另两种方式要更加简单易行,能够保留图像所有信息的情况下进行网络优化,达到对小目标精确分割的目的。
(2)上采样方法
上采样的技术是图像进行超分辨率的必要步骤,上采样大致被总结成了三个类别:
- 基于线性插值的上采样。
- 基于深度学习的上采样(转置卷积)。
- Unpooling 的方法。其实第三种只是做各种简单的补零或者扩充操作。
其中,线性插值用的比较多的主要有三种:·最近邻插值算法、双线性插值、双三次插值(BiCubic·),当然还有各种其改进型。如今S这些方法仍然广泛应用。这些方法各有优劣和劣势,主要在于处理效果和计算量的差别。计算效果上:·最近邻插值算法 < 双线性插值 < 双三次插值·,计算速度上:最近邻插值算法 > 双线性插值 > 双三次插值。
基于深度学习的上采样,有转置卷积、PixelShuffle(亚像素卷积,CVPR2016)、DUpsampling(亚像素卷积,CVPR2019)、Meta-Upscale(任意尺度缩放,CVPR2019)和 CAPAFE(内容关注与核重组,ICCV2019)等。
(3) 超参数调节
超参数调节不只是图像分割任务的重点,下面仅列出了几种需要重点关注的策略。
-
如何训练
- 观察训练趋势,metric 和 loss 的曲线。
- 根据任务和数据不同,loss 的值会有差别。
- 停止训练的标志:验证集上指标曲线达到高点且平稳。
- 使用多个而不是单一学习率
-
如何找到合适的学习率
- 周期性学习率。
- 用余弦函数来降低学习率。
- 带重启的 SGD 算法。