:開(kāi)箱即用權(quán)重與數(shù)據(jù)集實(shí)戰(zhàn)指南)
簡(jiǎn)介本資源面向從事工業(yè)質(zhì)檢、深度學(xué)習(xí)目標(biāo)檢測(cè)的開(kāi)發(fā)者與研究人員提供一套可直接復(fù)現(xiàn)的YOLOv7鋼材缺陷檢測(cè)方案解決鋼材表面缺陷自動(dòng)識(shí)別與模型訓(xùn)練問(wèn)題。壓縮包共166個(gè)文件約203.86MB包含31個(gè)Python腳本、36個(gè)yaml配置、14個(gè)ipynb實(shí)驗(yàn)筆記、2個(gè)pt權(quán)重文件以及jpg圖片、xml與txt標(biāo)簽、png圖表、sh腳本和Dockerfile等覆蓋訓(xùn)練、推理、導(dǎo)出與部署環(huán)節(jié)。數(shù)據(jù)集使用labelImg標(biāo)注圖片為jpg格式標(biāo)簽同時(shí)提供xml與txt兩種格式便于適配不同框架。資源內(nèi)含已訓(xùn)練好的檢測(cè)模型及PR曲線、loss曲線等評(píng)估結(jié)果可幫助讀者快速驗(yàn)證模型性能、理解訓(xùn)練過(guò)程并遷移到自有數(shù)據(jù)。目前已有1288人學(xué)習(xí)下載適合具備一定深度學(xué)習(xí)基礎(chǔ)、希望快速搭建鋼材缺陷檢測(cè)流程的讀者參考使用。1. 鋼材缺陷檢測(cè)為什么選 YOLOv7一份開(kāi)箱即用的權(quán)重與數(shù)據(jù)集產(chǎn)線上鋼板跑得飛快人眼盯久了必然漏檢傳統(tǒng)圖像處理又扛不住光照和氧化皮變化所以鋼材缺陷檢測(cè)這件事繞不開(kāi)目標(biāo)檢測(cè)。這份資源給的就是一條能直接跑通的路YOLOv7 鋼材缺陷檢測(cè)模型已經(jīng)訓(xùn)練好權(quán)重、PR 曲線、loss 曲線都在配套數(shù)據(jù)集用 labelImg 標(biāo)好jpg 圖片加 xml、txt 雙格式標(biāo)簽省掉了從零標(biāo)注和從零訓(xùn)練這兩件最耗時(shí)間的事。適合兩類人一類是想快速驗(yàn)證鋼材缺陷檢測(cè)能不能落地的算法工程師另一類是要拿現(xiàn)成數(shù)據(jù)集和權(quán)重做二次訓(xùn)練、換產(chǎn)線換缺陷類型的人。下面按「資源是什么、怎么跑、坑在哪」拆開(kāi)講。2. 拆開(kāi)資源包權(quán)重、數(shù)據(jù)集與訓(xùn)練曲線的對(duì)應(yīng)關(guān)系拿到一個(gè)檢測(cè)項(xiàng)目我第一件事不是急著跑推理而是先把包里的東西和它的用途對(duì)上號(hào)。鋼材缺陷檢測(cè)這類工業(yè)場(chǎng)景權(quán)重和數(shù)據(jù)集必須配套否則類別對(duì)不上檢測(cè)框會(huì)亂飛。這一章先把資源結(jié)構(gòu)講清楚再講怎么驗(yàn)證權(quán)重是不是真的能用。2.1 權(quán)重文件與訓(xùn)練產(chǎn)物的識(shí)別YOLOv7 訓(xùn)練完會(huì)產(chǎn)出幾類文件用途完全不同。.pt是 PyTorch 權(quán)重用來(lái)推理和繼續(xù)訓(xùn)練best.pt是驗(yàn)證集表現(xiàn)最好的那一版last.pt是最后一輪實(shí)際部署優(yōu)先用best.pt。資源里還有events.out.tfevents.*這類 TensorBoard 日志PR 曲線、loss 曲線就是從它里面讀出來(lái)的不是單獨(dú)的圖片文件得用 TensorBoard 打開(kāi)看。常見(jiàn)做法是先確認(rèn)權(quán)重對(duì)應(yīng)的類別數(shù)和類別名。YOLOv7 的權(quán)重里存了names字典直接加載就能打印出來(lái)import torch # 加載訓(xùn)練好的鋼材缺陷權(quán)重 ckpt torch.load(best.pt, map_locationcpu) model ckpt[model] if model in ckpt else ckpt # 打印類別信息確認(rèn)缺陷類型和數(shù)量 names model.names if hasattr(model, names) else ckpt.get(names) print(類別數(shù):, len(names)) print(類別名:, names)這段代碼的關(guān)鍵在map_locationcpu避免在沒(méi)有 GPU 的機(jī)器上加載時(shí)報(bào) CUDA 相關(guān)錯(cuò)誤。names打印出來(lái)就是這份權(quán)重認(rèn)識(shí)的缺陷類型鋼材場(chǎng)景常見(jiàn)的是夾雜、劃痕、斑塊、麻點(diǎn)這類具體以打印結(jié)果為準(zhǔn)。如果names是空的說(shuō)明權(quán)重保存方式不同需要從訓(xùn)練時(shí)的data.yaml里找類別定義。2.2 數(shù)據(jù)集目錄結(jié)構(gòu)與標(biāo)簽格式數(shù)據(jù)集這塊資源里圖片是 jpg標(biāo)簽給了 xml 和 txt 兩套分別放在兩個(gè)文件夾。xml 是 labelImg 直接存的 Pascal VOC 格式txt 是 YOLO 訓(xùn)練要的歸一化格式兩者內(nèi)容一致只是坐標(biāo)表達(dá)不同。YOLO 的 txt 每行是類別索引 中心x 中心y 寬 高全部歸一化到 0 到 1 之間。標(biāo)準(zhǔn)目錄一般長(zhǎng)這樣steel_dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── data.yamldata.yaml是訓(xùn)練和驗(yàn)證的入口配置內(nèi)容大致如下train: ./images/train val: ./images/val nc: 4 names: [inclusion, scratch, patch, pitted]nc是類別數(shù)names順序必須和 txt 里的類別索引嚴(yán)格對(duì)應(yīng)索引 0 對(duì)應(yīng)names第一個(gè)。這里最容易翻車xml 轉(zhuǎn) txt 時(shí)如果類別順序和data.yaml不一致訓(xùn)練 loss 會(huì)正常下降但檢測(cè)結(jié)果全錯(cuò)位屬于典型的「訓(xùn)練看著沒(méi)問(wèn)題、用起來(lái)全廢」。2.3 用 TensorBoard 讀 PR 曲線和 loss 曲線資源里帶了events.out.tfevents文件說(shuō)明訓(xùn)練過(guò)程有記錄??辞€不是為了好看是為了判斷這份權(quán)重能不能直接用。啟動(dòng) TensorBoardtensorboard --logdir ./runs/train --port 6006瀏覽器打開(kāi)對(duì)應(yīng)端口重點(diǎn)看三樣metrics/mAP_0.5是否收斂到合理區(qū)間、train/box_loss和val/box_loss是否背離、PR 曲線里每個(gè)類別的 AP 是否均衡。如果某個(gè)缺陷類別 AP 明顯偏低說(shuō)明這類樣本少或者標(biāo)注質(zhì)量差直接拿來(lái)檢測(cè)會(huì)漏。鋼材缺陷里斑塊和劃痕的 AP 通常差異較大看曲線時(shí)要有心理預(yù)期。提示TensorBoard 日志和權(quán)重必須來(lái)自同一次訓(xùn)練混用不同 run 的日志會(huì)得出錯(cuò)誤結(jié)論。3. 跑通推理與訓(xùn)練從單張圖片到自定義數(shù)據(jù)集資源能直接用但「直接用」和「用對(duì)」是兩回事。這一章講兩件事怎么用現(xiàn)成權(quán)重做推理驗(yàn)證以及怎么在它的基礎(chǔ)上換數(shù)據(jù)集繼續(xù)訓(xùn)練。鋼材缺陷檢測(cè)的落地多數(shù)時(shí)候不是從零訓(xùn)而是拿這份權(quán)重做微調(diào)。3.1 用訓(xùn)練好的權(quán)重做單張與批量推理YOLOv7 官方倉(cāng)庫(kù)的detect.py是推理入口。假設(shè)權(quán)重是best.pt圖片放在inference/imagespython detect.py \ --weights best.pt \ --source inference/images \ --img-size 640 \ --conf-thres 0.25 \ --iou-thres 0.45 \ --device 0參數(shù)逐個(gè)說(shuō)清楚--img-size 640是推理分辨率訓(xùn)練時(shí)用的多少這里就填多少改大了精度可能略升但速度掉--conf-thres 0.25是置信度閾值鋼材缺陷里小目標(biāo)多閾值設(shè)太高會(huì)漏檢設(shè)太低誤檢多0.25 是個(gè)常用起點(diǎn)--iou-thres 0.45控制 NMS 合并重疊缺陷多的時(shí)候可以適當(dāng)調(diào)高--device 0指定第一塊 GPU沒(méi)有 GPU 就寫cpu但速度會(huì)慢很多。推理結(jié)果默認(rèn)存到runs/detect/exp每張圖會(huì)畫出框和類別。驗(yàn)證權(quán)重是否可用我一般挑幾張有代表性的缺陷圖看框有沒(méi)有框偏、類別有沒(méi)有認(rèn)錯(cuò)。如果框位置對(duì)但類別全錯(cuò)回到 2.2 檢查類別順序如果框都框不住檢查--img-size是否和訓(xùn)練一致。3.2 在現(xiàn)有權(quán)重上做遷移訓(xùn)練換產(chǎn)線、換缺陷類型時(shí)最省事的做法是拿這份權(quán)重當(dāng)預(yù)訓(xùn)練凍結(jié)一部分層再訓(xùn)。YOLOv7 訓(xùn)練命令python train.py \ --weights best.pt \ --cfg cfg/training/yolov7.yaml \ --data data/steel.yaml \ --epochs 100 \ --batch-size 16 \ --img-size 640 \ --hyp data/hyp.scratch.p5.yaml \ --device 0--weights best.pt就是加載現(xiàn)成權(quán)重做初始化比從頭訓(xùn)收斂快很多--cfg指定模型結(jié)構(gòu)要和權(quán)重匹配YOLOv7 和 YOLOv7-e6 的結(jié)構(gòu)文件不同用錯(cuò)會(huì)報(bào)維度不匹配--hyp是超參文件鋼材缺陷樣本通常不多可以適當(dāng)調(diào)低學(xué)習(xí)率、增強(qiáng) mosaic 的概率。--batch-size受顯存限制16 是 640 分辨率下的常見(jiàn)值顯存不夠就往下調(diào)調(diào)到 8 甚至 4 也能訓(xùn)只是 batch norm 效果會(huì)差一些。訓(xùn)練過(guò)程中重點(diǎn)盯val/box_loss如果它先降后升說(shuō)明過(guò)擬合早?;蛘呒訑?shù)據(jù)增強(qiáng)。鋼材缺陷數(shù)據(jù)集往往類別不均衡某個(gè)缺陷只有幾十張圖這時(shí)候要么補(bǔ)樣本要么在hyp里調(diào)類別權(quán)重。3.3 導(dǎo)出 ONNX 與 TensorRT 做部署準(zhǔn)備資源里帶了YOLOv7-Dynamic-Batch-ONNXRUNTIME.ipynb和YOLOv7-Dynamic-Batch-TENSORRT.ipynb說(shuō)明作者考慮過(guò)部署。工業(yè)產(chǎn)線對(duì)速度敏感PyTorch 直接推理往往不夠?qū)С?ONNX 再轉(zhuǎn) TensorRT 是常見(jiàn)路徑。導(dǎo)出 ONNXpython export.py \ --weights best.pt \ --grid \ --img-size 640 640 \ --batch-size 1 \ --dynamic--grid是 YOLOv7 導(dǎo)出 ONNX 的必要參數(shù)漏了會(huì)報(bào)錯(cuò)--dynamic開(kāi)啟動(dòng)態(tài) batch方便后面按產(chǎn)線吞吐調(diào) batch--img-size要和訓(xùn)練一致。導(dǎo)出后用onnxruntime驗(yàn)證一遍輸出維度確認(rèn)沒(méi)有算子不支持。TensorRT 那步在 notebook 里做核心是設(shè)置合適的 workspace 和精度模式FP16 通常能提速且精度損失可接受INT8 需要校準(zhǔn)集鋼材缺陷場(chǎng)景要謹(jǐn)慎量化誤差可能讓小缺陷直接消失。4. 避坑與排查鋼材缺陷檢測(cè)里最容易翻車的幾件事這一章是我自己踩過(guò)和見(jiàn)別人踩過(guò)的坑按「現(xiàn)象 → 原因 → 解決」寫鋼材缺陷檢測(cè)場(chǎng)景尤其明顯?,F(xiàn)象推理結(jié)果框位置正確但類別全亂。原因xml 轉(zhuǎn) txt 時(shí)類別索引和data.yaml的names順序不一致或者多個(gè)標(biāo)注人員用了不同的類別拼寫。解決寫腳本統(tǒng)一校驗(yàn)把所有 txt 里的類別索引去重和names逐一對(duì)齊拼寫不一致的先歸一化再轉(zhuǎn)?,F(xiàn)象訓(xùn)練 loss 正常下降但 mAP 一直很低。原因標(biāo)簽歸一化坐標(biāo)算錯(cuò)常見(jiàn)的是用絕對(duì)坐標(biāo)除以了錯(cuò)誤的寬高或者 xml 里 xmin、xmax 順序顛倒。解決隨機(jī)抽幾張圖用腳本把 txt 框畫回原圖肉眼確認(rèn)框和缺陷重合這一步比看 loss 有用得多?,F(xiàn)象小缺陷漏檢嚴(yán)重。原因--img-size設(shè)得比訓(xùn)練小或者--conf-thres設(shè)太高。鋼材里麻點(diǎn)、細(xì)小劃痕本身就占幾十個(gè)像素縮圖后信息丟失。解決推理分辨率不低于訓(xùn)練分辨率conf 閾值從 0.25 往下試到 0.1同時(shí)看 PR 曲線里該類別的召回?,F(xiàn)象換機(jī)器后加載權(quán)重報(bào) CUDA 錯(cuò)誤。原因權(quán)重保存時(shí)綁定了特定 GPU 環(huán)境或者 torch 版本不匹配。解決torch.load加map_locationtorch 版本盡量和訓(xùn)練時(shí)一致跨版本加載失敗就重新導(dǎo)出 ONNX 再推理?,F(xiàn)象TensorBoard 打不開(kāi)或曲線是空的。原因--logdir指到了父目錄但里面多個(gè) run 混在一起或者 events 文件損壞。解決--logdir精確指到單次訓(xùn)練的 run 目錄確認(rèn) events 文件大小不為 0必要時(shí)重新訓(xùn)練一小輪生成新日志。注意鋼材缺陷數(shù)據(jù)集如果來(lái)自不同產(chǎn)線光照和背景差異大直接混訓(xùn)會(huì)讓模型兩頭不討好建議先分域驗(yàn)證再合并。5. 進(jìn)階技巧用驗(yàn)證集反推權(quán)重是否值得二次訓(xùn)練最后一章講一個(gè)我常用的判斷方法拿到一份現(xiàn)成權(quán)重和數(shù)據(jù)集先別急著訓(xùn)用驗(yàn)證集跑一遍看每個(gè)類別的 AP 和混淆矩陣再?zèng)Q定是微調(diào)還是重訓(xùn)。這一步能省掉大量無(wú)效訓(xùn)練時(shí)間。具體做法是拿val集跑test.pypython test.py \ --weights best.pt \ --data data/steel.yaml \ --img-size 640 \ --batch-size 16 \ --task val \ --device 0跑完會(huì)輸出每個(gè)類別的 P、R、mAP0.5、mAP0.5:0.95。我的判斷習(xí)慣是如果多數(shù)類別 mAP0.5 已經(jīng)過(guò) 0.8只有一兩個(gè)類別低那就在現(xiàn)有權(quán)重上補(bǔ)這類樣本微調(diào)epoch 不用多30 到 50 輪足夠如果整體都低說(shuō)明這份權(quán)重和你的數(shù)據(jù)域差太遠(yuǎn)不如拿它當(dāng)預(yù)訓(xùn)練從頭訓(xùn)或者干脆換更貼近的權(quán)重。再進(jìn)一步可以看混淆矩陣判斷是類別之間互相誤判還是背景被誤檢成缺陷。鋼材場(chǎng)景里斑塊和夾雜容易混如果混淆矩陣顯示這兩類互相串微調(diào)時(shí)就要針對(duì)性加這兩類的難例樣本而不是盲目加數(shù)據(jù)量。還有個(gè)細(xì)節(jié)驗(yàn)證時(shí)--img-size和--batch-size要和訓(xùn)練保持一致否則 mAP 會(huì)虛高或虛低得不出正確結(jié)論。我一般會(huì)把驗(yàn)證結(jié)果和 TensorBoard 里的 PR 曲線對(duì)照著看兩邊一致才認(rèn)為這份權(quán)重可信。從那以后我每次拿到別人訓(xùn)好的權(quán)重都強(qiáng)制先跑一遍驗(yàn)證集、畫一遍框、對(duì)一遍類別順序再?zèng)Q定要不要用。這套流程幫我避開(kāi)了不少「看著能用、上線就廢」的坑。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取