MMDet逐行解读之MaxIOUAssigner 您所在的位置:网站首页 max忽略背面在哪里 MMDet逐行解读之MaxIOUAssigner

MMDet逐行解读之MaxIOUAssigner

2024-02-01 06:42| 来源: 网络整理| 查看: 265

文章目录 前言1、关闭match_low_quality参数2、开启match_low_quality参数总结

前言

  本篇是MMdet逐行解读第二篇,代码地址:mmdet/bbox/assigners/max_iou_assigner.py。由于源码assigner的输入参数多而且不易理解,因此本文是从由简到难的顺序逐步分析各个参数的作用。历史文章如下:  AnchorGenerator解读

1、关闭match_low_quality参数

 我们首先构造了一个match_low_quality的assigner,该参数含义后面会讲。这一节主要分析pos_iou_thr和neg_iou_thr两个参数。另外,我又人为的分别构建了四个预测框和四个GT。

import torch from mmdet.core.bbox import build_assigner # maxIOU模块调试 config = dict( # 最大 IoU 原则分配器 type='MaxIoUAssigner', # 正样本阈值 pos_iou_thr=0.5, # 负样本阈值 neg_iou_thr=0.4, # 正样本阈值下限 min_pos_iou=0., # 仅当开启匹配低质量时该阈值才发挥作用 match_low_quality = False, #先为FALSE # 忽略 bboes 的阈值,-1表示不忽略 ignore_iof_thr=-1) assigner = build_assigner(config) # 构建一个分配器 bboxes = torch.Tensor([[0, 0, 10, 10], [10, 10, 20, 20], [3, 3, 6, 6],[2, 2, 3, 3]]) gt_bboxes = torch.Tensor([[0, 0, 10, 9], [10,10,19,19], [10,10,15,15],[3,3,4,4]]) res = assigner.assign(bboxes, gt_bboxes) print(res.gt_inds) # tensor([1, 2, 0, 0])

 首先从运行结果来看,bboxes和gt_bboxes的匹配结果为[1,2,0,0]。其含义是指:第一个bbox匹配第一个gt,第二个bbox匹配第二个gt,第三四个bbox匹配背景(0表示背景)。接下来,我们分析源码:  

overlaps = self.iou_calculator(gt_bboxes, bboxes) # 创建一个-1的tensor,用来保存匹配的结果。-1表示当前bbox为忽略样本 assigned_gt_inds = overlaps.new_full((num_bboxes, ), -1, dtype=torch.long) # 从列方向看分别得到每个bbox和哪个gtbox的iou最大 max_overlaps, argmax_overlaps = overlaps.max(dim=0) # 将iou低于阈值[0,0.4]的置为0,即处于该范围阈值的bbox为背景。 if isinstance(self.neg_iou_thr, float): assigned_gt_inds[(max_overlaps >= 0) & (max_overlaps = self.pos_iou_thr assigned_gt_inds[pos_inds] = argmax_overlaps[pos_inds] + 1

  其实实际执行的代码只有上述几行,注释我差不多已经注明了,我这里画个图阐述下,读者可以结合注释和图自行理解。首先计算每个gt和所有bbox的iou,得到一个4*4的iou矩阵overlaps。 在这里插入图片描述

 之后再dim=0上执行max操作,得到的max_overlaps=[0.9,0.81,0.11,0.01],argmax_overlaps=[0,1,3,0]。也就是图中带颜色的字体。之后,绿色字体由于0.5故分为正样本,但是最终的结果向量assigned_gt_inds需要存储每个bbox和第几个gt匹配,以bbox1为例,是和index=0的gt匹配,但0已被背景占用了,故需要+1。即bbox1和第一个gt1匹配。故最终结果向量就是代码执行出的[1,2,0,0]。

2、开启match_low_quality参数

  上节我们是关闭了该参数,从结果上来说,总共有四个gt,但是最终只有两个gt匹配成功。有两个gt未进行匹配。从保证召回率角度讲,这样肯定不合理。因此,assigner又设置了match_low_quality参数,即尽量要使所有gt都有一个anchor。这次我们开启该参数来学习该参数的作用,需要额外注意,该参数需要和min_pos_iou参数搭配使用。同理,先看执行效果:

import torch from mmdet.core.bbox import build_assigner # maxIOU模块调试 config = dict( # 最大 IoU 原则分配器 type='MaxIoUAssigner', # 正样本阈值 pos_iou_thr=0.5, # 负样本阈值 neg_iou_thr=0.4, # 正样本阈值下限 min_pos_iou=0., # 仅当开启匹配低质量时该阈值才发挥作用 match_low_quality = True, # 开启该参数 # 忽略 bboes 的阈值,-1表示不忽略 ignore_iof_thr=-1) assigner = build_assigner(config) # 构建一个分配器 bboxes = torch.Tensor([[0, 0, 10, 10], [10, 10, 20, 20], [3, 3, 6, 6],[2, 2, 3, 3]]) gt_bboxes = torch.Tensor([[0, 0, 10, 9], [10,10,19,19], [10,10,15,15],[3,3,4,4]]) res = assigner.assign(bboxes, gt_bboxes) print(res.gt_inds) # tensor([1, 3,4,0])

 开启后执行结果成了[1,3,4,0],即第二个bbox和第三个gt匹配,第三个bbox和第四个匹配,让人一头雾水。下面分析下代码:

''' overlaps = self.iou_calculator(gt_bboxes, bboxes) # 创建一个-1的tensor,用来保存匹配的结果。-1表示当前bbox为忽略样本 assigned_gt_inds = overlaps.new_full((num_bboxes, ), -1, dtype=torch.long) # 从列方向看分别得到每个bbox和哪个gtbox的iou最大 max_overlaps, argmax_overlaps = overlaps.max(dim=0) # 将iou低于阈值[0,0.4]的置为0,即处于该范围阈值的bbox为背景。 if isinstance(self.neg_iou_thr, float): assigned_gt_inds[(max_overlaps >= 0) & (max_overlaps < self.neg_iou_thr)] = 0 #若iou处于[0.5,1]范围的,将bbox置为ind+1,表示bbox和该gt匹配 pos_inds = max_overlaps >= self.pos_iou_thr assigned_gt_inds[pos_inds] = argmax_overlaps[pos_inds] + 1 ''' #获取每个gt和哪个bbox的iou最大。 gt_max_overlaps, gt_argmax_overlaps = overlaps.max(dim=1) if self.match_low_quality: # 遍历每个gt for i in range(num_gts): # 若阈值超过0. if gt_max_overlaps[i] >= self.min_pos_iou: # 将所有gt均进行匹配 if self.gt_max_assign_all: # 找到和gt最大iou相等的overlaps的位置 max_iou_inds = overlaps[i, :]==gt_max_overlaps[i] # 同理+1 assigned_gt_inds[max_iou_inds] = i + 1

  上述标绿代码就是未开启参数的效果,即执行完注释代码后匹配结果为[1,2,0,0]。下面分析未注释部分: 在这里插入图片描述  首先标红的字体就是gt_max_overlaps。即每个gt和哪个bbox的iou最大。然后遍历每个gt,若最大iou>min_pos_iou,则将该bbox和gt进行匹配。故bbox1显然还和gt1匹配,bbox2还和gt2匹配,但是遍历到第三个gt3时候,由于其还是和bbox2的iou最高,故将该bbox2匹配改了gt3,把gt2给覆盖掉了。即此时的assigned_gt_inds由[1,2,0,0]变成了[1,3,0,0]。即Bbox2匹配给了一个低质量gt。 之后,遍历gt4的时候,将其匹配给bbox3,也就得到了最终匹配结果assigned_gt_inds = [1,3,4,0]。从最终效果上看,确实能够保证将所有gt匹配上,但是有可能后匹配的把前面iou高的匹配给覆盖掉,导致低质量匹配产生。

总结

  在一阶段算法或者RPN阶段,可以开启低质量匹配,保证最大的召回率。但是在第二阶段RoI Head中要确保准确率,就不开启低质量匹配了。若有问题欢迎+vx:wulele2541612007,拉你进群探讨交流。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有