DETR 详解

date
Apr 19, 2022
Last edited time
Mar 28, 2023 08:05 AM
status
Published
slug
DETR详解
tags
DL
CV
summary
总结了两篇文章,添加了一些注解
type
Post
Field
Plat

1. Story

其实这篇文章的创新点从标题(End-to-End Object Detection with Transformers)就可以看出来,主要有以下三个重点:
  1. Object detection
  1. Transformers
  1. End-to-end
其中第一点为研究的领域,第二点为所用的工具,第三点则是模型的优点所在。
事实上,文章所做的工作,就是将 transformers 运用到了 object detection 领域,取代了现在的模型需要手工设计的工作(例如 非极大值抑制 和 anchor generation),并且取得了不错的结果。在 object detection 上 DETR 准确率和运行时间上和 Faster RCNN 相当;将模型 generalize 到 panoptic segmentation任务上,DETR 表现甚至还超过了其他的 baseline.
notion image
如上图所示,文章的主要有两个关键的部分。
第一个是用 transformer 的 encoder-decoder 架构一次性生成 个 box prediction。其中 是一个事先设定的、比远远大于 image 中 object 个数的一个整数;
第二个是设计了 bipartite matching loss,基于预测的 boxes 和 ground truth boxes 的二分图匹配计算 loss 的大小,从而使得预测的 box 的位置和类别更接近于 ground truth.
notion image

2. Transformer

这一节介绍 Transformer 的结构,从下图可以看出,主要包括三个部分:encoder, decoder 和 FFN。下面将分别介绍这三个部分。

2.1 Transformer Encoder

如下图所示,在 DETR 中,首先用 CNN backbone 处理 维的图像,得到 维的 feature map(一般 )。然后将 backbone 输出的 feature map 和 position encoding 相加,输入 Transformer Encoder 中处理,得到用于输入到 Transformer Decoder 的 image embedding。

cnn 骨架特征提取

骨架网络可以是任何一种,作者选择 resnet50,将最后一个 stage 即 stride=32 的特征图作为编码器输入。由于 resnet 仅仅作为一个小部分且已经经过了 imagenet 预训练,故和常规操作一样,会进行如下操作:
  • resnet 中所有 BN 都固定,即采用全局均值和方差
  • resnet 的 stem 和第一个 stage 不进行参数更新,即 parameter.requires_grad_(False)
  • backbone 的学习率小于 transformer,lr_backbone=1e-05, 其余为 0.0001
假设输入是 ,则 resnet50 输出是 ,2048 比较大,为了节省计算量,先采用 卷积降维为 256, 最后转化为序列格式输入到 transformer 中,输入 ,,

编码器设计和输入

编码器结构设计没有任何改变,但是输入改变了。
  1. 位置编码需要考虑 2d 空间
    1. 由于图像特征是 2d 特征,故位置嵌入向量也需要考虑 方向。前面说过编码方式可以采用 sincos,也可以设置为可学习,本文采用的依然是 sincos 模式,和前面说的一样,但是需要考虑 xy 两个方向 (前面说的序列只有 x 方向)。
      可以看出对于 的 2d 图像特征,不是类似 vision transoformer 做法简单的将其拉伸为 ,然后从 进行长度为 256 的位置编码,而是考虑了 方向同时编码,每个方向各编码 维向量,这种编码方式更符合图像特定。
      还有一个细节需要注意:原始 transformer 的 n 个编码器输入中,只有第一个编码器需要输入位置编码向量,但是 detr 里面对每个编码器都输入了同一个位置编码向量,论文中没有写为啥要如此修改。
  1. QKV 处理逻辑不同
    1. 作者设置编码器一共 6 个,并且位置编码向量仅仅加到 QK 中,V 中没有加入位置信息,这个和原始做法不一样,原始做法是 QKV 都加上了位置编码,论文中也没有写为啥要如此修改。
      其余地方就完全相同了,故代码就没必要贴了。总结下和原始 transformer 编码器不同的地方:
      • 输入编码器的位置编码需要考虑 2d 空间位置
      • 位置编码向量需要加入到每个编码器中
      • 在编码器内部位置编码仅仅和 QK 相加,V 不做任何处理
      经过 6 个编码器 forward 后,输出 shape 为 。
  1. 编码器部分整体运行流程
    1. 6 个编码器整体 forward 流程如下:
      notion image
      每个编码器内部运行流程如下:
 
从上面可以看出,DETR 不是一个完全由 Transformer 处理的架构,还是需要依赖于 CNN 作为 backbone 提取特征。
这里 Transformer Encoder 的结构和 Transformer 原始论文中的结构相同,这里就不再赘述。唯一需要注意的地方就是将 CNN backbone 输出的 feature map 转化为能够被 Transformer Encoder 处理的序列化数据的过程。主要有以下几个步骤:
  1. 维度压缩:将 CNN backbone 输出的 维的 feature map 先用 convolution 处理,将 channels 数量从 压缩到 ,即得到 维的新 feature map;
  1. 转化为序列化数据:将空间的维度(高和宽)压缩为一个维度,即把上一步得到的 维的 feature map 通过 reshape 成 维的 feature map;
  1. 加上 position encoding: 由于 transformer 模型是顺序无关的,所以需要加上 position encoding 反映位置信息。生成的方法不难但讲起来比较啰嗦,所以我把它放在附录 (a) 中,大家如果感兴趣可以翻到文章末尾的附录看一下。

