{"notes":[{"id":"object-detection/dino-detr","category":"object-detection","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"DINO","subtitle":"靠近，但不够近","author":"Z. Yuan","paperDate":"2022-03-07","publishedOn":"2024-12-19","world":"external/dino-detector","paperTitle":"DINO: DETR with Improved DeNoising Anchor Boxes for End-to-End Object Detection","paperUrl":"https://arxiv.org/abs/2203.03605","bibliography":{"title":"DINO: DETR with Improved DeNoising Anchor Boxes for End-to-End Object Detection","authors":["Hao Zhang","Feng Li","Shilong Liu","Lei Zhang","Hang Su","Jun Zhu","Lionel M. Ni","Heung-Yeung Shum"],"url":"https://arxiv.org/abs/2203.03605","pdfUrl":"https://arxiv.org/pdf/2203.03605v4","codeUrl":"https://github.com/IDEA-Research/DINO","preprint":{"id":"2203.03605","submittedOn":"2022-03-07","url":"https://arxiv.org/abs/2203.03605"},"publication":{"venue":"ICLR","year":2023,"kind":"conference","url":"https://iclr.cc/virtual/2023/poster/11884"},"citation":"@misc{objectdetectiondinodetr2022,\n  title = {{DINO: DETR with Improved DeNoising Anchor Boxes for End-to-End Object Detection}},\n  author = {Hao Zhang and Feng Li and Shilong Liu and Lei Zhang and Hang Su and Jun Zhu and Lionel M. Ni and Heung-Yeung Shum},\n  year = {2022},\n  eprint = {2203.03605},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/2203.03605}\n}\n","citationPath":"/content/papers/citations/object-detection/dino-detr.d8c8af775089.bib"},"thumbnail":{"src":"/content/papers/assets/6c328e7125d4762c3a4346a1c537cb4e917d47a640869bbf212de53f74ba64fc.png","width":942,"height":319},"locale":"zh-hans","path":"/content/papers/zh-hans/object-detection/dino-detr.cceb2ba57eac.md","headings":[{"id":"定义问题","text":"定义问题","depth":2},{"id":"解决问题","text":"解决问题","depth":2},{"id":"整体流程","text":"整体流程","depth":3},{"id":"对比式去噪","text":"对比式去噪","depth":3},{"id":"混合查询选择","text":"混合查询选择","depth":3},{"id":"look-forward-twice","text":"Look forward twice","depth":3},{"id":"讨论","text":"讨论","depth":2},{"id":"12-个-epoch","text":"12 个 epoch","depth":3},{"id":"练久一点","text":"练久一点","depth":3},{"id":"排行榜上的那一格","text":"排行榜上的那一格","depth":3},{"id":"消融494-是怎么叠出来的","text":"消融：49.4 是怎么叠出来的","depth":3},{"id":"结论","text":"结论","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"contrastive-learning/dino","relation":"referenced","topic":""},{"id":"object-detection/detr","relation":"referenced","topic":""},{"id":"object-detection/deformable-detr","relation":"referenced","topic":""}]},{"id":"contrastive-learning/dino","category":"contrastive-learning","legacyPath":"contrastive-learning/2104-dino","legacySlug":"2104-dino","legacyPaths":[],"title":"DINO","subtitle":"无标签的自蒸馏","author":"Z. Yuan","paperDate":"2021-04-29","publishedOn":"2025-03-18","paperTitle":"Emerging Properties in Self-Supervised Vision Transformers","paperUrl":"https://arxiv.org/abs/2104.14294","bibliography":{"title":"Emerging Properties in Self-Supervised Vision Transformers","authors":["Mathilde Caron","Hugo Touvron","Ishan Misra","Hervé Jégou","Julien Mairal","Piotr Bojanowski","Armand Joulin"],"url":"https://arxiv.org/abs/2104.14294","pdfUrl":"https://arxiv.org/pdf/2104.14294","codeUrl":null,"preprint":{"id":"2104.14294","submittedOn":"2021-04-29","url":"https://arxiv.org/abs/2104.14294"},"publication":{"venue":"ICCV","year":2021,"kind":"conference","url":"https://doi.org/10.1109/iccv48922.2021.00951"},"citation":"@misc{contrastivelearningdino2021,\n  title = {{Emerging Properties in Self-Supervised Vision Transformers}},\n  author = {Mathilde Caron and Hugo Touvron and Ishan Misra and Hervé Jégou and Julien Mairal and Piotr Bojanowski and Armand Joulin},\n  year = {2021},\n  eprint = {2104.14294},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/2104.14294}\n}\n","citationPath":"/content/papers/citations/contrastive-learning/dino.20875c1e301c.bib"},"thumbnail":{"src":"/content/papers/assets/c2d0ab75afb02750e17183e186f29b0ef6e184eda12673a31c96f199e338188f.jpg","width":664,"height":642},"locale":"zh-hans","path":"/content/papers/zh-hans/contrastive-learning/dino.f93d3e5f9f24.md","headings":[{"id":"定义问题","text":"定义问题","depth":2},{"id":"解决问题","text":"解决问题","depth":2},{"id":"避免模型崩溃","text":"避免模型崩溃","depth":3},{"id":"讨论","text":"讨论","depth":2},{"id":"和其他方法的比较","text":"和其他方法的比较","depth":3},{"id":"不同组件的重要性","text":"不同组件的重要性","depth":3},{"id":"模型崩溃测试","text":"模型崩溃测试","depth":3},{"id":"结论","text":"结论","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"contrastive-learning/dinov2","relation":"next","topic":"视觉表示的自蒸馏"}]},{"id":"object-detection/detr","category":"object-detection","legacyPath":"object-detection/2005-detr","legacySlug":"2005-detr","legacyPaths":[],"title":"DETR","subtitle":"跨领域的奠基者","author":"Z. Yuan","paperDate":"2020-05-26","publishedOn":"2024-06-04","paperTitle":"End-to-End Object Detection with Transformers","paperUrl":"https://www.ecva.net/papers/eccv_2020/papers_ECCV/html/832_ECCV_2020_paper.php","bibliography":{"title":"End-to-End Object Detection with Transformers","authors":["Nicolas Carion","Francisco Massa","Gabriel Synnaeve","Nicolas Usunier","Alexander Kirillov","Sergey Zagoruyko"],"url":"https://www.ecva.net/papers/eccv_2020/papers_ECCV/html/832_ECCV_2020_paper.php","pdfUrl":"https://www.ecva.net/papers/eccv_2020/papers_ECCV/papers/123460205.pdf","codeUrl":"https://github.com/facebookresearch/detr","preprint":{"id":"2005.12872","submittedOn":"2020-05-26","url":"https://arxiv.org/abs/2005.12872"},"publication":{"venue":"ECCV","year":2020,"kind":"conference","url":"https://www.ecva.net/papers/eccv_2020/papers_ECCV/html/832_ECCV_2020_paper.php"},"citation":"@misc{objectdetectiondetr2020,\n  title = {{End-to-End Object Detection with Transformers}},\n  author = {Nicolas Carion and Francisco Massa and Gabriel Synnaeve and Nicolas Usunier and Alexander Kirillov and Sergey Zagoruyko},\n  year = {2020},\n  eprint = {2005.12872},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/2005.12872}\n}\n","citationPath":"/content/papers/citations/object-detection/detr.5258ffe0b9a0.bib"},"thumbnail":{"src":"/content/papers/assets/dd7e8441e6460ff562cf558374789924518fafaed7ecde0e3e35ee778c316330.jpg","width":1024,"height":266},"locale":"zh-hans","path":"/content/papers/zh-hans/object-detection/detr.99d0f3b81385.md","headings":[{"id":"定义问题","text":"定义问题","depth":2},{"id":"解决问题","text":"解决问题","depth":2},{"id":"模型架构","text":"模型架构","depth":3},{"id":"损失设计","text":"损失设计","depth":3},{"id":"数据集","text":"数据集","depth":3},{"id":"技术细节","text":"技术细节","depth":3},{"id":"讨论","text":"讨论","depth":2},{"id":"这次行吗","text":"这次行吗？","depth":3},{"id":"模型组件分析","text":"模型组件分析","depth":3},{"id":"模型行为分析","text":"模型行为分析","depth":3},{"id":"对未见过目标数量的泛化能力","text":"对未见过目标数量的泛化能力","depth":3},{"id":"结论","text":"结论","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"object-detection/deformable-detr","relation":"next","topic":"集合预测与注意力检测器"},{"id":"object-detection/smca-detr","relation":"comparison","topic":"让 Transformer 检测器更快收敛"}]},{"id":"object-detection/deformable-detr","category":"object-detection","legacyPath":"object-detection/2010-deformable-detr","legacySlug":"2010-deformable-detr","legacyPaths":[],"title":"Deformable DETR","subtitle":"可变形的注意力机制","author":"Z. Yuan","paperDate":"2020-10-08","publishedOn":"2024-09-20","paperTitle":"Deformable DETR: Deformable Transformers for End-to-End Object Detection","paperUrl":"https://arxiv.org/abs/2010.04159","bibliography":{"title":"Deformable DETR: Deformable Transformers for End-to-End Object Detection","authors":["Xizhou Zhu","Weijie Su","Lewei Lu","Bin Li","Xiaogang Wang","Jifeng Dai"],"url":"https://arxiv.org/abs/2010.04159","pdfUrl":"https://arxiv.org/pdf/2010.04159","codeUrl":null,"preprint":{"id":"2010.04159","submittedOn":"2020-10-08","url":"https://arxiv.org/abs/2010.04159"},"publication":{"venue":"ICLR","year":2021,"kind":"conference","url":"https://arxiv.org/abs/2010.04159"},"citation":"@misc{objectdetectiondeformabledetr2020,\n  title = {{Deformable DETR: Deformable Transformers for End-to-End Object Detection}},\n  author = {Xizhou Zhu and Weijie Su and Lewei Lu and Bin Li and Xiaogang Wang and Jifeng Dai},\n  year = {2020},\n  eprint = {2010.04159},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/2010.04159}\n}\n","citationPath":"/content/papers/citations/object-detection/deformable-detr.df721a30472e.bib"},"thumbnail":{"src":"/content/papers/assets/36edfc5595a85c73fcdc9a4bbb9e1ca512e1f100676eb7c37203d71c84905c05.jpg","width":1224,"height":752},"locale":"zh-hans","path":"/content/papers/zh-hans/object-detection/deformable-detr.d2987152d10d.md","headings":[{"id":"定义问题","text":"定义问题","depth":2},{"id":"解决问题","text":"解决问题","depth":2},{"id":"可变形注意力","text":"可变形注意力","depth":3},{"id":"多尺度计算","text":"多尺度计算","depth":3},{"id":"模型架构","text":"模型架构","depth":3},{"id":"程式码拆解","text":"程式码拆解","depth":3},{"id":"训练策略","text":"训练策略","depth":3},{"id":"讨论","text":"讨论","depth":2},{"id":"与-detr-的比较","text":"与 DETR 的比较","depth":3},{"id":"消融实验","text":"消融实验","depth":3},{"id":"sota-比较","text":"SOTA 比较","depth":3},{"id":"结论","text":"结论","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"object-detection/detr","relation":"background","topic":"集合预测与注意力检测器"},{"id":"object-detection/h-detr","relation":"next","topic":"集合预测与注意力检测器"},{"id":"object-detection/smca-detr","relation":"comparison","topic":"让 Transformer 检测器更快收敛"}]}],"text":"这篇的 DINO 是 DETR with Improved deNoising anchOr boxes 的缩写，和本站另一篇自监督学习的 [DINO](/blog/papers/contrastive-learning/dino) 是两回事，只是撞了名。\n\n2022 年初，COCO test-dev 排行榜最前面的检测器，像 SwinV2-G 和 Florence，都把大型骨干网络接在 HTC++、DyHead 这类传统的检测头上，推理时还是得用 NMS 删掉重复框。DETR 那一派的论文，大多拿 ResNet-50 比谁收敛得快；作者在引言中写道，还没有人报告过 DETR 类模型换上大骨干网络、喂进大规模数据之后会怎样。\n\nDINO 把这张成绩单补上了。SwinL 骨干网络、先在 Objects365 上预训练，COCO test-dev 拿到 63.3 AP。作者说，这是端到端的 Transformer 检测器第一次在 COCO 排行榜上胜过当时最好的模型。同一套设计换回 ResNet-50，只训练 12 个 epoch，也有 49.4 AP。\n\nDETR 的大架构，这篇没有换掉。骨架来自 Deformable DETR、DAB-DETR 和 DN-DETR，作者在上面加了三项改动，第一项动的是去噪训练。DN-DETR 只教模型把歪掉的框修回来，DINO 另外教它对某些框回答「这里没有东西」。\n\n## 定义问题\n\n先补一点背景。DETR 准备一组固定数量的查询（query），每个查询输出一个类别和一个框。训练时用匈牙利算法，让每个标注物体只匹配给一个查询，其他查询的目标是「没有物体」。这样训练出来，推理时不用 NMS，代价是收敛很慢。\n\n接下来两年，几篇论文各补了一块，DINO 直接站在这三篇上面：\n\n- **Deformable DETR**：注意力只看参考点附近的少数采样点，算得快，也收敛得快。它还提出了两阶段（two-stage）的查询初始化，以及让 decoder 逐层修正框的做法。\n- **DAB-DETR**：把查询拆成位置和内容两部分，位置部分直接写成一个锚框 $(x, y, w, h)$，decoder 每一层都修正它一次。后文说的「锚框」都是这个意思。\n- **DN-DETR**：认为收敛慢是因为匹配不稳，同一个查询这一轮匹配到这个物体，下一轮可能换成别的。它在训练时把加了噪声的标注框当作额外的查询输入 decoder，要模型还原成原来的框。这批查询的答案事先就知道，用不着匈牙利匹配。\n\n作者在这个基础上看到了三个缺口。\n\n第一个在去噪。DN-DETR 的噪声框离标注框都不远，模型学到「附近有物体的锚框，把它修成那个物体就对了」。作者指出，它从没学过让附近没有物体的锚框回答「没有物体」。\n\n这会造成什么麻烦？按照作者在 §3.3 的分析，好几个锚框靠近同一个物体时，模型很难决定该用哪一个。选不好，同一个物体可能被框好几次，也可能挑到一个离得比较远的锚框。DETR 原本靠一对一匹配和查询之间的自注意力来压重复框，作者承认，这种能力有限。\n\n第二个在查询的初始化。DN-DETR 的锚框是学出来的固定值，每张图都从同一组位置出发。Deformable DETR 的两阶段做法，则从 encoder 挑分数最高的位置，连位置带内容一起拿来初始化查询。作者认为内容那一半不可靠，encoder 挑出来的特征还很粗糙，可能同时覆盖两个物体，也可能只覆盖物体的一部分。\n\n第三个在逐层修框。Deformable DETR 让每一层 decoder 修正上一层的框，但层与层之间切断了梯度，每一层只从自己的损失学习。作者猜测，后一层修得更准的框，应该也能回过头帮前一层一把。\n\n三个缺口里，第一个直接碰到了重复框。去噪时只教模型把框修回来，它学得会放手吗？\n\n\n> [!TIP]\n> \n> DETR、Deformable DETR 与 DN-DETR 的细节，可以参考我们的笔记：\n> \n> - **[[20.05] DETR：跨领域的奠基者](/blog/papers/object-detection/detr)**\n> - **[[20.10] Deformable DETR：可变形的注意力机制](/blog/papers/object-detection/deformable-detr)**\n> - **[[22.03] DN-DETR：今天配狗，明天配猫](/blog/papers/object-detection/dn-detr)**\n\n\n## 解决问题\n\n### 整体流程\n\nDINO 的组成和一般 DETR 类模型一样，一个骨干网络、六层 Transformer encoder、六层 decoder，再加上分类和框的预测头。原论文的架构图标出了新改动的位置：\n\n[![DINO 架构图：左边的多尺度特征与位置编码展平后送进 encoder；encoder 上方的 Query Selection 挑出位置，沿 Init Anchors 送到 decoder 当初始锚框，旁边是可学习的内容查询；decoder 右侧以虚线隔出 CDN，由加了噪声的标注框产生正、负样本查询](/content/papers/assets/6c328e7125d4762c3a4346a1c537cb4e917d47a640869bbf212de53f74ba64fc.png)](/content/papers/assets/6c328e7125d4762c3a4346a1c537cb4e917d47a640869bbf212de53f74ba64fc.png)\n\n*Zhang 等人，原论文 Figure 2，取自 [**v4 PDF 第 6 页**](https://arxiv.org/pdf/2203.03605v4#page=6)。DINO 的整体架构。*\n\n从左边看起。多尺度特征展平、加上位置编码后送进 encoder。encoder 上方的 Query Selection 从输出里挑位置，沿着 Init Anchors 那条线送到 decoder 底部当初始锚框；旁边的 Learnable Content Queries 是可学习的内容向量，两者合起来就是混合查询选择。decoder 右边用虚线隔开的 CDN，是训练时多出来的去噪查询，由加了噪声的标注框（GT+Noise）产生，分成正样本（Pos）和负样本（Neg）。Look forward twice 发生在 decoder 层与层之间，图上没有画出来。\n\n按数据流的顺序，一张图像会经过这几步：\n\n1. 骨干网络抽取多尺度特征。4-scale 版本取骨干网络第 2 到第 4 阶段的输出，再把第 4 阶段下采样一次，凑成四层；5-scale 版本再多加第 1 阶段，也就是分辨率最高的那一层。\n2. encoder 用可变形注意力整理这些特征。\n3. **混合查询选择**：从 encoder 的输出挑出分数最高的 900 个位置，拿它们预测的框当 decoder 的初始锚框。\n4. decoder 逐层修正这 900 个锚框，修框时用 **look forward twice** 传递梯度。训练时，decoder 还会多接收一批**对比式去噪**（Contrastive DeNoising，CDN）的查询。\n5. 预测头输出类别和框。900 个查询和标注做匈牙利匹配；去噪查询的答案事先已知，直接算损失。\n\n推理时，去噪那批查询整个拿掉，只剩 900 个查询。[官方代码](https://github.com/IDEA-Research/DINO)把 900 个查询在每个类别上的分数展平，取最高的 300 个作为输出，所以同一个查询可能以两个不同的类别各出现一次。后面不接 NMS；配置文件里留着一个 NMS 开关（`nms_iou_threshold`），默认是 -1，也就是关着。\n\n### 对比式去噪\n\nDN-DETR 只有一个噪声尺度 $\\lambda$，噪声不超过 $\\lambda$ 的框，都要还原成标注框。DINO 改用两个尺度 $\\lambda_1 < \\lambda_2$，把噪声框分成两种：\n\n- **正样本**：噪声小于 $\\lambda_1$，要还原成标注框。损失是框的 L1 与 GIoU，加上分类的 focal loss。\n- **负样本**：噪声介于 $\\lambda_1$ 和 $\\lambda_2$ 之间，要回答「没有物体」。只算分类的 focal loss，没有框的损失。\n\n每个标注框各产生一个正样本、一个负样本。一张图有 $n$ 个标注框，一组 CDN 查询就有 $2n$ 个；和 DN-DETR 一样，训练时会放好几组。原论文 Figure 3 画的是两组：\n\n[![CDN 示意图：左边两个 CDN group 各有三个黄色正样本与三个褐色负样本查询，一起通过 decoder，正样本对应 reconstruction loss，负样本对应 no object；右边是同心方框，内框标 positive 与 λ1，内外框之间标 negative 与 λ2](/content/papers/assets/2016ccac10bf8f058a0d252c75ab4adf790e4c28f042f38eeddd61a2c18c94e5.png)](/content/papers/assets/2016ccac10bf8f058a0d252c75ab4adf790e4c28f042f38eeddd61a2c18c94e5.png)\n\n*Zhang 等人，原论文 Figure 3，取自 [**v4 PDF 第 8 页**](https://arxiv.org/pdf/2203.03605v4#page=8)。CDN 组的结构与正负样本的示意。*\n\n先看左边。这张图像有三个标注框，所以每组有三个黄色的正样本、三个褐色的负样本，两组一起送进 decoder。正样本的输出算重建损失（reconstruction loss），负样本的目标是 no object。右边的同心方框是示意，中心点代表标注框，噪声落在内框里（小于 $\\lambda_1$）的是正样本，落在内外框之间（$\\lambda_1$ 到 $\\lambda_2$）的是负样本。锚框其实是四维的 $(x, y, w, h)$，作者为了好画，才把它画成平面上的点。\n\n论文设 $\\lambda_1 = 1.0$、$\\lambda_2 = 2.0$。对照官方代码，噪声加在框的四条边上，每条边各自随机向内或向外移。正样本移动的距离小于半个框宽（上下两条边则是半个框高），负样本移动半个到一整个框宽。官方训练脚本的 `dn_box_noise_scale` 设成 1.0，移动距离就是这个大小。\n\n组数是动态决定的。DINO 固定使用大约 100 对、也就是 200 个去噪查询，再根据 batch 里标注最多的那张图调整组数；官方代码把 200 除以那张图物体数的两倍，取整数。例如 batch 里最挤的一张有 7 个物体，就是 14 组、每组 14 个查询，一共 196 个。加上原来的 900 个，训练时 decoder 每张图要处理 1,096 个查询。\n\n这些查询之间用注意力掩码隔开。原来那 900 个查询看不到任何去噪查询，不然标注答案会通过自注意力泄漏过去；不同组之间也互相看不到。同一组里的正负样本则看得到彼此。\n\n那么，负样本到底离标注框多远？我们按照官方代码的加噪方式，对一个标注框各抽十万个正、负样本，计算它们和标注框的 IoU：\n\n```python\nimport numpy as np\n\nrng = np.random.default_rng(0)\n\ndef iou(boxes, gt):\n    # boxes: (N, 4)；gt: (4,)；格式都是 (x1, y1, x2, y2)\n    x1 = np.maximum(boxes[:, 0], gt[0])\n    y1 = np.maximum(boxes[:, 1], gt[1])\n    x2 = np.minimum(boxes[:, 2], gt[2])\n    y2 = np.minimum(boxes[:, 3], gt[3])\n    inter = np.clip(x2 - x1, 0, None) * np.clip(y2 - y1, 0, None)\n    area = np.clip(boxes[:, 2] - boxes[:, 0], 0, None) * np.clip(boxes[:, 3] - boxes[:, 1], 0, None)\n    gt_area = (gt[2] - gt[0]) * (gt[3] - gt[1])\n    return inter / (area + gt_area - inter)\n\ndef cdn_noise(gt, n, negative):\n    # 仿照官方 prepare_for_cdn：四条边各自向内或向外移\n    w, h = gt[2] - gt[0], gt[3] - gt[1]\n    half = np.array([w / 2, h / 2, w / 2, h / 2])\n    u = rng.random((n, 4)) + (1.0 if negative else 0.0)  # 正样本 [0, 1)，负样本 [1, 2)\n    sign = rng.choice([-1.0, 1.0], size=(n, 4))\n    return np.clip(gt + sign * u * half, 0.0, 1.0)\n\ngt = np.array([0.40, 0.35, 0.60, 0.65])  # 宽 0.2、高 0.3 的标注框，归一化坐标\nfor name, negative in ((\"正样本\", False), (\"负样本\", True)):\n    boxes = cdn_noise(gt, 100_000, negative)\n    v = iou(boxes, gt)\n    p10, p50, p90 = np.percentile(v, [10, 50, 90])\n    crossed = ((boxes[:, 2] <= boxes[:, 0]) | (boxes[:, 3] <= boxes[:, 1])).mean()\n    print(f\"{name}：IoU 中位数 {p50:.2f}，10%–90% 落在 {p10:.2f}–{p90:.2f}，\"\n          f\"最大 {v.max():.2f}，边交错 {crossed:.0%}\")\n```\n\n```text\n正样本：IoU 中位数 0.38，10%–90% 落在 0.21–0.56，最大 0.94，边交错 0%\n负样本：IoU 中位数 0.01，10%–90% 落在 0.00–0.12，最大 0.24，边交错 44%\n```\n\n正样本本身就歪得不少，IoU 中位数只有 0.38，模型要把它们修回标注框。负样本离得更远，中位数接近 0，最大只有 0.24。还有四成多的负样本，左右或上下两条边交错了；在官方代码里，这种框会变成宽或高几乎为零的锚框，模拟里的 IoU 记为 0。\n\n0.24 已经很接近一个可以手算的上限。物体没有贴着图像边缘时，负样本的每条边至少要移动半个框宽或框高。最贴近标注框的情况，是四条边都恰好向外移半个框，变成两倍宽、两倍高，把标注框包在正中间，IoU 是 $\\frac{wh}{2w \\cdot 2h} = \\frac{1}{4}$。\n\n所以这些负样本长得一点都不像重复框。拿 NMS 常用的 0.5 或 0.7 阈值来看，它们离「重复」还远得很。\n\n那它们在教什么？回到 decoder 怎么用锚框。锚框是起点，decoder 从锚框附近取特征，再一层层修正。只有正样本的 DN-DETR，让模型养成了把附近锚框修成那个物体的习惯。好几个锚框都在同一个物体附近时，照这个习惯全部修过去，输出的就是好几个几乎一样的框。重复出现在输出端，出发的锚框彼此可以相差很多。\n\n负样本补上另一半。它们一样待在物体附近，每条边最多偏一个框宽，decoder 取到的也是同一个物体的特征，答案却是「没有物体」。同一组里还有离得比较近的正样本，要修回标注框。模型得从这两种锚框的差别，学会起点偏多远就该放手。\n\n官方代码库有一则 issue 问过反方向的担心。假设一个锚框和物体的 IoU 是 0.7、另一个是 0.5，CDN 把 0.5 那个教成负样本；那如果下一张图只剩 IoU 0.5 的锚框，模型会不会连它也放弃？[IDEA-Research/DINO #176，2023-03-23](https://github.com/IDEA-Research/DINO/issues/176) 按照上面的模拟，官方设置下 IoU 0.5 的锚框落在正样本的范围，负样本最多到 0.25 左右。论文作者之一 Hao Zhang 回复说，CDN 的每一组总是同时有正样本和负样本，总会有锚框匹配到物体；他认为提问里的情况不会出现在匹配那一侧，要看阈值怎么设。至于 CDN 会不会让这种情况变差，他们还没有研究过。\n\nCDN 有没有真的让模型挑到比较好的锚框？作者定义了一个指标 ATD(k)（Average Top-K Distance）。对验证集里的每个标注框，找出最后匹配到它的那个查询，看它出发时的锚框和标注框差多远（四个坐标的 L1 距离），再把差最多的 $k$ 个取平均。匹配到远处锚框的情况越少，这个数字越小。\n\n在 ResNet-50、多尺度特征、12 个 epoch 的设置下，用全部物体算 ATD(100)，DN 和 CDN 差不多；只看小目标，CDN 的距离比较短，小目标的 AP 也高了 1.3。重复框的直接证据只有一个例子，在原论文 Figure 8：\n\n[![两张相同的儿童合照并排，只画出人的框。左图白色箭头指着一个小男孩，他身上叠了三个几乎重合的红框；右图同一位置只有一个框](/content/papers/assets/4aed72dc0127639f2eb01d2a2d681c46fbb1112ac82ea7dc1b2126a3559de642.png)](/content/papers/assets/4aed72dc0127639f2eb01d2a2d681c46fbb1112ac82ea7dc1b2126a3559de642.png)\n\n*Zhang 等人，原论文 Figure 8，取自 [**v4 PDF 第 15 页**](https://arxiv.org/pdf/2203.03605v4#page=15)。左图是用 DN 查询训练的模型，右图是 DINO；两张都只画「人」这个类别的框。*\n\n看左图白色箭头指的那个小男孩，他身上叠了三个几乎重合的框；右图同一个位置只剩一个。论文没有统计重复框的比例。\n\n会不会只是查询变多了？附录的 Table 7 比较了不同数量的去噪查询：\n\n| 去噪查询 | AP |\n| --- | ---: |\n| 不用去噪 | 45.1 |\n| 10 个 DN | 46.0 |\n| 50 个 DN | 46.7 |\n| 100 个 DN | 47.4 |\n| 200 个 DN | 47.4 |\n| 1,000 个 DN | 47.6 |\n| 100 对 CDN（200 个） | 47.9 |\n\n*表：整理自原论文 Table 7，ResNet-50、COCO val2017。*\n\nDN 查询从 0 加到 100 个，AP 从 45.1 升到 47.4，再往上加几乎不动，加到 1,000 个也只有 47.6。同样 200 个查询，把一半换成负样本，多了 0.5 AP。\n\n### 混合查询选择\n\ndecoder 的 900 个查询从哪里出发，有三种做法：\n\n| 做法 | 锚框（位置） | 内容 |\n| --- | --- | --- |\n| 静态（DETR、DN-DETR 等） | 学出来的固定值 | 全为 0，或学出来的固定值 |\n| 纯查询选择（Deformable DETR 两阶段） | encoder 分数前 K 名位置预测的框 | 同一批 encoder 特征经线性变换 |\n| 混合查询选择（DINO） | encoder 分数前 K 名位置预测的框 | 学出来的固定值 |\n\n*表：整理自原论文 §3.4 与 Figure 5。*\n\nDINO 只拿 encoder 给的位置，内容维持为可学习的向量。在官方代码里，K 就是 900；分数取每个位置在各类别上的最高分，挑出的框会先切断梯度，再当作锚框。\n\n作者认为 encoder 挑出的特征还没经过精炼，可能混了两个物体，或只有半个物体，拿来当内容反而会误导；位置则是有用的先验。decoder 依照较好的位置去 encoder 取特征，内容再一层层长出来。\n\n### Look forward twice\n\nDeformable DETR 的逐层修框是这样接的。第 $i$ 层拿到上一层的框 $b_{i-1}$，预测一个偏移 $\\Delta b_i$，两者合起来得到这一层的框，再切断梯度交给下一层。所以第 $i$ 层的参数，只会被第 $i$ 层自己的损失更新。作者把它叫做 look forward once。\n\nDINO 改成这样：\n\n$$\n\\begin{aligned}\n\\Delta b_i &= \\mathrm{Layer}_i(b_{i-1}), & b_i' &= \\mathrm{Update}(b_{i-1}, \\Delta b_i), \\\\\nb_i &= \\mathrm{Detach}(b_i'), & b_i^{(\\mathrm{pred})} &= \\mathrm{Update}(b_{i-1}', \\Delta b_i)\n\\end{aligned}\n$$\n\n$b_i'$ 是还带着梯度的框，$b_i$ 是切断梯度后的版本，下一层的输入仍然是 $b_i$。改变的是拿去算损失的预测框 $b_i^{(\\mathrm{pred})}$，它接在上一层还带梯度的 $b_{i-1}'$ 上。这样一来，同一个偏移 $\\Delta b_i$ 用了两次，一次组成这一层的 $b_i'$，一次通过 $b_i'$ 进到下一层的预测框，所以叫 look forward twice。\n\n$\\mathrm{Update}$ 和 Deformable DETR 一样，把归一化到 0 到 1 的坐标先取 inverse sigmoid，加上偏移，再用 sigmoid 转回来。\n\n我们拿一个坐标、两层 decoder，看第 2 层的损失会不会传到第 1 层的偏移：\n\n```python\nimport torch\n\ndef update(box, delta):\n    # 论文脚注 3：在 inverse sigmoid 空间相加，再转回 0～1\n    return torch.sigmoid(torch.logit(box) + delta)\n\ntarget = torch.tensor(0.60)  # 标注框的某个坐标\nb0 = torch.tensor(0.40)      # 第 1 层拿到的锚框坐标\n\nfor mode in (\"look forward once\", \"look forward twice\"):\n    d1 = torch.tensor(0.30, requires_grad=True)  # 第 1 层预测的偏移 Δb1\n    d2 = torch.tensor(0.20, requires_grad=True)  # 第 2 层预测的偏移 Δb2\n\n    b1_prime = update(b0, d1)   # b1'：保留梯度\n    b1 = b1_prime.detach()      # b1：切断梯度，交给第 2 层当锚框\n\n    if mode == \"look forward once\":\n        pred2 = update(b1, d2)\n    else:\n        pred2 = update(b1_prime, d2)\n\n    loss2 = (pred2 - target).abs()  # 只算第 2 层的 L1 损失\n    loss2.backward()\n    g1 = 0.0 if d1.grad is None else d1.grad.item()\n    print(f\"{mode}：第 2 层预测 {pred2.item():.4f}，\"\n          f\"对 Δb1 的梯度 {g1:+.4f}，对 Δb2 的梯度 {d2.grad.item():+.4f}\")\n```\n\n```text\nlook forward once：第 2 层预测 0.5236，对 Δb1 的梯度 +0.0000，对 Δb2 的梯度 -0.2494\nlook forward twice：第 2 层预测 0.5236，对 Δb1 的梯度 -0.2494，对 Δb2 的梯度 -0.2494\n```\n\n两种接法算出来的预测框一模一样，都是 0.5236，差别只在梯度。look forward once 时，第 2 层的损失碰不到 $\\Delta b_1$；look forward twice 时，它也传回了 $\\Delta b_1$。这里把每层的偏移简化成一个可学习的数字；实际模型里，$\\Delta b_i$ 是第 $i$ 层的输出，梯度会继续流进那一层的参数。梯度也只往回走一层，因为 $b_{i-1}$ 进第 $i$ 层之前已经切断了。\n\n推理时的计算完全没变，这个改动只影响训练。\n\n## 讨论\n\n### 12 个 epoch\n\n先看 ResNet-50、COCO val2017、训练 12 个 epoch 的比较：\n\n| 模型 | AP | AP_S | GFLOPs | 参数 | FPS |\n| --- | ---: | ---: | ---: | ---: | ---: |\n| Faster-RCNN（5-scale） | 37.9 | 22.4 | 207 | 40M | 21 |\n| Deformable DETR（4-scale） | 41.1 | — | 196 | 40M | 24 |\n| DN-Deformable-DETR（4-scale） | 43.4 | 24.8 | 265 | 48M | 23 |\n| DINO-4scale | 49.0 | 32.0 | 279 | 47M | 24 |\n| DINO-5scale | 49.4 | 32.3 | 860 | 47M | 10 |\n\n*表：整理自原论文 Table 1。FPS 都在同一张 A100 上测量，Faster-RCNN 的 FPS 用 mmdetection 测量。*\n\n和 DN-Deformable-DETR 比，DINO-4scale 高了 5.6 AP，计算量和参数量差不多；小目标的 AP_S 多了 7.2。两者的查询数也相当，DINO 用 900 个查询，DN-Deformable-DETR 用 300 个查询搭配 3 个 pattern，作者说效果相当于 900 个；Deformable DETR 用 300 个。\n\n4-scale 和 5-scale 的差别，在于有没有用骨干网络第 1 阶段的特征。这一层分辨率最高，GFLOPs 从 279 变成 860，大约三倍，FPS 从 24 掉到 10，换来 0.4 AP。摘要里那个 49.4，是 5-scale 的数字。\n\n### 练久一点\n\n训练到 24 和 36 个 epoch，4-scale 是 50.4 和 50.9，5-scale 是 51.3 和 51.2（Table 2）。对照组 DN-Deformable-DETR 训练了 50 个 epoch，是 48.6。摘要说 24 个 epoch 时比 DN-DETR 高 2.7 AP，比的就是 DINO 的 24 个 epoch 和 DN-DETR 的 50 个 epoch。5-scale 从 24 练到 36 个 epoch，分数已经不再往上走。\n\n训练成本在附录 B。同样用 8 张 A100，DINO 每个 epoch 约 55 分钟、每张卡 16GB，12 个 epoch 大约 11 小时。Deformable DETR（不含两阶段与逐层修框的基础版）每个 epoch 时间一样，训练 50 个 epoch 大约 46 小时，45.4 AP；DETR 每个 epoch 只要 16 分钟，但要 300 个 epoch，大约 80 小时，41.2 AP。这张表里 DINO 的成绩是 47.9，和下面的消融表是同一个时期的实现。\n\n### 排行榜上的那一格\n\n登上排行榜的那个 DINO，条件和上面差很多：\n\n- 骨干网络换成 SwinL，在 ImageNet-22K 上预训练。\n- 检测器先在 Objects365（约 170 万张标注图像）上预训练 26 个 epoch，用了 64 张 A100。\n- 再到 COCO 上微调 18 个 epoch，用 16 张 A100，图像放大成 1.5 倍（最长边 2000），作者说这一步大约多 0.5 AP。\n- 去噪查询加到 1,000 个。\n\n结果和几个大模型摆在一起：\n\n| 模型 | 参数 | 骨干网络预训练数据 | 检测预训练数据 | 端到端 | test-dev AP（无／有 TTA） |\n| --- | ---: | --- | --- | :---: | ---: |\n| Florence-CoSwin-H | ≥ 637M | FLD-900M | FLD-9M | | —／62.4 |\n| SwinV2-G | 3.0B | IN-22K-ext-70M | O365 | | —／63.1 |\n| DINO-SwinL | 218M | IN-22K-14M | O365 | ✓ | 63.2／63.3 |\n\n*表：整理自原论文 Table 3。IN 是 ImageNet，O365 是 Objects365；SwinV2-G 另外用了实例分割标注训练。*\n\n不加测试时增强（TTA），DINO 的 63.2 已经高过 SwinV2-G 加了 TTA 的 63.1，参数量是 218M 对 3.0B。val2017 上是 63.1，加 TTA 63.2。作者指出，Table 3 里先前的 SOTA 模型，检测头用的都是 HTC++ 或 DyHead，DINO 是第一个坐上这个位置的端到端 Transformer 检测器。官方代码库在 2022 年 3 月 8 日的公告也写着，以 63.3 AP 拿下 MS-COCO 排行榜第一。\n\n63.3 这个数字用了 TTA，也就是多尺度测试加水平翻转。传统检测器集成几次推理的结果时，会把所有框收在一起，再用 NMS 或 box voting 删掉重复的。作者说这套做法放在 DINO 上反而会掉点，因为 DETR 类模型本来就不太输出重复框，NMS 容易误删正确的框。他们改用一对一的集成方式，以其中一种增强的预测为主，每个框到其他增强的结果里，找 IoU 最高、而且超过阈值的那一个，再加权平均。\n\n同一篇论文，附录说 DETR 类模型不太输出重复框，§3.3 又承认匹配损失和自注意力压重复框的能力有限。两句话放在一起读，比较接近「大多数时候不重复，偶尔会有漏网之鱼」，那个被框了三次的小男孩，就是漏网的那种。\n\n### 消融：49.4 是怎么叠出来的\n\n最后看三个新设计各自贡献多少：\n\n| 设置 | 查询选择 | CDN | LFT | AP | AP_S |\n| --- | :---: | :---: | :---: | ---: | ---: |\n| 1. DN-DETR | 无 | | | 43.4 | 24.8 |\n| 2. 整理过实现的 DN-DETR | 无 | | | 44.9 | 26.9 |\n| 3. 强基线（2 加上纯查询选择） | 纯 | | | 46.5 | 29.6 |\n| 4. 3 改用混合查询选择 | 混合 | | | 47.0 | 31.1 |\n| 5. 4 加上 look forward twice | 混合 | | ✓ | 47.4 | 29.9 |\n| 6. DINO（5 加上 CDN） | 混合 | ✓ | ✓ | 47.9 | 31.2 |\n\n*表：整理自原论文 Table 4，ResNet-50、COCO val2017。*\n\n这张表的数字和论文初版相同，没有包含后来让 Table 1 升到 49.0 的工程调整，所以最后一行是 47.9。\n\n从 DN-DETR 的 43.4 到 DINO 的 47.9，一共多了 4.5 AP。最大的两步，是作者把 DN-DETR 的实现整理了一遍（+1.5），以及借用 Deformable DETR 的纯查询选择（+1.6）。三个新设计依次加了 0.5、0.4、0.5，合计 1.4。\n\n小目标那一列有点起伏。加上 look forward twice 之后，AP_S 从 31.1 掉到 29.9，加上 CDN 才回到 31.2；论文没有解释这次下降。\n\n所以摘要那句「12 个 epoch、49.4 AP」，是很多东西叠起来的成绩。负样本本身，在这张表上值 0.5 AP。\n\n混合查询选择还有一个附带效果，在附录 C。encoder 维持 6 层、decoder 从 6 层砍到 2 层，DINO 掉了 3.0 AP（47.4 到 44.4）；作者引用的 Dynamic DETR 砍到 2 层时掉了 13.8 AP。作者把这个差距归功于混合查询选择，锚框从 encoder 一开始就给得不错，比较不依赖 decoder 一层层修。这组实验用 12 个 epoch，去噪查询是 100 个、没有负样本。\n\n## 结论\n\nDINO 在 DN-DETR 的基础上加了三件事：\n\n1. **对比式去噪**：同一个标注框旁边，放一个偏得少、一个偏得多的锚框，前者修回标注框，后者回答没有物体。官方设置下，负样本和标注框的 IoU 最多约 0.25，它们教的是起点偏多远就该放手。\n2. **混合查询选择**：锚框从 encoder 挑，内容维持为可学习的向量。\n3. **Look forward twice**：下一层的损失，往回多传一层。\n\nResNet-50、12 个 epoch，4-scale 与 5-scale 分别做到 49.0 和 49.4 AP；换上 SwinL 和 Objects365 预训练，test-dev 63.2，加 TTA 63.3，登上当时的 COCO 排行榜第一。消融表上，三个新设计各约半个 AP，大部分进步来自实现整理和查询选择。负样本压重复框的直接证据只有一张示例图；ATD 曲线则显示小目标匹配到了比较近的锚框。\n\nDETR 不接 NMS，靠的是训练时教模型分辨哪些框该放手；作者自己也说，这种能力有限。部署时不妨像官方代码那样，留着 NMS 这个开关，需要时再打开。\n\nDINO 的速度则是另一笔账。一年后，RT-DETR 在 T4 GPU、TensorRT FP16、800×1333 的输入下测 DINO-Deformable-DETR-R50，只有 5 FPS。RT-DETR 的 decoder 训练几乎照搬 DINO 的设置，连去噪查询都带着；它动刀的是 encoder，因为多尺度特征让 encoder 成了计算瓶颈。这段故事可以接着读 [RT-DETR](/blog/papers/object-detection/rt-detr)。\n","imageSizes":{"/content/papers/assets/6c328e7125d4762c3a4346a1c537cb4e917d47a640869bbf212de53f74ba64fc.png":{"width":942,"height":319},"/content/papers/assets/2016ccac10bf8f058a0d252c75ab4adf790e4c28f042f38eeddd61a2c18c94e5.png":{"width":766,"height":353},"/content/papers/assets/4aed72dc0127639f2eb01d2a2d681c46fbb1112ac82ea7dc1b2126a3559de642.png":{"width":938,"height":313}}}
