自21年年初从语义分割的舒适圈跳入实例分割方向至今,已经一年又半载了。
看过一些文章,跑过一些实验,至今没有产出。
思想挣扎过许多次,要不要继续,最终决定遗憾退场。
写一点东西,记一记往昔,弥补遗憾于万一。
实例分割是结合目标检测和语义分割的一个更高层级的任务。
因此:
纵观实例分割的算法发展也是遵循这两条路线:
考虑到基于语义分割的的自下而上的实例分割算法(如Semantic Instance Segmentation with a Discriminative Loss Function,Deep Watershed Transform for Instance Segmentation)通常后处理步骤繁琐,且效果较差,本文主要探讨的是基于目标检测的自上而下的实例分割算法。
本文按照所采用的目标检测网络将实例分割算法划分为二阶段实例分割,一阶段实例分割,Query-based 实例分割三大类进行介绍。除此之外,按照对实例分割mask的表征方式的不同,介绍 Contour-based 和 Boundary Refinement 实例分割。
除此之外,一些方法(如:FCIS,TensorMask,deepmask,AdaptIS,MEInst)也都是非常经典的工作,本文由于篇幅原因,并未涉及。

Mask R-CNN是典型的自上而下的实例分割算法,其扩展自目标检测网络Faster R-CNN,在其基础上新增了mask预测分支。
因此,Mask R-CNN的主要工作集中在RoI Align和mask分支的设计,以下分别进行介绍:
由于RPN阶段得到的proposals box的大小是不一样的,而为了进行后续的class分类,box回归和mask分割任务,必须有一种操作将不同尺寸的box特征图归化到相同的空间尺寸以方便进行batch运算,RoI Pooling和RoI Align的作用就是如此。
RoI Pooling存在两次量化过程:
RoI Pooling这种粗糙的量化方式对于Mask R-CNN新增的mask分支会产生很大的量化误差,因此,提出了RoI Align方法,取消RoI Pooling中涉及的两次量化操作, 使用双线性插值的方法获得坐标为浮点数的像素点上的图像数值,其具体流程如下:

由于mask分支需要对目标进行精细的mask预测,因此,mask分支采用比分类和回归分支更高的特征分辨率。具体来讲,将经过RPN阶段筛选出来的RoI经过RoI Align层将其尺寸统一为
14
×
14
14 \times 14
14×14,然后使用4层全卷积层和一层反卷积层以及最终的分类层为每个RoI预测一个
28
×
28
28 \times 28
28×28的mask。

Cascade Mask R-CNN 也是探讨如何在检测器Cascade R-CNN基础上设计mask分支。
Cascade R-CNN主要针对 Faster R-CNN 中 R-CNN 部分采用单一 IoU 阈值进行正负样本选取会产生训练和测试过程中的不匹配的问题。 具体来讲:
因此,此处所描述的不匹配问题就在于:
通常threshold取0.5时,mismatch问题还不会很严重。而为了得到更精准的box,最直接的办法就是提高正样本的IoU阈值,那此时的mismatch问题就会更加严重。同时,提高IoU阈值会导致满足阈值条件的proposals比之前少了许多,极容易产生过拟合。

上述的实验表明,由于采用单一的IoU阈值会产生mismatch的问题,因此,无法通过一味提升IoU阈值来获取更精准的box预测。本文提出一种级联结构,并在不同层逐渐增大IoU阈值,来缓解mismatch问题并产生更精确的box预测。

Cascade R-CNN的结构如上图所示,首先在不同的stage采用不同的IoU阈值,同时不同stage也采用不同的H(H表示R-CNN Head)。
(1) 递增IoU阈值
下图中,横轴 Input IoU 表示 RPN 输出的 proposal 与 gt bbox 的 IoU,纵轴 Output IoU 是经过 R-CNN 的 box 分支回归输出后与gt bbox 的 IoU,不同线条代表不同阈值训练出来的 detector。可以发现,Input IoU 在 0.55-0.6 范围内 proposal 阈值设置为 0.5 时 detector 性能最好,在 0.6~0.75 阈值为 0.6 的 detector 性能最佳,而到了 0.75 之后就是阈值为 0.7 的 detector 性能最好了。只有输入 proposal 自身的 IoU 分布和 detector 训练用的阈值 IoU 较为接近的时候,detector 性能才最好。

