數(shù)據(jù)集:VOC格式解析與YOLO訓(xùn)練實(shí)戰(zhàn))
簡(jiǎn)介目標(biāo)檢測(cè)是計(jì)算機(jī)視覺(jué)的核心任務(wù)之一而高質(zhì)量的數(shù)據(jù)集與規(guī)范的標(biāo)注格式是模型性能的基石。在交通安防場(chǎng)景中頭盔檢測(cè)面臨小目標(biāo)、遮擋、多視角和極端光照等挑戰(zhàn)通用檢測(cè)模型難以直接勝任。VOC格式作為常見(jiàn)的目標(biāo)檢測(cè)標(biāo)注標(biāo)準(zhǔn)提供了清晰的邊界框與難例標(biāo)記信息便于數(shù)據(jù)清洗與模型訓(xùn)練。本文圍繞摩托車(chē)頭盔檢測(cè)數(shù)據(jù)集介紹其VOC目錄結(jié)構(gòu)與XML標(biāo)注要點(diǎn)分享數(shù)據(jù)清洗策略及轉(zhuǎn)YOLO格式的訓(xùn)練流程并給出YOLOv8實(shí)測(cè)參數(shù)與部署建議。該數(shù)據(jù)集覆蓋多種時(shí)段、角度與遮擋情況適合用于安防監(jiān)控、交通抓拍等場(chǎng)景幫助開(kāi)發(fā)者快速構(gòu)建高精度頭盔檢測(cè)系統(tǒng)。1. 頭盔檢測(cè)這個(gè)任務(wù)難就難在它不是把框畫(huà)準(zhǔn)就完事先說(shuō)個(gè)實(shí)際經(jīng)歷。前幾年幫朋友做過(guò)一個(gè)摩托車(chē)抓拍項(xiàng)目需求是在路口識(shí)別騎乘人員有沒(méi)有戴頭盔。最開(kāi)始圖省事直接用開(kāi)源的通用目標(biāo)檢測(cè)模型拿一個(gè)幾萬(wàn)張圖片的COCO子集隨便練了練結(jié)果一到晚上和側(cè)后方視角誤報(bào)漏報(bào)慘不忍睹。后來(lái)才意識(shí)到頭盔檢測(cè)這個(gè)任務(wù)和常規(guī)的行人檢測(cè)、車(chē)輛檢測(cè)完全是兩回事它的難點(diǎn)藏在很多意料之外的地方。第一目標(biāo)太小。路口監(jiān)控畫(huà)面里一輛摩托車(chē)可能只占幾百個(gè)像素頭盔更小經(jīng)常只有二三十個(gè)像素。通用模型在COCO這種大目標(biāo)數(shù)據(jù)集上表現(xiàn)好不代表在小目標(biāo)上能打。第二遮擋嚴(yán)重。前后車(chē)重疊、騎手低頭、頭盔被車(chē)身?yè)踝“脒呥@些都是常態(tài)。第三視角多樣。正臉、側(cè)臉、后腦勺不同角度頭盔形狀變化很大而且摩托車(chē)本身是斜著進(jìn)畫(huà)面的不像行人那樣直立。第四光線(xiàn)極端。白天強(qiáng)逆光、夜間車(chē)燈直射、雨天反光同一頂頭盔在不同光照下特征差異巨大。還有一類(lèi)容易被忽略的問(wèn)題類(lèi)別混淆。工地安全帽、自行車(chē)頭盔、電動(dòng)車(chē)頭盔外觀相似但用途不同如果數(shù)據(jù)集中這些樣本混在一起模型就會(huì)學(xué)得糊里糊涂。更有意思的是戴了帽子再戴頭盔、頭盔掛在車(chē)把上、騎手把頭盔拿在手里這種類(lèi)頭盔物體如果沒(méi)在數(shù)據(jù)里出現(xiàn)模型就會(huì)把它們當(dāng)成正樣本識(shí)別率直接被拉低。這批摩托車(chē)電動(dòng)車(chē)佩戴頭盔檢測(cè)數(shù)據(jù)集我拿到手之后第一反應(yīng)是終于有人把這種刁鉆場(chǎng)景規(guī)規(guī)矩矩地做成了數(shù)據(jù)集。它是標(biāo)準(zhǔn)的VOC格式標(biāo)注2514張圖片核心內(nèi)容包括摩托車(chē)、電動(dòng)車(chē)的騎乘人員及其頭盔佩戴狀態(tài)。聽(tīng)起來(lái)數(shù)量不算夸張但這個(gè)規(guī)模對(duì)頭盔檢測(cè)來(lái)說(shuō)并不小關(guān)鍵是它處理了上面說(shuō)的那些難點(diǎn)場(chǎng)景而不是市面上那種拿幾百?gòu)垐D硬湊的demo級(jí)數(shù)據(jù)集。如果你正在做安防監(jiān)控、交通抓拍、騎行安全提醒這類(lèi)項(xiàng)目這個(gè)數(shù)據(jù)集可以直接作為訓(xùn)練的起點(diǎn)省掉大量爬圖、清洗、標(biāo)注的時(shí)間。2. VOC標(biāo)注格式拆解這套數(shù)據(jù)集的目錄結(jié)構(gòu)與XML標(biāo)簽要點(diǎn)很多剛開(kāi)始做目標(biāo)檢測(cè)的讀者一聽(tīng)到VOC格式可能有點(diǎn)懵也有把VOC和標(biāo)注工具的通用導(dǎo)出格式混為一談的。這里先把VOC格式的根目錄結(jié)構(gòu)交代清楚你再對(duì)照看這個(gè)數(shù)據(jù)集會(huì)發(fā)現(xiàn)它的組織非常規(guī)范。2.1 VOC數(shù)據(jù)集的標(biāo)準(zhǔn)目錄骨骼一份合格的Pascal VOC格式數(shù)據(jù)集至少包含三個(gè)目錄和一個(gè)說(shuō)明文件這套頭盔數(shù)據(jù)集的結(jié)構(gòu)如下VOCdevkit/ ├── VOC2007/ │ ├── JPEGImages/ # 圖片原圖全部是jpg格式 │ ├── Annotations/ # 每張圖對(duì)應(yīng)的xml標(biāo)注文件 │ ├── ImageSets/ │ │ └── Main/ # train.txt、val.txt、trainval.txt │ └── labels/ # 有些VOC數(shù)據(jù)集會(huì)提供ID到類(lèi)別名的映射JPEGImages 和 Annotations 兩個(gè)目錄的文件名一一對(duì)應(yīng)比如img_0001.jpg對(duì)應(yīng)img_0001.xml。ImageSets/Main 下的txt文件里放的是不帶后綴的文件名列表一行一個(gè)用于訓(xùn)練、驗(yàn)證集劃分。這套數(shù)據(jù)集里還有一個(gè)點(diǎn)做得比較到位它把類(lèi)別信息單獨(dú)抽出來(lái)了后續(xù)轉(zhuǎn)YOLO格式時(shí)不需要手動(dòng)去翻XML猜類(lèi)別ID省了不少時(shí)間。2.2 XML里的關(guān)鍵字段怎么看VOC標(biāo)注文件的核心是object節(jié)點(diǎn)。我截取一個(gè)典型結(jié)構(gòu)說(shuō)明annotation folderVOC2007/folder filenameimg_0102.jpg/filename size width1920/width height1080/height depth3/depth /size object namehelmet/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin126/xmin ymin402/ymin xmax178/xmax ymax454/ymax /bndbox /object /annotation有幾個(gè)字段需要特別關(guān)注。difficult是新手最容易忽略的。它表示這個(gè)目標(biāo)是否難以識(shí)別通常被遮擋嚴(yán)重、極小、輪廓模糊的目標(biāo)會(huì)被標(biāo)記為1。訓(xùn)練時(shí)如果使用默認(rèn)配置difficult1的樣本可能會(huì)被直接忽略或者參與評(píng)估但不參與訓(xùn)練。這個(gè)數(shù)據(jù)集里大量難例樣本的difficult標(biāo)記是合理的后面的數(shù)據(jù)清洗部分我會(huì)展開(kāi)講這里只想提醒如果你用mmdetection跑記得在配置里把ignore_iof_thr之類(lèi)的參數(shù)調(diào)好不然難例樣本的作用就白費(fèi)了。truncated表示目標(biāo)是否超出圖像邊界。在頭盔檢測(cè)場(chǎng)景里摩托車(chē)駛?cè)氘?huà)面邊緣非常常見(jiàn)騎手可能只露出一半這種目標(biāo)如果沒(méi)標(biāo)好模型在邊界區(qū)域的預(yù)測(cè)就會(huì)很飄。bndbox是邊界框坐標(biāo)四個(gè)值分別是框左上角和右下角的x、y像素坐標(biāo)注意不是歸一化的讀取后需要自行根據(jù)圖像寬高轉(zhuǎn)換。那這個(gè)數(shù)據(jù)集里到底有哪些類(lèi)別從標(biāo)簽內(nèi)容來(lái)看主要圍繞三類(lèi)戴頭盔的騎手、未戴頭盔的騎手以及摩托車(chē)/電動(dòng)車(chē)本身。有些同類(lèi)數(shù)據(jù)集會(huì)把頭盔和人分開(kāi)有些會(huì)直接標(biāo)注整個(gè)騎乘人員加上頭盔狀態(tài)不同方案各有優(yōu)劣。如果下游任務(wù)是精確到戴沒(méi)戴我更建議用這類(lèi)把騎手和頭盔狀態(tài)區(qū)分開(kāi)的標(biāo)注后續(xù)做區(qū)域判斷會(huì)比較方便。2.3 為什么選VOC而不是直接用COCO或YOLO接觸過(guò)目標(biāo)檢測(cè)的讀者應(yīng)該知道現(xiàn)在主流格式還有COCO的JSON和YOLO的TXT。那這個(gè)數(shù)據(jù)集為什么用VOC我的判斷是VOC格式是很多標(biāo)注工具的通用中間格式先落成VOC后期你要轉(zhuǎn)YOLO、轉(zhuǎn)COCO都容易反向操作就麻煩得多。另外VOC格式的可讀性強(qiáng)XML里能看到難度標(biāo)記、截?cái)鄻?biāo)記方便你做數(shù)據(jù)清洗而COCO的JSON對(duì)新手來(lái)說(shuō)配嵌套層級(jí)就夠喝一壺了。實(shí)際使用中你大概率還是要做一步VOC轉(zhuǎn)YOLO畢竟當(dāng)前訓(xùn)練主流是YOLO系列。這個(gè)轉(zhuǎn)換非常機(jī)械唯一要注意的是類(lèi)別ID順序和生成train/val劃分時(shí)保證一定隨機(jī)性。這個(gè)數(shù)據(jù)集里的類(lèi)別相對(duì)固定轉(zhuǎn)起來(lái)不費(fèi)勁第三節(jié)會(huì)給轉(zhuǎn)換腳本。3. 2514張不等于亂爬2514張數(shù)據(jù)清洗和標(biāo)注規(guī)范才是識(shí)別率的底氣標(biāo)題里超高識(shí)別率這幾個(gè)字我一開(kāi)始是持懷疑態(tài)度的。畢竟標(biāo)注兩個(gè)字背后的水很深很多數(shù)據(jù)集宣傳幾千張圖實(shí)際打開(kāi)一看要么是大量重復(fù)圖片要么是邊界框畫(huà)得歪七扭八。真正上手這批數(shù)據(jù)之后我大致理解了它的識(shí)別率底氣從哪里來(lái)主要集中在三個(gè)方面。3.1 場(chǎng)景覆蓋邏輯不是隨機(jī)爬圖而是按難點(diǎn)分布采樣頭盔檢測(cè)的最大痛點(diǎn)不是看過(guò)足夠多的頭盔而是看過(guò)足夠多角度和光線(xiàn)下的頭盔。這個(gè)數(shù)據(jù)集在場(chǎng)景覆蓋上很講究我把主要分布總結(jié)成如下表格場(chǎng)景維度覆蓋情況對(duì)模型的作用時(shí)段白天、黃昏、夜間、逆光避免模型對(duì)光線(xiàn)過(guò)擬合拍攝角度正面、側(cè)面、側(cè)后方、俯拍提升多視角泛化能力車(chē)型摩托車(chē)、電動(dòng)車(chē)、踏板車(chē)防止只認(rèn)識(shí)某一種車(chē)氣候晴天、雨天、陰天提升惡劣天氣魯棒性密度單騎手、雙騎手、多車(chē)混行增強(qiáng)擁擠場(chǎng)景下的檢出能力遮擋程度無(wú)遮擋、部分遮擋、嚴(yán)重遮擋訓(xùn)練模型在難例下不自信也不漏檢我專(zhuān)門(mén)統(tǒng)計(jì)了圖片中目標(biāo)大小分布發(fā)現(xiàn)小目標(biāo)頭盔像素面積小于32×32占了相當(dāng)比例。這對(duì)訓(xùn)練特別有用因?yàn)閅OLO系列在小目標(biāo)上本來(lái)就容易翻車(chē)如果沒(méi)有足夠多的小目標(biāo)樣本模型會(huì)習(xí)慣性地把遠(yuǎn)處目標(biāo)忽略掉。3.2 標(biāo)注質(zhì)量邊界框的貼著標(biāo)和留白標(biāo)差別巨大標(biāo)注規(guī)范直接影響模型學(xué)到的東西。我看到很多新手用標(biāo)注工具時(shí)喜歡把邊界框框得比目標(biāo)大一圈理由是留點(diǎn)余量讓模型更容易學(xué)習(xí)。這個(gè)想法是大錯(cuò)特錯(cuò)的。目標(biāo)檢測(cè)的邊界框回歸是直接回歸到標(biāo)注框的如果你標(biāo)得松模型學(xué)出來(lái)的框就永遠(yuǎn)帶一圈背景IoU算不高NMS階段還會(huì)產(chǎn)生大量冗余框。而且如果框里混雜了旁邊的另一個(gè)目標(biāo)模型的特征就會(huì)被污染。這批數(shù)據(jù)集的標(biāo)注明顯遵循了tight box原則邊界框緊貼目標(biāo)的外沿對(duì)于頭盔這類(lèi)高反光、邊緣不明顯的物體手工標(biāo)注能做到這個(gè)貼合度說(shuō)明是花過(guò)功夫的。還有一處細(xì)節(jié)值得表?yè)P(yáng)對(duì)遮擋目標(biāo)的處理。常見(jiàn)有三種標(biāo)注策略把遮擋部分一起框進(jìn)去錯(cuò)誤會(huì)把遮擋物也學(xué)進(jìn)來(lái)只標(biāo)可見(jiàn)部分較合理保留了目標(biāo)外觀信息完全跳過(guò)遮擋目標(biāo)會(huì)出現(xiàn)大量漏檢。這個(gè)數(shù)據(jù)集的策略偏向前兩種的結(jié)合可見(jiàn)部分占比高就標(biāo)完整框可見(jiàn)部分很少就把difficult置為1讓訓(xùn)練時(shí)忽略它。這樣既不會(huì)漏掉難例的存在信息又不會(huì)在訓(xùn)練的時(shí)候強(qiáng)迫模型學(xué)習(xí)殘破特征。3.3 負(fù)樣本和難例挖掘識(shí)別率高的隱藏功臣分類(lèi)問(wèn)題講究正負(fù)樣本均衡目標(biāo)檢測(cè)也一樣。如果所有圖片里的騎手都是戴了頭盔的模型就學(xué)不會(huì)沒(méi)戴頭盔長(zhǎng)什么樣或者更準(zhǔn)確地說(shuō)它會(huì)把沒(méi)戴頭盔也預(yù)測(cè)成戴了頭盔因?yàn)檎龢颖咎嗔恕_@批數(shù)據(jù)集里的負(fù)樣本未戴頭盔比例是真實(shí)場(chǎng)景的水平而且負(fù)樣本里還包含了一些極易混淆的場(chǎng)景拿在手里的頭盔、放在后座的頭盔、戴帽子的人。這些都屬于類(lèi)頭盔負(fù)樣本。沒(méi)有這種數(shù)據(jù)在訓(xùn)練集里做磨刀石模型很容易把一切圓形隆起物都當(dāng)頭盔。難例挖掘的價(jià)值在于識(shí)別率不是看模型在最簡(jiǎn)單樣本上的表現(xiàn)而是看它在最?lèi)毫訕颖旧系舳嗌俜帧?shù)據(jù)集中那些低光照、高遮擋、極小目標(biāo)樣本才是訓(xùn)練后超高識(shí)別率的真正保障。4. 從VOC到Y(jié)OLO訓(xùn)練格式轉(zhuǎn)換、數(shù)據(jù)劃分與關(guān)鍵訓(xùn)練參數(shù)實(shí)測(cè)數(shù)據(jù)集本身質(zhì)量再高也要經(jīng)過(guò)格式轉(zhuǎn)換和訓(xùn)練才能變成能用的模型。這中間有幾個(gè)環(huán)節(jié)經(jīng)常會(huì)卡住人我把完整流程和實(shí)測(cè)參數(shù)列出來(lái)。4.1 VOC轉(zhuǎn)YOLO的一鍵腳本YOLO格式要求每張圖片對(duì)應(yīng)一個(gè)txt文件每行是類(lèi)別ID x_center y_center width height坐標(biāo)都是歸一化到0~1的。下面這個(gè)腳本可以直接用在數(shù)據(jù)集根目錄執(zhí)行即可import os import xml.etree.ElementTree as ET import random classes [helmet, head_without_helmet, motorcycle] def convert_annotation(xml_file, out_dir, img_width1920, img_height1080): tree ET.parse(xml_file) root tree.getroot() # 從XML中讀取實(shí)際圖像尺寸而不是用默認(rèn)值 size root.find(size) img_width int(size.find(width).text) img_height int(size.find(height).text) txt_name os.path.splitext(os.path.basename(xml_file))[0] .txt with open(os.path.join(out_dir, txt_name), w) as f: for obj in root.iter(object): difficult int(obj.find(difficult).text) if difficult 1: continue cls_name obj.find(name).text if cls_name not in classes: continue cls_id classes.index(cls_name) xmlbox obj.find(bndbox) xmin float(xmlbox.find(xmin).text) ymin float(xmlbox.find(ymin).text) xmax float(xmlbox.find(xmax).text) ymax float(xmlbox.find(ymax).text) x_center (xmin xmax) / 2 / img_width y_center (ymin ymax) / 2 / img_height w (xmax - xmin) / img_width h (ymax - ymin) / img_height f.write(f{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}\n) if __name__ __main__: annotation_dir VOC2007/Annotations label_dir VOC2007/labels os.makedirs(label_dir, exist_okTrue) xml_files [f for f in os.listdir(annotation_dir) if f.endswith(.xml)] for xml_file in xml_files: convert_annotation(os.path.join(annotation_dir, xml_file), label_dir) # 劃分train / val比例9:1 random.seed(42) random.shuffle(xml_files) val_count int(len(xml_files) * 0.1) with open(VOC2007/ImageSets/Main/train.txt, w) as f: for x in xml_files[val_count:]: f.write(os.path.splitext(x)[0] \n) with open(VOC2007/ImageSets/Main/val.txt, w) as f: for x in xml_files[:val_count]: f.write(os.path.splitext(x)[0] \n)這里有幾個(gè)細(xì)節(jié)值得提醒第一轉(zhuǎn)換時(shí)千萬(wàn)不要用固定默認(rèn)尺寸一定要從XML的size節(jié)點(diǎn)讀取實(shí)際寬高。如果數(shù)據(jù)集里混入了一些非1920×1080的圖用默認(rèn)尺寸會(huì)導(dǎo)致坐標(biāo)偏移訓(xùn)練集里直接埋雷。第二difficult1的樣本在轉(zhuǎn)YOLO格式時(shí)要過(guò)濾掉。YOLO格式?jīng)]有difficult這個(gè)概念的承載字段留著它在txt里只會(huì)變成一條普通樣本把難例當(dāng)成必學(xué)樣本訓(xùn)練時(shí)loss會(huì)異常抖動(dòng)。第三劃分train/val時(shí)要先隨機(jī)打亂并固定隨機(jī)種子。否則每次執(zhí)行腳本得到的劃分不同復(fù)現(xiàn)實(shí)驗(yàn)時(shí)模型性能忽高忽低你根本不知道是模型問(wèn)題還是數(shù)據(jù)劃分問(wèn)題。4.2 YOLOv8訓(xùn)練配置和實(shí)測(cè)參數(shù)以YOLOv8為例訓(xùn)練前先編寫(xiě)數(shù)據(jù)配置文件helmet.yamlpath: /path/to/VOCdevkit train: VOC2007/ImageSets/Main/train.txt val: VOC2007/ImageSets/Main/val.txt nc: 3 names: [helmet, head_without_helmet, motorcycle]然后啟動(dòng)訓(xùn)練yolo detect train datahelmet.yaml modelyolov8n.pt epochs200 imgsz640 batch16 device0實(shí)測(cè)下來(lái)有幾個(gè)參數(shù)對(duì)頭盔檢測(cè)的影響比其他任務(wù)更顯著圖片分辨率imgsz頭盔是小目標(biāo)imgsz從640提到960后mAP有2~3個(gè)點(diǎn)的提升。不要覺(jué)得640是萬(wàn)金油小目標(biāo)場(chǎng)景吃分辨率代價(jià)是顯存占用變大、推理速度變慢。如果部署在邊緣設(shè)備建議用640訓(xùn)練再想辦法做TTA。Mosaic增強(qiáng)YOLOv8默認(rèn)開(kāi)啟mosaic對(duì)頭盔這種小目標(biāo)是有利的因?yàn)樗讯鄰垐D拼在一起相當(dāng)于變相增加了小目標(biāo)數(shù)量。但如果數(shù)據(jù)集中頭部樣本特別密集mosaic會(huì)產(chǎn)生大量截?cái)嗟哪繕?biāo)反而干擾學(xué)習(xí)。實(shí)測(cè)把mosaic關(guān)閉或降低到0.5對(duì)這批數(shù)據(jù)沒(méi)有明顯負(fù)面影響甚至略好因?yàn)樵瓐D的密集場(chǎng)景已經(jīng)足夠。類(lèi)別不平衡未戴頭盔的樣本占比天然低于戴頭盔的這是安全現(xiàn)狀決定的但模型不能因此對(duì)未戴頭盔不敏感。如果訓(xùn)練后發(fā)現(xiàn)負(fù)類(lèi)召回率偏低可以嘗試給負(fù)類(lèi)提高loss權(quán)重或者在loss里設(shè)置類(lèi)別權(quán)重。YOLOv8中可以通過(guò)給數(shù)據(jù)集的cls_loss加大系數(shù)來(lái)實(shí)現(xiàn)簡(jiǎn)單粗暴但有效。多尺度訓(xùn)練頭盔檢測(cè)對(duì)尺度變化極其敏感開(kāi)啟多尺度訓(xùn)練scale0.5~1.5會(huì)讓模型在不同距離下的表現(xiàn)更穩(wěn)定代價(jià)是訓(xùn)練時(shí)間增加。這個(gè)數(shù)據(jù)集的場(chǎng)景分布里本身就有大量不同距離的騎手所以多尺度訓(xùn)練是收益大于成本的。4.3 訓(xùn)練時(shí)長(zhǎng)與收斂判斷這批數(shù)據(jù)2514張如果是8G顯存的卡batch16、imgsz640大概半小時(shí)左右就能看到val集loss明顯下降。我的經(jīng)驗(yàn)是訓(xùn)練150~200個(gè)epoch足夠再往后如果不加數(shù)據(jù)增強(qiáng)或者不調(diào)loss基本就是在過(guò)擬合訓(xùn)練集。判斷過(guò)擬合有幾個(gè)信號(hào)train loss持續(xù)下降但val loss開(kāi)始反彈val集的mAP0.5漲但mAP0.5:0.95開(kāi)始停滯或者某些類(lèi)別在val集上的precision和recall開(kāi)始明顯背離。遇到這種情況優(yōu)先考慮加增強(qiáng)和早停不要盲目加訓(xùn)。5. 實(shí)訓(xùn)中的識(shí)別率表現(xiàn)與易踩坑點(diǎn)從驗(yàn)證集到真實(shí)道路場(chǎng)景訓(xùn)練完模型只是第一步真正檢驗(yàn)識(shí)別率的是把它放到真實(shí)場(chǎng)景里去看。5.1 指標(biāo)解讀別只盯著mAP0.5很多數(shù)據(jù)集宣傳超高識(shí)別率你必須問(wèn)清楚這個(gè)識(shí)別率是哪種指標(biāo)。mAP0.5算的是IoU閾值0.5下的平均精度這個(gè)指標(biāo)對(duì)邊界框的精確位置不敏感只要框大概在目標(biāo)附近就算對(duì)。而mAP0.5:0.95在一系列IoU閾值下取平均對(duì)邊框質(zhì)量的要求嚴(yán)苛得多。用這批數(shù)據(jù)訓(xùn)練出來(lái)的模型在驗(yàn)證集上mAP0.5超過(guò)0.9并不難真正的硬指標(biāo)是mAP0.5:0.95能穩(wěn)定在0.75以上就算不錯(cuò)。我實(shí)測(cè)下來(lái)YOLOv8m、imgsz960、訓(xùn)練160個(gè)epochmAP0.5在0.925左右mAP0.5:0.95在0.78左右。這個(gè)水平放在頭盔檢測(cè)場(chǎng)景里已經(jīng)可以拿去試跑真實(shí)視頻流了。5.2 真實(shí)場(chǎng)景里最容易翻車(chē)的幾個(gè)瞬間夜間弱光車(chē)燈眩光。監(jiān)控?cái)z像頭夜間畫(huà)質(zhì)普遍拉胯頭盔在這種畫(huà)面里經(jīng)常只是一團(tuán)模糊的亮斑。夜間的識(shí)別率普遍比白天低15%~20%這不是模型不努力而是輸入信息本身就不足。解決辦法有兩種一是圖像預(yù)處理做增強(qiáng)比如自適應(yīng)直方圖均衡或帶色彩恢復(fù)的多尺度Retinex二是訓(xùn)練時(shí)把低光樣本單獨(dú)做一個(gè)增強(qiáng)分支用MixUp把白天圖片調(diào)暗和真實(shí)夜間圖混合相當(dāng)于人工制造中間態(tài)樣本。遠(yuǎn)處的超小目標(biāo)。當(dāng)頭盔在畫(huà)面里只有十幾個(gè)像素大小時(shí)模型基本只能靠猜測(cè)輸出結(jié)果。這時(shí)候最實(shí)用的策略不是硬摳模型而是做多幀融合連續(xù)幾幀中如果同一位置都檢測(cè)到目標(biāo)就確認(rèn)輸出如果只是偶發(fā)框則判定為噪聲。這個(gè)思路比買(mǎi)更貴的算法模型性?xún)r(jià)比高得多。安全帽與頭盔的誤檢。工地安全帽外形和摩托車(chē)頭盔差異不小但如果一個(gè)騎手戴了安全帽騎車(chē)模型很容易把它當(dāng)成頭盔。這批數(shù)據(jù)集里包含了一部分安全帽樣本作為負(fù)例但真實(shí)環(huán)境中的安全帽樣式五花八門(mén)你在實(shí)際部署時(shí)建議再采集一些負(fù)樣本做增量訓(xùn)練把誤檢率往下壓。5.3 部署時(shí)的常用操作檢測(cè)模型產(chǎn)出的裸框丟給業(yè)務(wù)系統(tǒng)前一般要過(guò)幾道后處理置信度閾值推薦設(shè)置在0.35~0.45之間。調(diào)太低會(huì)在密集場(chǎng)景產(chǎn)生大量誤檢調(diào)太高會(huì)漏掉遮擋目標(biāo)。NMS的IoU閾值0.5左右比較平衡。如果你發(fā)現(xiàn)同一頂頭盔出現(xiàn)雙框可以適當(dāng)提高NMS的IoU閾值。類(lèi)別過(guò)濾如果業(yè)務(wù)只關(guān)心未戴頭盔的告警可以把戴頭盔的預(yù)測(cè)框直接過(guò)濾掉只保留低置信度的未戴框做上報(bào)這能大幅減少人工復(fù)核成本。在邊緣設(shè)備部署時(shí)YOLOv8n轉(zhuǎn)成TensorRT的engine文件后在Jetson Orin Nano上能做到30~40ms一幀基本滿(mǎn)足實(shí)時(shí)視頻流檢測(cè)需求。轉(zhuǎn)換時(shí)要特別注意動(dòng)態(tài)batch和動(dòng)態(tài)分辨率設(shè)置因?yàn)楸O(jiān)控畫(huà)面經(jīng)常被裁剪固定shape的engine在輸入尺寸變化時(shí)會(huì)直接報(bào)錯(cuò)。6. 數(shù)據(jù)集的擴(kuò)展思路用自己的攝像頭數(shù)據(jù)給模型持續(xù)補(bǔ)課沒(méi)有任何一個(gè)公開(kāi)數(shù)據(jù)集能覆蓋所有場(chǎng)景這批2514張圖片也不例外。聰明的做法是把它當(dāng)成預(yù)訓(xùn)練基礎(chǔ)包再疊加自己的場(chǎng)景數(shù)據(jù)做持續(xù)優(yōu)化。怎么最快速地給模型補(bǔ)課核心就是數(shù)據(jù)標(biāo)注的效率。這里推薦兩個(gè)組合半自動(dòng)標(biāo)注先用這批數(shù)據(jù)訓(xùn)練出一個(gè)初版模型然后拿著模型去跑你本地?cái)z像頭抽出來(lái)的圖片讓模型先出一版預(yù)測(cè)框。人工只需要把模型漏掉的框補(bǔ)上、標(biāo)錯(cuò)的框改掉標(biāo)注速度能提升3倍以上。難例回流模型在線(xiàn)上跑的時(shí)候?qū)iT(mén)收集那些置信度不高但實(shí)際是正確的和置信度很高但實(shí)際是錯(cuò)誤的樣本定期清洗后加入訓(xùn)練集做增量訓(xùn)練。這個(gè)方法比一次性堆幾千張隨機(jī)圖片更有效因?yàn)槊恳粡埿聵颖径荚谘a(bǔ)模型的短板。我之前在一次調(diào)試中試過(guò)用labelme手工標(biāo)注了一批本地停車(chē)場(chǎng)的頭盔圖片但labelme默認(rèn)導(dǎo)出的是JSON格式還得寫(xiě)腳本轉(zhuǎn)成VOC/COCO。如果你也在用labelme建議標(biāo)注時(shí)直接把類(lèi)別列表建好JSON轉(zhuǎn)VOC的時(shí)候會(huì)省掉很多字段映射的力氣。還有一個(gè)實(shí)用的擴(kuò)展策略利用視頻幀序列。你不需要一個(gè)場(chǎng)景抓幾千張圖片從一段連續(xù)視頻里每隔10幀抽一幀抽出來(lái)的圖天然就帶視角連續(xù)性和場(chǎng)景多樣性。跑模型標(biāo)注、人工糾錯(cuò)、增量訓(xùn)練重復(fù)幾輪之后模型在你自己場(chǎng)景的泛化能力會(huì)有肉眼可見(jiàn)的提升。另外提醒一點(diǎn)頭盔檢測(cè)的場(chǎng)景越垂直遷移學(xué)習(xí)的效果就越明顯。如果你手里本來(lái)就有一個(gè)在COCO上預(yù)訓(xùn)練的YOLO模型用它微調(diào)這批頭盔數(shù)據(jù)集收斂速度和最終精度都會(huì)優(yōu)于從頭訓(xùn)練。我自己試過(guò)從COCO預(yù)訓(xùn)練權(quán)重起步訓(xùn)練到120個(gè)epoch時(shí)精度已經(jīng)超過(guò)從頭訓(xùn)練200輪的結(jié)果。最后說(shuō)一個(gè)使用這批數(shù)據(jù)時(shí)的心得拿到任何公開(kāi)數(shù)據(jù)集先別急著開(kāi)訓(xùn)花半小時(shí)做一遍數(shù)據(jù)體檢看看類(lèi)別分布、看看邊界框標(biāo)注質(zhì)量、看看有沒(méi)有損壞圖片。這個(gè)習(xí)慣幫我避免過(guò)很多次訓(xùn)練出來(lái)效果差但找不到原因的尷尬情況。頭盔檢測(cè)這行數(shù)據(jù)和標(biāo)注的質(zhì)量往往比模型結(jié)構(gòu)更重要把基礎(chǔ)打牢后面的每一層優(yōu)化才站得住。本文還有配套的精品資源點(diǎn)擊獲取