Non-Maximum Suppression (NMS)
非极大值抑制 (NMS) 会移除重叠的重复框,使每个对象只保留一个检测结果。了解其工作原理、调优方法以及无需 NMS 的模型。
非极大值抑制 (NMS) 是一个后处理步骤,用于将检测器原始且相互重叠的预测结果转换为每个物体一个框。密集型目标检测模型会为每张图像评估数千个候选边界框,而且通常有多个相邻候选框会以略有不同的位置和分数同时检测到同一个物体。NMS 会保留每个重叠簇中置信度最高的框,并抑制其余框;它使用交并比 (IoU)判断框之间的重叠是否足以将其视为重复框。
非极大值抑制的工作原理#
标准版本的贪心 NMS 会先丢弃低于置信度阈值的候选框,并按分数对剩余框排序。随后,它保留排名最高的框,移除所有与该框的 IoU 超过 IoU 阈值的框,再从剩余框中选出分数最高的框并重复上述过程,直到没有候选框为止。检测器通常按类别分别运行 NMS,因此行人框不会抑制与之重叠的自行车框。
torchvision 的 nms实现了单类别的贪心 NMS,并返回所保留框的索引,结果按分数排序。
import torch
from torchvision.ops import nms
# 候选框采用 [x1, y1, x2, y2] 格式,每个框对应一个置信度分数
boxes = torch.tensor(
[
[100, 100, 200, 200], # A
[105, 105, 195, 195], # B:与 A 几乎重复(IoU 为 0.81)
[300, 300, 400, 400], # C:独立物体
],
dtype=torch.float32,
)
scores = torch.tensor([0.90, 0.80, 0.95])
# 抑制所有与分数更高且已保留框的 IoU 超过 0.5 的框
keep = nms(boxes, scores, iou_threshold=0.5)
print(keep.tolist())输出为 [2, 0]:C 框分数最高,因此最先保留;A 框与 C 框不重叠,因此也会保留;B 框与 A 框的 IoU 为 0.81,因此会被移除。
调整阈值#
置信度阈值会在抑制开始前移除较弱的候选框。IoU 阈值则决定多大的重叠才算重复。当阈值过低时,彼此靠近的两个真实物体(例如人群中的行人)会合并为一个检测结果,导致召回率下降。当阈值过高时,重复框会被保留,导致精确率下降。类别无关 NMS允许任何框抑制其他类别的框,可在模型将同一物体预测为两个相似类别(例如“汽车”和“卡车”)时去除重复标签。
NMS 的局限性#
- 拥挤场景:单一固定的 IoU 阈值无法区分重复框和与第一个物体确实重叠的第二个物体,因此严重遮挡的物体会被抑制。
- 固定启发式规则:阈值由人工选择,位于训练网络之外,并非从数据中学习得到。
- 延迟与部署:贪心循环在网络运行后执行,其开销会随候选框数量增加,从而增加推理延迟。无法将 NMS 嵌入模型计算图的导出格式会输出原始候选框,因此应用程序必须自行运行 NMS。
NMS 变体与无 NMS 检测#
Soft-NMS会根据重叠程度降低重叠框的分数,而不是直接删除这些框,因此在拥挤场景中能够找回更多物体。DIoU-NMS 与距离交并比损失一同提出,它还会考虑框中心之间的距离,因此中心相距较远的两个框不太容易被抑制。
端到端检测器会彻底移除这一步骤。DETR通过预测结果与标签之间的一对一匈牙利匹配进行训练,因此每个目标恰好对应一个预测结果;YOLOv10则为实时 YOLO 模型引入了一对一检测头。YOLO26会训练两种检测头,并默认应用 NMS,因为其一对多检测头的得分略高:YOLO26n 在 COCO上的 mAP50-95为 40.9,而一对一检测头为 40.1。传入 nms=False 可选择一对一检测头,它每张图像最多输出 300 个最终边界框,无需执行 NMS;端到端检测指南展示了如何进行预测和导出。










