【实例分割论文】 SOLO:Segmenting Objects by Locations

论文名称:《SOLO: Segmenting Objects by Locations》

论文链接:https://arxiv.org/abs/1912.04488

参考代码:https://github.com/Epiphqny/SOLO (第三方实现,不完整)

目录

综述

背景介绍

总体思路

位置(location)

尺寸(size)

网络实现

FPN

扫描二维码关注公众号,回复: 8667159 查看本文章

Category Branch

Mask Branch

实验结果 

Decoupled SOLO


综述

作者提出了一种非常简单、直接的实例分割方法。通过引入“实例类别”这一概念,将实例分割的问题转化为两个分类问题。实例类别则是根据实例中的每一个像素的位置尺寸来确定标签的,思路非常巧妙。作者提出的模型精度不错,在COCO上超越了Mask R-CNN和其他单阶段实例分割模型,但思路是我觉得最值得follow的。 

背景介绍

实例分割(Instance Segmentation)是视觉四任务中相对最难的一个,它既具备语义分割(Semantic Segmentation)的特点,需要做到像素层面上的分类,也具备目标检测(Object Detection)的一部分特点,即需要定位出不同实例,即使它们是同一种类物体。因此,实例分割的研究长期以来都依赖较为复杂的两阶段的方法,两阶段方法又分为两条线,分别是自下而上基于语义分割的方法和自上而下基于检测的方法。

自上而下的实例分割方法的思路是:首先通过目标检测的方法找出实例所在的区域(bounding box),再在检测框内进行语义分割,每个分割结果都作为一个不同的实例输出

自下而上的实例分割方法的思路是:首先进行像素级别的语义分割,再通过聚类、度量学习等手段区分不同的实例。

作者认为,这些两阶段方法都是step-wise和indirect的,因此提出疑问,实例分割与语义分割为何在解决方法上相差如此之大?是否有办法更加简单地完成实例分割?

总体思路

这里引用作者的回答来理解作者的动机与思路。

SOLO的出发点很简单,怎么样简单直接的做实例分割?语义分割和实例分割,大家都是分割,为什么解决起来大相径庭?

语义分割,其实就是逐像素的语义类别分类:预测每个像素所在的物体的语义类别。类比下来,是不是可以进行逐像素的实例类别分类:预测每个像素所在的物体的实例类别

那么核心问题就是, 什么是物体的实例类别?物体的语义类别是由人为的定义来区分的,是由人来标注的。那图片里物体的什么属性可以用来区分实例呢?—— 位置和形状

如果一张图片里出现的两个物体,位置和形状完全一样,那这就是同一个实例。两个不同的实例,位置或者形状不一样。这里指的广义的形状:包括尺寸,角度,这些和位置无关的,每个物体都有的属性。由于泛泛的形状不好描述,我们采用尺寸来近似替换。

要理解本文的思想,重点就是要理解SOLO提出的实例类别(Instance Category)的概念。作者指出,实例类别就是量化后的物体中心位置(location)和物体的尺寸(size)。下面就解释一下这两个部分。

位置(location)

SOLO将一张图片划分S×S的网格,这就有了S*S个位置。不同于TensorMask和DeepMask将mask放在了特征图的channel维度上,SOLO参照语义分割,将定义的物体中心位置的类别放在了channel维度上,这样就保留了几何结构上的信息。

本质上来说,一个实例类别可以去近似一个实例的中心的位置。因此,通过将每个像素分类到对应的实例类别,就相当于逐像素地回归出物体的中心、这就将一个位置预测的问题从回归的问题转化成了分类的问题。这么做的意义是,分类问题能够更加直观和简单地用固定的channel数、同时不依赖后处理方法(如分组和学习像素嵌入embedding)对数量不定的实例进行建模。

尺寸(size)

对于尺寸的处理,SOLO使用了FPN来将不同尺寸的物体分配到不同层级的特征图上,依次作为物体的尺寸类别。这样,所有的实例都被分别开来,就可以去使用实例类别去分类物体了。

网络实现

SOLO将图片划分成S×S的网格,如果物体的中心(质心)落在了某个网格中,那么该网格就有了两个任务:(1)负责预测该物体语义类别(2)负责预测该物体的instance mask。这就对应了网络的两个分支。

