图像分类回答”这张图里是什么”,目标检测回答”图里有哪些物体、分别在哪”——输出是一组边界框(bounding box)加类别。自动驾驶找车辆和行人、工业质检找缺陷、人脸识别第一步找人脸(人脸识别篇 里的 YuNet 就是检测器),全是它的应用。
前置阅读:深度学习课程 04:CNN 图像分类( backbone 与卷积基础)。
三个绕不开的核心概念
IoU(交并比):预测框和真值框的交集面积除以并集面积,衡量框得多准:
通常 IoU > 0.5 算”检测到了”。训练时它是回归目标的一部分,评估时它是判定对错的标准。
NMS(非极大值抑制):模型对同一个物体往往输出一堆重叠框,NMS 留下分数最高的、删掉和它 IoU 超过阈值的其余框——去重的标准流程。调参时 conf(置信度阈值)和 IoU 阈值要一起调:conf 定”多肯定才算检出”,IoU 阈值定”多重叠算同一个”。
mAP(平均精度均值):检测任务的权威指标。按置信度排序预测结果,画出每个类别的 PR 曲线、算 AP(曲线下面积),再对所有类别求平均。mAP@0.5 是 IoU 阈值 0.5 下的结果,COCO 基准还常用 mAP@[.5:.95](多阈值平均,更严格)。看论文和榜单时务必确认说的是哪个口径,两者差 20 个点很正常。
Anchor:检测的”候选框先验”
早期 YOLO 和 Faster R-CNN 都是 anchor-based:在每个特征图位置预置若干不同长宽比的锚框,模型学习”锚框要往哪调、里面是什么”。Anchor 的尺寸分布要匹配数据——标注框普遍偏窄高(行人)就该配窄高锚。YOLOv5 起引入 auto-anchor 自动聚类数据里的框尺寸;YOLOv8 之后转向 anchor-free,直接预测中心点到四边的距离,少了一组超参,训练更省心。面试被问 anchor 时讲清这条演进线即可。
两阶段 vs 单阶段:两条演进路线
两阶段(R-CNN 家族):第一阶段提候选区域(可能含物体的一两千个框),第二阶段对每个区域分类和精修。Faster R-CNN 用 RPN(区域建议网络)把候选生成也变成可学习的,精度高但速度慢,适合离线高精度场景。R-CNN → Fast R-CNN → Faster R-CNN 的演进主线是”不断把慢步骤搬进网络共享计算”:Fast 共享了卷积特征,Faster 共享了候选生成。
单阶段(YOLO / SSD):直接在特征图上密集预测所有位置的框和类别,一次前向出结果。牺牲一点精度换数量级的速度,实时场景(视频流、机器人)的唯一选择。YOLO 从 v1 到 v8+ 的迭代,主线是anchor 机制的简化、多尺度特征的强化(FPN/PAN)和训练策略的工程化,精度和两阶段的差距早已抹平。
一句话记忆:两阶段”先找再看”,单阶段”边看边找”。工程选型默认从 YOLO 起步,精度不够再考虑两阶段或更大的 YOLO 型号。
YOLO 实战:训练自己的检测器
ultralytics 把 YOLO 的工程体验做到了极致:
# pip install ultralytics
from ultralytics import YOLO
# 1. 预训练模型直接推理
model = YOLO("yolov8n.pt")
results = model("street.jpg")
for box in results[0].boxes:
print(box.cls, box.conf.item(), box.xyxy.tolist())
# 2. 在自己的数据上微调
# 数据格式:images/ + labels/(YOLO txt:class x_center y_center w h,归一化)
model = YOLO("yolov8n.pt")
model.train(
data="my_dataset.yaml", # 声明训练/验证集路径与类别名
epochs=100,
imgsz=640,
batch=16,
)
数据格式是最常见的卡点:YOLO 标注是每行一个物体的 txt 文件,坐标全部归一化到 [0,1]。从 LabelImg/CVAT 等标注工具导出时选对格式。
训练的实战要点
先抽样把标签画回原图,再讨论模型结构:框坐标是像素还是归一化值、类别编号是否从约定起点开始、缩放与翻转是否同步修改框?这些错误未必导致训练崩溃,却会让模型持续学习错误的位置。
- 从预训练权重微调,不要从头训练——检测任务数据需求大,微调几百张图就能出可用模型,从头训练需要几万张起步。
- 数据增广就是检测的半条命:马赛克(mosaic)、随机裁剪、色彩抖动是 YOLO 默认开启的。小物体多的场景注意增广别把目标裁没了。
- 模型尺寸按延迟预算选:n/s/m/l/x 五档。边缘设备用 n,服务器追精度用 l/x。先测延迟再定型号,不要反过来。
- 评估看 mAP 也看单类 AP:整体 mAP 掩盖小样本类别的失效,和分类任务看宏 F1 一个道理。
踩坑排查
| 症状 | 原因 | 处理 |
|---|---|---|
| 训练 loss NaN | 学习率过大/标注坐标越界 | 降 lr;校验标注在 [0,1] 内 |
| 一个物体出多个框 | NMS 阈值不当 | 调 conf/iou 阈值 |
| 小物体全漏检 | 输入分辨率太低/anchor 不匹配 | 提 imgsz;用 P2 小目标层 |
| 验证 mAP 高上线差 | 训练/线上数据分布不同 | 检查分辨率、光照、场景差异 |
| 标注工具导出格式错 | 导出成 VOC/COCO 而非 YOLO | 转换脚本统一格式 |
| 推理慢 | 型号过大/没半精度 | 换小档型号;FP16/ONNX 导出 |
练习
- 用预训练 YOLO 在 10 张街景图上推理,统计各类别检出数与平均置信度。
- 标注 50 张自定义数据并微调,对比微调前后在验证集上的 mAP。
- 系统扫描 conf 阈值 [0.1, 0.9],画出精确率-召回率权衡曲线。
- 导出 ONNX 模型,对比 PyTorch 与 ONNX 推理的单张耗时。
面试常问
Q:IoU、NMS、mAP 分别解决什么? IoU 度量框的重合质量,是训练回归和评估判定的基础;NMS 解决同一物体多框重复;mAP 综合 PR 曲线衡量检测器在不同置信度下的整体水平。
Q:两阶段和单阶段检测器的本质区别? 两阶段先显式生成候选区域再逐个分类回归,精度优先;单阶段在特征图上密集锚点直接预测,速度优先。工程默认单阶段(YOLO 系),精度敏感且离线可用两阶段。
Q:小目标检测为什么难,怎么改进? 小目标在深层特征图上信息丢失严重。改进:提高输入分辨率、加浅层检测头(P2)、针对性增广(复制粘贴小目标)、用 FPN 多尺度融合。
Q:检测任务怎么做数据增广? 几何(翻转/缩放/裁剪——注意同步变换标注框)、色彩(HSV 抖动)、马赛克拼接(四图合一,丰富背景与尺度)、MixUp。增广必须同步更新标注坐标,这是检测增广和分类增广的关键区别。
下一篇相关阅读:图像生成:GAN、VAE 与 Diffusion 入门。
💬 评论
这套方案在哪一步卡住了?也欢迎补充你的实现方式或踩坑经验。