下图显示逐stage增大IoU后,正样本不仅没有减少,而且稍稍有增加。这是因为经过前一个stage的refinement,后一个stage的输出box变得更精确了,即与GT的IoU提升了。因此,Cascade R-CNN级联多个 R-CNN 模块,并且不断提高 IoU 阈值,不仅不会出现mismatch和过拟合,反而可以逐阶段修正box预测。

(2) 差异化R-CNN Head
下图显示经过每个stage的R-CNN Head后,输入到R-CNN Head的样本分布会发生变化,因此,采用共享的R-CNN Head无法有效适配变化的样本分布问题。因此,Cascade R-CNN在每个stage都采用独立参数的R-CNN Head。

为了将Cascade R-CNN目标检测器推广到实例分割,作者提出了(b)(c)(d)三种策略来新增mask分支。在测试时:

HTC的主要创新点有两个:
下图中展示了在Cascade R-CNN的基础上添加mask分支的四种依次递进的设计:

为了在不同stage的mask分支之间添加信息流,作者将前一个stage的特征 M i − 1 M_{i-1} Mi−1 ( 14 × 14 × 256 14\times14\times256 14×14×256)经过一个 1 × 1 1\times1 1×1卷积之后与当前stage RoI Align之后的特征 M i M_{i} Mi进行sum融合并输入到当前mask分支。
在实际训练时,前一个stage的RoI和当前stage的RoI并不一致,那么如果直接将前一个stage的特征拿过来与当前stage特征sum融合便会遇到空间不对齐的问题。因此,在实际训练过程中,需要用当前stage的RoI重新执行一遍前一个mask分支,这样就解决了mask特征不对齐的问题。测试时,与Cascade Mask R-CNN一致,只采用了最后一个stage的RoI输出,也不会遇到mask特征不对齐的问题。

为更好的区分前背景,进一步将语义分割引入到实例分割框架中,以获得更好的 spatial context。具体来讲:

在介绍一阶段实例分割前,我们引入局部mask和全局mask的概念,这也是二阶段实例分割与一阶段实例分割的本质差别。如果这一块看的时候有点懵逼,就先跳过,等看完一阶段部分再回来看也行。

(1) 局部mask
如上图所示,第二章介绍的二阶段实例分割采用的就是局部mask,将box内部的区域全部裁剪出来并通过RoI Align统一到相同的尺寸;
其优点是:
其缺点是:
(2) 全局mask
全局mask不需要经过裁剪和RoI Align的过程,而是直接从整个特征图中预测某个实例。
其优点是:
其缺点是:
之所以这篇文章给了五星,是因为在我看来,YOLACT算是后来的BlendMask,EmbedMask,Condinst这一系列文章的雏形。这一系列方法都是通过预测一组实例特定的参数与共享的1/4或者1/8的全局特征通过某种操作(通道加权求和,卷积或者聚类等)来预测一组实例的mask。
如果上面这句话理解有点困难的话,再拿Mask R-CNN举个例子:
接下来详细看一下YOLACT是怎么用共享的全局特征来进行实例分割的。YOLACT是在目标检测网络RetinaNet的基础上进行改造的。
RetinaNet本质上是由ResNet+FPN+两个FCN子网络(分类和回归)组成:
RetinaNet同时也是一个Anchor-based的模型:
也就是说,在 P 3 到 P 7 P_3到P_7 P3到P7的每个特征图的每个像素网格上都会预设9个anchor:
训练时的anchor正负样本分配策略如下:

