:1200張數(shù)據(jù)集訓(xùn)練與調(diào)優(yōu)指南)
簡介本資源為面向計算機視覺學(xué)習(xí)者和物流質(zhì)檢場景的YOLO快遞包裹與包裝盒缺陷檢測數(shù)據(jù)集適合具備一定目標(biāo)檢測基礎(chǔ)、希望快速開展訓(xùn)練與驗證的開發(fā)者。數(shù)據(jù)集共包含1200余張標(biāo)注圖像覆蓋Box、Box_broken、Open_package、Package四類目標(biāo)可支撐包裹破損識別、拆封狀態(tài)判斷等實際任務(wù)。壓縮包內(nèi)共2000個文件以1200個txt格式標(biāo)簽和799張jpg圖像為主另附1個yaml配置文件整體約28.19MB目錄已按train、val、test劃分完畢data.yaml中訓(xùn)練與驗證路徑、類別數(shù)及名稱均已配置yolov5、yolov7、yolov8、yolov9等主流框架可直接讀取并啟動訓(xùn)練。目前已有643人學(xué)習(xí)下載資源結(jié)構(gòu)清晰、開箱即用能幫助讀者省去數(shù)據(jù)整理與格式轉(zhuǎn)換環(huán)節(jié)將精力集中在模型選型、參數(shù)調(diào)優(yōu)與缺陷檢測效果對比上。1. 快遞包裹缺陷檢測數(shù)據(jù)集1200 張圖能撐起一個 YOLO 項目嗎快遞分揀線上紙箱破損、膠帶開裂、面單褶皺、包裹凹陷這幾類缺陷靠人眼盯著監(jiān)控屏幕一天下來漏檢率能到兩位數(shù)。很多做視覺的同行第一反應(yīng)是上 YOLO但真正卡住進度的從來不是模型結(jié)構(gòu)而是手里沒有一批標(biāo)注干凈、類別對齊、能直接喂進訓(xùn)練腳本的圖。這份「YOLO算法快遞包裹包裝盒缺陷檢測數(shù)據(jù)集」給的就是 1200 張已經(jīng)打好標(biāo)注的圖片覆蓋包裹和包裝盒兩類目標(biāo)上的常見缺陷格式按 YOLO 的 txt 標(biāo)注組織拿到手就能接進 ultralytics 的訓(xùn)練流程。它適合三類人剛?cè)腴T YOLO 想找一個真實工業(yè)場景練手的、做物流分揀質(zhì)檢需要快速驗證算法可行性的、以及手上有一堆現(xiàn)場圖但懶得從零標(biāo)一遍的。1200 張不算大但作為缺陷檢測的起步集夠你把數(shù)據(jù)管線、增強策略和評估口徑全部跑通一遍。2. 數(shù)據(jù)集結(jié)構(gòu)與 YOLO 標(biāo)注格式先看清目錄再動手2.1 目錄組織與文件對應(yīng)關(guān)系拿到一個目標(biāo)檢測數(shù)據(jù)集我習(xí)慣先不急著寫訓(xùn)練腳本而是把目錄結(jié)構(gòu)摸清楚。YOLO 格式的數(shù)據(jù)集通常長這樣一個 images 目錄放原圖一個 labels 目錄放同名 txt兩邊文件名一一對應(yīng)差一個后綴。這份快遞包裹缺陷數(shù)據(jù)集也是這個套路圖片是常見的 jpg標(biāo)注是 txt每行代表一個目標(biāo)框格式為類別索引 中心x 中心y 寬 高后四個值都是歸一化到 0 到 1 之間的小數(shù)。先跑一段腳本把目錄結(jié)構(gòu)和類別分布統(tǒng)計出來這一步能幫你提前發(fā)現(xiàn)很多問題比如某類缺陷只有十幾張、標(biāo)注框?qū)捀叱霈F(xiàn)負數(shù)、圖片和標(biāo)簽對不上號。import os from collections import Counter img_dir dataset/images lbl_dir dataset/labels # 統(tǒng)計圖片與標(biāo)簽的配對情況 imgs {os.path.splitext(f)[0] for f in os.listdir(img_dir)} lbls {os.path.splitext(f)[0] for f in os.listdir(lbl_dir)} print(圖片數(shù):, len(imgs), 標(biāo)簽數(shù):, len(lbls)) print(有圖無標(biāo)簽:, imgs - lbls) print(有標(biāo)簽無圖:, lbls - imgs) # 統(tǒng)計每個類別的目標(biāo)框數(shù)量 cls_counter Counter() for f in os.listdir(lbl_dir): with open(os.path.join(lbl_dir, f)) as fp: for line in fp: line line.strip() if line: cls_counter[int(line.split()[0])] 1 print(類別分布:, dict(sorted(cls_counter.items())))這段腳本做了兩件事一是用集合差集找出圖片和標(biāo)簽不匹配的文件二是遍歷所有標(biāo)簽文件統(tǒng)計每個類別的框數(shù)量。參數(shù)上img_dir和lbl_dir按你實際解壓后的路徑改。跑完如果發(fā)現(xiàn)「有圖無標(biāo)簽」不是空集說明有圖片漏標(biāo)訓(xùn)練時這些圖會被當(dāng)成純背景可能拉低召回如果某個類別框數(shù)只有個位數(shù)那這個類基本訓(xùn)不出來得考慮合并或補數(shù)據(jù)。2.2 類別索引與 data.yaml 配置YOLO 訓(xùn)練不認(rèn)中文類別名它只認(rèn)整數(shù)索引索引到名字的映射寫在 data.yaml 里。這份數(shù)據(jù)集的類別大概率是「包裹缺陷」和「包裝盒缺陷」兩類也可能拆得更細比如破損、開裂、凹陷分開。不管幾類data.yaml 的結(jié)構(gòu)是固定的path: ./dataset train: images/train val: images/val nc: 2 names: 0: package_defect 1: box_defectpath是數(shù)據(jù)集根目錄train和val是相對 path 的圖片路徑nc是類別數(shù)names是索引到名字的字典。這里有個血淚經(jīng)驗nc必須和 names 的條目數(shù)嚴(yán)格一致多一個少一個訓(xùn)練啟動時不一定報錯但評估階段混淆矩陣會直接錯位你看到的 mAP 就是假的。另外 names 的順序必須和標(biāo)注文件里的索引對上如果標(biāo)注里 0 是包裝盒、1 是包裹你 yaml 里寫反了模型學(xué)出來的東西整個顛倒。提示改完 data.yaml 先用yolo checks或手動加載一次配置確認(rèn)路徑能被解析到別等訓(xùn)練跑了半小時才發(fā)現(xiàn) val 路徑是空的。2.3 訓(xùn)練集與驗證集劃分1200 張圖如果全拿去訓(xùn)練你沒有任何獨立數(shù)據(jù)判斷模型是否過擬合。常見做法是按 8:2 或 7:3 切分訓(xùn)練集和驗證集。切分時要注意一點同一個包裹或同一個包裝盒的多角度圖盡量分到同一側(cè)否則驗證集里出現(xiàn)訓(xùn)練時見過的目標(biāo)mAP 會虛高。import random, shutil, os random.seed(42) names sorted(os.listdir(dataset/images)) random.shuffle(names) split int(len(names) * 0.8) for i, n in enumerate(names): dst train if i split else val shutil.copy(fdataset/images/{n}, fdataset/images/{dst}/{n}) shutil.copy(fdataset/labels/{os.path.splitext(n)[0]}.txt, fdataset/labels/{dst}/{os.path.splitext(n)[0]}.txt)random.seed(42)固定隨機種子保證每次切分結(jié)果一致方便復(fù)現(xiàn)。split控制訓(xùn)練集比例0.8 就是 80%。復(fù)制而不是移動是為了保留原始數(shù)據(jù)切錯了還能重來。跑完之后 images 下會有 train 和 val 兩個子目錄labels 下同理data.yaml 里的路徑也要相應(yīng)改成images/train和images/val。3. 用 ultralytics 跑通訓(xùn)練從環(huán)境到第一組權(quán)重3.1 環(huán)境安裝與版本選擇YOLO 生態(tài)現(xiàn)在最省心的是 ultralytics 這個庫pip 一條命令就能裝。但版本選擇有講究YOLOv8 穩(wěn)定、文檔全、社區(qū)問題好搜YOLOv11 更新但部分算子對老顯卡支持一般。如果你顯卡是 30 系或 40 系v8 和 v11 都能跑如果是更老的卡建議先確認(rèn) CUDA 版本再定。conda create -n yolo_defect python3.10 -y conda activate yolo_defect pip install ultralytics8.2.0 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118第一行建一個干凈的 Python 3.10 環(huán)境缺陷檢測這類項目別用系統(tǒng) Python依賴沖突能折騰你一整天。第二行激活環(huán)境。第三行裝 ultralytics這里鎖了 8.2.0是因為這個版本 API 穩(wěn)定網(wǎng)上教程對得上。第四行單獨裝 PyTorchcu118對應(yīng) CUDA 11.8你要根據(jù)自己的驅(qū)動版本換裝錯了訓(xùn)練時會報CUDA error: no kernel image is available。裝完跑一句yolo checks它會打印出 PyTorch 版本、CUDA 是否可用、顯卡型號。如果 CUDA 顯示不可用先別往下走回去查驅(qū)動和 PyTorch 版本匹配。3.2 訓(xùn)練命令與關(guān)鍵參數(shù)環(huán)境通了就可以起訓(xùn)練。ultralytics 的命令行接口很直接但參數(shù)不設(shè)對1200 張圖也能訓(xùn)出個廢物模型。yolo detect train \ datadataset/data.yaml \ modelyolov8n.pt \ epochs150 \ imgsz640 \ batch16 \ lr00.01 \ patience30 \ projectruns/defect \ nameexp1逐項說data指向你的 yamlmodelyolov8n.pt用 nano 版預(yù)訓(xùn)練權(quán)重1200 張圖的數(shù)據(jù)量n 或 s 就夠了上 l 或 x 只會過擬合epochs150是上限配合patience30做早停30 輪驗證指標(biāo)不漲就停省時間imgsz640是輸入分辨率缺陷目標(biāo)如果很小可以提到 960 或 1280但顯存占用會翻倍batch16按顯存調(diào)8G 顯存跑 640 分辨率大概能到 16爆顯存就降到 8lr00.01是初始學(xué)習(xí)率小數(shù)據(jù)集別設(shè)太大否則 loss 震蕩。訓(xùn)練過程中終端會打印每輪的 box_loss、cls_loss、mAP50、mAP50-95。box_loss 管定位cls_loss 管分類兩個都降才是正常收斂。如果 cls_loss 一直不降多半是類別不平衡或標(biāo)注有問題回到第 2 章那個統(tǒng)計腳本再查一遍。3.3 訓(xùn)練過程監(jiān)控與中斷恢復(fù)訓(xùn)練不是按了回車就完事中間要看曲線。ultralytics 會在runs/defect/exp1下生成 results.csv 和一堆可視化圖重點是 results.png 里的三條線訓(xùn)練 loss、驗證 loss、mAP。訓(xùn)練 loss 降但驗證 loss 漲是過擬合加數(shù)據(jù)增強或減模型容量兩條都降但 mAP 不動可能是學(xué)習(xí)率太小或標(biāo)注框質(zhì)量差。如果訓(xùn)練中途斷了比如斷電或手滑關(guān)了終端不用從頭來yolo detect train resume modelruns/defect/exp1/weights/last.ptresume會從 last.pt 里讀回優(yōu)化器狀態(tài)和輪次接著往下跑。但注意只有 last.pt 存在時才能恢復(fù)如果你只留了 best.pt那就只能重新訓(xùn)。我一般會在訓(xùn)練腳本外面套一層 nohup 或 tmux避免終端斷開導(dǎo)致訓(xùn)練中斷。4. 缺陷檢測的坑從標(biāo)注到推理的排查清單4.1 標(biāo)注框越界與零面積框現(xiàn)象訓(xùn)練啟動時報normalized coordinates out of range或者 loss 直接變 NaN。原因標(biāo)注文件里某個框的歸一化坐標(biāo)小于 0 或大于 1或者寬高算出來是 0。解決寫個校驗?zāi)_本把所有標(biāo)簽掃一遍越界的截斷到 0 到 1零面積的直接刪掉那一行。for f in os.listdir(lbl_dir): path os.path.join(lbl_dir, f) lines open(path).read().strip().split(\n) clean [] for line in lines: p line.split() if len(p) ! 5: continue c, x, y, w, h int(p[0]), *map(float, p[1:]) if w 0 or h 0: continue x, y min(max(x, 0), 1), min(max(y, 0), 1) w, h min(w, 1 - x), min(h, 1 - y) clean.append(f{c} {x:.6f} {y:.6f} {w:.6f} {h:.6f}) open(path, w).write(\n.join(clean))這段邏輯是逐行解析跳過格式不對的行丟棄零面積框把中心點和寬高裁到合法范圍。:.6f保留六位小數(shù)YOLO 對精度不敏感但統(tǒng)一格式能避免解析歧義。4.2 類別不平衡導(dǎo)致小類召回為零現(xiàn)象訓(xùn)練完看混淆矩陣某一類缺陷的召回率是 0模型把所有目標(biāo)都預(yù)測成另一類。原因1200 張圖里兩類缺陷數(shù)量差距大比如包裹缺陷 900 個框、包裝盒缺陷只有 80 個框模型傾向于預(yù)測多數(shù)類。解決一是用cls權(quán)重加權(quán)的損失二是在 data.yaml 里給少數(shù)類復(fù)制樣本三是用 mosaic 和 mixup 增強時提高少數(shù)類出現(xiàn)概率。ultralytics 默認(rèn)的增強已經(jīng)包含 mosaic但類別平衡還得自己動手。4.3 驗證集 mAP 高但實際推理漏檢現(xiàn)象驗證集 mAP50 到 0.9拿現(xiàn)場圖一測漏檢嚴(yán)重。原因驗證集和訓(xùn)練集來自同一批拍攝條件光照、角度、背景都相似模型沒學(xué)到泛化特征。解決從現(xiàn)場另找一批沒參與訓(xùn)練的圖做測試集哪怕只有幾十張也能暴露真實問題。另外檢查推理時的conf閾值默認(rèn) 0.25 偏高缺陷檢測可以降到 0.1 到 0.15 再試。4.4 圖片和標(biāo)簽文件名大小寫不一致現(xiàn)象訓(xùn)練時提示找不到標(biāo)簽但你去目錄里看文件明明在。原因圖片叫IMG_001.jpg標(biāo)簽叫img_001.txtLinux 下大小寫敏感Windows 下不敏感跨系統(tǒng)就翻車。解決統(tǒng)一轉(zhuǎn)成小寫或者寫腳本按圖片名去匹配標(biāo)簽名匹配不上的打印出來人工處理。4.5 顯存溢出與 batch 設(shè)置現(xiàn)象訓(xùn)練跑了幾輪突然CUDA out of memory。原因batch 設(shè)太大或者 imgsz 提太高或者驗證階段同時加載了太多圖。解決先把 batch 減半還不行就降 imgsz再不行用yolo detect train ... ampFalse關(guān)掉混合精度混合精度省顯存但偶爾會溢出。另外 ultralytics 的cacheTrue會把圖片緩存到內(nèi)存內(nèi)存不夠也會崩1200 張圖不大可以開但更大數(shù)據(jù)集要謹(jǐn)慎。5. 推理部署與效果驗證把權(quán)重跑成能看的檢測結(jié)果5.1 單圖與批量推理訓(xùn)練完 best.pt 在runs/defect/exp1/weights/下拿它做推理yolo detect predict \ modelruns/defect/exp1/weights/best.pt \ sourcetest_images \ conf0.15 \ iou0.5 \ saveTruesource可以是單張圖、一個目錄、甚至一段視頻。conf0.15是置信度閾值缺陷檢測寧可多報也別漏報所以比默認(rèn) 0.25 低。iou0.5是 NMS 的 IoU 閾值兩個框重疊超過 0.5 就合并缺陷目標(biāo)如果密集可以提到 0.6 減少誤合并。saveTrue會把畫了框的圖存到runs/detect/predict下。5.2 用驗證集指標(biāo)判斷模型能不能用推理出圖好看不代表模型能用得看量化指標(biāo)。訓(xùn)練結(jié)束后終端會打印一行匯總重點是 mAP50 和 mAP50-95。mAP50 是 IoU 閾值 0.5 時的平均精度缺陷檢測一般要求 0.85 以上mAP50-95 更嚴(yán)格能到 0.5 以上就算不錯。如果 mAP50 高但 mAP50-95 低說明框的位置不夠準(zhǔn)可能是標(biāo)注框偏大或偏小回去抽查幾張標(biāo)注圖。from ultralytics import YOLO model YOLO(runs/defect/exp1/weights/best.pt) metrics model.val(datadataset/data.yaml, splitval) print(mAP50:, metrics.box.map50) print(mAP50-95:, metrics.box.map) print(每類AP:, metrics.box.ap50)model.val會重新在驗證集上跑一遍評估返回的metrics.box.map50就是 mAP50ap50是每個類別的 AP 數(shù)組順序和 data.yaml 里 names 的順序一致。如果某一類 AP 明顯低單獨把那一類的圖挑出來看大概率是標(biāo)注質(zhì)量問題。5.3 導(dǎo)出 ONNX 與推理速度驗證如果要把模型部署到產(chǎn)線PyTorch 權(quán)重不夠快通常導(dǎo)出 ONNX 或 TensorRT。ONNX 通用性好TensorRT 在 N 卡上快但綁定硬件。yolo export modelruns/defect/exp1/weights/best.pt formatonnx imgsz640導(dǎo)出后在同目錄生成 best.onnx。驗證 ONNX 推理是否和 PyTorch 一致可以拿同一張圖分別跑對比框的數(shù)量和坐標(biāo)。常見坑是導(dǎo)出時 imgsz 和訓(xùn)練時不一致導(dǎo)致精度掉一截所以導(dǎo)出命令里顯式寫imgsz640。5.4 一個具體技巧用 TTA 提升小缺陷召回缺陷目標(biāo)往往很小單次推理容易漏。測試時增強TTA是個后悔藥把圖翻轉(zhuǎn)、縮放幾次分別推理再合并結(jié)果。ultralytics 推理時加augmentTrue就能開 TTAyolo detect predict modelbest.pt sourcetest_images augmentTrue conf0.1代價是推理時間翻幾倍適合離線質(zhì)檢或?qū)λ俣炔幻舾械沫h(huán)節(jié)。我一般會在模型上線前用 TTA 跑一遍驗證集看看 mAP 能漲多少如果漲幅不到 1 個點就不值得為它犧牲速度。從那以后我每次拿到新的缺陷數(shù)據(jù)集都強制先跑一遍標(biāo)注校驗和類別分布統(tǒng)計再決定要不要動模型結(jié)構(gòu)——數(shù)據(jù)上的坑模型補不回來。希望這份 1200 張的快遞包裹缺陷數(shù)據(jù)集能幫你把 YOLO 缺陷檢測這條路先走通一遍。本文還有配套的精品資源點擊獲取