目标检测综述核心拆解:从YOLO到DETR的技术演进与调优 简介这份综述文档面向计算机视觉学习者、算法工程师及准备相关面试的开发者系统梳理目标检测领域从传统思路到深度学习范式的演进脉络。文档先讲解传统方法中滑动窗口区域选择、SIFT/HOG特征提取及SVM分类器组合的局限随后重点剖析基于区域候选的深度学习算法包括R-CNN流程、SPP-Net对卷积特征复用的优化并对比各方法的精度与速度差异。资源为单个docx文件大小842KB目录结构清晰适合按章节阅读和标记笔记。已有325人浏览学习既可辅助课程复习也能为论文调研和实际工程中的算法选型提供参考。1. 目标检测综述到底在梳理什么从“框出目标”到“理解场景”做工业质检、自动驾驶或者安防监控的人翻开目标检测综述多半是被同一件事逼来的模板匹配和颜色阈值撑不住了想知道该换哪个模型、要不要自己改网络、训练集扩到多少才够用。目标检测综述不是把 YOLO 到 DETR 的论文按时间轴排一遍它实际在回答三个问题检测器把什么当作“目标”、用什么方式表达并回归出“目标”、拿到预测框之后拿什么标准判断好坏。算法发展现状讲的是前两个问题的答案迁移评价指标讲的是最后一个问题的共识。这篇内容按“技术演进—最小复现—边界场景—诊断技巧”的顺序展开新手能顺着路线图跑出第一个模型熟手在 mAP 涨不动的时候也知道先看 PR 曲线而不是先改学习率。2. 目标检测的技术演进而非堆模型两阶段、单阶段与无锚框之争2.1 两阶段与单阶段的取舍逻辑2.1.1 R-CNN 家族为什么先在“候选区域”上做文章检测综述里绕不开的第一个节点是 R-CNN先用选择性搜索提出约两千个候选区域再逐个送入卷积网络提取特征并分类。这个思路把“检测”从传统的滑动窗口暴力枚举里解放出来代价是每个候选区域都过一遍网络一张图推理动辄十几秒离工程落地很远。Fast R-CNN 用 RoI Pooling 把共享卷积特征截出来只在分类头上逐区域计算速度大幅提升Faster R-CNN 又用 RPNRegion Proposal Network把候选区域生成也变成网络的一部分至此“两阶段”的稳定形态确定下来。两阶段把任务拆成“先找在哪、再认是什么”两个子问题定位精度高尤其对大物体的框回归更细。代价是结构里多一个区域提议环节训练时要分别处理 RPN 和检测头的损失显存占用也更高。在综述的演进图表里这一阶段的意义不是被单阶段取代而是提出了“多任务联合训练”和“锚框采样”这两个至今仍被使用的基础操作。2.1.2 YOLO 与单阶段方法用回归换速度YOLO 走的是相反路线把检测完全当作回归问题来做。输入图像被划分成 S×S 网格每个网格单元一次预测若干个边界框、置信度和类别概率没有显式的候选区域生成环节。早期版本对小目标和重叠物体漏检明显因为网格粒度决定了下限后来引入多尺度预测在多个特征层上各自回归小目标的召回才有了实质改善。SSD 更早意识到特征层的价值在不同分辨率的特征图上分别做分类和框回归浅层负责小目标、深层负责大目标这为 FPN 的“多尺度预测”搭好了骨架。今天的工业项目里实时场景默认选单阶段产线质检 60 FPS 以上没有商量余地自动驾驶感知也需要前向推理时间稳定可预估。单阶段省掉的不是精度而是“两遍计算”的冗余路径。2.2 检测头、损失函数与正负样本分配2.2.1 从 Smooth L1 到 CIoU回归损失在解决什么框回归损失的目标是让预测框和真值框尽量贴近但直接相减 L1 有梯度抖动的毛病所以 Faster R-CNN 用了带阈值切换的 Smooth L1。后来 IoU Loss 把优化目标换成“交并比最大”比 L1 更贴近 mAP 的测量方式再往后 DIoU 加入中心点距离约束CIoU 再加长宽比一致性解决的是 IoU0 时梯度消失和中心偏移的问题。单阶段检测器常用的另一类是 Focal Loss 及其变体它解决的是类别极端不平衡背景框数量比目标框多几个数量级普通交叉熵会淹没真正的前景信号。Focal Loss 给易分类样本降权让训练重心落到难例上这也是 RetinaNet 能把单阶段精度拉到两阶段水平的关键。2.2.2 正负样本分配比损失函数更决定收敛质量损失函数定好之后“谁算正样本、谁算负样本”的分配策略直接决定训练走向。Faster R-CNN 的做法是把与真值 IoU 大于 0.7 的锚框都算正样本并随机采样 256 个YOLOv5 之后用 shape 匹配加 CIoU 筛选DETR 则把分配问题退化成二分图匹配让每个真值只对应一个预测框。不同分配策略对收敛速度的影响往往比主干网络换大换小更明显。正负样本分配的一个常见误解是“负样本就是背景”其实还包括“定位差但类别对的框”。这类框在单阶段里容易被打成正样本导致模型学出的边界框粗糙。综述里讨论的 ATSS、OTA 等分配算法本质都是在回答同一个问题怎么让分配规则对物体大小、遮挡程度和稀疏程度更鲁棒。2.3 无锚框与 Transformer 检测器把“框”还给特征锚框一直是挡在工程师面前的一堵墙尺寸、比例、数量都要手动调。FCOS 和 CornerNet 尝试去掉锚框用中心点加距离回归的方式预测目标但多目标重叠时中心点语义不清晰误检仍偏高。DETR 直接换思路把检测建模成集合预测问题用 Transformer 的注意力机制建立全局关联再通过匈牙利匹配监督预测框与真值的对应关系彻底移除了锚框和后处理 NMS。DETR 的代价是训练收敛慢小目标特征容易在注意力计算中被稀释Deformable DETR 用可变形注意力只聚焦稀疏采样点把收敛速度和精度同时拉回来。演进到 DINO 这类模型后检测器的结构描述已经很难用“几阶段”概括更像“特征提取器 查询机制 匹配损失”的组合体。综述里做横向对比时会把模型分成两阶段卷积、单阶段卷积、无锚框和 Transformer 四组选型的核心依据变成数据量、推理平台和延迟预算。3. 动手跑通最小复现数据集格式、训练命令与评价指标计算3.1 用 COCO 格式组织自己的数据目标检测的数据格式绕不开 COCO 和 Pascal VOC 两种。COCO 的 JSON 结构对初学者不友好但主流工具链都支持它所以最小复现从 COCO 起步更省事。转换时最关键的是 categories 信息要从 1 开始编号标注框用[x, y, width, height]坐标一律是浮点数类别 ID 要和训练时的数据配置保持一致。如果手里是 VOC XML最常见做法是用开源脚本转一遍但转换逻辑容易踩两个坑一是 VOC 的 bndbox 坐标没有归一化COCO 要求的是像素坐标二是 VOC 类别名和 COCO 类别 ID 的映射表如果多一份或少一份训练结果会莫名少几类。一个最小但完整的 COCO 子集 JSON 结构如下{ images: [ {id: 0, file_name: 000001.jpg, width: 1280, height: 720} ], annotations: [ {id: 0, image_id: 0, category_id: 1, bbox: [420.5, 100.2, 312.1, 420.8], area: 131328.0, iscrowd: 0} ], categories: [ {id: 1, name: helmet}, {id: 2, name: person} ] }这个结构里iscrowd是很多人会忽略的字段它标记该标注框内是否包含一组密集物体值为 1 时评估阶段会跳过该框内部的预测误标为 0 会让密集场景的 mAP 虚高。area在训练时用不到但 COCO 官方评估会按面积区间拆分 AP缺失时某些评估脚本会直接报错。3.2 用 Ultralytics YOLO 跑通最小训练命令选 Ultralytics 做为最小复现工具不是因为它最强而是因为配置文件和命令行的约定最少。先准备一个描述数据集的 YAMLpath: ./helmet_dataset train: images/train val: images/val nc: 2 names: [helmet, person]然后执行训练命令yolo detect train datahelmet.yaml modelyolo11n.pt epoch50 imgsz640 batch16 device0 project./runs namehelmet_exp1modelyolo11n.pt表示加载 nano 尺寸的预训练权重而不是从头训练迁移学习能让收敛时间缩短一半以上imgsz640是输入边长训练时会等比例缩放并补齐到 640 的倍数batch16在 12GB 显存上可以跑更大的批量需要配合梯度累积或者换更小的输入分辨率。训练过程中的关键监控指标不是 mAP而是box_loss和cls_loss的下降曲线。如果 box_loss 前 10 个 epoch 没有明显下降优先检查学习率而不是网络结构。生产项目里常用的 yolo 训练参数通常有这三项调整mosaic1.0做四图拼接增强但最后 10 个 epoch 要关闭避免分布偏移cos_lrTrue让学习率按余弦退火衰减比固定步长下降更平顺close_mosaic10指定最后多少轮关掉 mosaic让模型在接近真实数据分布上微调。数据量少的时候mosaic是提点的主力数据量达到数万张时反而要控制增强强度。3.3 mAP 的计算口径与常见误区评价指标是综述里最容易被一句话带过、但实际影响判断结论的部分。mAP 不是一个数而是一组数的平均先按置信度从高到低排所有预测框与真值框做 IoU 匹配IoU 大于阈值算 True Positive再逐点画出 Precision-Recall 曲线计算曲线下面积。COCO 风格把 IoU 阈值从 0.5 到 0.95 每隔 0.05 取一次算出十个 AP 再平均写出来是 mAP0.5:0.95Pascal VOC 风格只算 IoU0.5 的 AP数值普遍高出一截对比不同论文或项目时必须先确认口径一致。一个计算单类别 AP 的最小实现可以用来排查结果import numpy as np def compute_ap(precision, recall): # 11 点插值法取每个 recall 区间内 precision 最大值 ap 0.0 for t in np.linspace(0, 1, 11): p precision[recall t] if len(p) 0: continue ap np.max(p) / 11.0 return ap这里的插值逻辑是 VOC 早期标准COCO 用的是稠密采样加数值积分结果会有少量偏差。评估脚本输出里的AP_small、AP_medium、AP_large对应目标像素面积小于 32²、32² 到 96²、大于 96² 三类如果项目数据集以小目标为主单看总体 mAP 会掩盖小目标召回率很低的问题。注意不要拿训练集上的评价数值去指导模型选型那只是过拟合程度的度量。4. 小目标、开放词汇与激光雷达场景综述边界外的硬骨头4.1 小目标检测的三个突破口输入分辨率、上下文与切片推理小目标定义在 COCO 里很明确像素面积小于 32×32。这类物体在特征图上只占极少量像素经过几次下采样后基本消失所以最常见的第一个改动是提高输入分辨率。imgsz 从 640 提到 1280小目标 AP 往往能涨 5 到 8 个点但显存占用和推理延迟也同步翻倍产线上要算的是帧率预算而不是单纯看精度。第二个突破口是上下文信息小目标容易和背景混在一起需要更大的感受野来捕获“它在什么地方”。YOLO 系列在 head 前拼接不同尺度特征本质是让浅层小目标的特征也能看到深层语义。第三个工程技巧是切片推理用 SAHI 这类工具把大图切成若干有重叠的块分别检测再合并结果无人机航拍和卫星图里的目标检测几乎全靠切片才跑得动。切片的 overlap 一般设在 20% 到 50%太小会切断跨块目标太大则产生大量重复预测合并时要用 NMS 把阈值降到 0.3 以下才能压住重复框。4.2 开放词汇目标检测从“认识固定类别”到“按文本找目标”传统检测器做一次训练只能识别固定类别换个场景就要重新标注重新训练。开放词汇检测想解决的是训练时见过“车”但测试时让它找出“救护车”的框。常见方案有两种一是把语言模型和检测器做联合训练GLIP 把类别文本拼成 prompt 输入网络让文本编码和视觉特征在统一空间里对齐另一种是把现成检测器当区域提案器对每个候选框做裁剪再用 CLIP 之类的大型视觉语言模型做零样本分类。后一种方案工程上更好实现不需要重新训练检测器import open_clip import torch from PIL import Image model, _, preprocess open_clip.create_model_and_transforms( ViT-B-32, pretrainedlaion2b_s34b_b79k ) tokenizer open_clip.get_tokenizer(ViT-B-32) cropped Image.open(crop.jpg).convert(RGB) image preprocess(cropped).unsqueeze(0) text tokenizer([a photo of a helmet, a photo of a person, background]) with torch.no_grad(): image_features model.encode_image(image) text_features model.encode_text(text) logits (image_features text_features.T) * 100 # 温度系数 100 probs logits.softmax(dim-1) print(probs)这里的温度系数 100 是 CLIP 训练时用的常数值它控制相似度分数的分布锐度温度越高概率越接近均匀分布低则接近 one-hot。实际项目中几个系数对效果影响很大裁剪框边缘要留 10% 到 20% 的余量不然目标被切掉一半分类就会错文本模板用“a photo of a {类别}”比直接写类别名效果更稳。开放词汇检测的边界在于“开放”不等于“全能”CLIP 对密集小目标和同类别细粒度区分的表现仍然偏弱工业落地大多还是拿它做初筛。4.3 激光雷达点云与三维目标检测的评价差异三维目标检测的输入来源决定了它的算法路线差异很大。单目相机方案沿用二维检测思路只加一个深度估计头激光雷达方案要先做三维数据预处理。点云是稀疏且无序的无法直接喂卷积网络常见做法是体素化或 Pillar 化。VoxelNet 把点云划分成三维体素网格在稀疏体素上做 3D 卷积PointPillars 压成伪图像再走 2D 检测器在算力和精度之间取得平衡。感知里做传感器融合时二维检测框和三维框的匹配逻辑也与纯视觉项目不同常用 IoU 之外的距离阈值限制来判定同一目标。评价指标上三维检测的 IoU 计算和二维完全不是一回事。KITTI 的评测把物体分 easy、moderate、hard 三个难度级别AP 计算用 40 点插值而不是 COCO 的 101 点采样3D IoU 对车辆的阈值通常取 0.7对行人和骑行者取 0.5因为行人外形不规则严格要求 IoU 不现实。更关键的是三维检测常用 BEv 视角的 AP 和三维视角的 AP 两个指标并列前者评估鸟瞰位置精度后者评估完整三维框精度。只看 BEV AP 会掩盖高度估计的误差而高度误差在真实场景里直接影响路径规划的安全距离。5. PR 曲线拆解与“mAP 涨不动”时的诊断顺序mAP 长时间不涨比调参更重要的是先定位瓶颈方向。第一步永远是画出每个类别的 PR 曲线而不是盯着总体数字看。import matplotlib.pyplot as plt for cls in class_names: precision, recall eval_data[cls][precision], eval_data[cls][recall] plt.plot(recall, precision, labelcls) plt.xlabel(Recall) plt.ylabel(Precision) plt.legend() plt.savefig(pr_curves.png, dpi150)PR 曲线的形状能快速区分两类问题精度掉得早说明误检严重模型把大量背景当成了目标深挖时看置信度排名靠前的假例是不是集中在某一类召回到不了高位说明漏检严重真值框在低置信度区间就匹配不上这时加大输入分辨率或增加小目标增强会更有效。多类别项目还要看各类别曲线的分离程度如果某一类的 AP 明显低于其他类优先查这一类训练样本量和标注质量很多情况是标注框缺边或者类别样本太少导致的模型结构反而没责任。5.1 用错误类型分析代替直觉调参TIDE 这类错误分析库把预测错误拆成分类错误、定位错误、背景错误和重复检测四类跑完之后能告诉你“如果所有定位错误都修好mAP 会涨多少”。把这次实验结果做一次错误类型统计之后再决定改哪里通常能避开最常犯的一个浪费类别 AP 差距大时换更大的主干网络。主干网络提升的是整体特征表达能力对样本量不足的类别作用有限更好的做法是对该类做过采样或复制粘贴增强把训练分布纠正过来。5.2 三个立即可用的针对性技巧低置信度下漏检多可以调低预测阶段的置信度阈值到 0.05 重新评估观察 recall 是否明显上升如果上升很多说明训练正常但模型对某个类别不够自信需要的是难例挖掘而不是换损失函数误检集中在某几类在混淆矩阵里交叉分布可以考虑在数据加载时加入类别重采样让相似类别在每个 batch 里同时出现让判别边界被反复强化定位误差在所有错误中占比最高关注焦点从分类头转到回归头查看回归损失是否提前收敛必要时对回归分支加大损失权重或者切换更精细的 IoU 变体损失。跑一次这个脚本把 PR 曲线和错误类型统计存进实验目录后续每次训练对比只多一条命令却能避开低效调参反复试错的路。本文还有配套的精品资源点击获取