实例mask系数就是在RetinaNet分类和回归分支的基础上,并行添加一个mask系数预测分支,也就是如上图所示,预测为 W × H × k a W \times H \times ka W×H×ka 的分支,即接下来的采用通道加权操作合成实例mask的通道加权的系数, k k k就是通道的数目。实际操作会对预测出来的系数采用 t a n h tanh tanh进行非线性变换。
Mask特征直接在FPN P 3 P_3 P3特征图上接一个全卷积网络,将分辨率上采样至1/4并将通道映射为 k k k,最终的shape为 H × W × k H \times W \times k H×W×k。
最终的实例mask的预测就采用下图所示的公式合成:

这个矩阵乘法背后的含义就是对预测的mask特征的每个通道采用对应的mask系数进行加权求和,其本质就是一个 1 × 1 × k × 1 1 \times 1 \times k \times 1 1×1×k×1 的卷积操作,卷积核为 1 1 1,输入通道为 k k k,输出通道也为 1 1 1。
BlendMask与YOLACT整体来讲是很像的,给检测head部分新增一个实例相关的参数(Boxes Attens)预测分支,在1/4特征图上生成mask特征(Bases)。接下来照旧挨个模块简介一下:


EmbedMask与YOLACT同样很相似,不同之处在于:
EmbedMask的详细网络结构如下,基于FCOS目标检测网络进行实例分割设计,蓝色的部分是新添加的模块,主要包含实例Embedding预测模块(Proposal Embedding),全局特征图生成模块(Pixel Embedding),以及可学习实例聚类阈值预测模块(Proposal Margin)三个模块。


(1)中介绍的是一种固定阈值聚类方案,那么,如下图所示(虚线圆半径代表聚类阈值),大目标应该用大的阈值,小目标应该用小的阈值。阈值取得大了,小目标就会和其他目标混淆被分割出来,阈值取得小了,大目标只能分割出一部分来。那么,可学习的阈值就应运上马了。

可学习实例聚类阈值(Proposal Margin)是由Box Regression经过1x1的卷积后得到。为了让阈值可学习,需要将阈值作为参数整合入损失函数并且是一个可导的过程。 EmbedMask参考了Instance segmentation by jointly optimiz- ing spatial embeddings and clustering bandwidth这篇文章的做法,采用高斯分布对像素embedding
p
i
p_i
pi,实例embedding
Q
k
Q_k
Qk以及可学习实例阈值
Σ
k
Σ_k
Σk建模出
φ
(
x
i
,
S
k
)
φ(x_i, S_k)
φ(xi,Sk),代表像素
x
i
x_i
xi 属于实例
S
k
S_k
Sk 的概率,某个像素的embedding与实例embedding距离越近,属于该实例的概率就越大。

这里关于
φ
(
x
i
,
S
k
)
φ(x_i, S_k)
φ(xi,Sk)还有一些细节,上述的公式里面的实例embedding
Q
k
Q_k
Qk 并非某个位置(每个像素作为anchor预测一个实例)处预测出来的实例embedding,这是因为FCOS会给每个GT匹配到多个正样本位置,每个位置都会预测出一个实例embedding,按理他们应该一致的,但是这些属于同一目标的正样本预测出来embedding很难保证一致,那么如果同一个实例目标采用多个实例embedding与pixel embedding计算距离,那pixel embedding到底该与哪个位置预测的实例embedding学习的更接近呢,that’s a problem! 因此这里的
Q
k
Q_k
Qk 和
Σ
k
Σ_k
Σk实际上是属于某个实例GT的所有正样本预测的实例embedding和实例阈值的平均值,如下图所示。

最终的mask分支的损失函数如下:

此外,由于在训练期间的
Q
k
Q_k
Qk、
Σ
k
Σ_k
Σk与测试期间的
Q
k
Q_k
Qk、
Σ
k
Σ_k
Σk是不一致的,测试期间就直接是当前位置预测的实例embedding
q
j
q_j
qj 和实例阈值
σ
j
σ_j
σj,因此,在训练期间还要加一个损失函数来约束所有正样本预测的实例embedding
q
j
q_j
qj 和实例阈值
σ
j
σ_j
σj尽可能的接近均值,公式如下:

