深度学习模型之图像分割(Image Segmentation)
深度学习模型之图像分割(Image Segmentation)
Image Segmentation.
Image Segmentation 是一种对图像中的每个像素进行分层处理的技术。
- 语义分割 (semantic segmentation) 强调了不同类别间的明确界限,并未对同类别内的不同成员进行细分;
- 实例分割 (instance segmentation) 不仅关注各类别本身的识别还要分辨同属于一个类别的各个独特实例;
- 全景分割 (panoptic segmentation) 对于可计数的对象实例(如行人、汽车)采用了具体分类的方式而对于不可计数的语义区域(如天空、地面)则执行整体划分。

语义分割模型可以直接基于图像像素实现分类处理过程,并将其转化为密集标签化的分类问题。在实例分割领域中通常分为两种主要类型:一种是自顶向下的方法(Top-Down),其中会首先对每个目标实例计算其检测框范围,在该区域内执行具体的切割操作;另一种是自底向上的策略(Bottom-Up),即先完成整体场景中的物体类别划分工作,在此基础上再识别出具体的对象区域并完成切割任务。对于全景分割技术而言,则是在已有实例切割体系的基础上构建了一个更为复杂的系统架构——其中不仅保留了传统的切割流程(包括语义信息提取与目标对象定位两个环节),并且可采用不同的像素分组策略来提升性能表现
本文目录:
- 图像分割的方法
- 基于图像的评估标准
- 用于图像分割的损失计算方法
- 常用的经典数据集
1. 图像分割模型
图像分割的主要目标是通过深度学习模型对输入图像进行处理,并获得具有语义标签且尺寸与输入相同的输出图像。

主要使用 encoder-decoder 结构。
该结构主要包括两个关键组件:编码器和解码器。
其中,编码器的作用是从预处理后的图像数据中提取出有用的特征。
而解码器则负责将这些特征转化为具体的分割热图结果。
可以说,
其发展趋向主要体现在以下几个方面:
其一,
该方法在计算效率方面表现出了显著的优势;
其二,
在分割精度上也实现了较大的提升;
此外,
还能够较好地平衡计算资源与性能之间的关系。
- 全卷积网络:FCN , SegNet , RefineNet , U-Net , V-Net , M-Net , W-Net , Y-Net , UNet++ , Attention U-Net , GRUU-Net , BiSeNet V1,2 , DFANet , SegNeXt
- 上下文模块:DeepLab v1,2,3,3+ , PSPNet , FPN , UPerNet , EncNet , PSANet , APCNet , DMNet , OCRNet , PointRend , K-Net
- 基于Transformer :SETR , TransUNet , SegFormer , Segmenter , MaskFormer , SAM
- 通用技巧:Deep Supervision , Self-Correction
(1) 基于全卷积网络的图像分割模型
传统的卷积神经网络架构通常包含三个主要组件:卷积层、下采样层和全连接层。早期基于深度学习的图像分割模型旨在生成与输入图像尺寸一致的分割结果,并通过放弃全连接层而引入了一系列上采样操作。鉴于此,在这一阶段的研究重点转向如何更好地从卷积下采样的信息损失中恢复丢失的数据,并逐步发展出以U-Net为代表的对称编码器-解码器架构模式。
⚪ FCN
**FCN** introduced a novel approach using convolutional neural networks(CNNs) to address the Semantic Segmentation Problem. Initially, the system employed CNNs to extract features and reduce spatial resolution, subsequently reconstructing higher-resolution mappings through bilinear interpolation.

⚪ SegNet
SegNet 设计了对称的编码器-解码器结构,通过反池化进行上采样。

⚪ RefineNet
RefineNet 把编码器产生的多个分辨率特征进行一系列卷积、融合、池化。

⚪ U-Net
该系统采用经典的U型架构设计,在关键的下采样与上采样环节增加跳跃连接的方式

⚪ V-Net
V-Net 是3D 版本的U-Net ,下采样使用步长为2的卷积。

⚪ M-Net
基于 U-Net 的架构上增添了一个 left 和一个 right 部分。\n其中, left 通过最大池化持续地进行下采样处理, 而 right 部分则负责将数据进行上采样处理, 并将其叠加到各个层级的输出结果中。

⚪ W-Net
The W-Net architecture stacks two U-Net models to achieve unsupervised image segmentation. The encoder extracts feature representations for segmentation, while the decoder reconstructs the original image from these features.

⚪ Y-Net
Y-Net 在 U-Net 编码位置后增添了一个概率图预测模块,在分割任务基础上补充了分类模块。

⚪ UNet++
UNet++ 通过跳跃连接融合了不同深度的U-Net ,并为每级U-Net 引入深度监督。

⚪ Attention U-Net
Attention U-Net 通过整合Attention gate组件到其跳跃连接和上采样流程中,在此过程中实现了空间注意力机制的有效融合。

⚪ GRUU-Net
GRUU-Net 基于循环神经网络架构设计了U型结构,在不同尺度特征的基础上进行了深入融合处理以实现图像分割效果的提升。

⚪ BiSeNet
BiSeNet 采用了创新性的双边结构设计方案,并将该系统分别以空间路径(Spatial Path)和上下文路径(Context Path)为基础构建网络架构。在这一过程中,通过一个特征融合模块(FFM),该系统能够有效整合并优化两个子网络的特征表示,并实现实时语义分割的效果。

⚪ BiSeNet V2
BiSeNet V2架构中采用了细节分支和语干分支的设计方案,在模型构建过程中采用了更为高效轻量级的深度可分离卷积模块以提升效率,并且在每个解码阶段都引入了聚合层来进行特征信息整合最后还增加了辅助损失函数以进一步优化训练效果

⚪ DFANet
该研究采用经过优化的Xception网络作为其核心组件,并设计了一种多分支的特征重用框架来整合多种分支结构中的细节信息与上下文关联。

⚪ SegNeXt
该编码模块基于ViT架构设计。其自注意机制借助多尺度卷积注意力(MSCA)得以实现。而解码层则采用了简洁型Hamberger模组进行特征融合。

