戰(zhàn):從數(shù)據(jù)標(biāo)注到邊緣部署全流程)
“跌倒檢測”這四個(gè)字翻譯成兩種完全不同的語言。在普通人眼里它是關(guān)懷與風(fēng)險(xiǎn)是家里老人摔倒時(shí)的驚慌在機(jī)器視覺工程師眼里它是框、是類別、是置信度、是每秒多少幀的推理結(jié)果。YOLOv8 順手把這兩套語言縫合到一起主干網(wǎng)絡(luò)負(fù)責(zé)提特征檢測頭把特征轉(zhuǎn)成“人跌倒”這個(gè)結(jié)論。這篇實(shí)戰(zhàn)記錄覆蓋了從我拿到需求到模型上線部署的全過程數(shù)據(jù)標(biāo)注、模型訓(xùn)練、導(dǎo)出部署、真實(shí)場景接入。前前后后滿打滿算調(diào)了兩個(gè)多月項(xiàng)目本身并不復(fù)雜但坑全埋在細(xì)節(jié)里其中部署和誤報(bào)處理保守估計(jì)吃掉了八成的時(shí)間。適合正在做監(jiān)控場景檢測、或者想給老人的居住空間加一道“自動(dòng)預(yù)警”的開發(fā)者當(dāng)作一份可以直接抄作業(yè)的流程參考。1. 整體設(shè)計(jì)復(fù)盤從場景需求到技術(shù)選型1.1 機(jī)器眼里的“跌倒”到底長什么樣先把“跌倒”這件事在計(jì)算機(jī)視覺里的樣子說清楚。二維圖像里的跌倒本質(zhì)是“人的姿態(tài)出現(xiàn)異?!弊畛R姷漠嬅嫣卣魇侨梭w沿著地面的橫向分布人體框的寬明顯大于高或者人體區(qū)域整體呈現(xiàn)斜躺、蜷縮的形態(tài)同時(shí)相對靜止或只存在輕微移動(dòng)。簡單說模型學(xué)的不是一個(gè)物理動(dòng)作而是一組由“目標(biāo)框?qū)捀弑茸兓薄澳繕?biāo)輪廓分布”和“幀間位置變化”共同決定的圖像模式。這個(gè)定義在立項(xiàng)時(shí)非常重要因?yàn)樗苯記Q定了我們用檢測模型而不是姿態(tài)模型。跌倒瞬間動(dòng)作很快但從幀畫面看跌倒后的靜止姿態(tài)才是最容易穩(wěn)定捕捉的信號(hào)。檢測模型天然就是“找目標(biāo)、給邊界框”只要框能將跌倒后的躺倒姿態(tài)框得足夠穩(wěn)后臺(tái)上位機(jī)再配合連續(xù)幾幀的框位置變化就能很好地完成“跌倒判定 告警觸發(fā)”這件業(yè)務(wù)任務(wù)。另一方面真實(shí)場景的物聯(lián)網(wǎng)監(jiān)控是常亮的攝像頭視角多為斜俯視或平視畫面里人的尺度會(huì)變化、光照會(huì)變、遮擋會(huì)出現(xiàn)。這些都對模型的泛化能力提出了比實(shí)驗(yàn)室測試高得多的要求所以整個(gè)項(xiàng)目我刻意把“場景復(fù)雜”當(dāng)成第一設(shè)計(jì)約束寧可犧牲一點(diǎn)實(shí)驗(yàn)室精度也要保證現(xiàn)場環(huán)境的穩(wěn)定性。1.2 模型選型為什么用 YOLOv8而不是姿態(tài)估計(jì)或傳統(tǒng)視覺先說結(jié)論YOLOv8在“跌倒檢測”這件事上是一種權(quán)衡之后更偏向工程落地的選擇。項(xiàng)目初期我也認(rèn)真評(píng)估過另兩條技術(shù)路線。第一條是人體姿態(tài)估計(jì)例如基于關(guān)鍵點(diǎn)的方案。姿態(tài)估計(jì)能給出更精細(xì)的“人是否倒地”判斷通過計(jì)算肩膀和髖關(guān)節(jié)連線與地面的夾角來判斷倒地狀態(tài)。這條路線識(shí)別姿態(tài)確實(shí)更優(yōu)雅但問題是實(shí)時(shí)性開銷大一張圖上要同時(shí)跑目標(biāo)檢測和關(guān)鍵點(diǎn)回歸對邊緣設(shè)備的算力壓力陡增數(shù)據(jù)標(biāo)注成本也高需要給每個(gè)人逐幀標(biāo)注十幾個(gè)關(guān)鍵點(diǎn)最關(guān)鍵的是在相機(jī)斜俯視場景里部分關(guān)鍵點(diǎn)被遮擋的概率非常高一旦腳部或肩部關(guān)鍵點(diǎn)丟失角度計(jì)算立刻不可靠誤報(bào)反而會(huì)增多。第二條是傳統(tǒng)視覺方案比如背景建模配合輪廓分析。這類方案在光線固定、背景純凈的小范圍實(shí)驗(yàn)里表現(xiàn)尚可但在養(yǎng)老機(jī)構(gòu)或家庭環(huán)境下幾乎不可用。窗簾飄動(dòng)、光線漸變、寵物移動(dòng)都會(huì)觸發(fā)前景分割錯(cuò)誤誤報(bào)率高到完全沒有實(shí)用價(jià)值。下面這張表是我當(dāng)初做選型時(shí)整理的按工程落地角度來評(píng)分技術(shù)路線實(shí)時(shí)性標(biāo)注成本部署難度復(fù)雜場景魯棒性誤報(bào)率傳統(tǒng)背景差分高低低很差高姿態(tài)估計(jì)中高中高受遮擋影響大中YOLOv8檢測高中低較好控制后較低其實(shí)單看處理單幀圖像姿態(tài)估計(jì)也沒慢到不能用真正的問題出在工程鏈路上姿態(tài)估計(jì)后續(xù)還要串一套角度判斷邏輯而這套邏輯在真實(shí)環(huán)境里對攝像頭安裝高度、角度太敏感。YOLOv8則簡單得多一個(gè)檢測頭直接框出人所在區(qū)域要不要接分類邏輯、要不要接跟蹤都可以在部署階段靈活加。所以我最終選定YOLOv8核心思路就是“把復(fù)雜判斷推遲到后處理讓模型干自己最擅長的事”。1.3 項(xiàng)目技術(shù)棧與整體流程這個(gè)項(xiàng)目的技術(shù)棧很主流常規(guī)開發(fā)環(huán)境下幾乎可以一鍵復(fù)現(xiàn)模型框架YOLOv8采用官方預(yù)訓(xùn)練權(quán)重做微調(diào)而不是從頭訓(xùn)練。從頭訓(xùn)練在數(shù)據(jù)量上不現(xiàn)實(shí)微調(diào)則對數(shù)據(jù)需求友善得多。訓(xùn)練環(huán)境單張消費(fèi)級(jí)顯卡即可顯存16G上下完全夠用。部署環(huán)境邊緣計(jì)算盒子同時(shí)兼容CPU推理作為降級(jí)方案。業(yè)務(wù)外圍視頻流接入用RTSP數(shù)據(jù)處理用Python腳本實(shí)現(xiàn)“檢測結(jié)果 連續(xù)幀狀態(tài)機(jī)”的跌倒判定邏輯??梢暬唵巫隽艘粋€(gè)Web告警后臺(tái)用于展示報(bào)警截圖和現(xiàn)場視頻回放。整體流程可以拆成五段數(shù)據(jù)準(zhǔn)備與標(biāo)注模型訓(xùn)練與評(píng)估模型導(dǎo)出邊緣部署與環(huán)境適配告警業(yè)務(wù)邏輯聯(lián)調(diào)。每一段都有獨(dú)立的坑但最花時(shí)間的第二段和第五段。接下來我一條一條拆開講。2. 數(shù)據(jù)準(zhǔn)備與標(biāo)注決定模型上限的關(guān)鍵環(huán)節(jié)2.1 數(shù)據(jù)從哪來公開數(shù)據(jù)與自采數(shù)據(jù)相結(jié)合模型效果的天花板不是網(wǎng)絡(luò)結(jié)構(gòu)而是數(shù)據(jù)。YOLOv8的骨干網(wǎng)絡(luò)足夠強(qiáng)但喂進(jìn)去的數(shù)據(jù)如果沒有覆蓋真實(shí)場景的各種姿勢、光照、遮擋情況訓(xùn)練完照樣在監(jiān)控畫面里瘋狂誤報(bào)。我的數(shù)據(jù)源分成三塊第一塊是公開數(shù)據(jù)集。網(wǎng)上能搜到的跌倒檢測開源數(shù)據(jù)集我收集了三四套把里面的圖片全部抽取出來看了一遍。這一步很枯燥但必須做因?yàn)楹芏鄶?shù)據(jù)集的標(biāo)注質(zhì)量參差不齊有的把“蹲下?lián)鞏|西”也標(biāo)成了跌倒有的標(biāo)注框極其粗糙導(dǎo)致目標(biāo)特征學(xué)習(xí)混亂。我最終只篩選出圖像質(zhì)量清晰、跌倒姿態(tài)完整的圖片摔跤、坐倒、滑倒、暈厥倒地這幾類姿態(tài)盡量都要覆蓋。第二塊是自采模擬數(shù)據(jù)。我找了幾個(gè)同事在樣板間里模擬跌倒動(dòng)作用不同角度的相機(jī)錄制視頻然后抽幀保存。不要小看自采數(shù)據(jù)它是最能貼近真實(shí)部署場景的一環(huán)因?yàn)楣_數(shù)據(jù)集里的機(jī)位跟你的現(xiàn)場機(jī)位永遠(yuǎn)存在差異。第三塊是真實(shí)監(jiān)控?cái)?shù)據(jù)。這部分在涉及隱私的前提下只截取了場景中無人的背景幀作為負(fù)樣本或者經(jīng)充分脫敏后才使用。同時(shí)我會(huì)在無人的背景幀里混入一部分作為負(fù)樣本讓模型知道“當(dāng)前畫面沒有目標(biāo)”這對降低誤報(bào)有奇效。綜合下來訓(xùn)練集大概有12000多張圖其中正樣本包含跌倒和負(fù)樣本正常站立/行走/無人的背景的比例控制在大概1比3。一開始我是1比1發(fā)現(xiàn)模型雖然對跌倒敏感但也特別容易把掃地機(jī)器人誤報(bào)成人后來擴(kuò)大負(fù)樣本比例誤報(bào)明顯下降。2.2 類別定義與“半跌倒”邊界處理標(biāo)注之前先定類別這一步比多數(shù)人想象的更容易影響最終效果。我一開始只標(biāo)了兩類人類person和跌倒fall。邏輯是模型先檢出人再判斷人是否跌倒。但很快發(fā)現(xiàn)問題監(jiān)控畫面里人倒下的過程可能只有零點(diǎn)幾秒中間幀的姿態(tài)既不是站也不是躺模型在這一兩幀里會(huì)猶豫。更麻煩的是蹲下系鞋帶、彎腰撿東西、坐在地上休息這些姿態(tài)跟跌倒后的姿態(tài)實(shí)在太像了。最終我調(diào)整為三個(gè)類別站立/行走常規(guī)的直立或運(yùn)動(dòng)狀態(tài)。蹲坐/彎腰過渡狀態(tài)、低姿態(tài)。跌倒/躺倒人體大面積貼近地面且姿態(tài)異常。這三類并不是業(yè)務(wù)上的最終分類而是為了把“模糊地帶”從模型層面里分出來。模型只負(fù)責(zé)給出形態(tài)判斷至于“蹲坐”算不算危險(xiǎn)完全交給后處理邏輯結(jié)合持續(xù)時(shí)間來決定。這比讓模型強(qiáng)行二分類要穩(wěn)得多。舉個(gè)實(shí)際例子老人只是在床邊坐下來緩一緩畫面里的姿態(tài)跟跌倒非常接近如果沒有這個(gè)過渡類別系統(tǒng)大概率會(huì)誤報(bào)加了之后模型會(huì)把這種情況歸到蹲坐后處理邏輯再判斷是否連續(xù)若干秒沒有恢復(fù)直立才決定要不要告警。2.3 標(biāo)注工具與標(biāo)注易錯(cuò)點(diǎn)標(biāo)注工具我用了開源的標(biāo)注軟件支持自動(dòng)保存和快捷鍵操作在批量標(biāo)注效率上有肉眼可見的提升。下面幾個(gè)易錯(cuò)點(diǎn)都是真實(shí)踩過的坑標(biāo)注框不要刻意貼著人體外側(cè)。檢測框稍微包含一點(diǎn)背景反而有利于模型學(xué)到相對完整的輪廓特征。太緊的框遇到人體部分被遮擋時(shí)容易導(dǎo)致特征丟失。遮擋處理要統(tǒng)一規(guī)則。人體被桌椅遮擋了大約三分之一時(shí)也要正常標(biāo)注完整框。不要因?yàn)榭床灰娋椭粯?biāo)可見部分那樣會(huì)讓模型學(xué)習(xí)到殘缺特征。人體很小但清晰的圖片不要跳過。監(jiān)控畫面里經(jīng)常出現(xiàn)遠(yuǎn)景小目標(biāo)這種圖數(shù)量少但價(jià)值高。YOLOv8本身就存在小目標(biāo)檢測的弱點(diǎn)標(biāo)注時(shí)保留小目標(biāo)樣本有利于后續(xù)模型針對性訓(xùn)練。連續(xù)幀不要機(jī)械地全部抽取。跌倒動(dòng)作的視頻抽幀時(shí)盡量隔幾幀抽一張保證畫面多樣性否則連續(xù)相似幀會(huì)讓模型過擬合于某一特定動(dòng)作片段驗(yàn)證集上表現(xiàn)卻依然虛高。另外每批數(shù)據(jù)標(biāo)完以后我都會(huì)用第二個(gè)人去抽檢大概10%的標(biāo)注結(jié)果重點(diǎn)看邊界框和類別是否有明顯錯(cuò)誤。AI訓(xùn)練最怕的就是“臟數(shù)據(jù)進(jìn)、臟模型出”發(fā)現(xiàn)問題時(shí)返工成本遠(yuǎn)高于訓(xùn)練時(shí)間成本。2.4 數(shù)據(jù)增強(qiáng)不換模型也能提點(diǎn)YOLOv8自帶豐富的數(shù)據(jù)增強(qiáng)策略訓(xùn)練時(shí)開啟默認(rèn)增強(qiáng)就夠用但有幾個(gè)參數(shù)值得單獨(dú)調(diào)。色調(diào)、飽和度、亮度監(jiān)控畫面里色溫差異很大白天偏冷、夜間偏暖所以我把HSV增強(qiáng)的幅度比默認(rèn)值調(diào)大了大概50%模擬不同時(shí)間段的畫面風(fēng)格。隨機(jī)透視與平移這些模擬攝像機(jī)安裝角度小范圍變化能提升模型對不同機(jī)位的適應(yīng)能力。幅度不宜過大否則會(huì)讓目標(biāo)形變失真。Mosaic增強(qiáng)這幅圖是YOLO系列的老朋友多圖拼接能讓模型學(xué)會(huì)在復(fù)雜背景下辨別目標(biāo)。不過最后一二十個(gè)epoch我會(huì)把它關(guān)掉在這一階段使用Mosaic會(huì)導(dǎo)致訓(xùn)練特征分布與實(shí)際場景偏差具體做法在后面訓(xùn)練部分展開說。有一點(diǎn)必須提醒數(shù)據(jù)增強(qiáng)不是無腦拉滿增強(qiáng)過猛會(huì)讓模型學(xué)到虛假紋理。我的經(jīng)驗(yàn)是先在默認(rèn)參數(shù)下跑一個(gè)短期訓(xùn)練看驗(yàn)證集指標(biāo)再小幅調(diào)整增強(qiáng)參數(shù)對比幾次后取穩(wěn)定上升的方向小步嘗試比一次性大改更容易定位問題。3. 訓(xùn)練實(shí)戰(zhàn)配置、過程與評(píng)估3.1 訓(xùn)練環(huán)境與顯存占用訓(xùn)練環(huán)境非常平民化。操作系統(tǒng)是Ubuntu深度學(xué)習(xí)框架PyTorch顯卡用的是單張普通游戲顯卡。別被一些教程嚇住以為非得四卡起步Y(jié)OLOv8n和YOLOv8s這類模型在消費(fèi)級(jí)顯卡上完全可以訓(xùn)。顯存占用主要取決于圖像分辨率、batch size和模型寬度。我把輸入分辨率設(shè)為640×640模型選的是YOLOv8n和YOLOv8s各訓(xùn)了一版。YOLOv8s在精度上比n版低一點(diǎn)二者差異其實(shí)沒有想象中大但YOLOv8s的推理負(fù)載和顯存占用明顯更高??紤]到最終要上邊緣設(shè)備我選擇了YOLOv8s作為主干方案n版作為備選算是一個(gè)精度和延遲之間的折中。一個(gè)實(shí)用技巧訓(xùn)練時(shí)顯存不夠優(yōu)先調(diào)小batch size不要一上來就改圖像分辨率。分辨率降低會(huì)讓小目標(biāo)漏檢率直線上升這個(gè)代價(jià)比降低batch size嚴(yán)重得多。安裝環(huán)境只需要執(zhí)行幾條命令建議用虛擬環(huán)境隔離。項(xiàng)目里我用的是Python 3.10版本裝好Ultralytics后再裝一張基礎(chǔ)依賴清單避免后續(xù)額外擴(kuò)展時(shí)版本打架。3.2 訓(xùn)練參數(shù)逐項(xiàng)解讀YOLOv8的官方命令行工具已經(jīng)封裝得很順手但參數(shù)含義必須吃透不然訓(xùn)練跑起來出了問題都不知道去哪找。我用的是下面這份基礎(chǔ)配置來訓(xùn)練YOLOv8syolo train \ modelyolov8s.pt \ datadataset.yaml \ epochs120 \ imgsz640 \ batch16 \ optimizerSGD \ lr00.01 \ lrf0.01 \ cos_lrTrue \ patience20 \ device0逐項(xiàng)解釋我調(diào)整過的關(guān)鍵參數(shù)model參數(shù)用的是yolov8s.pt預(yù)訓(xùn)練權(quán)重這是在COCO數(shù)據(jù)集上訓(xùn)好的通用模型。風(fēng)吹日曬的YOLOv8已經(jīng)在通用目標(biāo)上學(xué)會(huì)了很好的特征表達(dá)我們只學(xué)“跌倒”這個(gè)新任務(wù)即可。epochs沒有設(shè)很大120輪是因?yàn)閿?shù)據(jù)量本身夠用過度訓(xùn)練反而開始過擬合。我觀察過訓(xùn)練日志大約在80輪之后驗(yàn)證集曲線就基本進(jìn)入平臺(tái)期120輪已經(jīng)足夠收斂多出來的輪數(shù)主要為了保險(xiǎn)。optimizer用SGD而不用AdamYOLOv8官方默認(rèn)也推薦SGD。Adam前期收斂快但后期容易在驗(yàn)證集上收不干凈SGD配合余弦退火學(xué)習(xí)率整體收斂過程更穩(wěn)最終精度通常略高。lr0、lrf和cos_lr組合成一套余弦退火策略學(xué)習(xí)率從0.01慢慢降到0.0001。這種曲線比固定學(xué)習(xí)率更平滑特別是后期微調(diào)階段不容易震蕩。patience20表示如果驗(yàn)證集指標(biāo)連續(xù)20個(gè)epoch沒有改善訓(xùn)練會(huì)自動(dòng)停止防止空轉(zhuǎn)浪費(fèi)時(shí)間。數(shù)據(jù)集配置文件是YAML格式里面定義訓(xùn)練驗(yàn)證路徑和類別名。這里有一個(gè)細(xì)節(jié)路徑最好用絕對路徑或者至少確保相對路徑是相對于配置文件所在目錄的我就在這上面栽過跟頭數(shù)據(jù)集移動(dòng)目錄后一直報(bào)找不到文件后來仔細(xì)看路徑拼接規(guī)則才發(fā)現(xiàn)問題。3.3 訓(xùn)練過程與中斷恢復(fù)訓(xùn)練過程不是一鍵執(zhí)行就完事我基本每隔一小時(shí)會(huì)看一眼曲線。主要看兩個(gè)地方候選值的變化趨勢和訓(xùn)練集損失。正常情況下推理損失和分類損失都應(yīng)該是連續(xù)下降的驗(yàn)證集mAP曲線呈現(xiàn)波浪式上升。如果發(fā)現(xiàn)候選值已經(jīng)掉頭持續(xù)下降幾個(gè)epoch而訓(xùn)練損失還在降這就是典型的過擬合信號(hào)需要對模型進(jìn)行正則化加強(qiáng)或者提前停止訓(xùn)練。另外如果訓(xùn)練開始階段mAP還是零不用慌前幾個(gè)epoch只是讓模型適應(yīng)新數(shù)據(jù)一般到10到15個(gè)epoch后曲線會(huì)突然開始抬頭。訓(xùn)練過程中途意外斷電也不想重新來YOLOv8支持?jǐn)帱c(diǎn)續(xù)訓(xùn)。我建議每5到10個(gè)epoch保留一個(gè)權(quán)重文件這里給出的是模型自動(dòng)保存的策略。萬一中斷只要找到最近的一個(gè)權(quán)重文件直接續(xù)訓(xùn)——一般從驗(yàn)證集指標(biāo)較高的那個(gè)checkpoint繼續(xù)能得到一個(gè)相對更穩(wěn)的收斂結(jié)果。另一個(gè)心得是訓(xùn)練階段要學(xué)會(huì)“看日志找線索”。日志里除了正常顯示mAP和loss之外還會(huì)顯示每個(gè)類別的精確率、召回率。如果使用“跌倒/躺倒”類別的召回率明顯偏低大概率是正樣本不夠模型把跌倒漏成了背景若精確率偏低大概率是負(fù)樣本不夠或者容易混淆的站姿過多模型過于激進(jìn)地把普通姿態(tài)判定為跌倒。定位到方向后再去補(bǔ)數(shù)據(jù)比盲目調(diào)參高效得多。3.4 評(píng)估指標(biāo)與權(quán)重版本選擇評(píng)估模型時(shí)不能只看一張圖上“看起來準(zhǔn)不準(zhǔn)”那只是主觀感受。我用下面這套指標(biāo)組合來客觀評(píng)價(jià)mAP50初始驗(yàn)證時(shí)的主要參考。它在IoU為0.5的寬松標(biāo)準(zhǔn)下計(jì)算所有類別的平均精度。這個(gè)指標(biāo)比較高說明模型基本能框住目標(biāo)但邊界框與真實(shí)框有較大浮動(dòng)也能接受。mAP50-95更嚴(yán)格的目標(biāo)檢測綜合指標(biāo)。它對邊界框位置精度的要求更高。如果這個(gè)指標(biāo)明顯偏低說明模型的坐標(biāo)回歸能力還不足檢測框經(jīng)常偏移。精確率與召回率我分別統(tǒng)計(jì)了“跌倒/躺倒”這一類別的精度和召回率。精確率要的是減誤報(bào)召回率要的是減漏報(bào)。業(yè)務(wù)場景里漏報(bào)更嚴(yán)重所以我的方向是“保召回率精確率通過后處理兜底”。訓(xùn)練完成后官方會(huì)輸出best.pt和last.pt兩個(gè)權(quán)重文件。不要直接把last.pt拿去部署它極大概率不是驗(yàn)證集指標(biāo)最高的版本。best.pt才是訓(xùn)練結(jié)束時(shí)驗(yàn)證集表現(xiàn)最好的那個(gè)checkpoint。后續(xù)如果要調(diào)整訓(xùn)練數(shù)據(jù)或參數(shù)建議在best.pt基礎(chǔ)上繼續(xù)而不是從頭再來。4. 部署與性能優(yōu)化從權(quán)重到邊緣設(shè)備4.1 先做精度確認(rèn)再導(dǎo)出推理格式模型訓(xùn)練完先別急著打包上設(shè)備先在本地測試集上做一輪推理效果巡檢把那些典型誤報(bào)圖、漏報(bào)圖打印出來看一下。我通常會(huì)把置信度閾值調(diào)到0.25把測試集里所有預(yù)測結(jié)果疊加到原圖上檢查模型在真實(shí)場景里的表現(xiàn)。這一步的產(chǎn)出是“可信度結(jié)論”確定閾值高一點(diǎn)還是低一點(diǎn)是決定后續(xù)告警敏感度的基礎(chǔ)。確認(rèn)精度在可接受范圍后再把PyTorch模型導(dǎo)出為推理引擎格式。我部署的邊緣盒子支持TensorRT所以導(dǎo)出命令是得用halfTrue也就是FP16精度。這一步能把推理速度提升一個(gè)量級(jí)后面詳細(xì)說。yolo export modelruns/train/exp/weights/best.pt formatengine imgsz640 halfTrue device0一些模型在導(dǎo)出為TensorRT引擎時(shí)會(huì)有精度損失所以導(dǎo)出后我還會(huì)跑一遍同等測試集把mAP對比一遍。如果出現(xiàn)明顯下降就回頭檢查訓(xùn)練盒子上預(yù)處理器和模型輸入尺寸的配置是否符合導(dǎo)出時(shí)的要求。4.2 邊緣設(shè)備部署方案我部署的目標(biāo)設(shè)備是一臺(tái)低功耗邊緣計(jì)算盒子算力不高但勝在便宜、穩(wěn)定、無風(fēng)扇設(shè)計(jì)適合安裝在天花板或走廊角落。這類設(shè)備的系統(tǒng)環(huán)境是精簡過的LinuxPython環(huán)境和桌面環(huán)境都折騰得比較徹底因此部署策略是這樣的主體推理代碼用Python寫調(diào)用TensorRT的Python綁定接口加載engine文件。視頻流讀取用OpenCV的RTSP拉流接口把攝像頭的網(wǎng)絡(luò)視頻流轉(zhuǎn)換為幀數(shù)據(jù)。推理輸出的是張量需要后處理解析出檢測框、類別、置信度然后傳給業(yè)務(wù)邏輯。這里有個(gè)非常關(guān)鍵的部署細(xì)節(jié)攝像頭出來的視頻分辨率并不一定是640×640而模型輸入要求固定的640×640。所以推理前必須做圖像縮放與填充。我維護(hù)了一個(gè)“等比例縮放灰邊填充”的函數(shù)保證圖像內(nèi)容不變形同時(shí)把實(shí)際縮放比例記錄下來。檢測框坐標(biāo)從這個(gè)640×640的坐標(biāo)系轉(zhuǎn)換回原始圖像分辨率時(shí)必須利用這個(gè)縮放比例反向換算否則后面的框畫出來所有位置都偏移。很多教程這一步是放過去的但實(shí)際部署時(shí)畫框位置錯(cuò)位、告警截圖區(qū)域錯(cuò)誤十個(gè)里面七個(gè)都是坐標(biāo)變換沒做對。4.3 推理速度優(yōu)化不只是快YOLOv8s 640輸入 TensorRT FP16在邊緣盒子上的推理速度大約能到30毫秒一幀也就是接近30FPS。如果還需要進(jìn)一步壓榨性能可以依次嘗試這幾招降低輸入分辨率。640降到576或512速度立馬上來但對小目標(biāo)的影響也最直接。如果你的攝像頭視角里人比較大這個(gè)方案很劃算。改用YOLOv8n模型。n版參數(shù)量大概是s版的四分之一推理速度快很多代價(jià)是精度下降。如果部署端算力實(shí)在太弱n版是最后的退路。減小檢測頭輸出規(guī)模。對只有一兩個(gè)類別的場景輸出層可以裁剪但這種改動(dòng)需要重新訓(xùn)練和導(dǎo)出操作繁瑣一般不到最后不用。推理耗時(shí)之外整個(gè)鏈路的耗時(shí)同樣不能忽視。RTSP拉流本身就有延遲加上多路視頻并發(fā)時(shí)CPU參與編解碼的開銷模型推理只占全線耗時(shí)的三分之一。如果要做多路視頻優(yōu)先給每路視頻分配一個(gè)獨(dú)立拉流線程推理再統(tǒng)一回收到一個(gè)線程里避免多線程并發(fā)推理擠爆GPU。4.4 后處理業(yè)務(wù)邏輯從“檢出跌倒”到“觸發(fā)告警”模型輸出的只是“這一幀里有人跌倒”離業(yè)務(wù)需求的“向后臺(tái)發(fā)出告警”還差三層處理第一層是置信度閾值。我最終把置信度閾值定到了0.45。閾值太低了誤報(bào)框全漏進(jìn)來后臺(tái)會(huì)被淹沒閾值太高了低質(zhì)量畫面里的真實(shí)跌倒又可能漏檢。這個(gè)值沒有標(biāo)準(zhǔn)答案建議在自己的測試集上畫出一個(gè)準(zhǔn)確率-召回率曲線再結(jié)合業(yè)務(wù)對誤報(bào)的容忍度拍板。第二層是連續(xù)幀確認(rèn)。單幀檢出不足以采信因?yàn)楫嬅嬖肼暫瓦\(yùn)動(dòng)模糊會(huì)偶發(fā)產(chǎn)生假陽性。我的做法是設(shè)一個(gè)連續(xù)幀狀態(tài)機(jī)檢測到fall后開始計(jì)數(shù)連續(xù)3幀都檢出fall才進(jìn)入預(yù)備告警狀態(tài)如果當(dāng)中有一幀顯示站立或蹲坐計(jì)數(shù)清零。這層邏輯把很多偶發(fā)誤報(bào)直接過濾掉。第三層是停留時(shí)間判斷。跌倒后如果人馬上站起來不需要告警只有跌倒?fàn)顟B(tài)持續(xù)超過比如10秒才觸發(fā)緊急告警。這樣處理能明顯減少“假跌倒”造成的無效告警。判斷時(shí)長需要跟現(xiàn)場客戶確認(rèn)有的場景希望更敏捷有的場景害怕打擾這段參數(shù)最好做成配置項(xiàng)而不是寫死。業(yè)務(wù)后臺(tái)方面我只是做了一個(gè)非常輕量的告警服務(wù)接收告警事件保存當(dāng)前幀截圖為證據(jù)圖同時(shí)把事件推送至管理人員。告警截圖最好存下來因?yàn)樗鞘潞笞匪莸闹匾獞{證。5. 落地避坑誤報(bào)、漏報(bào)與現(xiàn)場問題排查5.1 真實(shí)場景里的典型誤報(bào)這個(gè)項(xiàng)目里最費(fèi)精力的不是訓(xùn)練而是現(xiàn)場反復(fù)出現(xiàn)的誤報(bào)問題。挑三個(gè)最有代表性的講第一個(gè)是影子誤報(bào)。傍晚陽光斜射人的影子被拉得很長影子在地面上的輪廓在某些幀里會(huì)被模型當(dāng)成人形目標(biāo)尤其當(dāng)影子與本體分離時(shí)會(huì)檢出一個(gè)看起來像躺在地面的“人”。解決思路是盡量避免朝向窗戶的機(jī)位同時(shí)訓(xùn)練數(shù)據(jù)里加入大量含有影子的負(fù)樣本。還有個(gè)后處理補(bǔ)救辦法利用影子目標(biāo)運(yùn)動(dòng)特征與真實(shí)目標(biāo)的差異進(jìn)行過濾但性價(jià)比不如前兩者。第二個(gè)是椅子和沙發(fā)誤報(bào)。躺進(jìn)沙發(fā)里玩手機(jī)的人遠(yuǎn)看姿態(tài)就是“人體橫向分布”和跌倒寫征非常接近。單靠視覺幾乎無解只能靠后處理狀態(tài)機(jī)加“停留時(shí)間”來抑制短時(shí)間的躺臥不會(huì)觸發(fā)告警。真遇到長時(shí)間賴在沙發(fā)上不動(dòng)那就只能承認(rèn)這是系統(tǒng)的合理告警嚴(yán)格說也不能算誤報(bào)。第三個(gè)是相機(jī)抖動(dòng)與夜間噪聲。老式攝像頭或網(wǎng)絡(luò)傳輸不穩(wěn)定時(shí)視頻流會(huì)自動(dòng)丟幀偶爾會(huì)出現(xiàn)畫面跳動(dòng)的瞬間導(dǎo)致檢測框突然抖動(dòng)甚至閃現(xiàn)。我在后處理里加了一個(gè)檢測框最大位移限制如果下一幀框的位置相比上一幀發(fā)生超過畫面寬度一半的跳變就判定為跟蹤異常并忽略該幀。5.2 排查與調(diào)優(yōu)速查表現(xiàn)場出現(xiàn)問題最有用的是一張能快速對照排查的表。下面是我自己整理的現(xiàn)象可能原因處理手段漏報(bào)真實(shí)跌倒攝像頭視角過高或過低調(diào)整安裝角度補(bǔ)充對應(yīng)視角數(shù)據(jù)漏報(bào)真實(shí)跌倒人體在畫面中過小降低輸入分辨率或使用更高分辨率輸入誤報(bào)影子/倒影訓(xùn)練集缺少對應(yīng)負(fù)樣本收集影子樣本加入負(fù)樣本集誤報(bào)蹲坐/躺沙發(fā)類別定義過粗增加過渡類別后處理加停留判斷檢出結(jié)果閃爍抖動(dòng)單幀置信度過低提高置信度閾值增加連續(xù)幀確認(rèn)檢測框位置偏移坐標(biāo)變換未還原檢查縮放系數(shù)和灰邊偏移量實(shí)機(jī)推理太慢并發(fā)推理阻塞分流線程與推理線程分離夜間誤報(bào)增多光線過暗導(dǎo)致噪聲增大補(bǔ)光或切換夜間模式調(diào)整閾值先分清楚問題屬于“模型層”還是“工程層”。模型層問題一般表現(xiàn)為對真實(shí)場景數(shù)據(jù)不敏感工程層問題一般表現(xiàn)為坐標(biāo)錯(cuò)誤、幀率不穩(wěn)、告警邏輯缺陷。判斷方向?qū)α嗽賱?dòng)手省時(shí)間。5.3 效果復(fù)盤與后續(xù)擴(kuò)展方向這個(gè)項(xiàng)目做下來最終實(shí)機(jī)表現(xiàn)讓我比較滿意。線上測試統(tǒng)計(jì)了大概一周跌倒檢測的召回率在測試集上達(dá)到92%以上誤報(bào)率控制在約一天一次的水平而每次誤報(bào)集中出現(xiàn)在下班時(shí)段的光影劇烈變化期間。老人照護(hù)場景的反倒是“漏報(bào)”的代價(jià)更大所以我對召回率的容忍度要高于誤報(bào)率。后續(xù)如果繼續(xù)迭代我會(huì)優(yōu)先做三件事一是時(shí)序信息引入。給模型輸入連續(xù)幾幀的差分信息或直接接一條輕量級(jí)時(shí)序模塊讓跌倒動(dòng)作本身的速度特征參與判斷甩開靜態(tài)姿態(tài)死磕蹲坐類問題的老路。二是多目融合。單攝像頭遮擋是硬傷可以用兩個(gè)攝像頭從不同角度覆蓋同一區(qū)域兩個(gè)通道的一致判斷能顯著降低遮擋導(dǎo)致的漏報(bào)。三是端側(cè)告警分級(jí)。把跌倒檢測與睡眠監(jiān)測、久坐提醒、區(qū)域入侵檢測結(jié)合起來讓這套模型從一個(gè)獨(dú)立功能升級(jí)成一套綜合場景守護(hù)系統(tǒng)這對實(shí)際部署的工程價(jià)值遠(yuǎn)大于某一指標(biāo)的改善。最后分享一個(gè)小技巧實(shí)機(jī)調(diào)試時(shí)把模型預(yù)測的“置信度值”和“檢測框坐標(biāo)”一并打印到視頻輸出畫面的角落這個(gè)細(xì)節(jié)會(huì)幫你在現(xiàn)場快速判斷問題出在檢測環(huán)節(jié)還是后處理環(huán)節(jié)。我在項(xiàng)目收尾階段一直靠這招定位問題省下了不少對著監(jiān)控錄像反復(fù)回放的笨功夫。