当两个属于同一类别的目标同时出现时,要想将两者进行实例层面的区分,上述已经介绍的方法的解决思路如下:
那么,也给YOLACT这一类的一阶段方法引入位置先验信息,就可以减缓同类目标语义特征学习的足够差异化的压力,也就是说,两个同类目标虽然语义特征相似,但是位置特征是不同的,那这样也可以将两者在实例层面区分开来。




SOLO共出了两个版本,v1跟本章前面的几篇文章相关性都不大,v2在v1的基础上引入了动态卷积的方案。那就先介绍一下v1:

SOLOv1在网格上进行实例分割的方案有点类似YOLO,都是在网格上进行实例目标的检出,SOLOv1是做实例分割,YOLO是进行目标检测。但是SOLOv1并不像CondInst这一类方法,其并没有保留目标检测网络的bbox分支,而是只有分类分支和mask分支。 接下来分别从SOLOv1的网格正负样本分配和classification分支及mask分支的设计两个方面展开。
具体来讲,SOLO会首先将FPN不同层的特征图等分为 S × S S \times S S×S 个格子。正负样本的分配涉及到两个方面:
FPN同一层:
对于给定gt mask的质心、宽度w和高度h,设置比例因子,如0.2。被缩小后的box覆盖住的几个格子就是正样本,每一个gt平均有3个正样本。
FPN不同层:
但是,如果两个目标同时覆盖某个网格呢,为了处理这种情况,作者首先做了个统计:在验证集中,绝大多数(约98.9%)的实例要么中心位置不同,要么大小不同。 因此,如果两个目标中心位置接近,那就通过尺度将其分配到FPN的不同层去,这样就能解决掉98.9%的冲突。
论文设置scale_ranges=((1, 96), (48, 192), (96, 384), (192, 768), (384, 2048)),分别对应不同FPN的输出层。当实例的尺度落入某一个区间,则该FPN分支负责该实例的预测。由于不同区间存在重叠的情况,因此会存在不同FPN层预测相同的目标,这样同样会增加正样本的数量。

那么这里问题也是比较明显的,如下图所示,mask 分支在P2特征图上需要预测了
40
×
40
=
1600
40 \times 40 = 1600
40×40=1600 个channels,这个计算量和显存占用也太大了。

因此,作者提出了Decoupled head,不直接预测
S
2
S^2
S2 个channels了,只预测
2
S
2S
2S 个channels。那么处于
(
i
,
j
)
(i, j)
(i,j) 位置的网格对应的mask预测就由Y分支的第
i
i
i 个通道和X分支的第
j
j
j个 通道预测的mask进行element-wise乘即可。

SOLOv2采用类似CondInst的动态卷积方式,给每个网格代表的实例预测一组卷积参数,将其FPN各个分辨率融合后的特征图进行动态卷积来得到实例mask。


SOLOv2的mAP刚刚与Mask R-CNN齐平,但是在小目标和大目标的性能上出现了明显的反差

二阶段的实例分割算法最终输出的mask分辨率皆为 28 × 28 28 \times 28 28×28,这会导致一些目标的边缘预测不佳。因此,存在一系列方法对此进行修复,本文介绍此方向两篇经典且有效的工作:Pointrend和Refinemask,他们的基本思路都是进行crose to fine的refinement,既然 28 × 28 28 \times 28 28×28分辨率太低,那就往大的搞, 112 × 112 112 \times 112 112×112总可以了吧,不行就 224 × 224 224 \times 224 224×224。
Pointrend将图像分割视作渲染问题,我们直接透过故事包装看其实质做法。
Pointrend在测试阶段的步骤可以分为以下几步:

