據(jù)集解析與訓(xùn)練實戰(zhàn))
簡介目標(biāo)檢測是計算機(jī)視覺領(lǐng)域的核心任務(wù)之一在遙感圖像分析中具有廣泛應(yīng)用。遙感影像通常視場大、目標(biāo)尺度小工業(yè)設(shè)施如煙囪等對象往往僅占數(shù)十像素給檢測算法帶來嚴(yán)峻挑戰(zhàn)。YOLOv8作為當(dāng)前主流的單階段檢測框架憑借高效的特征提取與靈活的部署能力成為小目標(biāo)檢測任務(wù)中的常用基線。通過構(gòu)建規(guī)范的數(shù)據(jù)集并進(jìn)行格式轉(zhuǎn)換、數(shù)據(jù)校驗與訓(xùn)練調(diào)參可以系統(tǒng)評估模型性能并優(yōu)化檢測精度。本文以一份包含854張遙感圖像的煙囪檢測數(shù)據(jù)集為例介紹VOC與YOLO格式的組織結(jié)構(gòu)、小樣本場景下的訓(xùn)練策略及常見問題排查方法為遙感目標(biāo)檢測的工程實踐提供參考。 拿到這份854張的遙感圖像煙囪檢測數(shù)據(jù)集時我的第一反應(yīng)是終于有人把這類偏門目標(biāo)整理成標(biāo)準(zhǔn)格式了。做遙感目標(biāo)檢測的同行應(yīng)該都有體會公開數(shù)據(jù)集里翻來覆去就是飛機(jī)、船舶、車輛、油罐那幾類煙囪這種偏向工業(yè)設(shè)施的目標(biāo)想找一份現(xiàn)成的、帶完整標(biāo)注的數(shù)據(jù)只能靠運氣。我花了一整天時間把這份數(shù)據(jù)集完整跑了一遍從格式解析、數(shù)據(jù)校驗到基于YOLOv8的訓(xùn)練和推理把整個流程和踩過的坑都記錄下來。這份內(nèi)容適合兩類人一是剛接觸遙感目標(biāo)檢測、想用現(xiàn)成數(shù)據(jù)快速上手YOLO訓(xùn)練流程的初學(xué)者二是已經(jīng)在做遙感檢測、正在發(fā)愁缺少小樣本類別數(shù)據(jù)的研究者和工程師。我會從數(shù)據(jù)集結(jié)構(gòu)說起一直講到模型訓(xùn)練和推理實測盡量把細(xì)節(jié)講透。1. 拿到手先解析這份煙囪檢測數(shù)據(jù)集到底是什么1.1 壓縮包內(nèi)部結(jié)構(gòu)與標(biāo)注文件解剖這個.7z壓縮包解壓后典型的目錄結(jié)構(gòu)會包含VOC和YOLO兩套組織方式。VOC格式目錄下通常是JPEGImages存放全部854張遙感圖像Annotations里是對應(yīng)的.xml標(biāo)注文件ImageSets/Main下面則是train.txt、val.txt這類劃分文件。YOLO格式目錄則是images和labels兩個文件夾images里同樣存放圖像labels里是每個圖像對應(yīng)的.txt標(biāo)注文件。兩套格式共用同一批原始圖像只是標(biāo)注信息的組織方式不同。用文本編輯器打開VOC格式的XML文件能看到典型的annotation根節(jié)點里面包含size信息記錄圖像的寬度、高度和通道數(shù)然后是一個或多個object節(jié)點。每個object里有namechimney/name這樣的類別名稱還有bndbox節(jié)點下的xmin、ymin、xmax、ymax四個坐標(biāo)值。這就是VOC格式的核心用絕對像素坐標(biāo)記錄每個目標(biāo)的邊界框坐標(biāo)是整數(shù)單位是圖像的原始像素。再看YOLO格式的txt文件內(nèi)容格式是每行一個目標(biāo)五個數(shù)字依次是class_id x_center y_center width height。關(guān)鍵區(qū)別是坐標(biāo)和寬高都是相對值全部歸一化到0到1之間class_id從0開始計數(shù)。如果這個數(shù)據(jù)集只有煙囪這一個類別那這個class_id就是0。計算方式也很簡單x_center (xmin xmax) / 2 / image_widthy_center (ymin ymax) / 2 / image_heightwidth (xmax - xmin) / image_widthheight (ymax - ymin) / image_height。1.2 VOC和YOLO兩種格式到底選哪個用VOC格式是目標(biāo)檢測領(lǐng)域的老牌標(biāo)準(zhǔn)它的優(yōu)勢在于信息完整、結(jié)構(gòu)清晰XML文件里不僅記錄了目標(biāo)框的位置還能追加pose、truncated、difficult等附加屬性適合需要精細(xì)標(biāo)注信息的場景。但缺點也很明顯解析XML比解析txt慢占用的存儲空間更大而且很多現(xiàn)代訓(xùn)練框架不會直接消費XML文件需要先轉(zhuǎn)換成其他格式。YOLO格式則是當(dāng)前深度學(xué)習(xí)訓(xùn)練的主流格式每個標(biāo)注文件就是幾行文本讀取效率高解析邏輯簡單Ultralytics YOLO系列、MMDetection的YOLO系算法都能直接使用。缺點是信息比較單薄沒有額外的屬性描述所有標(biāo)注只有一個類別編號和四個歸一化坐標(biāo)值。所以這份數(shù)據(jù)集同時提供兩種格式本質(zhì)上是在照顧不同使用習(xí)慣的人群習(xí)慣傳統(tǒng)VOC流程的可以用XML做數(shù)據(jù)分析和精細(xì)處理直接跑深度學(xué)習(xí)訓(xùn)練的就用YOLO格式省去轉(zhuǎn)換步驟。1.3 這份數(shù)據(jù)適合做什么不適合做什么從數(shù)據(jù)規(guī)模來看854張圖像、單一類別屬于典型的小樣本數(shù)據(jù)集。這種規(guī)模適合做入門學(xué)習(xí)、算法驗證、可行性預(yù)研也適合作為預(yù)訓(xùn)練基礎(chǔ)配合其它遙感數(shù)據(jù)做領(lǐng)域微調(diào)。比如你想跑通YOLOv8的訓(xùn)練流程、理解數(shù)據(jù)標(biāo)注格式轉(zhuǎn)換、驗證小目標(biāo)檢測算法在工業(yè)場景下的效果這份數(shù)據(jù)完全夠用。但要說明白854張圖的量級想把模型練出很強(qiáng)的泛化能力是不夠的。如果目標(biāo)場景是高空大視角下密集排列的工業(yè)廠區(qū)煙囪或者需要適配多種衛(wèi)星傳感器不同分辨率、不同波段的影像這份數(shù)據(jù)只能作為起點還需要補(bǔ)充更多樣本、做數(shù)據(jù)增強(qiáng)、加入其它遙感數(shù)據(jù)集聯(lián)合訓(xùn)練。另外這份數(shù)據(jù)的圖像來源、分辨率、標(biāo)注質(zhì)量需要你先做一輪檢查我在第4部分會詳細(xì)講檢查方法和常見問題。2. 遙感圖像里的煙囪檢測難點到底在哪2.1 遙感目標(biāo)檢測和普通圖像檢測本質(zhì)差異是什么常規(guī)的目標(biāo)檢測任務(wù)比如相機(jī)拍攝的街景、室內(nèi)照片物體通常占畫面比例較大、紋理豐富、背景相對單一。遙感圖像完全不同視角是俯視的目標(biāo)尺度跨度極大一個煙囪在整幅圖上可能只有幾十個像素甚至十幾個像素。很多時候一張2048x2048的遙感圖里煙囪只占其中很小的區(qū)域這就帶來了嚴(yán)重的小目標(biāo)檢測問題。小目標(biāo)在特征提取層面非常吃虧。以YOLO系列為例下采樣倍數(shù)通常是32倍一個20x20像素的煙囪經(jīng)過特征提取后只剩不到1個像素的信息量幾乎完全丟失了細(xì)節(jié)特征。所以遙感檢測領(lǐng)域普遍會采用兩種策略一是用更大分辨率的輸入圖訓(xùn)練比如把訓(xùn)練尺寸從640提高到960甚至1280二是用切圖策略把大幅遙感圖切成小塊比如切成512x512的patch再逐個檢測最后把結(jié)果映射回原圖坐標(biāo)。這兩種方式在后續(xù)訓(xùn)練實操中我都會演示。還有一個本質(zhì)差異是方向性問題。自然圖像的目標(biāo)大多是正立的比如人、車、貓狗水平框就夠了。遙感圖像里煙囪如果是從側(cè)面拍到的常見的也還是豎立姿態(tài)水平檢測框勉強(qiáng)夠用。但如果影像里出現(xiàn)沿不同方向分布的塔式煙囪、電廠冷卻塔群水平框會引入大量背景區(qū)域這時候旋轉(zhuǎn)框檢測OBB方案會更合適比如MMRotate框架或者YOLOv8-OBB版本。不過這份數(shù)據(jù)集的標(biāo)注是VOC和YOLO兩種格式的水平框所以優(yōu)先用水平框檢測方案旋轉(zhuǎn)框作為后續(xù)擴(kuò)展方向。2.2 煙囪這個目標(biāo)本身有什么特殊之處煙囪在遙感圖像里有幾個顯著特征。首先是顏色紋理比較特殊工業(yè)煙囪通常是混凝土灰色、紅白相間或金屬深色和周圍建筑、植被、裸地都有一定區(qū)分度但也容易出現(xiàn)與水泥建筑、道路顏色相近的情況。其次是形態(tài)特征從高空俯視時獨立煙囪呈現(xiàn)圓形或橢圓形的頂端輪廓帶有環(huán)形陰影從側(cè)面視角看則是高瘦的矩形柱體長寬比很大。再說說檢測中的實際問題。煙囪往往會和廠房、冷卻塔、鍋爐房等建筑密集排列目標(biāo)之間互相遮擋、粘連檢測框容易出現(xiàn)重疊和漏檢。還有就是正負(fù)樣本不均衡的問題854張圖里如果只有1000多個煙囪實例而背景區(qū)域占了絕大部分模型很容易學(xué)到背景占多數(shù)的偏見導(dǎo)致誤檢率偏高。解決思路通常是調(diào)整損失函數(shù)中的正負(fù)樣本權(quán)重或者通過難例挖掘來強(qiáng)化模型對煙囪特征的記憶。2.3 為什么這種數(shù)據(jù)集稀缺它的價值在哪冷門目標(biāo)數(shù)據(jù)集稀缺的原因很現(xiàn)實采集和標(biāo)注的成本太高。遙感圖像的獲取本身就有門檻要么用公開衛(wèi)星影像挑選含煙囪的區(qū)域要么用無人機(jī)航拍都需要大量人工篩選。標(biāo)注階段更費神遙感圖像里煙囪尺度小、數(shù)量多標(biāo)注員需要放大圖像仔細(xì)觀察才能準(zhǔn)確框出目標(biāo)一幀圖標(biāo)注下來可能比普通圖像多花三四倍時間。而且煙囪在不同工業(yè)場景下的形態(tài)差異大負(fù)責(zé)標(biāo)注的人如果沒有一定行業(yè)知識很容易漏標(biāo)、錯標(biāo)。所以能有人把煙囪這類目標(biāo)做成公開的標(biāo)準(zhǔn)格式數(shù)據(jù)集價值是很明顯的。一方面省去了重復(fù)采集標(biāo)注的時間可以直接用來驗證算法另一方面它是小樣本遙感檢測的絕佳試驗場你可以在這個基礎(chǔ)上測試各種數(shù)據(jù)增強(qiáng)、小目標(biāo)檢測改進(jìn)、半監(jiān)督方案快速得到可對比的基線結(jié)果。3. 從數(shù)據(jù)集到模型基于YOLOv8的完整訓(xùn)練實操3.1 環(huán)境準(zhǔn)備與數(shù)據(jù)集校驗先說環(huán)境。我訓(xùn)練用的機(jī)器是單張RTX 3090顯卡顯存24GB系統(tǒng)是Ubuntu 20.04Python版本3.9。深度學(xué)習(xí)框架選擇Ultralytics YOLOv8直接通過pip安裝pip install ultralytics裝完之后可以先驗證下環(huán)境是否正常yolo predict modelyolov8n.pt sourcehttps://ultralytics.com/images/bus.jpg能順利輸出預(yù)測結(jié)果圖片說明環(huán)境沒問題。接下來把數(shù)據(jù)集壓縮包解壓我習(xí)慣放在項目目錄下的datasets文件夾里mkdir -p ~/projects/chimney_detection/datasets cd ~/projects/chimney_detection/datasets 7z x 遙感圖像煙囪檢測數(shù)據(jù)集VOCYOLO格式854張1類別.7z解壓后先別急著訓(xùn)練花15分鐘檢查數(shù)據(jù)質(zhì)量。這一步非常關(guān)鍵批量轉(zhuǎn)換過的數(shù)據(jù)集、尤其是從網(wǎng)上分享渠道來的數(shù)據(jù)經(jīng)常有各種隱蔽問題。我的檢查清單是這樣的每張圖像是否有對應(yīng)的標(biāo)注文件用腳本統(tǒng)計圖像和標(biāo)注文件數(shù)量是否一致標(biāo)注文件是否為空有些圖像可能沒有任何目標(biāo)過濾時要注意保留空標(biāo)簽的對應(yīng)關(guān)系XML中的name字段是否統(tǒng)一比如chimney和Chimney會被認(rèn)為是兩個類別YOLO格式txt里的坐標(biāo)值是否都在0到1之間有沒有超出邊界的異常值圖像是否能正常打開是否有損壞文件我用一段簡單的Python腳本快速檢查YOLO標(biāo)簽的合法性import os labels_dir yolo_labels error_files [] for f in os.listdir(labels_dir): if not f.endswith(.txt): continue path os.path.join(labels_dir, f) with open(path, r) as fp: lines fp.readlines() for line in lines: parts line.strip().split() if len(parts) ! 5: error_files.append((f, 字段數(shù)量不正確)) continue try: cls_id, x, y, w, h map(float, parts) except ValueError: error_files.append((f, 數(shù)值解析失敗)) continue if cls_id ! 0: error_files.append((f, f類別編號異常: {cls_id})) if not (0 x 1 and 0 y 1 and 0 w 1 and 0 h 1): error_files.append((f, f坐標(biāo)越界: {line.strip()})) if error_files: for item in error_files[:20]: print(item) print(f共發(fā)現(xiàn) {len(error_files)} 個異常) else: print(標(biāo)簽檢查通過)這個腳本跑完有異常就能立刻定位。在我實跑的過程中發(fā)現(xiàn)有一小部分txt文件存在多余空格和換行的問題雖然Ultralytics的解析器能容忍但保險起見統(tǒng)一做了清洗把連續(xù)空格替換成單個空格去掉空行。3.2 目錄組織與YAML配置Ultralytics YOLOv8對數(shù)據(jù)集的目錄結(jié)構(gòu)有固定要求把數(shù)據(jù)整理成如下結(jié)構(gòu)datasets/ └── chimney/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/也就是說需要在images和labels下面分別建立train、val、test子目錄同一張圖的圖像和標(biāo)簽文件名必須一一對應(yīng)。我是按照7:2:1的比例隨機(jī)劃分的訓(xùn)練集598張、驗證集171張、測試集85張。劃分的時候用腳本確保圖像和標(biāo)簽同步移動避免出現(xiàn)圖像有但標(biāo)簽沒有的情況。下面是一個簡單的劃分腳本思路import os import random import shutil images sorted(os.listdir(yolo_images)) random.seed(42) random.shuffle(images) total len(images) train_cnt int(total * 0.7) val_cnt int(total * 0.2) split {} for i, img in enumerate(images): if i train_cnt: split[img] train elif i train_cnt val_cnt: split[img] val else: split[img] test for img, subset in split.items(): src_img os.path.join(yolo_images, img) dst_img os.path.join(chimney/images, subset, img) os.makedirs(os.path.dirname(dst_img), exist_okTrue) shutil.copy(src_img, dst_img) label_name img.replace(.jpg, .txt).replace(.png, .txt) src_lbl os.path.join(yolo_labels, label_name) if os.path.exists(src_lbl): dst_lbl os.path.join(chimney/labels, subset, label_name) shutil.copy(src_lbl, dst_lbl)然后寫數(shù)據(jù)集配置文件chimney.yamlpath: /home/yourname/projects/chimney_detection/datasets/chimney train: images/train val: images/val test: images/test nc: 1 names: 0: chimneypath字段建議寫絕對路徑避免相對路徑解析錯亂。nc是類別數(shù)這里只有1個names從0開始映射類別名。3.3 訓(xùn)練命令與關(guān)鍵參數(shù)選擇數(shù)據(jù)配置完成直接啟動訓(xùn)練yolo train datachimney.yaml modelyolov8s.pt epochs100 batch16 imgsz640 device0我選擇的是yolov8s.pt預(yù)訓(xùn)練權(quán)重基于COCO數(shù)據(jù)集的預(yù)訓(xùn)練模型做遷移學(xué)習(xí)。為什么不直接從頭訓(xùn)練因為數(shù)據(jù)量只有854張從頭訓(xùn)練特征提取器根本學(xué)不夠預(yù)訓(xùn)練權(quán)重已經(jīng)學(xué)會了通用的邊緣、紋理、形狀特征只需要在煙囪這個特定類別上微調(diào)收斂速度和精度都能大幅提升。參數(shù)選擇上有幾個細(xì)節(jié)值得說。imgsz640這個是輸入圖像的訓(xùn)練分辨率。我在實跑中發(fā)現(xiàn)對于這份遙感數(shù)據(jù)集640是一個偏保守的設(shè)定。因為煙囪目標(biāo)普遍偏小用640訓(xùn)練時很多目標(biāo)在特征圖上的響應(yīng)非常弱。后來我嘗試把imgsz提高到960mAP50提升了大概5到8個百分點。代價是顯存占用和訓(xùn)練時間增加單卡3090跑960輸入、batch16顯存快接近20GB了。如果你的顯卡顯存不夠可以把batch降到8或者先用640跑通基線再基于模型微調(diào)時提高分辨率。epochs100對小數(shù)據(jù)集來說是夠用的甚至有些過擬合風(fēng)險。我觀察訓(xùn)練日志大約在50到70個epoch后驗證集的mAP曲線就開始趨于平緩說明模型已經(jīng)收斂。如果追求更快的迭代驗證可以先用50個epoch跑通全流程確認(rèn)一切正常后再跑完整的100個epoch。batch16在3090上比較合適過大的batch在小數(shù)據(jù)集上會加劇過擬合尤其是單一類別且域內(nèi)圖像分布接近的情況。還有一個建議訓(xùn)練時加上patience30這個參數(shù)開啟Early Stopping。這樣當(dāng)驗證集指標(biāo)連續(xù)30個epoch沒有提升時訓(xùn)練會自動停止避免無效的長時間訓(xùn)練對節(jié)省時間非常有幫助。命令行可以寫yolo train datachimney.yaml modelyolov8s.pt epochs100 batch16 imgsz640 device0 patience303.4 訓(xùn)練過程日志解讀與結(jié)果評估訓(xùn)練過程中終端會實時打印每個epoch的loss和指標(biāo)值得關(guān)注的包括box_loss、cls_loss、dfl_loss以及precision、recall、mAP50、mAP50-95這四項評價指標(biāo)。mAP50是IoU閾值為0.5時的平均精度均值mAP50-95則是從0.5到0.95每隔0.05取一次IoU閾值計算的平均值后者更嚴(yán)格、更能反映模型的定位精度。我這次訓(xùn)練的最終結(jié)果大概在mAP500.87、mAP50-950.52左右。單類別檢測能到0.87的mAP50說明這個數(shù)據(jù)集本身標(biāo)注質(zhì)量不錯、目標(biāo)特征也比較明確模型基本學(xué)會了煙囪的判別特征。但mAP50-95只有0.52說明框的定位精度還不算高大一些的目標(biāo)檢測框和真實框的重合度還不夠。這個結(jié)果其實反映了遙感小目標(biāo)檢測的典型特征分類容易、定位難。后續(xù)如果要提升定位精度可以嘗試更高分辨率訓(xùn)練、加入更精細(xì)的損失函數(shù)設(shè)計或者做目標(biāo)切片檢測。訓(xùn)練完成后模型權(quán)重保存在runs/detect/train/weights/目錄下best.pt是驗證集指標(biāo)最好的權(quán)重last.pt是最后一個epoch的權(quán)重。推理時優(yōu)先用best.pt。目錄下還有confusion_matrix.png、results.png、PR_curve.png等可視化結(jié)果可以直觀檢查模型的錯誤類型。比如混淆矩陣?yán)锶绻尘邦惐活A(yù)測為煙囪的比例偏高就是誤檢嚴(yán)重如果煙囪被預(yù)測為背景的比例高就是漏檢嚴(yán)重。我看了一下我的混淆矩陣漏檢還是主要問題這和遙感圖像小目標(biāo)占比高是一致的。模型訓(xùn)練完可以用測試集評估一下最終效果yolo val modelruns/detect/train/weights/best.pt datachimney.yaml splittest然后做一次實際推理生成帶檢測框的可視化結(jié)果yolo predict modelruns/detect/train/weights/best.pt source/path/to/test/images saveTrue conf0.25conf0.25是置信度閾值低于0.25的預(yù)測框會被過濾掉。遙感小目標(biāo)檢測中這個閾值可以適當(dāng)調(diào)低到0.15左右因為小目標(biāo)的置信度天然偏低閾值設(shè)太高容易漏檢。但調(diào)低也會引入更多誤檢需要根據(jù)自己的場景權(quán)衡。4. 訓(xùn)練過程中的常見報錯與排查實錄4.1 標(biāo)簽解析報錯類別編號和文件路徑的坑訓(xùn)練啟動時最容易遇到的一類報錯是標(biāo)簽解析異常。常見表現(xiàn)是控制臺出現(xiàn)一堆WARNING: skipping label之類的提示說明某個標(biāo)簽文件內(nèi)容不合法被Ultralytics跳過了。最常見的原因有三個。第一個原因是標(biāo)簽文件里出現(xiàn)了超出類別數(shù)的class_id。比如配置文件里nc1說明合法類別編號只有0如果標(biāo)簽文件里寫了1就會報錯。這類情況通常是格式轉(zhuǎn)換時類別映射出了問題比如轉(zhuǎn)換腳本用字典按名稱排序分配編號排序后編號對不上原始類別順序。排查方法是跑一遍前面那個標(biāo)簽檢查腳本把所有非0的class_id找出來。第二個原因是路徑配錯了導(dǎo)致訓(xùn)練時找不到圖像或標(biāo)簽。一個容易踩的坑是YAML配置里的path用了相對路徑而當(dāng)前工作目錄和YAML文件不在同一個層級路徑就失效了。最穩(wěn)妥的辦法是直接用絕對路徑或者把YAML文件放到數(shù)據(jù)集根目錄下用path: .。第三個原因是中文字符路徑。如果項目路徑或者圖像文件名里帶中文某些環(huán)境下OpenCV和NumPy讀取會出問題報Unable to read image之類的錯誤。這不是數(shù)據(jù)本身的問題是環(huán)境對非ASCII字符支持不完善。解決辦法就是把整個項目遷移到純英文路徑下文件名也改成英文字母加數(shù)字的組合。4.2 小目標(biāo)檢測效果差遙感數(shù)據(jù)的致命痛點如果你訓(xùn)練完去測試發(fā)現(xiàn)大煙囪檢測得很好但小煙囪幾乎全部漏檢恭喜你遇到了遙感目標(biāo)檢測最典型的問題。這不是模型笨而是小目標(biāo)經(jīng)過多次下采樣后在特征圖上的信息量已經(jīng)所剩無幾。解決方向有三個我按收益從高到低排列。第一是用更高分辨率訓(xùn)練。在顯存允許的情況下把imgsz從640提升到960甚至1280相當(dāng)于直接放大了目標(biāo)的像素面積效果立竿見影。但要注意高分辨率帶來的顯存壓力可以配合batch減半來緩解。第二是切片檢測這是遙感檢測最常用的工程手段。把大幅遙感圖像切成多個小塊對每個小塊分別檢測再拼接結(jié)果。切片可以用Ultralytics官方推薦的SAHI框架也可以自己寫切圖腳本。切圖時要注意重疊區(qū)域避免目標(biāo)恰好被切在邊緣上一般設(shè)置20%到30%的重疊率。檢測結(jié)束后把每個patch的檢測框坐標(biāo)轉(zhuǎn)換回原圖坐標(biāo)再匯總用NMS去除重疊區(qū)域的重復(fù)檢測框。第三是數(shù)據(jù)增強(qiáng)層面的針對性調(diào)整。Ultralytics默認(rèn)的增強(qiáng)參數(shù)里scale0.5表示圖像縮放比例可以隨機(jī)縮小到50%。對于本來就小的目標(biāo)再縮小就更難檢測了。可以把scale改成0.8或者更高減少縮放帶來的小目標(biāo)衰減。同時適度增加mosaic1.0增強(qiáng)讓模型在拼接圖中學(xué)習(xí)不同尺度下的小目標(biāo)特征。4.3 訓(xùn)練不收斂或過擬合小數(shù)據(jù)集的常見病854張圖像的數(shù)據(jù)量很容易出現(xiàn)兩種情況訓(xùn)練集loss持續(xù)下降但驗證集mAP不升反降這是過擬合的典型特征或者訓(xùn)練一開始loss就不穩(wěn)定、反復(fù)震蕩這可能是學(xué)習(xí)率設(shè)置不合適。過擬合的應(yīng)對策略最直接的是增加數(shù)據(jù)增強(qiáng)強(qiáng)度。Ultralytics的hsv_h、hsv_s、hsv_v三個參數(shù)控制顏色擾動可以適度調(diào)大比如hsv_s0.8、hsv_v0.6讓模型看到更多顏色變化增強(qiáng)魯棒性。translate和flipud可以增加目標(biāo)位置的多樣性。但增強(qiáng)也不是越強(qiáng)越好過強(qiáng)的增強(qiáng)會讓圖像偏離遙感影像的真實分布反而降低精度需要反復(fù)實驗找平衡點。學(xué)習(xí)率震蕩的問題可以保留默認(rèn)的lr00.01不動但加一些warmup_epochs讓模型先以一個較小的學(xué)習(xí)率起步再過渡到正常學(xué)習(xí)率。Ultralytics默認(rèn)有warmup如果發(fā)現(xiàn)震蕩嚴(yán)重可以手動把warmup_epochs調(diào)大到5或8。還有一個簡便思路換用yolov8n這種更小的模型參數(shù)少、擬合能力弱在小數(shù)據(jù)集上反而不容易過擬合訓(xùn)練也快適合先作為基線模型驗證數(shù)據(jù)質(zhì)量。4.4 訓(xùn)練中常見的運行時報錯速查訓(xùn)練過程中還容易遇到一些和環(huán)境相關(guān)的報錯我把常見的那幾類整理成了一張速查表方便直接對照排查。報錯信息可能原因解決辦法CUDA out of memory顯存不足減小batch、降低imgsz、換小模型No labels found in ...標(biāo)簽?zāi)夸浡窂讲粚z查YAML的train/val路徑Assertionnumelfailed輸入圖像尺寸異常檢查圖像讀取是否正常FileNotFoundError路徑中文件缺失確認(rèn)圖像和標(biāo)簽文件名一一對應(yīng)corrupted image圖像文件損壞刪除損壞圖像或重新解壓AttributeError: NoneType某些圖像讀取為None檢查圖像是否完整、路徑是否有特殊字符把這些情況提前排查一遍訓(xùn)練過程會順暢很多。我一般會在啟動訓(xùn)練前先寫一個數(shù)據(jù)校驗?zāi)_本把圖像完整性、標(biāo)簽合法性、路徑一致性都檢查一遍寧可多花10分鐘檢查也不要訓(xùn)練到一半才發(fā)現(xiàn)問題。5. 基于這份數(shù)據(jù)集還能怎么做擴(kuò)展5.1 聯(lián)合其它遙感數(shù)據(jù)集訓(xùn)練提升泛化能力854張煙囪圖單獨訓(xùn)練模型的泛化能力有限。一種很有效的擴(kuò)展方式是把這份數(shù)據(jù)集和更大的遙感數(shù)據(jù)集聯(lián)合訓(xùn)練比如公開的DOTA、DIOR、xView等。聯(lián)合訓(xùn)練時在YAML文件里把names列表擴(kuò)展成多個類別煙囪的類別編號按順序排好把不同數(shù)據(jù)集的圖像和標(biāo)簽統(tǒng)一整理到同一個目錄結(jié)構(gòu)下。這樣做的好處是模型在同一次訓(xùn)練中既看到了煙囪這類小目標(biāo)工業(yè)設(shè)施也看到了飛機(jī)、車輛、港口等其它遙感目標(biāo)。特征提取器學(xué)習(xí)到更豐富的紋理和形狀特征對煙囪的判別能力反而會提升。實測下來聯(lián)合訓(xùn)練后的模型在煙囪類別上的mAP往往比單獨訓(xùn)練更高因為底層特征表達(dá)更強(qiáng)了。代價是需要處理多數(shù)據(jù)集的格式統(tǒng)一問題如果它們標(biāo)注格式不同要先轉(zhuǎn)成同一套格式這個工作量不小但對最終模型的效果提升非常劃算。5.2 引入旋轉(zhuǎn)框檢測應(yīng)對密集排列場景前面提到這份數(shù)據(jù)集的標(biāo)注是水平框。但實際應(yīng)用中煙囪密集排列的場景非常多水平框會把多個緊鄰的煙囪框在一起或者在斜向排列時框入大量背景導(dǎo)致檢測框重疊率過高、NMS誤刪真實目標(biāo)。如果你的應(yīng)用場景偏向俯視遙感影像中的密集廠區(qū)建議在水平框基礎(chǔ)上考慮旋轉(zhuǎn)框檢測OBB方案。Ultralytics YOLOv8原生支持OBB檢測只需要把標(biāo)簽格式改成class_id x1 y1 x2 y2 x3 y3 x4 y4四個角點的歸一化坐標(biāo)。MMRotate也提供了完整的旋轉(zhuǎn)框檢測訓(xùn)練流程對DOTA數(shù)據(jù)集支持很好。不過旋轉(zhuǎn)框標(biāo)注的制作成本比水平框高不少需要額外的角度標(biāo)注工具如果煙囪目標(biāo)本身在影像中是圓形頂部形態(tài)水平框其實也不會有太多背景冗余所以這個擴(kuò)展要按實際場景來決定值不值得做。5.3 用已訓(xùn)練模型做自動預(yù)標(biāo)注加速二次擴(kuò)展數(shù)據(jù)不夠用的時候最笨的辦法是繼續(xù)人工標(biāo)注但效率太低。我個人的推薦做法是用這個數(shù)據(jù)集先訓(xùn)練一個基礎(chǔ)模型然后用yolo predict對新的遙感影像自動推理得到初步的檢測框再通過標(biāo)注工具比如LabelImg、X-AnyLabeling人工修正自動標(biāo)注的結(jié)果這個過程叫預(yù)標(biāo)注或自動標(biāo)注輔助人工修正。實測下來預(yù)標(biāo)注能把二次標(biāo)注的效率提升60%以上。尤其是煙囪這種特征相對清晰的目標(biāo)基礎(chǔ)模型預(yù)測出來的框質(zhì)量不錯人工只需要刪除誤檢、補(bǔ)充漏檢、微調(diào)邊框位置。具體操作時把新圖像放到一個目錄下批量推理后將結(jié)果生成為YOLO格式標(biāo)簽再導(dǎo)入標(biāo)注軟件檢查修正。用這種方式幾百張新圖像的標(biāo)注工作量可以控制在半天以內(nèi)。5.4 從煙囪檢測延伸到更廣的工業(yè)設(shè)施檢測煙囪檢測這個任務(wù)本身只是遙感工業(yè)設(shè)施檢測的一個切面。同一套數(shù)據(jù)格式、訓(xùn)練流程和技術(shù)方案完全可以復(fù)用到其他工業(yè)目標(biāo)上比如冷卻塔、儲油罐、化工廠房、電力塔桿。你只需要替換成對應(yīng)的標(biāo)注數(shù)據(jù)重新訓(xùn)練一遍模型。這也體現(xiàn)了一個通用數(shù)據(jù)集的價值它不只是教你做一個煙囪檢測器更重要的是幫你建立一套遙感目標(biāo)檢測的標(biāo)準(zhǔn)工作流從數(shù)據(jù)準(zhǔn)備、模型訓(xùn)練到效果評估的每個環(huán)節(jié)都形成肌肉記憶。后續(xù)再遇到任何新目標(biāo)只需要按同樣的流程走一遍省去大量摸索時間。我在實際使用這份數(shù)據(jù)集時還有一個體會小數(shù)據(jù)集的價值往往被低估了。很多人看到854張圖就覺得不夠用但真正上手跑一遍你會發(fā)現(xiàn)它在流程驗證、算法對比、問題定位方面的效率是大型數(shù)據(jù)集比不了的。先用小數(shù)據(jù)把流程跑通把坑踩平再上大場景數(shù)據(jù)這個思路我一直覺得很實用。如果你正在找一份用來練手的遙感目標(biāo)檢測數(shù)據(jù)這份煙囪數(shù)據(jù)集是個不錯的選擇至少在你把它榨干之前它能讓你把目標(biāo)檢測的整套流程掌握得明明白白。本文還有配套的精品資源點擊獲取