戰(zhàn):從數(shù)據(jù)集準(zhǔn)備到訓(xùn)練調(diào)參全流程解析)
簡介面向目標(biāo)檢測學(xué)習(xí)者和船只識別應(yīng)用開發(fā)者這是一套完整的YOLOv5艦船檢測資源包內(nèi)置訓(xùn)練好的多類別船只檢測權(quán)重、PR曲線與loss曲線等評估文件并附帶數(shù)千張標(biāo)注圖像覆蓋艦艇、游輪、帆船、軍艦等類別。標(biāo)注文件同時(shí)提供txt與xml兩種格式分別存放于獨(dú)立文件夾中既能直接訓(xùn)練YOLOv5也方便轉(zhuǎn)換為其他檢測框架數(shù)據(jù)集。代碼基于PyTorch實(shí)現(xiàn)復(fù)用YOLOv5環(huán)境即可加載權(quán)重后可直接完成圖片或視頻中的船只檢測。壓縮包共288個(gè)文件主要包含jpg圖片數(shù)據(jù)、yaml與yml配置、py推理腳本、pt權(quán)重、sh啟動腳本、csv訓(xùn)練記錄、說明文檔及notebook示例等整體約760.77MB。已有1677人學(xué)習(xí)下載適合需要快速獲得可靠船只檢測模型或高質(zhì)量標(biāo)注數(shù)據(jù)的研究者與工程人員可極大縮短模型從零訓(xùn)練與數(shù)據(jù)準(zhǔn)備周期尤其適合用于畢業(yè)設(shè)計(jì)、算法復(fù)現(xiàn)與工程落地前的快速驗(yàn)證。 艦船檢測這個(gè)方向在目標(biāo)檢測的畢設(shè)和橫向項(xiàng)目里一直是高頻選題。YOLOv5做艦船檢測配上幾千張標(biāo)注好的數(shù)據(jù)集這套組合我見了太多次自己也完整跑通過好幾輪。說句實(shí)在話這個(gè)題目看起來簡單真正動手做的時(shí)候坑基本都藏在數(shù)據(jù)準(zhǔn)備和訓(xùn)練細(xì)節(jié)里。很多人以為下載個(gè)數(shù)據(jù)集、克隆個(gè)倉庫、跑個(gè)train.py就完事了結(jié)果不是loss不收斂就是mAP低得沒法看最后連問題出在哪都說不清。這篇文章我就圍繞“YOLOv5艦船檢測 艦船檢測模型 幾千張標(biāo)注數(shù)據(jù)集”這個(gè)完整組合把從數(shù)據(jù)準(zhǔn)備、格式轉(zhuǎn)換、工程配置到訓(xùn)練調(diào)參、問題排查的完整鏈路拆開講一遍。做畢設(shè)、做課程設(shè)計(jì)或者只是想系統(tǒng)入門目標(biāo)檢測實(shí)戰(zhàn)的朋友都可以直接照著操作。不是那種只貼命令的教程我會把每一步背后的為什么也講清楚。1. 為什么是YOLOv5 幾千張數(shù)據(jù)集1.1 這個(gè)組合為什么流行YOLOv5能在艦船檢測這種任務(wù)里成為首選不是因?yàn)樗茸罡叨且驗(yàn)樗凇熬取⑺俣?、易用性、部署成本”四個(gè)維度上取得了一個(gè)絕大多數(shù)人都能接受的平衡點(diǎn)。艦船檢測常見的落地場景是港口監(jiān)控、航道管理、海事巡邏這些場景對實(shí)時(shí)性有硬要求動輒幾十上百路視頻流接入推理速度直接決定方案能不能用。YOLOv5在邊緣設(shè)備、普通顯卡上都能跑得動這點(diǎn)比很多兩階段模型更有優(yōu)勢。另外YOLOv5的工程化成熟度確實(shí)高。數(shù)據(jù)格式、訓(xùn)練流程、評估腳本、導(dǎo)出部署都做得比較順滑一個(gè)新手嚴(yán)格按照文檔操作大概率能跑通。相比之下如果用更復(fù)雜的檢測框架光是環(huán)境依賴就能勸退不少人。項(xiàng)目周期短、驗(yàn)收要求“能跑、能看、能匯報(bào)”的話YOLOv5幾乎是唯一不需要糾結(jié)的答案。1.2 “幾千張”這個(gè)規(guī)模的背后邏輯再說數(shù)據(jù)集規(guī)模。很多人的誤區(qū)是覺得標(biāo)注數(shù)據(jù)“越多越好”但實(shí)際項(xiàng)目中幾千張標(biāo)注圖片是一個(gè)很有性價(jià)比的區(qū)間。艦船檢測屬于單類或少數(shù)類別的目標(biāo)檢測類別數(shù)少模型需要學(xué)習(xí)的模式相對單一——船體輪廓、甲板結(jié)構(gòu)、船舶與背景的對比特征。這種情況下高質(zhì)量的三五千張圖片已經(jīng)足夠讓模型達(dá)到一個(gè)可用的水平。我個(gè)人的體感是如果標(biāo)注質(zhì)量靠譜、場景覆蓋多樣4000張左右的艦船數(shù)據(jù)訓(xùn)練出來的模型mAP50可以做到0.85以上。真正決定上限的不是數(shù)量而是數(shù)據(jù)的多樣性。全是同一視角、同一海況、同一光照條件下的圖哪怕給你一萬張泛化能力也堪憂。反過來如果圖片覆蓋了不同海況、近岸遠(yuǎn)海、不同天氣、不同船型2000張也能給你驚喜。所以“幾千張”這個(gè)規(guī)模本身是合理的關(guān)鍵在數(shù)據(jù)質(zhì)量。2. 數(shù)據(jù)集的獲取、清洗與格式轉(zhuǎn)換2.1 數(shù)據(jù)從哪來開源數(shù)據(jù)與自建標(biāo)注艦船檢測的數(shù)據(jù)獲取主要有三條路。第一條是直接用開源數(shù)據(jù)集常用的有SeaShips、HRSC2016還有一些遙感艦船數(shù)據(jù)集。SeaShips是目前用的比較多的一個(gè)包含上萬個(gè)實(shí)例涵蓋貨船、漁船、集裝箱船、客輪等多種類型場景貼近實(shí)際水域監(jiān)控。HRSC2016偏向遙感影像圖片來自谷歌地球分辨率高但視角單一適合做遙感方向的檢測。第二條路是自己爬圖標(biāo)注。用爬蟲從圖庫網(wǎng)站抓取艦船圖片然后用LabelImg或者X-AnyLabeling標(biāo)注。這條路的問題是版權(quán)和標(biāo)注成本——幾千張圖的標(biāo)注熟練工也要兩三周還不算返工。第三條路是混合路線先用開源數(shù)據(jù)訓(xùn)練一個(gè)初版模型再用這個(gè)模型去自動標(biāo)注新采集的圖片人工只做修正。這個(gè)方案效率最高但對初版模型的精度有要求通常適合已有一定基礎(chǔ)數(shù)據(jù)的情況。不管哪條路數(shù)據(jù)質(zhì)量把關(guān)都躲不掉。我的習(xí)慣是拿到數(shù)據(jù)后先做一輪快速篩查刪掉明顯重復(fù)的、嚴(yán)重模糊的、目標(biāo)占比過小的圖片。千萬不要把臟數(shù)據(jù)帶進(jìn)訓(xùn)練集后面排查問題會非常痛苦。2.2 標(biāo)注格式轉(zhuǎn)換從任意格式轉(zhuǎn)到Y(jié)OLOYOLOv5使用的標(biāo)注格式是txt文件每行對應(yīng)一個(gè)目標(biāo)格式為“類別id 中心點(diǎn)x 中心點(diǎn)y 寬度w 高度h”其中x、y、w、h都是相對于圖片寬度和高度的歸一化值。比如一張1920x1080的圖某個(gè)目標(biāo)的中心點(diǎn)像素坐標(biāo)是(960, 540)寬480高270那么對應(yīng)的一行是“0 0.5 0.5 0.25 0.25”。很多公開數(shù)據(jù)集的標(biāo)注并不是這個(gè)格式。HRSC2016的標(biāo)注是XML格式帶旋轉(zhuǎn)框信息SeaShips的標(biāo)注格式在不同版本里還不太一樣。另一種常見情況是之前用LabelImg標(biāo)注生成的是Pascal VOC格式的XML或者用labelme標(biāo)注生成的是JSON。這些格式都需要轉(zhuǎn)成YOLO的txt格式。數(shù)據(jù)格式規(guī)范是訓(xùn)練的第一步。如果不確定自己的標(biāo)注格式是否正確可以用一行代碼快速驗(yàn)證——把圖片和對應(yīng)的txt放進(jìn)同一個(gè)目錄然后用可視化腳本把標(biāo)注框畫出來肉眼檢查。這個(gè)步驟別省我見過太多人訓(xùn)練半天最后發(fā)現(xiàn)是坐標(biāo)歸一化算錯(cuò)了所有框的位置都是歪的。2.3 數(shù)據(jù)劃分與目錄結(jié)構(gòu)YOLOv5對數(shù)據(jù)集目錄結(jié)構(gòu)的要求是固定的官方推薦的結(jié)構(gòu)是datasets/ship/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/注意圖片和標(biāo)注文件的文件名必須一一對應(yīng)比如00001.jpg對應(yīng)00001.txt。劃分比例一般用8:2或者9:1訓(xùn)練集和驗(yàn)證集要確保分布一致比如同一個(gè)港口的圖片不能全跑進(jìn)訓(xùn)練集否則驗(yàn)證集上看到的全是“熟悉”的場景指標(biāo)會虛高。這里有個(gè)常用的劃分腳本思路import os import random import shutil random.seed(42) image_dir all_images label_dir all_labels train_ratio 0.8 images [f for f in os.listdir(image_dir) if f.endswith(.jpg)] random.shuffle(images) split_idx int(len(images) * train_ratio) for i, img in enumerate(images): src_img os.path.join(image_dir, img) src_lbl os.path.join(label_dir, img.replace(.jpg, .txt)) if i split_idx: dst_img os.path.join(datasets/ship/images/train, img) dst_lbl os.path.join(datasets/ship/labels/train, img.replace(.jpg, .txt)) else: dst_img os.path.join(datasets/ship/images/val, img) dst_lbl os.path.join(datasets/ship/labels/val, img.replace(.jpg, .txt)) shutil.copy(src_img, dst_img) shutil.copy(src_lbl, dst_lbl)注意劃分的時(shí)候不要只shuffle文件名后直接切要確認(rèn)沒有同名文件殘留。跑完之后檢查一下train和val的圖片數(shù)量比例是否符合預(yù)期。3. 訓(xùn)練前的工程準(zhǔn)備3.1 環(huán)境配置要點(diǎn)YOLOv5的環(huán)境配置沒有太多玄學(xué)PyTorch、CUDA、cuDNN版本匹配好就行。我建議直接創(chuàng)建一個(gè)干凈的conda環(huán)境Python用3.8或者3.9PyTorch選擇與顯卡驅(qū)動匹配的版本。說一個(gè)實(shí)操細(xì)節(jié)裝PyTorch的時(shí)候用官方源或者鏡像源不要在pip默認(rèn)源硬啃幾個(gè)G的包容易中途失敗或者慢到懷疑人生。YOLOv5倉庫本身依賴不多pip install -r requirements.txt就夠了。如果你打算訓(xùn)練時(shí)用WB或者TensorbBoard看曲線記得把對應(yīng)的依賴一起裝上。這塊沒什么坑但顯卡驅(qū)動的CUDA版本和PyTorch要求的CUDA版本不匹配是新手最容易卡殼的地方。3.2 data.yaml與模型選擇YOLOv5的數(shù)據(jù)配置靠一個(gè)YAML文件搞定。艦船檢測的data.yaml長這樣train: datasets/ship/images/train val: datasets/ship/images/val nc: 1 names: [ship]如果你的數(shù)據(jù)集是區(qū)分船型的比如貨船、漁船、客輪三類那就改成nc: 3names列表對應(yīng)順序?qū)懻_。這里有個(gè)很多人會忽略的細(xì)節(jié)——names的順序必須和標(biāo)注txt文件里的類別id完全一致。如果訓(xùn)練時(shí)發(fā)現(xiàn)類別標(biāo)簽錯(cuò)亂先檢查這里。模型規(guī)格方面YOLOv5提供了n/s/m/l/x幾個(gè)檔位。艦船檢測這種場景輸入圖片分辨率一般是640x640或者1280x1280。如果是邊緣設(shè)備部署建議用s模型起步參數(shù)量適中精度也夠如果是論文刷指標(biāo)m或者l模型上限更高。我之前對比過s和m在同一批艦船數(shù)據(jù)上的表現(xiàn)m的mAP50大約能提升2到3個(gè)百分點(diǎn)但推理速度下降40%左右。這個(gè)取舍要看你的落地場景沒有標(biāo)準(zhǔn)答案。3.3 先跑通再上量我強(qiáng)烈建議不要一上來就全量數(shù)據(jù)、大批次直接開訓(xùn)。正確做法是先用一個(gè)非常小的配置——幾十張圖、幾個(gè)epoch——把整個(gè)流程跑通確認(rèn)沒有路徑錯(cuò)誤、顯存爆掉、維度不匹配這類問題。這個(gè)小規(guī)模驗(yàn)證通常只需要十幾分鐘能幫你省下非常多排查時(shí)間。具體來說你可以在命令行中指定--epochs 3 --batch-size 4觀察一下訓(xùn)練能否正常啟動、loss是否在下降、驗(yàn)證集指標(biāo)是否有輸出。跑通之后再改成正式參數(shù)。這一步很多人看不上但我在實(shí)際項(xiàng)目里靠它躲過了好幾次“訓(xùn)練兩小時(shí)失敗重來”的悲劇。4. 訓(xùn)練全流程與調(diào)參心得4.1 關(guān)鍵超參數(shù)怎么定YOLOv5訓(xùn)練時(shí)的超參數(shù)主要在兩個(gè)地方命令行參數(shù)和hyp.scratch.yaml。命令行參數(shù)里最核心的幾個(gè)是--img、--batch、--epochs、--weights。輸入分辨率--img直接影響檢測精度和速度。對于艦船檢測我的建議是不要低于640。艦船目標(biāo)往往比較小尤其遙感影像里普通的近岸監(jiān)控畫面還好遙感圖上一艘船可能就幾十個(gè)像素640以下的輸入會把小目標(biāo)細(xì)節(jié)全部抹掉。如果顯卡允許用1280效果明顯更好但訓(xùn)練時(shí)間和顯存占用會大幅上升。--batch的大小受顯存限制。一張RTX 309024GB顯存YOLOv5s在img640時(shí)batch可以開到32甚至更大如果顯存不夠優(yōu)先降低batch而不是降低分辨率。batch太小會導(dǎo)致梯度噪聲大收斂不穩(wěn)定尤其艦船這種目標(biāo)尺度差異明顯的任務(wù)太小的batch會讓模型學(xué)到不穩(wěn)定的特征。--epochs的設(shè)置要看data規(guī)模。幾千張數(shù)據(jù)的情況下100到150個(gè)epoch是合理的區(qū)間。我通常的做法是先訓(xùn)100個(gè)epoch觀察驗(yàn)證集mAP的趨勢如果到后期還在穩(wěn)步上升就追加訓(xùn)練。YOLOv5支持在已有權(quán)重上繼續(xù)訓(xùn)練--weights指定到上次訓(xùn)練的last.pt--resume可以自動恢復(fù)。學(xué)習(xí)率方面YOLOv5在yolov5s.pt預(yù)訓(xùn)練權(quán)重基礎(chǔ)上繼續(xù)訓(xùn)練時(shí)默認(rèn)的0.01初始學(xué)習(xí)率是合理的選擇。如果你是加載自己的模型繼續(xù)訓(xùn)練建議把lr調(diào)到0.001以下避免破壞已學(xué)到的特征。4.2 訓(xùn)練過程監(jiān)控與斷點(diǎn)恢復(fù)訓(xùn)練啟動后終端會輸出每個(gè)epoch的box_loss、cls_loss、obj_loss和驗(yàn)證集指標(biāo)。我的習(xí)慣是重點(diǎn)看兩個(gè)指標(biāo)訓(xùn)練時(shí)的box_loss和驗(yàn)證集的mAP50。box_loss持續(xù)下降說明模型在學(xué)mAP50整體上升說明學(xué)的東西有用。如果loss下降但mAP紋絲不動大概率是數(shù)據(jù)標(biāo)注有問題或者類別定義模糊。TensorbBoard在這里幫了大忙。--project和--name參數(shù)可以指定輸出目錄訓(xùn)練日志和驗(yàn)證圖片都會自動保存。我經(jīng)常干的一件事是去驗(yàn)證結(jié)果里翻圖片看模型預(yù)測的框和真實(shí)標(biāo)注的差異。這種直觀觀察比看曲線更能發(fā)現(xiàn)問題。比如模型總是漏檢遠(yuǎn)處的小船或者總是把碼頭的起重機(jī)誤檢成船這些信息直接決定了后續(xù)優(yōu)化方向。務(wù)必養(yǎng)成斷點(diǎn)恢復(fù)的習(xí)慣。YOLOv5每次epoch結(jié)束都會保存last.pt和best.ptbest.pt是驗(yàn)證集mAP最高的權(quán)重。如果訓(xùn)練中途斷了用下面這個(gè)命令可以恢復(fù)python train.py --resume runs/train/exp/weights/last.pt省一次重新訓(xùn)練的時(shí)間就多一次調(diào)參的機(jī)會。4.3 指標(biāo)解讀P、R、mAP50、mAP50-95訓(xùn)練結(jié)束時(shí)驗(yàn)證集上會輸出四個(gè)核心指標(biāo)。Precision代表查準(zhǔn)率——模型檢出來的框里有多少確實(shí)是船Recall代表查全率——真實(shí)的船里面有多少被模型檢出來了。mAP50是IoU閾值0.5下的平均精度這是最常用的評價(jià)指標(biāo)mAP50-95是多個(gè)IoU閾值下的平均更能反映定位精度。艦船檢測的特殊性在于不同場景對P和R的側(cè)重不一樣。航道監(jiān)控里漏檢一艘船可能是安全事故所以R的優(yōu)先級更高但如果是港口流量統(tǒng)計(jì)誤檢太多會干擾統(tǒng)計(jì)結(jié)果P就更重要。調(diào)節(jié)置信度閾值--conf-thres可以直接控制這個(gè)平衡調(diào)低閾值可以提高召回率代價(jià)是誤檢變多調(diào)高閾值則反過來。部署階段的閾值和訓(xùn)練階段的默認(rèn)值可以分開調(diào)不用受訓(xùn)練設(shè)置限制。5. 艦船檢測常見問題與排查記錄5.1 典型故障速查表這里整理了我自己在艦船檢測項(xiàng)目中遇到的高頻問題以及對應(yīng)的排查思路和解決辦法。問題現(xiàn)象可能原因排查方法解決建議訓(xùn)練時(shí)loss不下降或反而上升學(xué)習(xí)率過大/數(shù)據(jù)標(biāo)注錯(cuò)亂查看loss曲線抽查標(biāo)注可視化調(diào)低初始學(xué)習(xí)率重新檢查數(shù)據(jù)集mAP50低但訓(xùn)練loss正常驗(yàn)證集與訓(xùn)練集分布差異大查看驗(yàn)證集的圖片構(gòu)成重新劃分?jǐn)?shù)據(jù)集確保分布一致小目標(biāo)艦船大量漏檢輸入分辨率不足/標(biāo)注框過小統(tǒng)計(jì)目標(biāo)框的像素尺寸提高img到1280或使用SAHI切片推理顯存不足OOMbatch過大或分辨率過高觀察顯存占用減小batch開啟梯度累積誤檢碼頭、島嶼等背景訓(xùn)練數(shù)據(jù)中背景單一檢查負(fù)樣本是否充足增加無目標(biāo)的純背景圖片作為負(fù)樣本訓(xùn)練到后期P高R低置信度過高攔截了低分目標(biāo)測試不同conf-thres下的結(jié)果部署時(shí)適當(dāng)降低置信度閾值第二行說的情況我踩過最大的跟頭。有次用了一個(gè)港口的視頻截幀做驗(yàn)證訓(xùn)練集是另一批近海航行的圖片兩個(gè)場景在光照、背景、目標(biāo)尺度上都差很多訓(xùn)練了100個(gè)epoch訓(xùn)練集loss已經(jīng)很低驗(yàn)證集mAP卻一直卡在0.3。最后重新按場景混合劃分?jǐn)?shù)據(jù)同樣配置下mAP直接翻倍。5.2 數(shù)據(jù)增強(qiáng)導(dǎo)致的兩個(gè)特殊坑艦船檢測里數(shù)據(jù)增強(qiáng)有一正一反兩個(gè)坑要特別注意。正面的坑是過度使用旋轉(zhuǎn)增強(qiáng)。艦船目標(biāo)有明確的方向性船頭和船尾的特征差異大如果你把圖片旋轉(zhuǎn)90度或180度當(dāng)做新的訓(xùn)練樣本模型需要額外學(xué)習(xí)所有朝向。這本身不是壞事但如果驗(yàn)證集里全是統(tǒng)一朝向的圖片比如都是船頭朝左訓(xùn)練結(jié)果會在驗(yàn)證集上表現(xiàn)虛高部署到實(shí)際場景又崩掉。正確做法是根據(jù)真實(shí)應(yīng)用場景決定是否用旋轉(zhuǎn)增強(qiáng)——監(jiān)控場景攝像頭固定不需要旋轉(zhuǎn)遙感影像方向隨機(jī)旋轉(zhuǎn)增強(qiáng)就能明顯提升泛化。反面的坑是mosaic增強(qiáng)導(dǎo)致小目標(biāo)信息丟失。YOLOv5默認(rèn)開啟mosaic它會把四張圖拼在一起同時(shí)做隨機(jī)縮放。對艦船這種目標(biāo)小、數(shù)量密集的任務(wù)mosaic縮放后小船的像素尺寸可能只剩十幾個(gè)模型根本學(xué)不到有效特征。如果發(fā)現(xiàn)小目標(biāo)檢測效果差先檢查訓(xùn)練時(shí)mosaic增強(qiáng)是不是一直都在開啟狀態(tài)訓(xùn)練后期可以關(guān)掉mosaic只用普通增強(qiáng)精調(diào)。YOLOv5在epochs的最后10到20個(gè)epoch會自動關(guān)閉mosaic這個(gè)機(jī)制對艦船這類小目標(biāo)密集任務(wù)非常重要。5.3 推理階段的兩個(gè)實(shí)用建議部署推理時(shí)我額外推薦兩個(gè)做法。第一個(gè)是使用SAHI切片推理。艦船檢測尤其適用于大圖中小目標(biāo)的場景——一張遙感大圖4096x4096直接resize到640再推理小船早就糊成幾個(gè)像素了。SAHI的思路是把大圖切成小塊每塊獨(dú)立推理再合并結(jié)果。如果你的數(shù)據(jù)來源是大尺寸遙感影像SAHI的提升是質(zhì)的飛躍甚至不需要重新訓(xùn)練模型。第二個(gè)是合理處理重疊檢測框。艦船密集??康母劭趫鼍爸邢噜彺坏臋z測框很容易重疊。NMS的IoU閾值默認(rèn)是0.45如果發(fā)現(xiàn)兩艘靠得很近的船被合并成一個(gè)框適當(dāng)調(diào)低NMS的IoU閾值到0.3左右試試反過來如果一艘船被拆成多個(gè)框就把閾值調(diào)高一點(diǎn)。這個(gè)參數(shù)改起來非常快卻能解決很多視覺形態(tài)上“臟亂差”的問題。最后再分享一點(diǎn)個(gè)人經(jīng)驗(yàn)。這類項(xiàng)目型任務(wù)數(shù)據(jù)準(zhǔn)備階段的時(shí)間至少要占整個(gè)項(xiàng)目周期的60%。模型結(jié)構(gòu)、訓(xùn)練參數(shù)這些都可以在幾天內(nèi)調(diào)整到位但數(shù)據(jù)的清洗、篩選、格式轉(zhuǎn)換、質(zhì)量抽查一個(gè)都省不了。艦船檢測的各種公開baseline已經(jīng)很成熟你面對的真正難題永遠(yuǎn)是“數(shù)據(jù)長什么樣模型就學(xué)成什么樣”。把幾千張數(shù)據(jù)整理到標(biāo)注精準(zhǔn)、場景均衡、格式統(tǒng)一你的模型就已經(jīng)贏了大半。本文還有配套的精品資源點(diǎn)擊獲取