【Transformer】DETR: End-to-End Object Detection with Transformers
文章目录
- 一、背景和动机
- 二、方法
- 2.1 目标检测集合的 loss
- 2.2 DETR 结构
- 三、效果
- 四、全景分割
- 五、代码
论文链接:https://arxiv.org/abs/2005.12872
代码链接:https://github.com/facebookresearch/detr
一、背景和动机
目标检测任务是对图片中的每个感兴趣的目标预测位置和类别,现在流行的 CNN 方法的目标检测器大都使用的非直接手段进行预测,比如通过大量的 proposal、anchor、window center 来回归和分类出目标的位置和类别。这种方法会被后处理方法影响效果,为了简化这种预测方法,作者提出了一种直接的预测方法,这种方法在机器翻译和语音识别里边已经有了大量研究,但在目标检测里边还没有使用,之前的方法要么使用了很多其他先验知识,要么和目前的基准方法差了很多,本文的希望可以弥补这个差距。
二、方法
作者将目标检测的训练 pipeline 看成了一个直接的序列预测问题。总体结构如图 1 所示,DEtection TRsformer(DETR)可以直接预测所有目标,训练也是使用一个 loss 来进行端到端的训练。
DETR 的两大特点:
- 一个大的特点是简化了检测的 pipeline,不需要手工设计的模块来编码先验信息,如 anchor 和 non-maximal suppression
- 另外一个是不需要特定的层,能够方便的重用到其他结构中
2.1 目标检测集合的 loss
DETR 能够一次性推断出 N 个预测结果,其中 N 是远远大于图像中目标个数的值。
训练中的一个难点在于根据真值给每个预测目标(类别、位置、尺寸)打分,所以本文的 loss 能够得到一个在预测和真值之间的最优双向匹配,然后优化 object-specific loss。
- yyy:真值,假设维度也为 N,不够的用空值来补全
- y^={yi}^i=1N\hat{y} = \{\hat{y_i\}}_{i=1}^Ny^={yi}^i=1N:预测的结果,N 远远大于目标个数
第一步:求最低 cost
为了获得最优的二分匹配,作者在 N 个元素 σ\sigmaσ 中寻找出了一个集合,这个集合有最低的 cost:
- LmatchL_{match}Lmatch 是真值 yiy_iyi 和第 σ(i)\sigma(i)σ(i) 个预测结果的 matching cost,是用匈牙利算法计算的。
- 这个 matching cost 同时考虑了类别、框的相似度
- 第 i 个真值可以看成 yi=(ci,bi)y_i=(c_i, b_i)yi=(ci,bi),其中 cic_ici 是类别 label,bi∈[0,1]4b_i\in[0, 1]^4bi∈[0,1]4 是框的中心和宽高
- 对于第 σ(i)\sigma(i)σ(i) 个预测,作者定义类别 cic_ici 的预测为 p^σ(i)(ci)\hat{p}_{\sigma(i)}(c_i)p^σ(i)(ci),框的预测为 b^σ(i)\hat{b}_{\sigma(i)}b^σ(i)
- Lmatch(yi,y^σ(i))L_{match}(y_i, \hat{y}_{\sigma(i)})Lmatch(yi,y^σ(i)) 为
- 这种过程类似于之前的 proposal match 或 anchor match,最主要的不同是作者需要进行一对一的匹配,没有过多剩余的匹配。
第二步:计算 loss
- σ^\hat{\sigma}σ^ 是第一步中计算得到的最优分配
- 在实际操作中,为了类别平衡,作者把 ci=ϕc_i=\phici=ϕ 的预测结果的 log-probability 的权重下降10倍
- 一个目标和 ϕ\phiϕ 的 matching cost 是不基于预测的,而是一个常数
Bounding box loss:
matching cost 和 loss 的第二项都是 Lbox(.)L_{box}(.)Lbox(.),不同于其他检测器,本文作者直接对 box 进行预测,但这种简化的实现方法引入了一个相对缩放损失的问题,L1 损失对不同大小的框的相同偏移的惩罚是相同的,所以作者将 L1 loss 和 generalized IoU loss 进行了组合,所以 box loss Lbox(bi,b^σ(i))L_{box}(b_i,\hat{b}_{\sigma(i)})Lbox(bi,b^σ(i)) 为:
2.2 DETR 结构
DETR 的结构如图 2,包括三个部分:
- CNN backbone,提取特征
- encoder-decoder transformer
- simple feed forward network,进行最终的检测预测
Backbone:
输入:原始图片:ximg∈R3×H0×W0x_{img}\in R^{3\times H_0 \times W_0}ximg∈R3×H0×W0
输出:低分辨率的特征图:f∈R2048×H×Wf \in R^{2048\times H \times W}f∈R2048×H×W (H=H0/32,W=W0/32)(H=H_0/32 , W=W_0/32)(H=H0/32,W=W0/32)
Transformer encoder:
- 降维:使用 1x1 卷积,将 2048 降到 ddd 维
- 编码为序列的输入:Transformer 期望的输入为一维,所以要将二维特征转换成一维特征 d×HWd\times HWd×HW
- 每个 encoder 都是由一个多头自注意力结构和一个 feed forward network 组成,特征输入 attention 结构之前,都会加上位置编码。
Transformer decoder:
- decoder 的输入是 object query,可以理解为不同 object 的 positional embedding,object query 通过decoder 转换成一个 output embedding
- decoder 是为了把 N 个大小为 d 的 embedding 特征进行 transforming
- decoder 是由多头自注意力结构和多头 encoder-decoder 结构组成
- 本文的decoder特点:同时并行的在每一个 decoder 层对 N 个目标进行解码
- 在每个 attention 层输入的时候,会给输入加上位置编码,最终得到输出
- 然后使用 FFN 对这些特征进行映射,映射为位置和类别,得到 N 个预测
- decoder 的输入在本文中是大小为 [100, 2, 256] ,初始化为全 0 的向量,即 decoder 学习的就是输入的这个向量
- decoder 的输出会分别送入分类头得到 [6, 2, 100,92] (coco) 和bbox头得到 [6, 2, 100, 4],然后取第一个 [2, 100,92] 和 [2, 100, 4] 作为预测的结果
Prediction feed-forward networks (FFNs)
- FFN 由 RELU + 隐层 + 线性映射层组成
- 预测:框的中心和宽高
- 线性层预测类别
- 由于预测的是一个固定长度为 N 的输出,所以新加了一个类别 ϕ\phiϕ,表示没有目标,可以看做其他检测网络中的 “背景” 类
Auxiliary decoding losses
- 经过实验,作者发现在训练 decoder 时,使用额外的 loss 很有效果,能够帮助模型输出每个类别的目标数量,所以,在每个 decoder 层,作者都会即将 FFN 和 Hungarian loss 加起来,所有 FFN 都是共享参数的。
三、效果
1、Encoder layer 个数的影响:
表 2 展示了不同 encoder 个数对效果的影响,使用 encoder AP 能提升 3.9 个点,作者猜想是因为 encoder 能捕捉全局场景,所以有利于对不同目标的解耦。
在图 3 中,展示了最后一层 encoder 的 attention map,可以看出特征图注意到了图中的很多位置,看起来能够对不同实例进行区分,能够简化decoder的目标提取和定位。
2、Decoder layer 个数的影响:
图 4 展示了随着 decoder layer 数量增加,AP 和 AP50 的变化情况,每增加一层,效果就有一定上升,总共带来了 8.2/9.5 的增加。
NMS 的影响:
- 使用了一个decoder时,当引入 NMS 后,效果得到了明显的增加,这可以解释为单个 decoding layer 没有计算输入元素的相关关系的能力,即会对一个目标产生很多预测。
- 当增加了 decoder 模块(2个和多个)后再使用 NMS 时,就没有很明显的效果提升了,即随着深度的增加而逐渐减小。这是因为 self-attention 机制能够抑制模型产生重复的预测。
使用相同的方法进行可视化,可以看出 decoder attention 比较注意位置信息,会更关注目标的末端,如头和腿,作者猜测是因为encoder已经对不同的目标进行了全局上的区分,decoder 只需要关注变化剧烈的纹理区域来提取出类别的边界。
3、Importance of FFN
- FFN 可以看成一个 1x1 的卷积层,使得 encoder 类似于一个基于 attention 的卷积网络
- 作者将该结构完全移除,只留下 attention,把网络参数从 41.3 M 降低到了 28.7 M,transformer 仅有 10.8 M 的参数,但性能降低了 2.3 AP,所以 FFN 是很重要的
4、Importance of positional encoding
- 本文的位置编码有两种,一个是空间位置编码,一个是输出位置编码,输出位置编码是不能移除的,所以作者对空间位置编码做了实验
- 实验发现位置编码对结果还是很有作用的
5、Decoder output slot analysis
图 7 可视化了 COCO2017 验证集的 20 种 bbox 预测输出, DETR 给每个查询输入学习了不同的特殊效果。
可以看出,每个 slot 都会聚焦于不同的区域和目标大小,所有的 slot 都有预测 image-wide box 的模式(对齐的红点),作者假设这与 COCO 的分布有关。
四、全景分割
五、代码
这是论文中的一段简化的 inference 代码
import torch
from torch import nn
from torchvision.models import resnet50class 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 modelimport pdb; pdb.set_trace()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) # inputs=[1, 3, 800, 1200], x=[1, 1024, 25, 38]h = self.conv(x) # h=[1, 256, 25, 38]H, W = h.shape[-2:] # H=25, W=38pos = 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) # pos=[950, 1, 256]h = self.transformer(pos + h.flatten(2).permute(2, 0, 1), self.query_pos.unsqueeze(1)) # h=[100, 1, 256]return self.linear_class(h), self.linear_bbox(h).sigmoid() # [100, 1, 92], [100, 1, 4]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)
训练:下载代码detr,然后把coco图像放到dataset下即可训练
python main.py
DETR 模型结构:detr.py
输入:原始图片
build backbone:
def build_backbone(args):position_embedding = build_position_encoding(args) # PositionEmbeddingSine()train_backbone = args.lr_backbone > 0 # Truereturn_interm_layers = args.masks # Falsebackbone = Backbone(args.backbone, train_backbone, return_interm_layers, args.dilation)model = Joiner(backbone, position_embedding) #(0) backbone() (1) PositionEmbeddingSine()model.num_channels = backbone.num_channels # 2048return model
- build transformer:
def build_transformer(args):return Transformer(d_model=args.hidden_dim,dropout=args.dropout,nhead=args.nheads,dim_feedforward=args.dim_feedforward,num_encoder_layers=args.enc_layers,num_decoder_layers=args.dec_layers,normalize_before=args.pre_norm,return_intermediate_dec=True,)
class Transformer(nn.Module):def __init__(self, d_model=512, nhead=8, num_encoder_layers=6,num_decoder_layers=6, dim_feedforward=2048, dropout=0.1,activation="relu", normalize_before=False,return_intermediate_dec=False):super().__init__()encoder_layer = TransformerEncoderLayer(d_model, nhead, dim_feedforward,dropout, activation, normalize_before)encoder_norm = nn.LayerNorm(d_model) if normalize_before else Noneself.encoder = TransformerEncoder(encoder_layer, num_encoder_layers, encoder_norm)decoder_layer = TransformerDecoderLayer(d_model, nhead, dim_feedforward,dropout, activation, normalize_before)decoder_norm = nn.LayerNorm(d_model)self.decoder = TransformerDecoder(decoder_layer, num_decoder_layers, decoder_norm,return_intermediate=return_intermediate_dec)self._reset_parameters()self.d_model = d_modelself.nhead = nheaddef _reset_parameters(self):for p in self.parameters():if p.dim() > 1:nn.init.xavier_uniform_(p)def forward(self, src, mask, query_embed, pos_embed):# flatten NxCxHxW to HWxNxCbs, c, h, w = src.shapesrc = src.flatten(2).permute(2, 0, 1)pos_embed = pos_embed.flatten(2).permute(2, 0, 1)query_embed = query_embed.unsqueeze(1).repeat(1, bs, 1)mask = mask.flatten(1)tgt = torch.zeros_like(query_embed)memory = self.encoder(src, src_key_padding_mask=mask, pos=pos_embed)hs = self.decoder(tgt, memory, memory_key_padding_mask=mask,pos=pos_embed, query_pos=query_embed)return hs.transpose(1, 2), memory.permute(1, 2, 0).view(bs, c, h, w)
其中各个模块:
encoder_layer:
TransformerEncoderLayer((self_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(linear1): Linear(in_features=256, out_features=2048, bias=True)(dropout): Dropout(p=0.1, inplace=False)(linear2): Linear(in_features=2048, out_features=256, bias=True)(norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(dropout1): Dropout(p=0.1, inplace=False)(dropout2): Dropout(p=0.1, inplace=False)
)
self.encoder
TransformerEncoder((layers): ModuleList((0): TransformerEncoderLayer((self_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(linear1): Linear(in_features=256, out_features=2048, bias=True)(dropout): Dropout(p=0.1, inplace=False)(linear2): Linear(in_features=2048, out_features=256, bias=True)(norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(dropout1): Dropout(p=0.1, inplace=False)(dropout2): Dropout(p=0.1, inplace=False))(1): TransformerEncoderLayer((self_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(linear1): Linear(in_features=256, out_features=2048, bias=True)(dropout): Dropout(p=0.1, inplace=False)(linear2): Linear(in_features=2048, out_features=256, bias=True)(norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(dropout1): Dropout(p=0.1, inplace=False)(dropout2): Dropout(p=0.1, inplace=False))(2): TransformerEncoderLayer((self_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(linear1): Linear(in_features=256, out_features=2048, bias=True)(dropout): Dropout(p=0.1, inplace=False)(linear2): Linear(in_features=2048, out_features=256, bias=True)(norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(dropout1): Dropout(p=0.1, inplace=False)(dropout2): Dropout(p=0.1, inplace=False))(3): TransformerEncoderLayer((self_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(linear1): Linear(in_features=256, out_features=2048, bias=True)(dropout): Dropout(p=0.1, inplace=False)(linear2): Linear(in_features=2048, out_features=256, bias=True)(norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(dropout1): Dropout(p=0.1, inplace=False)(dropout2): Dropout(p=0.1, inplace=False))(4): TransformerEncoderLayer((self_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(linear1): Linear(in_features=256, out_features=2048, bias=True)(dropout): Dropout(p=0.1, inplace=False)(linear2): Linear(in_features=2048, out_features=256, bias=True)(norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(dropout1): Dropout(p=0.1, inplace=False)(dropout2): Dropout(p=0.1, inplace=False))(5): TransformerEncoderLayer((self_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(linear1): Linear(in_features=256, out_features=2048, bias=True)(dropout): Dropout(p=0.1, inplace=False)(linear2): Linear(in_features=2048, out_features=256, bias=True)(norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(dropout1): Dropout(p=0.1, inplace=False)(dropout2): Dropout(p=0.1, inplace=False)))
)
decoder layer:
TransformerDecoderLayer((self_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(multihead_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(linear1): Linear(in_features=256, out_features=2048, bias=True)(dropout): Dropout(p=0.1, inplace=False)(linear2): Linear(in_features=2048, out_features=256, bias=True)(norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm3): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(dropout1): Dropout(p=0.1, inplace=False)(dropout2): Dropout(p=0.1, inplace=False)(dropout3): Dropout(p=0.1, inplace=False)
)
self.decoder
TransformerDecoder((layers): ModuleList((0): TransformerDecoderLayer((self_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(multihead_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(linear1): Linear(in_features=256, out_features=2048, bias=True)(dropout): Dropout(p=0.1, inplace=False)(linear2): Linear(in_features=2048, out_features=256, bias=True)(norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm3): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(dropout1): Dropout(p=0.1, inplace=False)(dropout2): Dropout(p=0.1, inplace=False)(dropout3): Dropout(p=0.1, inplace=False))(1): TransformerDecoderLayer((self_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(multihead_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(linear1): Linear(in_features=256, out_features=2048, bias=True)(dropout): Dropout(p=0.1, inplace=False)(linear2): Linear(in_features=2048, out_features=256, bias=True)(norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm3): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(dropout1): Dropout(p=0.1, inplace=False)(dropout2): Dropout(p=0.1, inplace=False)(dropout3): Dropout(p=0.1, inplace=False))(2): TransformerDecoderLayer((self_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(multihead_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(linear1): Linear(in_features=256, out_features=2048, bias=True)(dropout): Dropout(p=0.1, inplace=False)(linear2): Linear(in_features=2048, out_features=256, bias=True)(norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm3): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(dropout1): Dropout(p=0.1, inplace=False)(dropout2): Dropout(p=0.1, inplace=False)(dropout3): Dropout(p=0.1, inplace=False))(3): TransformerDecoderLayer((self_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(multihead_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(linear1): Linear(in_features=256, out_features=2048, bias=True)(dropout): Dropout(p=0.1, inplace=False)(linear2): Linear(in_features=2048, out_features=256, bias=True)(norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm3): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(dropout1): Dropout(p=0.1, inplace=False)(dropout2): Dropout(p=0.1, inplace=False)(dropout3): Dropout(p=0.1, inplace=False))(4): TransformerDecoderLayer((self_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(multihead_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(linear1): Linear(in_features=256, out_features=2048, bias=True)(dropout): Dropout(p=0.1, inplace=False)(linear2): Linear(in_features=2048, out_features=256, bias=True)(norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm3): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(dropout1): Dropout(p=0.1, inplace=False)(dropout2): Dropout(p=0.1, inplace=False)(dropout3): Dropout(p=0.1, inplace=False))(5): TransformerDecoderLayer((self_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(multihead_attn): MultiheadAttention((out_proj): _LinearWithBias(in_features=256, out_features=256, bias=True))(linear1): Linear(in_features=256, out_features=2048, bias=True)(dropout): Dropout(p=0.1, inplace=False)(linear2): Linear(in_features=2048, out_features=256, bias=True)(norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(norm3): LayerNorm((256,), eps=1e-05, elementwise_affine=True)(dropout1): Dropout(p=0.1, inplace=False)(dropout2): Dropout(p=0.1, inplace=False)(dropout3): Dropout(p=0.1, inplace=False)))(norm): LayerNorm((256,), eps=1e-05, elementwise_affine=True)
)
训练:engine.py
def train_one_epoch(model: torch.nn.Module, criterion: torch.nn.Module,data_loader: Iterable, optimizer: torch.optim.Optimizer,device: torch.device, epoch: int, max_norm: float = 0):model.train()criterion.train()metric_logger = utils.MetricLogger(delimiter=" ")metric_logger.add_meter('lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))metric_logger.add_meter('class_error', utils.SmoothedValue(window_size=1, fmt='{value:.2f}'))header = 'Epoch: [{}]'.format(epoch)print_freq = 10for samples, targets in metric_logger.log_every(data_loader, print_freq, header):samples = samples.to(device) # samples.tensors.shape=[2, 3, 736, 920]targets = [{k: v.to(device) for k, v in t.items()} for t in targets]outputs = model(samples) # outputs.keys(): ['pred_logits', 'pred_boxes', 'aux_outputs']# outputs['pred_logits'].shape=[2, 100, 92], outputs['pred_boxes'].shape=[2, 100, 4]# outputs['aux_outputs'][0]['pred_logits'].shape = [2, 100, 92]# outputs['aux_outputs'][0]['pred_boxes'].shape = [2, 100, 4]loss_dict = criterion(outputs, targets)weight_dict = criterion.weight_dictlosses = sum(loss_dict[k] * weight_dict[k] for k in loss_dict.keys() if k in weight_dict)# reduce losses over all GPUs for logging purposesloss_dict_reduced = utils.reduce_dict(loss_dict)loss_dict_reduced_unscaled = {f'{k}_unscaled': vfor k, v in loss_dict_reduced.items()}loss_dict_reduced_scaled = {k: v * weight_dict[k]for k, v in loss_dict_reduced.items() if k in weight_dict}losses_reduced_scaled = sum(loss_dict_reduced_scaled.values())loss_value = losses_reduced_scaled.item()if not math.isfinite(loss_value):print("Loss is {}, stopping training".format(loss_value))print(loss_dict_reduced)sys.exit(1)optimizer.zero_grad()losses.backward()if max_norm > 0:torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm)optimizer.step()metric_logger.update(loss=loss_value, **loss_dict_reduced_scaled, **loss_dict_reduced_unscaled)metric_logger.update(class_error=loss_dict_reduced['class_error'])metric_logger.update(lr=optimizer.param_groups[0]["lr"])# gather the stats from all processesmetric_logger.synchronize_between_processes()print("Averaged stats:", metric_logger)return {k: meter.global_avg for k, meter in metric_logger.meters.items()}
上述代码中的 target 长下面这个样子:len(target)=2
({'boxes': tensor([[0.4567, 0.4356, 0.3446, 0.2930],[0.8345, 0.4459, 0.3310, 0.3111],[0.4484, 0.0582, 0.3947, 0.1164],[0.8436, 0.0502, 0.3128, 0.1005],[0.7735, 0.5084, 0.0982, 0.0816],[0.1184, 0.4742, 0.2369, 0.2107],[0.4505, 0.4412, 0.3054, 0.2844],[0.8727, 0.4563, 0.1025, 0.0892],[0.1160, 0.0405, 0.2319, 0.0810],[0.8345, 0.4266, 0.3310, 0.2843]]), 'labels': tensor([2, 2, 2, 2, 2, 2, 2, 2, 2, 2]), 'image_id': tensor([382006]), 'area': tensor([45937.5547, 46857.6406, 20902.2129, 14303.7432, 3646.2932, 22717.0332, 39523.7812, 4161.9199, 8552.1719, 42826.0391]), 'iscrowd': tensor([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 'orig_size': tensor([429, 640]), 'size': tensor([711, 640])}, {'boxes': tensor([[0.7152, 0.3759, 0.0934, 0.0804],[0.8129, 0.3777, 0.0576, 0.0562],[0.7702, 0.3866, 0.0350, 0.0511],[0.7828, 0.6463, 0.0743, 0.2580],[0.8836, 0.5753, 0.1511, 0.2977],[0.9162, 0.6202, 0.0880, 0.3273],[0.8424, 0.3788, 0.0254, 0.0398],[0.9716, 0.3712, 0.0569, 0.0707],[0.0615, 0.4210, 0.0242, 0.0645],[0.8655, 0.3775, 0.0398, 0.0368],[0.8884, 0.3701, 0.0349, 0.0329],[0.9365, 0.3673, 0.0144, 0.0221],[0.5147, 0.1537, 0.0220, 0.0541],[0.9175, 0.1185, 0.0294, 0.0438],[0.0675, 0.0934, 0.0223, 0.0596],[0.9125, 0.3683, 0.0185, 0.0347],[0.9905, 0.3934, 0.0191, 0.0373],[0.5370, 0.1577, 0.0211, 0.0553]]), 'labels': tensor([2, 2, 2, 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2]), 'image_id': tensor([565286]), 'area': tensor([ 3843.2710, 1264.0637, 753.2280, 8374.9131, 11725.9863, 11407.3760, 373.8589, 1965.6881, 649.5052, 625.6856, 483.2297, 117.1264, 733.8372, 727.9525, 758.3719, 307.3998, 365.8919, 712.7703]), 'iscrowd': tensor([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 'orig_size': tensor([512, 640]), 'size': tensor([736, 920])})
【Transformer】DETR: End-to-End Object Detection with Transformers相关推荐
- 【翻译】Focal Loss for Dense Object Detection(RetinaNet)
[翻译]Focal Loss for Dense Object Detection(RetinaNet) 目录 摘要 1.介绍 2.相关工作 3.Focal Loss 3.1 平衡的交叉熵损失 3.2 ...
- 【显著性物体检测】【ECCV2018】Reverse Attention for Salient Object Detection【论文笔记】
简介:在不怎么增加计算量的前提下,采用从粗到精的思想,由高级特征到低级特征,补全显著性检测的轮廓[最近很多都是基于这个思想].模型的速度与效果都占优.具体关注,是怎么实现特征的多级利用的. ECSSD ...
- 【OrientedRepPoints】Oriented RepPoints for Aerial Object Detection核心点概括
论文地址:https://arxiv.org/abs/2105.11111 翻译:https://blog.csdn.net/songyuc/article/details/128227048 一.概 ...
- 【OrientedRepPoints】Oriented RepPoints for Aerial Object Detection的译读笔记
Oriented RepPoints for Aerial Object Detection 摘要 与通用目标不同,航空目标通常不是正轴对齐而且具有任意的方向,且周围背景较为杂乱.与主流方法使用边 ...
- 【Transformer】ATS: Adaptive Token Sampling For Efficient Vision Transformers
文章目录 一.背景 二.动机 三.方法 3.1 Token Scoring 3.2 Token Sampling 四.效果 一.背景 尽管现有的 transformer 模型在分类等任务上取得了较好的 ...
- 【Transformer】ViT:An image is worth 16x16: transformers for image recognition at scale
文章目录 一.背景和动机 二.方法 三.效果 四.Vision Transformer 学习到图像的哪些特征了 五.代码 代码链接:https://github.com/lucidrains/vit- ...
- 【ICLR2022】DECOUPLED ADAPTATION FOR CROSS-DOMAIN OBJECT DETECTION 解耦自适应用于跨域目标检测
摘要 解决的问题(动机): 跨域⽬标检测⽐⽬标分类更具挑战性,因为图像中存在多个对象,并且每个⽬标在未标记的⽬标域中的位置是未知的.因此,当我们调整不同物体的特征以增强探测器的可迁移性时,前景和背景的 ...
- 【Transformer】医学分割领域的应用与扩展(论文阅读)(二) || DETR
声明:仅学习使用~ 目录 1. Transformer学习 2. DETR 1. Transformer学习 前篇指路:[Transformer]医学分隔领域的应用与扩展(论文阅读)(一) 继续- 关 ...
- 【论文阅读】【3d目标检测】Group-Free 3D Object Detection via Transformers
论文标题:Group-Free 3D Object Detection via Transformers iccv2021 本文主要是针对votenet等网络中采用手工group的问题提出的改进 我们 ...
最新文章
- 老李分享:系统可用性评估
- DHTML【8】--CSS
- kaggle比赛模型融合指南
- Eclipse中如何修改SVN的地址
- HDU 2647 Reward (拓扑排序)
- 你好,同学!在云端学习最潮的技术吧!
- Linux下profile environment bashrc的区别
- 计算机网络符号显示叹号,在Win7系统中,电脑网络出现感叹号怎么解决?
- Python魔法方法(magic method)细解几个常用魔法方法(下)
- (C++)wchar_t 转 string / TCHAR转为char/判断是否进程运行/获得目标进程的入口
- Python学习之路day03——008用户输入input()方法
- ajax中加入if,如何添加if语句到Ajax
- 时间操作(Java版)—获取给定时间与当前系统时间的差值(以毫秒为单位)
- C语言打印杨辉三角(C笔记)
- 这是我转载的一篇,真的是不错《把SWF变回FLA》大家可以试试
- duet太香啦啦啦啦啦啦啦啦啦啦
- android tv 菜单键,Android TV开发总结(三)构建一个TV app的焦点控制及遇到的坑
- 剑灵力士卡刀ahk_技术宅分享 剑灵召唤一键卡刀代码使用教程
- 数据结构与算法——从零开始学习(一)基础概念篇
- WPS Office 2019 For Linux 英文版改为中文版
热门文章
- 20165201 2017-2018-2 《Java程序设计》第3周学习总结
- 关于C语言中递归的一点点小问题
- MessageBox、::MessageBox 、AfxMessageBox三者的区别
- c语言循环结成绩统计,学生成绩统计C语言实现
- this指针_C++:07this指针
- pdo mysql like_PHP PDO准备的语句-MySQL LIKE查询
- python文件行数统计_文件行数和代码行数统计
- python最新面试题_2018年最新Python面试题及答案
- python中的loop_django学习笔记之forloop
- C语言万年历 年历月历日历都要,c语言万年历