:冬蟲夏草小目標(biāo)檢測從訓(xùn)練到部署全流程)
簡介目標(biāo)檢測是計算機視覺領(lǐng)域的核心任務(wù)之一其本質(zhì)是在圖像中定位并識別感興趣的目標(biāo)。在實際工程中針對小目標(biāo)、復(fù)雜背景的檢測場景模型的選擇與訓(xùn)練策略往往比網(wǎng)絡(luò)結(jié)構(gòu)本身更關(guān)鍵。YOLOv5作為成熟穩(wěn)定的檢測框架憑借其輕量級設(shè)計、靈活的配置和豐富的生態(tài)資源在諸多垂直領(lǐng)域中得到廣泛應(yīng)用。本文以冬蟲夏草生長檢測為實踐案例系統(tǒng)介紹從數(shù)據(jù)集構(gòu)建、標(biāo)注規(guī)范、數(shù)據(jù)增強到模型訓(xùn)練、超參調(diào)整、權(quán)重選擇再到推理優(yōu)化與邊緣設(shè)備部署的完整鏈路。通過合理調(diào)整置信度閾值、輸入分辨率與錨框參數(shù)可有效提升小目標(biāo)的召回率。該技術(shù)路線同樣適用于農(nóng)作物監(jiān)測、野生資源調(diào)查、工業(yè)缺陷檢測等場景為開發(fā)者提供了一套可復(fù)用的工程化解決方案。 這個項目其實挺有意思的。冬蟲夏草這玩意兒跟工業(yè)質(zhì)檢里那些規(guī)規(guī)矩矩的螺絲釘完全不一樣它長在高原草甸上背景是枯草、泥土、碎石混在一起的復(fù)雜環(huán)境子座從土里冒出來個頭小、顏色跟周圍環(huán)境還特別接近人眼找起來都得瞇著眼睛仔細看。用YOLOv5來做單類別檢測聽起來不算復(fù)雜但真正跑通“數(shù)據(jù)準(zhǔn)備→標(biāo)注→訓(xùn)練→權(quán)重部署”這條鏈路里頭的坑一點不少。這篇就把整個實戰(zhàn)過程掰開揉碎從數(shù)據(jù)集怎么來、標(biāo)注要注意什么到訓(xùn)練參數(shù)怎么調(diào)、權(quán)重文件怎么選再到推理和常見問題排查一次性講清楚。1. 項目核心思路與方案選型1.1 為什么選YOLOv5而不是YOLOv8或者更重的框架先說結(jié)論單類別目標(biāo)檢測YOLOv5目前依然是性價比最高的選擇沒有之一。雖然YOLOv8、YOLOv9這些新版本在COCO這類通用數(shù)據(jù)集上刷榜刷得很歡但放到“冬蟲夏草生長檢測”這種垂直場景里YOLOv5的生態(tài)成熟度、踩坑資料數(shù)量、部署資料完整度都遠超新版本。具體原因有三點。第一YOLOv5對硬件的要求足夠友善。蟲草檢測這套任務(wù)目標(biāo)是小尺寸、低對比度通常需要在實地設(shè)備上跑可能是Jetson Nano可能是RK3568也可能是工廠或者實驗室里一臺普通的老GPU。YOLOv5s和YOLOv5n這兩個輕量級版本在GTX 1660這種入門級顯卡上就能訓(xùn)練推理時甚至CPU都能跑只不過速度慢一些。而YOLOv8雖然也有n/s版本但很多老設(shè)備上的推理庫和工具鏈對它的支持還沒有完全跟上。第二YOLOv5的代碼結(jié)構(gòu)清晰配置文件簡單適合做二次改動。比如后面要講的anchor尺寸調(diào)整、數(shù)據(jù)增強策略開關(guān)都是幾行配置的事。而且國內(nèi)外關(guān)于YOLOv5的教程、踩坑記錄、社區(qū)問答簡直是海量遇到問題搜一下基本都有答案。對這類偏應(yīng)用型的項目來說框架的“可救性”比“先進性”重要得多。第三YOLOv5的輸出權(quán)重格式對后續(xù)部署非常友好。不管是轉(zhuǎn)成onnx、TorchScript還是TensorRT都有成熟穩(wěn)定的轉(zhuǎn)換腳本這在后面做邊緣設(shè)備部署時會省掉大量時間。單類別任務(wù)尤其適合YOLOv5還有一個隱藏優(yōu)勢它的Neck和Head設(shè)計本身是按通用物體檢測優(yōu)化的在處理單類別、小目標(biāo)、復(fù)雜背景這類場景時可控的調(diào)節(jié)空間很大不需要做網(wǎng)絡(luò)結(jié)構(gòu)層面的改動只需要在數(shù)據(jù)增強、錨框、超參上做文章。1.2 單類別“生長檢測”的任務(wù)定位這里需要先把“檢測”和“分類”的概念理清楚。這個項目做的是“冬蟲夏草生長檢測”本質(zhì)上是在圖像中回答兩個問題圖中有沒有冬蟲夏草如果有它在哪里這類需求在實際業(yè)務(wù)中對應(yīng)很多場景。比如高原產(chǎn)區(qū)做蟲草資源的動態(tài)監(jiān)測通過無人機或地面巡拍采集圖像用模型自動框出每個蟲草的位置統(tǒng)計分布密度再比如藥材企業(yè)做收購分級前的初篩把大量歷史照片里的蟲草快速標(biāo)記出來替代人工一張張翻找還有科研單位做生長周期觀測通過連續(xù)圖像中的蟲草位置變化來分析出土?xí)r間、生長速度等指標(biāo)?!?類別”意味著不需要區(qū)分蟲草的種類、等級、生長階段只要能找到“目標(biāo)在哪”就行。這看起來比多類別任務(wù)簡單但實際做下來會發(fā)現(xiàn)單類別任務(wù)的難點不在“區(qū)分度”而在“查全率”也就是漏檢率。蟲草的顏色和周圍枯草接近早期出土的子座非常小幾十像素到一百像素都很常見如果不專門優(yōu)化小目標(biāo)檢測能力模型很容易漏掉大量真實目標(biāo)。所以這個項目的數(shù)據(jù)集設(shè)計和訓(xùn)練策略一切都是圍繞“少漏檢、少誤檢”來做的而不是追求把某個類別的AP刷到99%。2. 數(shù)據(jù)集構(gòu)建與預(yù)處理2.1 數(shù)據(jù)來源與采集策略冬蟲夏草的數(shù)據(jù)集不像車牌、行人那么爛大街公開的現(xiàn)成數(shù)據(jù)集很少所以很大概率需要自己動手?jǐn)€。根據(jù)我做類似農(nóng)作物檢測項目的經(jīng)驗數(shù)據(jù)來源可以分三條路按優(yōu)先級排列。第一條路是實地采集也就是帶著相機或手機到種植基地、產(chǎn)區(qū)草甸去拍。這是最理想的方式因為拍到的圖像和實際部署場景完全一致沒有域偏移問題。拍攝時要注意幾個細節(jié)盡量覆蓋不同時間段因為早晨和傍晚的光線角度、色溫完全不一樣要拍不同天氣條件晴天、陰天、雨后蟲草出土后帶著水珠的樣子和干燥時差別很大還要覆蓋不同背景純草地、碎石地、枯草密集地都要有。拍攝高度和角度也要模擬實際使用場景如果最終打算用無人機俯拍那訓(xùn)練數(shù)據(jù)就不要大量使用平視角度拍攝的圖。第二條路是整理歷史照片。很多產(chǎn)區(qū)的研究者、收購商手里都有大量歷史照片雖然可能沒有針對檢測任務(wù)做過標(biāo)注但作為檢測任務(wù)的原始素材非常合適。我建議在動手標(biāo)注之前先建一個簡單的素材池把同角度、同光線、同背景的相似照片去重避免模型過擬合到重復(fù)背景。第三條路是網(wǎng)絡(luò)公開圖片。這個只能作為補充因為公開圖片的版權(quán)、分辨率、拍攝角度差異太大而且能搜到的蟲草特寫圖大多是大目標(biāo)、清晰背景跟實際野外場景差距很大。如果非要用只能作為增加背景多樣性的輔助不能作為主力數(shù)據(jù)。我以自己做的這套數(shù)據(jù)為例總共1080張圖其中實地采集約700張歷史資料整理300張網(wǎng)絡(luò)補充80張。數(shù)量不算多但單類別檢測本身數(shù)據(jù)需求就不像多類別那么高關(guān)鍵是質(zhì)量。2.2 標(biāo)注工具與YOLO格式要點標(biāo)注工具我用的是LabelImg開源免費操作簡單安裝后直接就能用。用pip安裝就行pip install labelImg然后命令行啟動labelImg在工具里把圖片文件夾和預(yù)定義的類別文件路徑配置好類別文件就是一個txt每一行寫一個類別名。單類別項目就一行dongchongxiacao標(biāo)注界面里用矩形框把蟲草的子座框出來。這里有個非常關(guān)鍵的實操經(jīng)驗框的范圍寧小勿大。冬蟲夏草的檢測重點通常放在子座也就是露出地面的那一段真菌結(jié)構(gòu)上不要把周圍的泥土、小草、雜物包進框里。因為框得太大會讓模型學(xué)到“蟲草一堆背景區(qū)域一個小目標(biāo)”的錯誤映射推理時誤檢率會直線上升。標(biāo)注完成后LabelImg默認會生成VOC格式的XML文件需要轉(zhuǎn)成YOLO格式的txt。YOLO格式的核心是每張圖對應(yīng)一個txt文件每一行代表一個目標(biāo)格式是class_id center_x center_y width height注意這里的四個坐標(biāo)值全部是歸一化到0-1之間的用像素值除以圖像寬高得到。舉個例子一張1920x1080的圖中一個目標(biāo)框左上角在(500, 300)右下角在(800, 700)那么img_w, img_h 1920, 1080 x1, y1, x2, y2 500, 300, 800, 700 cx ((x1 x2) / 2) / img_w cy ((y1 y2) / 2) / img_h w (x2 - x1) / img_w h (y2 - y1) / img_h如果自己寫轉(zhuǎn)換腳本這段邏輯是核心。還要注意YOLO格式的txt文件名必須和圖片文件名完全一致包括擴展名前面的部分且放在對應(yīng)的labels目錄下否則訓(xùn)練時數(shù)據(jù)加載會報錯。2.3 數(shù)據(jù)增強策略與樣本平衡數(shù)據(jù)增強對于蟲草這類小目標(biāo)、復(fù)雜背景的任務(wù)極其重要。YOLOv5內(nèi)置了Mosaic增強、隨機翻轉(zhuǎn)、HSV色域增強、隨機仿射變換等這些在訓(xùn)練時默認會啟用。但對于蟲草場景我建議做幾個針對性調(diào)整。首先是Mosaic增強的拼圖策略。Mosaic會把4張圖縮放到小尺寸再拼接好處是增加了小目標(biāo)的數(shù)量壞處是如果原圖本身分辨率不高縮放后目標(biāo)會變得更加模糊。所以我建議在數(shù)據(jù)準(zhǔn)備階段就不要把原圖壓得太小YOLOv5在訓(xùn)練時會把圖resize到輸入尺寸比如640x640如果原圖本身分辨率不足目標(biāo)信噪比會急劇下降。我自己的經(jīng)驗是原圖分辨率至少保持1280以上訓(xùn)練時imgsz可以設(shè)成640讓模型在縮放過程中學(xué)到更多細節(jié)。其次是翻轉(zhuǎn)增強。YOLOv5默認的翻轉(zhuǎn)參數(shù)是隨機水平翻轉(zhuǎn)0.5也就是一半概率左右翻轉(zhuǎn)。蟲草的生長方向雖然天然隨機的但如果你在實際部署時對方向有明確要求比如明確要檢測“從土里向上生長”的狀態(tài)翻轉(zhuǎn)過狠會讓模型對方向不敏感。我在這個項目里把水平翻轉(zhuǎn)概率降到0.25垂直翻轉(zhuǎn)直接關(guān)閉因為垂直翻轉(zhuǎn)會讓蟲草變成“倒掛”狀態(tài)實際場景不會出現(xiàn)學(xué)了反而干擾。第三是HSV色域增強。蟲草和背景的顏色差異很微妙過度調(diào)整飽和度、色相會讓模型學(xué)到錯誤的顏色特征。YOLOv5默認的hsv_h、hsv_s、hsv_v參數(shù)是0.015、0.7、0.4對通用任務(wù)合適但對蟲草這種低對比度目標(biāo)我建議把hsv_s降到0.3左右把hsv_v保持0.4讓模型更關(guān)注形狀和紋理特征而不是死記顏色。數(shù)據(jù)集規(guī)模不夠時還可以用離線增強的方式擴充樣本比如旋轉(zhuǎn)90度、180度、270度對蟲草這種無方向性目標(biāo)其實沒毛病以及加入高斯噪聲、輕微模糊模擬不同天氣條件下拍攝的效果。但要記住一個原則增強是為了模擬真實分布不是為了編造不存在的場景。2.4 數(shù)據(jù)集目錄結(jié)構(gòu)標(biāo)準(zhǔn)的YOLOv5數(shù)據(jù)集目錄結(jié)構(gòu)如下dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── dongchongxiacao.yaml其中images和labels必須嚴(yán)格對應(yīng)train、val的比例按8:1:1或9:1來分都可以。單類別任務(wù)數(shù)據(jù)量本身不大我建議驗證集比例稍微高一些比如15%這樣評估指標(biāo)更可信。劃分的時候一定注意同一次拍攝的連續(xù)幀照片不要同時出現(xiàn)在訓(xùn)練集和驗證集里不然驗證集結(jié)果會虛高。我習(xí)慣按文件名前綴或目錄來劃分而不是隨機抽這樣更貼近真實場景。yaml配置文件內(nèi)容大概是這樣的train: dataset/images/train val: dataset/images/val test: dataset/images/test nc: 1 names: [dongchongxiacao]路徑建議用相對路徑這樣整個項目目錄拷到別的機器上不用改配置。yaml文件里的換行、空格縮進要嚴(yán)格按YAML語法一個空格錯位都會報錯。3. 環(huán)境配置與訓(xùn)練關(guān)鍵步驟3.1 YOLOv5環(huán)境安裝環(huán)境安裝這塊網(wǎng)上教程五花八門我直接說一套最穩(wěn)的流程。先創(chuàng)建Python虛擬環(huán)境推薦用condaconda create -n yolov5 python3.8 conda activate yolov5然后克隆YOLOv5倉庫并安裝依賴git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txtrequirements.txt會裝torch、torchvision、opencv-python、numpy、matplotlib等一堆依賴。需要注意這里默認裝的是CPU版torch如果你有NVIDIA GPU需要先裝對應(yīng)CUDA版本的torch再跑requirements。建議先單獨裝pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118再執(zhí)行pip install -r requirements.txt這樣能避免依賴順序問題。裝完之后先跑一個最簡單的測試python detect.py --weights yolov5s.pt --source data/images/bus.jpg如果順利輸出結(jié)果圖說明環(huán)境通了。如果卡在下載權(quán)重文件那一步就手動去下載yolov5s.pt放到項目根目錄。權(quán)重文件名必須嚴(yán)格匹配大小寫都不能錯。3.2 數(shù)據(jù)配置文件與訓(xùn)練啟動環(huán)境就緒后把前面準(zhǔn)備好的dataset目錄和yaml配置文件放到Y(jié)OLOv5項目同級目錄下。訓(xùn)練命令是python train.py --img 640 --batch 16 --epochs 200 --data dongchongxiacao.yaml --weights yolov5s.pt --name dongchong_test逐項解釋一下--img是輸入圖像尺寸640是默認值如果你的顯存夠比如12G以上可以調(diào)成960小目標(biāo)檢測效果會明顯提升--batch是批大小16在8G顯存下是安全的如果爆顯存就降到8--epochs是訓(xùn)練輪數(shù)單類別任務(wù)200輪完全夠再多了容易過擬合--weights是預(yù)訓(xùn)練權(quán)重這里用yolov5s.pt如果你顯存很小可以用yolov5n.pt更輕量但精度會掉一點--name是訓(xùn)練輸出的文件夾名YOLOv5會保存到runs/train/下。訓(xùn)練過程中要盯幾個東西。第一個是loss曲線YOLOv5的輸出里box_loss、obj_loss、cls_loss三條曲線單類別任務(wù)主要關(guān)注box_loss和obj_loss。正常情況是前50輪快速下降之后緩慢收斂如果曲線一路走平或者反彈說明有問題下面排查章節(jié)詳細說。第二個是mAP曲線每10輪會自動在驗證集上評估一次mAP0.5一般到0.85以上就算能用蟲草這種難檢測的小目標(biāo)0.8以上已經(jīng)算不錯了。3.3 超參數(shù)調(diào)整與實戰(zhàn)心得YOLOv5自帶一個超參數(shù)文件data/hyps/hyp.scratch-low.yaml默認值對通用任務(wù)比較穩(wěn)。但蟲草檢測有幾個參數(shù)值得動一動。一個是錨框anchor。YOLOv5默認的anchor是在COCO數(shù)據(jù)集聚類出來的對蟲草這種小目標(biāo)來說偏大。如果你在訓(xùn)練日志里看到某些anchor匹配率很低YOLOv5會自動重聚類所以一般不用手動改但為了保險可以在訓(xùn)練前用YOLOv5自帶的聚類腳本對標(biāo)注框做一次分析。方法不復(fù)雜本質(zhì)是用K-means統(tǒng)計所有標(biāo)注框的長寬分布。蟲草的目標(biāo)框特點是細長、瘦高子座是長的跟COCO里那些方形目標(biāo)差異很大。建議訓(xùn)練時開啟--multi-scale參數(shù)讓模型適應(yīng)不同尺度的目標(biāo)。另一個是正負樣本匹配的iou閾值。YOLOv5低版本用的是single anchor匹配策略新版本改成動態(tài)分配。如果想調(diào)可以在模型配置文件里改anchor_t默認4.0這個值越大允許預(yù)測框偏離真實框的程度越大對召回率有幫助但會犧牲一些精度。單類別任務(wù)我建議適度調(diào)高比如設(shè)成4.5因為蟲草目標(biāo)小、形狀細長太嚴(yán)格的正樣本匹配會讓模型學(xué)不到東西。還有一個非常容易被忽略的參數(shù)--workers。這個參數(shù)控制數(shù)據(jù)加載的線程數(shù)Windows下默認0Linux下可以設(shè)成4或8。數(shù)據(jù)加載速度跟不上GPU時訓(xùn)練會一直等數(shù)據(jù)GPU利用率上不去看起來像模型壞了一樣實際是IO瓶頸。3.4 權(quán)重文件解讀與版本管理訓(xùn)練結(jié)束后runs/train/dongchong_test/weights/目錄下會有兩個文件best.pt和last.pt。這兩個文件看似差不多實際用途完全不同。best.pt是整個訓(xùn)練過程中在驗證集上表現(xiàn)最好的權(quán)重也是我們?nèi)粘M评?、部署要用的那個。last.pt是最后一個epoch的權(quán)重主要用于中斷后恢復(fù)訓(xùn)練或者你想繼續(xù)在前一次訓(xùn)練結(jié)果的基礎(chǔ)上接著跑。千萬別把它們搞混了很多人圖省事直接用last.pt部署結(jié)果精度明顯偏低。權(quán)重文件用起來有幾個細節(jié)要注意。第一best.pt是包含完整的模型結(jié)構(gòu)、優(yōu)化器狀態(tài)和訓(xùn)練配置的文件比較大yolov5s大約15M如果只是做推理可以在detect.py里正常加載但如果是部署到生產(chǎn)環(huán)境建議用export.py先轉(zhuǎn)成onnx或TorchScript格式體積更小、加載更快。第二權(quán)重文件的版本和代碼版本必須匹配。用YOLOv6.0的代碼跑出來的權(quán)重拿到Y(jié)OLOv5v5.0的代碼里直接推理大概率報錯或者結(jié)果異常。我在本地會用一個簡單的腳本管理多個項目的權(quán)重文件目錄結(jié)構(gòu)按項目分weights/ ├── dongchong/ │ ├── best.pt │ ├── last.pt │ └── onnx/ │ └── best.onnx這樣每次訓(xùn)練成果不會互相覆蓋也能快速回溯。4. 模型評估與推理部署實踐4.1 評估指標(biāo)怎么看訓(xùn)練完之后runs/train/dongchong_test/下會有results.png里面畫了所有指標(biāo)曲線。單類別任務(wù)重點看四個Precision精確率、Recall召回率、mAP0.5、mAP0.5:0.95。在蟲草檢測場景里Recall比Precision重要。這個邏輯跟工業(yè)質(zhì)檢剛好相反質(zhì)檢里把良品誤判成次品會增加人工復(fù)檢成本但蟲草檢測如果漏檢Recall低意味著實際有蟲草的地方?jīng)]檢測出來統(tǒng)計密度或計數(shù)就會偏低這直接導(dǎo)致數(shù)據(jù)失真。所以訓(xùn)練階段如果發(fā)現(xiàn)Precision和Recall有矛盾優(yōu)先照顧Recall。YOLOv5在驗證時輸出的PR曲線圖會顯示置信度閾值與Precision/Recall的平衡關(guān)系。默認置信度閾值是0.25如果你發(fā)現(xiàn)推理時漏檢多可以把這個值降到0.15甚至0.1如果誤檢多就往上調(diào)到0.4。這個調(diào)參邏輯后面推理部分還會詳細說。一個容易踩的坑mAP0.5:0.95這個指標(biāo)在蟲草這種小目標(biāo)、細長形狀的任務(wù)上通常不會好看可能只有0.3-0.4這是正常的。因為這個IoU閾值范圍太嚴(yán)格蟲草的框稍微偏一點IoU就掉得厲害。不要單純因為mAP0.5:0.95不高就認為模型不行還是要看實際推理效果。4.2 推理參數(shù)優(yōu)化推理用detect.py基本命令python detect.py --weights runs/train/dongchong_test/weights/best.pt --source test_images/ --conf 0.25 --iou 0.45 --img 640--conf是置信度閾值--iou是NMS的IoU閾值。實際調(diào)參經(jīng)驗是蟲草檢測的置信度閾值不要設(shè)太高因為小目標(biāo)、低對比度目標(biāo)的置信度天然偏低。我實測下來0.15-0.2這個區(qū)間的置信度閾值能在漏檢和誤檢之間找到比較好的平衡點。NMS的iou閾值保持在0.45-0.5就行蟲草目標(biāo)之間基本不會互相重疊。如果檢測的是視頻或?qū)崟r攝像頭流還要注意--vid-stride參數(shù)默認是1也就是逐幀檢測。野外拍攝的視頻如果幀率很高比如30fps相鄰幀內(nèi)容幾乎不變可以調(diào)成2或3省一半算力還不漏目標(biāo)。代碼層面如果想在推理時順便輸出目標(biāo)的數(shù)量可以在detect.py的輸出循環(huán)里加幾行判斷統(tǒng)計每個檢測結(jié)果里框的數(shù)量。這個功能在蟲草密度統(tǒng)計場景特別實用。4.3 邊緣設(shè)備部署的思路如果最終要部署在Jetson、RK3588這類邊緣設(shè)備上做實時檢測建議提前把權(quán)重轉(zhuǎn)成TensorRT或RKNN格式。YOLOv5自帶的export.py支持onnx導(dǎo)出python export.py --weights best.pt --include onnx --opset 11轉(zhuǎn)出來的onnx可以接著用TensorRT的trtexec工具優(yōu)化或者轉(zhuǎn)成RKNN。這里有個重要提醒邊緣設(shè)備上的量化對細長小目標(biāo)不友好。蟲草目標(biāo)本身的像素面積小INT8量化后特征丟失嚴(yán)重很多目標(biāo)就檢測不到了。如果邊緣設(shè)備推理精度掉得厲害優(yōu)先考慮FP16而不是INT8或者干脆用FP32雖然慢一點但保精度。部署時還有一個很容易忽略的點輸入分辨率要和訓(xùn)練時保持一致。如果訓(xùn)練用640推理時為了提高速度改成320小目標(biāo)會大量漏檢。如果確實需要提速建議改batch size或換輕量主干而不是降低輸入分辨率。5. 常見問題與排查技巧實錄5.1 訓(xùn)練不收斂或loss震蕩這個現(xiàn)象在蟲草項目里很常見因為目標(biāo)小、正負樣本極度不平衡。首先要確認一個關(guān)鍵點是不是數(shù)據(jù)標(biāo)注出了問題。我遇到過好幾次訓(xùn)練loss一直降不下去打開標(biāo)注文件一看坐標(biāo)歸一化做錯了有一半目標(biāo)框的cx、cy超過1模型根本學(xué)不到正確位置。如果確認標(biāo)注沒問題再檢查訓(xùn)練集和驗證集是不是有重復(fù)。前面說過連續(xù)幀照片如果同時進訓(xùn)練集和驗證集驗證集的loss會很低但推理時表現(xiàn)差這是典型的“假收斂”。另外數(shù)據(jù)太少也會導(dǎo)致loss震蕩單類別任務(wù)至少要有500張有效圖再多就穩(wěn)很多。超參數(shù)方面如果前50輪loss完全沒有下降趨勢嘗試把--lr0初始學(xué)習(xí)率從默認的0.01降到0.001。蟲草這種難分類任務(wù)學(xué)習(xí)率太大容易在loss曲面震蕩小一點反而收斂更穩(wěn)。5.2 CUDA顯存不足顯存不足是新手遇到最多的報錯英文提示通常是CUDA out of memory。最直接的解決辦法是降低--batch從16降到8再降到4直到能跑起來。但要注意batch太小導(dǎo)致梯度估計不準(zhǔn)訓(xùn)練會不穩(wěn)定。我建議優(yōu)先降低--img尺寸從640降到512或480這樣顯存占用下降非常明顯同時小目標(biāo)性能損失不算太大。如果batch和img都不想動就開梯度累積可以通過在訓(xùn)練腳本里設(shè)置--accumulate參數(shù)YOLOv5新版沒有直接暴露的CLI參數(shù)需要改代碼或在hyp里調(diào)相當(dāng)于每多步積累一次梯度再更新效果近似于變相擴大batch。5.3 過擬合特征蟲草數(shù)據(jù)集如果采集場景單一模型很容易過擬合。表現(xiàn)形式是訓(xùn)練集loss很低但驗證集loss反彈或者驗證集mAP遲遲上不去。解決辦法有兩個方向。一是嚴(yán)格劃分?jǐn)?shù)據(jù)集保證訓(xùn)練集和驗證集的拍攝場景不重疊二是加大數(shù)據(jù)增強強度把Mosaic的縮放范圍調(diào)大、開啟copy_paste增強YOLOv5新版支持讓模型見過更多樣的輸入。5.4 推理誤檢、漏檢調(diào)整思路把常見問題整理成一張速查表方便直接對著排查。現(xiàn)象可能原因解決方式漏檢多該框的沒框置信度閾值偏高把--conf從0.25降到0.15漏檢多且小目標(biāo)完全看不見輸入分辨率太低把--img從640提高到960誤檢多把草、石頭框出來置信度閾值偏低把--conf從0.15升到0.35誤檢多且框偏大標(biāo)注框畫得太大重新檢查并修改部分標(biāo)注后重訓(xùn)驗證集AP高但新圖效果差訓(xùn)練集和部署場景差異大補充部署場景的數(shù)據(jù)或做遷移微調(diào)輸出結(jié)果閃爍視頻檢測幀間置信度波動結(jié)合跟蹤邏輯或提高幀推理穩(wěn)定性5.5 幾個容易忽視的細節(jié)這些細節(jié)是做完整個項目之后回頭看最想讓當(dāng)初的自己提前知道的。第一不要迷信訓(xùn)練輪數(shù)多。單類別蟲草檢測150-200輪足夠再多就是浪費算力和顯存。如果發(fā)現(xiàn)100輪以后mAP已經(jīng)開始走平可以直接提前停YOLOv5自帶早停機制默認patience是100也可以手動設(shè)小一點。第二權(quán)重文件損壞問題。從網(wǎng)上下載預(yù)訓(xùn)練權(quán)重時如果文件下載不全訓(xùn)練時可能不報錯但loss亂跳。遇到訓(xùn)練異常先把權(quán)重文件刪掉重新下載排除這個最簡單的可能性。第三配置文件的YAML格式陷阱。YOLOv5的data yaml里冒號后面一定要有空格train: dataset/images/train這種寫法如果寫成train:dataset/images/train會直接報錯而且報錯信息還很不直觀新人容易在這里卡一個小時。第四標(biāo)簽文件和圖片數(shù)量必須一一對應(yīng)。有些圖是沒有目標(biāo)的正確的做法是保留一個內(nèi)容的txt文件0字節(jié)千萬不要把沒有目標(biāo)的圖直接刪掉或者不生成空txt。YOLOv5在加載數(shù)據(jù)時會校驗數(shù)量對不上訓(xùn)練就會中斷。第五多尺度訓(xùn)練與推理分辨率的關(guān)系。如果訓(xùn)練時用了--multi-scale模型在各尺度下都能工作但推理時最好還是用訓(xùn)練時最常用的主尺度通常是640這樣效果最穩(wěn)定。最后再分享一個小技巧當(dāng)我對一個權(quán)重文件的效果不確定時會專門挑幾張最難的圖比如目標(biāo)極小、背景極亂、光線很差的單獨做測試而不是只看驗證集mAP。因為驗證集是數(shù)據(jù)集劃分出來的跟訓(xùn)練集同分布在這個數(shù)據(jù)集上效果好不代表真實現(xiàn)場效果好。用最難樣本做一個“壓力測試”這個權(quán)重能不能用心里馬上就有數(shù)了。這個項目做完最大的感受是目標(biāo)檢測項目的重心往往不在模型本身而在數(shù)據(jù)和細節(jié)上。YOLOv5的代碼和權(quán)重都是現(xiàn)成的真正決定蟲草檢測效果好壞的是有沒有一張干凈的、標(biāo)注合理的、分布貼近真實場景的數(shù)據(jù)集以及遇到了loss不降、顯存爆掉、識別不準(zhǔn)這些問題時能不能快速定位到癥結(jié)。把這套流程完整跑一遍后續(xù)再換其他單類別檢測項目基本就是復(fù)制粘貼再微調(diào)的事。本文還有配套的精品資源點擊獲取