新闻详情

新闻详情

首页 / 资讯中心 / 详情

DETR目标检测:从集合预测到端到端检测的工程实践

发布时间:2026/9/25 1:13:03来源:尧图网络
DETR目标检测:从集合预测到端到端检测的工程实践
1. 为什么DETR值得你花时间啃论文而不是直接跑代码目标检测这个领域过去七八年基本是YOLO、SSD、Faster R-CNN这几套框架轮流坐庄。大家默认的套路是先撒一大堆候选框再分类、再回归坐标、最后来个NMS把重叠的框去掉。这套流程能跑但工程上很烦——anchor的尺寸要调、NMS的阈值要调、正负样本的匹配策略要调每个数据集都得重新折腾一遍。DETREnd-to-End Object Detection with Transformers出来的时候最吸引我的不是它刷了多高的mAP而是它把上面那一整套手工设计的组件全砍掉了没有anchor没有NMS没有复杂的正负样本分配规则就是一个CNN backbone加一个Transformer编解码器直接输出固定数量的检测结果。这意味着什么意味着你换一个数据集理论上不需要重新设计anchor的宽高比不需要纠结IoU阈值设0.5还是0.7。对于做小目标检测、遥感图像目标检测、或者像手机屏幕缺陷检测这种类别少但形态多变的场景DETR的思路其实比YOLO系列更省心。当然它也有代价——收敛慢、小目标效果一般、训练需要更多epoch。但理解它的设计哲学对你后面看RT-DETR、DINO、甚至Swin Transformer做检测的变体都有帮助。这篇文章我打算按自己读论文和复现代码的顺序来写先讲清楚它到底把传统检测框架的哪些环节替换掉了再拆Transformer编码器解码器在检测任务里具体怎么用然后讲二分图匹配损失这个核心设计接着是位置编码和训练调参的实操细节最后聊聊它在小目标、自定义数据集上的表现和我踩过的坑。适合已经了解Transformer基本结构、想搞明白DETR到底怎么工作的人也适合跑过YOLO想换个思路的工程师。2. DETR把传统目标检测的哪些环节连根拔了2.1 从“先撒框再筛选”到“直接出集合”传统检测器的工作方式你可以理解成在一个城市里找特定建筑先在地图上密密麻麻画几万个格子anchor然后逐个判断这个格子里有没有目标、是什么目标、边界要不要微调。最后因为很多格子都框到了同一栋楼还得用NMS把重复的去掉。这套流程的麻烦在于anchor的设计强依赖数据集——你检测的是行人还是飞机anchor的宽高比完全不一样。而且NMS本身是个不可微的后处理训练和推理之间存在割裂。DETR的做法完全不同。它设定一个固定的检测数量N比如100个。然后让Transformer解码器一次性输出这100个结果每个结果包含类别和归一化的边界框坐标。如果图里只有3个目标那剩下的97个结果就预测为“无目标”类别。这里的关键是这100个输出之间是有交互的解码器里的自注意力机制让每个查询都能看到其他查询在关注什么所以它们会自然地分工不会都去抢同一个目标。这就从根本上避免了重复框的问题NMS自然就不需要了。注意DETR并不是真的“没有筛选”而是把筛选的工作交给了Transformer的自注意力机制和二分图匹配损失。它是在训练过程中学会让不同的查询对应不同目标的。2.2 集合预测视角下的损失函数设计既然输出是一个集合那怎么定义损失传统检测器是每个anchor单独算分类和回归损失然后加权求和。DETR不行因为它的100个输出和图中的M个真实目标之间没有预先定义的一一对应关系。你总不能随便拿第1个输出去匹配第1个目标吧那顺序一变损失就乱了。所以DETR用了二分图匹配bipartite matching。具体来说它把预测集合和真实目标集合之间的匹配问题转化成一个匈牙利算法可以求解的最优分配问题。匹配的代价同时考虑分类概率和边界框的相似度L1距离加GIoU。找到最优匹配之后再对匹配上的预测算分类损失和框回归损失没匹配上的预测只算“无目标”的分类损失。这个设计是整个DETR最精妙的地方也是它区别于所有传统检测器的核心。我一开始看论文的时候觉得这个匹配过程会很慢但实际上因为N固定是100真实目标数量一般也就几十个匈牙利算法的开销完全可以接受。而且PyTorch里scipy的linear_sum_assignment直接就能用代码量很少。2.3 和YOLO系列在工程直觉上的差异如果你跑过YOLOv5或者YOLOv8你会发现它们的训练流程里有一大堆超参数anchor的聚类、正样本的IoU阈值、损失函数的权重比例、NMS的置信度阈值和IoU阈值。这些参数在不同数据集上都要重新调有时候调不好模型直接不收敛。DETR把这些全去掉了换来的是一套更“端到端”的流程。你只需要定义好backbone、Transformer的层数、查询数量N剩下的交给损失函数和优化器。这对于做自定义数据集的人来说其实是好事——少了很多玄学调参的环节。但代价是DETR的收敛非常慢原论文在COCO上要训练500个epoch才能达到和Faster R-CNN差不多的效果而YOLO可能几十个epoch就收敛了。所以如果你追求快速出结果DETR不是首选但如果你想理解检测任务最本质的集合预测形式DETR值得细读。3. Transformer编解码器在检测任务里到底干了什么3.1 CNN backbone先把图变成特征序列DETR的输入是一张3×H×W的图首先经过一个CNN backbone原论文用的是ResNet-50输出一个C×H/32×W/32的特征图。比如输入800×1066的图backbone输出大概是2048×25×34。然后用一个1×1卷积把通道数降到d256得到256×25×34的特征图。接下来是关键一步把空间维度展平。25×34850个位置每个位置是一个256维的向量。再加上位置编码就得到了一个850×256的序列。这个序列就是Transformer编码器的输入。你可以把这850个向量理解成图像被切成了850个patch每个patch用一个256维的向量表示。这和Vision Transformer的做法很像只不过DETR用的是CNN特征而不是直接切patch。提示backbone输出的特征图越大序列越长Transformer的计算量就越大。原论文用的是ResNet-50的C5层下采样32倍。如果你换成ResNet-18或者把下采样倍数改小序列会变长显存和计算时间都会明显增加。3.2 编码器让每个位置都看到全图信息编码器就是标准的Transformer encoder结构由6层组成每层包含一个多头自注意力模块和一个前馈网络。自注意力的作用是让每个位置的特征都能和其他所有位置的特征交互。比如图像左上角有一个车轮右下角有一个车灯编码器通过自注意力可以让这两个位置的特征互相“看到”从而判断它们可能属于同一辆车。这和CNN的感受野扩展方式完全不同。CNN是靠层层堆叠来扩大感受野浅层只能看到局部深层才能看到全局。而Transformer编码器从第一层开始就是全局感受野每个位置都能直接和所有位置交互。这对于检测大目标或者需要全局上下文判断的场景很有优势。比如检测一只鸟如果只看局部可能分不清是鸟还是飞机但结合背景的天空、树枝等信息就很容易判断。编码器的输出是一个850×256的序列每个位置的特征都已经融合了全图的信息。这个序列接下来会作为解码器的key和value。3.3 解码器从100个查询里“问”出检测结果解码器的输入有两部分一部分是编码器的输出作为key和value另一部分是100个可学习的查询向量object queries每个查询是256维。这100个查询是随机初始化的在训练过程中逐渐学会关注图像的不同区域和不同类别。解码器也是6层每层包含三个模块自注意力查询之间互相看、交叉注意力查询看编码器输出、前馈网络。自注意力的作用是让100个查询之间互相协调避免多个查询都去检测同一个目标。交叉注意力是让每个查询从编码器输出的850个位置里提取自己需要的信息。解码器输出100个256维的向量每个向量经过一个共享的前馈网络就是两个全连接层分别预测类别和边界框。类别用softmax边界框用sigmoid归一化到[0,1]。最终得到100个预测结果每个包含类别概率和归一化坐标。我实际跑的时候发现这100个查询确实会分化。可视化之后能看到有些查询专门负责图像左侧区域有些负责右侧有些负责大目标有些负责小目标。这种分工不是人为指定的而是通过二分图匹配损失在训练中自然形成的。3.4 位置编码为什么不能省Transformer的自注意力本身是置换不变的也就是说如果你把输入序列的顺序打乱自注意力的输出不变。但图像是有空间结构的左上角和右下角的位置信息必须保留。所以DETR在编码器输入和解码器的交叉注意力里都加了位置编码。原论文用的是正弦位置编码和原始Transformer一样。具体做法是对每个位置的正弦和余弦函数值进行拼接得到一个256维的向量然后加到backbone输出的特征上。解码器那边查询向量本身是可学习的但交叉注意力里的key也加了位置编码这样查询才能知道它关注的是图像的哪个位置。我试过把位置编码去掉结果mAP直接掉了一半以上。模型完全分不清目标在左边还是右边边界框回归也乱了。所以位置编码在DETR里不是锦上添花而是必需品。4. 二分图匹配损失DETR最核心也最容易看懵的部分4.1 匹配代价矩阵怎么算假设一张图里有M个真实目标DETR输出N100个预测。我们要找到一个最优的一对一匹配使得总匹配代价最小。匹配代价同时考虑分类和框的位置。具体来说对于第i个预测和第j个真实目标代价定义为分类代价预测为真实类别的概率的负值。如果预测的类别和真实类别越接近这个代价越小。框代价预测框和真实框的L1距离加上GIoU损失。L1距离衡量坐标数值的差异GIoU衡量两个框的形状和重叠程度。总代价是这两部分的加权和。然后把这个代价矩阵丢给匈牙利算法得到最优匹配。匹配上的预测和真实目标一一对应没匹配上的预测就对应“无目标”。注意匹配代价里的分类概率是直接用softmax输出的概率而不是log概率。这一点在实现的时候容易搞错因为分类损失用的是log概率但匹配代价用的是概率。4.2 损失函数的具体构成匹配完成之后损失函数分三部分分类损失对所有预测算交叉熵。匹配上的预测用真实类别没匹配上的用“无目标”类别。原论文里“无目标”类别的损失权重降到了0.1因为大部分预测都是无目标的如果权重一样模型会倾向于把所有东西都预测成无目标。框回归损失只对匹配上的预测算。包括L1损失和GIoU损失两者加权求和。L1损失直接优化坐标数值GIoU损失优化框的重叠程度。辅助损失在解码器的每一层后面都加一个预测头算同样的损失。这样做是为了帮助梯度更好地传播加速收敛。原论文里辅助损失的权重和最后一层一样。我一开始觉得辅助损失没必要后来试了一下去掉辅助损失收敛速度明显变慢而且最终mAP也低了一两个点。所以如果你要复现DETR辅助损失最好保留。4.3 匈牙利算法在代码里怎么用PyTorch里可以用scipy的linear_sum_assignment一行代码就能求解最优匹配。代价矩阵的大小是N×MN100M一般不超过几十所以计算量很小。但要注意如果一张图里没有目标M0那匹配就直接跳过所有预测都算无目标损失。实际写代码的时候代价矩阵的计算要放在no_grad里因为匹配过程不需要梯度。匹配结果拿到之后再用它来索引预测和真实目标计算最终的损失。这个顺序不能反否则计算图会出问题。我踩过的一个坑是代价矩阵里的分类代价用的是预测概率但分类损失用的是log概率。如果搞混了匹配结果会不对模型很难收敛。建议在代码里把这两个概率分开命名避免混淆。5. 训练DETR时那些论文里不会写的实操细节5.1 学习率和优化器的选择原论文用的是AdamWbackbone的学习率是1e-5Transformer部分是1e-4。这个差异很重要因为backbone是预训练的学习率太大会破坏预训练权重Transformer是随机初始化的学习率太小收敛太慢。权重衰减设的是1e-4。我试过统一用1e-4的学习率结果backbone的特征被破坏得很厉害mAP比分开设置低了三个点以上。所以如果你要复现一定要把backbone和Transformer的学习率分开设置。另外学习率衰减用的是step schedule在第400个epoch的时候降10倍。但如果你只训练几十个epoch这个衰减策略就不适用了需要自己调整。5.2 数据增强的取舍DETR原论文用了比较激进的数据增强随机裁剪、随机缩放、颜色抖动。但要注意随机裁剪会改变目标的尺度和位置对于小目标检测来说可能会把目标裁掉。我在做小目标检测的时候把随机裁剪的概率调低了否则很多小目标直接消失了。另外DETR对输入图像的尺度比较敏感。原论文把图像短边缩放到480到800之间长边不超过1333。如果你把输入尺度设得太大序列长度会急剧增加显存吃不消设得太小小目标的信息会丢失。我一般把短边设在600左右长边不超过1000这样在显存和精度之间比较平衡。5.3 训练epoch数和收敛判断DETR最大的问题就是收敛慢。原论文在COCO上训练了500个epoch用了16块V100。如果你只有一块卡可能要跑好几天。我建议先用小数据集比如自己标注的几百张图跑通流程确认损失能正常下降再上大数据集。判断收敛不能只看总损失要分开看分类损失和框回归损失。分类损失一般下降得比较快框回归损失下降得慢。如果框回归损失一直不降可能是学习率太大或者位置编码有问题。另外mAP在训练前期会波动很大不要因为前几十个epoch的mAP低就放弃DETR就是这样后面会慢慢涨上来。提示如果你不想从头训练可以直接用原论文的预训练权重然后在自己的数据集上微调。微调的时候学习率要调小backbone可以冻结前几层只训练后面的层和Transformer部分。5.4 显存不够时的几种降级方案DETR的显存占用主要来自Transformer的注意力矩阵。序列长度是H/32×W/32如果输入是800×1066序列长度就是850注意力矩阵是850×850还可以接受。但如果输入更大比如1333×1333序列长度超过1700注意力矩阵就爆炸了。显存不够的时候可以试这几种方案一是把backbone换成ResNet-18特征图通道数少一些二是把输入尺度降下来短边设到480三是减少解码器的层数从6层降到3层四是减少查询数量从100降到50。这些都会影响精度但至少能跑起来。我试过把查询数量降到50mAP掉了大概两个点但显存省了不少。6. DETR在小目标和自定义数据集上的真实表现6.1 小目标检测为什么是DETR的短板DETR用的是ResNet-50的C5层下采样32倍。如果输入是800×1066特征图是25×34每个位置对应原图32×32的区域。如果一个目标在原图里只有20×20像素那它在特征图上还不到一个像素信息基本丢失了。这就是DETR小目标效果差的核心原因。相比之下YOLO系列用了FPN特征金字塔把浅层的高分辨率特征和深层的语义特征融合在一起小目标可以在浅层特征上被检测到。DETR原论文没有用FPN所以小目标mAP明显低于大目标。后来的一些改进工作比如Deformable DETR和RT-DETR都引入了多尺度特征来解决这个问题。如果你要做小目标检测直接用原版DETR效果不会好。可以考虑两个方向一是用Deformable DETR它用可变形注意力代替了全局注意力计算量小而且支持多尺度二是自己在DETR基础上加一个FPN把浅层特征也送进编码器。我试过第二种方案小目标mAP能提升五六个点但序列长度会增加显存和计算时间也会增加。6.2 自定义数据集标注的注意事项DETR对标注格式的要求和YOLO不一样。YOLO用的是归一化的中心点坐标加宽高DETR用的是归一化的左上角和右下角坐标。转换的时候要注意如果标注框超出图像边界要裁剪到[0,1]范围内否则损失计算会出问题。另外DETR对“无目标”类别的处理比较敏感。如果你的数据集里有很多小目标而你在数据增强的时候又把它们裁掉了那模型会学到很多“无目标”的样本导致漏检。我建议在做随机裁剪的时候检查一下裁剪后还剩多少目标如果目标太少就跳过这次裁剪。还有一个坑是类别不平衡。如果你的数据集里某一类特别多其他类特别少DETR的分类损失会被多数类主导。可以在分类损失里给少数类加权重或者用focal loss代替交叉熵。我试过focal loss对类别不平衡的场景有一定改善但需要调focusing参数。6.3 微调预训练模型的实际操作如果你不想从头训练可以用原论文的预训练权重微调。具体做法是加载backbone和Transformer的权重把最后的分类头换成你自己的类别数然后冻结backbone的前几层只训练后面的层和Transformer。学习率设小一点比如backbone用1e-6Transformer用1e-5。微调的时候要注意原论文的查询数量是100如果你的数据集里目标很少比如每张图只有一两个目标那100个查询可能太多了可以降到20或50。但查询数量不能太少否则模型没有足够的“容量”去表示不同位置和类别的目标。我一般设50在精度和速度之间比较平衡。微调的epoch数不用太多一般50到100个epoch就够了。如果mAP在20个epoch之后还在涨可以继续训练如果已经平了就停。我试过在一个500张图的数据集上微调大概30个epoch就收敛了mAP比从头训练高了十几个点。7. 从DETR到RT-DETR这条技术路线后来怎么走的7.1 Deformable DETR解决了什么问题Deformable DETR是DETR最重要的改进之一。它把编码器里的全局自注意力换成了可变形注意力每个位置只关注少数几个采样点而不是所有位置。这样做有两个好处一是计算量大幅降低序列长度可以做得更长二是支持多尺度特征小目标检测效果明显提升。具体来说可变形注意力对每个查询学习一组采样偏移量然后在特征图上采样。这样每个查询只需要关注它认为重要的几个位置而不是全图。这既保留了全局信息的灵活性又避免了全局注意力的计算爆炸。Deformable DETR的收敛速度也比原版DETR快很多大概50个epoch就能达到原版500个epoch的效果。7.2 RT-DETR为什么适合实时检测RT-DETR是最近比较火的一个工作它的目标是在保持DETR端到端优势的同时达到实时检测的速度。它主要做了几件事一是用高效的混合编码器代替了原来的Transformer编码器减少了计算量二是用IoU-aware的查询选择让解码器的查询更有针对性三是去掉了NMS真正做到了端到端。我实测下来RT-DETR在COCO上能达到和YOLOv8差不多的速度和精度而且没有NMS后处理。这对于部署到边缘设备或者手机端很有吸引力。如果你要做手机屏幕缺陷检测这类任务RT-DETR比原版DETR更合适因为它的速度和精度都更平衡。7.3 这条路线对目标检测领域的长期影响DETR最大的贡献不是它当时的精度而是它证明了目标检测可以不用anchor、不用NMS、不用手工设计的匹配策略。这个思路影响了后面一大批工作包括DINO、Mask DINO、Group DETR等等。现在很多检测器都在往端到端的方向走NMS正在被逐渐淘汰。从工程角度看端到端检测器的好处是部署简单。传统检测器导出ONNX之后还要自己实现NMS不同框架的NMS实现还有差异容易出bug。DETR系列直接输出最终结果导出和部署都更干净。虽然现在DETR系列的速度还不如YOLO但随着RT-DETR这类工作的推进差距在快速缩小。我个人在实际项目里的体会是如果你做的是类别少、目标大、对速度要求不极致的场景DETR系列很省心如果你做的是小目标、密集目标、或者需要极致速度的场景YOLO系列或者RT-DETR更合适。选型的时候不要只看论文里的mAP要结合自己的数据特点和部署环境来定。最后再分享一个小技巧跑DETR之前先把输入尺度、查询数量、学习率这三个参数调一遍它们对结果的影响比Transformer层数大得多。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

