練你的第一個 YOLOv8 缺陷檢測模型)
保姆級教程零基礎(chǔ)訓(xùn)練你的第一個 YOLOv8 缺陷檢測模型附 5 個產(chǎn)線真實(shí)踩坑目標(biāo)讀者會基本 Python、沒訓(xùn)過模型的工程師。目標(biāo)跟著本文一步步走訓(xùn)出第一個可用的工業(yè)缺陷檢測模型。全文以木料缺齒檢測為例每一步都附上我們項(xiàng)目中真實(shí)踩過的坑幫你繞開。0. 先看全貌整個流程五步別被術(shù)語嚇住拍圖 → 標(biāo)注 → 訓(xùn)練 → 驗(yàn)證 → 導(dǎo)出 (攢幾十張) (畫框) (一條命令) (看指標(biāo)) (一條命令)訓(xùn)練不需要 GPU百張級數(shù)據(jù)集 yolov8n純 CPU 訓(xùn) 200 輪約 40 分鐘。1. 環(huán)境準(zhǔn)備以 Ubuntu 22.04 為例Windows 的區(qū)別見代碼塊下方說明。先裝 Python 虛擬環(huán)境支持再建環(huán)境# Ubuntu安裝 venv 支持sudoaptupdatesudoaptinstallpython3-venv python3-pip# 創(chuàng)建并激活虛擬環(huán)境python3-mvenv yolo_envsourceyolo_env/bin/activate# 安裝 ultralytics國內(nèi)加 -i 鏡像源加速pipinstallultralytics-ihttps://pypi.tuna.tsinghua.edu.cn/simpleWindows 用戶跳過apt那兩行直接用python -m venv yolo_env創(chuàng)建環(huán)境激活命令換成yolo_env\Scripts\activate其余相同。驗(yàn)證安裝yolo version# 能打印版本號就 OK有 N 卡想 GPU 訓(xùn)練的再裝對應(yīng) CUDA 版的 PyTorch沒有就跳過CPU 完全夠用。2. 準(zhǔn)備圖片拍多少、怎么拍數(shù)量單類缺陷 50 張能跑通150 張左右能談上線。先拍 50 張把流程跑通NG 圖是主角每種缺陷至少 20~30 張OK 圖也要拍 10~20 張正常產(chǎn)品圖不用標(biāo)注讓模型見過好的是什么樣子這是壓誤檢的關(guān)鍵拍照條件盡量和現(xiàn)場一致同一相機(jī)、同一光照、同一角度。實(shí)驗(yàn)室擺拍的光線和產(chǎn)線不一樣訓(xùn)出來上線就翻車。圖片放到dataset/images_all/目錄格式 jpg/png 都行。坑 1用實(shí)驗(yàn)室擺拍圖代替現(xiàn)場圖。我們早期在實(shí)驗(yàn)室補(bǔ)光擺拍光線均勻背景干凈指標(biāo)很好上線后現(xiàn)場光照變化大、背景雜亂誤檢明顯偏多只能按現(xiàn)場條件全部重拍。實(shí)驗(yàn)室擺拍可以用來驗(yàn)證流程跑通但不要進(jìn)訓(xùn)練集——模型學(xué)的是數(shù)據(jù)分布訓(xùn)練圖和現(xiàn)場圖差多少上線效果就差多少。3. 標(biāo)注給缺陷畫框標(biāo)注工具任選國內(nèi)網(wǎng)絡(luò)都能正常使用工具形態(tài)適合誰labelImg本地客戶端pip 安裝首選輸出直接是 YOLO 格式精靈標(biāo)注助手國產(chǎn)客戶端官網(wǎng)直接下載不想碰命令行makesense.ai在線網(wǎng)頁免安裝臨時(shí)標(biāo)幾十張注意圖片需上傳CVAT自部署網(wǎng)頁版多人協(xié)作再用新手不必以 labelImg 為例走清華鏡像安裝不依賴 GitHubpipinstalllabelImg-ihttps://pypi.tuna.tsinghua.edu.cn/simple labelImg dataset/images_all/操作要點(diǎn)打開后把保存格式切到Y(jié)OLO默認(rèn)是 PascalVOC 的 XML一定要切W鍵畫框D鍵下一張類別先只建一個比如missing_tooth第一版不要貪多類別。每張圖標(biāo)完生成同名.txt每行一個框0 0.512 0.384 0.062 0.105 # ↑類別編號(從0開始) 中心x 中心y 寬 高均為0~1歸一化值4. 整理目錄 劃分訓(xùn)練/驗(yàn)證集YOLO 要求的目錄結(jié)構(gòu)dataset/ ├── train/images/ ← 訓(xùn)練圖 ├── train/labels/ ← 訓(xùn)練標(biāo)注 txt ├── val/images/ ← 驗(yàn)證圖 └── val/labels/自動劃分腳本8:2# split_dataset.py — 用法: python split_dataset.py dataset/images_all datasetimportrandom,shutil,sysfrompathlibimportPath src,dstPath(sys.argv[1]),Path(sys.argv[2])images[pforpinsrc.iterdir()ifp.suffix.lower()in(.jpg,.png,.bmp)]random.seed(42)random.shuffle(images)n_valmax(1,int(len(images)*0.2))val_setset(images[:n_val])forsubin(train,val):(dst/sub/images).mkdir(parentsTrue,exist_okTrue)(dst/sub/labels).mkdir(parentsTrue,exist_okTrue)forimginimages:subvalifimginval_setelsetrainshutil.copy(img,dst/sub/images/img.name)labelimg.with_suffix(.txt)iflabel.exists():shutil.copy(label,dst/sub/labels/label.name)# 沒有 txt 的是 OK 圖只復(fù)制圖片即可print(ftrain:{len(images)-n_val}張, val:{n_val}張)坑 2train/val 隨手按張劃分。同一根木料連拍的多張圖高度相似隨機(jī)劃分會把親兄弟圖分到訓(xùn)練集和驗(yàn)證集兩邊驗(yàn)證等于開卷考試指標(biāo)虛高上線后對不上。正確做法是按根劃分同一根木料的所有圖整體進(jìn)一邊。上面的腳本是隨機(jī)劃分有連拍場景的話分完務(wù)必手動檢查 val 目錄。再寫dataset.yamlpath:/絕對路徑/datasettrain:train/imagesval:val/imagesnc:1names:[missing_tooth]5. 訓(xùn)練一條命令yolo trainmodelyolov8n.ptdatadataset.yaml\imgsz512epochs200patience100batch8devicecpu逐參數(shù)說明參數(shù)含義建議modelyolov8n.pt從官方預(yù)訓(xùn)練權(quán)重起步必須用.pt見坑 3imgsz512輸入尺寸和部署端保持一致見坑 4epochs200最多訓(xùn)練輪數(shù)往大設(shè)配合 patience 早停patience100100 輪無提升則停止不用改batch8每批圖片數(shù)內(nèi)存不夠改 4devicecpu訓(xùn)練設(shè)備有顯卡改0坑 3從頭訓(xùn)練不用預(yù)訓(xùn)練權(quán)重。幾十張圖從頭訓(xùn)訓(xùn)練 loss 降得很漂亮但模型實(shí)際是把訓(xùn)練圖的背景紋理背下來了驗(yàn)證集上誤檢大量出現(xiàn)。換成yolov8n.pt預(yù)訓(xùn)練權(quán)重后立刻正?!A(yù)訓(xùn)練權(quán)重已經(jīng)學(xué)過邊緣、紋理、角點(diǎn)等通用底層特征小數(shù)據(jù)集只需學(xué)習(xí)缺陷本身的特征。注意modelyolov8n.pt遷移學(xué)習(xí)和modelyolov8n.yaml隨機(jī)初始化從頭訓(xùn)只差后綴效果天壤之別。坑 4訓(xùn)練用 640、部署用 512。我們早期版本訓(xùn)練用 640部署端為了壓節(jié)拍改成 512 后小缺陷置信度整體下滑、開始漏檢——模型按 640 的特征尺度學(xué)習(xí)輸入突然變小就匹配不上了。后續(xù)版本全部統(tǒng)一為 512 訓(xùn)練后恢復(fù)。原則訓(xùn)練輸入尺寸跟著部署走。訓(xùn)練產(chǎn)物在runs/detect/train/weights/best.pt。6. 看結(jié)果三個文件就夠打開runs/detect/train/results.png損失曲線。train loss 持續(xù)下降而 val loss 走平或回升說明開始過擬合下次可減少 epochsval_batch0_pred.jpg驗(yàn)證集預(yù)測可視化肉眼檢查框的位置是否準(zhǔn)確results.csv最后幾行指標(biāo)metrics/recall最重要漏檢率 1 ? 召回率產(chǎn)線優(yōu)先看這個metrics/precision對應(yīng)誤檢率metrics/mAP50綜合指標(biāo)0.9 以上較好???5只盯 mAP不數(shù)誤檢/漏檢個數(shù)。mAP 是綜合指標(biāo)漲兩個點(diǎn)不代表產(chǎn)線關(guān)心的問題有改善。我們后來建了固定的 OK/NG 測試集22 張 OK 標(biāo)準(zhǔn)樣 留存的 NG 圖每版模型跑一遍只數(shù)兩個數(shù)誤檢幾個、漏檢幾個。這兩個數(shù)和客戶驗(yàn)收口徑一致比曲線直觀。置信度閾值的調(diào)整也在這套測試集上做不再憑感覺定。7. 拿新圖驗(yàn)證找?guī)讖垱]參與訓(xùn)練的現(xiàn)場圖跑一遍yolo predictmodelruns/detect/train/weights/best.ptsource你的測試圖目錄結(jié)果在runs/detect/predict/。逐張檢查漏檢和誤檢不理想的圖標(biāo)注后補(bǔ)進(jìn)數(shù)據(jù)集重訓(xùn)——這就是數(shù)據(jù)迭代循環(huán)。8. 導(dǎo)出部署yoloexportmodelruns/detect/train/weights/best.ptformatonnximgsz512得到best.onnx交給部署程序OpenVINO 加載推理的完整過程見本系列部署篇。常見問題yolo命令找不到虛擬環(huán)境沒激活標(biāo)注了但訓(xùn)練提示沒有標(biāo)簽labelImg 保存格式?jīng)]切成 YOLO或 txt 未與圖片同名類別編號錯亂txt 第一列從 0 開始順序?qū)?yīng)dataset.yaml的names路徑報(bào)錯Windows 路徑避免中文和空格CPU 訓(xùn)練看似卡住CPU 跑滿即在正常訓(xùn)練200 輪約 40 分鐘。小結(jié)五個坑其實(shí)是同一條原則的不同體現(xiàn)訓(xùn)練的每個環(huán)節(jié)都要對齊最終部署和驗(yàn)收的真實(shí)條件——預(yù)訓(xùn)練權(quán)重 → 對齊真實(shí)數(shù)據(jù)量幾十張不是幾萬張按根劃分 → 對齊真實(shí)的樣本獨(dú)立性訓(xùn)練尺寸 部署尺寸 → 對齊真實(shí)輸入現(xiàn)場實(shí)拍 → 對齊真實(shí)圖像分布數(shù)誤檢/漏檢 → 對齊真實(shí)驗(yàn)收口徑系列文章《YOLOv8 工業(yè)缺陷檢測實(shí)戰(zhàn)上48 張缺陷圖起步8 個版本迭代到上線的完整記錄》《YOLOv8 工業(yè)缺陷檢測實(shí)戰(zhàn)下小樣本訓(xùn)練怎么把誤檢/漏檢率壓到產(chǎn)線標(biāo)準(zhǔn)》《YOLOv8 部署到無 GPU 工控機(jī)實(shí)戰(zhàn)ONNX 導(dǎo)出 OpenVINO 推理 手寫后處理》