FPN

SOLO在骨干网络后面使用了FPN,用来应对尺寸。FPN的每一层后都接上述两个并行的分支,进行类别和位置的预测;同时,FPN每个层级接的分支的网格数目也按照金字塔的形式变化(P2->P6, 40,36,,24,16,12),实现了多尺度预测(multi level prediction)。

消融实验证明,单一尺度的SOLO已经有了不错的检测精度(27.2 ap),但加入了FPN多尺度预测后的提升巨大。

Category Branch

Category Branch负责预测物体的语义类别,每个网格预测类别S×S×C,这部分跟YOLO是类似的。输入为Align后的S×S×C的网格图像,输出为S×S×C的类别。这个分支使用的损失函数 $L_{\text {cate }}$ 是focal loss

那如何设计标签呢?当网格(i,j)与物体的中心区域有大于阈值的重叠则认为是正样本。这里的中心区域定义在中心点(这里定义的中心点是物体的质心)周围的\epsilon=0.2 倍区域(来源于center sampleing)。对于每个正样本,都会有对应类别的instance mask,这就由后面的Mask Branch来预测。

此外,Category Branch需要将H*W的输入调整为S*S的网格输入,因此需要用到插值。作者实验了三种方法:直接插值、adpative pooling和区域网格插值,效果都差不多。

Mask Branch

每个正样本(有类别输出的网格)都会输出对应类别的instance mask,这里的通道channel和网格的对应关系是:第k个通道负责预测出第(i,j)个网格的instance mask,k = i*S+j。因此输出维度H×W×S×S 。这样的话就有了一一对应的语义类别和class-agnostic的instance mask。

预测instance mask的一个直观方法是类似语义分割使用FCN,但FCN是具有空间不变性(spatiallly invariant)的,而我们这边需要位置上的信息。因此,作者使用了CoordConv,将像素横纵坐标x,y(归一化到[-1,1])与输入特征做了concat再输入网络中。这样输入的维度就是 H*W*(D+2)了。

消融实验证明,一个的CoordConv就能带来3.6的ap提升,说明CoordConv的存在确实融入了位置变化信息。更多的CoordConv反而提升不大。

在这个分支中,损失函数为 L_{m a s k}=\frac{1}{N_{p o s}} \sum_{k} \mathbb{1}_{\left\{\mathbf{p}_{i, j}^{*}>0\right\}} d_{m a s k}\left(\mathbf{m}_{k}, \mathbf{m}_{k}^{*}\right)。针对d_mask,作者尝试了三种计算GT和预测mask像素的损失函数:Binary Cross Entropy (BCE), Focal Loss 和 Dice Loss,最终选择了Dice Loss。最后网络的总损失就是 L=L_{\text {cate}}+\lambda L_{\text {mask}}

消融实验证明,Focal Loss的效果要比BCE好,原因是实例mask中的大部分像素属于背景(负样本);然而,Dice Loss在无需调参的情况下取得了更好的效果。,

后处理

有了上面两个任务,接下来就是完成实例分割任务,得到最终的实例分割结果。很自然的,最终的结果就是所有网格的instance mask(即输出的每个通道)叠加的结果。最后再使用NMS过滤掉,不需要其他的后处理手段。

实验结果 

可以看到,SOLO的精度已经超越了Mask R-CNN,相较思路类似的PolarMask也有较大的优势。

Decoupled SOLO

原始的SOLO对于 S×S的网格需要S×S的输出通道,这对计算量是比较大的要求,但其实图片中通常并不会有这么多的实例,这里头有很多通道是多余的。因此,作者提出了更有效率的变种Decoupled SOLO

通过将原始的输出M \in \mathbb{R}^{H \times W \times S^2} 替换成了 X \in \mathbb{R}^{H \times W \times S} 和 Y \in \mathbb{R}^{H \times W \times S} 的element-wise multiplication,Decoupled SOLO将输出通道降成了S+S,大大降低了输出的维度和所需的GPU内存,同时精度上没有损失。

发布了11 篇原创文章 · 获赞 4 · 访问量 552

猜你喜欢

转载自blog.csdn.net/sanshibayuan/article/details/103895058