2.2 Transformer Decoder

Decoder结构

Transformer Decoder 结构如下图所示,结构基本上和原始的 Transformer 相同。可以看到 transformer 主要有两个输入:
notion image
  1. image embedding (由 Transformer Encoder 输出) 与 position encoding 之和;
  1. object queries
    1. 其中 image embedding 与 position encoding 上文讲过,不再赘述。这里主要讲一下 object queries.
      Object queries 有 个(其中 是一个事先设定的、比远远大于 image 中 object 个数的一个整数),输入 Transformer Decoder (using multi-headed self- and encoder-decoder attention mechanisms.) 后分别得到 个 decoder output embedding,经过 FFN(后面会讲)处理后就得到了 个预测的 boxes 和这些 boxes 的类别。具体实现上,object queries 是 个 learnable embedding,训练刚开始时可以随机初始化。在训练过程中,因为需要生成不同的 boxes,object queries 会被迫使变得不同来反映位置信息,所以也可以称为 leant positional encoding (注意和 encoder 中讲的 position encoding 区分,不是一个东西)。
此外,decoder部分还可以将位置编码作为输入 编码器环节采用的 sincos 位置编码向量也可以考虑引入,且该位置编码向量输入到每个解码器的第二个 Multi-Head Attention 中,后面有是否需要该位置编码的对比实验。
此外,和原始的 Transformer不同的是,DETR 的 Transformer Decoder 是一次性处理全部的 object queries,即一次性输出全部的 predictions;而不像原始的 Transformer 是 auto-regressive 的,从左到右一个词一个词地输出。 为了说明如何实现该功能,我们需要先回忆下原始 transformer 的顺序解码过程:输入 BOS_WORD,解码器输出 i;输入前面已经解码的 BOS_WORD 和 i,解码器输出 am…,输入已经解码的 BOS_WORD、i、am、a 和 student,解码器输出解码结束标志位 EOS_WORD, 每次解码都会利用前面已经解码输出的所有单词嵌入信息。现在就是一次解码,故只需要初始化时候输入一个全 0 的查询向量 A,类似于 BOS_WORD 作用,然后第一个解码器接受该输入 A,解码输出向量作为下一个解码器输入,不断推理即可,最后一层解码输出即为我们需要的输出,不需要在第二个解码器输入时候考虑 BOS_WORD 和第一个解码器输出。

Decoder的主要流程

n 个解码器整体流程如下:
内部每个解码器运行流程为:
解码器最终输出 shape 是 , 是指 个解码器的输出。

2.3 FFN(Feed-forward network)

notion image
FFN 在 DETR 中的位置如上图所示。从更细节的结构图(下图)看,其实有两种 FFN:一种预测 bounding box 的中心位置、高和宽,第二种预测 class 标签。下图是更细节的 DETR Transformer 结构,大家感兴趣可以仔细看一下。
notion image
作者实验发现,如果对解码器的每个输出都加入辅助的分类和回归 loss,可以提升性能,故作者除了对最后一个编码层的输出进行 Loss 监督外,还对其余 5 个编码器采用了同样的 loss 监督,只不过权重设置低一点而已。

3. Loss

上面我们介绍了如何用 Transformer 生成 个 prediction boxes(其中 是一个事先设定好的远远大于 image objects 个数的整数)。这里我们将介绍如何得到这 个 prediction boxes 和 image objects 的最优二分图匹配,并通过计算配对的 loss 来评价 prediction boxes 生成的好坏。

3.1 得到 prediction boxes 和 image objects 的最优二分图匹配

