如果你想從零開始寫整個物體偵測訓練流程,這樣你就能理解每一步並能夠自訂它,該怎麼做呢?這正是我想要達成的目標。我檢查了幾個知名的物體偵測流程,並設計了一個最適合我需求和任務的流程。多虧了Ultralytics、YOLOx、DAMO-YOLO、RT-DETR和D-FINE這些資源,我利用它們深入了解各種設計細節。最後,我在我的自訂流程中實現了最先進的即時物體偵測模型D-FINE。
計畫
資料集、增強和轉換:
- 馬賽克(使用仿射變換)
- 混合(Mixup)和切割(Cutout)
- 其他帶有邊界框的增強
- 信箱框(Letterbox)與簡單調整大小
訓練:
- 優化器
- 調度器
- EMA
- 批次累積
- AMP
- 梯度裁剪
- 日誌記錄
指標:
- 來自TorchMetrics / cocotools的mAP
- 如何計算精確度、召回率、IoU?
選擇適合你情況的解決方案
- 實驗
- 注意數據預處理
- 從哪裡開始
資料集
資料集處理通常是你開始工作的第一件事。在物體偵測中,你需要加載圖像和標註。標註通常以COCO格式存儲為json文件,或以YOLO格式存儲,每張圖像都有一個txt文件。讓我們來看看YOLO格式:每行的結構為:class_id, x_center, y_center, width, height,其中邊界框的值在0到1之間進行歸一化。
當你擁有圖像和txt文件後,你可以編寫你的資料集類別,這裡沒有什麼難的。加載所有內容,進行轉換(包括增強),並在訓練期間返回。我更喜歡通過為每個拆分創建CSV文件來分割數據,然後在Dataloader類中讀取它,而不是將文件物理移動到train/val/test文件夾。這是一個幫助我使用案例的自訂範例。
增強
首先,在為物體偵測增強圖像時,對邊界框應用相同的變換是至關重要的。為了方便做到這一點,我使用了Albumentations庫。例如:
def _init_augs(self, cfg) -> None:
if self.keep_ratio:
resize = [
A.LongestMaxSize(max_size=max(self.target_h, self.target_w)),
A.PadIfNeeded(
min_height=self.target_h,
min_width=self.target_w,
border_mode=cv2.BORDER_CONSTANT,
fill=(114, 114, 114),
),
]
else:
resize = [A.Resize(self.target_h, self.target_w)]
norm = [
A.Normalize(mean=self.norm[0], std=self.norm[1]),
ToTensorV2(),
]
if self.mode == "train":
augs = [
A.RandomBrightnessContrast(p=cfg.train.augs.brightness),
A.RandomGamma(p=cfg.train.augs.gamma),
A.Blur(p=cfg.train.augs.blur),
A.GaussNoise(p=cfg.train.augs.noise, std_range=(0.1, 0.2)),
A.ToGray(p=cfg.train.augs.to_gray),
A.Affine(
rotate=[90, 90],
p=cfg.train.augs.rotate_90,
fit_output=True,
),
A.HorizontalFlip(p=cfg.train.augs.left_right_flip),
A.VerticalFlip(p=cfg.train.augs.up_down_flip),
]
self.transform = A.Compose(
augs + resize + norm,
bbox_params=A.BboxParams(format="pascal_voc", label_fields=["class_labels"]),
)
elif self.mode in ["val", "test", "bench"]:
self.mosaic_prob = 0
self.transform = A.Compose(
resize + norm,
bbox_params=A.BboxParams(format="pascal_voc", label_fields=["class_labels"]),
)
其次,有很多有趣且不簡單的增強:
- 馬賽克。這個想法很簡單,我們可以取幾張圖像(例如4張),然後將它們堆疊在一起形成一個網格(2×2)。然後進行一些仿射變換並將其輸入模型。
- 混合(MixUp)。最初用於圖像分類(這真的很驚訝)。想法是:取兩張圖像,將它們重疊在一起,並設置一些透明度。在分類模型中,這通常意味著如果一張圖像的透明度為20%,而第二張為80%,那麼模型應該預測80%為類別1,20%為類別2。在物體偵測中,我們只是將更多的物體放入一張圖像中。
- 切割(Cutout)。切割涉及移除圖像的一部分(用黑色像素替換),以幫助模型學習更穩健的特徵。
我經常看到馬賽克在前~90%的訓練周期中以1.0的概率應用。然後通常會關閉,並使用較輕的增強。混合的情況也是如此,但我看到它的使用頻率要少得多(對於最受歡迎的檢測框架Ultralytics,它預設是關閉的,對於另一個框架,我看到P=0.15)。切割的使用頻率似乎也較低。
你可以在這兩篇文章中閱讀更多關於這些增強的內容:1, 2。
僅僅打開馬賽克的結果就相當不錯(沒有馬賽克的較暗模型得到的mAP是0.89,而有馬賽克的則是0.92,測試於真實數據集上)。
信箱框還是簡單調整大小?
在訓練期間,你通常會將輸入圖像調整為正方形。模型通常使用640×640的大小,並在COCO數據集上進行基準測試。主要有兩種方法可以達到這一點:
- 簡單調整到目標大小。
- 信箱框:將最長邊調整到目標大小(例如640),保持長寬比,並填充較短的一邊以達到目標尺寸。
這兩種方法各有優缺點。讓我們先討論它們,然後我會分享我進行的多次實驗結果,來比較這些方法。
簡單調整大小:
- 計算用於整個圖像,沒有無用的填充。
- “動態”長寬比可能作為一種正則化形式。
- 推理預處理與訓練預處理完全匹配(不包括增強)。
- 破壞實際幾何。調整大小的失真可能會影響圖像中的空間關係。儘管這可能是人類的偏見,認為固定的長寬比很重要。
信箱框:
- 保持實際的長寬比。
- 在推理期間,你可以切掉填充,並在不損失準確度的情況下運行非正方形圖像(某些模型可能會降級)。
- 可以在更大的圖像大小上訓練,然後在推理時切掉填充,以獲得與簡單調整大小相同的推理延遲。例如640×640與832×480。第二種方法將保持長寬比,物體的大小會大致相同。
部分計算被浪費在灰色填充上。
物體變得更小。
如何測試並決定使用哪一種呢?
從零開始訓練,使用以下參數:
- 簡單調整大小,640×640
- 保持長寬比,最大邊640,並添加填充(作為基準)
- 保持長寬比,更大的圖像大小(例如最大邊832),並添加填充。然後推理3個模型。當保持長寬比時,在推理期間切掉填充。比較延遲和指標。
以上是同一圖像的示例,經過切掉填充處理(640 × 384):
最終結果
了解所有細節後,讓我們看看在VisDrone數據集上,兩個模型的最佳設置的最終比較:
模型 | F1-score | 延遲(毫秒) |
---|---|---|
YOLO11m TRT動態 | 0.600 | 13.3 |
YOLO11m OV | 0.600 | 122.4 |
D-FINEs TRT | 0.629 | 12.3 |
D-FINEs OV | 0.629 | 57.4 |
如上所示,我能夠使用較小的D-FINE模型,並在速度和準確度上超越YOLO11。打敗Ultralytics,這個最廣泛使用的即時物體偵測模型,無論是在速度還是準確度上,都是一項相當了不起的成就,不是嗎?在其他幾個真實世界數據集上也觀察到了相同的模式。
我還嘗試了YOLOv12,這是在我撰寫本文時推出的。它的表現與YOLO11相似,甚至達到了稍低的指標(mAP 0.456對0.452)。看起來YOLO模型在過去幾年中遇到了瓶頸。D-FINE是物體偵測模型的一次重大更新。
最後,讓我們直觀地看看YOLO11m和D-FINEs之間的差異。YOLO11m,conf 0.25,nms iou 0.5,延遲13.3ms:
D-FINEs,conf 0.5,無nms,延遲12.3ms:

