12 KiB
DETR 中 Transformer 的过程说明
DETR(Detection Transformer)把目标检测任务改写成一个集合预测问题。它先用 CNN 提取图像特征,再把二维特征图展平成 token 序列,送入 Transformer Encoder 建模全局关系,最后用 Transformer Decoder 中的 object queries 去图像特征中查询目标。
1. 整体流程
原版 DETR 的主要流程如下:
输入图像
↓
CNN Backbone,例如 ResNet
↓
二维特征图 feature map
↓
1x1 卷积降维到 d_model = 256
↓
加入二维位置编码 positional encoding
↓
Transformer Encoder
↓
Transformer Decoder + object queries
↓
分类头 + 边界框回归头
↓
输出固定数量的检测结果
原版 DETR 常见配置:
| 数字 | 单位 / 含义 |
|---|---|
256 |
特征维度,单位是“维”,也就是每个 token 或 query 向量包含 256 个数值 |
6 |
Encoder 层数,单位是“层” |
6 |
Decoder 层数,单位是“层” |
8 |
attention head 数量,单位是“个 head” |
100 |
object query 数量,单位是“个 query”,表示最多输出 100 个候选检测槽位 |
2. Backbone 提取图像特征
输入图像的形状通常可以写成:
[B, 3, H, W]
其中:
| 符号 / 数字 | 单位 / 含义 |
|---|---|
B |
batch size,单位是“张图像”,表示一次输入多少张图 |
3 |
颜色通道数,单位是“个通道”,RGB 图像有 3 个通道 |
H |
图像高度,单位是“像素” |
W |
图像宽度,单位是“像素” |
图像经过 ResNet 这类 CNN backbone 后,会得到一个低分辨率的二维特征图。例如 stride 为 32 时,空间尺寸大约缩小为原图的 1/32:
[B, C, H/32, W/32]
这里的 32 表示下采样倍数,单位可以理解为“倍”。如果输入图像高度是 800 像素,那么经过 stride 32 的 backbone 后,特征图高度大约是:
800 / 32 = 25
也就是 25 个特征图位置。
以 ResNet-50 为例,最后输出通道数常见为:
[B, 2048, h, w]
其中:
| 数字 / 符号 | 单位 / 含义 |
|---|---|
2048 |
CNN 输出通道数,单位是“个通道” |
h |
特征图高度,单位是“个 feature map 网格位置” |
w |
特征图宽度,单位是“个 feature map 网格位置” |
然后 DETR 使用一个 1x1 卷积把通道数从 2048 降到 256:
[B, 2048, h, w] → [B, 256, h, w]
这里:
| 数字 | 单位 / 含义 |
|---|---|
1x1 |
卷积核尺寸,单位是“特征图网格”,表示卷积核覆盖 1 个高方向位置和 1 个宽方向位置 |
2048 |
输入通道数,单位是“个通道” |
256 |
输出特征维度,单位是“维”或“个通道”,也是 Transformer 的 d_model |
3. 把二维特征图展平成 token 序列
Transformer 处理的是序列,因此 DETR 会把二维特征图展平成一维 token 序列。
降维后的特征图形状是:
[B, 256, h, w]
展平空间维度后:
[B, 256, h*w]
再调整为 Transformer 常用格式:
[h*w, B, 256]
其中:
| 符号 / 数字 | 单位 / 含义 |
|---|---|
h*w |
token 数量,单位是“个 token”,每个 token 对应特征图上的一个空间位置 |
B |
batch size,单位是“张图像” |
256 |
每个 token 的向量维度,单位是“维” |
例如,如果特征图尺寸是:
25 x 34
其中 25 是特征图高度,单位是“个网格位置”;34 是特征图宽度,单位也是“个网格位置”。那么 token 数量是:
25 * 34 = 850
也就是 850 个视觉 token。
4. 加入二维位置编码
Transformer 本身不知道 token 在图像中的二维位置,所以 DETR 需要加入位置编码。
图像特征 token 是:
src: [h*w, B, 256]
位置编码是:
pos: [h*w, B, 256]
其中 256 的单位是“维”,表示位置编码向量和图像 token 向量具有相同维度,方便相加。
在 attention 中,通常把位置编码加到 query 和 key 上:
Q = src + pos
K = src + pos
V = src
这样 attention 在计算图像 token 之间关系时,就能利用空间位置信息。
5. Transformer Encoder
Encoder 的作用是让每个图像 token 都能关注整张图中的其他 token,从而获得全局上下文。
一层 Encoder 通常包含:
Multi-Head Self-Attention
↓
Add & Norm
↓
Feed Forward Network
↓
Add & Norm
在 Encoder self-attention 中:
Q = 图像 token + 位置编码
K = 图像 token + 位置编码
V = 图像 token
输入形状和输出形状保持一致:
[h*w, B, 256] → [h*w, B, 256]
其中:
| 符号 / 数字 | 单位 / 含义 |
|---|---|
h*w |
图像 token 数量,单位是“个 token” |
B |
batch size,单位是“张图像” |
256 |
token 特征维度,单位是“维” |
原版 DETR 使用 6 层 Encoder。这里的 6 单位是“层”,表示上述 Encoder block 重复堆叠 6 次。
6. Object Queries
Object query 是 DETR 的核心设计之一。
原版 DETR 默认使用:
num_queries = 100
也就是 100 个 object queries。这里的 100 单位是“个 query”,每个 query 可以理解为一个检测槽位。
每个 query 是一个可学习向量:
object_queries: [100, 256]
扩展到 batch 后:
[100, B, 256]
其中:
| 数字 / 符号 | 单位 / 含义 |
|---|---|
100 |
query 数量,单位是“个 query” |
B |
batch size,单位是“张图像” |
256 |
每个 query 的向量维度,单位是“维” |
可以把这 100 个 query 理解成 100 个检测槽位。每个槽位最后要么预测一个目标,要么预测 no object。
7. Transformer Decoder
Decoder 的输入包括两部分:
object queries: [100, B, 256]
encoder memory: [h*w, B, 256]
其中:
| 名称 | 单位 / 含义 |
|---|---|
object queries |
检测查询向量,单位是“个 query” |
encoder memory |
Encoder 输出的图像特征 token,单位是“个 token” |
每一层 Decoder 通常包含:
Object Query Self-Attention
↓
Cross-Attention with Encoder Output
↓
Feed Forward Network
原版 DETR 使用 6 层 Decoder。这里的 6 单位是“层”,表示 Decoder block 重复堆叠 6 次。
8. Decoder Self-Attention
Decoder 的 self-attention 发生在 object queries 之间。
输入形状:
[100, B, 256]
其中 100 是 query 数量,单位是“个 query”;256 是向量维度,单位是“维”。
这一步的作用是让不同 query 之间互相交换信息,减少多个 query 重复预测同一个目标的情况。
在 Decoder self-attention 中:
Q = object queries
K = object queries
V = object queries
输出形状仍然是:
[100, B, 256]
9. Decoder Cross-Attention
Cross-attention 是 DETR Decoder 中最关键的一步。
在 cross-attention 中:
Q 来自 object queries
K 来自 encoder 输出的图像 token
V 来自 encoder 输出的图像 token
对应形状是:
Q: [100, B, 256]
K: [h*w, B, 256]
V: [h*w, B, 256]
其中:
| 符号 / 数字 | 单位 / 含义 |
|---|---|
100 |
object query 数量,单位是“个 query” |
h*w |
图像 token 数量,单位是“个 token” |
B |
batch size,单位是“张图像” |
256 |
Q、K、V 向量维度,单位是“维” |
每个 object query 会对整张图的所有图像 token 做 attention,从图像特征中汇聚和自己相关的信息。
输出形状仍然是:
[100, B, 256]
10. Attention 中 Q、K、V 的维度
原版 DETR 的 Transformer 常见配置是:
d_model = 256
num_heads = 8
其中:
| 数字 | 单位 / 含义 |
|---|---|
256 |
Q、K、V 投影后的总向量维度,单位是“维” |
8 |
multi-head attention 的 head 数量,单位是“个 head” |
因此在 attention 中,Q、K、V 的总维度都是:
Q: 256 维
K: 256 维
V: 256 维
拆成 8 个 head 后,每个 head 的维度是:
256 / 8 = 32
这里的 32 单位是“维”,表示每个 attention head 内部处理的 Q、K、V 子向量维度。
所以可以总结为:
| 项目 | 数值 | 单位 / 含义 |
|---|---|---|
| Q 总维度 | 256 |
维 |
| K 总维度 | 256 |
维 |
| V 总维度 | 256 |
维 |
| attention head 数量 | 8 |
个 head |
| 每个 head 的维度 | 32 |
维 |
11. 输出预测
Decoder 最终输出:
[100, B, 256]
每个 query 对应一个候选检测结果。随后 DETR 使用两个预测头:
分类头 classification head
边界框回归头 box regression head
分类头输出:
[100, B, num_classes + 1]
其中:
| 符号 / 数字 | 单位 / 含义 |
|---|---|
100 |
query 数量,单位是“个预测槽位” |
B |
batch size,单位是“张图像” |
num_classes |
数据集类别数,单位是“个类别” |
+1 |
额外的 no object 类,单位是“个类别” |
边界框头输出:
[100, B, 4]
这里的 4 单位是“个坐标数值”,通常表示:
(cx, cy, w, h)
含义是:
| 坐标 | 单位 / 含义 |
|---|---|
cx |
边界框中心点 x 坐标,通常归一化到 [0, 1],单位是“相对图像宽度的比例” |
cy |
边界框中心点 y 坐标,通常归一化到 [0, 1],单位是“相对图像高度的比例” |
w |
边界框宽度,通常归一化到 [0, 1],单位是“相对图像宽度的比例” |
h |
边界框高度,通常归一化到 [0, 1],单位是“相对图像高度的比例” |
例如,w = 0.5 表示预测框宽度约占整张图宽度的 50%。
12. 匈牙利匹配与 no object
DETR 输出固定数量的预测,例如 100 个预测槽位。但一张图中的真实目标数量通常远少于 100。
训练时,DETR 使用 Hungarian matching,也就是匈牙利匹配,把预测结果和真实目标做一对一匹配。
例如一张图有 3 个真实目标。这里的 3 单位是“个目标”。DETR 输出 100 个预测,其中只有 3 个预测会被匹配到真实目标,剩下的 97 个预测应该输出 no object:
真实目标: 3 个
预测结果: 100 个
匹配到目标的预测: 3 个
no object 预测: 97 个
因为训练时强制一对一匹配,所以 DETR 推理时通常不需要 NMS。
13. 完整例子
假设输入图像经过 CNN 后得到:
[B, 2048, 25, 34]
其中:
| 数字 / 符号 | 单位 / 含义 |
|---|---|
B |
batch size,单位是“张图像” |
2048 |
CNN 输出通道数,单位是“个通道” |
25 |
特征图高度,单位是“个网格位置” |
34 |
特征图宽度,单位是“个网格位置” |
经过 1x1 卷积降维:
[B, 2048, 25, 34] → [B, 256, 25, 34]
展平成 token 序列:
[25*34, B, 256] = [850, B, 256]
其中 850 的单位是“个图像 token”。
送入 Encoder:
Encoder input: [850, B, 256]
Encoder output: [850, B, 256]
准备 object queries:
[100, B, 256]
送入 Decoder:
Decoder query: [100, B, 256]
Encoder memory: [850, B, 256]
Decoder output: [100, B, 256]
最后输出:
class logits: [100, B, num_classes + 1]
boxes: [100, B, 4]
14. 总结
DETR Transformer 的核心过程可以概括为:
CNN 把图像变成二维特征图
二维特征图被展平成图像 token 序列
Encoder 让所有图像 token 建立全局关系
Decoder 用 100 个 object queries 去图像 token 中查询目标
每个 query 输出一个类别和一个边界框
一句话总结:
DETR 先把图像变成一串 256 维的视觉 token,Encoder 负责理解整张图,Decoder 使用 100 个 256 维 object queries 从图像特征中查询目标,最终每个 query 预测一个类别和一个由 4 个归一化坐标数值组成的边界框。