首先大家可能有个疑问:假设对于一张图来说,ground truth boxes 的个数(即图中 object 的个数)为 ,由于 是一个事先设定好的远远大于 image objects 个数的整数,所以 ,即生成的 prediction boxes 的数量会远远大于 ground truth boxes 数量。这样怎么做匹配?为了解决这个问题,作者人为构造了一个新的物体类别 (表示没有物体)并加入 image objects 中,上面所说到的多出来的 个 prediction embedding 就会和 类别配对。这样就可以将 prediction boxes 和 image objects 的配对看作两个等容量的集合的二分图匹配了。
只要定义好每对 prediction box 和 image object 匹配的 cost,我们就能用匈牙利算法
什么是匈牙利算法
快速地找到使总 cost 最小的二分图匹配方案。
每对 prediction box 和 image object 匹配的 cost 定义如下:
其中, 为第 个 image object 的 class 标签, 为与第 个 object 配对的 prediction box 的 index; 是一个函数,当 时为 1,否则为 0; 表示 Transformer 预测的第 个 prediction box 类别为 的概率; 分别为第 个 image object 的 box 和第 个 prediction box 的位置; 计算的是 ground truth box 和 prediction box 之间的差距(下面详细介绍)。
上式总结起来就是,当配对的 image object 为 时,我们人为规定️配对的 cost;当配对的 image object 为真实的物体(即不为 )时,如果预测的 prediction box 类别和 image object 类别相同的概率越大,或者两者的 box 差距越小,配对的 cost 越小。 的计算公式如下:
.其中 为两个 box 中心坐标的 L1 距离。如果只用 L1 距离,当 box 大小不同时,即使 L1 距离相同,差距也会不一样。例如,两个 3x3 的 box 相距 3,和两个 30x30 的 box 相距 3 的差距是完全不同的。为了解决这个问题,作者还加入了与 box 大小无关的 ,通过 IoU 计算 loss。
这样,我们就完全定义好了每对 prediction box 和 image object 配对时的 cost。再利用匈牙利算法即可得到二分图最优匹配。
这一部分是利用 得到最优二分图匹配, 而不是作为真正优化的 loss。

3.2 根据最优二分图匹配计算 set prediction loss

上面我们得到了 prediction boxes 和 image objects 之间的最优匹配。这里我们基于这个最优匹配,来计算 set prediction loss,即评价 Transformer 生成这些 prediction boxes 的效果好坏。
Set prediction loss 计算公式如下:
其中 为最佳匹配,将第 个 image object 匹配到第 个 prediction box。这个式子各个部分的含义与 计算公式完全一致,这里就不再赘述。唯一需要注意的是,这里用的是 classification probability 的对数形式,而 中直接用的线性形式;且这里考虑了被匹配到 object 的 ,而 则直接定义为 0. 用 做反向传播即可优化 Transformer。

附录

a. position encoding 的生成方式

文中的position encoding采用原始Transformer论文的固定position encoding,即对于每个  维向量,用不同频率的sin函数对高(  )这个维度生成  维的position encoding,用不同频率cos函数对宽(  )这个维度生成  维的position encoding,然后将两个  维的position encoding concat成  维的position encoding。

b. object queries 的推断过程

论文附录中有一段 Inference 阶段 DETR 的 PyTorch 代码:
notion image
当然上面是简化代码,和实际代码不一样。具体流程是:
  • 将 图片输入到 resnet50 中进行特征提取, 输出
  • 通过 卷积降维,变成
  • 利用 函数计算位置编码
  • 将图像特征和位置编码向量相加,作为编码器输入,输出编码后的向量, 不变
  • 初始化全 0 的 的输出嵌入向量,结合位置编码向量和 query_embed,进行解码输出,解码器输出 shape 为,后面的解码器接受该输出,然后再次结合置编码向量和 query_embed 进行输出,不断前向
  • 将最后一个解码器输出输入到分类和回归 head 中,得到 100 个无序集合
  • 对 100 个无序集合进行后处理,主要是提取前景类别和对应的 bbox 坐标,乘上 即可得到最终坐标, 后处理代码如下:
既然训练时候对 6 个解码器输出都进行了 loss 监督,那么在测试时候也可以考虑将 6 个解码器的分类和回归分支输出结果进行 nms 合并,稍微有点性能提升。

2.2.4 小结

detr 整体做法非常简单,基本上没有改动原始 transformer 结构,其显著优点是:不需要设置啥先验,超参也比较少,训练和部署代码相比 faster rcnn 算法简单很多,理解上也比较简单。但是其缺点是:改了编解码器的输入,在论文中也没有解释为啥要如此设计,而且很多操作都是实验对比才确定的,比较迷。算法层面训练 epoch 次数远远大于 faster rcnn(300epoch),在同等 epoch 下明显性能不如 faster rcnn,而且训练占用内存也大于 faster rcnn。
整体而言,虽然效果不错,但是整个做法还是显得比较原始,很多地方感觉是尝试后得到的做法,没有很好的解释性,而且最大问题是训练 epoch 非常大和内存占用比较多,对应的就是收敛慢,期待后续作品。

参考

  1. Carion N, Massa F, Synnaeve G, et al. End-to-End Object Detection with Transformers[J]. arXiv preprint arXiv:2005.12872, 2020.
  1. Zhu X, Su W, Lu L, et al. Deformable DETR: Deformable Transformers for End-to-End Object Detection[J]. arXiv preprint arXiv:2010.04159, 2020.
  1. Kirillov A, He K, Girshick R, et al. Panoptic segmentation[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2019: 9404-9413.
  1. bcdefVaswani A, Shazeer N, Parmar N, et al. Attention is all you need[C]//Advances in neural information processing systems. 2017: 5998-6008.
  1. Parmar N, Vaswani A, Uszkoreit J, et al. Image transformer[J]. arXiv preprint arXiv:1802.05751, 2018.

© Lazurite 2021 - 2026