本节摘要:目标检测在"是什么"之外多答一句"在哪":输出若干边界框,各带类别与置信度。支撑它的通用货币是交并比(IoU)——预测框与真值框的重叠度;筛选重叠候选的手段是非极大值抑制(NMS);汇总指标是平均精度(mAP)。本节把 IoU 与 NMS 各手算一遍,再巡检两段式与单段式两条检测流水线的取舍。
分类流水线的输出是一个标签,可自动驾驶问的是"第几车道有行人、离我多远"——没有位置就是没答案。检测的最小改法是让网络对每个目标多回归四个数:框的左上与右下坐标。麻烦在评估:框差三个像素算对,偏半个车身算错,"完全相等"的判据没法用。行业选定的通用货币叫交并比:两框交集面积除以并集面积,完全重合为一、毫无交集为零,阈值(常用 0.5)一划,"算不算检测到"就有了客观裁断。
阅读完本节,你应当能够:
预测框与真值框的四个坐标一摆,交集是两者重叠的矩形,并集是两框覆盖的总面积(交集只算一次)。取一组可手算的数:真值框 (100,100,200,200)(面积一万),预测框 (120,120,200,220)(面积八千)。交集是 (120,120,200,200),宽 80 高 80,面积六千四;并集 = 一万加八千减六千四 = 一万一千六;IoU = 6400 ÷ 11600 ≈ 0.552——超过 0.5 的常用门槛,这一预测记为命中。
def iou(a, b): ax1, ay1, ax2, ay2 = a bx1, by1, bx2, by2 = b ix1, iy1 = max(ax1, bx1), max(ay1, by1) # 交集左上 ix2, iy2 = min(ax2, bx2), min(ay2, by2) # 交集右下 inter = max(0, ix2 - ix1) * max(0, iy2 - iy1) area_a = (ax2 - ax1) * (ay2 - ay1) area_b = (bx2 - bx1) * (by2 - by1) return inter / (area_a + area_b - inter) box_truth = (100, 100, 200, 200) box_pred = (120, 120, 200, 220) print(round(iou(box_truth, box_pred), 3)) # 0.552
检测网络内部其实不直接回归四个绝对坐标,而是在预设的"锚框"上微调:图像上密密麻麻铺不同大小长宽比的参考框,网络学每个锚框的修正量与"这里有没有目标"的置信度。一张图几千上万个锚框,绝大多数是背景——检测头本质上是一个"逐锚框的分类加回归",骨干照旧是第三章那批卷积特征。

几千个锚框必然对同一目标重复报信:一只猫头顶上摞着几十个高分框。非极大值抑制的规则朴素有效:按置信度从高到低排队,最高分先保留,其余与它 IoU 超过阈值的全部撤销;再从剩下的队里重复,直到清空。
def nms(boxes, thr=0.5): boxes = sorted(boxes, key=lambda b: -b[4]) # 按置信度排队 keep = [] while boxes: best = boxes.pop(0) keep.append(best) # 队首留任 boxes = [b for b in boxes if iou(best[:4], b[:4]) < thr] # 重叠者出局 return keep cands = [(100, 100, 200, 200, 0.95), (120, 120, 200, 220, 0.80), # 与前者 IoU 0.552,会被抑制 (400, 150, 470, 260, 0.90)] # 远处的另一目标 print("保留框数:", len(nms(cands))) # 2
流水线架构分两代。两段式(R-CNN 家族)先由区域建议网络挑出"可能有货"的候选,再对每个候选精细分类与修框:精度高、速度慢,适合离线与高要求场景。单段式(YOLO、SSD)把整图一次性铺进网格,每个格子直接报框:把检测当回归一路算完,速度快到能上实时视频,小目标与密集场景精度略让。选型的分水岭通常就一句话——要不要实时。
指标端把 IoU 与排序合成为 mAP:按 IoU 阈值判每个预测的对错,再按置信度排序统计不同召回水平下的精度并取平均,最后按类别平均。它比准确率苛刻得多——框不准、排序乱、漏检,任何一项都会在 mAP 上现形。
问:锚框铺多少合适?答:常见配置是每个位置三四种尺度乘三四种长宽比、共九到十六个锚,整图几千到几万个候选;锚越多覆盖越好、显存与负样本也越多,实践从默认配置起步再按目标尺寸分布微调。问:软性 NMS 是什么?答:传统 NMS 把重叠框直接删零,密集目标会被误杀;软性版本改为按 IoU 降分不删框,拥挤场景(货架、车流)的召回能明显回血,代价是阈值多一个要调。
⚠️ 常见坑:把 IoU 阈值当固定真理。密集小目标场景 0.5 的门槛会把贴得近的两个真值判重,物流包裹、车牌字符这类任务常要用 0.55 到 0.75 的高阈值口径(COCO 的 mAP 正是多点平均)。
框是目标级的答案,还有更细的要求:把每个像素都归类。下一节走进像素级阅卷。