基本信息

项目 内容
论文标题 End-to-End Object Detection with Transformers
作者
作者单位 Facebook AI
时间 2020
发表会议/期刊 ECCV20
论文别名 DEtection TRansformer

方法概览

特点 文章性质
输入
输出
所属领域 目标检测

在 DETR 出现之前,主流目标检测器(如 Faster R-CNN、YOLO、SSD)存在以下问题:

问题 说明
Anchor 机制复杂 需预设大量 anchor boxes,超参数多,设计繁琐
NMS 后处理 非极大值抑制(NMS)不可导,无法端到端训练
多阶段设计 RPN + RoI Pooling + 分类回归,流程复杂
训练不稳定 正负样本不平衡、anchor 匹配策略复杂

创新点

  1. 首次将 Transformer 架构成功应用于目标检测任务,摒弃了传统检测器中复杂的组件如 anchor、NMS、多阶段设计,实现了端到端的目标检测

网络架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
输入图像

├── CNN Backbone(如 ResNet)
│ ↓
│ 特征图 (H/32, W/32, C)
│ ↓
├── 展平
│ ↓
│ N × C(N = H/32 × W/32)
│ ↓
├── 位置编码(Positional Encoding为特征图添加 2D 位置信息(sinusoidal 或 learned))
│ ↓
├── Transformer Encoder(输入:展平的特征图+位置编码通过多头自注意力建模全局上下文关系)
│ ↓
│ 编码后的特征
│ ↓
├── Object Queries(100个可学习的向量,核心创新之一)
│ ↓
├── Transformer Decoder(输入ObjectQueries+Encoder输出目标表示每个包含类别和坐标信息)
│ ↓
└── 预测头(FFN)

预测集合:{ (class, box) } × 100

Object Queries每个 query 对应一个“潜在目标”。解码器用这些 query 去“询问”图像中是否有目标。相当于传统检测中的“anchor”,但更抽象、更灵活
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import torch
import torch.nn as nn
from torchvision.models import resnet50

class DETR(nn.Module):
def __init__(self, num_classes=80, num_queries=100, hidden_dim=256):
super().__init__()
self.num_classes = num_classes
self.num_queries = num_queries

# 1. Backbone
self.backbone = resnet50(pretrained=True)
self.backbone.fc = nn.Identity() # 移除分类头
self.conv1x1 = nn.Conv2d(2048, hidden_dim, 1) # 降维

# 2. 位置编码(简化版)
self.pos_encoder = nn.Parameter(torch.randn(1, hidden_dim, 20, 20))

# 3. Transformer
encoder_layer = nn.TransformerEncoderLayer(d_model=hidden_dim, nhead=8)
decoder_layer = nn.TransformerDecoderLayer(d_model=hidden_dim, nhead=8)
self.encoder = nn.TransformerEncoder(encoder_layer, num_layers=6)
self.decoder = nn.TransformerDecoder(decoder_layer, num_layers=6)

# 4. Object Queries
self.query_embed = nn.Parameter(torch.randn(num_queries, hidden_dim))

# 5. 预测头
self.class_head = nn.Linear(hidden_dim, num_classes + 1) # +1 for ∅
self.bbox_head = nn.Sequential(
nn.Linear(hidden_dim, 4),
nn.Sigmoid() # 归一化到 [0,1]
)

def forward(self, x):
# x: (B, 3, H, W)
B = x.shape[0]

# 1. Backbone
feat = self.backbone.conv1(x)
feat = self.backbone.bn1(feat)
feat = self.backbone.relu(feat)
feat = self.backbone.maxpool(feat)
feat = self.backbone.layer1(feat)
feat = self.backbone.layer2(feat)
feat = self.backbone.layer3(feat)
feat = self.backbone.layer4(feat) # (B, 2048, H/32, W/32)

feat = self.conv1x1(feat) # (B, 256, 20, 20)

# 2. 展平 + 位置编码
feat = feat.flatten(2).permute(2, 0, 1) # (N, B, C)
pos = self.pos_encoder.flatten(2).permute(2, 0, 1)
feat = feat + pos

# 3. Encoder
memory = self.encoder(feat) # (N, B, C)

# 4. Decoder
query_embed = self.query_embed.unsqueeze(1).repeat(1, B, 1) # (100, B, 256)
tgt = torch.zeros_like(query_embed)
hs = self.decoder(tgt, memory) # (100, B, 256)
hs = hs.transpose(0, 1) # (B, 100, 256)

# 5. 预测
class_logits = self.class_head(hs) # (B, 100, 81)
bbox_coords = self.bbox_head(hs) # (B, 100, 4)

return class_logits, bbox_coords

# 使用示例
model = DETR(num_classes=80, num_queries=100)
x = torch.randn(2, 3, 800, 800)
class_logits, bbox_coords = model(x)
print(class_logits.shape) # (2, 100, 81)
print(bbox_coords.shape) # (2, 100, 4)

损失函数:二分图匹配(Bipartite Matching)

问题:如何匹配预测和真实框?

  • 预测有 100 个框,真实只有 K 个(K < 100
  • 不能简单用 MSE 或 CE,因为“哪个预测对应哪个真实框”未知
    ✅ 解决方案:匈牙利匹配(Hungarian Matching)
  1. 对每个真实框 g_j,找到最匹配的预测框 p_{σ(j)}
  2. 匹配代价:
    • 第一项:类别匹配损失(负的类别概率)
    • 第二项:边界框损失(L1 + GIoU)
  3. 使用匈牙利算法找到最优匹配 σ
  4. 最终损失:

DETR 的局限(早期版本)

问题 说明
❌ 小目标检测弱 CNN 下采样 32 倍,小目标特征丢失
❌ 收敛慢 训练需要 500+ epochs,远慢于传统检测器
❌ Decoder 查询冗余 100 个 query 中大部分预测为 
❌ 缺乏层级特征 仅用最后一层特征,缺少多尺度融合

后续发展:DETR 的“进化树”

为了解决上述问题,一系列改进方法被提出:

方法 解决的问题
Deformable DETR最成功 收敛慢、计算量大(用可变形注意力)
Conditional DETR 收敛慢(改进 query 设计)
Sparse R-CNN query 冗余(用 proposal boxes 初始化 query)
UP-DETR 无监督/弱监督预训练
DAB-DETR 更好的 query 设计(用 box 初始化)
RT-DETR 实时检测(轻量化 + 高速推理)
DN-DETR 加速收敛(用 “denoising” 训练)