【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.pyDETR 模型結構:detr.py
-
輸入:原始圖片
-
build backbone:
- build transformer:
其中各個模塊:
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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 英伟达 GeForce RTX 4070
- 下一篇: 古尔曼不认同郭明錤预测:未听说苹果会在