[关闭]
@Team 2018-07-15T14:57:17.000000Z 字数 6878 阅读 7874

基于深度学习的图像语义分割算法综述

叶虎


本文翻译自An overview of semantic image segmentation,原作者保留版权。

这篇文章讲述卷积神经网络图像语义分割(semantic image segmentation)的应用。图像分割这项计算机视觉任务需要判定一张图片中特定区域的所属类别。

这个图像里有什么?它在图像中哪个位置?

更具体地说,图像语义分割的目标是将图像的每个像素所属类别进行标注。因为我们是预测图像中的每个像素,这个任务通常被称为密集预测(dense prediction)。

image.png-298.3kB

语义分割实例:预测图像中每个像素点的类别(来源:VOC 2012)

需要注意的一点是我们不对同一类的实例进行分离; 我们只关心每个像素的类别。 换句话说,如果输入图像中有两个相同类别的对象,则分割图本身并不一定将它们区分为单独的对象。 存在另外一类不同的模型,称为实例分割(instance segmentation)模型,其将分离同一类的各个对象。

分割模型广泛应用在各领域中,包括:

deeplabcityscape.gif-6035.9kB

用于自动驾驶的道路场景实时分割

image.png-74.4kB

分割后的胸部X片,其中红色是心脏,绿色是肺,蓝色是锁骨

任务描述

简单来说,我们的目标是输入一个RGB彩色图片()或者一个灰度图(),然后输出一个包含各个像素类别标签的分割图()。

image.png-551.5kB

注意:为了清晰起见,这里给出的是一个低分辨率的预测图。在现实中,分割标签的分辨率应该与原始输入的分辨率是一致的。

与我们处理标准分类值的方式类似,我们的预测目标可以采用one-hot编码,即为每一个可能的类创建一个输出通道。通过取每个像素点在各个channel的argmax可以得到最终的预测分割图(如上图所示)。

image.png-192.7kB

我们可以将分割图叠加到原始图像上可以检验分割效果。当我们将预测结果叠加到单个channel时,称这为一个mask,它可以给出一张图像中某个特定类的所在区域。

image.png-252.9kB

架构设计

对于图像语义分割任务,构建神经网络架构的一种简单方法是简单地堆叠多个卷积层(使用same padding以维持维度大小)并输出最终的分割图。 这通过特征映射的连续变换直接学习从输入图像到其对应分割的映射关系;但是,在整个网络中保持图像原始分辨率的计算成本非常高。

image.png-186.8kB

缺点:在整个网络中维持图像原始维度计算成本很高(来源:cs231n)

回想一下,对于深度卷积网络,前面的层倾向于学习低级特征,而后面的层学习更高级的特征映射。为了保持表现力,我们通常需要在网络更深时增加特征图(channels)的数量。

这不一定对图像分类的任务造成问题,因为对于该任务,我们只关心图像中包含的物体(而不是它所在的位置)。 因此,我们可以通过通过池化或跨步卷积(即压缩空间分辨率)周期性地对特征图进行下采样来减轻计算负载。然而,对于图像分割,我们希望我们的模型最后给出全分辨率的语义预测。

用于图像分割模型的一种流行方法是遵循编码器/解码器(encoder/decoder)结构,其中我们先对输入进行下采样(downsample),得到较低分辨率的特征映射,其学习到了如何高效地区分各个类,然后对这些特征进行上采样(upsample)以得到一个全分辨率分割图。

image.png-150.5kB

上采样(upsampling)方法

可以采用不同的方法来上采样以提高特征图的分辨率。 pooling操作聚合一个局部区域(平均或最大池化)来下采样,相对应地,unpooling操作通过将单个值分配到更高的分辨率来上采样。

image.png-133.8kB

然而目前为止最流行的方法是转置卷积(transpose convolutions),因为它是通过学习得到的上采样方法。

image.png-59.5kB

而典型的卷积运算将视野中所有值求点积并在相应位置输出单个值,而转置卷积恰恰相反。对于转置卷积,低分辨率特征图中某个值,乘以卷积核中的权重值,将这些加权值映射到输出特征图。

image.png-31.8kB

1D转置卷积的简化实例

