:YOLO小目標(biāo)檢測改進(jìn)與部署全流程解析)
接到“烏鴉識別”這個需求的時候我的第一反應(yīng)是這還不簡單套個YOLO系目標(biāo)檢測模型標(biāo)個幾千張圖訓(xùn)練一下不就出來了等項目真正推進(jìn)下去才意識到烏鴉可能是所有目標(biāo)檢測對象里極麻煩的一類。這個項目最終被命名為YOLOv26——注意官方并沒有發(fā)布到v26這是我們內(nèi)部第6代改進(jìn)分支的代號在開源的YOLO系檢測框架上針對烏鴉小目標(biāo)、低對比度、群鳥密集這三個老大難問題做了定向改造從數(shù)據(jù)、訓(xùn)練、評估一直做到真實場景部署。這一整套方案我認(rèn)為對做野生動物監(jiān)測、無人機(jī)巡檢、鳥類計數(shù)這些方向的朋友都有直接的參考價值。烏鴉識別這個場景有多現(xiàn)實的需求機(jī)場驅(qū)鳥、農(nóng)田鳥害監(jiān)測、城市烏鴉種群數(shù)量調(diào)查、垃圾處理場周邊烏鴉聚集預(yù)警都需要實時數(shù)清楚“有多少烏鴉、在哪里、在往哪飛”。但這些場景里烏鴉通常不是配合你擺拍的大鳥而是遠(yuǎn)處一個小黑點。目標(biāo)小、顏色深、背景雜、運動快普通檢測器很容易漏檢或者把黑色塑料袋、陰影也一起框進(jìn)來。這篇文章想把整個改進(jìn)思路、數(shù)據(jù)打磨過程、訓(xùn)練調(diào)參經(jīng)歷、部署踩的坑都攤開來講希望能讓正在做類似目標(biāo)檢測任務(wù)的人少走幾個月的彎路。1. 項目背景與需求拆解1.1 為什么通用的目標(biāo)檢測模型搞不定烏鴉先聊一個核心認(rèn)知烏鴉識別并不是“隨便找個檢測器訓(xùn)練一下就能用”的簡單任務(wù)。很多人第一次上手會拿現(xiàn)成的通用預(yù)訓(xùn)練模型試結(jié)果基本是兩種要么漏檢嚴(yán)重要么誤檢一片。原因有三點。第一目標(biāo)尺寸太小。監(jiān)控攝像頭或者無人機(jī)掛載設(shè)備拍到的烏鴉往往只有十幾個到幾十個像素。通用的檢測器設(shè)計時主要針對常規(guī)尺寸目標(biāo)高層特征圖的感受野很大小目標(biāo)經(jīng)過多次降采樣后幾乎沒有有效信息殘留自然檢測不到。第二對比度極端不足。烏鴉通體黑色在深色地面、柏油路面、樹蔭、陰影里它和背景的灰度差極小。算法想要靠顏色紋理來區(qū)分基本無從下手。它不像汽車有明確的邊緣和車燈也不像行人有人體結(jié)構(gòu)比例很多時候模型只能靠輪廓的細(xì)微變化來猜。第三行為模式帶來的密集遮擋。烏鴉經(jīng)常成群結(jié)隊飛行翅膀展開互相交錯目標(biāo)之間出現(xiàn)大量重疊。NMS非極大值抑制設(shè)得稍微激進(jìn)一點就會把緊挨著的兩只鳥合并成一只設(shè)得松一點同一個目標(biāo)又可能被重復(fù)框出來。這些細(xì)節(jié)在通用目標(biāo)檢測里也有但烏鴉場景里特別極端。所以把這個問題拆開來看它本質(zhì)上是一個“小目標(biāo)檢測 低對比度目標(biāo)識別 密集目標(biāo)計數(shù)”的綜合問題而不是一個簡單的分類問題。1.2 項目目標(biāo)與邊界定義項目啟動前我先把自己想要的結(jié)果邊界劃清楚不然很容易在無限調(diào)參里陷進(jìn)去。這個項目的目標(biāo)是給定監(jiān)控畫面或無人機(jī)拍攝的連續(xù)幀能實時框選出畫面中的烏鴉個體并輸出每只烏鴉的置信度供后續(xù)數(shù)量統(tǒng)計、軌跡跟蹤和告警聯(lián)動使用。要求白天、黃昏兩個時段下在100米以內(nèi)的觀測距離檢測召回率達(dá)到可實用水平群鳥密集時能區(qū)分相鄰個體整套算法能在邊緣設(shè)備上運行推理速度不低于每秒15幀。不做什么也提前說清楚。不做烏鴉的個體身份識別不做雌雄分類不區(qū)分小嘴烏鴉還是大嘴烏鴉也不做夜間紅外圖像的識別——夜間紅外模式一開始就排除在項目范圍外因為那個模式下烏鴉和背景幾乎全是灰度噪聲投入產(chǎn)出比太低。邊界定了之后后面所有數(shù)據(jù)采集、算法選型、評估指標(biāo)都有了錨點。2. 算法選型與改進(jìn)思路2.1 “YOLOv26”代號背后的技術(shù)基線先解釋一下標(biāo)題里的“YOLOv26”。在寫這篇文章的時間點上YOLO系列開源主線還沒有走到v26這個版本號。“26”是我們項目內(nèi)部的代號項目在某個YOLO系開源框架上做改進(jìn)前后迭代了六版第六版就是最終定型用于交付的版本團(tuán)隊內(nèi)部順口就叫YOLOv26。所以你不要把這個當(dāng)作官方發(fā)布的新版本它就是一個“針對特定場景深度改造過的YOLO系檢測器”。如果你在自己的項目里做類似的事完全可以把你的版本叫成任何你喜歡的代號。選型時我對比了幾個主流檢測方案。當(dāng)時主要看三類一階段檢測器、二階段檢測器、Transformer類檢測器。二階段檢測器精度上限高但速度很難滿足實時監(jiān)控場景Transformer類方法在密集目標(biāo)上表現(xiàn)好但對訓(xùn)練數(shù)據(jù)量和部署環(huán)境的要求偏重邊緣設(shè)備上跑起來吃力。YOLO系作為一階段檢測器的代表實時性好工程生態(tài)成熟前后處理工具鏈完整更適合這種需要快速落地的項目。這次改進(jìn)的基線不是官方原版權(quán)重而是社區(qū)維護(hù)的一個改進(jìn)分支主干網(wǎng)絡(luò)使用了重參數(shù)化和注意力融合的變體在精度和速度之間平衡不錯。我在這條基線上繼續(xù)做場景化改造。2.2 三大改進(jìn)策略與設(shè)計理由我針對烏鴉識別的痛點做了三處核心改進(jìn)每一處的理由都來自上一節(jié)分析的問題。第一處增加高分辨率小目標(biāo)檢測層。原版檢測器通常使用8倍、16倍、32倍降采樣特征圖來檢測大中小目標(biāo)。32倍降采樣層負(fù)責(zé)大目標(biāo)8倍負(fù)責(zé)中等目標(biāo)但對畫面里只有20像素左右的小目標(biāo)來說8倍降采樣之后的特征圖上它只占約2到3個像素已經(jīng)很難提供足夠的形狀信息。我在原結(jié)構(gòu)的P3層基礎(chǔ)上額外引入了一個4倍降采樣檢測分支專門負(fù)責(zé)小目標(biāo)。代價是計算量增加了大約18%訓(xùn)練和推理時間都變長了一些但小目標(biāo)召回率提升了十幾個百分點這筆賬很劃算。第二處引入輕量注意力模塊。烏鴉檢測最難受的是低對比度問題。我在主干網(wǎng)絡(luò)的三層輸出后面各接了一個輕量的注意力模塊同時關(guān)注通道維度和空間維度。通道注意力能告訴網(wǎng)絡(luò)“當(dāng)前這個區(qū)域的顏色均值偏低但紋理形態(tài)符合鳥類特征”空間注意力則把響應(yīng)集中到翅膀尖端、嘴部、尾羽這些判別性強(qiáng)的局部區(qū)域。這個模塊的設(shè)計原則是輕量整體新增參數(shù)約0.2M對推理速度影響幾乎可以忽略但能明顯壓低黑色物體誤檢。第三處修改損失函數(shù)對小目標(biāo)更友好。烏鴉檢測的標(biāo)簽框很多是小尺寸框常規(guī)IoU損失對小框的位置偏差懲罰不夠精細(xì)小框幾個像素的偏移就會導(dǎo)致IoU劇烈變化。我換成了帶動態(tài)聚焦機(jī)制的IoU變體損失讓小目標(biāo)樣本在梯度計算里獲得更高權(quán)重。實際效果是mAP50提升了兩到三個點小目標(biāo)尺度的精度提升尤其明顯。2.3 改進(jìn)方案中的取舍有提升就有代價這個項目里我做了幾個明確的取舍。第一個取舍是輸入分辨率。為了保住小目標(biāo)我把訓(xùn)練和推理的輸入分辨率定在960乘960而不是常用的640。分辨率越大小目標(biāo)在特征圖上的像素越多但顯存占用和推理耗時同步上漲。邊緣設(shè)備上跑640只能到25幀跑960就只有14到16幀勉強(qiáng)夠用。實際部署時我做了按區(qū)域裁剪的動態(tài)方案后文細(xì)說。第二個取舍是數(shù)據(jù)增強(qiáng)強(qiáng)度。Mosaic增強(qiáng)能大幅提升模型對復(fù)雜背景的魯棒性但對小目標(biāo)來說過度的隨機(jī)縮放會把烏鴉縮到連人眼都看不清的程度反而教壞模型。最后我把Mosaic的開啟策略改成前80輪開啟、后70輪關(guān)閉訓(xùn)練后期模型可以專注學(xué)習(xí)精細(xì)特征。第三個取舍是負(fù)樣本數(shù)量。通常目標(biāo)檢測模型只標(biāo)注正樣本目標(biāo)就行但烏鴉誤檢問題嚴(yán)重我在訓(xùn)練集里刻意加入了1200多張完全沒有烏鴉的負(fù)樣本圖包括陰影、黑色輪胎、黑色塑料袋、深色石塊、卷簾門等容易誤報的物體。代價是訓(xùn)練集變大、epoch時間變長但對壓低誤檢率效果非常明顯。3. 數(shù)據(jù)集構(gòu)建與標(biāo)注質(zhì)控3.1 數(shù)據(jù)來源與場景規(guī)劃模型效果的上限由數(shù)據(jù)質(zhì)量決定這句話在烏鴉識別項目里體現(xiàn)得淋漓盡致。數(shù)據(jù)來源分兩部分。一部分是自采我們在三個典型場景部署了采集設(shè)備機(jī)場周邊固定機(jī)位、農(nóng)田邊緣低空無人機(jī)視角、城市公園固定攝像頭視角。每個場景覆蓋不同時間、不同天氣、不同拍攝角度。另一部分是從公開鳥類圖庫里篩選出的烏鴉圖片做補(bǔ)充主要擴(kuò)充姿態(tài)多樣性。最終整理出可用于訓(xùn)練的約6500張正樣本圖標(biāo)注了約8900個烏鴉實例另有1200張負(fù)樣本圖。場景規(guī)劃階段要特別強(qiáng)調(diào)多樣性。我見過有的項目大量使用網(wǎng)上圖片訓(xùn)練結(jié)果現(xiàn)場部署時換一個角度就失靈。烏鴉的姿態(tài)差異很大站立、飛行、俯沖、集群盤旋、在樹枝間短暫停留都需要對應(yīng)的訓(xùn)練樣本。我在數(shù)據(jù)采集階段刻意把這些狀態(tài)分開統(tǒng)計確保每個狀態(tài)都有足夠的樣本量。無人機(jī)視角的數(shù)據(jù)也很有講究。無人機(jī)拍攝高度變化導(dǎo)致目標(biāo)尺度變化劇烈低空飛行時烏鴉可能占100像素以上高空巡航時只有10像素左右。這類數(shù)據(jù)容易暴露模型對尺度變化的敏感性訓(xùn)練時建議單獨增廣甚至放進(jìn)單獨的batch里。3.2 標(biāo)注規(guī)范與質(zhì)量糾錯標(biāo)圖這個環(huán)節(jié)看著簡單實際特別影響后面的模型表現(xiàn)。我第一批數(shù)據(jù)是自己標(biāo)注的標(biāo)到300張就開始懷疑人生——烏鴉翅膀展開時邊緣模糊喙和尾羽分界不清不同標(biāo)注人員對“這個算不算一只烏鴉”的標(biāo)準(zhǔn)很難統(tǒng)一。我定了一版標(biāo)注規(guī)范直接貼在這里你可以直接抄走完整可見的烏鴉個體用緊密貼合身體輪廓的矩形框被遮擋超過50%的不標(biāo)遠(yuǎn)處模糊到無法判斷是不是烏鴉的不標(biāo)翅膀展開時矩形框必須包含全部翼展站立時矩形框必須包含頭部和尾羽。集群飛行時哪怕兩只烏鴉緊挨著也要分別標(biāo)注不允許合并框。標(biāo)注完必須做交叉檢查。我讓標(biāo)注員分成兩組互相抽檢對方20%的標(biāo)注結(jié)果IoU低于0.7的標(biāo)注框視為不合格打回重標(biāo)。這個流程看起來費時間實際上能省掉后面大量因為標(biāo)注噪聲導(dǎo)致的模型調(diào)試時間。檢查還發(fā)現(xiàn)過一個高頻問題標(biāo)注框習(xí)慣性偏小沒有完全包含尾巴或翅膀尖這會直接拉低邊界框回歸精度。3.3 數(shù)據(jù)增強(qiáng)與負(fù)樣本補(bǔ)充數(shù)據(jù)增強(qiáng)部分我除了使用常規(guī)的Mosaic、隨機(jī)透視、HSV擾動之外重點用了Copy-Paste增強(qiáng)把標(biāo)注好的烏鴉摳出來隨機(jī)貼到?jīng)]有烏鴉的純背景圖上同時保留它的標(biāo)簽框。這種做法對小目標(biāo)檢測特別有效等于無中生有地擴(kuò)充了大量“烏鴉在不同背景下”的樣本。這里有一個容易踩的坑。Copy-Paste時如果只貼鳥、不做光照和角度調(diào)整模型會學(xué)到“背景邊緣有奇怪黑塊”這種錯誤模式。我處理的原則是粘貼位置避開其他物體的中央粘貼后對鳥塊做小幅旋轉(zhuǎn)和亮度擾動讓它的邊緣過渡和背景融合得自然一點。負(fù)樣本策略不多說只提一個關(guān)鍵點收集負(fù)樣本的時候要記錄具體是哪種物體被誤檢了。剛開始我發(fā)現(xiàn)誤檢對象集中在黑色易拉罐、黑色垃圾袋、黑白相間的球體上就定向補(bǔ)充了這些物體的負(fù)樣本。這個循環(huán)做兩三輪之后誤檢率顯著下降。4. 訓(xùn)練工程實現(xiàn)4.1 運行環(huán)境與工程結(jié)構(gòu)訓(xùn)練環(huán)境用的是單張24G顯存的消費級顯卡深度學(xué)習(xí)框架采用開源生態(tài)依賴庫按常規(guī)版本組合。整個工程結(jié)構(gòu)我分成了幾個獨立模塊數(shù)據(jù)加載與增廣模塊、模型定義模塊、訓(xùn)練器模塊、評估模塊、導(dǎo)出模塊。數(shù)據(jù)加載部分尤其值得用獨立模塊來寫因為后續(xù)換數(shù)據(jù)集、調(diào)增廣策略都只改這個文件不用動模型代碼。代碼組織建議遵循一個簡單的約定數(shù)據(jù)配置、模型配置、訓(xùn)練配置分離。尤其是訓(xùn)練配置我直接用一個YAML文件管理方便記錄每次實驗的參數(shù)組合。項目里同一個模型實驗跑了十幾個版本如果沒有配置管理你根本不知道上一次最佳結(jié)果用的什么參數(shù)。# 訓(xùn)練配置示例 img_size: 960 batch_size: 16 epochs: 150 workers: 8 optimizer: lr0: 0.01 lrf: 0.01 momentum: 0.937 weight_decay: 0.0005 loss: box: 7.5 cls: 0.5 dfl: 1.5 augment: mosaic: 1.0 # 前80輪開啟后70輪關(guān)閉 copy_paste: 0.5 flipud: 0.0 fliplr: 0.5 hsv_h: 0.015 hsv_s: 0.7 hsv_v: 0.54.2 訓(xùn)練超參與策略訓(xùn)練參數(shù)這里直接說結(jié)論。輸入分辨率960乘960batch size 16訓(xùn)練150個epoch。學(xué)習(xí)率初始0.01使用余弦退火衰減到0.0001前5個epoch用warmup預(yù)熱。優(yōu)化器用帶動量的SGD動量0.937權(quán)重衰減0.0005。為什么不直接用Adam在目標(biāo)檢測任務(wù)里SGD加合適的學(xué)習(xí)率調(diào)度通常收斂更穩(wěn)尤其在小目標(biāo)檢測場景Adam容易在訓(xùn)練后期陷入震蕩驗證集mAP的波動更明顯。這個經(jīng)驗不是絕對的但在我這個項目里對比過幾次SGD表現(xiàn)更穩(wěn)定。batch size的選擇要匹配顯存。我測試過32的batch顯存快滿了而且小目標(biāo)樣本占比高的數(shù)據(jù)里大batch反而可能導(dǎo)致某些包含小目標(biāo)的樣本在batch內(nèi)占比過低梯度被稀釋。16這個值在速度和精度上比較均衡。訓(xùn)練過程中我對增廣策略做了分階段調(diào)整前80輪開Mosaic和Copy-Paste后70輪關(guān)閉Mosaic只保留輕度顏色擾動。原因是訓(xùn)練后期模型需要收斂到精細(xì)的特征模式這時候過強(qiáng)的幾何增廣會干擾學(xué)習(xí)。4.3 訓(xùn)練曲線怎么看很多人看訓(xùn)練曲線只看loss數(shù)值降到多少這容易誤判。我的習(xí)慣是同時看三樣?xùn)|西訓(xùn)練loss、驗證集mAP50曲線、以及一個固定視頻片段上的實測效果。訓(xùn)練loss降到正常收斂區(qū)間不代表模型能用了。我見過loss曲線很漂亮但測試集上漏檢一堆的情況。比較有用的信號是驗證集mAP曲線mAP50持續(xù)上升說明模型還在學(xué)習(xí)mAP50:95和mAP50差距越來越大說明模型對大目標(biāo)學(xué)得比小目標(biāo)好這時應(yīng)該回頭檢查小目標(biāo)檢測層有沒有起作用驗證loss開始回升而訓(xùn)練loss繼續(xù)下降是過擬合的明確信號。我在這個項目里還堅持做一件事每隔20個epoch保存一次權(quán)重然后在同一段包含群鳥密集畫面的視頻上跑一眼。比看任何指標(biāo)都直觀能當(dāng)場發(fā)現(xiàn)“這個版本怎么把遠(yuǎn)處的啄木鳥也框進(jìn)去了”這種指標(biāo)看不出來的異常。5. 評估結(jié)果與指標(biāo)解讀5.1 測試集設(shè)計與指標(biāo)口徑評估環(huán)節(jié)最容易自欺欺人。如果你的測試集和訓(xùn)練集高度相似再差的模型也能刷出高分。我在項目里單獨制作了一個更貼近真實部署的測試集包含500張圖像覆蓋四個維度白天固定機(jī)位、黃昏固定機(jī)位、無人機(jī)低空俯視、無人機(jī)高空巡航。每張圖我都人工數(shù)過烏鴉數(shù)量確保標(biāo)簽完整。指標(biāo)上我同時看了mAP50、mAP50:95、精確率、召回率、F1和推理幀率。mAP50反映的是“檢測器找目標(biāo)的大致能力”mAP50:95這個指標(biāo)對框的質(zhì)量要求更高也更貼近落地場景的實際體驗。特別提醒一點類別只有烏鴉一個類的項目里mAP等于這個單類的AP沒有類別間平均的問題指標(biāo)數(shù)值很直接。不要被“mAP”這個名詞嚇到本質(zhì)上就是看你畫的框和人工標(biāo)注的框有多重合。5.2 改進(jìn)前后的量化對比基線模型用的是同一條技術(shù)框架下的默認(rèn)版本未加小目標(biāo)分支和注意力模塊。我們在一臺相同測試設(shè)備上跑同一套測試集結(jié)果如下模型版本mAP50mAP50:95召回率精確率參數(shù)量單幀耗時基線檢測器76.8%34.6%72.1%79.5%51.3M12msYOLOv26改進(jìn)版83.5%42.7%79.3%85.1%55.4M15ms數(shù)字看起來不算夸張但在實際場景里的體驗差異很明顯。基線版本在無人機(jī)高空畫面中幾乎無法框出10像素以下的烏鴉要么漏檢要么框出半只鳥改進(jìn)版雖然也會有漏檢但至少能穩(wěn)定框出大多數(shù)清晰可見的個體群鳥畫面里不再把相鄰個體合并成一只。代價是推理時間增加了25%但在邊緣設(shè)備上仍然可以滿足實時要求。我就接受了這筆開銷。5.3 可視化案例與效果分析評估的時候不要只看匯總數(shù)字我會至少挑三張典型圖仔細(xì)看。第一張是無人機(jī)高空拍攝的群鳥圖。這張圖里烏鴉平均尺寸只有15像素左右背景是紋理復(fù)雜的林地和農(nóng)田。改進(jìn)版能框出圖中7成的烏鴉基線只能框出3成。仔細(xì)觀察會發(fā)現(xiàn)改進(jìn)版的框更傾向于框住鳥的“上半身”也就是翅膀和頭部區(qū)域說明注意力模塊確實讓模型學(xué)會了關(guān)注更關(guān)鍵的特征部位。第二張是黃昏逆光場景烏鴉在空中幾乎成了剪影。這里模型表現(xiàn)會下降mAP50從白天的83掉到70左右屬于預(yù)期內(nèi)。逆光條件下有些烏鴉和背景的對比度已經(jīng)低到人眼都難識別對模型的期望值本來就不該拉滿。第三張是城市公園地面場景有幾只烏鴉在草地上走動背景里有黑色垃圾桶、深色石塊。改進(jìn)版沒有把它們誤檢成烏鴉但偶爾會漏檢被樹葉遮擋大半的個體。這類問題屬于遮擋困境后續(xù)可以結(jié)合視頻時序信息來解決。6. 部署落地6.1 面向兩種場景的部署方案這個項目實際部署在兩個場景里技術(shù)方案并不相同。固定監(jiān)控場景用的是局域網(wǎng)內(nèi)的網(wǎng)絡(luò)攝像頭視頻流通過RTSP協(xié)議拉取。我在一臺邊緣設(shè)備上跑了一個常駐推理進(jìn)程每秒抽兩幀送入模型輸出檢測結(jié)果然后做ROI區(qū)域過濾和數(shù)量統(tǒng)計。這個方案對硬件要求不高模型推理占用不到40%的CPUGPU剩余算力可以同時跑其他任務(wù)。無人機(jī)場景更麻煩。無人機(jī)上運行的是機(jī)載設(shè)備算力受限而且飛行時抖動、光照變化劇烈。我這里沒有直接在機(jī)載端跑全分辨率推理而是先做解碼縮放把1080P輸入縮到960乘960再做檢測。只有檢測到烏鴉目標(biāo)的幀才會觸發(fā)后續(xù)的ROI放大分析。通過這個分級策略整體處理速度從每秒8幀提升到了每秒15幀以上。6.2 推理流程與后處理參數(shù)部署時的推理流程和訓(xùn)練時不一樣需要單獨工程化。我整理成了一條標(biāo)準(zhǔn)流水線視頻解碼、幀縮放、歸一化、模型推理、置信度過濾、NMS去重、ROI過濾、計數(shù)輸出。置信度閾值的選擇不要拍腦袋。我在驗證集上做了閾值掃描發(fā)現(xiàn)閾值設(shè)在0.35時精確率和召回率的平衡點最好。設(shè)得低于0.25誤檢會明顯增多設(shè)得高于0.5漏檢率激增。這個值會隨數(shù)據(jù)分布變化建議你自己也做一次掃描不要直接照抄別人項目的數(shù)值。NMS閾值也需要單獨調(diào)。常規(guī)目標(biāo)檢測里NMS IoU閾值用0.45沒問題但群鳥密集場景下兩只緊挨著的烏鴉的預(yù)測框IoU可能超過0.45導(dǎo)致其中一只被錯誤抑制。我把密集場景的NMS閾值調(diào)到0.3代價是偶爾會出現(xiàn)同一只烏鴉被框兩次但這種錯誤可以在后處理里通過框中心距離合并來二次消除。6.3 部署時最隱蔽的坑部署過程中我踩過幾個不太好察覺的坑值得單獨拿出來說。第一個是輸入分辨率變化導(dǎo)致的小目標(biāo)丟失。模型訓(xùn)練時用960分辨率部署時如果為了提速改成640小目標(biāo)檢測層的感受野和特征分布完全對不上表現(xiàn)會斷崖式下降。如果你必須在低分辨率下推理請把訓(xùn)練時的分辨率也降下來重新訓(xùn)練而不是直接改推理參數(shù)。第二個是模型導(dǎo)出后的精度損失。浮點模型導(dǎo)出成加速格式時有些算子會降低計算精度小目標(biāo)分支特別敏感。我在導(dǎo)出后對比過驗證集精度發(fā)現(xiàn)mAP50下降了1.8個百分點。后來通過逐層分析定位到是注意力模塊里的歸一化層被融合后精度損失比較大需要手動保留高精度計算。第三個是圖像色調(diào)格式不一致。訓(xùn)練時用的是標(biāo)準(zhǔn)RGB輸入但部分?jǐn)z像頭輸出的是BGR順序。這個錯誤很隱蔽畫面顏色看起來只是稍微偏藍(lán)模型輸出卻會明顯變差。務(wù)必在部署代碼里確認(rèn)顏色通道順序這種低級錯誤一旦發(fā)生會浪費好幾個小時排查。7. 常見問題與排查速查表7.1 訓(xùn)練階段的典型問題現(xiàn)象可能原因排查與解決訓(xùn)練loss不降一直在高位震蕩學(xué)習(xí)率過大 / 數(shù)據(jù)標(biāo)注錯誤率過高 / 正負(fù)樣本失衡先降低學(xué)習(xí)率到原來的1/10試一輪抽查200張標(biāo)注框是否貼合目標(biāo)統(tǒng)計正負(fù)樣本比例負(fù)樣本過多時需要降權(quán)l(xiāng)oss下降很快但驗證集mAP不漲過擬合信號 / 增廣過強(qiáng) / 訓(xùn)練集分布和驗證集差異大關(guān)閉強(qiáng)增廣重訓(xùn)檢查驗證集是否包含訓(xùn)練集相近分布排除數(shù)據(jù)泄漏小目標(biāo)召回率極低輸入分辨率太小 / 小目標(biāo)分支未生效確認(rèn)模型里4倍降采樣檢測層是否真的接入了損失計算把輸入分辨率提升到訓(xùn)練值單獨統(tǒng)計40像素以下目標(biāo)的AP訓(xùn)練后期驗證集mAP震蕩學(xué)習(xí)率衰減過慢 / batch內(nèi)小目標(biāo)比例不穩(wěn)定腰斬學(xué)習(xí)率重訓(xùn)或者增大batch size讓梯度更穩(wěn)定7.2 檢測效果的典型問題現(xiàn)象可能原因排查與解決誤檢黑色陰影、輪胎、塑料袋訓(xùn)練集缺少對應(yīng)負(fù)樣本 / 注意力模塊沒有發(fā)揮作用收集這類誤檢物體做負(fù)樣本補(bǔ)訓(xùn)可視化注意力熱力圖確認(rèn)模型關(guān)注的區(qū)域是否集中到翅膀和頭尾群鳥密集時計數(shù)偏少NMS閾值過低/過高 / 模型對遮擋目標(biāo)不敏感先調(diào)低NMS閾值0.3左右如果還不行考慮用檢測加跟蹤的方式利用時序信息遠(yuǎn)處小目標(biāo)時有時無置信度閾值太高 / 輸入分辨率沒有對齊訓(xùn)練值做置信度閾值掃描確認(rèn)部署端預(yù)處理縮放邏輯和訓(xùn)練時一致模型把黑色鳥類和棕色鳥類混在一起數(shù)據(jù)里顏色多樣性不足檢查訓(xùn)練集分布補(bǔ)充不同羽色樣本如果有其他鳥類出現(xiàn)需要增加類別或設(shè)計負(fù)樣本7.3 部署環(huán)境的疑難雜癥現(xiàn)象可能原因排查與解決攝像頭畫面檢測效果差但測試集效果好現(xiàn)場畫質(zhì)/視角/光照與訓(xùn)練數(shù)據(jù)差異大采集現(xiàn)場數(shù)據(jù)微調(diào)模型這是最簡單也最有效的方法CPU推理特別慢模型沒有用對應(yīng)框架的加速接口 / 輸入圖沒有做預(yù)處理批量化檢查推理前處理是否拷貝了過多內(nèi)存利用進(jìn)程內(nèi)batch把多路視頻幀合并推理部署一段時間后誤檢增多場景環(huán)境變化出現(xiàn)了新的干擾物定期收集誤檢樣本做增量訓(xùn)練在前端加ROI或者規(guī)則過濾8. 踩坑復(fù)盤與后續(xù)擴(kuò)展空間8.1 幾點可能有點反常識的體會這個項目做下來讓我最意外的是模型結(jié)構(gòu)改進(jìn)帶來的收益遠(yuǎn)不如數(shù)據(jù)治理帶來的收益大。整個項目周期里效果提升最明顯的兩個節(jié)點一個是加入Copy-Paste增強(qiáng)和負(fù)樣本補(bǔ)充之后誤檢率大幅下降另一個是修復(fù)標(biāo)注框偏小的問題之后mAP50直接漲了三個點。相比之下增加小目標(biāo)檢測層雖然也有用但提升幅度并沒那么夸張。所以我現(xiàn)在看到有人一上來就討論換哪種骨干網(wǎng)絡(luò)、加哪種注意力模塊、用什么損失函數(shù)心里會默認(rèn)先問一句你的標(biāo)簽質(zhì)量檢查過了嗎你的測試集能反映真實場景嗎你的負(fù)樣本夠嗎這些問題不解決再先進(jìn)的模型結(jié)構(gòu)都是在腐蝕的地基上蓋樓。第二個體會是場景化的算法改進(jìn)一定要有具體的“反例”驅(qū)動。我每次想加一個改進(jìn)模塊之前都會先找出現(xiàn)有模型在哪些畫面上表現(xiàn)特別差把這些問題圖貼在白板上反推模型缺什么能力。比如發(fā)現(xiàn)逆光場景漏檢嚴(yán)重就去補(bǔ)逆光數(shù)據(jù)發(fā)現(xiàn)黑色陰影誤檢就去看注意力模塊的響應(yīng)圖。沒有真實場景反例驅(qū)動的改進(jìn)大概率是自我感動。8.2 后續(xù)值得繼續(xù)做的方向這個項目停在了“能實用”的程度后面可擴(kuò)展的空間其實還很大。一個方向是在檢測基礎(chǔ)上加跟蹤模塊。視頻流里烏鴉的運動是連續(xù)的如果接入輕量級的目標(biāo)跟蹤算法不僅能利用時序信息修正單幀漏檢還能直接輸出每只烏鴉的運動軌跡對機(jī)場驅(qū)鳥和城市種群的飛行動線分析都很有價值。另一個方向是模型壓縮和剪枝?,F(xiàn)在的55.4M參數(shù)在邊緣設(shè)備上跑15幀雖然夠用但不夠?qū)捲?。后續(xù)可以嘗試對注意力模塊做結(jié)構(gòu)化剪枝把小目標(biāo)檢測分支的通道數(shù)壓縮目標(biāo)是把單幀耗時再降到10毫秒以內(nèi)。還有一個我比較感興趣的方向是做多目標(biāo)監(jiān)測系統(tǒng)。烏鴉識別只是其中一個類別如果換成“烏鴉喜鵲鴿子無人機(jī)”多類別檢測技術(shù)上完全同構(gòu)只需要擴(kuò)充數(shù)據(jù)集和標(biāo)簽體系就能從一個垂直項目變成一個通用平臺。最后分享一個項目收尾時的小技巧部署上線前留下一個持續(xù)收集現(xiàn)場誤檢樣本的機(jī)制。把這個機(jī)制放進(jìn)系統(tǒng)里每周抽一次反饋數(shù)據(jù)定期補(bǔ)進(jìn)訓(xùn)練集模型才能跟著場景一起演化而不是上線那天就是它能力的最高點。