(2) 基于上下文模块的图像分割模型
多尺度问题被称为图像处理中的一个挑战性现象。具体而言是指图像中同一目标在不同尺寸状态下分割效果欠佳的情况。例如在相近的距离下拍摄的物体呈现较大形态而在较远距离下则因视角变化显得较小甚至难以识别。而解决这一问题的核心在于使网络能够适应并精确分割不同尺寸的目标对象
随着图像分割技术的进步不断取得新的进展,在这一过程中主要矛盾逐步由单纯依赖像素信息向更加注重上下文(context)信息转变,并据此构建了一系列能够有效提取多尺度特征的网络架构
在该阶段的分割网络架构中主要包含以下几部分:首先通过预训练的ResNet模型从图像中提取出具有较高区分度的特征(通常采用8倍率进行下采样)。接着引入了经过精心设计的上下文融合模块来整合不同尺度的空间信息。最后通过对特征进行8倍率上采样处理以及配置合理的1×1卷积层实现目标区域的有效分割。
几种方法通过将自注意力机制应用于图像分割任务来提取特征,在视觉场景分析中利用其全局交互特性来捕捉长距离依赖关系,并构建相应的上下文模块。详细讨论可参考卷积神经网络中的自注意力机制相关内容。
⚪ Deeplab
Deeplab 采用了具有空洞结构的卷积操作来处理图像分割问题,并通过全连接条件随机场模型实现了对分割结果的进一步优化。

⚪ DeepLab v2
Deeplab v2 采用了空洞空间金字塔池化机制 ASPP ,即通过使用不同扩张率的空间空洞卷积构建其金字塔状特征图。

⚪ DeepLab v3
Deeplab v3 对ASPP 模块做了升级,把扩张率调整为[1, 6, 12, 18],并增加了全局平均池化:

⚪ DeepLab v3+
Deeplab v3+ 采用了编码器-解码器结构。

上述Deeplab 模型的对比如下:

⚪ PSPNet
PSPNet 采用了金字塔池化模块 PPM 。该模块通过并联不同尺寸的平均池化层来实现,并经由卷积操作后结合上采样技术将其恢复至原始尺寸。

⚪ FPN
该模型采用特征金字塔架构(Feature Pyramid Network, FPN),通过多级编码器提取的不同层级特征信息,并利用卷积操作提取并融合各层次的空间信息,并通过上采样模块将其还原至原始分辨率。该结构最终构建出具有语义理解能力的表征空间。

⚪ UPerNet
该系统以快速特征网络(FPN)和金字塔池化网络(PPM)为基础构建了多任务分割架构,在不同任务之间分别设置了特定的检测模块。通过这一架构实现场景类别识别、关键部位识别以及材质与纹理分析。

⚪ EncNet
EncNet 采用了上下文编码组件CEM ,通过结合字典学习机制和残差编码技术提取全局场景的上下文特征;随后通过采用语义编码损失SE-loss来增强网络在理解场景上下文方面的性能。

⚪ PSANet
基于PSANet架构设计了一种名为PSA 的逐像素空间注意力机制,并通过建立每个特征像素与其相关联的双向信息流动路径实现了各向异性关系的表达与传播

⚪ APCNet
自适应计算网络(APCNet)通过自适应上下文模块(ACM)为每个局部位置生成相应的上下文向量,并将这些向量与原始特征图进行加权融合以实现上下文信息的有效整合。

⚪ DMNet
DMNet 基于动态卷积模块DCM 来识别不同尺度的空间关系,在此过程中,每个DCM 模均能处理与输入尺寸成比例的变化

⚪ OCRNet
OCRNet 基于预测结果以及输出像素级别的特征提取类属信息,并通过衡量像素级与类属级特征之间的相似程度来构建空间语义关联性。其核心目标是以增强空间语义关联性的目的实现目标检测任务中的语义分割效果。

⚪ PointRend
PointRend能够从_co coarse prediction_中提取出_N_个关键难点;基于其详细的特征属性和_co coarse预测结果_构建_point feature vectors;利用_MLP_神经网络模型_对这些关键点进行二次优化预测。

⚪ K-Net
开发了一种可适应核机制用于图像分割任务。通过自适应核配置实现对不同分割类型的整合。详细说明中指出采用N个独立模块对图像进行分类处理。每组模块能够识别并标记出对应区域。同时引入更新头模块以优化每组的学习性能。

(3) 基于Transformer的图像分割模型
Transformer 利用自注意力机制作为其序列处理的基础架构,在任何层次都能够具备全局感受野的能力;而且在不需要过分下采样的情况下能够有效提取特征,并从而保留了图像中的丰富细节。
⚪ SETR
该模型采用了ViT用于提取图像特征的编码器;利用卷积模块实现的渐进展深上采样与多层次特征融合的方法生成分割结果。

⚪ TransUNet
其编码器部分主要由 ResNet50 和 Vision Transformer(ViT)构成,在设计上采用了层次分明的模块布局。具体而言,在头三模块均基于两倍下采样设计的 ResNet Block 构建,在最后一层则由 12 层 Transformer 子层构成。

⚪ SegFormer
SegFormer 体系主要包括多尺度特征信息的分层编码机制(其中包含了高效的自注意力机制、混合前馈网络结构以及重叠块嵌入技术三个关键组件)以及一种轻量化全MLP解码器结构。

⚪ Segmenter
该系统主要采用了Transformer编码器-解码器架构。作为这一架构的核心组件之一,图像块序列通过Transformer编码器进行编码,并经mask Transformer进行解码。为了提升分割精度,在此过程中我们引入了一组可学习的类别嵌入,并通过计算这些嵌入与解码序列特征之间的乘积来生成每个图像块的具体分割图。

⚪ MaskFormer
该方法将分割问题视为基于掩码级别的分类任务。该模型通过生成多个二值掩膜来实现目标检测,并针对每个掩膜预测其所属类别。

⚪ Segment Anything
SAM 被视为图像分割领域的核心组件,在这一过程中研究人员强调了其创新性与实用性。该方法基于提示设计完成了模型架构的构建过程。具体而言,SAM 的实现采用了模块化设计:首先由图像编码器提取图像特征向量;随后由提示编码器提取与分割相关的潜在表示;最后将这两种特征向量进行融合处理,并通过轻量化掩码解码模块精确推导出分割掩膜信息。

(4) 分割模型中的通用技巧
⚪ Deep Supervision
通过在这些隐藏层之后引入一个辅助分类器模块作为主干网络的一个分支来进行实时监控和优化训练过程的技术叫做 Deep Supervision技术。这种技术旨在通过实时监控和优化训练过程来解决深层神经架构在训练中出现的问题如梯度消失以及收敛速度缓慢等。
一种包含深度监督的八层卷积网络架构如上图所示。在经过Conv4 处理后,在其输出中引入了一个用于监督学习的分支分类器。此外,在后续计算过程中,除了将该特征传递至后续模块外,在这一阶段还直接馈送到该分支分类器进行训练

