Paper · 2022-11-22 · cs.CV
DETRs with Collaborative Hybrid Assignments Training
Co-DETR adds training-only auxiliary detection heads (ATSS, Faster R-CNN) with one-to-many label assignment on the DETR encoder output, and feeds their positive boxes back to the shared decoder as extra query groups. Inference is the unchanged DETR. Deformable-DETR R50 (12 ep) goes from 37.1 to 42.9 AP on COCO val; a ViT-L model reaches 66.0 AP on test-dev.
Object detectionLabel assignmentBipartite matching for set-prediction lossesObject queries (learned query slots in transformer decoders)object-detectiontransformercomputer-visionlabel-assignmenttraining-scheme
arXivPDFCodeMarkdown14 min read
AI-compiled by claude-opus-5-5 on 2026-10-18, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.
In plain words
DETR-style detectors find objects by giving each real object to exactly one "slot" (query) of the model during training, using a matching step. That keeps the output free of duplicates, so no clean-up step is needed at the end. The downside is thin feedback: each object teaches the model through a single slot, so the feature extractor (the encoder) and the part that looks up objects (the decoder) learn slowly.
Older detectors such as ATSS and Faster R-CNN do the opposite. They mark many nearby positions as correct for the same object ("one-to-many" assignment). That gives the model much more feedback, but it produces duplicate boxes that have to be filtered afterwards.
Co-DETR uses both during training only. It attaches one or two classic detection heads to the DETR encoder, so the encoder gets the dense feedback those heads produce. It then takes the positions those heads marked as positive and runs them through the DETR decoder as extra groups of queries, each already paired with its object, which gives the decoder many more positive examples. At test time the extra heads and query groups are dropped, so the deployed model is exactly the original DETR variant. Costs and speed at inference stay the same; it just learns faster and ends up more accurate.
TL;DR
Co-DETR is a training scheme for any DETR variant. K auxiliary heads with classic one-to-many label assignment (ATSS, Faster R-CNN, …) are trained on a feature pyramid built from the encoder output. Their positive anchors or proposals become K extra groups of decoder queries, supervised with the auxiliary head's targets and no Hungarian matching. All auxiliary parts are dropped at inference. Author-reported COCO val AP: Deformable-DETR R50 12 ep 37.1 → 42.9 (K=2); DINO-Deformable-DETR Swin-L 36 ep 58.5 → 59.5; the system-level ViT-L model (Objects365 pre-training plus TTA) reaches 66.0 AP on test-dev and 67.9 AP on LVIS val. Training costs more: with K=2, GPU hours go from 70 to 120 for Deformable-DETR++ R50 tab. 7.
Problem
With one-to-one set matching each ground-truth box supervises one query, so few queries are positive §1. The authors argue this causes two problems. (1) Supervision on the encoder output is sparse, so its features separate foreground from background less well. They measure this with feature-norm "discriminability" maps and IoF-IoB curves, where replacing the Deformable-DETR decoder with an ATSS head gives a higher curve §1, §3.4, fig. 2, fig. 3. (2) Cross-attention in the decoder learns inefficiently with few positive queries, and Hungarian matching is unstable: the ground truth assigned to a query changes during training §3.4, fig. 5. Methods that add positives through duplicated query groups (Group-DETR, H-DETR) still use Hungarian matching. They also add many negative queries and do not supervise the encoder feature map densely §3.5.
Method
Standard DETR pipeline (backbone → encoder → decoder with object queries), plus two training-only additions §3.1, fig. 4:
- Multi-scale adapter §3.2. Turn the encoder output into a pyramid \{\mathcal{F}_1,\dots,\mathcal{F}_J\}, where level j has stride 2^{2+j}. For a single-scale encoder, follow ViTDet: apply 3×3 stride-2 convs to go down, and bilinear interpolation plus a 3×3 conv to go up. For a multi-scale encoder (Deformable-DETR, DINO), only downsample the coarsest encoder level to add one more level §3.2. In the code this is one 3×3 stride-2 conv plus GroupNorm(32) on the last encoder level co_deformable_detr_head.py co_deformable_detr_head.py.
- Collaborative auxiliary heads §3.2. Each of the K heads i predicts \hat{\mathbf{P}}_i on the pyramid, and its own assigner \mathcal{A}_i yields positives, their boxes, and negatives: \mathbf{P}_{i}^{\{pos\}}, \mathbf{B}_{i}^{\{pos\}}, \mathbf{P}_{i}^{\{neg\}} = \mathcal{A}_{i}(\hat{\mathbf{P}}_{i}, \mathbf{G}) eq. 1 \{pos\} / \{neg\} are sets of (level j, coordinate in \mathcal{F}_j) pairs, \mathbf{B}_i^{\{pos\}} are the positive boxes, and \mathbf{P} are the targets (classes, regression offsets) §3.2. The head loss is \mathcal{L}^{enc}_{i} = \mathcal{L}_{i}(\hat{\mathbf{P}}_{i}^{\{pos\}}, \mathbf{P}_{i}^{\{pos\}}) + \mathcal{L}_{i}(\hat{\mathbf{P}}_{i}^{\{neg\}}, \mathbf{P}_{i}^{\{neg\}}), \qquad \mathcal{L}^{enc} = \sum_{i=1}^{K}\mathcal{L}^{enc}_{i} eq. 2 eq. 3 with no regression loss on negatives §3.2. Per-head details are in Table 1 below.
- Customized positive queries §3.3. For head i with M_i positives \mathbf{B}_i^{\{pos\}} \in \mathbb{R}^{M_i\times 4}, build queries \mathbf{Q}_i \in \mathbb{R}^{M_i\times C}: \mathbf{Q}_{i} = \mathrm{Linear}(\mathrm{PE}(\mathbf{B}_{i}^{\{pos\}}))+\mathrm{Linear}(\mathrm{E}(\{\mathcal{F}_*\},\{pos\})) eq. 4 PE is a positional encoding of the box, and E picks the pyramid features at the positive (level, coordinate) indices §3.3. Each head's queries form a separate group, isolated from the other groups §1. The groups pass through the same L decoder layers as the main queries (shared parameters). Every query in an auxiliary group is positive with a pre-assigned target, so no matching is run §3.3. Per decoder layer l: \mathcal{L}^{dec}_{i, l} = \widetilde{\mathcal{L}}(\widetilde{\mathbf{P}}_{i, l}, \mathbf{P}_{i}^{\{pos\}}) eq. 5
- Total loss §3.3:
\mathcal{L}^{global} = \sum_{l=1}^{L}\left(\widetilde{\mathcal{L}}^{dec}_{l} + \lambda_{1}\sum_{i=1}^{K}\mathcal{L}^{dec}_{i, l} + \lambda_{2}\mathcal{L}^{enc}\right) eq. 6
\widetilde{\mathcal{L}}^{dec}_{l} is the usual one-to-one (Hungarian) DETR loss. Because \lambda_2\mathcal{L}^{enc} sits inside the sum over L layers, the encoder loss effectively counts L\cdot\lambda_2 times; the code folds this into the auxiliary heads' loss weights (
loss_weight = w * num_dec_layer * lambda_2) co_deformable_detr_r50_1x_coco.py co_deformable_detr_r50_1x_coco.py. - Inference: only the original DETR branch runs. No extra parameters or compute, and no NMS for the base method [abstract, §1]. The SOTA Co-DINO models, however, add NMS (see Pitfalls) §4.3.
Table 1: auxiliary heads tab. 1 (unless stated, the original implementations are followed, e.g. anchor generation):
| Head i | Loss \mathcal{L}_i | {pos}, {neg} generation | \mathbf{P}_i generation | \mathbf{B}_i^{\{pos\}} generation |
|---|---|---|---|---|
| Faster-RCNN | cls: CE; reg: GIoU | pos: IoU(proposal, gt) > 0.5; neg: IoU(proposal, gt) < 0.5 | pos: gt labels, offset(proposal, gt); neg: gt labels | positive proposals (x_1,y_1,x_2,y_2) |
| ATSS | cls: Focal; reg: GIoU, BCE | pos: IoU(anchor, gt) > (mean+std); neg: IoU(anchor, gt) < (mean+std) | pos: gt labels, offset(anchor, gt), centerness; neg: gt labels | positive anchors (x_1,y_1,x_2,y_2) |
| RetinaNet | cls: Focal; reg: GIoU | pos: IoU(anchor, gt) > 0.5; neg: IoU(anchor, gt) < 0.4 | pos: gt labels, offset(anchor, gt); neg: gt labels | positive anchors (x_1,y_1,x_2,y_2) |
| FCOS | cls: Focal; reg: GIoU, BCE | pos: points inside gt center area; neg: points outside | pos: gt labels, ltrb distance, centerness; neg: gt labels | FCOS point (cx, cy), w=h=8\times 2^{2+j} |
Head micro-design app. B: one-stage heads use GIoU loss and 1 stacked conv instead of 4, which the authors report costs no accuracy. Two-stage heads (RPN + RCNN from Faster/Mask R-CNN) use the same multi-scale features as the one-stage heads (stride 8 to 128), with GIoU in the RCNN stage.
# Co-DETR training step [§3.2] [§3.3] [eq. 1-6]
# Input: images (B, 3, H, W); gt: per image a list of (class, box)
# Output: scalar loss
def co_detr_training_step(images, gt, aux_heads, lambda_1, lambda_2):
feats = backbone(images)
# Encoder runs once; its output is shared by all branches [§3.1]
memory = encoder(feats) # list of (B, C, Hj, Wj)
# Main branch: object queries + Hungarian loss per layer [eq. 6]
main_preds = decoder(object_queries, memory) # one set per layer
loss = sum(hungarian_loss(p, gt) for p in main_preds)
# Add one coarser level: 3x3 stride-2 conv on last level [§3.2]
pyramid = memory + [downsample(memory[-1])]
for head in aux_heads:
# One-to-many assignment by the head's own rule [eq. 1] [tab. 1]
preds = head(pyramid)
pos, pos_boxes, pos_targets, neg = head.assign(preds, gt)
# Head loss, regression only on positives [eq. 2] [eq. 3]
# Inside the sum over L layers in eq. 6, so it counts L times
loss += num_layers * lambda_2 * head.loss(preds, pos, neg)
# Customized positive queries from boxes + features [eq. 4]
content = linear_feat(gather(pyramid, pos))
queries = linear_pe(pos_encoding(pos_boxes)) + content
# Same decoder weights, targets fixed, no matching [eq. 5]
aux_preds = decoder(queries, memory)
for layer_preds in aux_preds:
loss += lambda_1 * detr_loss(layer_preds, pos_targets)
return lossIn the code, query targets for the auxiliary groups are the ground-truth box matched to each positive (not the anchor), in normalized cxcywh. Each image keeps at most max_pos_coords = 300 positives per head (random subset beyond that), and groups are padded to at least 9 queries co_deformable_detr_head.py. Each auxiliary decoder layer uses the main head's losses (focal cls, L1, GIoU), multiplied by \lambda_1 co_deformable_detr_head.py.
Analysis tools §3.4. Discriminability score: take the per-pixel \ell_2 norm \widehat{\mathcal{F}}_j of each encoder level, resize it to image size and average the max-normalized maps: \mathcal{D}(\mathcal{F}) = \frac{1}{J}\sum_{j=1}^{J}\frac{\widehat{\mathcal{F}}_{j}}{\max(\widehat{\mathcal{F}}_{j})} eq. 7 Threshold it at S and compare with the GT foreground mask \mathcal{M}^{fg}: \mathcal{I}^{fg} = \frac{\sum_{h,w}\mathbb{1}(\mathcal{D}(\mathcal{F}_{h,w})>S)\cdot \mathcal{M}^{fg}_{h,w}}{\sum_{h,w}\mathcal{M}^{fg}_{h,w}} eq. 8 IoB is computed the same way on the background; sweeping S traces the IoF-IoB curve §3.4. Conflicts between heads H_i, H_j are measured as the KL divergence between Grad-CAM maps of the encoder features, averaged over COCO val §4.4 app. A: \mathcal{S}_{i,j} =\frac{1}{|\mathbf{D}|} \sum_{\mathbf{I} \in \mathbf{D}} \mathrm{KL}(\mathcal{C}(H_i(\mathbf{I})), \mathcal{C}(H_j(\mathbf{I}))), \qquad \mathcal{S}_{i} =\frac{1}{2(K-1)} \sum_{j \neq i}^{K} (\mathcal{S}_{i,j}+\mathcal{S}_{j,i}) eq. 9 eq. 10
Hyperparameters
| Name | Value | Where | Notes |
|---|---|---|---|
| auxiliary heads | K=2: ATSS + Faster-RCNN; K=1: ATSS | §4.1 | ablations default to K=1 §4.4; R50 configs ship K=2 co_deformable_detr_r50_1x_coco.py |
| \lambda_1, \lambda_2 | 1.0, 2.0 | §4.1 app. A, tab. 13 | \lambda_2 effectively × num decoder layers (6) in code |
| object queries | 300 (Co-Deformable-DETR); 900 for DINO variants and the 900q Swin-L model | §4.1 tab. 4 | |
| max customized queries per head per image | 300 | co_deformable_detr_head.py | not stated in paper |
| stacked convs in one-stage aux head | 1 | app. B tab. 12 co_deformable_detr_r50_1x_coco.py | reduced from 4 |
| aux feature strides | 8 to 128 | app. B | Co-DINO configs use 4 to 128 co_dino_5scale_r50_1x_coco.py |
| ATSS assigner | topk 9 | co_deformable_detr_r50_1x_coco.py | paper: "original implementation" tab. 1 |
| RCNN assigner / sampler | IoU 0.5/0.5; 512 RoIs, 25% positive | tab. 1 co_deformable_detr_r50_1x_coco.py | sampler not stated in paper |
| RPN assigner / sampler | IoU 0.7/0.3; 256 anchors, 50% positive; 1000 proposals | co_deformable_detr_r50_1x_coco.py | not stated in paper |
| optimizer | AdamW, lr 2e-4, wd 1e-4, backbone lr × 0.1, grad clip 0.1 | co_deformable_detr_r50_1x_coco.py | paper: "consistent with the baselines" §4.1 |
| schedule (1×) | 12 epochs, lr step at epoch 11 | co_deformable_detr_r50_1x_coco.py | |
| batch size | 32 total for ablations | §4.4 | code: 2 images/GPU co_deformable_detr_r50_1x_coco.py |
| Co-DINO-Deformable-DETR++ augmentation | large-scale jitter + copy-paste | §4.1 | |
| ViT-L Objects365 stage | EVA-02 init; 26 ep, lr 2.5e-4 ×0.1 at ep 24, batch 224, max side 1280, short side 480–1024, 1500 queries + 1000 DN queries | app. B | |
| ViT-L COCO fine-tune | 12 ep, lr 5e-5 ×0.1 at ep 8, batch 64, short side 480–1536, long ≤ 2400, EMA, TTA at test | §4.3 app. B | |
| LVIS system model | Co-DINO++ on Objects365: batch 192, lr 2e-4, 1280×1280, 900 queries + 1000 DN; LVIS fine-tune: 16 ep, batch 64, lr 5e-5 ×0.1 at ep 9 and 15, 1536×1536, no EMA, extra auxiliary mask branch, FedLoss | §4.3 app. B | |
| warmup, layer-wise decay for ViT-L | not stated |
Results
Author-reported, COCO val unless noted; all reproduced with mmdetection §4.2.
Plain baselines tab. 2:
| Method | K | epochs | AP |
|---|---|---|---|
| Conditional DETR-C5 | 0 / 1 / 2 | 36 | 39.4 / 41.5 / 41.8 |
| DAB-DETR-C5 | 0 / 1 / 2 | 36 | 41.2 / 43.1 / 43.5 |
| Deformable-DETR | 0 / 1 / 2 | 12 | 37.1 / 42.3 / 42.9 |
| Deformable-DETR | 0 / 1 / 2 | 36 | 43.3 / 46.8 / 46.5 |
Strong baselines tab. 3 († 5 feature levels, ‡ Swin-L):
| Method | K | epochs | AP |
|---|---|---|---|
| Deformable-DETR++ (R50) | 0 / 1 / 2 | 12 | 47.1 / 48.7 / 49.5 |
| DINO-Deformable-DETR† (R50) | 0 / 1 / 2 | 12 | 49.4 / 51.0 / 51.2 |
| Deformable-DETR++‡ | 0 / 1 / 2 | 12 | 55.2 / 56.4 / 56.9 |
| DINO-Deformable-DETR†‡ | 0 / 1 / 2 | 36 | 58.5 / 59.3 / 59.5 |
Comparison with DETR variants tab. 4 (Co-DINO rows also use QFL and NMS §4.3):
| Method | Backbone | #query | epochs | AP | AP50 | AP75 | APS | APM | APL |
|---|---|---|---|---|---|---|---|---|---|
| DINO-Deformable-DETR† | R50 | 900 | 12 | 49.4 | 66.9 | 53.8 | 32.3 | 52.5 | 63.9 |
| DINO-Deformable-DETR† | R50 | 900 | 36 | 51.2 | 69.0 | 55.8 | 35.0 | 54.3 | 65.3 |
| DINO-Deformable-DETR† | Swin-L | 900 | 36 | 58.5 | 77.0 | 64.1 | 41.5 | 62.3 | 74.0 |
| H-Deformable-DETR | R50 | 300 | 12 | 48.7 | 66.4 | 52.9 | 31.2 | 51.5 | 63.5 |
| H-Deformable-DETR | Swin-L | 900 | 36 | 57.9 | 76.8 | 63.6 | 42.4 | 61.9 | 73.4 |
| Co-Deformable-DETR | R50 | 300 | 12 | 49.5 | 67.6 | 54.3 | 32.4 | 52.7 | 63.7 |
| Co-Deformable-DETR | Swin-L | 900 | 36 | 58.5 | 77.1 | 64.5 | 42.4 | 62.4 | 74.0 |
| Co-DINO-Deformable-DETR† | R50 | 900 | 12 | 52.1 | 69.4 | 57.1 | 35.4 | 55.4 | 65.9 |
| Co-DINO-Deformable-DETR† | Swin-L | 900 | 12 | 58.9 | 76.9 | 64.8 | 42.6 | 62.7 | 75.1 |
| Co-DINO-Deformable-DETR† | Swin-L | 900 | 24 | 59.8 | 77.7 | 65.5 | 43.6 | 63.5 | 75.5 |
| Co-DINO-Deformable-DETR† | Swin-L | 900 | 36 | 60.0 | 77.7 | 66.1 | 44.6 | 63.9 | 75.7 |
| Co-DINO-Deformable-DETR++† | R50 | 900 | 12 | 52.1 | 69.3 | 57.3 | 35.4 | 55.5 | 67.2 |
| Co-DINO-Deformable-DETR++† | R50 | 900 | 36 | 54.8 | 72.5 | 60.1 | 38.3 | 58.4 | 69.6 |
| Co-DINO-Deformable-DETR++† | Swin-L | 900 | 12 | 59.3 | 77.3 | 64.9 | 43.3 | 63.3 | 75.5 |
| Co-DINO-Deformable-DETR++† | Swin-L | 900 | 24 | 60.4 | 78.3 | 66.4 | 44.6 | 64.2 | 76.5 |
| Co-DINO-Deformable-DETR++† | Swin-L | 900 | 36 | 60.7 | 78.5 | 66.7 | 45.1 | 64.7 | 76.4 |
(Table 4 also lists Conditional-DETR, Anchor-DETR, DAB-DETR, AdaMixer, Deformable-DETR, DN-Deformable-DETR and Group-DINO at 42.1 to 58.4 AP tab. 4.)
System level, COCO tab. 5 (Co-DETR: ViT-L, Objects365 pre-training, TTA §4.3):
| Method | Backbone | enc. #params | val AP | test-dev AP |
|---|---|---|---|---|
| HTC++ | SwinV2-G | 3.0B | 62.5 | 63.1 |
| DINO | Swin-L | 218M | 63.2 | 63.3 |
| BEIT3 | ViT-g | 1.9B | - | 63.7 |
| FD | SwinV2-G | 3.0B | - | 64.2 |
| DINO | FocalNet-H | 746M | 64.2 | 64.3 |
| Group DETRv2 | ViT-H | 629M | - | 64.5 |
| EVA-02 | ViT-L | 304M | 64.1 | 64.5 |
| DINO | InternImage-G | 3.0B | 65.3 | 65.5 |
| Co-DETR | ViT-L | 304M | 65.9 | 66.0 |
LVIS box AP tab. 6 (no TTA for the ViT-L model §4.3):
| Method | Backbone | enc. #params | val | minival |
|---|---|---|---|---|
| H-DETR | Swin-L | 218M | 47.9 | - |
| ViTDet | ViT-L / ViT-H | 307M / 632M | 51.2 / 53.4 | - |
| GLIPv2 | Swin-H | 637M | - | 59.8 |
| DINO | InternImage-G | 3.0B | 63.2 | 65.8 |
| EVA-02 | ViT-L | 304M | 65.2 | - |
| Co-DETR | Swin-L | 218M | 56.9 | 62.3 |
| Co-DETR | ViT-L | 304M | 67.9 | 71.9 |
Ablations (Deformable-DETR R50, K=1, batch 32, unless stated) §4.4:
Number and kind of heads, Deformable-DETR++ R50 tab. 7:
| K | Aux heads | Memory (MB) | GPU hours | AP |
|---|---|---|---|---|
| 0 | - | 12808 | 70 | 47.1 |
| 0 (H-Deformable-DETR) | - | 15307 | 104 | 48.4 |
| 1 | ATSS | 13947 | 86 | 48.7 |
| 2 | ATSS + PAA | 14629 | 124 | 49.0 |
| 2 | ATSS + Faster-RCNN | 14387 | 120 | 49.5 |
| 3 | ATSS + Faster-RCNN + PAA | 15263 | 150 | 49.5 |
| 6 | ATSS + Faster-RCNN + PAA + RetinaNet + FCOS + GFL | 19385 | 280 | 48.9 |
Single auxiliary head choice, 36 ep tab. 8: baseline 43.3; RetinaNet 46.1; Faster-RCNN 46.3; Mask-RCNN, FCOS, PAA, GFL 46.5 each; ATSS 46.8 AP. Other K variants from the text: two ATSS heads 49.2 vs one ATSS 48.7 vs ATSS + Faster-RCNN 49.5 §4.4; six ATSS heads 49.5 vs six different heads 48.9 §4.4.
Components tab. 9:
| aux head | pos queries | 12 ep AP | 36 ep AP |
|---|---|---|---|
| ✗ | ✗ | 37.1 | 43.3 |
| ✓ | ✗ | 41.6 | 46.2 |
| ✗ | ✓ | 40.5 | 45.3 |
| ✓ | ✓ | 42.3 | 46.8 |
Longer schedules tab. 10: Co-Deformable-DETR (K=1) 36 ep, 288 GPU h → 46.8; the baseline reaches 44.5 / 46.0 / 45.9 at 50 / 100 / 150 ep (333 / 667 / 1000 GPU h). Auxiliary branches also improve tab. 11: with NMS, ATSS goes 46.8 → 47.4 (K=1) → 48.0 (K=2) and Faster-RCNN 45.9 → 46.7 (K=2); the DETR branch 47.1 → 48.7 → 49.5. Stacked convs 0–5 in the aux head: 41.8–42.3 AP, 12 ep tab. 12. \lambda sweep, 36 ep tab. 13: \lambda_1 \in \{0.25, 0.5, 1, 2\} at \lambda_2=2 gives 46.2 / 46.6 / 46.8 / 46.1; \lambda_2 \in \{1, 2, 3, 4\} at \lambda_1=1 gives 46.1 / 46.8 / 46.5 / 46.3. Positives per GT box on COCO average 18.7 for Faster-RCNN and 8.8 for ATSS app. A. Compared with Group-DETR (3 groups, 44.6 AP), aux head alone (K=1) gives 46.2 app. A.
Paper vs code
- Padding with negatives. The paper says only positive coordinates go to the decoder §3.5. By default (
use_zero_padding=False) the code pads each image's group up to the batch maximum (at least 9, at most 300) with randomly sampled negative anchors/proposals. These get background labels with classification weight 1 and box weight 0 co_deformable_detr_head.py. - Query construction differs from eq. 4. Co-Deformable-DETR: one Linear(2C→2C)+LayerNorm on the box sine embedding, split into positional query and content query. Then LayerNorm(Linear(feature)) is added to the content, and a per-head embedding to the positional part transformer.py. Co-DINO: Linear(2C→C)+LayerNorm on the box embedding is the query, plus LayerNorm(Linear(feature)) transformer.py. Each auxiliary head has its own projection layers transformer.py. For RCNN heads the "feature" is the RoI feature of the proposal, not a pyramid point co_deformable_detr_head.py.
- Known bug kept on purpose. In Co-Deformable-DETR the head embedding is built as
nn.Embedding(num_co_heads, 1, 1, embed_dims)instead ofnn.Embedding(num_co_heads, embed_dims). The authors kept it to reproduce their ResNet-50 results and say it can be fixed for Swin transformer.py. - Faster-RCNN head losses. Table 1 lists CE + GIoU. The code's RPN stage uses sigmoid CE + L1, and the RCNN stage uses softmax CE + GIoU with weight 10 (× 6 × \lambda_2) co_deformable_detr_r50_1x_coco.py co_deformable_detr_r50_1x_coco.py. ATSS uses focal (weight 1), GIoU (weight 2) and centerness CE, all × 6 × \lambda_2 co_deformable_detr_r50_1x_coco.py.
- Pyramid levels. The paper uses strides 8 to 128 for the auxiliary heads app. B. Co-DINO configs use 6 levels with strides 4 to 128 co_dino_5scale_r50_1x_coco.py. In Co-Deformable-DETR the RoI extractor uses only strides 8 to 64 co_deformable_detr_r50_1x_coco.py.
- Inference post-processing. Co-DINO configs evaluate with soft-NMS (IoU 0.8, 300 boxes per image) co_dino_5scale_r50_1x_coco.py. They train with QualityFocalLoss co_dino_5scale_r50_1x_coco.py, matching the QFL + NMS mentioned in §4.3.
Pitfalls
- "No NMS" holds only for the base method. The headline Co-DINO numbers (tab. 4 to 6) use NMS, soft-NMS in the code. Gains over DINO in tab. 4 therefore mix the training scheme with post-processing. The tab. 3 numbers are the cleaner comparison: for example, Co-DINO R50 12 ep is 51.2 there and 52.1 in tab. 4.
- Encoder loss scale. Eq. 6 places \lambda_2\mathcal{L}^{enc} inside the sum over decoder layers. If you add the auxiliary-head loss once with weight 2.0, you get 1/6 of the weight the authors trained with (6 decoder layers). The code multiplies by
num_dec_layer. - Aux query targets. Customized queries regress the matched GT box, not the anchor/proposal they came from. The box they came from only sets the query's position (reference point) and positional encoding co_deformable_detr_head.py transformer.py.
- Group isolation. The groups must not attend to each other or to the main queries; the code runs one separate decoder pass per auxiliary head co_detr.py. Training cost therefore grows with K: GPU hours go 70 → 86 → 120 → 150 → 280 for K = 0, 1, 2, 3, 6 tab. 7.
- Ragged positives. Positive counts vary per image. The code pads to the batch max with negatives (not masked) and caps at 300 by random subsampling, so a few positives per head can be dropped for crowded images.
- More heads is not better. K>2 different heads gives no gain or hurts (6 heads: 48.9 vs 49.5 AP), which the authors attribute to conflicting assignments §4.4, fig. 6. Use ATSS for K=1 and ATSS + Faster-RCNN for K=2.
- Auxiliary heads see a reshaped encoder output, not the backbone. The extra coarse level comes from a conv on the encoder's coarsest level. The decoder of the auxiliary groups uses only the original encoder levels (the code passes
x[:-1]) co_deformable_detr_head.py. - Inconsistent cross-references. App. A points to "Table 6" and "Table 8" for the K and component ablations; in the compiled paper these are Tables 7 and 9.
- Not specified: the exact positional encoding of boxes in eq. 4 (the code uses the DETR-style sine proposal embedding), how the multi-scale adapter is initialized, and the warmup/schedule for the ViT-L runs.
Lineage
- Builds on: DETR (one-to-one set matching and Hungarian loss), plus Deformable-DETR, DAB-DETR, Conditional DETR and DINO (arXiv:2010.04159, arXiv:2201.12329, arXiv:2108.06152, arXiv:2203.03605) as base detectors. One-to-many assigners come from ATSS (arXiv:1912.02424), Faster R-CNN (arXiv:1506.01497), RetinaNet (arXiv:1708.02002) and FCOS (arXiv:1904.01355). The adapter follows ViTDet (arXiv:2203.16527).
- Compared against: Group-DETR (arXiv:2207.13085) and H-DETR (arXiv:2207.13080), which add positives through duplicated one-to-one query groups. Co-DETR instead uses classic one-to-many assigners and supervises the encoder densely §3.5.
Source and license
Adapted from “DETRs with Collaborative Hybrid Assignments Training” by Zhuofan Zong, Guanglu Song, Yu Liu (arXiv:2211.12860), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/Sense-X/Co-DETR at commit 26653521e471 (MIT). Any quoted code is shown under that license.