實(shí)戰(zhàn):22600張數(shù)據(jù)集訓(xùn)練調(diào)優(yōu)與邊緣部署)
駕駛員行為檢測(cè)這個(gè)方向我在過(guò)去兩年里陸續(xù)接觸過(guò)幾個(gè)落地項(xiàng)目從最初拿公開(kāi)數(shù)據(jù)集跑通baseline到后來(lái)自己參與標(biāo)注和清洗兩萬(wàn)多張實(shí)拍圖踩過(guò)的坑不算少。這次拿到的是一份22600張規(guī)模的YOLO格式駕駛員行為檢測(cè)數(shù)據(jù)集說(shuō)實(shí)話這個(gè)體量在細(xì)分場(chǎng)景里已經(jīng)算相當(dāng)能打的了——市面上大多數(shù)公開(kāi)的駕駛行為數(shù)據(jù)集要么只有幾千張要么類別定義模糊、標(biāo)注質(zhì)量參差真正能直接拿來(lái)訓(xùn)練并部署上車的并不多。這份數(shù)據(jù)集的核心價(jià)值在于它把駕駛員行為這個(gè)籠統(tǒng)的概念拆成了可檢測(cè)的具體動(dòng)作類別并且用YOLO系列最順手的標(biāo)注格式組織好了省去了從零構(gòu)建標(biāo)注體系的大量時(shí)間。我打算圍繞這份數(shù)據(jù)集把從數(shù)據(jù)理解、格式校驗(yàn)、訓(xùn)練配置、類別不均衡處理到最終部署時(shí)的一些真實(shí)經(jīng)驗(yàn)完整講一遍。不管你是剛?cè)腴T(mén)目標(biāo)檢測(cè)想找個(gè)真實(shí)場(chǎng)景練手還是已經(jīng)在做智能座艙相關(guān)產(chǎn)品需要快速驗(yàn)證方案這篇內(nèi)容應(yīng)該都能給你省下不少試錯(cuò)成本。尤其是那些準(zhǔn)備把模型往邊緣設(shè)備上搬的朋友后面關(guān)于輸入分辨率和推理幀率的取舍部分值得仔細(xì)看看。1. 先搞清楚這22600張圖到底能檢測(cè)什么拿到任何一份數(shù)據(jù)集我的習(xí)慣是先別急著寫(xiě)訓(xùn)練腳本而是花半天時(shí)間把數(shù)據(jù)摸一遍。很多人上來(lái)就model.train()結(jié)果訓(xùn)到一半發(fā)現(xiàn)類別定義和自己業(yè)務(wù)對(duì)不上或者某些類別的樣本少得可憐白白浪費(fèi)算力。這份駕駛員行為檢測(cè)數(shù)據(jù)集從命名和常見(jiàn)同類數(shù)據(jù)集的組織方式推斷覆蓋的行為類別大概率包括打電話、抽煙、喝水、吃東西、單手駕駛、雙手離開(kāi)方向盤(pán)、轉(zhuǎn)頭張望、低頭看手機(jī)、正常駕駛等。具體類別數(shù)以你拿到的data.yaml為準(zhǔn)但理解這些類別的劃分邏輯比記住數(shù)字更重要。1.1 行為類別的粒度決定了模型的上限這里有個(gè)很容易被忽略的問(wèn)題行為檢測(cè)的類別粒度直接決定了你后面能不能把它用起來(lái)。舉個(gè)例子打電話和看手機(jī)在很多數(shù)據(jù)集里是分開(kāi)的兩類但在實(shí)際業(yè)務(wù)中低頭看導(dǎo)航和低頭刷視頻在視覺(jué)上高度相似如果數(shù)據(jù)集沒(méi)有區(qū)分你的模型就永遠(yuǎn)分不出來(lái)。反過(guò)來(lái)如果數(shù)據(jù)集把右手打電話和左手打電話分成兩類那對(duì)檢測(cè)精度是災(zāi)難——樣本被稀釋模型還得學(xué)一個(gè)本質(zhì)上無(wú)關(guān)的左右手差異。我的建議是先列出你業(yè)務(wù)真正關(guān)心的行為清單再和數(shù)據(jù)集類別做映射。能合并的合并該拆分的如果數(shù)據(jù)集沒(méi)拆就得考慮自己補(bǔ)標(biāo)注。22600張的規(guī)模如果按8:1:1劃分訓(xùn)練驗(yàn)證測(cè)試測(cè)試集也有兩千多張足夠做一次靠譜的類別分布統(tǒng)計(jì)。1.2 用幾行腳本把類別分布和標(biāo)注質(zhì)量摸清楚在動(dòng)手訓(xùn)練前我強(qiáng)烈建議跑一遍數(shù)據(jù)體檢。下面這段腳本可以統(tǒng)計(jì)每個(gè)類別的實(shí)例數(shù)量、每張圖的標(biāo)注框數(shù)量分布以及框的寬高比分布這幾個(gè)指標(biāo)能幫你提前發(fā)現(xiàn)大部分問(wèn)題。import os import glob from collections import Counter import numpy as np label_dir labels/train class_names [normal, phone, smoke, drink, eat, hand_off_wheel, look_around, look_down] cls_counter Counter() boxes_per_img [] aspect_ratios [] for txt in glob.glob(os.path.join(label_dir, *.txt)): with open(txt) as f: lines [l.strip() for l in f if l.strip()] boxes_per_img.append(len(lines)) for line in lines: parts line.split() cid int(parts[0]) w, h float(parts[3]), float(parts[4]) cls_counter[cid] 1 if h 0: aspect_ratios.append(w / h) print(類別實(shí)例數(shù):, {class_names[k]: v for k, v in cls_counter.items()}) print(每圖平均框數(shù):, np.mean(boxes_per_img)) print(寬高比中位數(shù):, np.median(aspect_ratios))跑完之后重點(diǎn)看兩件事。第一有沒(méi)有某個(gè)類別實(shí)例數(shù)特別少比如只有幾百個(gè)而最多的類別有幾萬(wàn)個(gè)這種長(zhǎng)尾分布會(huì)直接導(dǎo)致小類別召回率上不去。第二寬高比中位數(shù)如果偏離1太遠(yuǎn)說(shuō)明默認(rèn)的anchor設(shè)置可能不合適需要考慮重新聚類anchor或者用anchor-free的檢測(cè)頭。提示如果發(fā)現(xiàn)某些類別實(shí)例數(shù)低于總實(shí)例數(shù)的2%先別急著上focal loss優(yōu)先考慮數(shù)據(jù)層面能不能補(bǔ)或者用過(guò)采樣把這類圖片在訓(xùn)練時(shí)多喂幾遍效果往往比調(diào)損失函數(shù)更直接。1.3 標(biāo)注框的臟數(shù)據(jù)長(zhǎng)什么樣YOLO格式的標(biāo)注是歸一化的class x_center y_center width height理論上所有值都在0到1之間。但實(shí)際拿到的數(shù)據(jù)集里我見(jiàn)過(guò)坐標(biāo)超出1的、寬高為0的、甚至類別id超出類別總數(shù)的。這些臟標(biāo)注如果不清理訓(xùn)練時(shí)輕則loss異常重則直接報(bào)錯(cuò)中斷。上面那段腳本稍微改一下就能做校驗(yàn)把越界的行打印出來(lái)人工確認(rèn)是刪是改。22600張的規(guī)模臟數(shù)據(jù)比例通常在千分之幾花一兩個(gè)小時(shí)清理完全值得。2. YOLO格式數(shù)據(jù)的目錄組織與配置陷阱數(shù)據(jù)摸清楚之后接下來(lái)是把它組織成YOLO訓(xùn)練框架能直接吃的結(jié)構(gòu)。這一步看起來(lái)簡(jiǎn)單但我在不同項(xiàng)目里見(jiàn)過(guò)太多因?yàn)槁窂?、緩存、配置文件?xiě)錯(cuò)導(dǎo)致訓(xùn)練跑不起來(lái)的案例。尤其是當(dāng)你在多臺(tái)機(jī)器之間遷移數(shù)據(jù)時(shí)絕對(duì)路徑和相對(duì)路徑的坑幾乎每次都會(huì)踩。2.1 標(biāo)準(zhǔn)目錄結(jié)構(gòu)與data.yaml的正確寫(xiě)法YOLO系列無(wú)論是v5、v8還是更新的版本對(duì)目錄結(jié)構(gòu)有約定俗成的期望。推薦的組織方式是這樣dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yaml關(guān)鍵點(diǎn)是images和labels下的子目錄名必須嚴(yán)格對(duì)應(yīng)YOLO在找標(biāo)簽時(shí)是把圖片路徑里的images替換成labels再改后綴如果目錄名對(duì)不上它會(huì)靜默地認(rèn)為這張圖沒(méi)有標(biāo)簽直接跳過(guò)。這個(gè)坑特別隱蔽因?yàn)橛?xùn)練不會(huì)報(bào)錯(cuò)只是你的有效樣本悄悄少了一批。data.yaml的寫(xiě)法也有講究path: /abs/path/to/dataset train: images/train val: images/val test: images/test nc: 8 names: [normal, phone, smoke, drink, eat, hand_off_wheel, look_around, look_down]path建議寫(xiě)絕對(duì)路徑train/val/test寫(xiě)相對(duì)于path的路徑。我遇到過(guò)有人把train寫(xiě)成絕對(duì)路徑、path又寫(xiě)了另一個(gè)絕對(duì)路徑結(jié)果框架拼接出來(lái)的路徑完全不對(duì)。另外nc和names的長(zhǎng)度必須一致少一個(gè)都會(huì)在訓(xùn)練啟動(dòng)時(shí)報(bào)索引錯(cuò)誤。2.2 緩存文件引發(fā)的改了數(shù)據(jù)沒(méi)生效YOLO在第一次訓(xùn)練時(shí)會(huì)生成*.cache文件把標(biāo)簽解析結(jié)果緩存起來(lái)加速后續(xù)訓(xùn)練。這本來(lái)是個(gè)優(yōu)化但如果你中途修改了標(biāo)簽文件卻沒(méi)刪緩存框架會(huì)繼續(xù)用舊緩存導(dǎo)致你改的東西完全不生效。我有個(gè)同事調(diào)了一下午類別映射怎么訓(xùn)結(jié)果都不對(duì)最后發(fā)現(xiàn)是緩存沒(méi)清。處理辦法很簡(jiǎn)單每次改動(dòng)標(biāo)簽后手動(dòng)刪掉labels目錄下所有.cache文件或者干脆在訓(xùn)練腳本里加一句清理邏輯。這個(gè)細(xì)節(jié)在官方文檔里提得不多但實(shí)際項(xiàng)目中幾乎人人踩過(guò)。2.3 訓(xùn)練集驗(yàn)證集劃分的隱藏偏差如果你的數(shù)據(jù)集是別人劃分好的最好自己再檢查一遍劃分是否合理。我見(jiàn)過(guò)按圖片文件名順序簡(jiǎn)單切分的結(jié)果同一段視頻抽出來(lái)的連續(xù)幀被分到了訓(xùn)練集和驗(yàn)證集兩邊導(dǎo)致驗(yàn)證指標(biāo)虛高——模型其實(shí)在驗(yàn)證集上見(jiàn)過(guò)幾乎一樣的畫(huà)面。駕駛員行為數(shù)據(jù)很多來(lái)自連續(xù)視頻抽幀這個(gè)問(wèn)題尤其嚴(yán)重。正確的做法是按視頻源或按時(shí)間段劃分確保同一個(gè)駕駛員、同一段行程的幀只出現(xiàn)在一個(gè)集合里。如果數(shù)據(jù)集沒(méi)提供視頻源信息退而求其次可以按圖片的拍攝時(shí)間或文件修改時(shí)間做分組劃分。這一步多花點(diǎn)心思驗(yàn)證指標(biāo)才有參考價(jià)值。3. 訓(xùn)練配置從anchor到學(xué)習(xí)率的實(shí)戰(zhàn)取舍數(shù)據(jù)準(zhǔn)備好了真正決定模型好不好用的就是訓(xùn)練配置。這一塊網(wǎng)上教程很多但大多是拿COCO或VOC的通用配置直接套放到駕駛員行為這種特定場(chǎng)景未必合適。我結(jié)合這份數(shù)據(jù)集的特點(diǎn)講幾個(gè)我認(rèn)為最關(guān)鍵的配置點(diǎn)。3.1 輸入分辨率與駕駛員行為的小目標(biāo)問(wèn)題駕駛員行為檢測(cè)有個(gè)天然特點(diǎn)攝像頭通常裝在方向盤(pán)上方或A柱附近畫(huà)面里駕駛員占的比例不小但手部、手機(jī)、煙這些關(guān)鍵目標(biāo)相對(duì)整張圖來(lái)說(shuō)可能偏小。如果你用默認(rèn)的640輸入手部動(dòng)作的細(xì)節(jié)可能就糊掉了。我的經(jīng)驗(yàn)是如果算力允許訓(xùn)練時(shí)用比推理時(shí)更大的分辨率。比如訓(xùn)練用960或1280推理再降到640這樣模型學(xué)到的是更清晰的特征降分辨率推理時(shí)精度損失相對(duì)可控。反過(guò)來(lái)如果訓(xùn)練就用640推理想提到1280精度提升非常有限因?yàn)槟P蜎](méi)見(jiàn)過(guò)高分辨率的細(xì)節(jié)。當(dāng)然分辨率翻倍顯存占用和訓(xùn)練時(shí)間大致是平方級(jí)增長(zhǎng)。22600張圖1280分辨率下用單張24G顯存的卡batch size可能只能開(kāi)到8到16訓(xùn)練輪次要多一些才能收斂。這個(gè)取舍要根據(jù)你手頭的硬件來(lái)定。3.2 anchor聚類別直接用COCO的默認(rèn)值YOLOv5和v8都支持自動(dòng)anchor計(jì)算訓(xùn)練啟動(dòng)時(shí)會(huì)根據(jù)你的數(shù)據(jù)集重新聚類anchor。這個(gè)功能一定要開(kāi)。駕駛員行為數(shù)據(jù)集的框分布和COCO差異很大——COCO里各種尺度都有而駕駛行為框大多集中在中大尺度寬高比也偏向接近1的方形手部、手機(jī)、臉部區(qū)域。如果你用的是YOLOv5在訓(xùn)練命令里加上--noautoanchor的反面也就是保持自動(dòng)anchor開(kāi)啟默認(rèn)就是開(kāi)的。如果用的是需要手動(dòng)指定anchor的版本建議自己跑一遍k-means聚類from sklearn.cluster import KMeans import numpy as np # wh 是從所有標(biāo)簽里讀出來(lái)的 (width, height) 數(shù)組已歸一化 k 9 kmeans KMeans(n_clustersk, random_state42).fit(wh) anchors kmeans.cluster_centers_ print(聚類anchor:, anchors)聚類出來(lái)的anchor如果和默認(rèn)值差異超過(guò)20%就果斷換成新的。這個(gè)改動(dòng)對(duì)召回率的提升在特定場(chǎng)景下往往比換backbone還明顯。3.3 學(xué)習(xí)率與warmup小數(shù)據(jù)集要更保守22600張?jiān)谀繕?biāo)檢測(cè)里算中等偏小。這種規(guī)模下我傾向于用比默認(rèn)更小的初始學(xué)習(xí)率和更長(zhǎng)的warmup。YOLOv8默認(rèn)初始lr是0.01我一般會(huì)降到0.005甚至0.003warmup輪次從3提到5。原因是小數(shù)據(jù)集上梯度噪聲大學(xué)習(xí)率太高容易在早期就把特征帶偏后面很難拉回來(lái)。另外余弦退火cosine schedule在這個(gè)規(guī)模上表現(xiàn)通常比step schedule更穩(wěn)。如果你發(fā)現(xiàn)訓(xùn)練loss在前幾個(gè)epoch劇烈震蕩八成是學(xué)習(xí)率或warmup設(shè)置太激進(jìn)先降lr再看。3.4 數(shù)據(jù)增強(qiáng)的度駕駛場(chǎng)景不能亂增強(qiáng)YOLO默認(rèn)的增強(qiáng)包括mosaic、mixup、隨機(jī)縮放、色彩抖動(dòng)等。這些在通用場(chǎng)景很有效但駕駛行為檢測(cè)要小心。mosaic把四張圖拼一起可能把駕駛員的手和另一個(gè)人的手機(jī)拼到一塊產(chǎn)生語(yǔ)義錯(cuò)誤的樣本。mixup更激進(jìn)直接做圖像混合對(duì)行為識(shí)別這種依賴局部細(xì)節(jié)的任務(wù)可能有害。我的建議是mosaic可以開(kāi)但把概率從默認(rèn)的1.0降到0.5左右mixup直接關(guān)掉色彩抖動(dòng)保留因?yàn)檐噧?nèi)光照變化確實(shí)大隨機(jī)縮放保留但范圍別太大避免把關(guān)鍵的手部動(dòng)作縮得看不清。翻轉(zhuǎn)要謹(jǐn)慎水平翻轉(zhuǎn)會(huì)讓左手打電話變成右手打電話如果你的類別區(qū)分了左右手翻轉(zhuǎn)就得關(guān)掉。4. 類別不均衡與難例讓模型真正學(xué)會(huì)危險(xiǎn)行為駕駛員行為數(shù)據(jù)集幾乎必然存在類別不均衡——正常駕駛的樣本遠(yuǎn)多于抽煙、打電話這些異常行為。這是數(shù)據(jù)本身的分布決定的不是標(biāo)注問(wèn)題。怎么處理這個(gè)不均衡直接決定了模型在真實(shí)場(chǎng)景下能不能及時(shí)報(bào)警。4.1 從損失函數(shù)入手的幾種方案對(duì)比處理不均衡最直接的是在損失函數(shù)上做文章。我把常用的幾種方案和適用場(chǎng)景整理成表方便你對(duì)照選擇。方案原理適用場(chǎng)景注意事項(xiàng)類別加權(quán)給少樣本類別更高權(quán)重中度不均衡權(quán)重別設(shè)太極端否則正常類誤報(bào)飆升Focal Loss降低易分樣本權(quán)重難例多、長(zhǎng)尾明顯需調(diào)gamma默認(rèn)2不一定最優(yōu)過(guò)采樣重復(fù)少樣本圖片少樣本類別極少容易過(guò)擬合配合強(qiáng)增強(qiáng)使用復(fù)制粘貼增強(qiáng)把少樣本目標(biāo)貼到其他圖目標(biāo)可分離粘貼位置要合理避免懸空我個(gè)人的優(yōu)先級(jí)是先試類別加權(quán)簡(jiǎn)單可控如果小類別召回還是上不去再上focal loss過(guò)采樣作為最后手段且必須配合較強(qiáng)的數(shù)據(jù)增強(qiáng)否則模型會(huì)把那幾張圖背下來(lái)。4.2 難例挖掘那些看起來(lái)像但其實(shí)不是的樣本駕駛員行為檢測(cè)里有一類特別討厭的難例駕駛員撓頭被誤判成打電話拿水杯被誤判成抽煙調(diào)整后視鏡被誤判成轉(zhuǎn)頭張望。這些樣本在訓(xùn)練集里往往被標(biāo)成正常類但模型就是學(xué)不會(huì)區(qū)分。處理這類問(wèn)題的有效辦法是難例挖掘。先用訓(xùn)練好的模型在驗(yàn)證集上跑一遍把置信度在0.3到0.7之間的預(yù)測(cè)框挑出來(lái)人工復(fù)核。這些模型拿不準(zhǔn)的樣本恰恰是提升邊界能力的關(guān)鍵。把它們加入訓(xùn)練集重新訓(xùn)練往往能帶來(lái)幾個(gè)點(diǎn)的精度提升。22600張的規(guī)模挖出幾百個(gè)難例補(bǔ)充進(jìn)去性價(jià)比很高。4.3 評(píng)估指標(biāo)不能只看mAP在行為檢測(cè)這種安全相關(guān)場(chǎng)景mAP高不代表能用。你更該關(guān)注的是每個(gè)類別的召回率和誤報(bào)率。抽煙這種類別漏檢召回低意味著沒(méi)報(bào)警誤報(bào)精度低意味著頻繁打擾駕駛員。兩者哪個(gè)更不能接受取決于你的產(chǎn)品定位。我通常會(huì)把每個(gè)類別的PR曲線單獨(dú)畫(huà)出來(lái)看而不是只看一個(gè)總mAP。如果某個(gè)危險(xiǎn)行為的召回低于85%那這個(gè)模型基本不能上線得回去補(bǔ)數(shù)據(jù)或調(diào)閾值。另外混淆矩陣一定要看它能告訴你模型到底把A類錯(cuò)分成了B類還是C類這對(duì)定位問(wèn)題是決定性的。5. 部署落地分辨率和幀率的真實(shí)賬訓(xùn)練完模型真正的挑戰(zhàn)才開(kāi)始。駕駛員行為檢測(cè)大多要跑在車機(jī)或邊緣盒子上算力有限還得保證實(shí)時(shí)性。這一塊我踩的坑最多也最有發(fā)言權(quán)。5.1 輸入分辨率、幀率與路數(shù)的三角關(guān)系經(jīng)常有人問(wèn)某個(gè)算力平臺(tái)上YOLO能跑多少路。這個(gè)問(wèn)題沒(méi)有標(biāo)準(zhǔn)答案因?yàn)樗Q于分辨率、幀率、模型大小三者的組合。我拿一個(gè)常見(jiàn)的場(chǎng)景舉例說(shuō)明這個(gè)賬怎么算。假設(shè)你用TensorRT加速模型是YOLOv8s級(jí)別輸入640x640在某個(gè)主流邊緣芯片上單幀推理耗時(shí)約8毫秒。那么理論最大幀率是125幀每秒。如果每路視頻需要25幀每秒的處理速度理論上能支持5路。但這是理想值實(shí)際要打七折左右因?yàn)檫€有視頻解碼、預(yù)處理、后處理、內(nèi)存拷貝的開(kāi)銷。所以實(shí)際能穩(wěn)定跑3到4路。如果把輸入提到1280推理耗時(shí)大約變成原來(lái)的3到4倍也就是25到32毫秒一幀那25幀每秒就只能勉強(qiáng)跑1路甚至跑不滿。這就是為什么分辨率的選擇必須和你的路數(shù)需求一起考慮。輸入分辨率單幀耗時(shí)(相對(duì))25fps下單路占用可支持路數(shù)(估算)6401x約40%3-4路960約2.2x約90%1-2路1280約3.5x超100%1路(需降幀)注意上表是相對(duì)估算具體數(shù)值必須在你自己的硬件上實(shí)測(cè)。不同芯片的TensorRT優(yōu)化程度、內(nèi)存帶寬差異很大別人的數(shù)據(jù)只能參考。5.2 模型剪枝與量化精度換速度的邊界在哪如果算力實(shí)在不夠就得考慮剪枝和量化。INT8量化通常能帶來(lái)1.5到2倍的速度提升精度損失在1到2個(gè)點(diǎn)以內(nèi)對(duì)行為檢測(cè)來(lái)說(shuō)一般可以接受。但有個(gè)前提你的校準(zhǔn)集必須覆蓋真實(shí)場(chǎng)景的光照和角度分布否則量化后的模型在暗光或逆光下會(huì)崩得很厲害。剪枝要更謹(jǐn)慎。駕駛員行為檢測(cè)依賴手部、臉部這些細(xì)節(jié)特征剪枝剪過(guò)頭會(huì)直接把這些小目標(biāo)的特征通道剪沒(méi)。我的經(jīng)驗(yàn)是剪枝率控制在20%以內(nèi)剪完必須重新微調(diào)至少10個(gè)epoch并且重點(diǎn)看小類別召回有沒(méi)有掉。5.3 后處理與報(bào)警邏輯模型之外的功夫模型輸出只是檢測(cè)框真正要變成產(chǎn)品還得有后處理邏輯。比如打電話這個(gè)行為單幀檢測(cè)到可能是誤報(bào)連續(xù)5幀都檢測(cè)到才觸發(fā)報(bào)警這樣能大幅降低誤報(bào)。但連續(xù)幀數(shù)設(shè)太多又會(huì)漏掉快速的動(dòng)作。這個(gè)閾值需要在真實(shí)數(shù)據(jù)上反復(fù)調(diào)。另外檢測(cè)框的置信度閾值也不是越高越好。危險(xiǎn)行為檢測(cè)我傾向于把閾值設(shè)低一點(diǎn)比如0.3寧可多報(bào)也別漏報(bào)然后用時(shí)序邏輯去過(guò)濾誤報(bào)。這和通用目標(biāo)檢測(cè)的思路是反的但符合安全場(chǎng)景的需求。6. 幾個(gè)我踩過(guò)的坑和對(duì)應(yīng)的解法最后這部分我想把幾個(gè)印象深刻的坑單獨(dú)拎出來(lái)講都是那種文檔里不會(huì)寫(xiě)、但實(shí)際項(xiàng)目里一定會(huì)遇到的。6.1 訓(xùn)練中BN層崩潰有一次訓(xùn)練到第30個(gè)epoch左右loss突然變成NaN怎么都恢復(fù)不了。排查下來(lái)是某個(gè)batch里出現(xiàn)了全黑的圖片數(shù)據(jù)里有損壞文件導(dǎo)致BN層的方差計(jì)算出問(wèn)題。解決辦法有兩個(gè)一是在數(shù)據(jù)加載時(shí)加校驗(yàn)把全黑、全白、尺寸異常的圖片過(guò)濾掉二是把BN的eps調(diào)大一點(diǎn)增加數(shù)值穩(wěn)定性。前者治本后者治標(biāo)建議都做。6.2 混淆矩陣總和不等于樣本數(shù)這個(gè)現(xiàn)象很多人遇到過(guò)以為是框架bug。其實(shí)是因?yàn)閅OLO的混淆矩陣統(tǒng)計(jì)的是預(yù)測(cè)框和真實(shí)框的匹配結(jié)果一個(gè)真實(shí)框可能匹配到多個(gè)預(yù)測(cè)框或者因?yàn)镮oU閾值設(shè)置導(dǎo)致某些框沒(méi)被計(jì)入。如果你發(fā)現(xiàn)總和對(duì)不上先檢查IoU閾值和置信度閾值通常調(diào)一下就能對(duì)上。這不是數(shù)據(jù)問(wèn)題不用慌。6.3 驗(yàn)證集指標(biāo)很好但實(shí)車一塌糊涂這是最經(jīng)典的坑。原因通常是訓(xùn)練數(shù)據(jù)的分布和實(shí)車場(chǎng)景不一致——數(shù)據(jù)集里的駕駛員可能都是白天、正面、光線充足而實(shí)車會(huì)遇到夜間、側(cè)臉、逆光。解決辦法只有一個(gè)拿實(shí)車數(shù)據(jù)做測(cè)試把bad case挑出來(lái)補(bǔ)進(jìn)訓(xùn)練集。22600張是個(gè)很好的起點(diǎn)但要真正上車通常還需要再補(bǔ)幾千張真實(shí)場(chǎng)景的難例。數(shù)據(jù)集是起點(diǎn)不是終點(diǎn)。6.4 關(guān)于預(yù)訓(xùn)練權(quán)重的選擇很多人糾結(jié)用COCO預(yù)訓(xùn)練還是ImageNet預(yù)訓(xùn)練。我的經(jīng)驗(yàn)是目標(biāo)檢測(cè)任務(wù)直接用COCO預(yù)訓(xùn)練的檢測(cè)權(quán)重收斂最快。如果找不到對(duì)應(yīng)版本的檢測(cè)權(quán)重用ImageNet的分類權(quán)重初始化backbone也比從頭訓(xùn)強(qiáng)。但要注意如果你改過(guò)backbone結(jié)構(gòu)預(yù)訓(xùn)練權(quán)重可能對(duì)不上這時(shí)候要么用strictFalse加載能對(duì)上的部分要么干脆從頭訓(xùn)但把學(xué)習(xí)率調(diào)更小、輪次拉更長(zhǎng)。駕駛員行為檢測(cè)這個(gè)方向數(shù)據(jù)是根基配置是杠桿部署是試金石。22600張的數(shù)據(jù)集給了你一個(gè)不錯(cuò)的起點(diǎn)但真正決定成敗的是你對(duì)業(yè)務(wù)場(chǎng)景的理解和對(duì)細(xì)節(jié)的把控。我在實(shí)際項(xiàng)目里最大的體會(huì)是與其花大量時(shí)間調(diào)模型結(jié)構(gòu)不如先把數(shù)據(jù)清洗和類別定義做扎實(shí)前者帶來(lái)的提升往往是后者的好幾倍。另外別迷信公開(kāi)數(shù)據(jù)集上的漂亮指標(biāo)拿你自己的場(chǎng)景數(shù)據(jù)測(cè)一遍才知道模型到底行不行。