層實(shí)現(xiàn)垃圾分類實(shí)時(shí)識(shí)別與邊緣部署實(shí)踐)
垃圾分類這件事做起來(lái)比想象中復(fù)雜得多。我一直覺(jué)得回收物里的“瓶瓶罐罐”應(yīng)該是最容易分的真上手做了一個(gè)自動(dòng)分類識(shí)別項(xiàng)目之后才意識(shí)到玻璃瓶和陶瓷片在鏡頭下有多像亞克力板和塑料蓋混在一起時(shí)連人都容易看走眼。這個(gè)項(xiàng)目我用的是YOLOv10n加P2檢測(cè)層的組合目標(biāo)就是在低成本設(shè)備上實(shí)現(xiàn)可回收物的實(shí)時(shí)分類識(shí)別。整套方案跑下來(lái)識(shí)別速度和精度都達(dá)到了可用的狀態(tài)這篇文章把我從數(shù)據(jù)準(zhǔn)備、模型選型到訓(xùn)練部署的完整過(guò)程以及踩過(guò)的幾個(gè)比較深的坑一次性整理出來(lái)希望對(duì)正在做垃圾分類視覺(jué)方案的同行有點(diǎn)幫助。這個(gè)項(xiàng)目適合誰(shuí)參考如果你是做邊緣設(shè)備上的目標(biāo)檢測(cè)或者正在搭智能回收箱、垃圾分類演示系統(tǒng)再或者只是對(duì)YOLO系列模型如何加P2層感興趣這篇內(nèi)容都值得看一看。我會(huì)把整個(gè)決策過(guò)程講清楚而不只是貼一段訓(xùn)練命令畢竟知道為什么這么選比會(huì)敲代碼重要得多。1. 整體設(shè)計(jì)與思路拆解1.1 為什么選YOLOv10n而不是YOLOv8或YOLOv5我最早其實(shí)是從YOLOv5起步的那套生態(tài)太成熟了網(wǎng)上資料一抓一大把。但真正放到垃圾分類這個(gè)場(chǎng)景里有幾個(gè)問(wèn)題讓我不得不換方向。首先是部署環(huán)境智能回收箱里面用的基本是低功耗的嵌入式板子算力有限YOLOv5s跑起來(lái)雖然能到實(shí)時(shí)但留給其他業(yè)務(wù)邏輯的算力就不夠了。第二是后處理流程YOLOv5和v8都需要非極大值抑制這在代碼層面不難寫但在設(shè)備上多一步處理延遲就高一點(diǎn)而且NMS的參數(shù)還需要單獨(dú)調(diào)偶爾還會(huì)出現(xiàn)同一個(gè)瓶子被兩個(gè)框同時(shí)框住的情況。YOLOv10在這個(gè)場(chǎng)景下的優(yōu)勢(shì)非常直接它的核心賣點(diǎn)是無(wú)NMS推理訓(xùn)練的時(shí)候用了一致雙分配策略讓模型在推理階段可以省掉NMS這個(gè)過(guò)程直接輸出最終檢測(cè)結(jié)果。我在實(shí)際測(cè)試中發(fā)現(xiàn)同樣的輸入分辨率下YOLOv10n的推理延遲比YOLOv8n低了大概20%這個(gè)差距在邊緣設(shè)備上很可觀。另一個(gè)讓我堅(jiān)定的理由是YOLOv10的端到端特性。以前做嵌入式部署導(dǎo)出到TensorRT或者ONNX之后為了把NMS算子塞進(jìn)去經(jīng)常要折騰半天。YOLOv10直接省掉這一步導(dǎo)出模型就簡(jiǎn)單很多我后面甚至?xí)iT講這個(gè)過(guò)程。選nano版本也是經(jīng)過(guò)考量的。很多人有個(gè)誤區(qū)覺(jué)得模型越大精度越高就無(wú)腦往上沖。但可回收物分類這個(gè)任務(wù)類別之間的差異總體來(lái)說(shuō)是比較明顯的瓶子的形狀、玻璃的質(zhì)感、紙箱的紋理這些特征用一個(gè)小模型其實(shí)就能學(xué)到。我用YOLOv10n跑出來(lái)的效果和v10s在主力類別上的mAP差距只有1.5個(gè)點(diǎn)但參數(shù)量從4.5M降到2.3M計(jì)算量直接從8.2 GFLOPs降到大約6.7 GFLOPs這個(gè)交易我認(rèn)為非常劃算。1.2 P2檢測(cè)層到底解決了什么問(wèn)題P2檢測(cè)層是這次項(xiàng)目里我覺(jué)得最關(guān)鍵的一個(gè)設(shè)計(jì)。標(biāo)準(zhǔn)YOLOv10的檢測(cè)頭從P3到P5對(duì)應(yīng)下采樣8倍、16倍、32倍的特征圖。聽(tīng)起來(lái)好像覆蓋得挺全的但垃圾分類場(chǎng)景里有很多目標(biāo)物就是很小比如一袋垃圾里的塑料瓶蓋、單獨(dú)的煙蒂、碎玻璃渣這些目標(biāo)在原圖上可能就二三十個(gè)像素經(jīng)過(guò)8倍下采樣之后只剩3到4個(gè)像素特征基本就丟失了。P2層就是把高分辨率的特征圖也接入檢測(cè)頭對(duì)應(yīng)原圖的4倍下采樣。這樣一來(lái)小目標(biāo)在特征圖上的尺寸翻了一倍模型能捕捉到的細(xì)節(jié)多得多。我用同一個(gè)數(shù)據(jù)集在YOLOv10n和YOLOv10n-P2之間做過(guò)對(duì)比測(cè)試加P2之后小目標(biāo)類別的mAP50提升了接近4個(gè)百分點(diǎn)這個(gè)幅度在小模型上是非??捎^的。當(dāng)然天下沒(méi)有免費(fèi)的午餐。P2檢測(cè)頭意味著模型要多處理一層高分辨率特征圖計(jì)算量會(huì)增加一部分推理延遲也會(huì)略微上升。我實(shí)測(cè)下來(lái)YOLOv10n加P2之后參數(shù)量從2.3M漲到大概3.1MGPU上的推理時(shí)間增加了大約15%CPU上增加得更明顯。所以P2不是盲目加的如果你的場(chǎng)景目標(biāo)物都比較大加P2反而畫蛇添足。但可回收物檢測(cè)這種對(duì)細(xì)粒度要求高的場(chǎng)景我認(rèn)為這一層是必須的。1.3 類別的設(shè)定與識(shí)別策略可回收物的分類標(biāo)準(zhǔn)各地有差異我沒(méi)有也沒(méi)有權(quán)限直接去對(duì)應(yīng)某地的具體政策而是從通用性的角度出發(fā)設(shè)定了幾個(gè)最常見(jiàn)的類別塑料瓶、玻璃瓶、易拉罐鋁制品、紙箱/紙殼、還有紡織品。另外我還加了一個(gè)其他可回收物作為兜底避免模型遇到?jīng)]見(jiàn)過(guò)的東西時(shí)強(qiáng)制做錯(cuò)誤分類。在識(shí)別策略上有一個(gè)細(xì)節(jié)值得分享。剛開始我用的是單一模型識(shí)別所有類別后來(lái)發(fā)現(xiàn)玻璃瓶和塑料瓶在視覺(jué)上確實(shí)不好區(qū)分——透光性接近顏色也接近。我試著把玻璃瓶單獨(dú)拆出來(lái)用一個(gè)小分類器做二次確認(rèn)效果好了很多。這其實(shí)就是目標(biāo)檢測(cè)里常用的粗分類加細(xì)分類的級(jí)聯(lián)思路雖然增加了一步流程但對(duì)生產(chǎn)環(huán)境的精度提升很有幫助。不過(guò)為了保持方案的可復(fù)現(xiàn)性和簡(jiǎn)潔性最終交付的版本還是單模型多類別識(shí)別級(jí)聯(lián)方案作為一個(gè)優(yōu)化分支記錄在文檔里。2. 數(shù)據(jù)集準(zhǔn)備與增強(qiáng)策略2.1 數(shù)據(jù)采集與標(biāo)注的經(jīng)驗(yàn)做目標(biāo)檢測(cè)項(xiàng)目數(shù)據(jù)永遠(yuǎn)是第一位的。我在網(wǎng)上找了一些垃圾圖像的數(shù)據(jù)集也自己拍攝補(bǔ)充了很多在回收站常見(jiàn)的真實(shí)場(chǎng)景圖片。這里有一個(gè)經(jīng)驗(yàn)就是網(wǎng)上的數(shù)據(jù)集雖然標(biāo)注規(guī)范但背景太干凈了都是純色桌面上的物體特寫?,F(xiàn)實(shí)場(chǎng)景里垃圾桶旁邊可能有紙屑雜物光線忽明忽暗甚至有人直接把袋子扔下來(lái)把瓶子壓得變形。如果你只用公開數(shù)據(jù)集訓(xùn)練模型在其他環(huán)境里表現(xiàn)會(huì)明顯下降。我自己補(bǔ)充數(shù)據(jù)時(shí)專門跑到回收點(diǎn)拍了三個(gè)不同時(shí)段的照片上午順光、中午強(qiáng)光、傍晚暗光。手機(jī)拍攝分辨率不用太高但構(gòu)圖一定要貼近真實(shí)使用場(chǎng)景。標(biāo)注的時(shí)候用了一種很樸素的策略把所有塑料瓶統(tǒng)一標(biāo)注為plastic_bottle不區(qū)分透明和不透明讓模型自己去學(xué)這兩種形態(tài)的共同特征。玻璃瓶同樣處理標(biāo)注為glass_bottle易拉罐統(tǒng)一為aluminum_can紙類為cardboard紡織物為textile還有一類others作為兜底。標(biāo)注工具用的就是常見(jiàn)的開源標(biāo)注軟件導(dǎo)出格式直接選YOLO的txt格式每個(gè)圖片對(duì)應(yīng)一個(gè)txt文件里面每行是類別id x_center y_center width height坐標(biāo)全部歸一化到0到1之間。這里要特別強(qiáng)調(diào)連續(xù)標(biāo)注兩三個(gè)小時(shí)后必須休息一下疲勞狀態(tài)下畫的目標(biāo)框位置會(huì)明顯偏移后面處理起來(lái)非常麻煩。2.2 易混淆類別的處理技巧垃圾分類識(shí)別最難的不是認(rèn)出這是瓶子而是分辨這是玻璃還是塑料。兩者在圖像上的區(qū)別確實(shí)微小尤其是透明玻璃瓶和透明PET塑料瓶肉眼看過(guò)去都是細(xì)長(zhǎng)條狀半透明高光位置也接近。我的處理辦法是盡量在標(biāo)注時(shí)把這類易混淆樣本單獨(dú)篩出來(lái)配合P2層的高分辨率特征讓模型有更多的像素紋理信息可以依據(jù)——玻璃瓶的瓶口形態(tài)和塑料瓶有明顯差異瓶底凹槽和壁厚的邊緣特征也不同。我還在數(shù)據(jù)增強(qiáng)環(huán)節(jié)專門加入了針對(duì)性的選項(xiàng)。光照變化模擬用的是HSV增強(qiáng)色相偏移設(shè)置得非常小亮度和飽和度做隨機(jī)擾動(dòng)模糊增強(qiáng)適量加了一些模擬運(yùn)動(dòng)中的抓拍效果。這里有一點(diǎn)要注意類別不平衡的問(wèn)題在垃圾數(shù)據(jù)里很常見(jiàn)塑料瓶的樣本可能占了40%紡織品只有5%。如果不處理模型會(huì)對(duì)樣本多的類別過(guò)擬合。我用最簡(jiǎn)單的加權(quán)采樣策略讓每個(gè)類別的樣本在每次epoch中出現(xiàn)的概率盡量均勻效果很不錯(cuò)。2.3 數(shù)據(jù)劃分與驗(yàn)證集設(shè)計(jì)數(shù)據(jù)劃分這部分我的做法是70%訓(xùn)練、20%驗(yàn)證、10%測(cè)試同時(shí)保證劃分后的數(shù)據(jù)分布一致。比如玻璃瓶樣本不能全落在訓(xùn)練集里驗(yàn)證集和測(cè)試集里也必須有這樣才能測(cè)出模型的真實(shí)泛化能力。另外我專門留了一組零樣本測(cè)試集就是在網(wǎng)上找一些訓(xùn)練時(shí)完全沒(méi)有見(jiàn)過(guò)的垃圾圖片模擬冷啟動(dòng)場(chǎng)景。這個(gè)測(cè)試集不進(jìn)訓(xùn)練流程只用來(lái)做最終效果驗(yàn)收。事實(shí)證明這一步非常必要模型在驗(yàn)證集上mAP50能到90但零樣本測(cè)試集上只有78差距很大這才暴露了過(guò)擬合問(wèn)題。精調(diào)之后通過(guò)增加數(shù)據(jù)增強(qiáng)強(qiáng)度和降低模型復(fù)雜度我成功把零樣本測(cè)試集上的性能提升到了85以上。這個(gè)數(shù)字我認(rèn)為是判斷模型能不能真正上線的關(guān)鍵指標(biāo)而不是只看驗(yàn)證集的漂亮分?jǐn)?shù)。3. 模型訓(xùn)練與核心配置3.1 訓(xùn)練環(huán)境與超參數(shù)選擇訓(xùn)練我用了一臺(tái)帶有一張中等規(guī)格GPU的機(jī)器。很多人關(guān)心顯存夠不夠其實(shí)YOLOv10n參數(shù)量很小在batch size16、輸入分辨率640x640的情況下顯存占用也就6GB左右門檻不高。超參數(shù)里面最值得討論的是輸入分辨率和epoch數(shù)。我試過(guò)480、640、800三檔分辨率480下面是速度很快但小目標(biāo)類別的表現(xiàn)明顯下降玻璃瓶這類中等尺寸目標(biāo)倒還好但瓶蓋和小碎片直接丟失。640是平衡點(diǎn)識(shí)別速度和精度都讓人滿意。800分辨率確實(shí)讓mAP又漲了1.5個(gè)點(diǎn)但推理耗時(shí)增加了接近50%部署到嵌入式設(shè)備上實(shí)在扛不住最終選了640。epoch數(shù)我設(shè)置了300輪配合早停機(jī)制。YOLOv10官方預(yù)訓(xùn)練權(quán)重是在COCO數(shù)據(jù)集上訓(xùn)練的雖然分類類別不一樣但底層特征提取能力是共通的所以我沒(méi)有從零開始訓(xùn)練而是基于預(yù)訓(xùn)練權(quán)重做遷移學(xué)習(xí)。遷移學(xué)習(xí)有個(gè)經(jīng)驗(yàn)初始學(xué)習(xí)率不要太高不然容易把預(yù)訓(xùn)練學(xué)好的底層特征破壞掉。我用的是初始學(xué)習(xí)率0.01帶動(dòng)量0.937權(quán)重衰減0.0005訓(xùn)練過(guò)程跑得比較穩(wěn)定。3.2 訓(xùn)練過(guò)程中的關(guān)鍵觀察訓(xùn)練過(guò)程中我習(xí)慣盯著幾個(gè)關(guān)鍵指標(biāo)看box_loss、cls_loss以及驗(yàn)證集的mAP50和mAP50-95。剛開始的幾十個(gè)epoch損失下降很快mAP也一路漲這是正常現(xiàn)象。但我發(fā)現(xiàn)大概在第180輪開始驗(yàn)證集mAP就基本不再上升了訓(xùn)練損失還在緩慢下降——這就是典型過(guò)擬合信號(hào)。此時(shí)早停機(jī)制還沒(méi)觸發(fā)因?yàn)槲以O(shè)的耐心值是50輪實(shí)際上我選擇手動(dòng)在第220輪左右停掉了訓(xùn)練。在P2模型上我觀察到過(guò)擬合的時(shí)間點(diǎn)比標(biāo)準(zhǔn)模型來(lái)得更早一些因?yàn)镻2層的參數(shù)量變大對(duì)訓(xùn)練數(shù)據(jù)的擬合能力更強(qiáng)這其實(shí)需要配合更強(qiáng)的數(shù)據(jù)增強(qiáng)一起用。最終保存的最優(yōu)權(quán)重是驗(yàn)證集上表現(xiàn)最好的一輪而不是最后一輪。這是一個(gè)很簡(jiǎn)單但經(jīng)常被忽略的操作因?yàn)楹竺娴挠?xùn)練可能已經(jīng)在過(guò)擬合邊緣徘徊了。3.3 與標(biāo)準(zhǔn)YOLOv10n的對(duì)比實(shí)驗(yàn)結(jié)果我在同等條件下訓(xùn)練了兩個(gè)模型一個(gè)標(biāo)準(zhǔn)YOLOv10n一個(gè)添加P2檢測(cè)頭的YOLOv10n-P2其他配置完全一致方便做對(duì)照。模型參數(shù)量GFLOPsmAP50mAP50-95小目標(biāo)mAP50YOLOv10n2.3M6.788.263.561.3YOLOv10n-P23.1M8.990.166.865.2表格里的小目標(biāo)mAP50是單獨(dú)統(tǒng)計(jì)瓶蓋、碎片這類小尺寸物體算出來(lái)的指標(biāo)??梢郧逦吹絇2層帶來(lái)最大的收益就在小目標(biāo)這一項(xiàng)上提升了接近4個(gè)點(diǎn)??俶AP50的提升是1.9個(gè)點(diǎn)看起來(lái)不算大但考慮到這已經(jīng)是90左右的水平每一分的提升都來(lái)之不易。速度方面GPU推理時(shí)間從5.6ms增加到6.5ms這個(gè)代價(jià)換4個(gè)點(diǎn)的小目標(biāo)精度我認(rèn)為值得。4. 模型導(dǎo)出與部署實(shí)踐4.1 從訓(xùn)練權(quán)重到ONNX導(dǎo)出的避坑記錄訓(xùn)練完成后部署的第一步是把PyTorch權(quán)重導(dǎo)出為ONNX格式這一步理論上很簡(jiǎn)單但我在實(shí)際操作中踩了一個(gè)不小的坑。因?yàn)槲矣玫氖菐2結(jié)構(gòu)的自定義配置導(dǎo)出時(shí)如果參數(shù)設(shè)置不對(duì)會(huì)報(bào)錯(cuò)提示檢測(cè)頭維度匹配不上后來(lái)排查發(fā)現(xiàn)是導(dǎo)出時(shí)的opset版本太低導(dǎo)致的。我最終選擇的opset是12以上同時(shí)把dynamic輸入打開讓模型可以接受動(dòng)態(tài)尺寸的輸入。這里有一個(gè)權(quán)衡要講清楚動(dòng)態(tài)輸入意味著部署端可以傳入任意分辨率的圖片靈活性高但推理速度會(huì)比固定尺寸略慢。我建議部署時(shí)先用動(dòng)態(tài)尺寸導(dǎo)出驗(yàn)證效果后再固定到640x640這樣性能最優(yōu)。導(dǎo)出命令的要點(diǎn)就是輸入節(jié)點(diǎn)的命名要固定后面在推理代碼里要用同一個(gè)名字來(lái)填數(shù)據(jù)。如果這一步搞錯(cuò)了部署端的tensor維度就會(huì)完全對(duì)不上你會(huì)看到一片亂碼的輸出。4.2 邊緣設(shè)備上的推理優(yōu)化在CPU設(shè)備上做推理優(yōu)化時(shí)YOLOv10無(wú)NMS的特性幫了大忙。標(biāo)準(zhǔn)YOLO在ONNX Runtime下除了跑主干網(wǎng)絡(luò)之外還要額外處理NMS節(jié)點(diǎn)這部分在CPU上很耗時(shí)經(jīng)常要占整個(gè)推理時(shí)間的30%。YOLOv10直接輸出解碼后的結(jié)果雖然官方說(shuō)不需要NMS但為了保險(xiǎn)起見(jiàn)我仍然在部署端保留了一個(gè)簡(jiǎn)單的置信度過(guò)濾和重疊框合并邏輯只是這個(gè)邏輯比傳統(tǒng)NMS簡(jiǎn)單得多計(jì)算量可以忽略不計(jì)。我還測(cè)試了OpenVINO、TensorRT等多種推理后端。TensorRT的加速效果確實(shí)最好但轉(zhuǎn)換過(guò)程比較繁瑣需要校準(zhǔn)數(shù)據(jù)OpenVINO則勝在部署簡(jiǎn)單只需要把ONNX文件直接導(dǎo)入不需要額外校準(zhǔn)。如果你的目標(biāo)設(shè)備是Intel平臺(tái)我推薦直接用OpenVINO如果是ARM架構(gòu)的板子ONNX Runtime的CPU版本加上合理線程數(shù)配置就能有不錯(cuò)的表現(xiàn)。線程數(shù)這個(gè)參數(shù)很多人不重視默認(rèn)值在邊緣設(shè)備上往往不是最優(yōu)的。我實(shí)測(cè)單核和多核的效果差異很顯著多核模式下延遲降到單核的60%左右但功耗也會(huì)上升需要根據(jù)設(shè)備散熱條件取舍。4.3 整個(gè)識(shí)別流程的串接部署端的整個(gè)識(shí)別流程我分成三步圖像預(yù)處理、模型推理、后處理。預(yù)處理這一步需要保持和訓(xùn)練時(shí)一致的預(yù)處理方式我用的是Letterbox加灰度填充將原始圖像等比縮放到640x640多余部分用灰色填充。這里有個(gè)容易被忽視的點(diǎn)就是填充顏色必須和訓(xùn)練時(shí)一致。我見(jiàn)過(guò)有人訓(xùn)練時(shí)用白色填充推理時(shí)用黑色填充導(dǎo)致檢測(cè)精度驟降。推理輸出是一個(gè)維度為1x84x8400的tensor其中84是4個(gè)框坐標(biāo)加80個(gè)COCO類別的概率8400是預(yù)設(shè)錨框的數(shù)量。因?yàn)槲业淖远x模型類別數(shù)是6實(shí)際輸出維度會(huì)變成1x10x8400后面處理時(shí)要注意調(diào)整。解碼之后對(duì)置信度低于0.25的框直接刪除然后按類別聚合處理輸出最終結(jié)果。這一步我建議加一個(gè)簡(jiǎn)單的消抖邏輯。因?yàn)閿z像頭在連續(xù)幀中檢測(cè)同一個(gè)瓶子時(shí)框的位置會(huì)輕微抖動(dòng)輸出給機(jī)械臂或者舵機(jī)的抓取坐標(biāo)就會(huì)不穩(wěn)定。我對(duì)檢測(cè)框的坐標(biāo)做滑動(dòng)平均連續(xù)3幀的坐標(biāo)取平均輸出抓取準(zhǔn)確率明顯提升。5. 識(shí)別效果與性能分析5.1 各類別的識(shí)別表現(xiàn)差異模型訓(xùn)練完之后我統(tǒng)計(jì)了每個(gè)類別的單獨(dú)表現(xiàn)這比看整體的mAP要直觀得多。塑料瓶和易拉罐這兩個(gè)類別效果最好準(zhǔn)確率都在93%以上這是因?yàn)檫@兩個(gè)類別樣本量大、形態(tài)也比較統(tǒng)一塑料瓶有瓶口、瓶身、瓶底的固定結(jié)構(gòu)易拉罐有拉環(huán)和金屬反光的獨(dú)特特征模型學(xué)起來(lái)很輕松。紙箱和紡織物屬于中等難度紙箱的麻煩在于形態(tài)多變壓扁的和立體的完全是兩種樣子模型偶爾會(huì)把壓扁的紙箱和廢紙混在一起。紡織物的難點(diǎn)在紋理豐富程度毛衣和T恤的紋理差異很大模型對(duì)光滑面料和粗糙面料的響應(yīng)不一樣我補(bǔ)充了很多不同材質(zhì)織物樣本后準(zhǔn)確率才逐漸上來(lái)。最難的還是玻璃瓶尤其是透明玻璃瓶在灰色背景下的表現(xiàn)不太穩(wěn)定。我檢查了一些失敗樣本發(fā)現(xiàn)模型會(huì)把帶有綠色調(diào)的玻璃瓶誤判為塑料瓶問(wèn)題出在訓(xùn)練數(shù)據(jù)里綠色塑料瓶樣本太多模型形成了綠色塑料的錯(cuò)誤關(guān)聯(lián)。這個(gè)問(wèn)題的解決方法是往玻璃類別里補(bǔ)充帶有淡綠色調(diào)的樣本同時(shí)增加綠色塑料瓶的標(biāo)注準(zhǔn)確性雙管齊下才把混淆率壓下去。5.2 光照與拍攝角度的影響測(cè)試部署到實(shí)際場(chǎng)景之前我在一個(gè)模擬回收裝置的環(huán)境里做了專門的壓力測(cè)試。測(cè)試環(huán)境的光照用的是常見(jiàn)白光燈角度從正面照和側(cè)上方照兩種我發(fā)現(xiàn)在側(cè)上方光照下所有類別的識(shí)別準(zhǔn)確率都有所下降約2到3個(gè)點(diǎn)。原因在于強(qiáng)光在玻璃瓶表面形成大面積高光區(qū)域把瓶子本身的紋理信息遮蓋掉了。應(yīng)對(duì)策略是從算法層面和數(shù)據(jù)層面同時(shí)下手。數(shù)據(jù)層面我在訓(xùn)練數(shù)據(jù)增強(qiáng)中增加了隨機(jī)高光模擬讓模型適應(yīng)局部過(guò)曝算法層面我調(diào)整了預(yù)處理時(shí)的曝光補(bǔ)償在推理前先做一次直方圖均衡化。這兩步疊加后來(lái)看側(cè)光條件下的準(zhǔn)確率下降從3個(gè)點(diǎn)控制到了1個(gè)點(diǎn)以內(nèi)。5.3 吞吐量與實(shí)時(shí)性評(píng)估對(duì)部署在回收裝備上的系統(tǒng)來(lái)說(shuō)實(shí)時(shí)性是最硬的指標(biāo)。我的設(shè)備上最終實(shí)現(xiàn)的單幀推理時(shí)間是145毫秒加上預(yù)處理和后處理整體單幀流程在180毫秒左右換算下來(lái)每秒處理5.5幀左右。對(duì)一個(gè)需要抓取物品的機(jī)械臂來(lái)說(shuō)這個(gè)速度已經(jīng)夠用了。在連續(xù)運(yùn)行測(cè)試中模型在1600多幀圖像上的平均檢測(cè)置信度穩(wěn)定在0.72附近沒(méi)有出現(xiàn)大幅波動(dòng)內(nèi)存占用也保持穩(wěn)定長(zhǎng)時(shí)間運(yùn)行沒(méi)有明顯泄漏。CPU溫度在長(zhǎng)時(shí)間滿負(fù)荷運(yùn)行后處于可接受范圍不需要額外加散熱器就能穩(wěn)住。我覺(jué)得這個(gè)方案在算力要求上已經(jīng)比動(dòng)輒需要高性能獨(dú)立顯卡的方案實(shí)用得多普通性能級(jí)別的嵌入式設(shè)備就能帶起來(lái)。6. 常見(jiàn)問(wèn)題與排查技巧實(shí)錄6.1 訓(xùn)練階段的典型報(bào)錯(cuò)與解法問(wèn)題現(xiàn)象原因分析解決方案訓(xùn)練開始后Loss一直是NaN學(xué)習(xí)率設(shè)置過(guò)高導(dǎo)致梯度爆炸調(diào)低初始學(xué)習(xí)率加上梯度裁剪驗(yàn)證階段沒(méi)有檢測(cè)框輸出導(dǎo)出或加載配置時(shí)類別數(shù)設(shè)置錯(cuò)誤檢查數(shù)據(jù)配置文件的類別數(shù)與模型頭維度一致小目標(biāo)類別mAP始終不過(guò)60輸入分辨率太低或缺少P2層提升輸入到640啟用P2檢測(cè)頭推理時(shí)輸出維度錯(cuò)亂ONNX導(dǎo)出時(shí)opset版本過(guò)低或動(dòng)態(tài)軸未正確設(shè)置使用opset 12以上配合Nchw輸入格式CPU推理速度遠(yuǎn)低于預(yù)期線程數(shù)配置不當(dāng)或模型長(zhǎng)時(shí)間沒(méi)有做算子融合手動(dòng)設(shè)置線程數(shù)使用OpenVINO執(zhí)行推理這些坑里面我最想強(qiáng)調(diào)的還是配置文件的類別數(shù)問(wèn)題。項(xiàng)目中途改過(guò)一次類別把5類變成6類但是訓(xùn)練腳本里有個(gè)舊緩存沒(méi)有清掉導(dǎo)致模型一直按5類來(lái)創(chuàng)建檢測(cè)頭訓(xùn)練出來(lái)的模型輸出維度不匹配部署時(shí)怎么都跑不通。清理緩存文件之后重新訓(xùn)練問(wèn)題立刻解決。6.2 數(shù)據(jù)不平衡導(dǎo)致的偏向問(wèn)題垃圾分類的數(shù)據(jù)天生是不平衡的塑料瓶太多紡織品太少。如果直接把原始數(shù)據(jù)丟給模型訓(xùn)練模型對(duì)紡織品的召回率會(huì)非常低因?yàn)樗谟?xùn)練過(guò)程中見(jiàn)到紡織品的次數(shù)太少了。我開始也經(jīng)歷過(guò)這個(gè)問(wèn)題驗(yàn)證集上塑料瓶的準(zhǔn)確率已經(jīng)到95%了紡織品只有68%。我采取的措施是通用的過(guò)采樣方案把紡織品樣本做復(fù)制和增強(qiáng)后再放入訓(xùn)練集同時(shí)降低了塑料瓶樣本的采樣權(quán)重。這樣一來(lái)模型不會(huì)對(duì)塑料瓶過(guò)度偏向整體的類別均衡性有所改善。需要提醒的是過(guò)采樣要適度同一樣本重復(fù)太多次會(huì)造成對(duì)特定圖像的過(guò)擬合。我的經(jīng)驗(yàn)是重復(fù)次數(shù)不要超過(guò)3次配合其他增強(qiáng)方式一起用效果更可控。6.3 部署環(huán)境的意外問(wèn)題在方案交付前我還在兩套不同配置的設(shè)備上做過(guò)遷移部署測(cè)試發(fā)現(xiàn)同一個(gè)ONNX文件在不同設(shè)備上的推理速度差異能達(dá)到3倍。原因不只是硬件算力不同還包括內(nèi)存帶寬和緩存大小的差異。這件事給我最大的教訓(xùn)是性能評(píng)估一定要在目標(biāo)硬件上做不要在開發(fā)機(jī)上跑完就給出結(jié)論。另外還有一個(gè)很細(xì)節(jié)的問(wèn)題攝像頭的自動(dòng)白平衡會(huì)影響輸入的色偏。回收箱里既有自然光又有燈光攝像頭會(huì)在不同色溫之間自動(dòng)調(diào)整導(dǎo)致同一種瓶子在不同時(shí)刻拍出來(lái)的顏色不一樣。處理方式是固定攝像頭的自動(dòng)參數(shù)同時(shí)保證曝光時(shí)間和增益不要自動(dòng)變化盡量讓輸入圖像的色彩穩(wěn)定。這雖然是一個(gè)圖像采集端的調(diào)整但對(duì)識(shí)別精度的影響非常大。7. 一些心得與后續(xù)改進(jìn)方向這個(gè)項(xiàng)目讓我最深刻的體會(huì)是用YOLOv10n這樣的輕量級(jí)模型加上P2檢測(cè)層來(lái)提升小目標(biāo)能力確實(shí)是一條很適合垃圾分類場(chǎng)景的技術(shù)路線。它兼顧了精度和速度讓部署到中低端設(shè)備成為可能同時(shí)YOLOv10端到端免NMS的特性又讓部署環(huán)節(jié)省了很多事情。如果后續(xù)要繼續(xù)迭代我第一個(gè)想做的事情是嘗試更精準(zhǔn)的類別粒度比如把現(xiàn)在的塑料瓶拆分成透明塑料瓶和不透明塑料瓶把紙類再分成瓦楞紙和辦公紙細(xì)分之后對(duì)下游的回收價(jià)值評(píng)估會(huì)更有意義。第二個(gè)方向是把檢測(cè)和分類解耦用一個(gè)檢測(cè)模型定位所有可疑垃圾區(qū)域再針對(duì)每個(gè)區(qū)域使用更高精度的分類模型來(lái)識(shí)別具體類別這樣可以把玻璃和塑料的混淆問(wèn)題再壓一壓。還有一個(gè)可以探索的方向是加入深度信息如果用雙攝或者深度傳感器輔助檢測(cè)瓶子的立體形狀會(huì)讓分類準(zhǔn)確率進(jìn)一步提升不過(guò)這個(gè)對(duì)硬件成本的影響也需要評(píng)估。