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

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

实例分割主要有两大类别,而这两大类方法都不够直接。

  1. 自上而下即detect-then-segment:太依赖于目标检测的准确率
  2. 自下而上:为每个像素学习一个嵌入向量(有点像Cornernet),该方法依赖于每个像素的嵌入学习和分组后处理。

出发点:一张图片中的实例基本的不同是什么?要么具有不同的中心点,要么具有不同的大小。所以是否可以直接利用这两个信息去区分实例?
实现:引入”实例类别“,也就是量化的中心点位置和物体大小,根据实例的位置和大小为实例中的每个像素分配类别。

  • 中心点位置
    一张图片可以被分为 S × S S\times S 个网格,所以定义 S 2 S^2 中心点位置类别。将这些类别加在通道上,对应的通道负责对应网格的实例掩码。
  • 大小
    利用FPN来预测多种尺度大小的实例。

相关工作

Top-down
基于检测的方法

  1. FCIS:将RPN生成的ROIs和位置敏感分数图结合在一起
  2. Mask R-CNN:给Faster R-CNN添加了分支
  3. PANet:在Mask R-CNN的基础上增强了特征表示来提高精度
  4. Mask Scoring R-CNN:添加了mask-IoU分支去估计mask的质量并且打分去提高精度
  5. TensorMask:在给定的滑动窗口里分割。

缺点:太依赖于anchor

Bottom-up
基于语义分割的方法

  1. SGN将实例分割问题分解为一系列子分组问题。
  2. SSAP学习像素对的亲和力金字塔,即两个像素属于同一实例的概率,并通过级联图分区顺序生成实例。

缺点:精度不高,需要分组后处理

Direct
没有直接利用mask annotations进行训练,也没有直接预测实例mask和类别。

  1. AdaptIS
  2. PolarMask

模型结构

在这里插入图片描述
上图所示是简单的一个框架,并没有FPN。SOLO将实例分割分为两个子任务,类别预测实例掩码生成,将一张图片划分为 S × S S\times S 个网格,如果一个物体的质心落在某个网格(若有多个物体落在该网格?该思路的前提是每个网格必须属于一个实例,因此只有一个类别),那么这个网格有两个任务:

  1. 预测该物体的类别
  2. 生成该物体的实例掩码

branch

如下图所示便是两个分支,分别对应上述的两个任务。除了输出卷积,其他卷积都是 3 × 3 3\times 3 ,分类分支的Align代表的是自适应性池化、插值或者region-grid插值,这三种的效果都差不多。
在这里插入图片描述
对于每一个FPN,后面都会接一个上述的分支结构(SOLO head),从而实现多尺度预测。
在这里插入图片描述
加入了FPN后提高了大约8个点,可见作用很大。

对于类别预测分支,当网格 ( i , j ) (i,j) center region有大于阈值的重叠的则认为是正例。center region定义为 ( c x , c y , ϵ w , ϵ h ) (c_x,c_y,\epsilon w,\epsilon h) 的区域,这里的中心点并不是bbox的中心,而是质心,其中 ϵ = 0.2 \epsilon=0.2 。这来源于center sampling,在Foveabox和FCOS中都有所体现。对于每个正例都有一个二值的mask,也就是在上分支中标记出正例所在的grid后,找到其所对应下分支 S 2 S^2 的通道中的一个通道进行标注。

对于Mask分支,之所以有 S 2 S^2 的通道,就是作者所说的中心点位置类别,第 ( i j ) (i,j) 个网格的instance mask对应第 k k 个通道( k = i × S + j k=i\times S+j )。
生成mask的分支类似于语义分割,是FCN(全卷积神经网络),具有平移不变性,然而本方法的mask不是直接生成,而是基于网格的位置( S 2 S^2 个通道),所以需要平移可变性
如何解决卷积带来的平移不变性?
借鉴于CoordConv,创建一个与输入相同的空间大小的张量,其中包含像素坐标,这些坐标被标准化至[-1,1],并和原始的输入进行通道上的concat。若原始输入大小为 H × W × D H\times W\times D ,则新输入张量的大小为 H × W × ( D + 2 ) H\times W\times (D+2) ,其中最后两个通道为 x y xy 像素坐标,从而提供全局位置信息。
在这里插入图片描述
消融实验中,一个的CoordConv能提高3.6的精度,再加反而没必要,可见该操作确实提供了一些位置信息。

损失函数

定义损失函数如下式:
L = L c a t e + λ L m a s k L = L_{cate}+\lambda L_{mask}
L c a t e L_{cate} 是分类分支的损失函数,用的是Focal Loss。
L m a s k L_{mask} 是mask生成的损失函数,如下式所示:
在这里插入图片描述
在这里插入图片描述
N p o s N_{pos} 表示的是正样本的个数(??), p m p*和m* 是分类和mask的target, I I II p i , j p_{i,j}^* 大于0时为1。对于 d m a s k d_{mask} 表示Dice Loss(因为这个损失相比于BCE、focal loss效果更好)。
L D i c e = 1 D ( p , q ) L_{Dice}=1-D(p,q)
在这里插入图片描述

Inference

前向传播得到类别分数 p i , j p_{i,j} 和相应的mask m k m_k ,其中 k = i S + j k=i*S+j
首先用置信度阈值0.1过滤掉分数比较低的预测,然后选取前500个排好序的mask进行NMS操作,然后用0.5的阈值进行mask二值化,保留前100个instance mask进行评估。

实验

在这里插入图片描述
在这里插入图片描述

Decoupled SOLO head

在这里插入图片描述
原来的head有 S 2 S^2 个通道,这计算量还是很大的,并且有实例的网格远远小于没有实例的网格,有些通道没有必要,所以作者提出了Decoupled SOLO head,将通道变为 S + S S+S ,减少显存的同时精度也没有降低。

发布了86 篇原创文章 · 获赞 10 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_36530992/article/details/103857123