D-FINE模型的精確度和召回率都更高。而且它的速度也更快。這裡還有D-FINE的“m”版本:

難道不奇怪嗎?連左邊那輛車都被偵測到了!
注意數據預處理
這部分可能會稍微超出文章的範疇,但我想至少快速提一下,因為有些部分可以自動化並用於流程中。作為計算機視覺工程師,我確實看到,如果工程師不花時間處理數據,他們就無法獲得好的模型。你可以擁有所有最先進的模型和正確的做法,但垃圾進——垃圾出。因此,我總是非常重視如何處理任務,以及如何收集、過濾、驗證和標註數據。不要認為標註團隊會做好所有事情。親自檢查數據集的一部分,以確保標註良好且收集的圖像具有代表性。
幾個快速的想法:
- 從驗證/測試集移除重複和近似重複的樣本。模型不應該在同一樣本上進行兩次驗證,並且你肯定不希望出現數據洩漏,因為在訓練和驗證集中獲得兩張相同的圖像。
- 檢查你的物體可以有多小。所有肉眼看不見的物體都不應該被標註。還要記住,增強會使物體看起來更小(例如,馬賽克或縮小)。根據這些增強進行配置,以免在圖像上出現無法使用的小物體。
- 當你已經有一個針對特定任務的模型並需要更多數據時,嘗試使用你的模型對新圖像進行預標註。檢查模型失敗的案例,並收集更多類似的案例。
從哪裡開始
我在這個流程上花了很多時間,並準備與想要嘗試的人分享。它使用最先進的D-FINE模型,並添加了一些原始資源中缺少的功能(馬賽克增強、批次累積、調度器、更多指標、預處理圖像和評估預測的可視化、導出和推理代碼、更好的日誌記錄、統一和簡化的配置文件)。
這是我的資源庫的鏈接。這是原始的D-FINE資源庫,我也在那裡貢獻。如果你需要任何幫助,請在LinkedIn上聯繫我。謝謝你的時間!
引用和致謝
DroneVis
title=Detection and tracking meet drones challenge,
author=Zhu, Pengfei and Wen, Longyin and Du, Dawei and Bian, Xiao and Fan, Heng and Hu, Qinghua and Ling, Haibin,
journal=IEEE Transactions on Pattern Analysis and Machine Intelligence,
volume=44,
number=11,
pages=7380–7399,
year=2021,
publisher=IEEE
D-FINE
@miscpeng2024dfine,
title=D-FINE: Redefine Regression Task in DETRs as Fine-grained Distribution Refinement,
author=Yansong Peng and Hebei Li and Peixi Wu and Yueyi Zhang and Xiaoyan Sun and Feng Wu,
year=2024,
eprint=2410.13842,
archivePrefix=arXiv,
primaryClass=cs.CV
本文由 AI 台灣 運用 AI 技術編撰,內容僅供參考,請自行核實相關資訊。
歡迎加入我們的 AI TAIWAN 台灣人工智慧中心 FB 社團,
隨時掌握最新 AI 動態與實用資訊!