非极大值抑制 (Non-Maximum Suppression, NMS)

目录

NMS 基本过程

  • 当前的物体检测算法为了保证召回率,对于同一个真实物体往往会有多于 1 个的候选框输出。由于多余的候选框会影响检测精度,因此需要利用 NMS 过滤掉重叠的候选框,得到最佳的预测输出
    非极大值抑制 (Non-Maximum Suppression, NMS)

在上图中,候选框 C 的得分比 A 要低,在评测时,C 候选框会被当做一个 False Positive 来看待,从而降低模型精度。实际上,由于候选框 A 的质量要比 C 好,理想的输出是 A 而不是 C,我们希望能够抑制掉候选框 C


NMS 方法

  • NMS 方法简单有效,并且对检测结果至关重要,在物体检测算法中有着广泛的应用。基本的 NMS 方法利用得分高的边框抑制得分低且重叠程度高的边框,因此涉及以下两个量化指标
    • 预测得分:NMS 假设一个边框的预测得分越高,这个框就要被优先考虑,其他与其重叠超过一定程度的边框要被舍弃,非极大值即是指得分的非极大值
    • IoU:IoU 用于评价两个边框的重合程度。如果两个边框的 IoU 超过一定阈值时,得分低的边框会被舍弃。阈值通常会取 0.5 或者 0.7

NMS 方法的实现

def nms(bboxes, scores, thresh=0.5):
	"""
	Args:
		bboxes: 所有预测框的左上点坐标、右下点坐标 (图片的最左上点坐标为 [0, 0])
		scores: 所有预测框的得分
		thresh: 设定的 IoU 阈值
	"""
    x1, y1 = bboxes[:,0], bboxes[:,1]	# 所有预测框的左上角坐标
    x2, y2 = bboxes[:,2], bboxes[:,3]	# 所有预测框的右下角坐标
    # 计算每个 box 的面积
    areas = (x2 - x1) * (y2 - y1)
    # 对得分进行降序排列,order 为降序排列的索引
    _, order = scores.sort(0, descending=True)
    # keep 保留了 NMS 留下的边框 box
    keep = []

    while order.numel() > 0:
        if order.numel() == 1:   # 保留框只剩一个         
        	i = order.item()
            keep.append(i)
            break
        else:
            i = order[0].item()	 # 保留 scores 最大的那个框 box[i]
            keep.append(i)
        # 巧妙利用 tensor.clamp 函数求取每一个框与当前框的最大值和最小值
        xx1 = x1[order[1:]].clamp(min=x1[i])	# 取 Anchor[i] 与其余 Anchors 的最大 x1, y1
        yy1 = y1[order[1:]].clamp(min=y1[i])	
        xx2 = x2[order[1:]].clamp(max=x2[i])	# 取 Anchor[i] 与其余 Anchors 的最小 x2, y2
        yy2 = y2[order[1:]].clamp(max=y2[i])
        # 求取每一个框与当前框的重合部分面积
        inter = (xx2 - xx1).clamp(min=0) * (yy2 - yy1).clamp(min=0)
        # 计算每一个框与当前框的 IoU
        iou = inter / (areas[i] + areas[order[1:]] - inter + 1e-9)
        # 保留 IoU 小于阈值的边框索引 (nonzero 用于返回非零元素的索引)
        idx = (iou <= threshold).nonzero().squeeze()
        if idx.numel() == 0:
            break
        # 这里的 +1 是为了补充 idx 与 order 之间的索引差
        order = order[idx+1]

	# 返回保留下的所有边框的索引值
    return torch.LongTensor(keep)

NMS 的缺陷

  • (1) 最大的问题就是将得分较低的边框强制性地去掉,如果物体出现较为密集时,本身属于两个物体的边框,其中得分较低的也有可能被抑制掉,从而降低了模型的召回率
  • (2) 阈值难以确定。过高的阈值容易出现大量误检,而过低的阈值则容易降低模型的召回率,这个超参很难确定
  • (3) 将得分作为衡量指标。NMS 简单地将得分作为一个边框的置信度,但在一些情况下,得分高的边框不一定位置更准,因此这个衡量指标也有待考量
  • (4) 速度:NMS 的实现存在较多的循环步骤,GPU 的并行化实现不是特别容易,尤其是预测框较多时,耗时较多

针对上述问题陆续产生了一系列改进的方法,如 Soft NMSSofter NMSIoU-Net

抑制得分: Soft NMS

加权平均: Softer NMS

定位置信度: IoU-Net

参考文献

  • 《深度学习之 PyTorch 物体检测实战》
上一篇:[译]. NET 6 新增API - 下


下一篇:1063 Set Similarity (25分)