目录
写在前面
实例分割(Instance Segmentation)
两阶段实例分割
自上而下(Top-Down)
自下而上(Bottom-Up)
单阶段实例分割
YOLACT&YOLACT++ ICCV 2019
PolarMask
SOLO
位置(location)
尺寸(size)
网络实现
实验结果
BlendMask
总结
参考
兵荒马乱的秋招结束了,浑浑噩噩地过了几个月,荒废了不少日子,现在打算重新捡起论文来读。这段时间,单阶段实例分割(Single Shot Instance Segmentation)的文章开始大量出现。这篇文章记录一下单阶段实例分割的方法,并简单介绍一下自己印象深刻的几篇论文。
实例分割(Instance Segmentation)是视觉经典四个任务中相对最难的一个,它既具备语义分割(Semantic Segmentation)的特点,需要做到像素层面上的分类,也具备目标检测(Object Detection)的一部分特点,即需要定位出不同实例,即使它们是同一种类。因此,实例分割的研究长期以来都有着两条线,分别是自下而上的基于语义分割的方法和自上而下的基于检测的方法,这两种方法都属于两阶段的方法,下面将分别简单介绍。
自上而下的实例分割方法的思路是:首先通过目标检测的方法找出实例所在的区域(bounding box),再在检测框内进行语义分割,每个分割结果都作为一个不同的实例输出。
这类方法的代表作就是大名鼎鼎的Mask R-CNN了,如下图,总体结构就是Faster R-CNN的两阶段目标检测,box head用来做检测,增加了mask head用来做分割,模型大家都很熟,细节就不再赘述。
自下而上的实例分割方法的思路是:首先进行像素级别的语义分割,再通过聚类、度量学习等手段区分不同的实例。
自下而上的工作并不多,通常的做法都是通过Instance Embedding的做法来做。举一篇CVPR2017的文章为例,
论文名称:Semantic Instance Segmentation with a Discriminative Loss Function。
参考代码:https://github.com/Wizaron/instance-segmentation-pytorch
这篇论文的实例分割做法是:
(1)语义分割:首先在第一个阶段做了语义分割,得到了所有的物体mask;
(2)像素嵌入:再通过使用一个判别式损失函数来训练网络,网络的优化目标是将图像每个像素投影到 n维特征空间后,同属于一个实例的像素尽量靠近,形成一个 cluster
, 每一个实例对应一个 cluster
, 不同 cluster
则尽量远离
(3)后处理:最后使用聚类的方法(如mean-shift)来输出不同的实例。
文章的关键在于提出的判别式损失函数,它的组成如下:
(1)拉力。惩罚同一实例中所有元素与其平均值之间的距离。也就是说,获取一个实例的所有像素,并计算平均值。这种拉力会将同一实例中的所有像素点拉近到嵌入空间中的同一个点。简单说,就是减少每一个实例的嵌入方差。
(2)推力。获取所有中心点 (在嵌入空间embedding中,而不是空间中心),然后将它们推得更远。
(3)正则化。中心点不应该离原点太远。
文章的超参数设置和迭代方法还是有比较多的坑,感兴趣的可以去看原文和代码。更多关于Instance Embedding的文章可以看看[1]。
下面就聊聊单阶段实例分割(Single Shot Instance Segmentation),这方面工作其实也是受到了单阶段目标检测研究的影响,因此也有两种思路,一种是受one-stage, anchot-based 检测模型如YOLO,RetinaNet启发,代表作有YOLACT和SOLO;一种是受anchor-free检测模型如 FCOS 启发,代表作有PolarMask和AdaptIS。
目前(2020年1月)来看,单阶段实例分割的精度最高的模型应该是新出的BlendMask(COCO, 41.3),在精度和速度上都超越了Mask R-CNN,已经很接近两阶段模型(SOTA应该是HTC?)了。
原文:https://arxiv.org/abs/1904.02689
代码(官方):https://github.com/dbolya/yolact
YOLACT是我最早看的一篇单阶段实例分割的文章,主要参照了单阶段检测模型RetinaNet,因此把它归类于单阶段的实例分割。YOLACT将实例分割任务拆分成两个并行的子任务:
(1)通过一个Protonet网络, 为每张图片生成 k 个 原型mask
(2)对每个实例,预测k个的线性组合系数(Mask Coefficients)
最后通过线性组合,生成实例mask,在此过程中,网络学会了如何定位不同位置、颜色和语义实例的mask。
具体网络结构如下:
(1)Backbone:Resnet 101+FPN,与RetinaNet相同;
(2)Protonet:接在FPN输出的后面,是一个FCN网络,预测得到针对原图的原型mask
(3)Prediction Head:相比RetinaNet的Head,多了一个Mask Cofficient分支,预测Mask系数,因此输出是4*c+k
此外,论文中还用到了Fast NMS方法,比原有的NMS速度更快,精度减得不多。
之后,作者又提出了改进版的YOLACT++,改进之处主要有:
(1)参考Mask Scoring RCNN,添加fast mask re-scoring分支,更好地评价实例mask的好坏;
(2)Backbone网络中引入可变形卷积DCN;
(3)优化了Prediction Head中的anchor设计
YOLACT和YOLACT++的实验效果如下:
原文:https://arxiv.org/abs/1909.13226
代码(官方):https://github.com/xieenze/PolarMask
这篇文章是一篇anchor-free的一阶段实例分割模型,主要参考了检测模型FCOS。我之前的关于Anchor-Free检测模型的博客中提到了,anchor-free方法有两类,一类是基于关键点Keypoint,一类是基于密集预测的,FCOS就是基于后者的。
关于PolarMask的原理,这里摘抄一段作者大佬的详细解析 ,就不班门弄斧了,感兴趣的可以看作者文章跟论文。
PolarMask 基于极坐标系建模轮廓,把实例分割问题转化为实例中心点分类(instance center classification)问题和密集距离回归(dense distance regression)问题。同时,我们还提出了两个有效的方法,用来优化high-quality正样本采样和dense distance regression的损失函数优化,分别是Polar CenterNess和 Polar IoU Loss。没有使用任何trick(多尺度训练,延长训练时间等),PolarMask 在ResNext 101的配置下 在coco test-dev上取得了32.9的mAP。 这是首次,我们证明了更复杂的实例分割问题,可以在网络设计和计算复杂度上,和anchor free物体检测一样简单。我们希望PolarMask可以成为一个简单且强有效的single shot instance segmentation 的baseline。
PolarMask最重要的特点是:
(1) anchor free and bbox free,不需要出检测框
(2) fully convolutional network, 相比FCOS把4根射线散发到36根射线,将instance segmentation和object detection用同一种建模方式来表达。
多说一句,从实验结果可以看到,PolarMask的精度并不是很高,而且速度上也没有优势,但是它的思路是非常巧妙的,对后面的研究有着很大的启发意义。
原文:https://arxiv.org/abs/1912.04488
代码:https://github.com/WXinlong/SOLO
这篇文章的思路也非常巧妙,作者提出,可以将实例分割的问题转化为像素的“实例标签”的分类问题。这里同样引用作者的回答来理解这一动机。
SOLO的出发点很简单,怎么样简单直接的做实例分割?语义分割和实例分割,大家都是分割,为什么解决起来大相径庭?
语义分割,其实就是逐像素的语义类别分类:预测每个像素所在的物体的语义类别。类比下来,是不是可以进行逐像素的实例类别分类:预测每个像素所在的物体的实例类别。
那么核心问题就是, 什么是物体的实例类别?物体的语义类别是由人为的定义来区分的,是由人来标注的。那图片里物体的什么属性可以用来区分实例呢?—— 位置和形状。
如果一张图片里出现的两个物体,位置和形状完全一样,那这就是同一个实例。两个不同的实例,位置或者形状不一样。这里指的广义的形状:包括尺寸,角度,这些和位置无关的,每个物体都有的属性。由于泛泛的形状不好描述,我们采用尺寸来近似替换。
要理解本文的思想,重点就是要理解SOLO提出的实例类别(Instance Category)的概念。作者指出,实例类别就是量化后的物体中心位置(location)和物体的尺寸(size)。下面就解释一下这两个部分。
SOLO将一张图片划分S×S的网格,这就有了S*S个位置。不同于TensorMask和DeepMask将mask放在了特征图的channel维度上,SOLO参照语义分割,将定义的物体中心位置的类别放在了channel维度上,这样就保留了几何结构上的信息
本质上来说,一个实例类别可以去近似一个实例的中心的位置。因此,通过将每个像素分类到对应的实例类别,就相当于逐像素地回归出物体的中心、这就将一个位置预测的问题从回归的问题转化成了分类的问题。这么做的意义是,分类问题能够更加直观和简单地用固定的channel数、同时不依赖后处理方法(如分组和学习像素嵌入embedding)对数量不定的实例进行建模。
对于尺寸的处理,SOLO使用了FPN来将不同尺寸的物体分配到不同层级的特征图上,依次作为物体的尺寸类别。这样,所有的实例都被分别开来,就可以去使用实例类别去分类物体了。
SOLO将图片划分成S×S的网格,如果物体的中心(质心)落在了某个网格中,那么该网格就有了两个任务:(1)负责预测该物体语义类别(2)负责预测该物体的instance mask。这就对应了网络的两个分支Category Branch和Mask Branch。同时,SOLO在骨干网络后面使用了FPN,用来应对尺寸。FPN的每一层后都接上述两个并行的分支,进行类别和位置的预测,每个分支的网格数目也相应不同,小的实例对应更多的的网格。
可以看到,SOLO的精度已经超越了Mask R-CNN,相较思路类似的PolarMask也有较大的优势。
详细的论文分析可以移步我的笔记【实例分割论文】 SOLO:Segmenting Objects by Locations
原文:https://arxiv.org/abs/2001.00309
代码:暂无(也不太需要)
BlendMask是一阶段的密集实例分割方法,结合了Top-down和Bottom-up的方法的思路。它通过在anchor-free检测模型FCOS的基础上增加了Bottom Module提取low-level的细节特征,并在instance-level上预测一个attention;借鉴FCIS和YOLACT的融合方法,作者提出了Blender模块来更好地融合这两种特征。最终,BlendMask在COCO上的精度(41.3AP)与速度(BlendMask-RT 34.2mAP, 25FPS on 1080ti)都超越了Mask R-CNN。
这篇文章虽然精度、速度高,但创新点不能算突出,还是YOLACT和Mask R-CNN的思路。好在实验做的很充足,优化模型的思路也很值得借鉴,最后还专门对比了下Mask R-CNN,好评~
具体的解析可以看我的另一篇文章:
【实例分割论文】BlendMask: Top-Down Meets Bottom-Up for Instance Segmentation
一阶段实例分割的发展主要归功于一阶段检测器RetinaNet、FCOS等,并且也从中衍生出了一些很不错的思路。文中提到的三篇文章是我认为最有代表性的,希望后面能有更多惊艳的文章出现。
[1] Instance Embedding: Segmentation Without Proposals
[2] 论文阅读《Semantic Instance Segmentation with a Discriminative loss function》
[3] 论文学习笔记-YOLACT++
[4] 【ICCV 2019】一文读懂实时实例分割模型 YOLACT
[5] 论文笔记:AdaptIS
[6] 论文速递 | 实例分割算法BlendMask,实时又state-of-the-art