Nicolas Carion, Francisco Massa, Gabriel Synnaeve, Nicolas Usunier, Alexander Kirillov,
Sergey Zagoruyko. End-to-End Object Detection with Transformers. (pdf)
什么是 DETR ?
DETR 是第一个提出基于 Transformer 的端到端目标检测,没有了 NMS、anchor 等等操作,其效果和 Faster RCNN 相当(在大物体上超过了 Faster RCNN,在小物体上却不如)
RCNN 系列的操作并不是一个直观的物体检测过程,因为最初的方法无法直接获取到检测对象,所以使用了 proposal + classifier 的方法——通过一些密集的方框去覆盖整张图像可能出现物体的部分,然后预测该视野范围内的物体类别以及对该视野范围进行微调
而我们人类更习惯的方式是先确定哪里有物体,然后在进一步去判断这个物体是什么。而 DETR 采用的即是这样一种直观的方法,先确定整张图像的物体情况,然后在调整具体的检测对象视野
下图是 Faster RCNN 和 DETR 的一个比较
DETR 把目标检测看成是一个 set prediction 问题——即给定一个固定小规模的目标查询集,DETR 推理目标和全局图像的关系,然后直接输出最终的预测集,最后再通过二分图匹配确定哪个框对应哪类目标
模型的整体结构
backbone
传统的 CNN 网络,输入的图片大小为 W 0 × H 0 × 3 W_0\times H_0\times3 W0×H0×3,变换后输出的特征图大小为 W 0 32 × H 0 32 × 2048 \frac{W_0}{32}\times\frac{H_0}{32}\times2048 32W0×32H0×2048
encoder
首先,通过一个 1 × 1 1\times1 1×1 卷积将 backbone 提取到的特征压缩到 d × H × W ( H = H 0 32 , W = W 0 32 ) d\times H\times W\ (H=\frac{H_0}{32}, W=\frac{W_0}{32}) d×H×W (H=32H0,W=32W0)。因为 transformer 的输入是一个序列,因此需要再通过 flatten 形成一个 d × H W d\times HW d×HW 的特征图。整个过程如下图所示
接着,我们需要关注的是 image feature 展开为 H × W H\times W H×W 的一维向量,这对 bbox 的预测是很有利的
由于 encoder 对序列顺序不敏感,所以在传入 encoder 之间需要将一个的特征向量和空间位置编码相加。这里的空间位置编码类似于 Faster RCNN 中的 anchor,为了让体现图像在 x x x 和 y y y 维度上的信息,spatial positional encoding 计算了两个维度的位置编码,然后连接到一起。为了增强对控件位置的感知,作者不仅在 encoder 输入时会添加位置编码,而且在每个 attention layer 都加入位置编码
另外,作者在实验中可视化了最后一层 encoder 的注意力图,发现 encoder 已经能够很好的区分开每个实物,这样就简化了 decoder 提取物体和定位的工作
decoder
decoder 有两个输入一个是 object query(或者上一层 decoder 的输出),另一个是 encoder 的输出。与 transformer 不同的是,在 DETR 中 decoder 是并行解码。decoder 中的 object query 中是 N N N 个 d d d 维的向量,与 encoder 中的 spatial position encoding 类似,是学习到的位置编码,在 decoder 中的每个 attention layer 都会加入这些位置编码。object query 通过 decoder 转换为 output embedding。经过 FFN,它们被独立解码为对应的框坐标和类标签,从而得到 N N N 个最终预测
到这里,我们需要进一步讨论一下 object queries,在 DETR 中它起着很大在作用
需要注意的是,上图的可视化结果是 COCO 验证集上所有图片的 box prediction(如下面论文中对图片的说明)
我刚开始的时候即使看完上面的整个过程,但还不是很理解 object queries 到底是如何训练得到这种对图像特殊的观察模式。其实拆分来看就很好理解了。我们仍然以左上的 object queries 中的一个 embedding 做说明,同样还是将其比作一个提问题的小人,这个小人在刚开始的时候是一个随机向量,这个随机的向量让他的兴趣点关注在了图像的左下角。然后经过第一层 decoder 训练,他的注意力发生了一定的变换,即他学习到了一些东西。接着 transformer 再向上传入第二层 decoder 中,这个小人也就带着他在第一层学到的内容到了第二层,同样第二层的输入会在来自第一层输入的基础上嵌入 object queries,那么这个小人就会带着他学习到的内容更加关注左下角一些其他还没学习到的内容。以此类推,当 Transformer 训练完成后,这个小人对图像左下角的观察就形成了一套完整的独特的观察模式,也就是上面图片左上的可视化结果
上面的可视化结果还有一个奇怪的地方,中为什么每个 slot 中间都有一条红色的竖线,但是没有一条蓝色的横线。作者将这点归因于 COCO 数据集物体分布所导致
我们现在来看一下 DETR transformer 的结构,你会上面的整个过程有更加深刻的理解
transformer 中的这种注意力机制是很神奇的 object queries 中每一个小人对不同的事物感兴趣,包括不同的类别信息和不同的区域,然后这些小人都将输出他们感兴趣的内容的最佳预测。这些小人他们的学习过程是相互作用的,也就是在 transformer 模型中序列中的每个位置可以相互关注,每个位置都可以相互通信和协作聚合图像中的信息。因此,在每一层中,他们都可以相互交流,然后在下层又重复这个过程,然后达成共识某块区域出现了某种物体。这也说明了上面可视化的结果为什么那个小人不是只关注左下一个地方,还会有其他很多关注的地方,具体说来每个都有自己主要关注的内容。更加直观的来说,就是人多力量大,每个小人学习关注自己感兴趣的地方,然后相互交流,提问题的人多了,问题千奇百怪,于是模型对全局信息的抓取就越好
上图有个很奇怪的地方,后面大象被遮住的后腿在 transformer 中也注意到了,至于为什么会注意到,最好的解释是这是模型中的一些小偏差所导致的
但是,综合上面对 encoder 和 decoder 注意力机制的描述可以看到,self-attention 和 encoder-decoder attention 使得模型可以利用 embedding 之间的成对关系进行全局的推理,同时也能够使用整个图像作为上下文联系帮助全局推理的进行
Prediction FFNs
预测头部的 FFN 包含三个部分:(1)一个 ReLU 函数;(2) d d d 维的隐藏层的 3 层 MLP;(3)一个线性层
一边的 FFN 使用 softmax 预测最终的输出标签;另一边的 FFN 预测固定大小( N N N 个, e.g. 100)的边界框,其中 N N N 通常比图像中感兴趣的对象的实际数量要大很多,因此使用了一个额外的标签 ϕ \phi ϕ 表示检测到任何对象,即 background
Auxiliary decoding losses
作者发现在训练的过程中使用辅助损失是很有帮助的,尤其可以使得模型对每个类输出正确的物体数量。在每个 decoder layer 后面都添加 prediction FNNs 和 Hungarian loss。所有的 prediction FFNs 共享参数。不同 decoder layer 的结果输入 FFNs 之前都先经过一个共享权重的 LayerNorm 进行处理
DETR 的损失函数
基于序列预测的思想,作者将网络的预测结果看作是一个长度为 N N N 的固定顺序序列 y ^ = { y ^ i } i = 1 N \hat y=\left\{\hat y_i\right\}_{i=1}^N y^={y^i}i=1N, y ^ i = ( c ^ i , b ^ i ) \hat y_i=(\hat c_i,\hat b_i) y^i=(c^i,b^i),同时将 ground truth 也视为一个序列 y y y, y i = ( c i , b i ) y_i=(c_i, b_i) yi=(ci,bi), c i c_i ci 表示该目标所属的真实类别, b i ∈ [ 0 , 1 ] 4 b_i\in[0,1]^4 bi∈[0,1]4 表示一个四元组(ground truth box 的中心点坐标和宽高,它们都是相对图像的比例坐标)。 y y y 的长度往往都小于 N N N,用 ϕ \phi ϕ 对该序列进行填充
那么预测任务就可以看作是
y
y
y 与
y
^
\hat y
y^ 之间的二分图匹配问题,采用匈牙利算法(Hungarian Algorithm)作为二分匹配算法的求解方法,于是定义最小匹配策略如下
σ
^
=
a
r
g
m
i
n
σ
∈
S
∑
i
N
L
m
a
t
c
h
(
y
i
,
y
^
σ
(
i
)
)
\hat\sigma=\underset{\sigma\in\mathfrak{S}}{argmin}\ \sum_i^N\mathcal{L}_{match}(y_i,\hat y_{\sigma(i)})
σ^=σ∈Sargmin i∑NLmatch(yi,y^σ(i))
L
m
a
t
c
h
(
y
i
,
y
^
σ
(
i
)
)
\mathcal{L}_{match}(y_i,\hat y_{\sigma(i)})
Lmatch(yi,y^σ(i)) 计算 ground truth
y
i
y_i
yi 和序号为
σ
(
i
)
\sigma(i)
σ(i) 的预测值之间的matching cost,它不仅考虑了分类损失也考虑了预测的 box 和标注 box 的损失。对于序号为
σ
(
i
)
\sigma(i)
σ(i) 的预测,我们定义
p
^
σ
(
i
)
(
c
i
)
\hat p_{\sigma(i)}(c_i)
p^σ(i)(ci) 表示其属于
c
i
c_i
ci 的概率,定义
b
^
σ
(
i
)
\hat b_{\sigma(i)}
b^σ(i) 表示 predicted box,于是
L
m
a
t
c
h
(
y
i
,
y
^
σ
(
i
)
)
\mathcal{L}_{match}(y_i,\hat y_{\sigma(i)})
Lmatch(yi,y^σ(i)) 可以描述为如下的形式
L
m
a
t
c
h
(
y
i
,
y
^
σ
(
i
)
)
=
−
1
{
c
i
≠
ϕ
}
p
^
σ
(
i
)
(
c
i
)
+
1
{
c
i
≠
ϕ
}
L
b
o
x
(
b
i
,
b
^
σ
(
i
)
)
\mathcal{L}_{match}(y_i,\hat y_{\sigma(i)})=-\mathbb 1_{\{c_i\neq\phi\}}\hat p_{\sigma(i)}(c_i)+\mathbb 1_{\{c_i\neq\phi\}}\mathcal L_{box}(b_i,\hat b_{\sigma}(i))
Lmatch(yi,y^σ(i))=−1{ci=ϕ}p^σ(i)(ci)+1{ci=ϕ}Lbox(bi,b^σ(i))
注意,物体和背景的 matching cost并不依赖于所做的预测,它们之间的 match cost 是一个固定值。同时,我们看到 matching cost 中使用的是
p
^
σ
(
i
)
(
c
i
)
\hat p_{\sigma(i)}(c_i)
p^σ(i)(ci) 而不同于 Hungarian loss 中的 log-probability,原因是采用
p
^
σ
(
i
)
(
c
i
)
\hat p_{\sigma(i)}(c_i)
p^σ(i)(ci) 才能使得分类损失和定位损失在同一个数量级上
接下来计算损失函数,对前面的所有配对计算 Hungarian loss
L
H
u
n
g
a
r
i
a
n
(
y
,
y
^
)
=
∑
i
N
[
−
l
o
g
p
^
σ
(
i
)
(
c
i
)
+
1
{
c
i
≠
ϕ
}
L
b
o
x
(
b
i
,
b
^
σ
^
(
i
)
)
]
\mathcal{L}_{Hungarian}(y_,\hat y)=\sum_i^N\left[-log\hat p_{\sigma(i)}(c_i)+\mathbb 1_{\{c_i\neq\phi\}}\mathcal L_{box}(b_i,\hat b_{\hat\sigma}(i))\right]
LHungarian(y,y^)=i∑N[−logp^σ(i)(ci)+1{ci=ϕ}Lbox(bi,b^σ^(i))]
在实际操作中,考虑到物体类和背景类的不平衡(对于
N
=
100
N=100
N=100,可能会有
90
90
90 多个对象都是 background),因此对于
c
i
=
ϕ
c_i=\phi
ci=ϕ 的情况,需要对其 log-probability 除以
10
10
10 来降低在损失中的权重
和 Faster RCNN 不同,DETR 不预测两个框之间的偏差
Δ
w
.
r
.
t
\Delta w.r.t
Δw.r.t,而是直接预测 box。这样操作起来是比较简单的,但是损失函数的相对范围会有问题——对于 L1 损失,大框的一点偏差将会带来很大的损失,而小框即使偏差很大可能在数量上并不会导致很大的损失。考虑到这点,作者引入了 IoU 损失,它与框大框小并没有任何关联。于是,
L
b
o
x
(
b
i
,
b
^
σ
^
(
i
)
)
\mathcal L_{box}(b_i,\hat b_{\hat\sigma}(i))
Lbox(bi,b^σ^(i)) 就可以定义为如下形式
L
b
o
x
(
b
i
,
b
^
σ
^
(
i
)
)
=
λ
i
o
u
L
i
o
u
(
b
i
,
b
^
σ
(
i
)
)
+
λ
L
1
∣
∣
b
i
−
b
^
σ
^
∣
∣
1
\mathcal L_{box}(b_i,\hat b_{\hat\sigma}(i))=\lambda_{iou}\mathcal L_{iou}(b_i,\hat b_{\sigma}(i))+\lambda_{L_1}||b_i-\hat b_{\hat\sigma}||_1
Lbox(bi,b^σ^(i))=λiouLiou(bi,b^σ(i))+λL1∣∣bi−b^σ^∣∣1
L
i
o
u
\mathcal L_{iou}
Liou 采用 GIOU,定义为
L
i
o
u
(
b
i
,
b
^
σ
^
(
i
)
)
=
1
−
(
∣
b
σ
(
i
)
∩
b
^
i
∣
∣
b
σ
(
i
)
∪
b
^
i
∣
−
∣
B
(
b
σ
(
i
)
,
b
^
i
)
∖
b
σ
(
i
)
∪
b
^
i
∣
∣
B
(
b
σ
(
i
)
,
b
^
i
)
∣
)
\mathcal L_{iou}(b_i,\hat b_{\hat\sigma}(i))=1-\left(\frac{|b_{\sigma(i)}\cap\hat b_i|}{|b_{\sigma(i)}\cup\hat b_i|}-\frac{|B(b_{\sigma(i)},\hat b_i)\setminus b_{\sigma(i)}\cup\hat b_i|}{|B(b_{\sigma(i)},\hat b_i)|}\right)
Liou(bi,b^σ^(i))=1−(∣bσ(i)∪b^i∣∣bσ(i)∩b^i∣−∣B(bσ(i),b^i)∣∣B(bσ(i),b^i)∖bσ(i)∪b^i∣)
DETR 用于语义分割
如下图所示是论文中关于 DETR 用于语义分割的一个说明,首先通过 DETR encoder 得到注意力图,然后在使用 CNN 将注意力图进行放大,最后根据注意力图对每个像素进行简单的分类
关于 DETR 的思考
训练是否有可能优化?因为 transformer 总是在图片上随机的学习到东西再将它们做联系,因此需要将整张图片保留在显存中直到学习完毕才换出。每块 V100(32 G)的显存只能放下四张图片的 batch,64 个 batch 就用了 16 块 V100 实现。这样的显存占用十分吓人