想象你经营一家餐厅,后厨忙成一团。老办法是这样的:服务生先在每张餐桌上贴满几百张贴纸,每张贴纸都预测“这里可能有一道菜”,可结果往往是同一道菜被七八张贴纸同时贴上。为了避免重复上菜,后厨还得专门安排一个人反复比对、撕掉多余贴纸(这就是 NMS 非极大值抑制);就连贴纸的尺寸、形状、贴多密,都得靠大厨多年经验设计(这就是 Anchor 锚框)。流程又繁琐又脆弱,还经常漏掉角落里的小菜品。 2020 年,Meta(原 Facebook)AI 团队端出了全新的方案——DETR(Detection Transformer)。它不贴纸了,而是直接备好 100 个固定的“空盘子”(目标查询),请来一位拥有全局视野的 Transformer 大厨:扫一眼全场所有食材,果断决定“这个盘子装这份菜,那个盘子装那份菜”。每个盘子只装一道菜,绝不重复;菜单和摆盘位置一次成型,彻底告别撕贴纸和设计贴纸的烦恼。 这套“一盘一菜”的设计背后,藏着三个核心秘密:用自注意力获得全局视野、用空盘子替代锚框、用二分图匹配保证不重复。读完这篇文章,你就能从零理解这套端到端目标检测的新范式,以及它为什么深刻改变了计算机视觉的思考方式。
掌握 DETR,意味着你理解了所有现代 Transformer 检测器的共同底座(Deformable DETR、DINO、RT-DETR 都是它的后代);从“手工后处理”到“端到端建模”的思维转变,是 AI 算法工程师进阶路上至关重要的一课。
目录
可视化演示
演示DETR端到端目标检测Transformer的核心机制:编码器-解码器架构、二分图匹配、目标查询和与传统检测器对比,通过交互式动画展示DETR的创新设计。
本节配有交互动效(进入视口后自动加载,约 3KB)。
编码器-解码器架构 CNN骨干提取特征图 Transformer编码器处理序列 解码器+目标查询输出预测 DETR开创端到端检测新范式
1. 传统检测的“贴纸困境”
旧厨房里,服务生为了不放过任何一道菜,会在餐桌上铺满密密麻麻的贴纸。每张贴纸就是一个“锚框”(Anchor Box),它有自己的位置、宽高和比例。问题是:贴纸铺多少、铺多大、怎么铺,全凭大厨的经验——这正是传统检测器最令人头疼的地方。
在 CNN 目标检测里,Anchor 是预先定义好的一组候选框,密集地铺在特征图的每个位置上。以 Faster R-CNN 为例,一张输入图片经过骨干网络后,特征图只有几十乘几十的分辨率,但每个位置要铺多个不同尺寸比例的锚框,候选框数量轻松达到数万个,其中绝大多数都是背景。
1. H(特征图高度):餐桌横排格子的数量,对应特征图的高这一维度。
2. W(特征图宽度):餐桌竖排格子的数量,对应特征图的宽这一维度。
3. A(每格贴纸数):每个格子铺几张贴纸,通常取 3 到 9 个不同尺寸比例。
4. 相乘(总贴纸数):三者相乘就得到需要逐一判断“有没有物体”的候选框总量。
锚框铺完,还要面对“正负样本不均”:成千上万个锚框里只有几十个真正框住物体,其余全是负样本,训练时必须精心设计采样策略。更麻烦的是,同一个物体常被多个锚框同时命中,于是需要 NMS 按得分排序、反复抑制重复框。这一整套手工设计(锚框尺寸、比例、IoU 阈值、NMS 阈值)又脆又繁——换一个数据集,往往就要从头再调一遍。
贴纸困境的根源,是“先在局部乱猜、再全局收拾残局”的两段式思路。DETR 要做的,就是请一位不一样的厨师,用全新的配菜逻辑一次性解决问题。
2. Transformer 大厨的“全局视野”
要摆脱贴纸困境,先得有一位能“一眼看全桌”的大厨。普通的 CNN 大厨只能看到自己拳头大小的一块区域(局部感受野),想看全桌得一层层叠高、不断“垫脚”。Transformer 的自注意力机制则不同,它像大厨的目光在整张餐桌上来回扫视,任何两道菜之间都能直接建立联系。
自注意力是 Transformer 的灵魂。特征序列中的每个位置都生成三个向量:查询(Query)、键(Key)、值(Value)。查询与所有键做相似度打分,打分越高的位置,其值在加权求和时占的比重越大。一句话:让每个位置都能“盯着全场说话”。
1. Q(查询向量):大厨的目光,代表“我在找什么”。
2. K(键向量):每道菜的标签,代表“我是什么”。
3. QK^T(相似度打分):目光与全场标签逐一比对,得到匹配分数。
4. 1/√d_k(缩放因子):防止点积数值过大导致 softmax 进入饱和区、梯度消失。
5. softmax(归一化为权重):把分数变成一组加起来等于 1 的“注意力权重”。
6. ×V(加权求和):按权重汇总全场的值向量,得到融合全局信息的输出。
自注意力的计算复杂度是 O(n²),n 是序列长度。在 DETR 里,图像被展平成几千个特征块,两两之间都要计算关系,这正是“全局推理”的来源——远处的两个物体能不能同时出现、有没有遮挡,大厨一目了然。代价是计算量大,但这换来了端到端建模的能力。
有了全局视野的大厨,DETR 终于可以放心地撤掉桌面上所有贴纸。接下来,我们看看这套新厨房的完整流水线。
3. 新厨房流水线:DETR 整体架构
新厨房的流水线分四段:备菜、摆上传送带、大厨烹饪、装盘出菜。备菜师傅是 CNN 骨干网络(如 ResNet),把原始图像加工成特征图;接着特征图被“展平”成一长条序列,并贴上座位号(位置编码);然后送进 Transformer 编码器,让大厨反复全局扫视;最后解码器结合“空盘子”逐盘确认装什么菜、摆在哪里。
形式化地,输入图像 x 先经过 CNN 得到特征图,展平后加上位置编码,成为编码器的输入序列。位置编码至关重要——如果没有座位号,展平后的特征块就分不清“原来在图像的哪个位置”,全局视野就变成了“脸盲”。
1. CNN(x)(特征提取):备菜师傅把原始图像切成长宽缩小、通道变深的特征图。
2. Flatten(序列化展平):把二维特征图拉直,变成一长串“食材块”序列。
3. PE(位置编码):给每个食材块贴上“原来在哪”的座位号,保留空间信息。
4. z₀(编码器输入):特征与座位号相加后的结果,是编码器读到的第一行“菜谱”。
编码器由多层 Transformer Encoder 堆叠而成,每层都做自注意力。解码器则不同:它不只读特征序列,还要读一组“目标查询”(Object Queries)。DETR 的预测头很简单——每个查询对应一个类别 logits 和一个 4 维边框(中心 x、中心 y、宽、高),直接输出即可。
流水线从原始图像到最终预测,一气呵成、没有任何中间后处理模块。这正是“端到端”的字面含义:输入像素、输出预测,中间所有环节联合训练、可微传播。
4. 100 个“空盘子”:目标查询机制
新厨房里最显眼的,是备餐台上那 100 个一模一样的空盘子,这就是“目标查询”。它们不是普通盘子,而是 100 个可学习的向量嵌入,从训练开始到结束都在不断“进化”,逐渐学会“我负责找哪种类型的菜”。
与传统的滑窗或锚框不同,目标查询不需要分布在具体位置上——它分布在“语义空间”里。解码器每一层都会让这些查询去“读取”编码器的特征,每个查询最终输出一个预测。由于查询是固定数量的(默认 100),DETR 最多检测 100 个物体,这对绝大多数场景绰绰有余。
1. Q_query(目标查询矩阵):100 个可学习的空盘子,它们不是固定位置,而是可进化的语义向量。
2. z₀(编码器记忆):编码器输出的全局特征“菜谱”,包含整张图的上下文信息。
3. Decoder(解码器):大厨对照菜谱给每个盘子配菜的过程,通常堆叠 6 层。
4. O(解码输出):装好盘的 100 份预测,每份可拆成类别 logits 和边框坐标。
并行解码是 DETR 的另一特点:100 个查询同时被解码,不需要像 NLP 那样一个一个“吐词”。但并行解码有个隐患——如果不加约束,多个查询可能抢同一道菜。DETR 的解决办法,就是下一节的主角:二分图匹配。
空盘子不是万能的,但配合匹配机制后,它们成了绝妙的“席位预约系统”:座位固定、数量固定、每座一客,从根源上消灭了重复预订。
5. 上菜的艺术:二分图匹配
有了 100 个盘子和若干道真实菜品,怎么决定“哪个盘子端哪道菜”?DETR 的做法是:把这个问题当成一场“最佳配对”——每道菜最多进一个盘子,每个盘子最多端一道菜,让总体的“默契分”最高。这就是二分图匹配,用匈牙利算法求解。
训练时,DETR 把预测的 100 份结果和真实的物体集合(通常不到 100 个)组成一个二分图:左边是预测,右边是真值(外加若干“空位”)。每一条边都有一个成本——分类不匹配的代价加上边框不重合的代价。匈牙利算法一次性求出全局最优的配对方案,保证每个真值只被一个查询负责。
1. N(预测数量):预测总数等于目标查询数,DETR 默认取 100。
2. σ(一个配对方案):一种把预测和真值对应起来的排列,回答“哪个盘子端哪道菜”。
3. S_N(所有排列的集合):全部可能的配对方案,共 N! 种。
4. L_match(匹配成本):单个配对“不默契”的代价,由分类错误和边框偏差共同构成。
5. argmin(选最优):在所有方案中挑出总成本最低的那个,记为 σ̂。
匹配完成后,才计算真正的检测损失。匹配损失只用于“找人”,而最终的训练损失是对齐后每一对的分类损失加边框损失(L1 + GIoU)之和。更重要的是:因为匹配是“一对一”的,预测天然没有重复框——测试时直接用匹配好的查询输出即可,NMS 被彻底请出厨房。
二分图匹配的精髓是“全局最优的一对一分配”。它把“去重”从后处理变成了训练目标的一部分,这正是 DETR 敢宣称端到端的底气。
6. 与大厨 Faster R-CNN 过招
老牌大厨 Faster R-CNN 功勋卓著,但它的厨房里摆满了各类“秘制道具”:锚框生成器、RPN 区域建议网络、RoI 池化、NMS 去重……每一步都是独立调参的模块,误差会层层累积。DETR 把它们全部精简为“一张编码器-解码器的桌子 + 100 个空盘子”。
从数量上看差距震撼:传统检测器的候选锚框动辄数万甚至十万个,而 DETR 的候选“盘子”只有 100 个。
1. N_query(查询数量):DETR 的候选盘子数,默认固定为 100。
2. N_anchor(锚框数量):传统检测器的贴纸数,高分辨率输入下可达十万数量级。
3. ≪(远小于):表示两者相差约三个数量级,也暗示设计哲学的差异。
但 DETR 并非完美。它的老毛病有三:其一,小目标检测弱——特征图分辨率有限,小物体信息在多次下采样后难以保留;其二,收敛特别慢——需要约 500 个 epoch 才能媲美 Faster R-CNN,而后者通常十几个 epoch 就初见成效;其三,计算量大,自注意力的二次复杂度在高分辨率输入上非常昂贵。
好在后续改进者层出不穷:Deformable DETR 用可变形注意力聚焦稀疏的关键点、引入多尺度特征,把小目标短板补上大半,同时把收敛提速约 10 倍。这说明:DETR 的“端到端”范式是对的,工程上的短板正在被逐一攻克。
7. 端到端:一个范式的诞生
把 DETR 的所有零件拼起来,你会看到一幅简洁的图画:输入图像 x,直接输出预测 y,中间的 CNN、Transformer、匹配机制全部作为一个整体进行训练。没有任何手工后处理,没有不可微的模块——这就是端到端。
1. x(输入图像):原始像素,不经过任何手工特征工程。
2. f_θ(整体网络):CNN 骨干 + Transformer 编码器/解码器 + 预测头,全部参数由 θ 表示。
3. y(输出预测):一组“类别 + 边框”的集合,直接可用。
4. θ*(最优参数):通过最小化损失函数学习到的最终参数。
端到端带来的红利是多维的:去掉了锚框和 NMS,新类别扩展不再需要重新设计锚框比例;全局匹配让模型自动学会“一个物体只有一个预测”;统一的可微流程让研究者可以像搭积木一样替换组件(换骨干、换解码器、换匹配成本),而不用推翻整个系统。
从工程角度,DETR 把检测任务从“分类+回归+后处理”三段式,压缩成了“一个模型、一个损失、一次前向”。这大幅降低了部署和调参成本——以前调 NMS 阈值、锚框比例的经验活,现在都变成了数据驱动。
回看整篇文章的比喻:旧厨房满桌贴纸、人工撕重复;新厨房 100 个空盘子、大厨全局扫视、一次配菜到位。DETR 告诉我们的不只是“换了个模型”,而是:当你能把任务定义成“一一对应”的匹配问题时,很多繁琐的中间环节都可以直接消失。
AI 应用场景
自动驾驶感知
阶段:模型部署与推理优化
解决的问题:自动驾驶需要同时检测车辆、行人、骑行者等多类目标,传统检测器的锚框和 NMS 阈值要针对不同距离、不同类别反复调参,部署时后处理逻辑复杂且难以在车规芯片上高效实现。DETR 端到端输出、天然无重复框,后处理逻辑极简,模型更易量化与加速。
具体案例:某自动驾驶团队将 DETR 作为基线检测器部署到车载 Orin 平台,用 TensorRT 加速 Transformer,推理时直接读取 100 个查询的输出,过滤低置信度后即可发送给跟踪模块,省去了 NMS 算子跨平台移植的麻烦。
医学影像病灶检测
阶段:模型训练与数据标注
解决的问题:病理切片与 CT 影像中病灶大小差异极大,传统锚框需要为不同尺度手动设计比例;DETR 的目标查询天然覆盖全局,配合二分图匹配可以稳定检测稀疏的微小病灶,对“一张图只有一两个目标”的低密度场景尤其友好。
具体案例:在肺结节检测任务中,单张 CT 切片通常只有 1 到 3 个结节,传统方法在数千个锚框中“大海捞针”;换成 DETR 后,100 个查询直接与结节做全局匹配,训练更稳定,误检率显著下降。
通用目标检测平台
阶段:模型迭代与新类别扩展
解决的问题:传统检测器新增一个类别,可能要重新调整锚框比例和正负样本策略;DETR 的匹配机制和查询设计与类别无关,加类别只需要修改分类头的输出维度,极大缩短了新类别的上线周期。
具体案例:某工业质检平台每季度新增缺陷类型,团队将 Faster R-CNN 换成 DETR 后,新类别从数据标注到上线的时间从两周缩短到两天,且无需人工调整任何后处理参数。
Python 演示
import numpy as npimport torchimport torch.nn as nn def simple_position(h, w, device): """极简位置编码: 把特征块序号归一化, 广播到所有通道""" pos = torch.arange(h * w, device=device).float() / (h * w) return pos.unsqueeze(0).unsqueeze(-1) class MiniBackbone(nn.Module): """迷你CNN骨干: 把224x224x3图像变成14x14x256特征图""" def __init__(self, in_ch=3, feat=256): super().__init__() self.net = nn.Sequential( nn.Conv2d(in_ch, 64, 3, 2, 1), nn.ReLU(), nn.Conv2d(64, 128, 3, 2, 1), nn.ReLU(), nn.Conv2d(128, feat, 3, 2, 1), nn.ReLU(), nn.Conv2d(feat, feat, 3, 2, 1), nn.ReLU(), ) self.proj = nn.Conv2d(feat, feat, 1) def forward(self, x): return self.proj(self.net(x)) class MiniDETR(nn.Module): """迷你DETR: CNN骨干 + 编码器 + 解码器 + 预测头""" def __init__(self, num_queries=100, num_classes=80, feat=256): super().__init__() self.backbone = MiniBackbone(feat=feat) enc_layer = nn.TransformerEncoderLayer(feat, 8, batch_first=True) self.encoder = nn.TransformerEncoder(enc_layer, num_layers=6) dec_layer = nn.TransformerDecoderLayer(feat, 8, batch_first=True) self.decoder = nn.TransformerDecoder(dec_layer, num_layers=6) self.queries = nn.Parameter(torch.randn(num_queries, feat)) self.class_head = nn.Linear(feat, num_classes + 1) self.box_head = nn.Linear(feat, 4) def forward(self, x): f = self.backbone(x) # (B,256,14,14) 备菜 b, _, h, w = f.shape z = f.flatten(2).transpose(1, 2) # (B,196,256) 展平传送带 pos = simple_position(h, w, x.device) mem = self.encoder(z + pos) # 编码器全局扫视 q = self.queries.unsqueeze(0).repeat(b, 1, 1) out = self.decoder(q, mem) # (B,100,256) 并行装盘 logits = self.class_head(out) # (B,100,C+1) boxes = self.box_head(out).sigmoid() # (B,100,4) return logits, boxes def hungarian_match(pred_logits, pred_boxes, gt_boxes, gt_labels): """二分图匹配: 为每个真值框找一个最优查询""" n_pred = pred_logits.shape[0] n_gt = gt_boxes.shape[0] cost = np.zeros((n_pred, n_gt)) for i in range(n_pred): for j in range(n_gt): cls_cost = -np.log(pred_logits[i, gt_labels[j]] + 1e-8) box_cost = np.abs(pred_boxes[i] - gt_boxes[j]).sum() cost[i, j] = cls_cost + box_cost try: from scipy.optimize import linear_sum_assignment row, col = linear_sum_assignment(cost) return list(zip(row, col)) except ImportError: matches, used = [], set() for _ in range(n_gt): i, j = min( ((i, j) for i in range(n_pred) for j in range(n_gt) if i not in [m[0] for m in matches] and j not in used), key=lambda ij: cost[ij[0], ij[1]]) matches.append((i, j)) used.add(j) return matches def main(): torch.manual_seed(0) model = MiniDETR(num_queries=10, num_classes=3) images = torch.randn(2, 3, 224, 224) logits, boxes = model(images) print("输出形状:", tuple(logits.shape), tuple(boxes.shape)) pred_logits = torch.softmax(logits[0], dim=-1).detach().numpy() pred_boxes = boxes[0].detach().numpy() gt_boxes = np.array([[0.10, 0.20, 0.30, 0.40], [0.55, 0.45, 0.20, 0.30]]) gt_labels = np.array([1, 2]) matches = hungarian_match(pred_logits, pred_boxes, gt_boxes, gt_labels) print("二分图匹配结果(查询索引, 真值索引):", matches) if __name__ == "__main__": main()
f = self.backbone(x)CNN 备菜师傅把原始图像切成特征图。z = f.flatten(2).transpose(1, 2)把特征图展平成一长条“食材传送带”,形状变成 (196, 256)。pos = simple_position(h, w, x.device)给每块食材贴座位号,也就是位置编码。mem = self.encoder(z + pos)编码器让大厨在整张图上反复全局扫视。q = self.queries.unsqueeze(0).repeat(b, 1, 1)端出固定数量的空盘子(目标查询)。out = self.decoder(q, mem)解码器并行装盘:每个盘子同时读取全局特征。logits = self.class_head(out)判断每道菜的类别,输出 C+1 个类别分数。boxes = self.box_head(out).sigmoid()输出每道菜的摆盘位置,归一化到 0~1。cost[i, j] = cls_cost + box_cost计算“菜-盘子”配对的联合成本。row, col = linear_sum_assignment(cost)匈牙利算法求出全局最优的一对一匹配。
常见误区
误区我以为 DETR 既然是 Transformer 检测器,肯定是用纯注意力结构替换掉卷积,跟 CNN 彻底拜拜了。
正解DETR 的骨干网络依然是 CNN(如 ResNet-50)。CNN 负责高效的局部特征提取(备菜师傅),Transformer 负责全局关系建模(掌勺大厨),两者分工明确、缺一不可。真正用纯 Transformer 做骨干的是 ViT,那是另一个故事。类比来说,DETR 只是换了“主厨思路”,并没有把“砧板师傅”开除。
为何常见:“Transformer 检测器”这个标签容易让人误以为全程都是注意力,忽略了 CNN 提取浅层特征的高性价比。
误区我觉得 100 个查询就表示图片里最多有 100 个物体,实际物体少了会浪费,应该把查询数设成数据集里最多物体的数量。
正解查询是固定的超参数(默认 100),它代表“最多可能检测的物体数”,不是“必须检测的数量”。物体少时,多余的查询会在匹配中落到“无物体”类(∅),什么也不输出。就像餐厅备了 100 个空盘子,不代表每桌必须坐满 100 位客人;盘子太少反而会漏菜。
为何常见:人容易把“名额”误解为“硬性要求”,忽略了背景类(∅)的存在。
误区我以为 DETR 通过二分图匹配直接输出结果,不存在正负样本不平衡问题,训练起来又快又稳。
正解DETR 依然有正负样本——只是它通过匹配动态分配:匹配成功的查询是正样本,剩余查询对应“无物体”负样本。它解决的是“正负样本比例悬殊且分配方式手工”的问题,而不是消灭正负样本。而且匹配在训练早期不稳定,反而导致 DETR 收敛缓慢,需要约 500 个 epoch。
为何常见:“端到端”“无需 NMS”等宣传词容易让人以为所有传统问题都消失了,实则它只是把问题换了一种解决方式。
误区我以为 DETR 完全数据驱动,一点点人工先验都没有,是绝对的“白纸模型”。
正解DETR 依然有先验:位置编码告诉模型特征来自哪里,可学习的目标查询在初始化时就带有语义偏好,预测头对边框参数做了归一化。它只是把“锚框尺寸比例”这类强先验,换成了更柔和的、可学习的先验。“无 Anchor”不等于“无先验”。
为何常见:“Anchor-Free“被望文生义地理解成”毫无先验”,其实 Anchor-Free 只是不依赖手工设计的固定框集合。
误区新范式看起来这么高级,速度肯定也更快,所有指标都应该全面超过 Faster R-CNN。
正解DETR 在 COCO 上 AP 与 Faster R-CNN 相当,大目标上更优,但小目标明显更弱;自注意力的 O(n²) 复杂度让它在高分辨率输入下推理并不快。它的价值主要在“范式”:流程极简、无需后处理、易扩展,而不是“每一项指标都碾压”。
为何常见:媒体常用的“革命性”“端到端”等词容易让人脑补出全面碾压的印象,忽略了论文里同样坦诚的局限分析。
面试题
Q1. DETR 的目标查询(Object Queries)本质上是一组什么?
- A.预先设计的锚框集合方案
- B.固定数量的可学习空盘子← 正确答案
- C.区域建议网络的输出结果
- D.对图像进行滑窗裁剪
答案:B。目标查询本质上是 100 个可学习的向量嵌入,像备餐台上等装菜的固定空盘子,B 正确。A 是锚框概念,C 是 Faster R-CNN 中 RPN 的产物,D 是滑动窗口思路,都与查询机制无关。
Q2. DETR 相比 Faster R-CNN,最关键的流程简化是?
- A.完全去掉骨干网络模块
- B.去掉 NMS 和 Anchor 设计← 正确答案
- C.去掉位置编码模块
- D.去掉自注意力机制
答案:B。DETR 最关键的简化是用“目标查询 + 二分图匹配”替代了 Anchor 和 NMS,B 正确。它没有去掉骨干 CNN(A 错),位置编码和自注意力是核心模块(C、D 错)。
Q3. DETR 默认使用多少个目标查询?
- A.128 个
- B.100 个← 正确答案
- C.1000 个
- D.90 个
答案:B。DETR 默认设置 100 个目标查询,对应最多同时检测 100 个物体,B 正确。128、1000、90 都不是论文的默认配置,属于干扰项。
Q4. 二分图匹配中匈牙利算法的作用是?
- A.对预测框做非极大值抑制
- B.找出全局成本最小的一对一配对← 正确答案
- C.计算每个锚框的 IoU 得分
- D.随机打乱查询排列顺序
答案:B。二分图匹配是一个分配问题,匈牙利算法能一次求出全局成本最小的一对一配对,B 正确。NMS 是局部贪心抑制(A 错),IoU 只是匹配成本的一部分(C 错),随机打乱显然荒谬(D 错)。
Q5. self-attention 公式中除以 √d_k 的主要原因是?
- A.提升模型非线性表达能力
- B.防止点积过大导致梯度消失← 正确答案
- C.使特征通道数量减半
- D.强制让注意力变成稀疏
答案:B。QK^T 点积会随维度增大而方差变大,除以 √d_k 起到缩放作用,防止数值过大进入 softmax 饱和区导致梯度消失,B 正确。其余选项与缩放目的无关。
Q6. DETR 训练时“空查询”(没有对应真值的查询)会怎样?
- A.直接丢弃不参与训练
- B.匹配到无物体背景类别← 正确答案
- C.与最近的查询合并
- D.强制分配一个随机真值
答案:B。没有真值对应的查询会在匹配中落到“无物体”背景类(∅),参与分类损失但不算边框损失,B 正确。直接丢弃会失去负样本约束,其余选项都不符合 DETR 的匹配逻辑。
Q7. 下列哪项是 DETR 对小目标检测效果差的主因?
- A.低分辨率特征图信息丢失← 正确答案
- B.匈牙利算法计算复杂度太高
- C.目标查询数量设置太少
- D.缺少 Anchor 尺度先验信息
答案:A。DETR 在单尺度低分辨率特征图上做全局建模,小目标经过多次下采样后信息几乎丢失,A 正确。匈牙利算法只影响训练效率(B 错),100 个查询足够(C 错),缺少锚框先验不是小目标问题的根因(D 错)。
Q8. DETR 相比传统检测器的优势包括?
- A.无需手工设计锚框大小比例← 正确答案
- B.无需非极大值抑制后处理← 正确答案
- C.训练阶段收敛速度更快
- D.整个流程端到端可微训练← 正确答案
答案:ABD。DETR 用目标查询和二分图匹配去掉了锚框与 NMS,且整个流程可微,A、B、D 正确。但 DETR 收敛比 Faster R-CNN 慢得多,需要约 500 个 epoch,C 是它的缺点而非优点。
Q9. 关于 DETR 的二分图匹配,正确的说法有?
- A.匹配损失含分类与边框回归← 正确答案
- B.空查询匹配到背景类别← 正确答案
- C.每个真值只配一个查询← 正确答案
- D.匹配损失与匈牙利算法完全无关
答案:ABC。匹配损失由分类负对数 + 边框损失(L1+GIoU)构成,空查询匹配到 ∅ 背景类,匹配保证一对一,A、B、C 正确。匈牙利算法恰恰是求解该匹配的核心工具,D 错误。
Q10. DETR 由哪些主要组件构成?
- A.CNN 骨干网络提取特征← 正确答案
- B.Transformer 编码器部分← 正确答案
- C.Transformer 解码器部分← 正确答案
- D.区域建议网络 RPN 模块
答案:ABC。DETR 由 CNN 骨干 + Transformer 编码器/解码器 + 预测头组成,A、B、C 正确。RPN 是 Faster R-CNN 的组件,DETR 中完全没有区域建议网络。