计算机视觉目标检测——DETR(End-to-End Object Detection with Transformers)
计算机视觉目标检测——DETR(End-to-End Object Detection with Transformers)
文章目录
- 计算机视觉目标检测——DETR(End-to-End Object Detection with Transformers)
- 摘要
- Abstract
- 一、DETR算法
- 1. 摘要(Abstract)
- 2. 引言(Introduction)
- 3. 方法(The DETR model)
- 3.1 二分图匹配
- 3.2 损失函数
- 3.3 DETR的具体架构
- 4. 实验
- 总结
摘要
本周主要学习了DETR(End-to-End Object Detection with Transformers)目标检测算法及其相关内容。DETR通过引入Transformer,将目标检测任务视为集合预测问题,首次实现了端到端的目标检测,无需NMS后处理和anchor设计(相较于YOLO),显著简化了模型训练和部署流程。论文的核心贡献包括设计了基于二分图匹配的目标函数,确保输出的独特性,并通过Transformer的encoder-decoder架构实现了高效的目标检测。实验表明,DETR在COCO数据集上达到了与Faster R-CNN相当的性能,同时表现出良好的扩展性,能够适配全景分割等任务。尽管在小目标检测上存在不足,但相关改进工作已取得显著进展。
Abstract
The study focuses on DETR (End-to-End Object Detection with Transformers), a milestone framework in object detection. DETR reformulates object detection as a set prediction problem, achieving end-to-end detection without requiring NMS post-processing or anchor design(compared to YOLO), significantly simplifying model training and deployment. Its key contributions include a novel objective function based on bipartite matching, ensuring unique predictions, and leveraging the encoder-decoder architecture of Transformers for efficient object detection. Experiments demonstrate that DETR achieves comparable performance to Faster R-CNN on the COCO dataset, while exhibiting excellent scalability to tasks like panoptic segmentation. Although DETR faces challenges in detecting small objects, subsequent research has effectively addressed these issues.
一、DETR算法
DETR是目标检测领域的里程碑式工作,从论文标题“End-to-End Object Detection with Transformers”可知两个关键词:端到端和transformer。
从目标检测研究开始受到关注到DETR都很少有端到端的方法,大部分方法最后至少需要后处理操作(NMS, non-maximum suppression, 非极大值抑制)。无论是proposal based方法、anchor based方法、non-anchor based方法,最后都会生成很多预测框,如何去除这些冗余的框就是NMS要做的事情。而问题也随之出现:一是有了NMS,模型调参就会很复杂,二是即使训练好了一个模型,部署起来也非常困难(NMS不是所有硬件都支持)。
所以一个简单的、端到端模型一直是研究者梦寐以求的框架,DETR解决了以上的这些痛点。
DETR的优势在于:
- 不需要proposal、不需要anchor,直接利用transformer这种全局建模的能力,把目标检测看做是集合预测问题。
- 因为有了这种全局建模的能力,DETR不会有那么多冗余框,最后出什么结果就是什么结果,不需要NMS做后处理,让模型的训练和部署简单不少。
1. 摘要(Abstract)
DETR提出将目标检测任务直接视为集合预测的问题。目标检测本来任务就是给定一个图像,预测一堆框,每个框不仅要知道的其坐标,还要知道框里包含物体的类别,这些框就是一个集合,不同的图像对应的集合也是不同的,集合预测问题就是给定一个图片,我要预测这个集合。
摘要首先从大体的贡献上描述了贡献,即把目标检测做成一个端到端的框架,把之前特别依赖人的先验知识的部分删掉了(NMS部分、anchor),一旦把这两个部分拿掉之后,我们也不用费尽心思设计这种anchor,最后不会出现这么多框,不会用到NMS,也不会用到很多超参去调。
细节上的具体贡献分为:首先,DETR提出了新的目标函数,通过二分图匹配的方式,强制模型输出一组独一无二的预测(没有那么多冗余框,每个物体理想状态下就会生成一个框)。其次,就是引入了Transformer的encoder-decoder架构,这一部分中又包含了两个小贡献。一是decoder中加入额外的输入learned object query,其扮演以往框架中的anchor的角色,二是并行检测比串行检测更合适,并不是检测一个大物体前必须先检测一个小物体,或从左到右检测,我们希望越快越好。
DETR的能力表现:
- 简单性:想法上简单,不需要一个特殊的library,只要硬件支持Transformer或CNN,就一定支持DETR的实现。
- 性能:在coco数据集上,DETR和一个训练非常好的faster RCNN基线网络取得了差不多的效果,模型内存和速度也和faster RCNN差不多。
- 扩展性:DETR不仅是个模型也是个通用的框架,DETR在全景分割任务上效果很好,DETR能够非常简单拓展到其他任务上。
2. 引言(Introduction)
上述的摘要中提到DETR提出将目标检测任务直接视为集合预测的问题。而当时大多数好用的目标检测器,都是用间接的方式去处理集合预测问题,(1)比如proposal方式(如RCNN系列工作),(2)anchor方式(YOLO系列,focal loss)(3)non-anchor based方法(物体中心点center net,FCOS)。他们都没有直接做集合预测任务,而是设计一个替代(回归、分类)解决目标检测问题。所有这些方法性能受限于后处理操作(NMS),由于用了anchor和NMS导致检测器都非常复杂,难以优化和调参。
DETR框架的大致流程为:
- CNN提取特征。
- 特征拉直,送到encoder-decoder中,encoder的作用是进一步学习全局信息,为近下来的decoder,也就是最后出预测框做铺垫。
- decoder生成框的输出,当你有了图像特征之后,还会有一个object query(限定了你要出多少框),通过query和特征在decoder里进行自注意力操作,得到输出的框(文中是100,无论是什么图片都会预测100个框)。
- loss计算通过二分图匹配,计算100个预测的框和2个GT框的matching loss,决定100个预测框哪两个是独一无二对应到红黄色的GT框,匹配的框去算目标检测的loss。
上述的是DETR训练的步骤,而在DETR的推理过程中,步骤1、2、3一致,步骤4不需要,直接在最后的输出上用一个阈值卡一个输出的置信度,置信度比较大(>0.7的)保留,置信度小于0.7的当做背景物体。
DETR既有优势,但也存在缺陷:
- DETR对大物体预测很准,这主要归功于Transformer,能进行全局建模(原来使用anchor的话就会受限于anchor大小)。
- 缺陷是DETR对小物体的预测效果不好(后续关于DETR的多尺度、多特征改进工作,可以提高小物体的检测,改善了这些问题)。
3. 方法(The DETR model)
这部分主要包含两块内容:一是基于集合的目标函数怎么做,作者如何通过二分图匹配把预测的框和GT框连接在一起,算得目标函数。二是介绍DETR的具体模型架构。
3.1 二分图匹配
DETR在单次通过解码器时推断一个固定大小的有 N 个预测的集合,其中 N 被设置为显著大于图像中典型的物体数量,文中N为100。训练的主要困难之一是在 ground truth 方面对预测对象(类别、位置、大小)进行打分。我们的损失在预测对象和真实对象之间产生一个最佳的二分匹配,然后优化 object-specific ( bounding box ) 的损失。
用
y
y
y表示对象的ground truth集合,
y
^
=
{
y
^
i
}
i
=
1
N
\hat y = \{ {\hat y_i}\} _{i = 1}^N
y^={y^i}i=1N表示有
N
N
N个预测的集合。假设N远大于图像中物体的个数,我们考虑y也是一个大小为N的被 ( no object ) 填充的集合。为了在这两个集合之间找到一个二分匹配,我们用最低的代价搜索N个元素
σ
∈
℘
N
\sigma \in {\wp _N}
σ∈℘N的一个置换:
σ ^ = arg min σ ∈ ℘ N ∑ i N L m a t c h ( y i , y ^ σ ( i ) ) \hat \sigma = \mathop {\arg \min }\limits_{\sigma \in {\wp _N}} \sum\limits_i^N {{L_{match}}({y_i},{{\hat y}_{\sigma (i)}})} σ^=σ∈℘Nargmini∑NLmatch(yi,y^σ(i))
-
L m a t c h ( y i , y ^ σ ( i ) ) {{L_{match}}({y_i},{{\hat y}_{\sigma (i)}})} Lmatch(yi,y^σ(i))是真值 y i {{y_i}} yi和具有索引 σ i {\sigma _i} σi的一个预测之间的一个成对匹配代价(a pair-wise matching cost)。这个最优分配是通过匈牙利算法计算的。匹配代价同时考虑了类预测以及预测框和真实框之间的相似性。
-
真实集合的每个元素 i i i都可以看成一个 y i = ( c i , b i ) {y_i} = ({c_i},{b_i}) yi=(ci,bi),其中 c i {c_i} ci是目标类标签(目标类标签特可能是 ϕ \phi ϕ)。 b i ∈ [ 0 , 1 ] 4 {b_i} \in {\left[ {0,1} \right]^4} bi∈[0,1]4是一个向量,它定义了真实框的中心坐标及其相对于图像的高度和宽度。
-
对于索引 σ i {\sigma _i} σi的预测,我们定义类 c i {c _i} ci的概率为 p ^ σ ( i ) ( c i ) {{\hat p}_{\sigma (i)}}({c_i}) p^σ(i)(ci),预测框为 b ^ σ ( i ) {{\hat b}_{\sigma (i)}} b^σ(i)。
利用上述的符号,可以将 L m a t c h ( y i , y ^ σ ( i ) ) {{L_{match}}({y_i},{{\hat y}_{\sigma (i)}})} Lmatch(yi,y^σ(i))定义为:
− 1 { c i ≠ ϕ } p ^ σ ( i ) ( c i ) + 1 { c i ≠ ϕ } L b o x ( b i , b ^ σ ( i ) ) - {1_{\{ {c_i} \ne \phi \} }}{{\hat p}_{\sigma (i)}}({c_i}) + {1_{\{ {c_i} \ne \phi \} }}{L_{box}}({b_i},{{\hat b}_{\sigma (i)}}) −1{ci=ϕ}p^σ(i)(ci)+1{ci=ϕ}Lbox(bi,b^σ(i))
这种寻找匹配的过程与用于匹配proposal或anchor的启发式分配规则起到了相同的作用。但主要的区别是,我们可以找到一对一的匹配,进行无重复的直接集合预测。
3.2 损失函数
第二步是计算损失函数,即计算上一步中匹配的所有配对的匈牙利损失。我们定义的损失类似于常见目标检测器的损失,即类别预测的负对数和box 损失的线性组合:
其中的 σ ^ {\hat \sigma } σ^是第一步中计算的最优分配。
匹配代价和匈牙利损失的第二部分是对边界框进行评分的 L b o x ( b i , b ^ σ ( i ) ) {L_{box}}({b_i},{{\hat b}_{\sigma (i)}}) Lbox(bi,b^σ(i)),与带初试猜测检测器如anchor不同,我们直接进行框预测。虽然这种方法简化了实施,但它对损失的相对规模造成了问题。最常用的L1 Loss对于小框和大框会有不同的尺度,即使它们的相对误差相似。为了缓解这一问题,使用的损失函数是L1 Loss和广义的IoU损失 L i o u ( ⋅ , ⋅ ) {L_{iou}}( \cdot , \cdot ) Liou(⋅,⋅)的线性组合, L b o x ( b i , b ^ σ ( i ) ) {L_{box}}({b_i},{{\hat b}_{\sigma (i)}}) Lbox(bi,b^σ(i))是尺度不变的损失函数。
因此 L b o x ( b i , b ^ σ ( i ) ) {L_{box}}({b_i},{{\hat b}_{\sigma (i)}}) Lbox(bi,b^σ(i)),被定义为:
而广义的IoU损失 L i o u ( ⋅ , ⋅ ) {L_{iou}}( \cdot , \cdot ) Liou(⋅,⋅)定义为:
3.3 DETR的具体架构
DETR的网络结构主要由三部分组成:CNN骨干网、Transformer编码器和解码器,以及输出层。
- CNN骨干网:负责从输入图像中提取特征图。DETR通常使用ResNet等深度卷积神经网络作为骨干网,通过一系列的卷积和池化操作,将输入图像转换为高维特征图。
- Transformer编码器:用于对CNN骨干网提取的特征图进行编码。编码器由多个Transformer block组成,每个block包含自注意力层和前馈神经网络层。通过多层自注意力机制,编码器能够捕获特征图中不同位置之间的全局上下文关系,生成一组特征向量。
- Transformer解码器:解码器是DETR实现集合预测的关键部分。它接受编码器的输出和一组可学习的目标查询(object queries),通过自注意力机制和编码器-解码器注意力机制,将目标查询解码为一系列目标的边界框坐标和类别标签。
- 预测头:两个简单的前馈网络( feed forward network,FFN )来进行最终的检测预测。分别用于预测边界框的标准化中心坐标、高度和宽度,以及类别标签。
其中的object queries有必要进行说明:
DETR直接定义了100个目标框的slot,在DETR这里就被称为object query。在训练时,这100个object query将会通过 transformer进行self attention操作,以及和输入图像进行cross attention操作。 通过这种方式,每个object query将会逐步进化成可以预测目标框及其类别的一个特征向量。最终通过两个FFN,即可回归出目标框的位置和类别。
该网络一次前向传播的过程为:
- 输入图像,经过标准 CNN 后,得到图像的特征矩阵。
- 把图像特征拉直,并进行位置编码补充。
- 在 Transformer Encoder 中学习图像的全局信息。
- 位置嵌入和 Encoder 的输出作为 Decoder 的输入,经过解码后传递给 FFN。
- 判断 FFN 预测图像中是否包含目标对象。
- 如果有,则输出预测框和类别;否则输出一个 “no object” 类。
下面是DETR的Pytorch简单实现,非常简洁且清晰地描述了上述的网络结构:
import torch2
from torch import nn3
from torchvision.models import resnet5045
class DETR(nn.Module):
def __init__(self, num_classes, hidden_dim, nheads,
num_encoder_layers, num_decoder_layers):
super().__init__()
# We take only convolutional layers from ResNet-50 model
self.backbone = nn.Sequential(*list(resnet50(pretrained=True).children())[:-2])
self.conv = nn.Conv2d(2048, hidden_dim, 1)
self.transformer = nn.Transformer(hidden_dim, nheads,
num_encoder_layers, num_decoder_layers)
self.linear_class = nn.Linear(hidden_dim, num_classes + 1)
self.linear_bbox = nn.Linear(hidden_dim, 4)
self.query_pos = nn.Parameter(torch.rand(100, hidden_dim))
self.row_embed = nn.Parameter(torch.rand(50, hidden_dim // 2))
self.col_embed = nn.Parameter(torch.rand(50, hidden_dim // 2))
def forward(self, inputs):
x = self.backbone(inputs)
h = self.conv(x)
H, W = h.shape[-2:]
pos = torch.cat([
self.col_embed[:W].unsqueeze(0).repeat(H, 1, 1),
self.row_embed[:H].unsqueeze(1).repeat(1, W, 1),
], dim=-1).flatten(0, 1).unsqueeze(1)
h = self.transformer(pos + h.flatten(2).permute(2, 0, 1),
self.query_pos.unsqueeze(1))
return self.linear_class(h), self.linear_bbox(h).sigmoid()
detr = DETR(num_classes=91, hidden_dim=256, nheads=8, num_encoder_layers=6, num_decoder_layers=6)
detr.eval()
inputs = torch.randn(1, 3, 800, 1200)
logits, bboxes = detr(inputs)
4. 实验
使用AdamW训练DETR,将初始Transformer的学习率设置为 1 0 − 4 {10^{ - 4}} 10−4,主干的学习率设置为 1 0 − 5 {10^{ - 5}} 10−5,权重衰减设置为 1 0 − 4 {10^{ - 4}} 10−4。所有的Transformer权重都是初始化好的,而主干网是用ImageNet预训练的ResNet模型,它来自于具有冻结BN层的torchvision库。
文章用两个不同的主干报告结果:一个ResNet-50和一个ResNet-101。相应的模型分别称为DETR和DETR-R101。之后,文章提到还通过向主干的最后一个阶段添加一个展开,并从这个阶段的第一个卷积中移除一个跨步来提高特征分辨率。相应的模型分别称为 DETR-DC5 和 DETR-DC5-R101 (扩张的C5级)。
优缺点:这种修改将分辨率提高了两倍,从而提高了对小目标的性能,代价是编码器的自注意力增加了16倍,导致整体计算成本增加了 2 倍。下表给出了这些模型与Faster R-CNN的FLOPs的全面比较。
采用DETR - DC5模型进行预测。对于不同的对象,采用不同的颜色对注意力分数进行编码。解码器通常关注对象的四肢,如腿部和头部。通过颜色可以观察到,不同物体之间的边缘划分的很是明显,如下图,虽然大象的四肢和皮肤很相似,但是也难逃DETR的法眼,还有斑马的条纹很复杂,但是也没有对DETR造成困难。
总结
DETR模型通过将目标检测任务转化为集合预测问题,提出了一种端到端的检测方案,有效解决了传统方法中依赖NMS和anchor设计的不足。通过Transformer的全局建模能力,DETR简化了目标检测的框架设计,显著提升了大目标的检测精度,并在COCO数据集上表现出与Faster R-CNN相当的性能。尽管在小目标检测上存在一定局限性,但相关多尺度改进工作已取得显著成果。DETR不仅是一种目标检测模型,更是一个通用的框架,其创新性和可扩展性或许可以用到我之后的研究中,值得思考。