商业模式黑话入门:toB、toC、toD、B2B、C2C、O2O、B2C、P2P全解析 2026/9/25 1:46:52

商业模式黑话入门:toB、toC、toD、B2B、C2C、O2O、B2C、P2P全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Win11磁盘根目录新建文件夹权限问题深度解析与四类场景解法 2026/9/25 1:46:52

Win11磁盘根目录新建文件夹权限问题深度解析与四类场景解法

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
光猫超级密码原理与安全启用指南 2026/9/25 1:46:52

光猫超级密码原理与安全启用指南

简介:本资源是一份面向网络运维人员、通信工程技术人员及家庭宽带DIY爱好者的FTTH光猫深度配置指南,聚焦电信定制型光猫(如华为HG8245、E8-C等)超级管理员权限获取与路由模式改造。内容完整覆盖telnet登录、shell环境进入、从hw_c…

阅读更多 →
秒到飞秒换算全解析:毫秒、微秒、纳秒、皮秒时间单位一次捋清 2026/9/25 1:46:52

秒到飞秒换算全解析:毫秒、微秒、纳秒、皮秒时间单位一次捋清

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
XDMA驱动底层读写DLL封装:PCIe DMA传输与上位机接口设计 2026/9/25 1:46:52

XDMA驱动底层读写DLL封装:PCIe DMA传输与上位机接口设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
数控平面磨床哪家好?天津铭杰数控提供高刚性磨床设备,支持试样加工与工艺验证 2026/9/25 1:46:46

数控平面磨床哪家好?天津铭杰数控提供高刚性磨床设备,支持试样加工与工艺验证

数控平面磨床行业基础科普数控平面磨床是借助数字化控制系统完成平面磨削加工的高精度加工设备,是磨床品类中应用范围最广的一类加工装备,主要用于对金属或者其他材质工件的平面、台阶面、沟槽等部位做精密加工,能实现较高的加工精度与表面光…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