原文链接:YOLACT 、 YOLACT++、YolactEdge小结_yx868xy的博客-CSDN博客
目录
一、YOLACT
YOLACT是2019年发表在ICCV上面的一个实时实例分割的模型,它主要是通过两个并行的子网络来实现实例分割的。
(1)Prediction Head分支生成各个anchor的类别置信度、位置回归参数以及mask的掩码系数;
(2)Protonet分支生成一组原型mask。
然后将原型mask和mask的掩码系数相乘,从而得到图片中每一个目标物体的mask。论文中还提出了一个新的NMS算法叫Fast-NMS,和传统的NMS算法相比只有轻微的精度损失,但是却大大提升了分割的速度。
Mask R-CNN,即“先检测后分割”的方法,首先定位到目标物体的边框,然后在边框内分割目标物体。而YOLACT是一个one-stage模型,它和two-stage的模型(Mask R-CNN)相比起来,速度更快,但是精度稍差一些。YOLACT模型的框架如图所示。
1、Backbone:
YOLACT模型输入的图像大小为550*550,采用的Backbone为ResNet101,源代码中作者还使用了ResNet50和DarkNet53网络结构。ResNet的卷积模块一共有5个从conv1,conv2_x到conv5_x,分别对应图1 YOLACT模型中的C1,C2到C5。YOLACT和SSD一样采用了多尺度的特征图, 从而可以检测到不同尺寸的物体,也就是在大的特征图上检测小的物体,在小的特征图上检测大的物体。
2、FPN:
图1中的P3-P7是FPN网络,它是由C5经过1个卷积层得到P5,然后对P5采用双线性插值使特征图扩大一倍,与经过卷积的C4相加得到P4,再采用同样的方法即可得到P3。再然后,对P5进行卷积和下采样得到P6,对P6进行同样的卷积和下采样得到P7,从而建立FPN网络。接下来是并行的操作。P3 被送入 Protonet,P3-P7 也被同时送到 Prediction Head 中。(采用FPN的好处就是模型学习到特征更丰富,更有利于分割不同大小的目标物体。)
3、Protonet 分支:
Protonet分支的网络结构如下图3所示,它是由由若干卷积层组成。其输入是 P3,其输出的mask维度是 138 * 138 * k (k=32),即 32 个 prototype mask,每个大小是 138 * 138。
4、Prediction Head分支:
Prediction Head分支的网络结构如图4所示,它是在RetinaNet的基础上改进得到的,采用共享卷积网络,从而可以提高速度,达到实时分割的目的。它的输入是 P3-P7 共五个特征图,每个特征图先生成anchor,每个像素点生成3个anchor,比例是 1:1、1:2和2:1。五个特征图的anchor基本边长分别是24、48、96、192和384。基本边长根据不同比例进行调整,确保 anchor 的面积相等。
为了便于理解,接下来以 P3 为例进行解释说明。假设P3的维度是 W3 * H3 * 256,那么它的anchor个数就是 a3 = W3 * H3 * 3。接下来 Prediction Head 为其生成三类输出:
类别置信度,由于 COCO 中共有 81 类(包括背景),所以其维度为 a3 * 81;
位置偏移,维度为 a3 * 4;
mask 置信度,维度为 a3 * 32。
对 P4-P7 进行的操作是相同的,最后将这些结果拼接起来,标记 a = a3 + a4 + a5 + a6 + a7,得到:
全部类别置信度,由于 COCO 中共有 81 类(包括背景),所以其维度为 a * 81;
全部位置偏移,维度为 a * 4;
全部 mask 置信度,维度为 a * 32。
5、Fast NMS:
通过Prediction Head分支网络后会得到很多anchor,可以在anchor的位置加上位置偏移得到RoI位置。由于RoI存在重叠,NMS 是常用的筛选算法,而本文提出了一种新的筛选算法叫Fast-NMS,在保证精度的前提下,减少了筛选的时间。
接下来,通过举例详细介绍Fast NMS算法。假设我们有5个RoI,对于 person这一类,按分类置信度由高到低排序得到b1、b2、b3、b4和 b5。接下来通过矩阵运算得到5个ROI相互之间的IoU,假设结果如下图所示:
可以看出这是一个对称矩阵,接下来将这个对称阵的对角线和下三角元素删掉,得到结果如下图所示:
接下来对每一列取最大值,得到结果[-, 0.8, 0.6, 0.6, 0.4]。假设阈值为0.5,那么IoU超过0.5的RoI需要舍弃掉。根据刚才得到的结果,b2、b3和b4对应的列都超出了阈值,所以这三个RoI会舍去。这样做的原因是,由于每一个元素都是行号小于列号,而序号又是按分类置信度从高到低降序排列的,因此任一元素大于阈值,代表着这一列对应的 RoI 与一个比它置信度高的 RoI 过于重叠了,需要将它舍去。
6、mask系数
典型的基于Anchor的检测模型会为每个Anchor预测4个值用于表征box信息,和C个值用于表征类别得分,共(4+C)个值。YOLACT为 每个Anchor预测(4+C+k)个值,额外k个值即为mask系数。
另外作者认为,为了能够通过线性组合来得到最终想要的mask,能够从最终的mask中减去原型mask是很重要的。换言之就是,mask系数必须有正有负。所以,在mask系数预测时使用了tanh函数进行非线性激活,因为tanh函数的值域是(-1,1).
7、mask合成
通过基本的矩阵乘法配合sigmoid函数来处理两分支的输出,从而合成mask。Prediction Head分支得到的mask coefficient和Protonet分支得到的 prototype mask 做矩阵乘法
其中,P是h×w×k的原型mask集合,C是n×k的系数集合,代表有n个通过NMS和阈值过滤的实例,每个实例对应有k个mask系数。
8、Crop & Threshold
为了改善小目标的分割效果,在推理时会首先根据检测框进行裁剪,再阈值化。而在训练时,会使用ground truth框来进行裁剪,并通过除以对应ground truth框面积来平衡loss尺度。
Crop指的是将边界外的mask清零,训练阶段的边界是ground truth bounding box,评估阶段的边界是预测的bounding box。Threshold指的是以0.5为阈值对生成的 mask进行图像二值化处理。
9、Loss:
YOLACT模型使用的loss是由边框的分类loss、边框的位置回归loss同SSD和mask损失为预测mask和ground truth mask的逐像素二进制交叉熵构成。
其中mask loss在计算时,因为mask的大小是138*138,需要先将原图的mask数据通过双线性插值缩小到这一尺寸。
原文还有YOLACT++、YolactEdge介绍:
YOLACT 、 YOLACT++、YolactEdge小结_yx868xy的博客-CSDN博客
二、个人总结:
我一开始的时候是接触目标检测,比如yolov5。然后学习到yolov,其整合了实例分割,在 C++ 部署的时候,看不懂实例分割的后处理,所以才在网上找到这篇优秀的总结。
所以我的关注点是:
1、Protonet 分支:
输入是P3,输出维度为138*138*k(k=32),即32个prototype mask,每个大小是138*138
2、Prediction Head分支
输入为P3-P7共5个特征图,
输出是:
类别置信度,由于 COCO 中共有 81 类(包括背景),所以其维度为 a * 81,a表述anchor数量;
位置偏移,维度为 a * 4;
mask 置信度,维度为 a * 32。
3、mask合成
Prediction Head分支得到的mask coefficient和Protonet分支得到的 prototype mask 做矩阵乘法,得到Assembly:
4、Crop & Threshold
为了改善小目标的分割效果,在推理时会首先根据检测框进行裁剪,再阈值化。而在训练时,会使用ground truth框来进行裁剪,并通过除以对应ground truth框面积来平衡loss尺度。
Crop指的是将边界外的mask清零,训练阶段的边界是ground truth bounding box,评估阶段的边界是预测的bounding box。Threshold指的是以0.5为阈值对生成的 mask进行图像二值化处理。