實(shí)戰(zhàn):700張VOC數(shù)據(jù)集訓(xùn)練YOLO模型全流程)
簡(jiǎn)介一份面向變電站繼電保護(hù)控制柜屏幕檢測(cè)的計(jì)算機(jī)視覺數(shù)據(jù)集包含七百?gòu)埰聊粓D像配套VOC格式標(biāo)注文件適用于電力智能化、工業(yè)視覺方向的研究人員與開發(fā)者可用于訓(xùn)練卷積神經(jīng)網(wǎng)絡(luò)、YOLO系列等目標(biāo)檢測(cè)模型實(shí)現(xiàn)電壓讀數(shù)、電流曲線、指示燈等元素的自動(dòng)識(shí)別支撐遠(yuǎn)程監(jiān)控、故障診斷與自動(dòng)化巡檢等場(chǎng)景。資源共一千四百五十個(gè)文件其中七百二十五幅jpg圖像與七百二十五份xml標(biāo)簽一一對(duì)應(yīng)壓縮包約32.29MB結(jié)構(gòu)清晰便于直接進(jìn)行模型訓(xùn)練與驗(yàn)證該數(shù)據(jù)集采用PASCAL VOC注釋標(biāo)準(zhǔn)涵蓋對(duì)象名稱、邊界框坐標(biāo)、遮擋與截?cái)酄顟B(tài)等關(guān)鍵信息可配合主流目標(biāo)檢測(cè)框架使用。目前已有1301人學(xué)習(xí)下載數(shù)據(jù)規(guī)模適中、標(biāo)注規(guī)范適合開展屏幕檢測(cè)算法實(shí)驗(yàn)、遷移學(xué)習(xí)調(diào)優(yōu)以及語(yǔ)義分割等進(jìn)階研究通過該數(shù)據(jù)集電力行業(yè)有望加速實(shí)現(xiàn)自動(dòng)化、實(shí)時(shí)的變電站監(jiān)控與故障預(yù)測(cè)提升供電系統(tǒng)的穩(wěn)定性與安全性。1. 變電站屏幕檢測(cè)數(shù)據(jù)集700張VOC圖能不能直接訓(xùn)出能用的模型變電站的繼電保護(hù)屏上跳動(dòng)著頻率、電壓、開關(guān)位置和告警報(bào)文巡檢員一天要看幾十面柜子靠人眼盯屏既費(fèi)人力也容易漏。做屏幕檢測(cè)的第一步是拿到一套帶標(biāo)簽的工業(yè)圖像數(shù)據(jù)集比如這套700張圖像、VOC標(biāo)簽的變電站繼電保護(hù)控制柜屏幕數(shù)據(jù)。先說(shuō)清楚這里的“屏幕檢測(cè)”定位的是屏幕區(qū)域本身不是去OCR屏幕里的每一個(gè)字符。坐標(biāo)框住的是液晶屏、指示燈面板和保護(hù)裝置的人機(jī)交互界面。VOC標(biāo)簽意味著每個(gè)XML文件里記錄了目標(biāo)類別和邊界框能直接喂給目標(biāo)檢測(cè)訓(xùn)練流程。適合讀這篇筆記的人是剛?cè)胧值谝粋€(gè)工業(yè)視覺數(shù)據(jù)集的算法工程師或者是做電力智能巡檢落地、正為訓(xùn)練數(shù)據(jù)發(fā)愁的實(shí)施人員。700張不算多但按正確流程處理足夠訓(xùn)練出第一個(gè)可上驗(yàn)證臺(tái)的檢測(cè)模型。2. 先用腳本讀懂VOC標(biāo)簽坐標(biāo)、類別分布與屏幕畫面構(gòu)成2.1 拿到700張圖先別進(jìn)訓(xùn)練腳本先看清拍到的是什么畫面很多工業(yè)數(shù)據(jù)集的坑不在模型訓(xùn)練階段而在你根本不了解圖像內(nèi)容。我第一次拿到類似數(shù)據(jù)集時(shí)直接跑轉(zhuǎn)換腳本結(jié)果訓(xùn)練到一半發(fā)現(xiàn)一半圖像是過曝的另一半是柜門半開的廢圖。正確做法是先做目錄拓?fù)浜蛨D像尺寸的抽樣檢查確認(rèn)這批圖的采集來(lái)源、分辨率和拍攝視角。# 先摸清數(shù)據(jù)集的目錄結(jié)構(gòu)與圖像尺寸 find . -type f \( -name *.jpg -o -name *.png -o -name *.xml \) | head -20 python3 - PY import glob from PIL import Image imgs sorted(glob.glob(images/*.jpg) glob.glob(images/*.png)) print(圖像總數(shù):, len(imgs)) for p in imgs[:8]: im Image.open(p) print(p, im.size, im.mode) PY這段腳本做了兩件事第一條命令列出數(shù)據(jù)集里的圖片和XML文件的前20個(gè)路徑讓你看清圖像文件與標(biāo)簽文件是否一一對(duì)應(yīng)Python片段統(tǒng)計(jì)圖像總數(shù)并打印前8張的分辨率與色彩模式。為什么要看這些因?yàn)楣I(yè)相機(jī)和手機(jī)拍攝的圖混在一起時(shí)分辨率差異會(huì)直接影響后續(xù)歸一化坐標(biāo)的準(zhǔn)確性PIL讀出來(lái)尺寸若與XML中記錄的width不一致就是標(biāo)簽污染的源頭。抽樣檢查建議按等間隔抽20張不用隨機(jī)抽。隨機(jī)抽容易集中在同一個(gè)時(shí)段等間隔能看到拍攝時(shí)間推進(jìn)過程中光照、屏幕亮度和柜門狀態(tài)的變化。人工過一遍重點(diǎn)確認(rèn)三件事屏幕在畫面中的占比是否穩(wěn)定是否存在一個(gè)畫面里出現(xiàn)兩三塊屏幕的情況以及有沒有大量連續(xù)幀高度相似——如果700張里有200張幾乎是同一秒拍的訓(xùn)練集的有效信息量就會(huì)縮水。2.2 把VOC的XML解析成統(tǒng)計(jì)表類別、數(shù)量、框面積分布VOC標(biāo)簽的XML結(jié)構(gòu)很固定根節(jié)點(diǎn)annotation下是filename、size每個(gè)object節(jié)點(diǎn)里有name和bndboxbndbox里是xmin、ymin、xmax、ymax四個(gè)整數(shù)坐標(biāo)。這個(gè)格式人類可讀但機(jī)器處理不方便。我一般先把所有XML解析成一張CSV表后續(xù)的格式轉(zhuǎn)換、類別統(tǒng)計(jì)、框面積分析都基于這張表。import xml.etree.ElementTree as ET import glob, os, csv rows [] for xml_path in sorted(glob.glob(labels/*.xml)): root ET.parse(xml_path).getroot() img_name root.find(filename).text for obj in root.iter(object): name obj.find(name).text box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) rows.append([os.path.basename(img_name), name, xmin, ymin, xmax, ymax, xmax - xmin, ymax - ymin]) with open(label_summary.csv, w, newline) as f: writer csv.writer(f) writer.writerow([image, class, xmin, ymin, xmax, ymax, w, h]) writer.writerows(rows)這段代碼遍歷所有XML把每個(gè)目標(biāo)的類別、邊界框坐標(biāo)和寬高展開成一行。用ET解析而不是正則去抓文本是因?yàn)閄ML屬性順序偶爾會(huì)變基于標(biāo)簽名取值更穩(wěn)妥。落成CSV后用Excel透視表或pandas看一眼類別分布。正常情況下這類數(shù)據(jù)集的類別名通常就是screen或者display不會(huì)太復(fù)雜。如果類別超過三種就要警惕是不是把“指示燈亮起”“按鍵面板”“屏幕內(nèi)容區(qū)域”都單獨(dú)標(biāo)了類。對(duì)屏幕檢測(cè)任務(wù)來(lái)說(shuō)類別粒度越粗越好細(xì)分類別會(huì)讓同類樣本之間的差異變大模型學(xué)到的特征不夠穩(wěn)定。2.3 先跑一遍標(biāo)簽合法性自檢越界、空框、張冠李戴標(biāo)簽合法性自檢是訓(xùn)練前最值得花時(shí)間的步驟。工業(yè)數(shù)據(jù)集的標(biāo)簽往往是人工標(biāo)注或半自動(dòng)標(biāo)注產(chǎn)物漏標(biāo)、錯(cuò)標(biāo)、坐標(biāo)越界非常常見。臟標(biāo)簽直接進(jìn)入訓(xùn)練流程loss曲線會(huì)忽高忽低模型精度上不去時(shí)你根本分不清是網(wǎng)絡(luò)結(jié)構(gòu)問題還是數(shù)據(jù)問題。import xml.etree.ElementTree as ET import glob from PIL import Image import os bad [] for xml_path in sorted(glob.glob(labels/*.xml)): root ET.parse(xml_path).getroot() img_rel os.path.join(images, root.find(filename).text) if not os.path.exists(img_rel): bad.append((xml_path, missing image, root.find(filename).text)) continue with Image.open(img_rel) as im: W, H im.size for obj in root.iter(object): box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) if xmin xmax or ymin ymax: bad.append((xml_path, zero area box, (xmin, ymin, xmax, ymax))) if xmin 0 or ymin 0 or xmax W or ymax H: bad.append((xml_path, out of bound, (xmin, ymin, xmax, ymax, W, H))) for item in bad[:30]: print(item) print(total bad:, len(bad))這個(gè)自檢腳本輸出三類問題圖像文件缺失、框面積為零、框越界。面積為零的框通常來(lái)自標(biāo)注工具誤操作越界框則常出現(xiàn)在標(biāo)注后裁剪了原圖的場(chǎng)景。面對(duì)越界框不要一律刪除——輕微越界可以用clip修正也就是把坐標(biāo)截?cái)嗟綀D像范圍內(nèi)面積為零的框沒有任何信息量直接刪除。這樣清洗后的標(biāo)簽才配進(jìn)入訓(xùn)練管線。我見過的項(xiàng)目里這類數(shù)據(jù)集直接訓(xùn)練出現(xiàn)的“翻車”十有八九是壞標(biāo)簽沒清干凈而不是模型不行。3. 把VOC轉(zhuǎn)成YOLO訓(xùn)練輸入格式換算與訓(xùn)練參數(shù)的選擇3.1 為什么我從VOC轉(zhuǎn)YOLO一句理由加一條換算公式現(xiàn)在主流檢測(cè)訓(xùn)練流程無(wú)論是YOLOv5、YOLOv8還是MMDetection下的YOLO系列都偏好使用一個(gè)圖像對(duì)應(yīng)一個(gè)txt標(biāo)簽文件、每行“類別ID 歸一化中心坐標(biāo) 歸一化寬高”的格式。VOC的像素級(jí)絕對(duì)坐標(biāo)直觀但不同框架對(duì)坐標(biāo)系的起點(diǎn)定義不一致有的從左上角0開始有的從左上角1開始直接硬喂容易出邊界誤差。換算公式很簡(jiǎn)單x_center (xmin xmax) / 2 / W y_center (ymin ymax) / 2 / H w (xmax - xmin) / W h (ymax - ymin) / H所有坐標(biāo)都除以圖像真實(shí)寬高得到0到1之間的相對(duì)值。注意這里用的是XML里記錄的坐標(biāo)和圖像的真實(shí)像素尺寸不是標(biāo)注工具預(yù)覽圖里的縮放尺寸。轉(zhuǎn)換時(shí)用錯(cuò)寬高比會(huì)導(dǎo)致檢測(cè)框整體偏移這種錯(cuò)誤在人工抽查單張圖時(shí)很難發(fā)現(xiàn)但模型訓(xùn)練時(shí)就是系統(tǒng)性噪聲。有人會(huì)問如果用的框架原生支持VOC何必多此一舉我的習(xí)慣是統(tǒng)一轉(zhuǎn)成YOLO文本格式因?yàn)楣I(yè)項(xiàng)目里大概率會(huì)在訓(xùn)練中途換模型骨架換成YOLO格式后yolov5、yolov8、rtdetr等模型都能零成本切換不必再為格式適配浪費(fèi)時(shí)間。3.2 轉(zhuǎn)換腳本把XML和圖像落成訓(xùn)練目錄import xml.etree.ElementTree as ET import glob, os, shutil from PIL import Image # 推薦目錄結(jié)構(gòu): datasets/screen_detect/{images,labels}/{train,val} os.makedirs(datasets/screen_detect/images/train, exist_okTrue) os.makedirs(datasets/screen_detect/images/val, exist_okTrue) os.makedirs(datasets/screen_detect/labels/train, exist_okTrue) os.makedirs(datasets/screen_detect/labels/val, exist_okTrue) # 預(yù)先把要進(jìn)驗(yàn)證集的圖像文件名寫進(jìn) val_imgs.txt val_set set(l.strip() for l in open(val_imgs.txt)) class_names [screen] def convert_voc_to_yolo(xml_path, split): root ET.parse(xml_path).getroot() img_name root.find(filename).text if folder in {c.tag for c in root}: pass with Image.open(os.path.join(images, img_name)) as im: W, H im.size out_lines [] for obj in root.iter(object): name obj.find(name).text if name not in class_names: continue box obj.find(bndbox) xmin max(float(box.find(xmin).text), 0) ymin max(float(box.find(ymin).text), 0) xmax min(float(box.find(xmax).text), W) ymax min(float(box.find(ymax).text), H) if xmax - xmin 3 or ymax - ymin 3: continue x_center (xmin xmax) / 2 / W y_center (ymin ymax) / 2 / H w (xmax - xmin) / W h (ymax - ymin) / H out_lines.append(f0 {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) img_src os.path.join(images, img_name) dst_img_dir fdatasets/screen_detect/images/{split} dst_lbl_dir fdatasets/screen_detect/labels/{split} shutil.copy(img_src, os.path.join(dst_img_dir, img_name)) label_name os.path.splitext(img_name)[0] .txt with open(os.path.join(dst_lbl_dir, label_name), w) as f: f.write(\n.join(out_lines)) for xml_path in glob.glob(labels/*.xml): img_name ET.parse(xml_path).getroot().find(filename).text split val if img_name in val_set else train convert_voc_to_yolo(xml_path, split)這個(gè)腳本有幾個(gè)值得解釋的設(shè)計(jì)。一是寬高小于3像素的框直接丟棄這類框通常來(lái)自標(biāo)注手抖對(duì)訓(xùn)練只有噪聲貢獻(xiàn)。二是clip操作把越界坐標(biāo)先拉回圖像邊界再判斷是否值得保留。三是val_imgs.txt由你預(yù)先決定這樣訓(xùn)練集和驗(yàn)證集的劃分可以反復(fù)調(diào)整不需要改腳本。寬度值和height值保留六位小數(shù)避免歸一化精度不足導(dǎo)致的小目標(biāo)框抖動(dòng)。轉(zhuǎn)換完成后檢查一下labels/train里有沒有空文件。如果一個(gè)txt內(nèi)容為空說(shuō)明該圖像的標(biāo)注框全被過濾掉了對(duì)應(yīng)圖像應(yīng)該從訓(xùn)練集里移走否則模型會(huì)拿一張無(wú)目標(biāo)圖做負(fù)樣本造成誤檢。3.3 數(shù)據(jù)劃分按拍攝場(chǎng)景分組別隨機(jī)打散700張圖的數(shù)據(jù)集最常見的錯(cuò)誤是隨機(jī)劃分訓(xùn)練集和驗(yàn)證集。屏幕檢測(cè)圖像有一個(gè)特點(diǎn)同一面柜子連續(xù)拍攝的幾十幀背景、光照、屏幕狀態(tài)高度相似。隨機(jī)劃分時(shí)第3幀進(jìn)訓(xùn)練集、第4幀進(jìn)驗(yàn)證集驗(yàn)證結(jié)果會(huì)虛高因?yàn)槟P蛶缀酢耙娺^”同一場(chǎng)景?,F(xiàn)場(chǎng)部署時(shí)換個(gè)角度、換個(gè)柜門狀態(tài)精度立刻掉下來(lái)。我一般會(huì)先按文件名中的時(shí)間戳或柜體編號(hào)分組同一組的連續(xù)幀要么全進(jìn)訓(xùn)練集要么全進(jìn)驗(yàn)證集。如果文件名里沒有明顯分組標(biāo)志就按時(shí)間順序每連續(xù)30幀作為一個(gè)分組單位做按組的隨機(jī)劃分。import glob, random imgs sorted(glob.glob(images/*.jpg)) # 每30幀為一個(gè)組保證連續(xù)幀不跨集合 groups [imgs[i:i30] for i in range(0, len(imgs), 30)] random.seed(42) random.shuffle(groups) val_cnt int(len(groups) * 0.2) val_groups groups[:val_cnt] val_set set() for g in val_groups: for path in g: val_set.add(os.path.basename(path)) with open(val_imgs.txt, w) as f: for name in sorted(val_set): f.write(name \n)這段代碼的作用和理由是什么它把拍攝時(shí)序相近的圖像捆在一起驗(yàn)證集不再和訓(xùn)練集共享同場(chǎng)景畫面評(píng)估結(jié)果更接近“新現(xiàn)場(chǎng)”的表現(xiàn)。seed固定為42保證每次運(yùn)行劃分一致這是模型實(shí)驗(yàn)可復(fù)現(xiàn)的前提。如果驗(yàn)證集圖像數(shù)量偏少可以把val比例降到15%但不要低于10%否則指標(biāo)波動(dòng)太大小改動(dòng)就看不出效果了。3.4 訓(xùn)練命令與三個(gè)最不該亂動(dòng)的參數(shù)劃分完成后就可以跑第一個(gè)訓(xùn)練。以YOLOv8為例一條最直接的訓(xùn)練命令yolo detect train \ datadatasets/screen_detect/data.yaml \ modelyolov8s.pt \ imgsz640 \ batch16 \ epochs150 \ patience20 \ mosaic1.0 \ projectruns/screen_detect先解釋data.yaml它指向訓(xùn)練/驗(yàn)證圖像目錄、類別名和類別數(shù)量YOLO框架會(huì)依據(jù)目錄自動(dòng)尋找對(duì)應(yīng)labels下的txt文件。imgsz640是屏幕檢測(cè)任務(wù)里性價(jià)比最高的起手式屏幕區(qū)域通常是畫面中的中等目標(biāo)640分辨率能保留邊框細(xì)節(jié)又不會(huì)讓顯存爆炸。batch16取決于顯卡顯存12GB顯存跑yolov8s batch16沒問題。mosaic1.0的增強(qiáng)方式會(huì)同時(shí)拼接4張圖訓(xùn)練對(duì)小目標(biāo)檢測(cè)確實(shí)有好處但這個(gè)參數(shù)配合imgsz一起動(dòng)時(shí)模型表現(xiàn)變化很難歸因——你改了分辨率又改了拼接強(qiáng)度指標(biāo)掉了都不知道該怪誰(shuí)。我的習(xí)慣是先把mosaic固定為0.5到1.0之間的經(jīng)驗(yàn)值只調(diào)imgsz或只調(diào)batch保持單一變量。訓(xùn)練過程中真正值得盯的是驗(yàn)證集mAP50曲線和loss曲線。工業(yè)屏幕檢測(cè)不要求指標(biāo)突破天際mAP50能穩(wěn)定在0.95以上且驗(yàn)證集和訓(xùn)練集差距小于3%就是一個(gè)可以接受的第一版模型。如果訓(xùn)練集mAP一路走高但驗(yàn)證集徘徊不前先回頭查數(shù)據(jù)劃分多半是同一場(chǎng)景的畫面泄漏到了兩個(gè)集合里。4. 屏幕檢測(cè)避坑反光、畫面刷新與標(biāo)注污染4.1 反光把屏幕框“藏”起來(lái)先查驗(yàn)證集里有多少高光樣本現(xiàn)場(chǎng)拍照最直觀的坑就是反光。變電站控制柜表面通常是亮面金屬或玻璃指示燈、屏幕、柜體邊框混在一起陽(yáng)光或LED燈直射時(shí)屏幕區(qū)域白茫茫一片紋理幾乎消失?,F(xiàn)象檢出的屏幕框不穩(wěn)定或者框到旁邊的高光柜面上。原因訓(xùn)練集里高光樣本占比低模型學(xué)到的屏幕特征偏向“有規(guī)則字符內(nèi)容的矩形區(qū)域”一旦屏幕內(nèi)容被反光吞掉特征就不存在了。解決先統(tǒng)計(jì)驗(yàn)證集里高光樣本的比例低于30%就需要專門補(bǔ)充或做數(shù)據(jù)增強(qiáng)。訓(xùn)練時(shí)打開HSV增強(qiáng)的亮度抖動(dòng)把亮度范圍L從默認(rèn)值擴(kuò)展讓模型見過“更亮”和“更暗”的屏幕。如果條件允許在現(xiàn)場(chǎng)調(diào)整相機(jī)偏振鏡或遮光罩直接物理消除反光這比任何模型手段都有效。4.2 同一個(gè)屏幕亮屏和黑屏標(biāo)簽口徑卻不統(tǒng)一保護(hù)裝置的屏幕有兩種狀態(tài)很容易讓人標(biāo)注時(shí)精神分裂亮屏?xí)r內(nèi)容清晰屏幕玻璃邊緣和顯示區(qū)域邊界明顯滅屏或待機(jī)時(shí)整個(gè)屏發(fā)黑標(biāo)注員只能靠玻璃輪廓和邊框定位?,F(xiàn)象XML里同一塊屏幕有的框標(biāo)的是顯示區(qū)域有的框標(biāo)的是整個(gè)玻璃外沿兩種標(biāo)簽混在一起訓(xùn)出來(lái)的模型在亮屏和滅屏切換時(shí)會(huì)出現(xiàn)框的大小跳變。原因標(biāo)注規(guī)范沒有定義清楚“屏幕”的邊界。解決定一個(gè)硬性約定——屏幕檢測(cè)的目標(biāo)是“屏幕組件的外接矩形框”以玻璃面板的物理邊界為準(zhǔn)不跟隨顯示內(nèi)容縮放。這個(gè)規(guī)則從第一張圖就要定死中途改標(biāo)注規(guī)則等于整個(gè)數(shù)據(jù)集作廢一半。如果這類數(shù)據(jù)集是別人標(biāo)好的先抽樣看10張滅屏樣本的框位置確認(rèn)口徑一致再進(jìn)入訓(xùn)練。4.3 XML坐標(biāo)越界且類別為空轉(zhuǎn)換時(shí)不能直接報(bào)錯(cuò)退出標(biāo)簽校驗(yàn)時(shí)發(fā)現(xiàn)越界框和空類別處理方法不是讓轉(zhuǎn)換腳本報(bào)錯(cuò)退出而是要建立一套明確的清洗規(guī)則。我見過最頭疼的情況是一個(gè)XML里只有filename和size節(jié)點(diǎn)object節(jié)點(diǎn)全部丟失對(duì)應(yīng)圖像是純背景圖。這種圖在訓(xùn)練中會(huì)被當(dāng)作負(fù)樣本如果數(shù)量很少影響有限但如果占了一成以上模型會(huì)變得過度保守屏幕上真有告警時(shí)反而檢不出來(lái)。現(xiàn)象YOLO訓(xùn)練時(shí)loss出現(xiàn)NaN或者驗(yàn)證集精度歸零。原因轉(zhuǎn)換腳本遇到空標(biāo)簽直接寫了空文件模型讀到空標(biāo)簽后梯度爆炸。解決轉(zhuǎn)換腳本里對(duì)空標(biāo)簽文件統(tǒng)一打標(biāo)記訓(xùn)練配置里用超參數(shù)跳過空標(biāo)簽圖像或者直接把這類圖像移到exclude目錄不讓它進(jìn)訓(xùn)練目錄。清洗原則是寧可刪掉10個(gè)壞框也不要讓一個(gè)壞框污染訓(xùn)練集。壞框讓模型學(xué)到錯(cuò)誤的位置先驗(yàn)后面調(diào)再多的增強(qiáng)參數(shù)都補(bǔ)不回來(lái)。4.4 驗(yàn)證集mAP高現(xiàn)場(chǎng)卻識(shí)別不到位姿和背景泛化問題這是屏幕檢測(cè)類項(xiàng)目最典型的翻車現(xiàn)場(chǎng)。訓(xùn)練時(shí)看著每張測(cè)試圖都框得完美m(xù)AP50刷到0.97拿到變電站現(xiàn)場(chǎng)一測(cè)同一個(gè)柜子隔了兩米遠(yuǎn)或者換了個(gè)仰視角度模型就開始漏檢。現(xiàn)象現(xiàn)場(chǎng)識(shí)別率掉一半檢測(cè)框在屏幕上抖來(lái)抖去。原因700張工業(yè)圖像數(shù)據(jù)集的采集工況通常很單一可能是同一臺(tái)相機(jī)、固定機(jī)位、固定焦距拍出來(lái)的模型把“固定拍攝條件”當(dāng)成了特征。解決把現(xiàn)場(chǎng)部署當(dāng)作冷啟動(dòng)第一周先采集現(xiàn)場(chǎng)視頻按每秒抽一幀的頻率抽幾百?gòu)垐D用已訓(xùn)練好的模型做預(yù)標(biāo)注人工確認(rèn)后加入訓(xùn)練集。這一步的核心思路是數(shù)據(jù)集的價(jià)值不在于700張這個(gè)數(shù)字而在于它是否覆蓋了現(xiàn)場(chǎng)可能的位姿變化和光照變化。與其糾結(jié)訓(xùn)練參數(shù)不如盡快讓模型見到“真正的現(xiàn)場(chǎng)”。5. 從700張到能上線的最小閉環(huán)指標(biāo)、增量與模型反哺數(shù)據(jù)5.1 先定驗(yàn)收指標(biāo)mAP之外還要盯漏報(bào)率屏幕檢測(cè)在工業(yè)現(xiàn)場(chǎng)的驗(yàn)收邏輯和學(xué)術(shù)競(jìng)賽不一樣。做保護(hù)屏巡檢輔助時(shí)漏掉一塊屏幕比多框一塊屏幕嚴(yán)重得多。漏檢意味著告警信息沒有被采集到直接關(guān)系到設(shè)備狀態(tài)判斷所以不能只看mAP。指標(biāo)參考值說(shuō)明正常光照漏檢率小于1%屏幕內(nèi)容清晰時(shí)不允許漏檢高反光/低亮度漏檢率小于5%惡劣光照下允許小幅下降單屏誤檢率小于1%把柜體、指示燈誤認(rèn)為屏幕單幀推理耗時(shí)小于100ms640分辨率GPU或邊緣盒子這個(gè)表是參考值具體閾值要和現(xiàn)場(chǎng)的巡檢制度掛鉤。如果屏幕檢測(cè)模塊是巡檢機(jī)器人的前置環(huán)節(jié)后面還要接告警識(shí)別那漏檢率還要再壓一個(gè)量級(jí)。算法側(cè)滿足指標(biāo)還不夠最終要看連續(xù)跑一周的現(xiàn)場(chǎng)視頻里的表現(xiàn)。我習(xí)慣在交付前留一天專門做“對(duì)抗測(cè)試”人為制造反光、遮擋、斜視、半屏亮度變化看模型哪個(gè)場(chǎng)景先崩當(dāng)天補(bǔ)數(shù)據(jù)當(dāng)天重訓(xùn)。5.2 把700張當(dāng)成母庫(kù)而不是訓(xùn)練倉(cāng)庫(kù)做這類工業(yè)圖像數(shù)據(jù)集最容易犯的錯(cuò)是把它當(dāng)作一次性的訓(xùn)練物料用完就丟。正確的做法是把它當(dāng)成母庫(kù)原始圖像和原始XML永遠(yuǎn)不動(dòng)另建工作庫(kù)和鏡像庫(kù)。工作庫(kù)存放清洗后用于訓(xùn)練的數(shù)據(jù)鏡像庫(kù)存放每次清洗動(dòng)作前后的快照相當(dāng)于后悔藥——哪天發(fā)現(xiàn)某次清洗規(guī)則刪錯(cuò)了樣本還能從鏡像庫(kù)恢復(fù)。增量流程固定為五步新圖像進(jìn)母庫(kù)跑標(biāo)簽合法性自檢人工抽檢標(biāo)注質(zhì)量轉(zhuǎn)換為YOLO格式合并到工作庫(kù)后重訓(xùn)。這個(gè)過程看起來(lái)繁瑣但比每次拿到新數(shù)據(jù)就全員重標(biāo)、反復(fù)調(diào)參要省時(shí)得多。迭代到第二個(gè)月時(shí)母庫(kù)里的圖像可能已經(jīng)超過3000張但訓(xùn)練工作庫(kù)只需要保持平衡的類別分布和場(chǎng)景覆蓋不必把所有數(shù)據(jù)都灌進(jìn)訓(xùn)練。5.3 用模型反哺數(shù)據(jù)集主動(dòng)抽取難樣本最后一個(gè)技巧是讓訓(xùn)練好的模型幫你找數(shù)據(jù)。用當(dāng)前模型在未標(biāo)注的視頻幀上跑預(yù)測(cè)把置信度落在0.3到0.6之間的檢測(cè)框抽出來(lái)人工看這些框到底對(duì)不對(duì)。置信度很低說(shuō)明模型很猶豫這些畫面往往是新增光照、新增角度、新增遮擋正是當(dāng)前訓(xùn)練集的短板。置信度很高且框準(zhǔn)確的樣本可以自動(dòng)加入訓(xùn)練集置信度高但框偏的樣本則說(shuō)明存在相似干擾物需要人工確認(rèn)后決定要不要標(biāo)注成負(fù)樣本。我在早期做這類屏幕檢測(cè)項(xiàng)目時(shí)貪省事跳過清洗結(jié)果后續(xù)所有模型精度都上不去排查了兩天才發(fā)現(xiàn)是壞標(biāo)簽在搗亂。后來(lái)凡是新數(shù)據(jù)集進(jìn)入訓(xùn)練前都強(qiáng)制跑一遍標(biāo)簽體檢這個(gè)習(xí)慣讓后續(xù)所有模型都穩(wěn)定了。拿到這套700張的VOC數(shù)據(jù)集順序應(yīng)該是解析統(tǒng)計(jì)、清洗校驗(yàn)、分組劃分、轉(zhuǎn)換訓(xùn)練最后帶上現(xiàn)場(chǎng)數(shù)據(jù)做增量。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取