⚪ Self-Correction
- Reference :Self-Correction for Human Parsing
图像分割任务中的标签可能包含噪声。该算法是一种通过自校正方法净化分割标签噪声的技术。 模型训练基于包含噪声的标签进行训练,并融合当前模型与前一最佳模型的参数来推断更为可靠的标签。随后,通过修正这些推断出的高质量标注数据,并使用这些经过修正的标签来训练更加稳健的模型。
自适应调整机制主要包括模型融合和标签融合两个主要环节。在模型融合阶段,在当前迭代轮次的学习参数\hat{w}与上一轮次最优学习参数\hat{w}_{m-1}的基础上进行计算,并根据计算结果确定最终的融合权重;随后再将该融合权重应用于更新历史上的最优学习参数。
\hat{w}_m = \frac{m}{m+1}\hat{w}_{m-1} + \frac{1}{m+1}\hat{w}
标签更新遵循基于融合当前预测结果\hat{y}和前一轮标签\hat{y}_{m-1}的方法生成更加清晰地反映类别关系的新标签:
\hat{y}_m = \frac{m}{m+1}\hat{y}_{m-1} + \frac{1}{m+1}\hat{y}

⭐ 参考文献
- Fully Convolutional Networks for Semantic Segmentation:(arXiv1411)FCN: 语义分割的全卷积网络。
- Semantic Image Segmentation with Deep Convolutional Nets and Fully Connected CRFs:(arXiv1412)DeepLab: 通过深度卷积网络和全连接条件随机场实现图像语义分割。
- U-Net: Convolutional Networks for Biomedical Image Segmentation:(arXiv1505)U-Net: 用于医学图像分割的卷积网络。
- SegNet: A Deep Convolutional Encoder-Decoder Architecture for Image Segmentation:(arXiv1511)SegNet: 图像分割的深度卷积编码器-解码器结构。
- V-Net: Fully Convolutional Neural Networks for Volumetric Medical Image Segmentation:(arXiv1606)V-Net:用于三维医学图像分割的全卷积网络。
- DeepLab: Semantic Image Segmentation with Deep Convolutional Nets, Atrous Convolution, and Fully Connected CRFs:(arXiv1606)DeepLab v2: 通过带有空洞卷积的金字塔池化实现图像语义分割。
- RefineNet: Multi-Path Refinement Networks for High-Resolution Semantic Segmentation:(arXiv1611)RefineNet: 高分辨率语义分割的多路径优化网络。
- Pyramid Scene Parsing Network:(arXiv1612)PSPNet: 金字塔场景解析网络。
- M-Net: A Convolutional Neural Network for Deep Brain Structure Segmentation:(ISBI 2017)M-Net:用于三维脑结构分割的二维卷积神经网络。
- Rethinking Atrous Convolution for Semantic Image Segmentation:(arXiv1706)DeepLab v3: 重新评估图像语义分割中的扩张卷积。
- W-Net: A Deep Model for Fully Unsupervised Image Segmentation:(arXiv1711)W-Net:一种无监督的图像分割方法。
- Encoder-Decoder with Atrous Separable Convolution for Semantic Image Segmentation:(arXiv1802)DeepLab v3+: 图像语义分割中的扩张可分离卷积。
- Context Encoding for Semantic Segmentation:(arXiv1803)EncNet: 语义分割的上下文编码。
- Attention U-Net: Learning Where to Look for the Pancreas:(arXiv1804)Attention U-Net: 向U-Net引入注意力机制。
- Y-Net: Joint Segmentation and Classification for Diagnosis of Breast Biopsy Images:(arXiv1806)Y-Net:乳腺活检图像的分割和分类。
- UNet++: A Nested U-Net Architecture for Medical Image Segmentation:(arXiv1807)UNet++:用于医学图像分割的巢型UNet。
- Unified Perceptual Parsing for Scene Understanding:(arXiv1807)UPerNet: 场景理解的统一感知解析。
- BiSeNet: Bilateral Segmentation Network for Real-time Semantic Segmentation:(arXiv1808)BiSeNet: 实时语义分割的双边分割网络。
- PSANet: Point-wise Spatial Attention Network for Scene Parsing:(ECCV2018)PSANet: 场景解析的逐点空间注意力网络。
- GRUU-Net: Integrated convolutional and gated recurrent neural network for cell segmentation:(Medical Image Analysis2018)GRUU-Net: 细胞分割的融合卷积门控循环神经网络。
- Panoptic Feature Pyramid Networks:(arXiv1901)全景特征金字塔网络。
- DFANet: Deep Feature Aggregation for Real-Time Semantic Segmentation:(arXiv1904)DFANet: 实时语义分割的深度特征聚合。
- Object-Contextual Representations for Semantic Segmentation:(arXiv1909)OCRNet:语义分割中的目标上下文表示。
- PointRend: Image Segmentation as Rendering:(arXiv1912)PointRend: 把图像分割建模为渲染。
- Adaptive Pyramid Context Network for Semantic Segmentation:(CVPR2019)APCNet: 语义分割的自适应金字塔上下文网络。
- Dynamic Multi-Scale Filters for Semantic Segmentation:(ICCV2019)DMNet: 语义分割的动态多尺度滤波器。
- BiSeNet V2: Bilateral Network with Guided Aggregation for Real-time Semantic Segmentation:(arXiv2004)BiSeNet V2: 实时语义分割的带引导聚合的双边网络。
- Rethinking Semantic Segmentation from a Sequence-to-Sequence Perspective with Transformers:(arXiv2012)用Transformer从序列到序列的角度重新思考语义分割。
- TransUNet: Transformers Make Strong Encoders for Medical Image Segmentation:(arXiv2102)TransUNet:用Transformer为医学图像分割构造强力编码器。
- SegFormer: Simple and Efficient Design for Semantic Segmentation with Transformers:(arXiv2105)SegFormer:为语义分割设计的简单高效的Transformer模型。
- Segmenter: Transformer for Semantic Segmentation:(arXiv2105)Segmenter:为语义分割设计的视觉Transformer。
- K-Net: Towards Unified Image Segmentation:(arXiv2106)K-Net: 面向统一的图像分割。
- Per-Pixel Classification is Not All You Needfor Semantic Segmentation:(arXiv2107)MaskFormer:逐像素分类并不是语义分割所必需的。
- SegNeXt: Rethinking Convolutional Attention Design for Semantic Segmentation:(arXiv2209)SegNeXt:重新思考语义分割中的卷积注意力设计。
- Segment Anything:(arXiv2304)SAM:分割任意模型。
2. 图像分割的评估指标
可以说图像分割任务本质上属于图像像素级别的分类问题。通常采用一系列经典的分类评价指标来衡量模型性能。在实际应用中常用的一些关键指标
- Pixel Accuracy (PA): 衡量图像分类模型预测结果与真实标签之间的匹配程度。
- Class Pixel Accuracy (CPA): 衡量模型对特定类别的预测准确性。
- Class Mean Pixel Accuracy (MPA): 对所有类别的平均预测准确性进行评估。
- Intersection over Union, IoU: 衡量目标检测中预测区域与真实区域的重叠程度。
- Mean Intersection over Union, MIoU: 对所有目标实例计算IoU的均值表现。
- Frequency-Weighted Intersection over Union, FWIoU: 在IoU计算中加入类别频率信息以平衡不同类别的权重影响。
- Dice Coefficient (DC): 度量图像分割模型生成区域与真实区域的相似性程度。
上述评估指标均基于混淆矩阵 而存在,在此基础上介绍这些评估指标的计算过程
⚪ 混淆矩阵
图像分割问题本质上是对图像中的像素的分类问题。
(1) 二分类
以二分类任务为例,在图像中,每一个像素都有可能被归类为正例或者反例。通过分析像素的实际类别以及模型的预测结果,则可以将这些像素划分为四种类型中的一种:
真正例 TP:实际为正类的正确预测
* 假正例 FP:把反类预测为正类的情况
* 真反例 TN:真实为反类的正确判断
* 假反例 FN:将正类误判为反类的情况
绘制分类结果的混淆矩阵(confusion matrix) 如下:
根据混淆矩阵可做如下计算:
-
准确率(accuracy) ,定义为模型分类正确的像素比例:
-
查准率(precision) ,定义为模型预测为正例的所有像素中,真正为正例的像素比例:
-
查全率(recall) ,又称召回率 ,定义为所有真正为正例的像素中,模型预测为正例的像素比例:
-
F1分数(F1-Score) ,定义为查准率和召回率的调和平均数。
(2) 多分类
一般情况下是典型的multi-label classification问题,并且还有类似的结论。在处理multi-label classification问题时,请问您能否提供一些背景信息?
对于多分类问题,也可计算:
-
准确率 :
-
查准率 ,以类别1为例:
-
查全率 ,以类别1为例:
(3) 计算混淆矩阵
为了实现图像分割的预测结果与真实标签之间的对比分析,在深度学习框架中可以通过调用np.bincount函数来生成混淆矩阵的具体操作流程如下:
import numpy as np
def genConfusionMatrix(numClass, imgPredict, imgLabel):
'''
Parameters
----------
numClass : 类别数(不包括背景).
imgPredict : 预测图像.
imgLabel : 标签图像.
'''
# remove classes from unlabeled pixels in gt image and predict
mask = (imgLabel >= 0) & (imgLabel < numClass)
label = numClass * imgLabel[mask] + imgPredict[mask]
count = np.bincount(label, minlength=numClass**2)
confusionMatrix = count.reshape(numClass, numClass)
return confusionMatrix
imgPredict = np.array([[0,1,0],
[2,1,0],
[2,2,1]])
imgLabel = np.array([[0,2,0],
[2,1,0],
[0,2,1]])
print(genConfusionMatrix(3, imgPredict, imgLabel))
###
[[3 0 1]
[0 2 0]
[0 1 2]]
###
⚪ 像素准确率 PA
像素准确率 (pixel accuracy, PA) 评估了在所有类别中正确预测的像素数量相对于图像总像素数的比例,在分类任务中这等同于准确率(accuracy) 一种指标。
PA 计算为混淆矩阵对角线元素之和比矩阵所有元素之和,以二分类为例:
def pixelAccuracy(confusionMatrix):
# return all class overall pixel accuracy
# PA = acc = (TP + TN) / (TP + TN + FP + TN)
acc = np.diag(confusionMatrix).sum() / confusionMatrix.sum()
return acc
⚪ 类别像素准确率 CPA
类别的像素准确率(class pixel accuracy, CPA)度量所有预测标记为i的像素中真实属于类别i的像素相对于总像素数的比例,在分类任务中被称作查准率(precision)。
第i类别中的CPA值由混淆矩阵中对应位置的对角线元素与该行总和的比例确定。在二分类问题中,类别索引为0的CPA值计算公式如下所示:
def classPixelAccuracy(confusionMatrix):
# return each category pixel accuracy(A more accurate way to call it precision)
# acc = (TP) / TP + FP
classAcc = np.diag(confusionMatrix) / confusionMatrix.sum(axis=0)
return classAcc # 返回一个列表,表示各类别的预测准确率
⚪ 类别平均像素准确率 MPA
该算法实现了对测试集图像进行分类处理的能力评估,并且在验证集上达到了令人满意的分类准确率
该系统基于改进型卷积神经网络架构设计,并通过多层感知器进行特征提取与分类
该模型采用分步优化策略以降低计算复杂度的同时确保了分类性能的稳定提升
该算法通过引入自适应学习率调整机制实现了训练过程中的动态优化效果
该系统采用分布式架构以提高计算资源利用率并保证了系统的实时运行能力
def meanPixelAccuracy(confusionMatrix):
classAcc = classPixelAccuracy(confusionMatrix)
meanAcc = np.nanmean(classAcc) # np.nanmean表示遇到Nan类型,其值取为0
return meanAcc
⚪ 交并比 IoU
交并比(Intersection over Union, IoU)又被用来计算两个区域之间的重叠程度。
被分类标记为类别i的所有像素构成的集合被称为I_i。其中该列元素总和作为度量依据。实际标记属于类别Ii 的全部 pixels 被视为 ground truth pixels 集合 T_i$$ 用于评估分类性能。
第i类别的IoU定义为其对应的混淆矩阵主对角线元素除以其所在行及所在列的所有元素除积之商。在二分类情形下,则可具体表示为:对于类别索引为0的情形而言
def IntersectionOverUnion(confusionMatrix):
# Intersection = TP Union = TP + FP + FN
# IoU = TP / (TP + FP + FN)
intersection = np.diag(confusionMatrix)
union = np.sum(confusionMatrix, axis=1) + np.sum(confusionMatrix, axis=0) - np.diag(confusionMatrix)
IoU = intersection / union
return IoU # 返回列表,其值为各个类别的IoU
⚪ 平均交并比 MIoU
该指标(Mean Intersection over Union, MIoU)被定义为各类别IoU的均值
def meanIntersectionOverUnion(confusionMatrix):
IoU = IntersectionOverUnion(confusionMatrix)
mIoU = np.nanmean(IoU) # 求各类别IoU的平均
return mIoU
⚪ 频率加权交并比 FWIoU
频率加权交并比 (Frequency-based weighted Intersection-over-union, FWIoU) 以类别i中实际存在的像素占比作为权重对各分类结果进行加权计算。
对于每个类别i来说,在计算其对应的FWIoU值时首先要确定混淆矩阵中该类别对应行的所有元素之和与整个混淆矩阵所有元素之和的比例然后将其与该类别对应的IoU值相乘即可得到结果具体而言在二分类问题中类别0的FWIoU值可以通过以下公式进行计算:
最终给出的FWIoU 应为所有类别FWIoU 的求和。
def Frequency_Weighted_Intersection_over_Union(confusion_matrix):
# FWIOU = [(TP+FN)/(TP+FP+TN+FN)] *[TP / (TP + FP + FN)]
freq = np.sum(confusion_matrix, axis=1) / np.sum(confusion_matrix)
iu = np.diag(confusion_matrix) / (
np.sum(confusion_matrix, axis=1) +
np.sum(confusion_matrix, axis=0) -
np.diag(confusion_matrix))
FWIoU = (freq[freq > 0] * iu[freq > 0]).sum()
return FWIoU
⚪ Dice Coefficient
该指标用于度量图像中预测区域A与实际区域B在像素级别的重叠情况。
在分类模型中,标记为类标号为j=1,2,\dots,C的所有输入样本构成了一个大小等于各类样本数量的一维向量\mathbf{S}_j^{(train)}=\{\mathbf{x}_i|\hat{y}_i=j\}。其中\mathbf{x}_i\in\mathbb{R}^n是第j=1,2,\dots,C个类别的特征向量集;\hat{y}_i=j\in Y=\{1,2,\dots,C\}是模型对输入样本x_i^{(train)}\in X^{(train)}=\{x_1^{(train)},x_2^{(train)},\dots,x_{N_t}^{(train)}\}的学习结果;而\mathbb{R}^n\times Y^n\times Y^m\times X^m_{mn}\times X^n_{nn}\times X^n_{nn}\times X^n_{nn}则是数据集空间。
Dice Coefficient 被定义为其分子和分母分别加入两个集合的交集区域后的结果。
第i个类别的Dice值表示为混淆矩阵中对应对角线元素的两倍除以该列元素与该行元素的总和。例如,在二分类场景中,类别索引为0的情况其Dice值计算公式如下所示:
因此Dice 系数等价于分类指标中的F1-Score 。
def Dice(confusionMatrix):
# Dice = 2*TP / (TP + FP + TP + FN)
intersection = np.diag(confusionMatrix)
Dice = 2*intersection / (
np.sum(confusionMatrix, axis=1) + np.sum(confusionMatrix, axis=0))
return Dice # 返回列表,其值为各个类别的Dice
在该特定场景中(针对二元分割问题),Dice系数能够直接地基于预测矩阵和标签矩阵进行计算
def dice_coef(pred, target):
"""
Dice = 2*sum(|A*B|)/(sum(A^2)+sum(B^2))
"""
smooth = 1.
m1 = pred.view(-1).float()
m2 = target.view(-1).float()
intersection = (m1 * m2).sum().float()
dice = (2. * intersection + smooth) / (torch.sum(m1*m1) + torch.sum(m2*m2) + smooth)
return dice
3. 图像分割的损失函数
在本节中, 我们参考了论文 Loss odyssey in medical image segmentation 和 GitHub库 SegLoss: A collection of loss functions for medical image segmentation.
图像分割的损失函数旨在度量预测分割与真实标注之间的差异程度。一个合理的损失函数不仅被用来指导网络在特定评估指标下模仿真实标注的趋势特征,并且能够平衡误判情况(包括假阳性率和假阴性率)。
基于损失函数的不同推导路径,图像分割任务中使用的常见损失函数可被归类为:
- 基于概率分布的损失:包括交叉熵(Cross-Entropy)、加权交叉熵(Weighted Cross-Entropy)、Top-K熵(TopK)、焦点散度(Focal Entropy)以及距离图惩罚性交叉熵(Distance Map Penalized CE)。
- 基于分割区域的损失:涉及敏感性与特异性差异数值化(Sensitivity-Specifity Difference Numericalization)、交并比度量(IoU)、Lovász散度、Dice系数、Tversky指标及其变体、不均衡渐近相似性测量(Asymmetric Similarity Measure)以及广义Dice散度。
- 基于边界检测的损失:涵盖边界检测相关技术如边界散度与Hausdorff距离度量(Hausdorff Distance)。
在实际应用中,人们往往会将上述损失函数进行结合运用的方式进行操作;例如采用Cross-Entropy Loss + Dice Loss 的组合形式来进行训练模型参数的优化过程

