资讯详情

目标检测三大流派:RCNN、YOLO、DETR原理与部署选型指南

📅 2026/11/2 13:16:05 | 华诺云谱 👁 阅读
目标检测三大流派:RCNN、YOLO、DETR原理与部署选型指南
聊到目标检测绕不开三个名字RCNN、YOLO、DETR。它们分别代表了两阶段检测、单阶段检测、端到端Transformer检测三种思路也是工业落地、竞赛刷分、学术研究里最常被拿来做对比的三大流派。很多新手一上来就急着跑YOLO训练但遇到精度瓶颈、部署延迟、小目标漏检这些问题时往往是因为不清楚三种方案背后的设计逻辑。这篇文章我按自己的理解把三者的核心原理、损失函数、训练细节和部署坑点串起来讲一遍读完你至少能明白某个业务场景下到底该选哪个方案以及选完之后训练和部署有哪些必须避开的坑。1. 两阶段检测器RCNN系列是怎么一步步把“检测”拆成两个工序的两阶段的核心思路一句话就能概括先把可能有物体的区域找出来再对这些候选区域挨个做分类和框回归。整个过程像一场筛选面试第一轮海选先圈定重点第二轮精面再逐个确认。这个思路从RCNN一路进化到Faster RCNN每一步都在解决一个明确瓶颈。1.1 RCNN的开山思路区域提议加分类为什么当年能跑通2014年RCNN提出的时候目标检测还没有一个统一的可训练框架。当时大家的做法是把检测拆成候选区域生成、特征提取、分类三个独立步骤。RCNN用的是Selective Search先在图上融合颜色、纹理、大小等相似区域生成大概2000个候选框然后对每个候选框裁剪缩放成固定尺寸分别送进CNN提取特征最后接一个SVM分类器和一个框回归器。这里有一个关键点RCNN的训练是分阶段进行的CNN分类器、SVM、框回归器是分开优化的不是端到端。我见过不少刚接触这个时期论文的人不理解为什么要这么做。理由是当时的GPU算力和数据规模都不支持端到端的联合训练而且SVM在小样本上有优势。这套思路虽然精度在当时很惊艳但速度非常感人——每张图片在GPU上也要跑几十秒因为2000个候选框每个都要独立过一次网络完全没有共享中间计算。1.2 Fast RCNN的共享卷积与RoI池化让提速成为可能Fast RCNN最大的改进在于解决了“重复计算”的问题。它把整张图只过一次CNN得到完整的特征图然后把Selective Search生成的候选框映射到特征图对应的区域上再通过RoI池化把每个区域统一成固定尺寸送到后面的全连接层做分类和回归。RoI池化的逻辑值得好好理解。它把候选区域在特征图上划分成固定格数比如7x7然后对每个格子做最大池化。这样一来不管候选框原始大小怎么变输出的特征尺寸都是7x7后面的全连接层就可以接收定长输入。这个设计让一张图上所有候选框共享了底层的卷积计算检测速度比RCNN高了差不多两个数量级。Fast RCNN还顺手把SVM换成了Softmax把分类和框回归放进同一个网络里做多任务训练这时候已经非常接近后来的工业落地形态了。1.3 Faster RCNN的RPN把“找框”也变成网络的一部分Faster RCNN的贡献是把“候选区域生成”这件事也从外部算法换成了网络结构。它引入了一个轻量级的RPNRegion Proposal Network直接在特征图的每个位置预置若干不同尺度和长宽比的anchor框然后网络同时输出这个anchor是前景还是背景以及相对真实框的偏移量。这一步相当于让“找框”也变成可以梯度优化的环节。RPN和Fast RCNN检测头在训练的时候是交替优化的推理时两个阶段串起来用。第一阶段RPN从几万个anchor里粗筛出几百个候选区域第二阶段检测头再对候选区域精分类并修正框的位置。整个过程就是一个完整的、可训练的端到端模型精度和速度均衡也是后面很多工业方案的基础。1.4 两阶段模型怎么选Faster RCNN的适用场景和性能参考正常情况下同等骨干网络下Faster RCNN的精度要好于大部分单阶段模型因为两阶段相当于多了一次“精修”机会对小目标和遮挡场景更友好。参考公开报告的数据以ResNet50-FPN为骨干的Faster RCNN在COCO val上的mAP大概在37到40之间而同一批骨干的YOLOv4或YOLOv5类似量级的模型在速度领先的情况下精度大约在33到38之间。当然具体要看训练策略和数据不能只看单组benchmark就下死结论。选择上我的经验是如果你的任务里目标尺寸跨度大、小目标比例高或者你手里只有小规模数据集需要稳定可控的训练过程那Faster RCNN系列更稳。反之如果目标是实时视频流、边缘设备、快速迭代那单阶段方案更合适。两阶段最大的代价是速度和结构复杂度部署时要多写不少前后处理逻辑这一点后面讲部署的时候会再展开。2. YOLO系列单阶段把检测当成回归问题做YOLO的出现可以说是对两阶段方案的一次彻底反叛。它不在第一阶段生成候选区域而是把整张图划分成网格直接在每个网格上预测目标的类别和框坐标。整套检测被压缩成一次前向推理从图像输入到最终输出之间没有任何中间筛选环节所以速度天然占优。2.1 YOLOv1的核心思想网格划分、边界框与宽高开根号的用意YOLOv1把输入图片划分为S x S的网格比如7x7。每个网格负责预测若干个边界框比如2个每个框输出中心坐标、宽高、置信度再加上网格对所有类别的分类概率。如果一个物体的中心落在某个网格内那么这个网格就负责预测这个物体。这里有个很多人忽略的设计细节损失函数里对宽高做了开根号处理。原因是原始宽高的数值方差很大大物体的几像素偏移和小物体的几像素偏移在误差数值上差异巨大。对大框来说2像素偏差稀松平常但对小框来说这可能是致命的。开根号的作用是压缩大尺寸和高数值的误差权重让模型不太容易被大框带偏。这个小技巧后来也被很多单阶段模型沿用。理解了这一点再看后面版本对损失函数的各种改动就容易多了。2.2 从v2到v8的演进主线和每个版本的典型改动YOLO系列的演进脉络非常清晰每个版本都在解决前一个版本的突出短板。YOLOv2引入了anchor机制和Batch Normalization让模型开始具备相对稳定的训练过程YOLOv3引入了多尺度预测和FPN结构不同尺寸的特征图分别负责大中小目标的检测小目标召回率第一次有了明显改善YOLOv4和YOLOv5时期工程细节开始主导比如Mosaic数据增强、CIoU损失、CSP结构、EMA权重等这些改动让训练更方便、部署更容易。到了YOLOv8Ultralytics做了许多结构性调整把anchor-free机制变成了默认配置检测头不再依赖预设anchor而是直接在特征图上预测中心和宽高配合DFLDistribution Focal Loss和CIoU损失整体训练更简洁。我自己的体感是v8对新手最友好文档全API统一但它的某些结构细节和训练技巧直接沿用v5也不是不行选择标准应该看你自己的数据量、硬件资源和团队习惯不必盲目追新。2.3 YOLO损失函数全景分类、框回归和置信度分别怎么算YOLO的损失函数长期以来由三部分组成分类损失、边界框回归损失、置信度损失。分类损失通常用交叉熵判断每个网格预测的类别和真实类别是否一致置信度损失是判断预测框中是否有物体并与真实IoU进行对比框回归损失则负责让预测的坐标尽可能贴合真实框。早期的YOLOv1用的是均方误差来做框回归YOLOv3之后大家普遍换成IoU系列损失。IoU损失有个天然问题是当两个框完全不重叠时损失梯度为0所以后来又演化出GIoU、DIoU、CIoU这些变体。YOLOv5和v8最常见的组合是CIoU加上DFL其中DFL负责让框回归变成一种分布预测而非单点预测这在处理边界模糊目标时很有帮助。训练的时候一般让这三个损失的权重保持默认即可但如果你发现某一类任务表现明显失衡比如框位置总是偏大或偏小可以先试着调整框回归损失的权重而不是一上来就改学习率。2.4 什么时候果断选YOLO什么时候要犹豫YOLO最适合的场景是视频级实时检测比如监控、车载、工业质检流水线。原因是单阶段前向一次出结果部署到TensorRT之后帧率可以做得非常高。加上生态极其成熟标注格式、导出onnx、TensorRT脚本、各种平台支持都非常完善几乎从训练到上线是一条龙。犹豫的场景通常是极致的精度竞赛和小目标密集场景。如果图片里有大量微小目标比如几十个像素的远处行人YOLO多尺度预测虽然能覆盖一部分但相比DETR这类全局建模的模型它在上下文理解上会偏弱需要靠多尺度增强和加大输入分辨率来补救。3. DETRTransformer进入检测把目标检测变成集合预测DETR是2020年Facebook提出的端到端检测框架它彻底改变了前面这些模型的设计语言。它不再使用anchor、不再使用NMS、也不需要RPN而是把检测看作一个“从N个候选查询到N个预测结果”的集合预测问题用Transformer的去重能力直接产出最终框。3.1 取消anchor与NMS的底层逻辑匈牙利匹配和object queriesDETR整体的流程是这样的CNN骨干提取特征后把特征图展平成序列输入Transformer的EncoderDecoder输入的是一个固定数量的可学习object queries比如100个这些query通过交叉注意力从Encoder特征里“查询”出各自感兴趣的目标最终每个query输出一个框和一组类别概率。由于这一百个query都可能被用于预测目标训练时就必须做匹配。DETR用匈牙利算法在预测结果和真实框之间做二分匹配确保每个真实框只对应一个最优预测其他预测则被分类为“无目标”。正是这种显式的匹配机制让模型在推理时自然避免了重复预测NMS因此被扔掉。理解了这一点你再看DETR的工作过程就不会觉得神秘它本质上是让网络自己学习把目标与query一一对应起来。3.2 用DETR训练自己的数据收敛速度、epoch设置和骨干冻结技巧DETR训练自己数据时最大的体感就是慢。原始论文用了500个epoch在COCO上训练普通GPU实在耗不起。如果只是在自己业务数据上微调我建议先加载COCO上预训练的checkpoint然后把骨干网络冻结住只训练Transformer部分。这样既能保留骨干的特征提取能力又能显著减少训练时间。数据规模上DETR对数据量的要求比YOLO高。这是因为Transformer的全局注意力需要大量样本才能学到稳定的匹配关系。如果你只有一两千张自定义数据建议先在类似领域做预训练或者用Deformable DETR这类收敛更快的变体。还有个容易踩的坑是输入分辨率。DETR默认把图片变成固定尺寸送入网络如果业务图本身很大且目标很小不能像YOLO那样简单调个imgsz就完事需要确认Encoder里特征序列长度是否超出显存预算必要时裁剪或切块训练。3.3 DETR的变体与改进Deformable、DINO和RT-DETR的实用价值原版DETR的问题主要集中在收敛慢、小目标弱、计算量大业界很快给出了一系列改进。Deformable DETR把注意力变成了稀疏采样只在参考点附近选取少量采样点大幅降低计算量收敛速度提升约10倍。DINO则在Deformable的基础上做了对比去噪训练把收敛速度和精度进一步拉高是当前很多实验室做端到端检测的首选基线。真正让DETR进入工程视野的是RT-DETR它把Encoder的复杂计算做了重构引入了高效的混合编码器和IoU-aware查询选择依靠视觉特征主导而非decoder交叉注意力来生成查询从而在DETR系列里达成了实时性能。实测下来RT-DETR在相似延迟下精度可以和YOLOv8掰掰手腕而且免去了NMS部署链路更短。如果说DETR代表了学术上的完整形态RT-DETR就是把这个形态商业化的那个版本。4. 从训练到部署YOLO工程落地的完整链路前面花了不少篇幅讲原理现在说说我实际训练和部署时最常用的一套流程。这部分以YOLO为主因为它的生态最成熟也最容易踩到具体问题。整个链路从数据准备开始到训练参数、评估指标再到TensorRT部署和多路并发估算每一环都有讲究。4.1 数据准备标注格式转换、数据集划分与真实场景数据采集数据是检测项目的天花板。无论选哪个模型数据质量不过关后面的训练和调参基本都是白费。YOLO训练用的最标准格式是每个图片对应一个同名txt文件每行内容为“类别编号 cx cy w h”其中cx、cy、w、h都是相对图像宽高的归一化坐标。如果拿到的数据是VOC格式的xml或者COCO格式的json需要先做转换这个环节我建议写一个脚本统一处理不要手动改。数据集划分上我习惯按8:1:1划分训练、验证、测试并且用随机种子固定下来保证多次实验可以公平对比。划分的时候要注意同一张图片的不同增强版本不能同时出现在训练集和验证集中否则会天然抬高评估分数。还有一点容易被忽略公开数据集如中餐菜品、电力红外设备这类特定领域最好先做一轮真实业务场景的数据采集再补充公开数据。公开数据集往往场景单一直接拿到业务里用很容易出现域差异导致的精度骤降。4.2 训练参数的选择预训练权重、batch size与学习率YOLO训练时最省事的做法是加载官方预训练权重比如yolov8s.pt在此基础上微调。这样做的好处是骨干网络已经具备通用的特征提取能力即使你的数据量不大也能在较少的epoch内达到不错的效果。训练命令可以用下面最基本的方式启动yolo detect train datadata.yaml modelyolov8s.pt epochs100 imgsz640 batch16 device0,1这里比较关键的是batch size。batch太小会出现一个很典型的训练问题——BN统计量不稳定也就是很多人说的BN崩溃后面我会专门讲。batch大则相对稳定但会占用更多显存。当显存不够时我优先建议降低分辨率而不是强行减小batch或者使用梯度累积。学习率方面用官方默认配置通常没问题但如果发现loss抖得厉害可以考虑把初始学习率从0.01降到0.003左右再配合warmup来稳定前几个epoch。4.3 评估指标怎么看混淆矩阵、mAP和“总和不为1”的真相训练完要看模型好坏离不开混淆矩阵和mAP。YOLO训练结束后会在验证集上输出混淆矩阵每一行代表真实类别每一列代表预测类别对角线是正确分类的比例。很多人会拿这个矩阵去算行和或列和发现无论如何都不为1于是怀疑程序出了问题。其实检测任务的混淆矩阵和分类任务完全不同。检测里的一个真实框既有可能被预测匹配也可能因为置信度低于阈值而没有被匹配没匹配上的会被计入背景类。同一张图里还可能存在预测框和真实框的IoU刚好卡在阈值边缘导致归类不一致的情况。所以单看混淆矩阵的行和列总和不为1是非常正常的它受置信度阈值、IoU阈值、NMS设置共同影响。真正要关注的是对角线上的数值行归一化之后对角线数值代表每一类有多少比例被正确检出。mAP也是同理它把Precision-Recall曲线下的面积做一个积分兼顾了不同阈值下的表现。我平时更习惯分开看mAP50看整体框得准不准mAP50-95看框和类别的综合精细度。如果你的业务是精准计数就多关注mAP50如果业务要求精细分割级别的框质量那mAP50-95更有参考价值。4.4 TensorRT部署与多路视频流的并发估算YOLO训练完之后下一步就是部署。常见的流程是先导出onnx再用TensorRT转成engineFP16是性价比最高的选择。导出onnx时要注意opset版本和动态尺寸设置务必把动态batch和动态分辨率打开yolo export modelbest.pt formatonnx dynamicTrue opset12 trtexec --onnxbest.onnx --saveEnginebest.engine --fp16 --minShapesimages:1x3x640x640 --optShapesimages:8x3x640x640 --maxShapesimages:16x3x640x640这里再解释一下很多人关心的“T4跑1080P25帧每秒视频流能支持多少路”。先看单路负载假设每路视频用640分辨率YOLOv8s做检测TensorRT FP16推理一帧大约5到8毫秒加上视频解码、缩放预处理、后处理NMS单帧完整处理链路保守估计在10到12毫秒。一路视频每秒25帧意味着单路每秒要吃掉约250到300毫秒的GPU时间。T4整卡一秒只有1000毫秒所以按同步串行处理的话理论并发在3到4路之间。但如果把多路视频的帧组成batch一次推理GPU利用率能显著提升配合DeepStream这类方案实际并发可以做到8到10路甚至更高。所以这个问题没有标准答案它取决于模型规格、是否batch化、预处理是否搬到了GPU上、是否用了硬解。5. 常见问题与排查技巧实录最后这部分是我这些年踩坑的集合。很多问题在文档里找不到标准答案但遇到的时候一旦不会排整个项目节奏就卡住了。5.1 训练不收敛或loss为nan按优先级查这四件事第一查数据确认标注框里没有出现负值坐标、宽高为0、类别索引越界这类低级问题。第二查学习率初始学习率过大是loss爆炸最常见的元凶尤其当你换了大模型或大batch时原来的学习率可能已经不适用。第三查BN如果batch size小于8BN统计量极不稳定loss会出现周期性震荡建议加大batch或用SyncBN。第四查硬件混合精度训练时某些显卡驱动版本和CUDA版本不匹配会偶发nan值可以先用FP32跑几个epoch验证一下。BN崩溃值得多说一句。我实际遇到过训练到一半loss突然飙高之后再也降不下来的情况排了一圈发现是数据里混了少量全黑的图片走归一化之后特征方差为0BN的running stats被污染了。从此我所有数据集都会在训练前写一段脚本做min-max检查把异常图片单独拎出来看一眼。5.2 小目标漏检严重分辨率、P2层与多尺度训练小目标漏检是YOLO系列的老问题。先看特征金字塔YOLO默认从P3开始往下融合P3对应的是下采样8倍的特征图每个特征点大约对应原图8x8像素。如果目标本身就小于8x8像素那么在特征图里几乎没有可用的特征点检不出来是必然的。最简单的缓解办法是提高输入分辨率把imgsz从640提到960甚至1280小目标的特征点变多了精度会明显改善代价是推理变慢。如果再不够那就需要增加P2层即把下采样4倍的特征图也接入检测头。P2层对显存和计算量都不友好一般只在高精度场景中使用。还有一个常用组合是开启多尺度训练训练时随机在0.5到1.5倍分辨率之间切换让模型对小目标更鲁棒但理解上要清楚这只是正则化手段不会凭空增加信息量。5.3 RTSP监控视频流检测拉流、抽帧与断流处理做监控类项目时输入不是一张张图片而是RTSP视频流。最直接的方式是用FFmpeg拉流按固定间隔抽帧送入检测模型。抽帧间隔取决于你的业务要求每秒抽1帧和每秒抽5帧对CPU、GPU的消耗差别很大。这里有个关键设计抽帧一定要放到独立线程或进程否则解码卡顿会直接阻塞检测主循环。视频流还有个常见问题是网络抖动导致断流重连逻辑一定要做成指数退避几十秒就疯狂重试只会让服务器负载雪崩。如果机器网卡和CPU都比较紧张可以考虑GPU硬解把解码这一步也从CPU搬走。我习惯用带异步队列的解码框架解码线程塞满队列检测线程从队列取帧这样即使偶发解码延迟检测侧也不至于空等。5.4 模型加速瘦身蒸馏、剪枝和CLIP辅助的新玩法训练好一个大模型之后直接用大模型做部署当然精度最高但成本也高。我常用的一条路线是“大模型训小模型学”也就是知识蒸馏。具体做法是把YOLO大模型的输出概率或特征图当作老师让一个小模型在同样的数据上通过损失函数来模仿老师的输出。温度系数通常取3到5蒸馏损失和真实标签的损失按0.5比0.5加权。这种方式在边缘设备上能拿到比直接训练小模型高几个点的精度。剪枝的思路则是把不重要的通道裁掉。有些框架可以自动分析BN层缩放因子把gamma小的通道认为是冗余通道剪掉之后微调恢复精度。这个方案在YOLOv5时代很流行v8上因为结构改动剪枝工具没有跟上所以用的人相对变少。最近还有一个很有意思的方向是YOLO加CLIP利用CLIP的图文对齐能力实现开放词汇检测也就是模型不用事先固定死类别输入一段文本描述就能去找对应的目标。现阶段它还不能完全替代标准YOLO但做预筛选和新品类探测场景已经很有实用价值了。我个人目前在实际项目里最常用的组合还是“YOLOv8做主干检测DETR系做复杂场景复检Faster RCNN作为精度基准线”。这三个流派不是互相替代的关系而是同一问题的三个求解角度。你在选型时可以先拿公开权重在你的验证集上跑一轮用数据说话再决定往哪个方向投入调参时间。检测这个领域不缺少理论缺的是把理论落到自己数据和业务场景里的耐心。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