影醉阏轩窗

衣带渐宽终不悔,为伊消得人憔悴。
扩大
缩小

二阶段目标检测总结

概述:

最新几年的论文都是在单阶段Transform上进行发掘提升,基本上2020-2021年二阶段论文全军覆没,这篇博文也是总结2016-2019年的发展,最后一篇CenternetV2比较特殊,不能完全算作传统意义的二阶段网络。

目前什么地方还使用二阶段论文?

  1. 比赛场景,经常使用FasterRCNN的变种+其它网络进行联合预测
  2. 目标比较小的场景(使用较少,一般用anchor-free、增大输入去代替、分割图像检测)
  3. 辅助一阶段使用,和(2)类似但不同。比如检测远距离人形+人脸,方案一:先检测人,后检测人脸,两个都是OneStage。方案二:使用TwoStage网络,第一阶段检测人形,第二阶段检测人脸。当然只有第二类别是第一类别的从属,且是唯一关系才能进行!

一. FasterRCNN

以torchvision给出的demo为例子:

  1. 第一阶段,和基础SSD等一阶段操作类似,但是这一阶段会立刻输出候选区域

https://github.com/pytorch/vision/blob/183a722169421c83638e68ee2d8fc5bd3415c4b4/torchvision/models/detection/rpn.py#L29

  1. 将候选区域从FPN输出的feature上抠出来

  2. 使用ROIPooling对齐候选特征的大小

https://github.com/pytorch/vision/blob/183a722169421c83638e68ee2d8fc5bd3415c4b4/torchvision/ops/poolers.py#L83-L277

  1. 第二阶段,直接进行FC细化Reg/Cls,当然这里只能是一个候选区域最多一个目标。
class FastRCNNPredictor(nn.Module):
    """
    Standard classification + bounding box regression layers
    for Fast R-CNN.
    Args:
        in_channels (int): number of input channels
        num_classes (int): number of output classes (including background)
    """

    def __init__(self, in_channels, num_classes):
        super(FastRCNNPredictor, self).__init__()
        self.cls_score = nn.Linear(in_channels, num_classes)
        self.bbox_pred = nn.Linear(in_channels, num_classes * 4)

    def forward(self, x):
        if x.dim() == 4:
            assert list(x.shape[2:]) == [1, 1]
        x = x.flatten(start_dim=1)
        scores = self.cls_score(x)
        bbox_deltas = self.bbox_pred(x)

        return scores, bbox_deltas
image-20210624170757195

注释:

  • 最后一步FC是参考anchor的做法,首先想到的是\(self.bbox\_pred = nn.Linear(in\_channels,4)\) ,因为已经使用class进行了过滤,没有必要再把regression去使用class再去过滤一遍。当然使用class对回归进行区分,这效果肯定优于单个回归。
  • 我们再进一步延伸,如果在不同的class之下,再使用一种手段(长宽、面积、anchor等)对其进一步划分,比如:假设候选区域数量不变为 \(P\),类别为两类(人形、人脸),进一步使用anchor限制(两个anchor,5和20,比例4倍以内使用5,超过4倍使用20),这样会不会更精细?
  • 上一步我们限制了候选区域数量,能不能使用输入多个不同组的候选区域,后面连接多个不同的predict?这就是后续改进cascadeRCNN的由来。

二. MaskRCNN

  1. 第一阶段使用FasterRCNN,RPN网络都相同
  2. 第二阶段输出多一个分支 \(K\times m\times m\) , 其中 \(K\) 表示种类,\(m\) 表示输出分辨率

注意: 最后输出的mask大小是固定的,设置大小得根据实际种类而定。这个mask分支和FCN有点区别,这里使用K个feature,然后直接进行二分类操作,而FCN使用单个feature进行多分类操作,目前检测的分类loss都是进行单独的二分类操作。

image-20210624175016872

三. CascadeRCNN

  1. 第一阶段和FasterRCNN完全一样

  2. 第二阶段使用多个RoiHead层进行级联

下图完全显示了CascadeRCNN的由来

  • 下图(C)仅仅在前向计算的时候使用级联finetune操作,精度也得到一定提升,但是有两个缺陷。1)使用共享的Head-H1,不仅时间没降低,而且参数效果还不好。所以在端侧单阶段目标检测中,一般不使用共享的头,虽然参数减少了,但是计算量一点未变,所以都使用不共享的头。2)都是固定的,不能进行训练,后面的阶段已经处于过拟合状态。
  • 下图(d)最大的缺点就是候选区域固定,非常容易过拟合。有一个优点,后面的stage仅仅进行分类而不进行reg,这是cascade未考虑的。但是,分类分支花费的代价很小,基本影响不到大局,所以讨论的人很少。
  • 下图(b)融合了两者的优点,1)可训练。2)不共享。3)候选区域不同。
