檢測(cè):YOLOv8數(shù)據(jù)集訓(xùn)練與避坑指南)
簡(jiǎn)介一套面向巖石表面礦物質(zhì)檢測(cè)的YOLO格式目標(biāo)檢測(cè)數(shù)據(jù)集適合地質(zhì)學(xué)研究者和計(jì)算機(jī)視覺開發(fā)者用于礦物識(shí)別、目標(biāo)檢測(cè)模型訓(xùn)練與算法驗(yàn)證。資源共2000個(gè)文件壓縮包約59.08MB包含1138個(gè)txt標(biāo)簽文件、861張jpg巖石圖像和1個(gè)Python可視化腳本已按訓(xùn)練集與驗(yàn)證集劃分并完成數(shù)據(jù)增強(qiáng)可直接用于YOLO全系列網(wǎng)絡(luò)訓(xùn)練。類別覆蓋石英、斑銅礦、黃鐵礦等8種常見礦物class文件明確各類名稱配套show腳本可將邊界框繪制在原始圖像上便于檢查標(biāo)注質(zhì)量與調(diào)試模型輸出。目前已有454人學(xué)習(xí)使用對(duì)需要在巖石樣本場(chǎng)景中落地目標(biāo)檢測(cè)的研究者來說這是一套可直接上手、適合評(píng)估與復(fù)現(xiàn)實(shí)驗(yàn)的高質(zhì)量數(shù)據(jù)資源。1. 從目檢到框選巖石表面礦物質(zhì)檢測(cè)數(shù)據(jù)集到底能解決什么問題“巖石表面礦物質(zhì)檢測(cè)數(shù)據(jù)集”聽起來像是一個(gè)普通的圖片包但它真正解決的是地質(zhì)工作里的一個(gè)老問題巖石照片上的礦物種類多、顏色相近、顆粒大小懸殊靠人眼一找一框既慢又難以復(fù)現(xiàn)。超過 1000 張圖片和標(biāo)簽意味著模型用一個(gè)晚上就能在預(yù)訓(xùn)練權(quán)重上完成遷移學(xué)習(xí)跑出第一版能框出石英、長(zhǎng)石、云母的檢測(cè)結(jié)果。這個(gè)標(biāo)題的價(jià)值不在于數(shù)字本身而在于它給了目標(biāo)檢測(cè)流程一個(gè)可驗(yàn)證的落點(diǎn)。剛上手目標(biāo)檢測(cè)的新手可以用它把標(biāo)注、訓(xùn)練、評(píng)估完整走一圈做地質(zhì)信息化的人也能從它看到自動(dòng)礦物識(shí)別的邊界在哪里。2. 拆解巖石表面礦物質(zhì)檢測(cè)數(shù)據(jù)集的標(biāo)簽從歸一化坐標(biāo)到類別分布2.1 一張圖對(duì)應(yīng)一個(gè)標(biāo)簽YOLO txt 和 VOC xml 里到底存了什么市面上常見的巖石表面礦物質(zhì)檢測(cè)數(shù)據(jù)集組織方式一般是“圖片文件夾 標(biāo)簽文件夾”圖片多為 JPG/PNG常見尺寸從 1280×960 到更高分辨率。標(biāo)簽有兩種常見形態(tài)一種是 YOLO 訓(xùn)練直接用的 .txt每行一個(gè)目標(biāo)另一種是 VOC 的 .xml用節(jié)點(diǎn)記錄目標(biāo)類別和坐標(biāo)。拿到數(shù)據(jù)集后我一般先看根目錄下有沒有 classes.txt 或 obj.names因?yàn)轭悇e順序決定編號(hào)這個(gè)順序一旦亂了后面訓(xùn)練就是黑匣子。一個(gè)典型的 YOLO 標(biāo)簽文件長(zhǎng)這樣0 0.4512 0.3784 0.1825 0.2136 1 0.7231 0.5190 0.0958 0.0814 0 0.2108 0.6142 0.3037 0.2789邏輯很簡(jiǎn)單每行 5 個(gè)數(shù)第一個(gè)是類別編號(hào)后四個(gè)是歸一化后的中心點(diǎn) x、中心點(diǎn) y、框?qū)?、框高。歸一化的意思是這些值都除以了圖片原始寬高所以范圍在 0 到 1 之間。這樣做的好處是訓(xùn)練時(shí)無論圖片縮放成多大坐標(biāo)都能跟著比例走。但這也帶來一個(gè)隱藏約束標(biāo)簽坐標(biāo)和圖片方向強(qiáng)綁定。如果照片被旋轉(zhuǎn)過標(biāo)簽不會(huì)自動(dòng)旋轉(zhuǎn)訓(xùn)練出來的框全部錯(cuò)位。因此拿到數(shù)據(jù)集的第一個(gè)動(dòng)作不是訓(xùn)練而是確認(rèn)圖片有沒有 EXIF 旋轉(zhuǎn)信息以及標(biāo)簽里的框是不是都落在圖片范圍內(nèi)。數(shù)據(jù)集的標(biāo)簽文件不一定完全干凈我常遇到某個(gè) txt 是空的、某個(gè)類別編號(hào)越界、還有少數(shù)圖片沒有對(duì)應(yīng)標(biāo)簽。如果你拿到的標(biāo)簽是 VOC xml轉(zhuǎn)換到 YOLO 時(shí)標(biāo)準(zhǔn)做法是解析objectname和bndbox里的 xmin、ymin、xmax、ymax再換算成歸一化中心寬高。目標(biāo)檢測(cè)常用標(biāo)注工具如 LabelImg、LabelMe 都能導(dǎo)出這兩類格式但導(dǎo)出時(shí)要注意坐標(biāo)是不是整數(shù)、有沒有負(fù)數(shù)。巖石表面礦物質(zhì)檢測(cè)的難點(diǎn)在于礦物邊界經(jīng)常是漸變的標(biāo)注員往往會(huì)把“像”和“是”混在一起所以標(biāo)簽質(zhì)量比數(shù)量更重要。2.2 用腳本統(tǒng)計(jì)類別分布和框大小動(dòng)手前先給數(shù)據(jù)集做體檢我不建議直接訓(xùn)練先用腳本給數(shù)據(jù)集做一次體檢看類別分布、空標(biāo)簽和圖片配對(duì)情況。這個(gè)腳本可以復(fù)用到你后續(xù)自己采的數(shù)據(jù)上。from pathlib import Path from collections import Counter label_dir Path(labels/train) img_dir Path(images/train) cls_counter Counter() box_sizes [] empty_label 0 unmatched 0 for txt in label_dir.glob(*.txt): img img_dir / (txt.stem .jpg) if not img.exists(): unmatched 1 continue lines txt.read_text().strip().splitlines() if not lines: empty_label 1 for line in lines: parts line.split() if len(parts) ! 5: continue c, cx, cy, w, h parts cls_counter[c] 1 box_sizes.append((float(w), float(h))) print(類別編號(hào) - 目標(biāo)數(shù)量:, sorted(cls_counter.items())) print(空標(biāo)簽文件數(shù):, empty_label) print(標(biāo)簽存在但圖片缺失:, unmatched)這段腳本會(huì)告訴你三個(gè)關(guān)鍵信息。第一每個(gè)類別的目標(biāo)數(shù)量是不是均衡如果某個(gè)礦物類別只有幾十個(gè)框模型很容易把它忽略。第二空標(biāo)簽文件的數(shù)量如果訓(xùn)練集里有一批圖片沒有標(biāo)注訓(xùn)練時(shí)這些圖片會(huì)被當(dāng)作背景間接把正樣本的損失拉低。第三標(biāo)簽和圖片是否一一對(duì)應(yīng)文件名不匹配是最常見的低級(jí)問題??虼笮∫惨?。巖石表面礦物質(zhì)檢測(cè)里礦物顆粒可能只有圖片寬度的 2% 到 3%這類小目標(biāo)在高分辨率原圖里能看清但縮放到 640×640 訓(xùn)練尺寸后就剩下十幾個(gè)像素。如果統(tǒng)計(jì)發(fā)現(xiàn)大量框?qū)捀叨夹∮?0.05后面要考慮切圖或者提高訓(xùn)練分辨率而不是盲目調(diào)學(xué)習(xí)率。2.3 訓(xùn)練集、驗(yàn)證集、測(cè)試集劃分別讓同一塊巖石既進(jìn)訓(xùn)練又進(jìn)驗(yàn)證數(shù)據(jù)集劃分是最容易被忽視的環(huán)節(jié)。如果同一個(gè)巖石樣本的連拍照片既出現(xiàn)在訓(xùn)練集又出現(xiàn)在驗(yàn)證集模型相當(dāng)于“背答案”驗(yàn)證集 mAP 會(huì)虛高。正確做法是按拍攝對(duì)象或者巖心編號(hào)分組而不是逐張隨機(jī)切。常見做法是先按文件名前綴分桶再組間劃分。假設(shè)文件名格式是granite_01_03.jpg這種代表花崗巖樣本 01 的第 3 張照片那劃分就應(yīng)該以granite_01為粒度。如果數(shù)據(jù)集的命名沒有規(guī)律就按拍攝時(shí)間或目錄分組。mkdir -p images/{train,val} labels/{train,val} python - PY from pathlib import Path import random random.seed(42) imgs sorted(Path(images/all).glob(*)) val_n int(len(imgs) * 0.2) random.shuffle(imgs) for idx, img in enumerate(imgs): split val if idx val_n else train img.rename(fimages/{split}/{img.name}) lab Path(flabels/all/{img.stem}.txt) if lab.exists(): lab.rename(flabels/{split}/{lab.name}) else: print(缺少標(biāo)簽:, img.name) PY這段代碼把 20% 圖片劃為驗(yàn)證集其余為訓(xùn)練集。注意要先建目錄再移動(dòng)圖片和同名標(biāo)簽。如果你知道數(shù)據(jù)里有很強(qiáng)的場(chǎng)景相關(guān)性就不要用random.shuffle否則驗(yàn)證集會(huì)泄漏到訓(xùn)練集里。泄漏的直接后果是模型在驗(yàn)證集上表現(xiàn)很好一到野外新照片就明顯變差。參數(shù)方面val_n的比例可以按總數(shù)調(diào)整超過 2000 張可以只留 15% 做驗(yàn)證但只有 1000 張左右時(shí)20% 是安全值。random.seed(42)的作用是讓每次運(yùn)行結(jié)果一致方便復(fù)現(xiàn)。3. 用 YOLOv8 訓(xùn)練巖石表面礦物質(zhì)檢測(cè)數(shù)據(jù)集目錄、yaml 和訓(xùn)練參數(shù)3.1 目錄結(jié)構(gòu)萬萬不能錯(cuò)images 與 labels 同級(jí)且相對(duì)路徑穩(wěn)定YOLOv8 雖然用起來簡(jiǎn)單但目錄結(jié)構(gòu)寫錯(cuò)會(huì)浪費(fèi)大量時(shí)間。建議把所有數(shù)據(jù)和標(biāo)簽放在同一個(gè)工程目錄下保持 images 和 labels 兩個(gè)同級(jí)文件夾。目錄樹如下rock-mineral/ ├── data.yaml ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── train/ └── val/注意 labels 是復(fù)數(shù)不是 label大小寫也要和 yaml 里完全一致。很多人在這個(gè)細(xì)節(jié)上翻車訓(xùn)練跑起來后 loss 一直不變最后才發(fā)現(xiàn)圖片路徑找不到標(biāo)簽整個(gè)數(shù)據(jù)集被當(dāng)成背景訓(xùn)練。對(duì)應(yīng)的 data.yaml 可以這樣寫path: /absolute/path/to/rock-mineral train: images/train val: images/val nc: 4 names: 0: quartz 1: feldspar 2: mica 3: pyrite邏輯說明path是工程根目錄train和val是相對(duì)于根目錄的圖片文件夾路徑模型會(huì)自動(dòng)到同名labels文件夾找標(biāo)簽。nc是類別數(shù)一定要和 names 里的數(shù)量一致names 的順序也必須和標(biāo)簽 txt 里的編號(hào)一致。我見過不少人把 names 寫成中文比如“石英”“長(zhǎng)石”訓(xùn)練本身沒問題但推理時(shí)輸出中文類別名會(huì)在某些終端里顯示亂碼后續(xù)生成報(bào)告還要再映射一次。建議全部用英文或拼音保存后再做顯示層的中文映射。另一個(gè)容易踩的點(diǎn)是path用相對(duì)路徑導(dǎo)致之后在不同目錄下執(zhí)行命令時(shí)找不到數(shù)據(jù)。yaml 里的 path 最好寫成絕對(duì)路徑或者直接 cd 到工程目錄下再訓(xùn)練。3.2 訓(xùn)練命令與參數(shù)imgsz、batch、epochs、patience 怎么定環(huán)境里裝好 ultralytics 后訓(xùn)練命令可以保持最小化先不用管一堆高級(jí)參數(shù)。cd /path/to/rock-mineral yolo detect train \ datadata.yaml \ modelyolov8n.pt \ imgsz640 \ batch8 \ epochs100 \ patience15 \ projectruns/detect \ namerock_mineral_v1參數(shù)解讀modelyolov8n.pt使用 COCO 預(yù)訓(xùn)練權(quán)重做遷移學(xué)習(xí)。巖石表面礦物質(zhì)檢測(cè)數(shù)據(jù)集只有 1000 多張從零初始化訓(xùn)練很難收斂預(yù)訓(xùn)練權(quán)重能提供通用的紋理和邊緣特征。n 是 nano 版速度最快、顯存占用小如果顯卡顯存有 12G 以上可以換成yolov8s.pt精度通常更高一些。imgsz640訓(xùn)練時(shí)把輸入圖片統(tǒng)一縮放到 640×640。如果原始圖片是 1280×960直接縮放會(huì)丟掉很多細(xì)顆粒礦物細(xì)節(jié)。可以先跑 640 看基線再提高到 960 對(duì)比。提高 imgsz 會(huì)顯著增加顯存和訓(xùn)練時(shí)間但小目標(biāo)召回率往往會(huì)變好。batch8在 8G 顯存上這是比較穩(wěn)的值。batch 太大容易 OOM太小則梯度噪聲大。epochs100配合 early stopping 使用。對(duì)于 1000 張左右的數(shù)據(jù)集40 到 100 個(gè) epoch 基本夠用不用機(jī)械地跑到 300。patience15連續(xù) 15 個(gè) epoch 驗(yàn)證集 mAP 沒有提升就自動(dòng)停止。這個(gè)參數(shù)是后悔藥能防止你睡覺時(shí)模型把磁盤跑滿也避免過擬合。訓(xùn)練結(jié)束后結(jié)果會(huì)輸出到runs/detect/rock_mineral_v1/weights/里面best.pt是驗(yàn)證集上表現(xiàn)最好的權(quán)重last.pt是最后一個(gè) epoch 的權(quán)重。我一般只用 best.pt除非 last.pt 的召回率明顯更高。3.3 訓(xùn)練日志里的玄學(xué)loss 曲線、P/R/mAP 和早停訓(xùn)練過程中終端會(huì)打印每個(gè) epoch 的box_loss、cls_loss、dfl_loss、precision、recall、mAP50、mAP50-95這幾項(xiàng)。新手最容易犯的錯(cuò)是只盯著 loss 下降就覺得萬事大吉實(shí)際上分類損失下降但召回率不變的情況很常見尤其是巖石表面礦物質(zhì)檢測(cè)這種類別不平衡的任務(wù)。我更習(xí)慣看驗(yàn)證集上的 recall。礦物檢測(cè)的漏檢代價(jià)往往比誤檢更高漏掉一個(gè)黃鐵礦顆??赡軐?dǎo)致后續(xù)品位估算偏差。如果 recall 一直上不去大概率是小目標(biāo)漏檢或類別樣本太少而不是學(xué)習(xí)率的問題。訓(xùn)練日志里還會(huì)顯示早停信息類似EarlyStopping: training stopped early as no improvement observed in last 15 epochs。這不是錯(cuò)誤是正常機(jī)制。早停過早也可能說明驗(yàn)證集劃分不合理或類別分布太單一需要回頭檢查數(shù)據(jù)劃分而不是重啟訓(xùn)練。還有一類玄學(xué)是 loss 曲線突然飆升到幾十然后訓(xùn)練崩潰這通常和 batch 里出現(xiàn)了異常圖片或標(biāo)簽坐標(biāo)越界有關(guān)下一章會(huì)專門講。4. 推理與評(píng)估用 mAP50 和混淆矩陣判斷礦物檢測(cè)模型能不能用4.1 最小推理腳本把批量圖片跑一遍再導(dǎo)出結(jié)果訓(xùn)練完成后先在驗(yàn)證集上跑一次推理看輸出結(jié)果是不是符合直覺。yolo detect predict \ modelruns/detect/rock_mineral_v1/weights/best.pt \ sourceimages/val \ imgsz640 \ conf0.25 \ iou0.5 \ save_txtTrue \ save_confTrue這個(gè)命令會(huì)讀取images/val下所有圖片用 best.pt 預(yù)測(cè)結(jié)果保存到runs/detect/predict/。conf0.25表示置信度低于 0.25 的框會(huì)被丟掉iou0.5是 NMS 的 IoU 閾值。對(duì)礦物檢測(cè)如果漏檢多可以把 conf 降到 0.1代價(jià)是誤檢框變多。如果需要更細(xì)致的控制用 Python 腳本from ultralytics import YOLO model YOLO(runs/detect/rock_mineral_v1/weights/best.pt) results model.predict( sourceimages/val, imgsz640, conf0.25, iou0.5, save_txtTrue, save_confTrue, ) for r in results: boxes r.boxes print(r.path, len(boxes), boxes.cls.tolist(), boxes.conf.tolist())邏輯說明results 里每個(gè)元素對(duì)應(yīng)一張圖片boxes.cls是類別編號(hào)列表boxes.conf是置信度列表。代碼最后打印出每張圖片檢出的礦物類別和置信度方便快速掃一眼哪些圖片被漏檢。這里的核心參數(shù)和命令行一致imgsz最好和訓(xùn)練時(shí)保持一致不然框的坐標(biāo)會(huì)偏。4.2 mAP50 和 mAP50-95 在巖礦場(chǎng)景里怎么讀評(píng)估更推薦用官方 val 命令yolo detect val \ modelruns/detect/rock_mineral_v1/weights/best.pt \ datadata.yaml \ imgsz640這會(huì)輸出 precision、recall、mAP50、mAP50-95并保存混淆矩陣到runs/detect/val/confusion_matrix.png。對(duì)巖石表面礦物質(zhì)檢測(cè)數(shù)據(jù)集我通常設(shè)定的可用標(biāo)準(zhǔn)是 mAP50 到 0.8 以上mAP50-95 在 0.4 到 0.6 之間都是正常范圍。為什么 mAP50 和 mAP50-95 差距這么大原因在 IoU 閾值。mAP50 只要求預(yù)測(cè)框和真實(shí)框的重疊率超過 0.5 就算對(duì)mAP50-95 是從 0.5 到 0.95 取多個(gè)閾值平均。礦物顆粒邊界往往是漸變的標(biāo)注員畫框時(shí)就不太緊同一個(gè)目標(biāo)換個(gè)標(biāo)注員可能畫出的框大小差 10% 以上這直接拉低了 mAP50-95。還有一部分原因是礦物形狀不規(guī)則矩形框天然不能緊貼目標(biāo)這在只做檢測(cè)時(shí)問題不大但如果后續(xù)要統(tǒng)計(jì)面積框精度就會(huì)影響結(jié)果。還要注意val 命令默認(rèn)用驗(yàn)證集里所有圖片評(píng)估。如果訓(xùn)練時(shí)模型已經(jīng)見過類似的照片評(píng)估結(jié)果會(huì)偏樂觀。更嚴(yán)格的做法是把數(shù)據(jù)分成 train、val、test 三份test 只用來做一次最終評(píng)估不要參與調(diào)參。1000 張的規(guī)模可以按 70% 訓(xùn)練、15% 驗(yàn)證、15% 測(cè)試劃分。4.3 混淆矩陣定位漏檢和誤檢哪一對(duì)礦物最容易被混訓(xùn)練生成的confusion_matrix.png是排查模型缺陷的第一手材料。橫軸是真實(shí)類別縱軸是預(yù)測(cè)類別對(duì)角線上的數(shù)字代表正確檢出的比例。在巖石表面礦物質(zhì)檢測(cè)里石英和長(zhǎng)石這兩類最容易互混因?yàn)槿庋巯骂伾浅=咏际菧\色粒狀云母和角閃石也容易混淆特別是云母片在反光下呈現(xiàn)深色片狀??吹交煜仃?yán)锬硞€(gè)非對(duì)角線格子數(shù)值很高不要急著換模型。先回標(biāo)簽文件夾里抽查幾十張對(duì)應(yīng)類別的原圖看是不是標(biāo)注標(biāo)準(zhǔn)本身有問題。經(jīng)常出現(xiàn)同一個(gè)標(biāo)注員把淺色礦物全部標(biāo)成石英另一個(gè)標(biāo)注員標(biāo)成長(zhǎng)石。這種情況模型再調(diào)參也沒用需要統(tǒng)一標(biāo)注規(guī)范或者合并類別。還有一類問題是“背景”行比較高說明模型在空白巖石表面上產(chǎn)生了大量誤檢。巖石表面本身紋理復(fù)雜陰影和裂隙很容易被當(dāng)作礦物邊界。對(duì)策是把 conf 調(diào)高到 0.35 以上或者收集一批背景圖加入訓(xùn)練集作為負(fù)樣本。對(duì)巖石表面礦物質(zhì)檢測(cè)來說寧可少檢幾個(gè)不確定目標(biāo)也比到處框強(qiáng)。5. 巖石表面礦物質(zhì)檢測(cè)的避坑指南六個(gè)最容易翻車的現(xiàn)場(chǎng)問題5.1 現(xiàn)象訓(xùn)了半天驗(yàn)證集一個(gè)目標(biāo)都不出訓(xùn)練 loss 正常下降但用 best.pt 預(yù)測(cè)時(shí)每張圖片都輸出空列表。先檢查標(biāo)簽最常見的局面是標(biāo)簽里所有類別編號(hào)從 1 開始而 YOLO 的類別編號(hào)必須從 0 開始。如果classes.txt里定義的是1: quartz, 2: feldspar訓(xùn)練時(shí)模型會(huì)認(rèn)為類別編號(hào) 0 是不存在的類別自然學(xué)不到東西。解決寫一個(gè)循環(huán)遍歷所有 txt把所有類別編號(hào)減一同時(shí)檢查最大編號(hào)是否小于nc如果等于nc也說明編號(hào)越界了。空標(biāo)簽文件多也會(huì)造成這種現(xiàn)象模型把所有圖都當(dāng)作背景預(yù)測(cè)時(shí)無法輸出目標(biāo)。5.2 現(xiàn)象訓(xùn)練時(shí)框全是斜的或旋轉(zhuǎn)了有些巖石照片來自手機(jī)或相機(jī)文件里帶 EXIF 方向信息預(yù)覽軟件會(huì)自動(dòng)轉(zhuǎn)正但訓(xùn)練框架在讀取圖片時(shí)未必處理這個(gè)方向?qū)е聵?biāo)簽里的坐標(biāo)和實(shí)際像素錯(cuò)位。特征是框能框到礦物但整體偏移或者邊界框被壓扁。解決訓(xùn)練前用 PIL 讀圖后統(tǒng)一轉(zhuǎn)正再保存并去掉原圖的 EXIF 信息。轉(zhuǎn)正后再重新檢查標(biāo)簽是否還對(duì)應(yīng)因?yàn)檗D(zhuǎn)正會(huì)改變寬高尺寸如果標(biāo)簽還是按原圖尺寸歸一化的同樣會(huì)錯(cuò)位。常見的做法是用下面的代碼先處理一遍整批圖片from PIL import Image, ImageOps from pathlib import Path for img_path in Path(images/all).glob(*.jpg): img Image.open(img_path) img ImageOps.exif_transpose(img) img.save(img_path)這個(gè)腳本會(huì)把 EXIF 指定的旋轉(zhuǎn)方向?qū)戇M(jìn)實(shí)際像素里以后再讀圖就一致了。5.3 現(xiàn)象黃鐵礦和方解石訓(xùn)練時(shí)分得開驗(yàn)證集上混成一片訓(xùn)練 loss 很低驗(yàn)證集 mAP 也不差但單獨(dú)看這兩類的混淆矩陣時(shí)誤檢率特別高。原因是標(biāo)注標(biāo)準(zhǔn)前后不一致。黃鐵礦是淺銅黃色方解石在部分光線下也呈淺黃色兩個(gè)標(biāo)注員對(duì)同一塊區(qū)域可能給出不同類別。解決抽查標(biāo)簽樣本如果發(fā)現(xiàn)同一礦物在不同照片里被標(biāo)成不同類別需要合并類別或重新審核。一個(gè)穩(wěn)妥的做法是先只檢測(cè)“金屬礦物”和“非金屬礦物”兩類訓(xùn)練穩(wěn)定后再細(xì)分。對(duì)巖石表面礦物質(zhì)檢測(cè)來說類別定義越貼近野外可辨識(shí)度模型越好學(xué)。5.4 現(xiàn)象顯存 OOM訓(xùn)練中斷訓(xùn)練到中途爆顯存終端報(bào)CUDA out of memory。最常見的原因是 batch 設(shè)置過大以及cacheTrue把數(shù)據(jù)全部加載到內(nèi)存里。有些 1000 多張的高分辨率圖片全部緩存后內(nèi)存占用超過 32G顯存不夠就直接崩。解決batch 降到 4imgsz降到 640并把訓(xùn)練命令的cache參數(shù)去掉或顯式設(shè)為cacheFalse。如果還崩加一句device0確認(rèn)只使用一張 GPU避免程序把數(shù)據(jù)分配到多個(gè)設(shè)備上。另外一個(gè)容易被忽視的點(diǎn)是電腦在跑訓(xùn)練的同時(shí)還掛著瀏覽器和 IDE顯存被其他進(jìn)程占用訓(xùn)練前最好關(guān)掉無關(guān)程序。5.5 現(xiàn)象小顆粒礦物全部漏檢礦物顆粒在巖石表面往往大小懸殊大的有幾厘米小的只有幾個(gè)毫米。原圖里小顆粒還看得出縮放成 640 后只有十幾個(gè)像素模型學(xué)不到足夠特征導(dǎo)致 recall 明顯偏低。解決優(yōu)先提高訓(xùn)練和推理的imgsz到 960 或 1280如果顯存不夠就改用切圖訓(xùn)練把原圖切塊后按塊訓(xùn)練和預(yù)測(cè)。切圖時(shí)要注意相鄰塊之間保留重疊區(qū)域避免目標(biāo)被切斷。還有一種做法是單獨(dú)把小目標(biāo)較多的圖片復(fù)制一份并放大和原圖同時(shí)參與訓(xùn)練效果也還可以。5.6 現(xiàn)象類別不少但某個(gè)類別 AP 一直是 0訓(xùn)練日志里某個(gè)類別的平均精度從頭到尾都是 0其他類別都正常。先看這個(gè)類別在訓(xùn)練集和驗(yàn)證集里的分布如果訓(xùn)練集里有該類別但驗(yàn)證集里沒有那這個(gè)指標(biāo)就是 0沒有任何參考意義反過來訓(xùn)練集里只有幾個(gè)目標(biāo)模型學(xué)不到代表性特征。解決統(tǒng)計(jì)每個(gè)類別在訓(xùn)練集和驗(yàn)證集的目標(biāo)數(shù)量確認(rèn)兩邊都有足夠樣本。對(duì)樣本極少的類別可以對(duì)該類礦物圖片做旋轉(zhuǎn)、縮放、色彩抖動(dòng)增強(qiáng)或者把同一張圖中該目標(biāo)的裁剪塊復(fù)制到其他背景上形成新的訓(xùn)練樣本。如果數(shù)據(jù)集本身只有 1000 張某些類別數(shù)量少是常態(tài)不要強(qiáng)行增加類別數(shù)先降低類別粒度更現(xiàn)實(shí)。6. 把模型接到現(xiàn)場(chǎng)數(shù)據(jù)上批量推斷、切圖和產(chǎn)出統(tǒng)計(jì)表6.1 切圖讓小粒徑礦物不漏檢Tiled Inference訓(xùn)練完的模型接入現(xiàn)場(chǎng)照片時(shí)常見問題是新照片分辨率比訓(xùn)練圖高得多比如無人機(jī)或掃描儀拍出的 4000×3000 圖片。直接縮放到 640 會(huì)讓小礦物丟失這時(shí)我會(huì)用切圖推理。每 640 像素一塊重疊 50 像素防止目標(biāo)被切斷檢測(cè)結(jié)果坐標(biāo)再映射回原圖。import cv2 from ultralytics import YOLO model YOLO(best.pt) img cv2.imread(field_photo.jpg) h, w img.shape[:2] tile 640 overlap 50 detections [] for y in range(0, h, tile - overlap): for x in range(0, w, tile - overlap): crop img[y:y tile, x:x tile] results model(crop, imgsztile, conf0.2) for box in results[0].boxes: cx, cy, bw, bh box.xywh[0].cpu().tolist() detections.append((x cx, y cy, bw, bh, box.cls[0].item(), box.conf[0].item()))這段代碼的關(guān)鍵是把小圖的中心坐標(biāo)加上切圖的左上角偏移量才能還原出原圖位置。overlap50是給被切斷的目標(biāo)一個(gè)緩沖目標(biāo)物被切成兩半時(shí)至少有一個(gè)切塊能完整框住它。推理時(shí)每個(gè)切塊單獨(dú)跑內(nèi)存占用比直接跑大圖低很多缺點(diǎn)是耗時(shí)線性增加。6.2 把預(yù)測(cè)結(jié)果輸出成 CSV給地質(zhì)統(tǒng)計(jì)用的表礦物檢測(cè)的下一步經(jīng)常是統(tǒng)計(jì)數(shù)量、算面積占比。我會(huì)把推斷結(jié)果寫進(jìn) CSV后續(xù)用 pandas 或者 Excel 匯總。import csv with open(minerals.csv, w, newline) as f: writer csv.writer(f) writer.writerow([image, class, conf, x, y, w, h]) for det in detections: x, y, bw, bh, cls_id, conf det writer.writerow([field_photo.jpg, int(cls_id), round(conf, 3), int(x), int(y), int(bw), int(bh)])這個(gè)格式可以直接算每個(gè)類別的框數(shù)量也可以用框?qū)捀呓扑愠龈采w率。注意這里框坐標(biāo)是以原圖左上角為原點(diǎn)單位是像素。如果后續(xù)要輸出成厘米或毫米需要提前記錄圖像的空間分辨率我一般會(huì)在拍攝時(shí)留一把標(biāo)尺在畫面里作為換算基準(zhǔn)。6.3 用框面積粗算礦物含量模型只能輔助不能替代框面積占比可以粗略估計(jì)礦物暴露面積但它會(huì)高估大顆粒礦物。因?yàn)橐粋€(gè)礦物顆粒的矩形框通常遠(yuǎn)大于實(shí)際面積顆粒越不規(guī)則誤差越大。做正式儲(chǔ)量估算時(shí)我會(huì)改用實(shí)例分割模型或者在檢測(cè)框基礎(chǔ)上再裁剪出目標(biāo)區(qū)域做像素級(jí)分類。還有一個(gè)更簡(jiǎn)單的辦法把檢測(cè)框中心點(diǎn)畫成密度圖用密度分布代替面積占比能規(guī)避一部分框大小不穩(wěn)的問題。我自己的血淚教訓(xùn)是上次用模型統(tǒng)計(jì)兩種礦物的面積占比模型給出的黃鐵礦面積占比是 37%人工目檢是 29%原因是光照不均勻?qū)е掳挡柯z亮部又被重復(fù)框選。后來我在訓(xùn)練集里加入了不同光照條件的樣本同時(shí)對(duì)推理結(jié)果按亮度做分組閾值調(diào)整誤差才壓到 5% 以內(nèi)。從那以后我每次把模型接到新場(chǎng)景前都會(huì)先拿人工標(biāo)注過的 20 張圖做一次對(duì)照測(cè)試再?zèng)Q定閾值怎么設(shè)。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取