數(shù)據(jù)集實(shí)戰(zhàn):500張圖從訓(xùn)練到避坑)
簡(jiǎn)介本資源為面向電力巡檢與計(jì)算機(jī)視覺方向的YOLO破損絕緣子檢測(cè)數(shù)據(jù)集適用于輸電線路絕緣子缺陷識(shí)別模型的訓(xùn)練與驗(yàn)證可服務(wù)于目標(biāo)檢測(cè)入門者及電力智能巡檢相關(guān)項(xiàng)目開發(fā)者。壓縮包共1801個(gè)文件包含600張jpg真實(shí)場(chǎng)景圖像、600個(gè)xml格式VOC標(biāo)注文件與601個(gè)txt格式Y(jié)OLO標(biāo)注文件兩種標(biāo)簽分別存放于獨(dú)立文件夾可直接接入YOLO系列檢測(cè)框架包體約54.95MB。數(shù)據(jù)覆蓋多種拍攝場(chǎng)景標(biāo)注類別為break_insulator單一目標(biāo)標(biāo)注質(zhì)量較高便于快速構(gòu)建訓(xùn)練集與驗(yàn)證集。目前已有1647人學(xué)習(xí)下載配套博文提供了數(shù)據(jù)集說明與檢測(cè)結(jié)果參考讀者可據(jù)此復(fù)現(xiàn)絕緣子缺陷檢測(cè)流程理解VOC與YOLO兩種標(biāo)注格式的轉(zhuǎn)換與使用方式為后續(xù)模型調(diào)優(yōu)與工程落地提供可靠的數(shù)據(jù)基礎(chǔ)。1. 拆開這份破損絕緣子數(shù)據(jù)集500 張實(shí)拍圖能跑出什么結(jié)果電力巡檢航拍圖里絕緣子串上一小塊破損往往只占幾十個(gè)像素人眼盯久了容易漏模型卻能在毫秒級(jí)給出框。這份 YOLO 破損絕緣子檢測(cè)數(shù)據(jù)集就是沖著這個(gè)場(chǎng)景來的500 多張真實(shí)場(chǎng)景 jpg 圖片用 labelImg 逐張標(biāo)注類別只有一個(gè)break_insulator同時(shí)給了 VOC 的 xml 和 YOLO 的 txt 兩套標(biāo)簽分別放在兩個(gè)文件夾里。拿到手不用自己從零標(biāo)直接能喂給 YOLO 系列做缺陷目標(biāo)檢測(cè)。它適合三類人一是剛接觸工業(yè)缺陷檢測(cè)、想找個(gè)單類別小數(shù)據(jù)集跑通訓(xùn)練閉環(huán)的二是做電力巡檢算法驗(yàn)證、需要快速搭 baseline 的三是教學(xué)或課程設(shè)計(jì)要一份標(biāo)注規(guī)范、格式齊全的現(xiàn)成數(shù)據(jù)。不適合想要多類別、大規(guī)模、帶分割掩碼的人——這里只有檢測(cè)框只有一個(gè)類。下面按「數(shù)據(jù)長(zhǎng)什么樣 → 怎么轉(zhuǎn)怎么訓(xùn) → 坑在哪 → 怎么驗(yàn)證」走一遍。2. 數(shù)據(jù)集結(jié)構(gòu)與標(biāo)簽格式VOC 和 YOLO 兩套標(biāo)簽怎么對(duì)應(yīng)2.1 目錄組織與文件命名這類數(shù)據(jù)集常見的組織方式是把圖片放一個(gè)目錄標(biāo)簽按格式分兩個(gè)目錄。你拿到手大概率是這種結(jié)構(gòu)dataset/ ├── images/ # 全部 jpg 原圖如 0780.jpg 0059.jpg 0108.jpg ├── annotations_voc/ # VOC 格式 xml與圖片同名 └── labels_yolo/ # YOLO 格式 txt與圖片同名圖片名是純數(shù)字編號(hào)0780、0059、0108、0202 這些標(biāo)簽文件必須和圖片同名只換擴(kuò)展名。這是后面所有轉(zhuǎn)換和訓(xùn)練能對(duì)上的前提。先做一件事確認(rèn)圖片數(shù)和標(biāo)簽數(shù)是否一致缺一張都會(huì)在訓(xùn)練時(shí)報(bào) image not found 或靜默丟樣本。# 統(tǒng)計(jì)三邊數(shù)量三者應(yīng)基本一致 ls images/ | wc -l ls annotations_voc/ | wc -l ls labels_yolo/ | wc -l邏輯說明wc -l數(shù)文件行數(shù)即文件個(gè)數(shù)。參數(shù)上沒什么可調(diào)的重點(diǎn)是三個(gè)數(shù)字要對(duì)得上。如果 labels_yolo 比 images 少說明有圖沒標(biāo)或漏轉(zhuǎn)先補(bǔ)齊再往下走別急著訓(xùn)練。2.2 VOC xml 與 YOLO txt 的字段差異VOC 的 xml 存的是絕對(duì)像素坐標(biāo)YOLO 的 txt 存的是歸一化后的中心點(diǎn)加寬高。兩者換算關(guān)系是固定的理解這個(gè)換算后面自己寫腳本或排查錯(cuò)框都靠它。字段VOC xmlYOLO txt坐標(biāo)形式xmin, ymin, xmax, ymax像素cx, cy, w, h0~1 歸一化類別表示namebreak_insulator/name行首數(shù)字 0類別索引每行含義一個(gè) object 節(jié)點(diǎn)一個(gè)框一行一個(gè)框依賴圖片尺寸是需讀 width/height否已歸一化換算公式cx (xminxmax)/2/widthcy (yminymax)/2/heightw (xmax-xmin)/widthh (ymax-ymin)/height。因?yàn)橹挥幸粋€(gè)類別txt 每行開頭永遠(yuǎn)是0不用維護(hù) class 映射表這也是單類別數(shù)據(jù)集省事的地方。2.3 校驗(yàn)標(biāo)簽是否越界或?yàn)榭諛?biāo)注數(shù)據(jù)最常見的暗病是框超出圖片邊界、寬高為 0、或者某張圖根本沒有對(duì)應(yīng) txt。訓(xùn)練前跑一段校驗(yàn)比訓(xùn)練到一半 loss 變 nan 再回頭查省事得多。import os, glob from PIL import Image img_dir images lbl_dir labels_yolo bad [] for img_path in glob.glob(os.path.join(img_dir, *.jpg)): name os.path.splitext(os.path.basename(img_path))[0] lbl_path os.path.join(lbl_dir, name .txt) if not os.path.exists(lbl_path): bad.append((name, missing label)); continue w, h Image.open(img_path).size with open(lbl_path) as f: lines [l.strip() for l in f if l.strip()] if not lines: bad.append((name, empty label)); continue for l in lines: cls, cx, cy, bw, bh l.split() cx, cy, bw, bh map(float, (cx, cy, bw, bh)) # 歸一化值應(yīng)在 0~1且框不能越界 if not (0 cx 1 and 0 cy 1 and 0 bw 1 and 0 bh 1): bad.append((name, out of range)) print(問題樣本, bad)邏輯說明逐圖找同名 txt檢查是否存在、是否為空、歸一化值是否越界。參數(shù)上0 bw 1排除了寬高為 0 的退化框。跑完如果bad為空說明標(biāo)簽基本干凈有輸出就按名字去修別帶著臟數(shù)據(jù)開訓(xùn)。3. 從零跑通 YOLO 訓(xùn)練環(huán)境、配置與一次完整迭代3.1 環(huán)境與依賴版本選擇YOLO 系列版本多這份數(shù)據(jù)是純檢測(cè)框、單類別用 YOLOv5 或 YOLOv8 都能直接吃。新手我一般建議先上 YOLOv8命令行封裝好配置文件少要改結(jié)構(gòu)做改進(jìn)再換 v5 或自己搭。環(huán)境上核心就三樣Python、PyTorch、ultralytics。conda create -n insulator python3.10 -y conda activate insulator # 按自己顯卡 CUDA 版本裝 torch這里以 cu118 為例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics邏輯說明單獨(dú)建環(huán)境避免和系統(tǒng)包打架。--index-url指定 PyTorch 官方源CUDA 版本要和驅(qū)動(dòng)匹配裝完用torch.cuda.is_available()驗(yàn)證返回 False 就是版本沒對(duì)上先解決再訓(xùn)練否則會(huì)退到 CPU 上慢到懷疑人生。3.2 數(shù)據(jù)集配置文件與目錄規(guī)范YOLOv8 要求 images 和 labels 分 train/val 子目錄且 labels 路徑是把 images 里的images替換成labels。所以先把數(shù)據(jù)整理成標(biāo)準(zhǔn)結(jié)構(gòu)mkdir -p datasets/insulator/images/train datasets/insulator/images/val mkdir -p datasets/insulator/labels/train datasets/insulator/labels/val # 按 8:2 劃分示例前 400 張進(jìn) train其余進(jìn) val然后寫data.yamlpath: datasets/insulator train: images/train val: images/val nc: 1 names: [break_insulator]邏輯說明nc是類別數(shù)這里只有破損絕緣子一個(gè)類寫 1names順序必須和 txt 里的類別索引一致索引 0 對(duì)應(yīng)break_insulator。path是數(shù)據(jù)集根目錄train/val 是相對(duì)它的路徑。這個(gè)文件寫錯(cuò)類別數(shù)或名字對(duì)不上訓(xùn)練不報(bào)錯(cuò)但類別全亂是最隱蔽的坑之一。3.3 啟動(dòng)訓(xùn)練與關(guān)鍵參數(shù)配置齊了就能起訓(xùn)。單類別 500 張圖屬于小數(shù)據(jù)集參數(shù)學(xué)要保守一點(diǎn)防止過擬合。yolo detect train \ datadatasets/insulator/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience30 \ projectruns/insulator \ nameexp1邏輯說明modelyolov8n.pt用官方預(yù)訓(xùn)練權(quán)重做遷移學(xué)習(xí)小數(shù)據(jù)集從零訓(xùn)幾乎學(xué)不出東西這一步別省。imgsz640是輸入分辨率破損區(qū)域小的話可以試 960但顯存和速度要權(quán)衡。batch16按顯存調(diào)爆顯存就降到 8 或 4。lr00.01是初始學(xué)習(xí)率小數(shù)據(jù)集可降到 0.005 更穩(wěn)。patience30表示 30 輪沒提升就早停省時(shí)間。訓(xùn)練完權(quán)重在runs/insulator/exp1/weights/best.pt。3.4 推理與結(jié)果查看訓(xùn)完先別急著下結(jié)論拿幾張驗(yàn)證圖跑推理肉眼看框準(zhǔn)不準(zhǔn)。yolo detect predict \ modelruns/insulator/exp1/weights/best.pt \ sourcedatasets/insulator/images/val \ conf0.25 \ saveTrue邏輯說明conf0.25是置信度閾值低于它的框不顯示。破損絕緣子這種小目標(biāo)閾值設(shè)太高會(huì)漏檢設(shè)太低會(huì)誤檢0.25 是個(gè)常用起點(diǎn)實(shí)際按驗(yàn)證集表現(xiàn)調(diào)。結(jié)果圖默認(rèn)存到runs/detect/predict重點(diǎn)看漏檢該框沒框和誤檢背景被框哪類多再?zèng)Q定調(diào)閾值還是補(bǔ)數(shù)據(jù)。4. 避坑與排查小數(shù)據(jù)集訓(xùn)練最容易翻車的幾處4.1 現(xiàn)象訓(xùn)練 loss 正常但驗(yàn)證全框錯(cuò)位原因VOC 轉(zhuǎn) YOLO 時(shí)用了錯(cuò)誤的圖片寬高或者圖片被 resize 過但標(biāo)簽沒同步。歸一化坐標(biāo)一旦基于錯(cuò)誤尺寸算框就會(huì)整體偏移。解決回到 2.3 的校驗(yàn)?zāi)_本重點(diǎn)核對(duì)Image.open(img_path).size讀到的寬高和標(biāo)注時(shí)是否一致。如果圖片被批量壓縮過標(biāo)簽必須基于壓縮后的尺寸重算不能沿用原圖坐標(biāo)。4.2 現(xiàn)象訓(xùn)練報(bào) No labels found 或某類樣本數(shù)為 0原因YOLOv8 找 labels 的規(guī)則是把路徑里的images替換成labels如果你的目錄不是這個(gè)命名或者 txt 沒放進(jìn)對(duì)應(yīng) train/val 子目錄它就找不到。解決嚴(yán)格按 3.2 的結(jié)構(gòu)放labels 下也要有 train/val。用yolo detect train啟動(dòng)后看它打印的掃描結(jié)果確認(rèn) train/val 的 images 和 labels 數(shù)量都對(duì)得上。4.3 現(xiàn)象模型把整張圖都框成破損絕緣子原因單類別數(shù)據(jù)集里如果負(fù)樣本沒有破損的圖太少模型學(xué)不到「什么不是目標(biāo)」容易過度激活。500 張里如果幾乎每張都有破損背景多樣性就不夠。解決確認(rèn)數(shù)據(jù)里是否混有正常絕緣子圖作為負(fù)樣本沒有的話推理時(shí)適當(dāng)提高conf或在訓(xùn)練時(shí)加一些背景圖。單類別檢測(cè)的誤檢很多時(shí)候是數(shù)據(jù)分布問題不是模型問題。4.4 現(xiàn)象顯存溢出CUDA out of memory原因imgsz或batch設(shè)太大或同時(shí)開了多個(gè)訓(xùn)練進(jìn)程。解決先把batch減半還不行就降imgsz到 512。YOLOv8 支持batch-1自動(dòng)選但小顯存機(jī)器上自動(dòng)值也可能偏大手動(dòng)設(shè)更穩(wěn)。4.5 現(xiàn)象訓(xùn)練幾十輪后 mAP 不升反降原因小數(shù)據(jù)集過擬合模型開始記訓(xùn)練集噪聲。解決靠patience早?;蚣訑?shù)據(jù)增強(qiáng)YOLOv8 默認(rèn)帶 mosaic、翻轉(zhuǎn)等也可以減小模型用 n 而不是 s/m。500 張圖配 nano 模型通常比大模型更合適。5. 進(jìn)階驗(yàn)證與提效把這份數(shù)據(jù)用出上限數(shù)據(jù)量擺在這500 張單類別想靠堆輪數(shù)提升很有限真正拉開差距的是驗(yàn)證方法和數(shù)據(jù)利用方式。我一般會(huì)先做一次交叉驗(yàn)證式的劃分檢查把 train/val 換幾個(gè)隨機(jī)種子重劃看 mAP 波動(dòng)大不大。波動(dòng)超過 5 個(gè)點(diǎn)說明驗(yàn)證集太小或分布不均這時(shí)候單次結(jié)果不可信得固定劃分再談?wù){(diào)參。驗(yàn)證指標(biāo)別只看 mAP50。破損絕緣子是小目標(biāo)重點(diǎn)看 mAP50-95 和 recallrecall 低說明漏檢多巡檢場(chǎng)景漏檢比誤檢危險(xiǎn)得多。用混淆矩陣確認(rèn)有沒有把背景誤判成目標(biāo)單類別下矩陣就 2x2一眼能看出問題。如果 recall 上不去優(yōu)先補(bǔ)小目標(biāo)樣本而不是調(diào)網(wǎng)絡(luò)結(jié)構(gòu)。提效上有個(gè)具體技巧把這份數(shù)據(jù)和公開的絕緣子數(shù)據(jù)做混合訓(xùn)練。單類別的好處是類別定義統(tǒng)一只要對(duì)方也是break_insulator或能映射過來直接合并 txt 即可不用改data.yaml的nc。合并后樣本量上去小目標(biāo)召回通常有明顯改善。合并前記得統(tǒng)一圖片命名避免同名覆蓋。import os, shutil, glob # 把第二份數(shù)據(jù)的圖片和標(biāo)簽并入主數(shù)據(jù)集重命名防沖突 src_img, src_lbl extra/images, extra/labels dst_img, dst_lbl datasets/insulator/images/train, datasets/insulator/labels/train prefix mix_ for p in glob.glob(os.path.join(src_img, *.jpg)): name os.path.splitext(os.path.basename(p))[0] shutil.copy(p, os.path.join(dst_img, prefix name .jpg)) lp os.path.join(src_lbl, name .txt) if os.path.exists(lp): shutil.copy(lp, os.path.join(dst_lbl, prefix name .txt))邏輯說明加統(tǒng)一前綴避免和原圖重名覆蓋圖片和標(biāo)簽同步復(fù)制保證配對(duì)。參數(shù)上prefix按來源改合并完重新跑一遍 2.3 的校驗(yàn)確認(rèn)沒有越界框再訓(xùn)練。合并數(shù)據(jù)最怕的就是標(biāo)簽和圖片錯(cuò)位這一步不能省。從那以后我每次拿到新數(shù)據(jù)集都強(qiáng)制先跑一遍數(shù)量核對(duì)和越界校驗(yàn)再動(dòng)訓(xùn)練腳本——省下的排查時(shí)間遠(yuǎn)比那幾分鐘多。這份破損絕緣子數(shù)據(jù)集結(jié)構(gòu)清晰、格式齊全適合當(dāng)單類別檢測(cè)的練手和 baseline按上面的流程走一遍基本能跑出可用的結(jié)果。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取