image-20210624175552697

四. Libra RCNN

未改变实际的流程结构,文章从均衡的角度对各个模块进行改进。

  1. \(feature\) 均衡,使用FPN、PAN、BiFPN进行互相链接
  2. 采样均衡,原始SSD分配使用Max-IOU,采样使用Random-Sample
  3. loss均衡,原始SSD直接使用独立的分支进行计算

IOU-Balance采样,下图是困难负样本(\(Iou<0.5\) 称为困难负样本)的Iou分布,其中64%样本\(Iou>0.05\),36%的样本\(Iou<0.05\),注意这里是百分比图,不是个数量图!!!下图中使用随机采样,会导致70%的样本\(Iou<0.05\) ,这明显是不符合下图的困难负样本的分布图的。如何将下附图的每个方格采样比例趋于平衡?很明显的想到还是使用方格将IOU进行区域划分(直方图的表示方法),然后按照一定比例进行采样即可。论文给出一些控制参数,使得表达更为通俗易懂。

image-20210628102008413

关于feature部分的平衡,这部分有点玄,意义不大。。。

关于loss的平衡,主要对smooth-L1进行调整,文章分析了loss的贡献率,\(loss<1.0\) 贡献30%,相反贡献70%,既然要平衡,那就要提升 \(loss<1.0\) 的梯度(loss占比),其实和focal-loss一样,都是提升困难样本的比重。

\[L_{b}(x)=\left\{\begin{array}{ll} \frac{\alpha}{b}(b|x|+1) \ln (b|x|+1)-\alpha|x| & \text { if }|x|<1 \\ \gamma|x|+C & \text { otherwise } \end{array}\right. \]

image-20210628105740276

五. GridRCNN

  1. 第一阶段和FasterRCNN完全一样
  2. 分类分支相同,回归分支使用关键点

从当前的角度看,这篇论文较为简单,属于简化版的anchor-free模型,因为是对候选区域进行操作,不需要anchor的匹配,不需要进行nms等操作。和top-bottom的pose估计一模一样!!

如果把第一阶段也使用关键点去估计,那这篇二阶段文章就完全是anchor-free+pose的文章了。

image-20210628114513211

需要注意一点,经常出现候选区域把目标截断(二阶段网络都存在的问题),那关键点就不存在(使用0表示),但是对于定位就很不准确。最简单的方式是直接扩大候选区域的截图范围,作者尝试这种方案效果不理想。作者采用候选区域不变,仅对候选回归框做扩大。如下图所示,绿色是目标框,白色实线是候选框,输入白色实线候选区域,在白色虚线的基础上进行回归。

image-20210628114708997

六. GridRCNN-V2

  1. 第一阶段和FasterRCNN完全一样
  2. 第二阶段和GridRCNN-V1基本相同

这篇论文主要是对第一版本的速度进行改进:

  • keypoint branch 从\(56\times56\)降低到\(28 \times 28\) ,论文说这样做不仅会加快速度,而且还会提高精度。之前在关键点上试验,使用期望定位会有精度损失。
  • 减小候选区域的大小,降低channels
  • 联合整个batch图像进行计算。之前使用for循环,单次计算单张图像,对于目标数量非常敏感,现在是对batch进行一次计算。
  • NMS仅进行一次
image-20210628143308421

七. Double-Head RCNN

  1. 第一阶段和FasterRCNN完全一样
  2. 第二阶段ROI-Head使用多个头进行预测

此想法类似多模型W联合预测WBF,使用全连接头+卷积头联合预测,唯一注意的是cls分支使用联合loss,而reg分支使用单独预测。

\[s=s^{f c}+s^{c o n v}\left(1-s^{f c}\right)=s^{c o n v}+s^{f c}\left(1-s^{c o n v}\right), \]

利用联合预测效果绝对有所提升,但是额外的分支预测占用较多的资源,如何做到Trade-Off是关键。

image-20210628192146045

八. CenterNetV2

在刚开始的概述(3)中,表达了一种二阶段网络的特殊应用,这篇文章将此应用表述成一种方案:我们可以使用任何一阶段的网络作为RPN层(包括anchor-based、anchor-free操作),后面ROI阶段可以使用任何之前的第二阶段网络。这不就是集合前人的大杂烩?搞不懂为啥没有使用YOLOV4作为第一阶段进行比较

image-20210628171112266

进一步引申:

  • 类似人形+人脸的检测组合(概述3)
  • 关键点检测模型(Top-Bottom),比如人体关键点估计,可以直接使用二阶段网络。

posted on 2021-06-28 17:24  影醉阏轩窗  阅读(1593)  评论(0编辑  收藏  举报

导航

/* 线条鼠标集合 */ /* 鼠标点击求赞文字特效 */ //带头像评论