Pointrend的核心思想体现在测试阶段,即迭代地对直接双线性插值后的mask上的不确定点以二次预测的方式进行修复,以得到良好的物体边缘。换句话说,相当于在coarse to fine refinement的过程中加入了cascade hard example mining。
考虑到测试期间每次迭代的MLP网络都是共享的,训练期间并没有采用迭代修复的过程,只是在单个分辨率( 7 × 7 7 \times 7 7×7)选取一批难点,并构造难点特征输入到一个MLP网络进行难点再预测。

RefineMask网络结构如下,其也是考虑到Mask R-CNN输出的mask分辨率太低,进行了以下改进:

SFM包含4个输入:(1)instance feature,(2)instance mask,(3)semantic feature,(4)semantic mask,其均是通过RoI Align得到的。
SFM模块具体操作是将四个部分的输入concat到一起然后通过三路并行的扩张卷积(输出通道254),用于提取不同感受野的特征,最终将instance mask和semantic mask再次concat输出(最终输出通道256)。

在训练期间,RefineMask共计会输出 14 × 14 14 \times 14 14×14, 28 × 28 28 \times 28 28×28, 56 × 56 56 \times 56 56×56, 112 × 112 112 \times 112 112×112 四个分辨率的预测,其中, 14 × 14 14 \times 14 14×14 和 28 × 28 28 \times 28 28×28的instance mask监督与Mask R-CNN一致,但是 56 × 56 56 \times 56 56×56 和 112 × 112 112 \times 112 112×112 预测的instance mask仅包含边界区域,其真值范围是边界线两侧n个像素宽的区域。
在测试期间,考虑到低分辨率特征预测的内部信息更加连续,高分辨率特征预测的边缘信息更加准确,因此,融合
28
×
28
28 \times 28
28×28 的mask预测的内部区域与
56
×
56
56 \times 56
56×56 的mask预测的边界区域来获取得到
56
×
56
56 \times 56
56×56 的mask,同理可以得到最终的
112
×
112
112 \times 112
112×112 的maks。

之前介绍的无论是二阶段还是一阶段实例分割都是从mask(局部mask or 全局mask)的层面来表征一个实例,在实例分割领域里,还有一类方法是从轮廓的角度来表征实例mask,这也更贴近人工用labelme进行分割标注的过程。本章仅介绍该方向思想最简洁且有效的算法PolarMask,还有一些方法,比如Curve-GCN和Deep Snakes,这些方法通常需要繁杂的算法流程(首先给定一个initial contour,网络对图片提取feature map,然后在contour上的每个节点提取一个feature,也就得到了定义在contour上的一组feature,紧接着通过GCN或者卷积给每个节点预测一个offset来变形contour)",在本章不做介绍。
PolarMask对目标检测网络FCOS进行了简单的扩展实现了目标检测和实例分割架构的统一。如下图所示:

因此,两者的网络结构的改动很小,即将FCOS的回归分支的回归量从 H × W × 4 H \times W \times 4 H×W×4 变为 H × W × n H \times W \times n H×W×n, n n n 代表的是回归实例轮廓的射线的条数。
除此之外,PolarMask和FCOS还有以下几点不同:
Polar centerness可以抑制(通过与classification score相乘)左下角的图中间所示的红色射线的这种射线出发点严重偏离实例中心点的情况。因为这种例子往往难以优化并且会产生低质量的mask。

对于Polar Mask 回归分支最常用的loss就是smooth-l1和IoU loss。 然而,smooth-l1损失忽略了同一目标36条射线之间的相关性,从而导致定位精度较低。 IoU损失能够将36条射线当做一个整体来优化,并且可以直接优化IoU指标(mAP内部依赖IoU进行mask排序)。 本文针对Polar Mask提出了一个Polar IoU Loss,如下图所示:


