您的位置:

深度解读detr:视觉物体检测的转变

一、文章介绍

detr是Facebook AI Research在2020年所提出的一种新型视觉物体检测方法,通过在全卷积神经网络中使用transformer编码器-解码器结构,将物体检测任务从先前的两阶段目标检测方法转变为一阶段的end-to-end方法,可以在保持预测准确性的同时提高检测效率。本文将介绍detr的核心思想、模型结构及其训练方法,以及与常见的目标检测方法的比较。

二、一阶段end-to-end物体检测

我们知道,传统目标检测方法一般都是两阶段的。首先,使用区域提取算法生成包含物体的候选窗口,然后将这些窗口送入分类器和回归器中进行分类和位置估计。这种方法一般效果很好,但是速度慢且复杂。而detr使用了一阶段的end-to-end方法,直接在图像上预测物体的位置和类别。这样一来,第一阶段的计算可以被跳过,检测速度大大提高。

三、Transformer结构的应用

detr中的核心思想是使用transformer打包特征图,然后使用一个解码器输出检测结果。利用transformer的自注意力机制,detr能自动提取特征图中的重要特征,使空间信息得到了更好的利用。同时,transformer使得编码器-解码器框架可以应用于物体检测任务。

四、模型结构

detr的模型结构是一个全卷积神经网络,由一个编码器和一个解码器组成。输入是一张图像,经过卷积神经网络进行特征提取,然后传入transformer编码器中进行特征图打包,最终由解码器输出检测结果,即每个目标包含类别和边界框。detr使用5个编码器层和6个解码器层,每个解码器层都将encoder输出和自己的前一个输出输入transformer中。


class DETR(nn.Module):
    def __init__(self, backbone, num_classes, num_queries):
        super().__init__()
        self.num_queries = num_queries
        
        self.query_embed = nn.Embedding(num_queries, self.hidden_dim)
        self.transformer = nn.Transformer(
            d_model=self.hidden_dim,
            nhead=self.nhead,
            num_encoder_layers=self.num_encoder_layers,
            num_decoder_layers=self.num_decoder_layers,
            dim_feedforward=self.dim_feedforward,
            dropout=self.transformer_dropout,
            activation=self.activation,
            normalize_before=self.normalize_before,
        )
        self.input_proj = nn.Conv2d(backbone.num_channels, self.hidden_dim, kernel_size=1)
        self.backbone = backbone
        self.class_embed = nn.Linear(self.hidden_dim, num_classes + 1)
        self.bbox_embed = MLP(hidden_dim, hidden_dim, 4, 3)

五、训练方法

detr的训练是一个端到端的过程,梯度由所有步骤共同计算。Cityscapes和COCO数据集是在训练过程中使用的常见数据集,在COCO数据集上可以达到较好的表现。为了提高模型的准确性,detr使用了多任务学习,并使用了一个匈牙利算法为每个预测框匹配真实目标或背景类别。为了提高训练效率,作者使用了分布式训练并使用了warmup策略逐渐增加学习率。

六、实验结果与对比

实验结果表明,detr在COCO数据集上的表现相当出色。mAP@50增加了4.2%(从42.0%到46.2%),并且在只有一个物体的图像中的表现也特别好。同时,与Faster R-CNN等目标检测方法相比,detr有着更好的检测速度。另外,detr也被证明在其他形式的目标检测中具有灵活性。

七、总结

detr等一阶段end-to-end物体检测方法的出现将彻底改变目标检测的方式。detr不仅提高了检测速度,还在准确率方面达到了很好的性能。但是,detr也存在一些限制,例如对小物体的检测效果不佳等。但是,这个方向仍然具有很大的潜力和研究价值。

完整代码


# 定义模型
class DETR(nn.Module):
    def __init__(self, backbone, num_classes, num_queries):
        super().__init__()
        self.num_queries = num_queries
        
        self.query_embed = nn.Embedding(num_queries, self.hidden_dim)
        self.transformer = nn.Transformer(
            d_model=self.hidden_dim,
            nhead=self.nhead,
            num_encoder_layers=self.num_encoder_layers,
            num_decoder_layers=self.num_decoder_layers,
            dim_feedforward=self.dim_feedforward,
            dropout=self.transformer_dropout,
            activation=self.activation,
            normalize_before=self.normalize_before,
        )
        self.input_proj = nn.Conv2d(backbone.num_channels, self.hidden_dim, kernel_size=1)
        self.backbone = backbone
        self.class_embed = nn.Linear(self.hidden_dim, num_classes + 1)
        self.bbox_embed = MLP(hidden_dim, hidden_dim, 4, 3)
    
    def forward(self, x):
        hs = self.backbone(x)
        hs = self.input_proj(hs)
        bs, c, h, w = hs.shape
        hs = hs.flatten(2).permute(2, 0, 1)
        query_embed = self.query_embed.weight.unsqueeze(1).repeat(1, bs, 1)
        memory = self.transformer_encoder(hs)
        hs = self.transformer_decoder(query_embed, memory)
        return hs.transpose(0, 1), self.class_embed(hs), self.bbox_embed(hs).sigmoid