DETR论文精读

论文介绍了一种基于Transformer的端到端目标检测模型DETR,它通过二分图匹配避免了Proposal和Anchor的使用。DETR在COCO上表现接近FasterR-CNN,但对小物体检测有局限。后续工作如DeformableDETR改进了小物体检测。该模型展示了在对象检测领域的创新方法和挑战。
摘要由CSDN通过智能技术生成

论文题目End-to-End Object Detection with Transformers

代码:facebookresearch/detr: End-to-End Object Detection with Transformers (github.com)

端到端:通常指的是一种设计和实现方式,它将输入数据直接映射到期望的输出结果,而不需要或者很少需要人为地定义中间步骤或特征。这种算法在机器学习和人工智能领域尤为常见,尤其是在自然语言处理(NLP)、计算机视觉和其他需要复杂数据处理的领域。

端到端算法的一个典型例子是深度学习模型,如卷积神经网络(CNN)和循环神经网络(RNN),它们在图像识别、语音识别和机器翻译等任务中取得了显著的成功。这些模型通过多层的非线性变换,自动从原始数据中学习到复杂的特征表示。

然而,端到端算法也有其局限性,例如可能需要大量的计算资源和数据,以及模型的可解释性可能较差。

端到端的目标监测解决了痛点,即不需要proposal,也不需要anchor。不需要nms进行后处理(NMS(Non-Maximum Suppression,非极大值抑制)是目标检测算法中的一个重要后处理步骤。在目标检测任务中,尤其是在使用基于锚点(anchor-based)的方法时,如Faster R-CNN、SSD、YOLO等,模型通常会为每个类别生成多个候选边界框(bounding boxes),这些框可能包含对同一目标的多次检测,即存在重叠的边界框。NMS的目的是减少这些重叠的边界框,确保对于每个检测到的目标,只保留一个最有可能的边界框。这样做可以提高检测的准确性,避免重复检测同一个目标,并且使得最终的检测结果更加清晰和准确。)

摘要:目标是给定一个图片预测集合(框)。

  • 提出了新的目标函数,通过二分图匹配的方式能够强制模型输出一组独一无二的预测框
  • 使用transformer encoder和decoder的架构
  • 并行化(实时性好)
  • 简单性
  • 能够简单的扩展到别的领域(eg.全景分割、目标追踪、姿态预测、语义分割)

论文DETR结构图(简洁)

步骤:

  • step1.使用卷积神经网络提取特征
  • step2.transformer encoder 进一步学习全局的信息,帮助后面做检测
  • step3.transformer decoder生成预测的框
  • step4.将预测的框和ground truth框做匹配,在匹配的框上面算目标检测的loss

论文提到在COCO数据集上达到了与Faster R-CNN模型差不多的效果,且DETR对大物体的检测效果好。在小物体上效果不是很好,需要不断的进化 ,且训练速度慢。(为解决这些问题,不到半年Deformable DETR出现了,通过多尺度的特征解决小物体问题。)DETR不仅可以作为一个方法也可以作为一个框架,设计理念为了能够适用于更多复杂任务。

相关工作:大部分的目标检测分类器都是根据已有的猜测做的预测(eg.Two-stage detector初始猜测是proposals、Single-stage初始猜测是anchor/物体中心点)

Recurrent detector(15、16年的工作):使用的全是RNN,也就是自回归模型(时效性和性能会比较差)

The DETR model:

  • 基于集合的目标函数

模型最后的输出是一个固定的集合,n个输出(100)

使用二分图匹配

 将abc看成目标检测的100个框,xyz看成groundtruth框。cost matrix 就说loss,一旦拥有loss就可以用scipy.linear_sum_assignment(匈牙利算法)得到最优解。

LOSS公式如下:

由于使用了transformer提取全局的特征会导致loss很大,作者使用了L_1 loss和generalized iou loss(和框大小无关的目标函数)合体算bounding box loss

如下所示为DETR结构图(细节)

代码实现

import torch
from torch import nn
from torchvision.models import resnet50

class DETR(nn.Module):
    def __init__(self,num_classes, hidden_dim, nheads, num_encoder_layers, num_decoder_layers):
        super().__init__()
        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_layer, num_decoder_layers)
        self.linear_class = nn.Linear(hidden_dim, num_classes +1)
        self.iinear_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()
# num_classes 为类别数量
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)

编码器的层数越深,学到的特征越好。encoder尽可能的将物体和物体分离开。decoder去学边缘来跟好的处理遮挡的物体。

如下图所示为20个object query可视化

绿色点为小的bounding box,红色为大的横向的bounding box,蓝色的代表竖向的大的bounding box。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值