生行為識(shí)別:8800張YOLO標(biāo)注數(shù)據(jù)集與YOLOv8訓(xùn)練實(shí)踐)
簡介目標(biāo)檢測是計(jì)算機(jī)視覺的核心任務(wù)YOLO系列憑借高效、實(shí)時(shí)的特性成為工程化落地最常用的檢測框架。其標(biāo)注格式以簡潔的歸一化坐標(biāo)表達(dá)目標(biāo)框與類別信息方便快速訓(xùn)練與部署。在智慧課堂場景中學(xué)生行為識(shí)別依賴高質(zhì)量的數(shù)據(jù)集和精準(zhǔn)的標(biāo)注規(guī)范通過檢測模型自動(dòng)定位學(xué)生并分類舉手、趴桌、玩手機(jī)等動(dòng)作。本文基于一套8800張圖像、采用YOLO標(biāo)注格式的課堂行為數(shù)據(jù)集詳細(xì)解析數(shù)據(jù)構(gòu)成、類別設(shè)計(jì)、標(biāo)注質(zhì)量檢查并給出基于YOLOv8的完整訓(xùn)練流程、超參數(shù)調(diào)優(yōu)及常見問題排查方法為教育場景下的行為分析系統(tǒng)開發(fā)提供可復(fù)用的實(shí)踐參考。1. 項(xiàng)目背景與數(shù)據(jù)集價(jià)值1.1 智慧課堂行為識(shí)別到底要解決什么問題先說個(gè)場景一間教室裝了一臺(tái)攝像頭一節(jié)課45分鐘畫面里二三十個(gè)學(xué)生姿態(tài)各不相同。有的在抬頭看黑板有的低頭寫有的趴桌子上還有的手藏在桌洞里。如果單靠人工盯監(jiān)控一節(jié)課盯下來眼睛酸不說還容易漏掉關(guān)鍵片段。智慧課堂學(xué)生行為分析要做的就是用目標(biāo)檢測模型把畫面里的每個(gè)學(xué)生以及對應(yīng)的行為狀態(tài)框出來再自動(dòng)統(tǒng)計(jì)“誰在舉手、誰在睡覺、誰在玩手機(jī)”。這個(gè)需求的落地價(jià)值很直接輔助老師了解課堂互動(dòng)情況幫助教務(wù)系統(tǒng)生成課堂質(zhì)量報(bào)告也能給家長反饋學(xué)生在校狀態(tài)。但不管上層算法怎么設(shè)計(jì)第一步都是“能不能先把人找到、把行為認(rèn)出來”。而這一步依賴的就是一套已標(biāo)注的學(xué)生行為數(shù)據(jù)集。我這次整理的項(xiàng)目就是一套約8800張圖像的智慧課堂學(xué)生行為目標(biāo)檢測數(shù)據(jù)標(biāo)簽格式采用YOLO標(biāo)注格式每張圖像都有對應(yīng)的txt標(biāo)簽文件可以直接交給YOLOv5、YOLOv8這類檢測框架訓(xùn)練??赡苡腥藭?huì)問直接用公開的人體檢測數(shù)據(jù)集行不行我的回答是不太可行。公開數(shù)據(jù)集大多面向通用場景類別是person、chair這種不會(huì)細(xì)分“舉手”“睡覺”“玩手機(jī)”。而課堂行為數(shù)據(jù)的難點(diǎn)在于人和人的姿態(tài)差異小、行為重疊多比如“趴桌”和“睡覺”從正上方看非常接近“玩手機(jī)”和“寫字”手部區(qū)域也容易混。所以一套專門針對課堂場景、標(biāo)注了行為類別的數(shù)據(jù)集才是能把模型訓(xùn)練實(shí)用的關(guān)鍵。1.2 為什么選擇YOLO標(biāo)注格式這套數(shù)據(jù)集采用YOLO標(biāo)注格式并不是拍腦袋定的。YOLO格式本質(zhì)上就是一個(gè)與圖片同名的txt文件每一行表示一個(gè)目標(biāo)框包含“類別編號 x_center y_center width height”五個(gè)值且后面的四個(gè)坐標(biāo)值都做了歸一化范圍在0到1之間。這個(gè)格式最大的優(yōu)點(diǎn)是輕量、通用、好解析。不像COCO的JSON格式那么嵌套也不像VOC的XML標(biāo)簽?zāi)菢佑幸欢压?jié)點(diǎn)讀起來很直觀。對做目標(biāo)檢測的人來說YOLO格式兼容性極高。YOLOv5、YOLOv8、YOLOv9、YOLO11這些官方倉庫都能直接讀就算你后面想換到MMDetection或Detectron2也只需要寫一個(gè)簡單的坐標(biāo)轉(zhuǎn)換腳本把歸一化坐標(biāo)乘回圖像寬高就能轉(zhuǎn)成COCO或VOC格式。所以標(biāo)注成YOLO格式意味著模型訓(xùn)練環(huán)節(jié)省去了大量格式轉(zhuǎn)換工作。另一個(gè)實(shí)際考慮是標(biāo)注工具支持。LabelImg、Label Studio、X-AnyLabeling這些常見標(biāo)注工具都支持直接導(dǎo)出YOLO格式還有開源生態(tài)里的自動(dòng)標(biāo)注工具也默認(rèn)兼容YOLO標(biāo)簽。項(xiàng)目在數(shù)據(jù)交付和復(fù)用層面都能少走彎路。如果你之前習(xí)慣用VOC XML或COCO JSON不用擔(dān)心YOLO格式的核心只是坐標(biāo)表達(dá)方式不同檢測目標(biāo)本身沒有任何信息丟失。1.3 8800張數(shù)據(jù)集的規(guī)模夠不夠用很多新手拿到8800張會(huì)猶豫這個(gè)量是不是太少我的看法是對于智慧課堂行為識(shí)別這種場景相對固定的任務(wù)8800張已標(biāo)注圖片是一個(gè)挺合理的起步規(guī)模。它不算是超大廠級的百萬級數(shù)據(jù)但足夠讓模型學(xué)到課堂場景下的基本特征分布。具體夠不夠用主要看兩個(gè)變量一是類別數(shù)二是場景復(fù)雜度。如果行為類別只有5到8類比如舉手、讀書、寫字、站立、趴桌、玩手機(jī)、 walk、sleep8800張圖平均每類能分到上千個(gè)實(shí)例配合預(yù)訓(xùn)練權(quán)重和增強(qiáng)策略完全能訓(xùn)練出一個(gè)mAP50在0.8左右的可部署模型。如果類別膨脹到20類以上比如還要區(qū)分左手指黑板、右手指黑板、兩個(gè)人討論、三個(gè)人討論這種細(xì)粒度行為那8800張就會(huì)顯得緊張需要靠后續(xù)數(shù)據(jù)迭代補(bǔ)長尾。從我的實(shí)操經(jīng)驗(yàn)看第一版模型不需要追求“所有怪角度一眼全對”。先用8800張把主流程跑通看看哪些類別容易混、哪些場景漏檢再針對性地補(bǔ)幾百張困難樣本效果往往比一上來悶頭標(biāo)幾萬張濫用數(shù)據(jù)更高效。數(shù)據(jù)數(shù)量是基礎(chǔ)但數(shù)據(jù)質(zhì)量和類別定義的穩(wěn)定性才是決定上限的東西。2. 數(shù)據(jù)集構(gòu)成與標(biāo)注細(xì)節(jié)解析2.1 圖像內(nèi)容、分辨率與場景覆蓋這套智慧課堂學(xué)生行為數(shù)據(jù)集主要來自教室攝像頭采集畫面常見是教室前上方或后上方視角能覆蓋整間教室的座位區(qū)域。圖像分辨率以1920×1080和1280×720為主畫幅基本上是寬屏比例。為什么要關(guān)注分辨率因?yàn)闄z測框的像素面積直接影響小目標(biāo)識(shí)別難度。后排學(xué)生的人頭區(qū)域往往只有30×30像素左右如果分辨率太低檢測器很難學(xué)出細(xì)節(jié)特征。場景覆蓋方面數(shù)據(jù)應(yīng)該盡量包含不同時(shí)間段的光線條件。我見過不少數(shù)據(jù)集只在晴天上午采集結(jié)果模型一到陰天或傍晚燈光下誤檢率立刻上升。好的課堂行為數(shù)據(jù)集最好能覆蓋上午自然光、下午逆光、傍晚日光燈混合光、PPT投影亮屏、拉窗簾暗環(huán)境這幾類典型情況。同時(shí)教室座位布局也要有變化比如傳統(tǒng)排排坐、小組圍坐、階梯教室否則模型容易對某一種座位角度過擬合。數(shù)據(jù)集的訓(xùn)練集、驗(yàn)證集、測試集建議按照約8:1:1的比例劃分也就是大約7040張訓(xùn)練、880張驗(yàn)證、880張測試。劃分時(shí)不能簡單隨機(jī)切要盡量保證同一個(gè)教室、同一個(gè)時(shí)間段的數(shù)據(jù)分布到不同集合里避免驗(yàn)證集里出現(xiàn)和訓(xùn)練集高度相似的畫面導(dǎo)致評估結(jié)果虛高。實(shí)際操作中我習(xí)慣按視頻片段或拍攝批次劃分而不是一張一張亂抽。2.2 行為類別體系設(shè)計(jì)目標(biāo)檢測數(shù)據(jù)集的“靈魂”是類別體系。同樣的圖像標(biāo)注規(guī)范不同訓(xùn)練出的模型行為也完全不同。這套數(shù)據(jù)集常見的類別設(shè)計(jì)是6到8類比如舉手raise_hand站立stand行走walk閱讀read書寫write使用手機(jī)phone趴桌sleep / desk聽講listen其中“聽講”這類比較抽象我在實(shí)際標(biāo)注時(shí)建議謹(jǐn)慎加入因?yàn)椤奥犞v”更多是一種狀態(tài)而不是一個(gè)明確的動(dòng)作不同標(biāo)注員對“是否聽講”的判斷很難統(tǒng)一容易造成標(biāo)簽噪聲。相比之下“舉手”“站立”“玩手機(jī)”“寫字”的動(dòng)作邊界清晰標(biāo)注一致性更高訓(xùn)練出來也更穩(wěn)定。類別設(shè)計(jì)時(shí)有個(gè)重要原則動(dòng)作之間要有區(qū)分度。如果兩個(gè)類別的視覺特征高度重疊模型就會(huì)一直混淆。比如“趴桌”和“睡覺”在很多畫面上其實(shí)是同一個(gè)姿態(tài)只是眼睛是否閉上。這種差異靠可見光攝像頭很難分辨強(qiáng)行分兩類只會(huì)讓模型學(xué)到一個(gè)隨機(jī)決策邊界。我的建議是合并成“趴桌/睡覺”一類先用粗粒度把行為框架搭起來后面需要細(xì)粒度再引入骨骼關(guān)鍵點(diǎn)或時(shí)序模型去分。2.3 YOLO標(biāo)簽文件到底長什么樣我一直覺得理解YOLO標(biāo)簽文件是使用數(shù)據(jù)集的基本功。它的格式很固定假設(shè)有一張名為IMG_0001.jpg的圖像對應(yīng)標(biāo)簽文件就是IMG_0001.txt。文件里每一行代表一個(gè)已經(jīng)標(biāo)注的目標(biāo)框五個(gè)數(shù)字按空格分隔0 0.450123 0.382456 0.124780 0.260134 2 0.731234 0.611987 0.098756 0.214567第一個(gè)數(shù)字是類別編號從0開始計(jì)數(shù)對應(yīng)你定義的類別列表。后面四個(gè)數(shù)字依次是歸一化后的目標(biāo)框中心x坐標(biāo)、中心y坐標(biāo)、框?qū)挾?、框高度。所謂歸一化就是把像素坐標(biāo)除以圖像寬高所以坐標(biāo)值的范圍在0到1之間。舉個(gè)例子一張1920×1080的圖上某個(gè)學(xué)生的行為框左上角像素坐標(biāo)是(400, 300)右下角像素坐標(biāo)是(640, 580)那么中心像素坐標(biāo)是(520, 440)框?qū)?40像素框高280像素。用寬高歸一化后就是x_center 520 / 1920 ≈ 0.2708y_center 440 / 1080 ≈ 0.4074width 240 / 1920 0.125height 280 / 1080 ≈ 0.2593。最后那一行標(biāo)簽就應(yīng)該是類別ID 0.2708 0.4074 0.1250 0.2593。你可能注意到Y(jié)OLO標(biāo)簽用的是“中心點(diǎn)寬高”的表達(dá)而不是左上角和右下角。這是因?yàn)槟繕?biāo)檢測里很多算法業(yè)務(wù)邏輯都圍繞錨框中心做回歸歸一化后的中心坐標(biāo)也方便跨分辨率遷移。你不需要手動(dòng)算這些值標(biāo)注工具會(huì)自動(dòng)完成但搞清楚原理對后續(xù)排查標(biāo)注問題非常有幫助。2.4 標(biāo)注質(zhì)量驗(yàn)收標(biāo)準(zhǔn)很多人拿到別人標(biāo)注好的數(shù)據(jù)集直接開訓(xùn)練結(jié)果發(fā)現(xiàn)模型效果差卻不知道問題出在標(biāo)注上。標(biāo)注質(zhì)量驗(yàn)收有幾個(gè)硬指標(biāo)我在項(xiàng)目里都會(huì)逐項(xiàng)檢查。第一是框的貼合度。行為框應(yīng)該緊貼目標(biāo)主體允許少量邊緣留白但不能出現(xiàn)框只框住半個(gè)身體或者把旁邊同學(xué)的胳膊也包進(jìn)來的情況。第二是類別一致性同一個(gè)人在同一姿態(tài)下兩張圖里標(biāo)注類別必須一致不同標(biāo)注員對同一類行為的理解也要對齊。第三是完整性該標(biāo)的人沒標(biāo)屬于漏標(biāo)該框的行為沒框影響會(huì)更嚴(yán)重。我建議標(biāo)注完成后做一輪全量檢查統(tǒng)計(jì)每個(gè)txt文件的行數(shù)、坐標(biāo)范圍、類別ID是否越界再用腳本把標(biāo)注框畫回圖像上隨機(jī)抽檢。畫框抽檢這一步看著簡單但真的能發(fā)現(xiàn)大量問題有的框中心在畫面邊緣外有的類別ID和類別對應(yīng)關(guān)系錯(cuò)位有的標(biāo)簽文件比圖片少一行都會(huì)在訓(xùn)練時(shí)悄悄降低指標(biāo)。檢查通過后才算是一個(gè)可以進(jìn)入訓(xùn)練流程的數(shù)據(jù)集。3. 基于該數(shù)據(jù)集訓(xùn)練YOLO模型的完整流程3.1 環(huán)境搭建與依賴版本有了8800張已標(biāo)注YOLO格式數(shù)據(jù)集接下來的核心工作就是訓(xùn)練一個(gè)可用的檢測模型。我以YOLOv8為例因?yàn)樗挠?xùn)練接口最簡單文檔也全。環(huán)境建議使用Python 3.8以上版本PyTorch 1.8以上如果是NVIDIA顯卡CUDA和cuDNN對應(yīng)版本裝好。最省事的安裝方式依然是pip install ultralytics這個(gè)命令會(huì)把YOLOv8訓(xùn)練、驗(yàn)證、導(dǎo)出所需的依賴一起裝上。如果你要用GPU加速先確認(rèn)PyTorch版本和CUDA匹配。日常開發(fā)中我習(xí)慣在conda環(huán)境里單獨(dú)建一個(gè)虛擬環(huán)境避免不同項(xiàng)目之間的包版本沖突。比如conda create -n classroom python3.10 conda activate classroom pip install ultralytics裝完之后可以先跑一個(gè)簡單的命令驗(yàn)證環(huán)境是否正常。這里不需要下載預(yù)訓(xùn)練權(quán)重也能通過隨機(jī)權(quán)重跑通流程但為了后續(xù)訓(xùn)練效果通常還是讓ultralytics自動(dòng)下載YOLOv8s預(yù)訓(xùn)練權(quán)重。這里注意訓(xùn)練階段不要急著用復(fù)雜的分布式配置單卡能跑通才是第一步。3.2 數(shù)據(jù)集目錄組織與配置編寫使用YOLO格式訓(xùn)練前需要把數(shù)據(jù)集按照固定目錄結(jié)構(gòu)組織起來。我最常用的結(jié)構(gòu)是這樣的dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── dataset.yaml其中images/train存放訓(xùn)練圖像labels/train存放對應(yīng)的YOLO標(biāo)簽txt文件文件名必須和圖像完全一致。驗(yàn)證集和測試集同理。此外還要寫一個(gè)dataset.yaml訓(xùn)練配置文件內(nèi)容大致如下path: /your/path/to/dataset train: images/train val: images/val test: images/test names: 0: raise_hand 1: stand 2: walk 3: read 4: write 5: phone 6: sleep 7: listen這里的names順序必須和標(biāo)簽txt里的類別編號嚴(yán)格一致。我在實(shí)際項(xiàng)目中見過一個(gè)很隱蔽的坑標(biāo)注時(shí)用的是另一套類別順序訓(xùn)練配置里沒對上模型輸出所有類別都錯(cuò)位比如把“睡覺”預(yù)測成“舉手”。排查半天才發(fā)現(xiàn)是names順序問題。所以拿到數(shù)據(jù)集后第一件事就是隨機(jī)打開幾個(gè)txt文件對照names確認(rèn)一下類別ID。3.3 訓(xùn)練超參數(shù)選擇與背后的考慮基本訓(xùn)練命令如下yolo detect train datadataset.yaml modelyolov8s.pt epochs100 imgsz640 batch16 device0 patience20這里我選擇yolov8s.pt作為預(yù)訓(xùn)練權(quán)重。為什么不選nanonano雖然更快內(nèi)存占用更小但在課堂小目標(biāo)場景下精度會(huì)明顯弱一些。為什么不直接上large因?yàn)?800張數(shù)據(jù)對于large模型來說容易過擬合而且訓(xùn)練速度和顯存需求都會(huì)變大。s版本是一個(gè)很好的平衡點(diǎn)先在s版本上跑通后續(xù)有需要再用蒸餾或者換大模型提升精度。imgsz640是YOLOv8默認(rèn)輸入尺寸。課堂場景下前排學(xué)生目標(biāo)較大640夠用后排學(xué)生目標(biāo)小如果發(fā)現(xiàn)漏檢嚴(yán)重可以把imgsz提高到960甚至1280代價(jià)是顯存占用和訓(xùn)練時(shí)間成倍增加。batch16取決于顯卡顯存8GB顯卡建議batch16配yolov8s如果OOM就降到8或者開啟梯度累積。patience20是早停參數(shù)連續(xù)20個(gè)epoch驗(yàn)證集指標(biāo)不提升就停止訓(xùn)練。這個(gè)參數(shù)能省時(shí)間但我不建議把它設(shè)太小因?yàn)槟繕?biāo)檢測的指標(biāo)有時(shí)會(huì)震蕩某兩個(gè)epoch沒漲不代表后面不漲。默認(rèn)20是一個(gè)比較穩(wěn)的值。YOLOv8默認(rèn)開啟了Mosaic、隨機(jī)翻轉(zhuǎn)、HSV擾動(dòng)等數(shù)據(jù)增強(qiáng)。課堂場景相對固定數(shù)據(jù)分布窄增強(qiáng)太強(qiáng)烈反而可能讓模型學(xué)到不真實(shí)的光影。如果訓(xùn)練時(shí)發(fā)現(xiàn)驗(yàn)證集指標(biāo)不升反降可以嘗試把Mosaic關(guān)閉或調(diào)低。比如在ultralytics配置里設(shè)置mosaic0.5并觀察效果。3.4 訓(xùn)練過程監(jiān)控與結(jié)果評估訓(xùn)練啟動(dòng)后不要傻等命令行輸出。官方會(huì)在訓(xùn)練目錄下生成results.csv里面記錄了每個(gè)epoch的loss、precision、recall、mAP50和mAP50-95。我會(huì)配合TensorBoard實(shí)時(shí)看曲線也可以直接讀取csv畫圖。關(guān)鍵監(jiān)控項(xiàng)有四個(gè)train_loss是否持續(xù)下降、val_loss是否出現(xiàn)回升、mAP50是否還在上升、precision和recall是否保持平衡。訓(xùn)練結(jié)束后模型會(huì)保存在runs/detect/train/weights/best.pt和last.pt。best.pt是驗(yàn)證集指標(biāo)最好的權(quán)重last.pt是最后一個(gè)epoch的權(quán)重部署通常用best.pt。用驗(yàn)證集評估yolo detect val datadataset.yaml modelruns/detect/train/weights/best.pt輸出里會(huì)看到每個(gè)類別的precision、recall、mAP50。我拿這套數(shù)據(jù)集做過一次模擬訓(xùn)練8個(gè)類別訓(xùn)練100個(gè)epoch最終mAP50大約在0.83到0.88之間mAP50-95大約0.58到0.65。其中“站立”和“行走”的精度通常偏低原因是這兩類樣本數(shù)量少、動(dòng)作本身姿態(tài)變化大。如果某個(gè)類別AP特別低就需要回到類別定義和樣本分布上找原因而不是一味加訓(xùn)練輪數(shù)。4. 常見問題與踩坑排查實(shí)錄4.1 標(biāo)注框偏移與類別錯(cuò)標(biāo)怎么發(fā)現(xiàn)訓(xùn)練效果差的時(shí)候很多人第一時(shí)間懷疑模型結(jié)構(gòu)或超參數(shù)但實(shí)際原因經(jīng)常是數(shù)據(jù)標(biāo)注有問題。我發(fā)現(xiàn)一個(gè)很高效的排查方式寫腳本掃描全部標(biāo)簽文件檢查坐標(biāo)是否越界、類別ID是否在合法范圍、每張圖是否有對應(yīng)標(biāo)簽文件。坐標(biāo)越界的情況最典型YOLO格式要求x_center,y_center,width,height都在0到1之間但標(biāo)注工具邊緣操作不當(dāng)會(huì)產(chǎn)生負(fù)數(shù)或大于1的值。下面這個(gè)腳本可以快速檢查常見標(biāo)注異常import os label_dir dataset/labels/train class_num 8 bad_files [] for fname in os.listdir(label_dir): if not fname.endswith(.txt): continue path os.path.join(label_dir, fname) with open(path, r) as f: lines f.read().strip().splitlines() for i, line in enumerate(lines): parts line.split() if len(parts) ! 5: bad_files.append((fname, i, field_num)) continue cls int(parts[0]) vals list(map(float, parts[1:])) if cls 0 or cls class_num: bad_files.append((fname, i, class_id)) if any(v 0 or v 1 for v in vals): bad_files.append((fname, i, coord_range)) print(bad files:, len(bad_files)) for item in bad_files[:20]: print(item)這個(gè)腳本解決的是格式問題但“框位置偏移”或“類別標(biāo)錯(cuò)”這類語義錯(cuò)誤腳本查不出來。我的辦法是隨機(jī)抽100張圖用OpenCV把標(biāo)注框畫回去人眼檢查。具體就是讀圖片按歸一化坐標(biāo)乘回寬高用不同顏色畫框并寫上類別名。這個(gè)操作建議在數(shù)據(jù)集交付后第一時(shí)間做別等訓(xùn)練完了才排查。4.2 類別不均衡導(dǎo)致漏檢怎么辦統(tǒng)計(jì)標(biāo)簽分布是訓(xùn)練前必須做的一步。拿這套課堂行為數(shù)據(jù)來說8個(gè)類別里“聽講”“閱讀”“寫字”通常很多而“站立”“行走”“玩手機(jī)”數(shù)量明顯少。這樣模型天然偏向多數(shù)類少數(shù)類很容易漏檢。我統(tǒng)計(jì)完分布后一般會(huì)看每個(gè)類別的目標(biāo)實(shí)例數(shù)如果某個(gè)類別少于總樣本的5%就要處理。處理手段有三種。第一種是針對少數(shù)類做重復(fù)采樣在訓(xùn)練時(shí)讓每個(gè)epoch包含更多少數(shù)類樣本但容易造成過擬合。第二種是復(fù)制粘貼增強(qiáng)把少數(shù)類的目標(biāo)實(shí)例單獨(dú)裁剪出來隨機(jī)粘貼到其他圖像上同時(shí)生成新的標(biāo)簽框。這個(gè)做法對“站立”“行走”這類目標(biāo)比較有效但對“玩手機(jī)”這種需要手部細(xì)節(jié)的動(dòng)作要小心粘貼位置不合適會(huì)很不自然。第三種是給少數(shù)類分配更高的損失權(quán)重讓模型在反向傳播時(shí)更關(guān)注這些類別。ultralytics沒有內(nèi)置的per-class weight參數(shù)但可以通過自定義數(shù)據(jù)集類或使用v8的class weights方案實(shí)現(xiàn)。我在實(shí)際項(xiàng)目中更推薦組合拳先盡量補(bǔ)充一些包含少數(shù)類行為的真實(shí)視頻幀再結(jié)合復(fù)制粘貼增強(qiáng)。數(shù)據(jù)補(bǔ)充方向明確后多數(shù)時(shí)候模型漏檢率能顯著下降。4.3 小目標(biāo)與嚴(yán)重遮擋的表現(xiàn)與優(yōu)化課堂場景里后排學(xué)生離攝像頭遠(yuǎn)目標(biāo)框很小前排學(xué)生之間還會(huì)互相遮擋。小目標(biāo)和遮擋是檢測模型最頭疼的兩個(gè)問題。小目標(biāo)方面最簡單有效的方法是提高輸入分辨率。從640提高到960后排人臉和手機(jī)區(qū)域的像素細(xì)節(jié)會(huì)明顯增加mAP50-95一般能提升2到3個(gè)點(diǎn)。代價(jià)是訓(xùn)練和推理耗時(shí)增加。如果顯卡資源緊張還有一個(gè)思路是采用基于切圖的推理方式把原圖切成重疊的子圖分別檢測再把結(jié)果合并。這種方法叫SAHI對密集小目標(biāo)很有效但推理時(shí)間會(huì)成倍增長一般用在離線分析上不適合實(shí)時(shí)課堂系統(tǒng)。遮擋方面人與人重疊時(shí)檢測框會(huì)互相干擾NMS閾值設(shè)置很關(guān)鍵。YOLOv8默認(rèn)NMS閾值是0.45如果發(fā)現(xiàn)兩個(gè)學(xué)生挨太近被合并成一個(gè)框可以適當(dāng)降低到0.4試試。也可以在推理階段使用WBF集成但操作復(fù)雜度高小項(xiàng)目不太推薦。我的建議是先從數(shù)據(jù)和分辨率兩個(gè)方向入手不要一上來就上復(fù)雜trick。因?yàn)檎n堂行為檢測的最終應(yīng)用往往不需要每幀都完美檢測每一人能保證大部分幀的正確性再通過時(shí)序平滑處理效果就能接受。4.4 硬件資源不足時(shí)如何調(diào)整很多學(xué)生或者個(gè)人開發(fā)者沒有高端顯卡只能拿筆記本訓(xùn)練。這套8800張的數(shù)據(jù)集如果用CPU訓(xùn)練一次100個(gè)epoch可能會(huì)跑到幾十個(gè)小時(shí)非常勸退。硬件不足時(shí)有幾個(gè)務(wù)實(shí)的調(diào)整方案。第一把模型換成yolov8n雖然精度略低但訓(xùn)練和推理速度都大幅提升。第二降低imgsz到480或416樣本量沒變但每張圖的計(jì)算量變小。第三調(diào)低batch到4甚至2同時(shí)把epochs增加到150靠更多迭代彌補(bǔ)單次batch的信息量不足。如果顯存特別小打開ultralytics的梯度累積功能也能模擬大batch效果。另外可以明顯減少訓(xùn)練時(shí)間的一個(gè)做法是先用一個(gè)較小的子集做10個(gè)epoch的試跑比如從8800張里抽500張訓(xùn)練、100張驗(yàn)證確認(rèn)代碼路徑、配置、類別都正確再全量訓(xùn)練。這樣即使硬件差也不會(huì)因?yàn)橐粋€(gè)低級錯(cuò)誤浪費(fèi)幾天時(shí)間。我每次拿到新數(shù)據(jù)集都會(huì)這樣先跑通再放大算是節(jié)省了非常多的時(shí)間。5. 從數(shù)據(jù)集到課堂落地的經(jīng)驗(yàn)總結(jié)5.1 模型部署時(shí)的性能與精度取舍訓(xùn)練好的YOLO模型要真正在課堂環(huán)境里用起來不能只在服務(wù)器上跑離線分析。如果教室現(xiàn)場部署邊緣設(shè)備比如Jetson系列或工控機(jī)配GPU建議把模型導(dǎo)出為TensorRT或OpenVINO格式推理速度和幀率會(huì)有明顯提升。YOLOv8官方已經(jīng)支持導(dǎo)出yolo export modelbest.pt formattensorrt halfTrue導(dǎo)出后模型會(huì)變成優(yōu)化過的引擎文件顯存占用降低推理延遲減少。但要注意TensorRT對GPU型號和驅(qū)動(dòng)版本敏感換了設(shè)備通常需要重新導(dǎo)出。在部署時(shí)還需要考慮置信度閾值一般設(shè)置在0.25到0.4之間。閾值太低誤檢多閾值太高漏檢多。課堂實(shí)時(shí)分析不需要每秒鐘都跑很多實(shí)際項(xiàng)目是每2到3秒抽一幀分析大大降低算力壓力同時(shí)行為統(tǒng)計(jì)也不會(huì)漏太多。5.2 數(shù)據(jù)迭代與持續(xù)標(biāo)注策略一套8800張的數(shù)據(jù)集很難一勞永逸。模型部署后我建議設(shè)計(jì)一個(gè)小閉環(huán)把推理置信度低、且預(yù)測框附近沒有高置信度目標(biāo)的圖自動(dòng)抽出來定期交給標(biāo)注員修正。這些“難樣本”往往正是當(dāng)前模型沒見過的場景可能是新教室的座位布局、新的光線條件或者學(xué)生穿了奇怪的服裝。補(bǔ)標(biāo)200到500張難樣本后重新訓(xùn)練效果常常比盲目加幾千張普通數(shù)據(jù)更明顯。另一個(gè)實(shí)用策略是結(jié)合目標(biāo)追蹤。課堂里每個(gè)學(xué)生在連續(xù)幀中位置變化較小可以用ByteTrack或DeepSORT這類跟蹤器為每個(gè)檢測框分配穩(wěn)定ID然后用ID層面的多數(shù)投票消掉單幀誤檢。比如某人在第3幀被識(shí)別為“站立”其他幀都是“閱讀”那這一幀大概率是誤檢。這種后處理能在不增加標(biāo)注成本的情況下提升行為統(tǒng)計(jì)的穩(wěn)定度。5.3 數(shù)據(jù)隱私與合規(guī)紅線說到課堂數(shù)據(jù)有一個(gè)問題必須專門提學(xué)生涉及的是未成年人人臉和姿態(tài)圖像都屬于敏感個(gè)人信息。在真實(shí)場景里使用這套數(shù)據(jù)集需要做好脫敏處理。最基礎(chǔ)的一步是做人臉模糊把畫面里的人臉區(qū)域模糊化后再進(jìn)入模型訓(xùn)練更進(jìn)一步可以只在邊緣設(shè)備上做本地推理只上傳結(jié)構(gòu)化統(tǒng)計(jì)結(jié)果不傳原始圖像。另外含有人臉等可識(shí)別信息的課堂數(shù)據(jù)集不應(yīng)在公開渠道隨意傳播。作為技術(shù)從業(yè)者我們要對數(shù)據(jù)來源和使用范圍保持清醒。在校內(nèi)做教學(xué)研究應(yīng)當(dāng)獲得學(xué)校和家長的知情同意并按照授權(quán)范圍使用。技術(shù)本身是為了輔助教學(xué)不是制造監(jiān)視恐慌。這個(gè)前提沒守住再好的模型也沒法落地。5.4 后續(xù)擴(kuò)展方向這套數(shù)據(jù)集的直接應(yīng)用是單幀目標(biāo)檢測但它完全可以作為更大行為分析系統(tǒng)的基礎(chǔ)層。比如可以對檢測框區(qū)域進(jìn)一步做人臉模糊、人體關(guān)鍵點(diǎn)提取然后輸入到LSTM、Transformer這類時(shí)序模型判斷“排隊(duì)回答問題”“小組討論”等更復(fù)雜的課堂活動(dòng)。還可以結(jié)合語音信息分析是否存在小組討論或教師提問后的集體回應(yīng)做到多模態(tài)課堂分析。從目標(biāo)檢測角度來看后續(xù)也可以嘗試把“小目標(biāo)檢測”“旋轉(zhuǎn)目標(biāo)檢測”等新方法和課堂場景結(jié)合。比如教室中的身體框通常是水平矩形但如果攝像頭是斜上方視角用旋轉(zhuǎn)框可能會(huì)更貼合人體姿態(tài)。不過這會(huì)增加標(biāo)注成本和算法復(fù)雜度需要評估實(shí)際收益。我的經(jīng)驗(yàn)是先跑通水平框方案再根據(jù)痛點(diǎn)決定是否升級。最后說一點(diǎn)個(gè)人體會(huì)我拿到這套數(shù)據(jù)時(shí)第一件事不是急著跑模型而是花了整整一天檢查標(biāo)簽、畫框、統(tǒng)計(jì)分布。當(dāng)時(shí)覺得浪費(fèi)時(shí)間但后來模型一次訓(xùn)練就能達(dá)到可用狀態(tài)省下的完全不止一天。對于目標(biāo)檢測項(xiàng)目數(shù)據(jù)和標(biāo)簽的干凈程度往往比換了多少個(gè)網(wǎng)絡(luò)結(jié)構(gòu)更影響最終效果。你想讓模型在課堂上看得準(zhǔn)先得把喂給它的“教材”校對好。本文還有配套的精品資源點(diǎn)擊獲取