某些卷积核可能在输出特征图中产生重叠(例如卷积, 如下图所示),此时重叠值就简单地加在一起。 不好的是,这往往会在输出中形成棋盘效应(不均匀重叠,可以参考Deconvolution and Checkerboard Artifacts),这是不希望被看到的,因此最好确保选择的卷积核不会导致重叠。

padding_strides_transposed--1-.gif-266.1kB

步长为2的3x3转置卷积,其中上面输入,下面是输出。(来源:https://github.com/vdumoulin/conv_arithmetic

全卷积网络(Fully convolutional networks)

2014年底,Long等人介绍了使用“全卷积”网络解决像素级图像分割任务,其实现了端到端的训练。 该论文的作者采用已有的较优图像分类网络(例如AlexNet)作为网络的编码器模块,并增加了带有转置卷积层的解码器模块,以便对粗粒度的特征图进行上采样以得到全分辨率分割图。

image.png-108.9kB

整个网络如下所示,它采用像素级交叉熵损失函数进行训练。
image.png-133.4kB

然而,由于编码器模块将输入的分辨率降低了32倍,所以解码器模块很难得到细粒度的分割(如下所示)。

image.png-36.1kB

作者对这种困境做出了如下评论:

语义分割面临语义和位置之间的内在矛盾:全局信息解决的是“是什么”问题,而局部信息解决的是“在哪里”的问题......结合细粒度层和粗粒度层使模型能在全局信息下做出局部预测。

添加短路连接(Adding skip connections)

作者对编码的特征缓慢上采样(分阶段)来解决上面的问题,并添加了从前面层的短路连接,最后对这样的两个特征图求和。

image.png-94kB

这些从网络中较早层的短路连接(在下采样操作之前)应该包含必要的细节,这样可以重建准确的分割边界。 因而,我们可以通过加上这些短路连接来恢复更精密的细节。

image.png-41.3kB

Ronneberger等人通过扩大网络解码器模块的容量来改进“全卷积”架构。更具体地说,他们提出了U-Net架构,它包括一个可以捕获上下文信息的收缩路径(contracting path)和一个能够实现精确定位的与收缩路径对称的扩展路径。这种更简单的架构已经变得非常流行,并且已经对一系列分割问题有效。

image.png-77.6kB

注意:由于使用了valid填充,原始网络会出现分辨率降低。然而,一些人会选择使用same填充来保证分辨率不变。

Long等人(FCN论文)指出数据增强(随机镜像,或者通过将图像平移32像素来随机抖动)并没有导致性能的显着提升。Ronneberger等人(U-Net论文)却发现数据增强(对训练样本作随机的弹性变形)是训练成功的关键之一。似乎数据增强的有效性(和类型)取决于问题所在的领域。

高级的U-Net变体(Advanced U-Net variants)

标准U-Net模型的block中由一系列卷积层组成。有一些更高级的block可以替代这些堆栈卷积层。

Drozdzal等人(The Importance of Skip Connections in Biomedical Image Segmentation)采用了残差块(residual blocks)。除了标准U-Net结构中已有的长短路连接(在编码器和解码器模块的相应特征图之间),该残差块在块内引入短路连接。他们发现这种短路连接使得训练过程收敛更快,并可以训练更深层的网络模型。

更进一步,Jegou等人(Pattern Recognition The One Hundred Layers Tiramisu: Fully Convolutional DenseNets for Semantic Segmentation)采用了密集连接块(DenseNet网络单元),仍然使用U-Net架构,他们指出DenseNet的特点对语义分割很有效,因为它自然地引入短路连接,并实现了多尺度监督。这些密集块有效之处在于它们不仅包含从最近层得到的高级特征,还包含了从前面层传递的低级特征,这实现了高效的特征重用。

image.png-102.9kB

该架构的一个非常重要点是上采样路径在密集块的输入和输出之间没有短路连接。作者指出,由于上采样路径会增加特征图的空间分辨率,因此特征数量的线性增长对内存要求太高。因此,只有密集块的输出在解码器模块中被传递。

image.png-164.2kB

FC-DenseNet103模型在CamVid数据集上所实现的分割效果。

空洞卷积(Dilated/atrous convolutions)

对特征图进行下采样的一个好处是,在给定卷积核情况下,它会增加后续卷积的感受野(相对于输入)。由于大卷积核的参数效率低(在Rethinking the Inception Architecture for Computer Vision 的3.1节中讨论),这种方法比增加卷积核大小更好。 然而,这是以降低空间分辨率为代价的。

空洞卷积为获得宽感受野提供了另一种方法,其可以保持完整的空间维度。如下图所示,用于空洞卷积的值是在某个指定的扩张率(dilation rate)下间隔开的。

dilation.gif-122kB

一些架构(Multi-Scale Context Aggregation by Dilated Convolutions)使用使用一系列扩张率连续增长的空洞卷积层来替换一些pooling层,以实现在不损失空间细节的同时获得相同的感受野。然而,完全使用空洞卷积替换掉pooling层依然会导致较大的计算成本(见DeepLab: Semantic Image Segmentation with Deep Convolutional Nets, Atrous Convolution, and Fully Connected CRFs)。

损失函数

用于图像分割任务的最常用的损失函数是像素级的交叉熵损失(pixel-wise cross entropy loss)。 该损失单独地检查每个像素点,将类预测(深度方向的像素矢量)与one-hot编码的目标矢量进行比较。

image.png-82.6kB

因为交叉熵损失函数单独评估每个像素矢量的分类预测,然后对所有像素求平均值,所以我们基本上假定同等地对待图像中每个像素点。 如果各种类在图像分布不平衡时,这可能会是一个问题,因为训练过程将受最多的类所支配。Long等人(FCN论文)为每个输出通道的损失使用了权重,以抵消数据集中类不平衡问题。

同时,Ronneberger等人(U-Net论文)为每个像素的损失设置权重,使得分割对象的边界处具有更高的权重。该损失加权方案使得U-Net模型以不连续的方式分割生物医学图像中的细胞,这样可以在二元分割图中容易地分离出单个细胞。

image.png-152.9kB

二元分割图可以给出单个细胞的清晰边界

用于图像分割任务另一种流行的损失函数是基于Dice系数的损失,其本质上是衡量两个样本之间的重叠度。该度量值在0~1之间,其中Dice系数为1表示完全重叠。Dice系数最初针对二进制数据而提出的,计算公式如下:


其中表示A和B集合的共有元素数,而表示A集合中的元素数,与之类似。

为了根据预测的分割mask计算Dice系数,我们可以将预测mask和目标mask相乘(元素级)并且求矩阵元素和作为

image.png-38.5kB

因为我们的目标mask是二进制的,所以我们首先将预测结果中在目标mask中为0的像素清零。对于剩余的像素,我们基本上是在惩罚低置信度的预测值;该表达式的值越高(在分子中),Dice系数越高。

对于,一些研究者(The Importance of Skip Connections in Biomedical Image Segmentation)简单地求和,另外一些研究者(V-Net: Fully Convolutional Neural Networks for Volumetric Medical Image Segmentation)倾向于采用平方和。我并没知道在一系列任务中哪种方式更好,所以你可以两种方式都尝试,然后选择结果最好的那个。

image.png-23.7kB

你可能会问想知道,为什么Dice系数的分子中有2,这是因为我们的分母重复计算了两集合之间的共同元素。 由于损失函数要最小化,我们将简单地使用1-Dice作为损失函数。这种损失函数被称为soft Dice损失,因为我们直接使用预测概率而不是先设定阈值并将它们转换为二进制mask。

对于神经网络的输出,分子关注的是预测和目标mask之间的共同激活值,而分母与每个mask中的激活量相关。 这产生一种根据目标mask的大小来归一化损失的效果,使得soft mask损失不会难以从图像中分布较少的类中学习。

注意soft Dice是对于每个类是单独计算的,然后平均各个类的结果作为最终的评分。例子如下图所示。

image.png-88.8kB

常用数据集以及图像分割大赛

下面,我列出了一些常用数据集,研究人员使用这些数据集来训练新模型和并作为现有技术的基准。 你还可以看一下之前的Kaggle比赛,并了解获胜方的解决方案是如何在特定任务赢得比赛的。

数据集

以往的Kaggle竞赛

延伸阅读

论文

课程

博客

图片标注工具

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注