:數據集解析與訓練避坑指南)
簡介基于YOLO的軸承生產缺陷檢測數據集與配套代碼以568張現場圖片為基礎面向工業(yè)視覺質檢、自動化產線缺陷識別場景的開發(fā)者與學習者專門解決缺少帶標注工業(yè)樣本、難以快速上手YOLO目標檢測流程的問題。資源共1772個文件壓縮包約755MB其中包含jpg現場圖片及配套的txt、xml兩類標注文件覆蓋三類典型軸承生產缺陷另附2個Python腳本和1個YAML配置用于數據集檢查、格式轉換或訓練環(huán)境適配方便直接接入YOLO系列模型。已有337人學習下載。數據已預先完成類別ID劃分與邊界框標注省去手動標注與格式整理環(huán)節(jié)可立即用于YOLO模型的訓練、驗證和檢測效果可視化借助腳本與配置也能快速復現從數據預處理到模型評估的完整鏈路。對正在構建軸承表面缺陷檢測方案或希望系統掌握YOLO數據集制作與訓練流程的讀者這是一份結構清晰、可直接上手的實戰(zhàn)素材。1. 用YOLO做軸承缺陷檢測568張圖三類缺陷這份資源能幫你少走多少彎路聊軸承缺陷檢測繞不開YOLO上手YOLO繞不開數據集。這套資源給的是一個YOLO格式的軸承生產缺陷檢測數據集568張圖片三類缺陷圖片和同名txt標注已經按標準目錄配對好。它最適合兩類人一類是剛接觸工業(yè)視覺、想用一個真實小數據集把YOLO訓練全流程跑通的開發(fā)者另一類是在軸承檢測項目里做算法選型、需要一份帶標注數據來驗證訓練管線的工程師。先說一個反直覺的結論568張圖在深度學習里不算多但對工業(yè)缺陷檢測來說已經足夠暴露大部分問題。數據標注是否一致、類別是否均衡、小缺陷是否漏標、訓練參數是否激進都能在這個規(guī)模下看出端倪。把這份資源的每一張標注當成調試工具來用比單純追求“更大的數據集”更實際。2. 拆這份數據集的底細文件命名、標簽格式與類別分布跑訓練前最怕的不是模型選錯而是數據集拿到手就直接塞給訓練腳本。下面按“盤點文件→讀懂單行標注→統計類別分布→劃分訓練集”四個步驟拆開每一步都能找到對應的檢查手段。2.1 先盤點文件圖片、標簽、類別清單三者要一一對應從項目給出的圖片列表看圖片命名是356.jpg、355.jpg、357.jpg這類純數字編號。對應的YOLO標簽通常同名、后綴為.txt放在labels目錄。解壓后第一步我建議做三件事數圖片數量、數標簽數量、檢查重復文件名。# 在數據集根目錄執(zhí)行先看總量 find images -name *.jpg | wc -l find labels -name *.txt | wc -l這里有個容易被忽略的細節(jié)原始文件列表里359.jpg出現了兩次。重復文件名在Windows解壓、網盤同步、git管理時都可能產生。如果images目錄里同一張圖有兩份標簽文件卻只有一份訓練時這張圖會被重復采樣導致模型對該張圖過擬合如果圖片去重了但標簽留了兩份則標簽統計數量虛高。我一般會先把重復名字拎出來單獨查一下# 找出所有重復圖片名輸出重復清單 find images -name *.jpg | xargs -n1 basename | sort | uniq -dsort和uniq -d組合起來能直接列出出現超過一次的文件名比用Python腳本更快速。看到重復項不要直接刪先比較文件大小和md5值再決定保留哪一份。另外還要確認是否存在classes.txt或data.yaml這個文件定義了三個類別ID的對應順序沒有它后面訓練時的類別名會亂掉。2.2 讀懂txt單行標注類別ID、歸一化坐標和邊界框寬高YOLO的標注文件不是直接存像素坐標而是存歸一化坐標。每一行格式固定為類別ID x_center y_center width height前四列都是相對于圖片寬高的比例值取值范圍通常是0~1只有類別ID是整數。假設有一張1280x1024的軸承端面圖其中一個缺陷的邊界框中心是(320, 512)框寬128像素、高64像素那么對應txt里的一行是1 0.250000 0.500000 0.100000 0.062500這個例子中五列分別表示類別ID為1、框中心x比例0.25、框中心y比例0.5、框寬比例0.1、框高比例0.0625。讀標簽時最需要警惕兩類錯誤一類是坐標沒有歸一化直接寫成像素值訓練時邊界框會超出圖片范圍另一類是五個數字的順序寫錯把x_center和width對調訓練不報錯但丟失效果極差。在開始訓練前我通常會把每張圖對應的txt打開至少看三行確認里邊的類別ID確實是0、1、2而不是1、2、3。如果編碼是從1開始把所有類別ID統一減1否則data.yaml里的nc和names會全部錯位。還有一個值得注意的細節(jié)檢查一下標簽里有沒有0.000000或1.000000這類邊緣值。如果坐標落在圖片邊界上有可能是標注時手滑拖出了畫面這類框在增強時容易被裁剪掉導致訓練數據白白丟失一部分。2.3 用Python統計類別分布和框大小先判斷數據是否可訓工業(yè)缺陷檢測里三類缺陷數量往往不對稱。某個缺陷占一半以上另外兩類加起來都不到30%。568張圖本身不多這種不平衡會被進一步放大。所以我在拿到數據集后的第一件事是寫一個統計腳本把每個類別的樣本數、每張圖的平均框數、平均框尺寸算出來。import glob from collections import Counter labels glob.glob(labels/*.txt) cls_counter Counter() box_counter 0 total_w 0.0 total_h 0.0 for lb in labels: with open(lb, r, encodingutf-8) as f: for line in f: parts line.strip().split() if len(parts) 5: continue cls_counter[int(parts[0])] 1 box_counter 1 total_w float(parts[3]) total_h float(parts[4]) print(類別分布:, dict(cls_counter)) print(總標注框數:, box_counter) if box_counter: print(平均框尺寸占比: {:.3f} x {:.3f}.format(total_w / box_counter, total_h / box_counter))腳本邏輯并不復雜讀取labels目錄下所有txt文件逐行解析五列內容把第一列作為類別ID計入Counter把寬高比例累加后求平均。輸出結果里如果某一類樣本數只有幾十個、平均框寬低于0.05就是一個預警信號。前者說明樣本太少需要復制增強后者說明缺陷目標偏小需要提高輸入分辨率或使用SAHI切片推理。類別ID對應的業(yè)務含義需要和數據集自帶的class定義對應。一個典型的三類缺陷映射可能長這樣類別ID常見缺陷類型訓練檢查項0表面裂紋確認裂紋框是否貼緊缺陷1劃痕劃痕常為長條檢查錨框長寬比2邊緣毛刺邊緣缺陷容易漏檢單獨看AP實際類別名以壓縮包內classes.txt或README中寫明的為準。這里給出的是最常見的映射方案不是從該數據集硬性推出的。確認好類別后把統計腳本的輸出和這張表對照就能知道訓練前需不需要做類別重平衡。2.4 劃分train/val不要直接隨機切按類別做分層抽樣很多教程會讓你直接執(zhí)行一個隨機劃分腳本把圖片按比例分成兩份。在小數據集上這種隨機劃分很容易導致val集中缺少某類缺陷。比如某個類別總共只有30張隨機分15%出來可能只有3張到val另外還有可能一張都分不到。驗證集里缺類mAP計算時該類的AP算作0產生誤導性的結果。我建議按類別分層抽樣先把所有包含類別A、B、C的圖片分別列出來再按各自類別數量的一定比例抽取val。用Python實現時最簡潔的方式是使用scikit-learn里的train_test_split或者直接寫一個簡單的分層腳本import glob import random from collections import defaultdict random.seed(42) img_files glob.glob(images/*.jpg) by_cls defaultdict(list) for img in img_files: lb img.replace(images, labels).replace(.jpg, .txt) if not os.path.exists(lb): continue with open(lb, r, encodingutf-8) as f: cls_set set(line.split()[0] for line in f if line.strip()) by_cls[tuple(sorted(cls_set))].append(img) val_imgs set() for cls_key, imgs in by_cls.items(): val_count max(1, int(len(imgs) * 0.15)) val_imgs.update(random.sample(imgs, val_count)) print(val圖片數:, len(val_imgs))這段腳本的核心邏輯是先把圖片按“包含哪些類別”分組再從每個分組中按15%抽到val。這樣即使一張圖同時含三類缺陷也不會被重復分進val。最終train和val的目錄可以用一個shutil.move循環(huán)完成。這里提醒一句不要在腳本里把jpg的替換寫成大寫.JPG不同平臺導出的圖片后綴大小寫不統一會導致標簽匹配失敗。3. 用這份數據把YOLO訓練跑通目錄編排、訓練命令和首輪評估數據盤點結束接下來就是落地訓練。這里推薦的流程以YOLOv8為準因為它的自定義數據集接口比Darknet更干凈適合快速驗證如果你執(zhí)意要用Darknet數據結構是一樣的但配置文件和anchor計算要額外處理。YOLOv8的訓練流程分四步編排目錄、寫data.yaml、跑訓練命令、解讀首輪輸出。3.1 目錄編排images和labels同級train和val分開YOLOv8要求數據集根目錄下必須有images和labels兩個同級目錄每個目錄下再按train和val分開。很多人習慣把圖片放在data/img、標簽放在data/label訓練腳本找不到標簽浪費一整個下午查路徑。標準結構如下bearing_defect/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ ├── data.yaml └── classes.txt這里的目錄名不能改寫成image、label或者annotations除非你愿意修改訓練腳本里的路徑拼接邏輯。特別需要注意的是train和val的圖片目錄與標簽目錄必須一一對應images/train里的每一張圖必須在labels/train里有同名txt。不能把A目錄下的圖配到B目錄下的標簽即使路徑能對上數量訓練腳本也會因為找不到同名文件而把圖丟棄。劃分時我一般把val控制在總樣本量的15%~20%。568張圖的情況下train可以放460張左右val放100張左右。如果某個類別在val里的樣本數少于5張說明劃分比例可能有問題需要回到2.4里的分層抽樣調整。3.2 寫data.yamlnc和names決定模型知道自己在檢測什么data.yaml是YOLO訓練的數據入口。它至少需要四個字段path或數據根目錄、train相對路徑、val相對路徑、nc和names。一個可用的配置如下# data.yaml path: /home/user/bearing_defect train: images/train val: images/val nc: 3 names: 0: crack 1: scratch 2: burr這里nc是類別總數names是類別名。這看起來簡單但卻是訓練配置里最容易出錯的字段。如果標簽里實際出現了類別ID3而nc仍然填3訓練腳本會把ID3的行當作無效標注扔掉表現為loss下降正常但mAP上不去。如果names的下標寫成了1、2、3和標簽ID差一位推理時類別名會全部錯位部署到界面時顯示的缺陷類型完全不對。類別名建議用英文小寫。工業(yè)軟件里經常用中文顯示缺陷名稱但訓練配置里使用中文會在Windows環(huán)境出現編碼問題轉TensorRT時還要額外處理字符映射。正確做法是訓練時用crack、scratch、burr這樣的英文名在業(yè)務界面里再做一次中文翻譯。3.3 YOLOv8訓練命令參數不是越大越好準備就緒后在終端或PyCharm里運行訓練命令。以yolov8s為預訓練權重命令如下yolo train datadata.yaml modelyolov8s.pt epochs300 imgsz640 batch16 patience30 projectruns/bearing_defect nameexp1參數選擇有明確的業(yè)務邏輯。modelyolov8s.pt選s而不是n是因為工業(yè)缺陷目標普遍偏小s模型的頸部網絡能保留更多細節(jié)epochs300看起來多但配合patience30實際可能在120輪左右就停止屬于“給足預算但允許早?!钡膶懛āmgsz640是第一輪驗證用的分辨率如果后續(xù)發(fā)現小缺陷漏檢再提高到768或1024。batch16在12G顯存上比較穩(wěn)妥8G卡建議降到8。這里最容易被誤解的是patience。它代表多少個epoch沒有改善就停止訓練而不是最多訓練多少輪。小數據集的loss曲線震蕩嚴重如果patience設成10模型可能在上升期被截斷設到30到50更合理。訓練過程中不要隨手改參數重啟先讓它跑完一個完整輪次再看曲線。如果不想用命令行在PyCharm里直接運行Python腳本也是一樣的核心調用是from ultralytics import YOLO model YOLO(yolov8s.pt) model.train(datadata.yaml, epochs300, imgsz640, batch16, patience30)不管是命令行還是腳本邏輯完全一致只是寫法不同。第一次跑的時候建議開啟verboseTrue讓控制臺打印出每個epoch的完整信息方便后面排查問題。3.4 首輪輸出怎么讀先別盯總mAP看單類AP和預測圖訓練啟動后控制臺先打印模型結構、參數量、FLOPs然后進入epoch迭代。第一個epoch結束時終端會出現val指標包括mAP50和mAP50-95。在568張圖的小數據集上第一次迭代的mAP可能只有0.2甚至更低這是正常的模型還沒有充分學習。真正要盯的是后面幾十個epoch里mAP是否持續(xù)上升。訓練結束后進入runs/bearing_defect/exp1/目錄重點看兩個文件。第一是results.png里面有box_loss、cls_loss、mAP曲線。如果box_loss一直在降但mAP50在某個位置不再變化優(yōu)先懷疑某個類別的標注噪音。第二是val_batch0_pred.jpg這類可視化圖看預測框是緊貼缺陷邊緣還是把金屬紋理反光也框了進來。后者在軸承表面高反光場景非常常見僅靠mAP看不出來。相比DarknetYOLOv8訓練自定義數據集時少了一個麻煩anchor自動學習。Darknet需要預先計算anchor尺寸輸入圖片為640分辨率時用錯anchor就會導致很多候選框根本不覆蓋小缺陷。YOLOv8的anchor是自動調整的但代價是更依賴數據本身的標注質量。如果val圖上一個框都沒畫出來先回標簽格式和目錄里去查不要先懷疑模型結構。3.5 小數據集的過擬合信號loss下降、單類AP異常工業(yè)場景里過擬合不是單純“mAP低”而是訓練集mAP很高、val mAP波動大甚至反向下降。在results.png中這種信號的典型表現是box_loss在train側降到0.02以下但val側box_loss重新抬頭兩個曲線分叉。原因是網絡開始記住568張圖里某些獨特的金屬紋理而不是學習缺陷本身的共性。對這種過擬合最有效的手段不是縮小模型而是加強數據增強和正則化??梢栽谟柧毭钪性黾釉鰪妳当热鏷sv_h0.015, hsv_s0.7, hsv_v0.4, degrees10.0, translate0.1, scale0.5讓模型每次看到的是同一缺陷的不同光照和角度版本。軸承檢測還有一個特殊的有效手段隨機裁剪。把圖像增強里的mosaic1.0和mixup0.2打開模型對非缺陷背景的過擬合會明顯緩解。這個內容不需要修改代碼YOLOv8把這些開放成了訓練參數。4. 軸承缺陷數據集的常見問題排查五個坑現象原因與解決下面五條是從實際項目中反復踩出來、驗證過的通用問題直接對號入座就行。4.1 圖片與標簽數量不一致訓練報“found no labels”現象數據目錄配置好后運行訓練腳本終端提示找不到標簽或者labels里的txt數量明顯少于images里的圖片數量每個epoch幾秒鐘就結束val階段沒有任何預測輸出。原因大部分情況是解壓工具丟文件或者文件名沒有嚴格同名。YOLO慣例是0001.jpg對應0001.txt如果圖片是.jpg標簽寫了.jpeg.xml或者圖片是png而標簽是txt數量就會對不上。還有一個隱藏原因某些網盤在Windows下解壓會把長文件名截斷后綴變成奇怪的縮寫標簽文件無法被識別。解決先不要改訓練腳本用清單比對腳本把問題文件找出來。import os from pathlib import Path img_dir Path(images) label_dir Path(labels) imgs {p.stem: p for p in img_dir.rglob(*) if p.suffix.lower() in (.jpg, .jpeg, .png)} labels {p.stem: p for p in label_dir.rglob(*.txt)} missing_label [str(p) for name, p in imgs.items() if name not in labels] missing_image [str(p) for name, p in labels.items() if name not in imgs] print(缺標簽圖片數:, len(missing_label)) print(缺圖片標簽數:, len(missing_image))這段腳本用stem作為關聯鍵把圖片和標簽分別裝進兩個字典然后對比缺失項。它比直接數文件數量更可靠因為它能發(fā)現同名但放在錯誤子目錄的情況。輸出的清單里如果缺的是標簽回到標注工具重新導出如果缺的是圖片檢查是不是被誤移動到backup目錄。4.2 標簽里出現第四類nc參數錯位導致誤檢現象訓練時loss能正常下降推理時在無缺陷區(qū)域頻繁輸出高置信度框而且框的位置與軸承邊緣紋理高度相關。查看類別統計時發(fā)現出現了標簽ID大于等于3的標注。原因項目在標注時把“背景”或“正?!币矘顺闪艘粋€類別導出YOLO格式時背景成了類別0三類缺陷順延成1、2、3。data.yaml里nc仍然填3類別3的標注被訓練腳本忽略模型實際看到的有效類別只剩兩個背景紋理被迫承擔了第三個類別的預測任務。解決先統計一下標簽里的最大類別ID。如果確實出現了3而且第4類是背景正確的做法是刪除該類別對應的所有標簽行而不是把nc改成4。因為軸承缺陷檢測場景下無法窮舉所有正常紋理把背景當成一個類別訓練在線推理時必然會出現大量假陽性。# 找出含類別ID大于2的標簽文件 grep -rlE ^[3-9] labels/ | head -n 20用grep快速定位含異常ID的文件然后單獨處理。如果異常ID是標注失誤直接修改對應行如果是一個獨立類別要回到標注工具確認這個類別是否有足夠樣本支撐訓練。實話說在568張圖這個規(guī)模下不建議用四類數據硬訓去掉背景類、聚焦三類缺陷更容易拿到可交付的模型。4.3 劃痕類缺陷漏檢嚴重mAP50不低產線實測打不到現象驗證集mAP50達到了0.85以上但拿現場拍的新圖測試細小的劃痕和淺裂紋基本漏檢偶爾框出來的也是斷斷續(xù)續(xù)的片段。放大預測圖后發(fā)現預測框比缺陷本身大很多。原因劃痕是典型的長條形小目標寬高比常有1:10甚至更極端。YOLO默認輸出層會對特征圖做下采樣640分辨率輸入時一個寬度占比不到3%的小劃痕在下采樣后的特征圖上可能只剩1到2個像素特征強度不夠。另外如果標注框貼著劃痕的包圍盒但長寬比極端模型回歸難度也高。解決優(yōu)先把imgsz提高到768或1024這一步對長條形缺陷的提升通常比換模型更明顯。接著在訓練參數中開啟更強的增強尤其是degrees15和scale0.5讓模型見到不同旋轉角度和不同尺度的劃痕。還有一招是把該類別單獨復制一份做拼接增強比如把多個小劃痕圖拼成一張訓練圖變相增加該類別在每張圖里的出現頻率。如果實測階段仍然漏檢把檢測置信度閾值從默認的0.25適當降低到0.1再看漏檢情況。閾值降低會增加誤檢但可以用來區(qū)分“模型學到了但沒有自信”和“模型根本沒學到”。這一步在生產環(huán)境里要謹慎閾值的最終值要結合誤檢成本來確定。4.4 正常軸承圖片混進訓練集模型開始學會漏檢現象訓練loss表現正常推理時對沒有缺陷的軸承也輸出高置信度框誤檢率居高不下換個場景真實缺陷反而被漏檢。原因無標注圖片放在了images目錄里訓練腳本會把它們當作負樣本背景。這類圖片數量一旦偏多模型學到的傾向是“盡量輸出空框”。更有問題的是如果一張圖里有缺陷但漏標了訓練腳本會認為該區(qū)域的紋理屬于背景直接壓制模型對同類缺陷的響應。解決把正常件、無標注圖、漏標注圖全部從訓練目錄里請出去。正常件如果確實要參與訓練要么單獨加一個normal類別要么不在訓練集里出現、只作為推理階段的負樣本測試集。在軸承產線上無缺陷樣本往往比缺陷樣本容易獲取得多正確用法是留一批正常圖專門做閾值調參和誤檢率統計而不是混在訓練數據里讓模型“自己悟”。4.5 顯存不足、PyCharm里訓練中斷batch、workers、cache順序排查現象訓練跑到第幾十個epoch時突然報CUDA out of memory或者整個IDE卡死重啟后訓練進度丟失。部分時候現象表現為CPU吃掉絕大部分核GPU利用率卻只有零頭。原因8G或12G顯存的機器上imgsz640、batch16、yolov8s理論上能跑但疊加了Mosaic增強、緩存、過多的數據加載線程后顯存和內存會同時飆升。尤其是PyCharm這類IDE里跑訓練解釋器自帶的內存分配和調試器會額外吃掉一部分資源問題更容易復現。解決依次調整三個參數。第一是batch8顯存占用大約減半第二是顯式設置cacheFalse關閉數據緩存第三是workers2降低數據加載線程數。如果這三個都改了還崩把imgsz降到480試試。已經中斷的時候weights目錄下通常有l(wèi)ast.pt直接在訓練命令末尾加resumeTrue就能從最近一次保存的權重繼續(xù)不用從頭開始。需要說明的是resume依賴YOLOv8內部斷點機制如果中斷前沒正常保存就不要強求繼續(xù)直接檢查日志定位原因更實際。5. 從mAP到產線可用三類缺陷的驗證順序和部署參數邊界訓練收尾后離產線還差兩步驗證順序和部署參數。先說驗證順序。我拿到一個訓練好的模型不會直接看總mAP而是按三個步驟執(zhí)行。第一步打開results.png看三類缺陷各自的AP曲線找到明顯短板的那一類第二步用該類的真實圖像做預測可視化區(qū)分是漏檢、誤檢還是定位偏移第三步截取一段生產現場視頻按10秒一段統計誤檢次數。這套順序能在不寫復雜代碼的情況下把模型的主要失效模式定位出來。部署時最常被問到的問題是T4上用TensorRT跑640分辨率YOLO能支持多少路1080p 25fps的視頻流。這類問題的答案不能靠嘴說必須實測。我的做法是先用batch1測單路純推理時間然后把總幀率除以單路幀率再乘一個0.7的安全系數。真正容易翻車的地方有三個一是只測了模型推理時間沒有算視頻解碼和前后處理二是沒有考慮多個推理進程共享顯存時的峰值三是int8量化之后小缺陷的AP可能比fp16掉得更明顯。對軸承這類小目標缺陷場景建議量化后逐個類別重新跑一次AP再決定用int8還是fp16。如果某一類缺陷的AP掉了超過3個百分點就退回fp16。自從我做過一次“只測推理時間就定方案”的蠢事以后每次拿到新的軸承缺陷模型都會強制走一遍“逐類AP→誤檢視頻測試→三檔量化對比”的流程確認所有參數后才去談路數。這個習慣救過我很多次希望幫到你。本文還有配套的精品資源點擊獲取