(1) 基于分布的损失 Distribution-based Loss
基于分布的损失函数旨在最小化两种分布之间的差异。
⚪ Cross-Entropy Loss
交叉熵损失是由KL 散度导出的,衡量数据分布P和预测分布Q之间的差异:
观察到数据分布\text{P}通常是可获得的\text{.}因此\text{,}在分割任务中\text{,}通过最小化数据分布\text{P}与预测分布\text{Q}之间的KL散度相当于最小化交叉熵损失\text{H(P, Q)}\text{.}对于分割任务而言\text{,}在像素i属于标签c\text{的情况下(即二元指示符}g_i^c = 1\text{)\text{,}其对应的预测结果s_i^c = 1\text{;}$否则(即二元指示符}g_i^c = 0\text{)$\text{,}$其对应的预测结果$s_i^c = 0\text{.}基于这些定义\text{,}$在分割任务中交叉熵损失被定义为:
ce_loss = torch.nn.CrossEntropyLoss()
# result无需经过Softmax,gt为整型
loss = ce_loss(result, gt)
⚪ Weighted Cross-Entropy Loss
为了应对分类数据中的类别不平衡问题,在模型训练中采用了加权交叉熵损失函数来解决这一挑战。该损失函数通过赋予每个类别一个权重w_c来进行调整。具体而言,在训练数据集中通常是根据类别的出现频率来确定这些权重值的设置方式。
wce_loss = torch.nn.CrossEntropyLoss(weight=weight)
loss = wce_loss(result, gt)
⚪ TopK Loss
TopK 损失主要通过引导网络在训练过程中更加关注具有挑战性的样本(hard samples )。当计算交叉熵损失时,在所有分类像素中选择训练集中损失最高的前k%分类像素进行处理。
class TopKLoss(nn.Module):
def __init__(self, weight=None, ignore_index=-100, k=10):
super(TopKLoss, self).__init__()
self.k = k
self.ce_loss = torch.nn.CrossEntropyLoss(reduce=False)
def forward(self, result, gt):
res = self.ce_loss(result, gt)
num_pixels = np.prod(res.shape)
res, _ = torch.topk(res.view((-1, )), int(num_pixels * self.k / 100), sorted=False)
return res.mean()
⚪ Focal Loss
Focal Loss 借助于缩减那些易于被正确分类的像素点所对应的损失权重这一机制, 旨在解决前景与背景类别间的失衡问题.
from einops import rearrange
class FocalLoss(nn.Module):
def __init__(self, gamma=2):
super(FocalLoss, self).__init__()
self.gamma = gamma
def forward(self, result, gt):
result = rearrange(result, 'b c h w -> b c (h w)')
result = torch.softmax(result, dim=1)
gt = rearrange(gt, 'b h w -> b 1 (h w)')
y_onehot = torch.zeros_like(result)
y_onehot = y_onehot.scatter_(1, gt.data, 1)
pt = (y_onehot * result).sum(1)
logpt = pt.log()
gamma = self.gamma
loss = -1 * torch.pow((1 - pt), gamma) * logpt
return loss.mean()
⚪ Distance Map Penalized CE Loss
基于真实标签生成的距离图加权交叉熵损失函数能够有效引导网络关注图像中的复杂边界区域。
其中D^c被视为类别c的距离惩罚因子,在计算过程中采用真实标签对应距离变换图的倒数值作为基础变量。这种设计使得在边界区域的像素点上能够获得相对较高的权重系数。
from einops import rearrange
from scipy.ndimage import distance_transform_edt
class DisPenalizedCE(torch.nn.Module):
def __init__(self):
super(DisPenalizedCE, self).__init__()
@torch.no_grad()
def one_hot2dist(self, seg):
res = np.zeros_like(seg)
for c in range(seg.shape[1]):
posmask = seg[:,c,...]
if posmask.any():
negmask = 1.-posmask
pos_edt = distance_transform_edt(posmask)
pos_edt = (np.max(pos_edt)-pos_edt)*posmask
neg_edt = distance_transform_edt(negmask)
neg_edt = (np.max(neg_edt)-neg_edt)*negmask
res[:,c,...] = pos_edt + neg_edt
return res
def forward(self, result, gt):
result = torch.softmax(result, dim=1)
gt = rearrange(gt, 'b h w -> b 1 h w')
y_onehot = torch.zeros_like(result)
y_onehot = y_onehot.scatter_(1, gt.data, 1)
dist = torch.from_numpy(self.one_hot2dist(y_onehot.cpu().numpy())+1).float()
result = torch.softmax(result, dim=1)
result_logs = torch.log(result)
loss = -result_logs * y_onehot
weighted_loss = loss*dist
return weighted_loss.mean()
(2) 基于区域的损失 Region-based Loss
基于区域定义的损失函数旨在减少真实标签与预测分割之间差异的程度,并通过提升两者的重叠面积来优化性能。
⚪ Sensitivity-Specifity Loss
敏感性-特异性损失通过加权敏感性与特异性来解决类别不平衡问题:
from einops import rearrange, einsum
class SSLoss(nn.Module):
def __init__(self, smooth=1.):
super(SSLoss, self).__init__()
self.smooth = smooth
self.r = 0.1 # weight parameter in SS paper
def forward(self, result, gt):
result = rearrange(result, 'b c h w -> b c (h w)')
result = torch.softmax(result, dim=1)
gt = rearrange(gt, 'b h w -> b 1 (h w)')
y_onehot = torch.zeros_like(result)
y_onehot = y_onehot.scatter_(1, gt.data, 1)
# no object value
bg_onehot = 1 - y_onehot
squared_error = (y_onehot - result)**2
specificity_numerator = einsum(squared_error, y_onehot, 'b c n, b c n -> b c')
specificity_denominator = einsum(y_onehot, 'b c n -> b c')+self.smooth
specificity_part = einsum(specificity_numerator, 'b c -> b')/einsum(specificity_denominator, 'b c -> b')
sensitivity_numerator = einsum(squared_error, bg_onehot, 'b c n, b c n -> b c')
sensitivity_denominator = einsum(bg_onehot, 'b c n -> b c')+self.smooth
sensitivity_part = einsum(sensitivity_numerator, 'b c -> b')/einsum(sensitivity_denominator, 'b c -> b')
ss = self.r * specificity_part + (1-self.r) * sensitivity_part
return ss.mean()
⚪ IoU Loss
IoU Loss 直接提升 IoU index 。基于这一前提下,预测热图和真实标签均可表示为 [0,1] 矩阵;从而,在这一前提下,集合运算可以直接通过对应元素进行计算:
from einops import rearrange, einsum
class IoULoss(nn.Module):
def __init__(self, smooth=1e-5):
super(IoULoss, self).__init__()
self.smooth = smooth
def forward(self, result, gt):
result = rearrange(result, 'b c h w -> b c (h w)')
result = torch.softmax(result, dim=1)
gt = rearrange(gt, 'b h w -> b 1 (h w)')
y_onehot = torch.zeros_like(result)
y_onehot = y_onehot.scatter_(1, gt.data, 1)
intersection = einsum(result, y_onehot, "b c n, b c n -> b c")
union = einsum(result, "b c n -> b c") + einsum(y_onehot, "b c n -> b c") - einsum(result, y_onehot, "b c n, b c n -> b c")
divided = 1 - (einsum(intersection, "b c -> b") + self.smooth) / (einsum(union, "b c -> b") + self.smooth)
return divided.mean()
⚪ Lovász Loss
Lovász Loss 通过 Lovász 扩张使图像分割中的 IoU Loss 平滑化。
首先定义类别c的误分类像素集合M_c:
\mathbf{M}_c\left(\boldsymbol{y}^_, \tilde{\boldsymbol{y}}\right)=\left{\boldsymbol{y}^_ =c, \tilde{\boldsymbol{y}} \neq c\right} \cup\left{\boldsymbol{y}^* \neq c, \tilde{\boldsymbol{y}}=c\right}
则IoU Loss 可以写成集合M_c的函数:
定义类别c的像素误差向量m(c) \in [0,1]^N:
则按照定义可知,则\Delta_{J_c}(\mathbf{M}_c)的Lovász延拓\overline{\Delta_{J_c}}(m(c))
其中,\pi是m中元素的一个按递减顺序排列:m_{\pi_1} \geq m_{\pi_2} \geq \cdots \geq m_{\pi_N}。
from einops import rearrange
def lovasz_grad(gt_sorted):
"""
Computes gradient of the Lovasz extension w.r.t sorted errors
"""
n = len(gt_sorted)
gts = gt_sorted.sum()
intersection = gts - gt_sorted.float().cumsum(0)
union = gts + (1 - gt_sorted).float().cumsum(0)
jaccard = 1. - intersection / union
if n > 1: # cover 1-pixel case
jaccard[1:n] = jaccard[1:n] - jaccard[0:-1]
return jaccard
class LovaszLoss(nn.Module):
def __init__(self):
super(LovaszLoss, self).__init__()
def lovasz_softmax_flat(self, inputs, targets):
num_classes = inputs.size(1)
losses = []
for c in range(num_classes):
target_c = (targets == c).float()
input_c = inputs[:, c]
loss_c = (target_c - input_c).abs()
loss_c_sorted, loss_index = torch.sort(loss_c, 0, descending=True)
target_c_sorted = target_c[loss_index]
losses.append(torch.dot(loss_c_sorted, lovasz_grad(target_c_sorted)))
losses = torch.stack(losses)
return losses.mean()
def forward(self, inputs, targets):
# inputs.shape = (batch size, class_num, h, w)
# targets.shape = (batch size, h, w)
inputs = rearrange(inputs, 'b c h w -> (b h w) c')
targets = targets.view(-1)
losses = self.lovasz_softmax_flat(inputs, targets)
return losses
⚪ Dice Loss
Dice Loss 具有相似性质于 IoU loss ,其主要致力于优化 Dice Coefficient 。值得注意的是,在这一框架下所处理的对象均为二维或三维空间中的区域划分问题;因此,在这种情况下预测热图以及真实标签均可表示为[0,1]矩阵;基于此基础之上,则可将集合运算简化为对应元素的操作。
from einops import rearrange, einsum
class DiceLoss(nn.Module):
def __init__(self, smooth=1e-5):
super(DiceLoss, self).__init__()
self.smooth = smooth
def forward(self, result, gt):
result = rearrange(result, 'b c h w -> b c (h w)')
result = torch.softmax(result, dim=1)
gt = rearrange(gt, 'b h w -> b 1 (h w)')
y_onehot = torch.zeros_like(result)
y_onehot = y_onehot.scatter_(1, gt.data, 1)
intersection = einsum(result, y_onehot, "b c n, b c n -> b c")
union = einsum(result, "b c n -> b c") + einsum(y_onehot, "b c n -> b c")
divided = 1 - 2 * (einsum(intersection, "b c -> b") + self.smooth) / (einsum(union, "b c -> b") + self.smooth)
return divided.mean()
⚪ Tversky Loss
Dice Loss 可以被定义为其查准率与召回率的harmonic mean,并赋予false positive and false negative sample equal weighting. Tversky Weighting通过修改Dice Loss分母中的false positive and false negative sample weight allocation, 实现了precision与recall之间的balance.
from einops import rearrange, einsum
class TverskyLoss(nn.Module):
def __init__(self, smooth=1.):
super(TverskyLoss, self).__init__()
self.smooth = smooth
self.alpha = 0.3
self.beta = 0.7
def forward(self, result, gt):
result = rearrange(result, 'b c h w -> b c (h w)')
result = torch.softmax(result, dim=1)
gt = rearrange(gt, 'b h w -> b 1 (h w)')
y_onehot = torch.zeros_like(result)
y_onehot = y_onehot.scatter_(1, gt.data, 1)
intersection = einsum(result, y_onehot, "b c n, b c n -> b c")
FP = einsum(result, 1-y_onehot, "b c n, b c n -> b c")
FN = einsum(1-result, y_onehot, "b c n, b c n -> b c")
denominator = intersection + self.alpha * FP + self.beta * FN
divided = 1 - einsum(intersection, "b c -> b") / einsum(denominator, "b c -> b").clamp(min=self.smooth)
return divided.mean()
⚪ Focal Tversky Loss
该损失函数通过将Focal Loss融合到Tversky Loss中实现对难以分类样本像素的更加强调。
⚪ Asymmetric Similarity Loss
与与 **Asymmetric Similarity Loss 和 Tversky Loss 一样, 它们的动机相似, 都旨在调节误报和误漏样本的比例, 以实现查准率与召回率之间的平衡. 这相当于将 Tversky Loss 中的参数设置为 α + β = 1.
from einops import rearrange, einsum
class AsymLoss(nn.Module):
def __init__(self, smooth=1.):
super(AsymLoss, self).__init__()
self.smooth = smooth
self.beta = 1.5
def forward(self, result, gt):
result = rearrange(result, 'b c h w -> b c (h w)')
result = torch.softmax(result, dim=1)
gt = rearrange(gt, 'b h w -> b 1 (h w)')
y_onehot = torch.zeros_like(result)
y_onehot = y_onehot.scatter_(1, gt.data, 1)
weight = (self.beta**2)/(1+self.beta**2)
intersection = einsum(result, y_onehot, "b c n, b c n -> b c")
FP = einsum(result, 1-y_onehot, "b c n, b c n -> b c")
FN = einsum(1-result, y_onehot, "b c n, b c n -> b c")
denominator = intersection + weight * FP + (1-weight) * FN
divided = 1 - einsum(intersection, "b c -> b") / einsum(denominator, "b c -> b").clamp(min=self.smooth)
return divided.mean()
⚪ Generalized Dice Loss
在多标签分类场景下,Generalized Dice Loss被视为Dice Loss的扩展形式,在此过程中,每个类别c的权重与其对应的标签频率的平方根成反比:w_c=1/(\sum_{i=1}^Ng_i^c)^2.
from einops import rearrange, einsum
class GDiceLoss(nn.Module):
def __init__(self, smooth=1e-5):
super(GDiceLoss, self).__init__()
self.smooth = smooth
def forward(self, result, gt):
result = rearrange(result, 'b c h w -> b c (h w)')
result = torch.softmax(result, dim=1)
gt = rearrange(gt, 'b h w -> b 1 (h w)')
y_onehot = torch.zeros_like(result)
y_onehot = y_onehot.scatter_(1, gt.data, 1)
w = 1 / (einsum(y_onehot, "b c n -> b c") + 1e-10)**2
intersection = einsum(result, y_onehot, "b c n, b c n -> b c")
union = einsum(result, "b c n -> b c") + einsum(y_onehot, "b c n -> b c")
divided = 1 - 2 * (einsum(intersection, w, "b c, b c -> b") + self.smooth) / (einsum(union, w, "b c, b c -> b") + self.smooth)
return divided.mean()
⚪ Penalty Loss
Penalty Loss 将 Tversky Loss 中的这一概念应用于 Generalized Dice Loss 中。
from einops import rearrange, einsum
class PenaltyLoss(nn.Module):
def __init__(self, smooth=1e-5):
super(PenaltyLoss, self).__init__()
self.smooth = smooth
self.k = 2.5
def forward(self, result, gt):
result = rearrange(result, 'b c h w -> b c (h w)')
result = torch.softmax(result, dim=1)
gt = rearrange(gt, 'b h w -> b 1 (h w)')
y_onehot = torch.zeros_like(result)
y_onehot = y_onehot.scatter_(1, gt.data, 1)
w = 1 / (einsum(y_onehot, "b c n -> b c") + 1e-10)**2
intersection = einsum(result, y_onehot, "b c n, b c n -> b c")
union = einsum(result+y_onehot, "b c n -> b c")
FP = einsum(result, 1-y_onehot, "b c n, b c n -> b c")
FN = einsum(1-result, y_onehot, "b c n, b c n -> b c")
denominator = einsum(union, w, "b c, b c -> b") + self.k * einsum(FP, w, "b c, b c -> b") + self.k * einsum(FN, w, "b c, b c -> b")
divided = 1 - 2 * einsum(intersection, w, "b c, b c -> b") / denominator.clamp(min=self.smooth)
return divided.mean()
(3) 基于边界的损失 Boundary-based Loss
基于边界的损失被称为一种以目标物体轮廓为基础的距离度量形式定义的损失函数,在评估时它衡量真实标签与预测分割结果中目标边界之间的差异程度。
有两种不同的方法用于计算两个边界之间的距离。其中一种是基于微分的方法,在这种分析方法中,在每一点沿着边界曲线垂直方向上测量速度变化率的变化率以评估各点处的运动状况。另一种则是基于积分的方法,在这种情况下通过对两组边界中不匹配区域进行积分运算以估算整体差异程度。
当进行神经网络训练时
⚪ Boundary Loss
在Boundary Loss框架中,每个采样点q经过softmax操作后得到输出s_{\theta}(q),该输出值被权重函数\phi_G: \Omega \rightarrow \mathbb{R}所加权。其中\phi_G(q)表示基于真实标签边界的水平集函数:当采样点q位于类别区域时(即q \in G),则\phi_G(q) = -D_G(q);反之,则\phi_G(q) = D_G(q)。此外,在这种情况下,距离函数d_D: \Omega \rightarrow \mathbb{R}^+被定义为相对于边界\partial G的距离变换图对应于其位置关系(如图X所示)。
\mathcal{L}_B(\theta) = \int_{\Omega} \phi_G(q) s_{\theta}(q) d q
from einops import rearrange, einsum
from scipy.ndimage import distance_transform_edt
class BDLoss(nn.Module):
def __init__(self):
super(BDLoss, self).__init__()
@torch.no_grad()
def one_hot2dist(self, seg):
res = np.zeros_like(seg)
for c in range(seg.shape[1]):
posmask = seg[:,c,...]
if posmask.any():
negmask = 1.-posmask
neg_map = distance_transform_edt(negmask)
pos_map = distance_transform_edt(posmask)
res[:,c,...] = neg_map * negmask - (pos_map - 1) * posmask
return res
def forward(self, result, gt):
result = torch.softmax(result, dim=1)
gt = rearrange(gt, 'b h w -> b 1 h w')
y_onehot = torch.zeros_like(result)
y_onehot = y_onehot.scatter_(1, gt.data, 1)
bound = torch.from_numpy(self.one_hot2dist(y_onehot.cpu().numpy())).float()
# only compute the loss of foreground
pc = result[:, 1:, ...]
dc = bound[:, 1:, ...]
multipled = pc * dc
return multipled.mean()
⚪ Hausdorff Distance Loss
豪斯多夫损失借助于[distance transform graph]进行估算和提升以优化真实标签与预测分割之间的 Hausdorff 距离
其中d_G, d_S分别对应于真实标注和预测分割后的距离变换结果,在此基础上进行计算以确定每个像素与目标边界的最短距离。
from einops import rearrange
from scipy.ndimage import distance_transform_edt
class HausdorffDTLoss(nn.Module):
"""Binary Hausdorff loss based on distance transform"""
def __init__(self, alpha=2.0):
super(HausdorffDTLoss, self).__init__()
self.alpha = alpha
@torch.no_grad()
def one_hot2dist(self, seg):
res = np.zeros_like(seg)
for c in range(seg.shape[1]):
posmask = seg[:,c,...]
if posmask.any():
negmask = 1.-posmask
pos_edt = distance_transform_edt(posmask)
neg_edt = distance_transform_edt(negmask)
res[:,c,...] = pos_edt + neg_edt
return res
def forward(self, result, gt):
result = torch.softmax(result, dim=1)
gt = rearrange(gt, 'b h w -> b 1 h w')
y_onehot = torch.zeros_like(result)
y_onehot = y_onehot.scatter_(1, gt.data, 1)
pred_dt = torch.from_numpy(self.one_hot2dist(result.cpu().numpy())).float()
target_dt = torch.from_numpy(self.one_hot2dist(y_onehot.cpu().numpy())).float()
pred_error = (result - y_onehot) *
distance = pred_dt ** self.alpha + target_dt ** self.alpha
dt_field = pred_error * distance
return dt_field.mean()
4. 常用的图像分割数据集
图像分割任务广泛应用于自动驾驶、遥感影像分析、医学影像分析等多个领域当中,在这一背景下人们常用的图像是指那些经过专门采集和标注的数据样本集合

⚪ Cityscapes
Cityscapes 被认为是最常用且广泛应用的语义分割数据集之一,并且专注于模拟真实的城市街道场景。该集合由来自全球50座不同城市的街景构成,并包含高质量标注图片(总计5,000张)以及低质量标注图片(总计2万张)。
关于测试集的表现,在过去几年中 Cityscapes 数据集中 state-of-the-art(SOTA)指标并未出现显著提升趋势;目前 SOTA mIoU 值维持在 80\% 至 85\% 之间。值得注意的是,在 Cityscapes 数据集上主要的研究集中在实时语义分割等应用领域。

⚪ ADE20K
ADE20K 也是最常用于研究语义分割任务的重要数据集合之一。该集合包含了来自不同领域的超过 多张图片以及 个不同的类别。其中训练集包含来自该集合的约 多张图片(具体为约 ),验证集则包含约 张图片。近年来,在研究领域中广泛使用的Transformers等新提出的模型多数是在基于 的数据集中评估其在语义分割任务中的表现情况。
关于测试集的表现,ADE20K 的 SOTA mIoU 数值仍然在被不停刷新,目前在 55~60 之间,偏低的指标绝对值主要可以归于以下两个原因:
- ADE20K 数据集中类别数目增加至150类,在计算mIoU指标时会受到长尾小样本类别负面影响而使结果偏低。
- ADE20K 数据集提供了大量图片数据(其中训练集共计20,210张、验证集为2,000张),这对算法模型性能提出了更高的要求。

⚪ SYNTHIA
SYNTHIA 是计算机合成的城市道路驾驶环境的像素级标注的数据集。是为了在自动驾驶或城市场景规划等研究领域中的场景理解而提出的。提供了11 个类别物体(分别为天空、建筑、道路、人行道、栅栏、植被、杆、车、信号标志、行人、骑自行车的人)细粒度的像素级别的标注。

⚪ APSIS
HumanPortraitSegmetationDatabase(AutomaticPortraitSegmetationforImageSty wholement,AbrreviationAPSIS)

