{"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-hant","path":"/content/papers/zh-hant/object-detection/dino-detr.667f5bcbb753.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-hant","path":"/content/papers/zh-hant/contrastive-learning/dino.8c09b17f0fdf.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-hant","path":"/content/papers/zh-hant/object-detection/detr.5ef9bf1965a5.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-hant","path":"/content/papers/zh-hant/object-detection/deformable-detr.4eb78eef1d58.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}}}