Query-based方法均是起源于目标检测网络DETR(参考以前写的一篇文章https://niecongchong.blog.csdn.net/article/details/118611442)),其通过初始化一组(如100个)可学习的query,并采用Transformer结构对query特征进行迭代更新,进而对每个query进行回归和分类,这样就可以对每张图输出固定数目的检测结果,最终,通过与GT之间的匈牙利匹配来实现label assignment。由于DETR收敛时间极慢(500epoch),在DETR之后有一系列方法针对其进行改进,Sparse RCNN,Deformable DETR,Adamixer,DINO是其中比较经典的工作。
本章所介绍的三篇文章中,QueryInst是Sparse RCNN的基础上的工作,SOLQ是Deformable DETR基础上的工作,Mask2former则是自成一家,且类似SOLO阉割掉了检测分支。
QueryInst之于Sparse RCNN的角色极其类似于Mask R-CNN之于Faster R-CNN,也就是说,QueryInst是结合Sparse RCNN和局部mask(RoI Align)的产物。
下图呈现了QueryInst的模型整体结构:

下面具体来讲一下box head和mask head的结构。

对于Box Head,在每个stage,给定初始化的Proposal boxes ( B , N , 4 ) (B, N, 4) (B,N,4)和Proposal Features ( B , N , 256 ) (B, N, 256) (B,N,256) 以及 FPN P 2 − P 5 P2-P5 P2−P5的特征图:
对于Mask Head,将batch中每张图片的所有正样本对应的 Proposal boxes 和 Proposal Features 拼接起来,得到 ( P , 4 ) (P, 4) (P,4)和 ( P , 256 ) (P, 256) (P,256) 作为输入:

这里是
D
y
n
C
o
n
v
m
a
s
k
DynConv^{mask}
DynConvmask的示意图,对于
D
y
n
C
o
n
v
m
a
s
k
DynConv^{mask}
DynConvmask和
D
y
n
C
o
n
v
b
o
x
DynConv^{box}
DynConvbox的区别,后者是输入样本量是
(
B
,
N
)
(B, N)
(B,N),前者仅包含正样本,样本量为
(
P
)
(P)
(P),从实现层面,只需要将
(
B
,
N
)
(B, N)
(B,N) reshape为
(
B
×
N
)
(B \times N)
(B×N),两者的shape便会保持一致了。
具体来讲,给定transformed object query with shape ( B , N , 256 ) (B, N, 256) (B,N,256)和ROI Align得到的bbox feature ( B , N , 256 , 7 , 7 ) (B, N, 256, 7, 7) (B,N,256,7,7),首先利用一个全连接层对 object query 进行映射得到两组1*1卷积参数 ( B , N , 256 ∗ 64 ) (B, N, 256*64) (B,N,256∗64) 和 ( B , N , 64 ∗ 256 ) (B, N, 64*256) (B,N,64∗256) ,进而使用这两组卷积参数对bbox feature进行卷积得到输出 ( B , N , 256 , 7 , 7 ) (B, N, 256, 7, 7) (B,N,256,7,7),如果是 D y n C o n v m a s k DynConv^{mask} DynConvmask,到这里就输出了,但是对于 D y n C o n v b o x DynConv^{box} DynConvbox,还需要将其reshape为 ( B , N , 256 ∗ 7 ∗ 7 ) (B, N, 256*7*7) (B,N,256∗7∗7)再进行通道降维得到输出后的object query ( B , N , 256 ) (B, N, 256) (B,N,256)。
SOLQ 在Deformable DETR基础上提出直接预测实例mask压缩编码来实现端到端的实例分割。
如下图所示,DETR的框架是利用query直接同时预测出 cls 和 box,本文新增了一个并行分支来预测mask的压缩编码。

SOLQ采用的是局部mask即输入到可逆压缩编码算法的mask label是经过RoI Cropping和RoI Align的局部mask,不过这里的输出尺寸并不是 28 × 28 28 \times 28 28×28,文中采用的RoI Align输出分辨率是 128 × 128 128 \times 128 128×128,能够一定程度解决Mask R-CNN边缘预测粗糙的问题。

SOLQ探索了Sparse Coding、PCA和DCT三种方式进行压缩编码。文章最终采用DCT进行压缩编码:

DCT压缩的原理参考:http://zhaoxuhui.top/blog/2018/05/26/DCTforImageDenoising.html

Mask2former的整体结构包含三个部分:


Transformer Decoder部分采用与DETR相似的query方式进行目标检测,即首先初始化N*256的query feature,进而采用1/32,1/16,1/8三个分辨率的特征对query feature进行迭代更新并进行最终的class和mask预测。本文的Transformer Decoder与DETR中使用的Decoder有两个区别,分别是(1)masked attention;(2)调换self-attention和cross-attention的顺序。除此之外,与DETR的不同的是,本文采用多尺度特征更新query,避免了DETR仅仅使用1/32特征图造成的小目标的检测效果较差。
Masked attention是针对DETR transformer Decoder中的cross-attention部分的改进。有研究表明,DETR类的模型收敛速度慢的部分原因是cross-attention中的全局上下文需要经过较长的训练时间才能使得注意力每次集中在目标附近,即局部上下文。本文考虑到在cross-attention中使用局部上下文能够加速模型的收敛,设计了masked attention模块,即每次仅使用特征图的前景区域的特征更新query。
两者的对比如下:
| Cross attention | ![]() |
|---|---|
| Masked attention | ![]() ![]() |
M l − 1 M_{l-1} Ml−1采用的是前一个transformer decoder层预测的mask,并使用阈值0.5进行截断得到的二值图。当某个像素的前一层被预测为背景,即 M l − 1 = 0 M_{l-1}=0 Ml−1=0,映射后的 M l − 1 = − ∞ \mathcal{M}_{l-1}=-\infty Ml−1=−∞,则经过softmax映射后,其该像素点的注意力便会下降为0。最终,便只有前景区域的像素点特征会影响query X l X_{l} Xl的更新。
作者文中描述:由于query feature是zero初始化的,第一层transformer Decoder直接上来就进行self-attention不会产生任何有意义的特征,因此先使用cross attention对query feature进行更新后再执行query feature内部的self-attention反而是一种更佳的做法。
但是实际上这个是有争议的,无论是DETR还是本文的query都是随机初始化的,并没有zero初始化的情况。

不同于语义分割,其最终是预测
C
l
a
s
s
∗
H
∗
W
Class*H*W
Class∗H∗W的特征图,并对其进行监督。然而,maskformer则需要预测
N
u
m
_
q
u
e
r
i
e
s
∗
H
∗
W
Num\_queries*H*W
Num_queries∗H∗W的特征图。由于query数目通常远大于类别数目,因此,这一类方法会导致巨大的训练内存占用。本文参考PointRend,在每个
H
∗
W
H*W
H∗W的特征图依据当前像素的不确定度选取K个采样点而不是整个特征图来计算损失函数。其中,不确定度的衡量是依据像素预测置信度得到的。
u
n
c
e
r
t
a
i
n
t
y
=
−
(
t
o
r
c
h
.
a
b
s
(
g
t
_
c
l
a
s
s
_
l
o
g
i
t
s
)
)
uncertainty=-(torch.abs(gt\_class\_logits))
uncertainty=−(torch.abs(gt_class_logits))
除了在计算损失函数的过程中运用了采样点,本文还在matcher匈牙利匹配时才用了采样点的策略。不同之处在于,在matcher过程中,还不清楚每个query和哪个gt匹配,因此无法同样采用不确定度进行选点无法保证能够选取到gt的前景区域,因此,在matcher过程是采用随机均匀分布采样了K个点,同一个batch所有的query和gt均是采样这K个点。

本来想在结尾处介绍一下自己进半年多的探索过方向和一些结果,后来想想,都是半成品,似乎没有拿出来的必要,都是过眼云烟,idea刚探索出来时觉得无比惊艳,越做越觉得平庸随大流,然后烂尾放弃,而后换个地方填坑。
这一载半,寻寻觅觅,终止于此。