深度学习视频行为识别实战:从SlowFast到OpenMMLab的完整指南
简介:这套深度学习视频行为识别项目(Mo-action-recognition-master)面向具备Python与深度学习基础的研究者和开发者,围绕视频中的人类行为检测与识别问题,提供了从数据预处理、时空特征建模、模型训练与评估到推理部署的完整参考流程。项目整合了多种主流网络结构,包括3D卷积、LSTM、GRU、ResNet、VGG等,并配有数据增强、光流处理、训练日志、验证脚本等模块,便于读者针对不同任务对比模型效果。压缩包共40个文件,其中38个Python源码文件承载模型定义、训练和评估逻辑,1个Markdown文档说明项目结构,1个Shell脚本可快速启动流程,整体仅41KB,轻量易读、便于二次开发。目前已有2428人学习下载,适合作为入门视频行为识别、开展算法实验、调整参数或进行迁移学习研究的代码库,能帮助理解从视频帧到动作标签的完整建模思路。 深度学习视频中的行为识别,这个话题我琢磨了很久,也踩了不少坑。从最早用OpenCV手工提取光流,到后来上手SlowFast、VideoSwin,再到给实际项目做推理加速,一路走过来发现这个方向的水确实深,但摸清楚套路之后,很多问题是有章可循的。这篇文章不打算写成教科书,而是把我实际做过的方案、调过的参数、趟过的坑,按一个完整项目的推进顺序梳理出来,给正在入门或者项目卡壳的朋友一份能直接“抄作业”的参考。
1. 行为识别的整体思路与方案选型
1.1 行为识别到底在解决什么问题
行为识别,通俗点说,就是让计算机“看懂”一段视频里的人在做什么。比如一个人从画面左边走到右边,这是不是跌倒;两个人靠近之后有没有发生肢体冲突;工人在产线上有没有按规定戴好安全帽并完成操作流程。这些任务都属于视频中的行为识别。
很多刚接触这个方向的人会把它和图像分类混在一起,觉得“不就是把每帧图片过一遍CNN嘛”。实际上完全不是一回事。行为识别天然带有时间维度,同样的动作,放到不同节奏、不同视角、不同遮挡条件下,特征差异非常大。举一个最直白的例子:一个人挥手的动作,如果只拿一帧静止画面给分类模型看,模型很难区分他是在打招呼还是在驱赶蚊虫,但放进一段连续视频里,时间序列上的运动轨迹就把语义变得清晰了。
这就引出了行为识别任务的核心难点:不仅要提取空间上的外观特征,还要建立时间上的运动关联。早期经典方法用的是手工设计的特征,比如用光流法计算相邻帧之间的像素运动场,再配合iDT(Improved Dense Trajectories)这类密集轨迹描述子,虽然在某些数据集上效果尚可,但泛化能力很弱。深度学习普及之后,这个领域被彻底重写,基于大规模数据驱动的端到端模型成了绝对主流。
1.2 为什么首选深度学习方法而非传统视觉方案
在项目立项初期,我专门花时间对比过传统视觉方案和深度学习方案的差异。传统方案的核心逻辑是“人工设计特征+分类器”,典型流程是:抽取关键点、计算光流、编码成特征描述子、送入SVM或随机森林分类。这套流程在动作种类少、场景固定、摄像头静止的条件下能跑通,但一遇到复杂背景或动作类间差异小的情况就歇菜了。
深度学习方案的核心优势在于特征是“学出来”的,不需要人去设计,尤其是大规模视频数据集预训练出来的模型,对视角变化、光照变化、部分遮挡都有更强的鲁棒性。实测下来,在相同数据集上,深度模型的精度通常能比传统特征方案高出20到30个百分点,同时推理阶段如果做得好,速度也能达到实时或者准实时。
另一个不容忽视的因素是生态成熟度。现阶段PyTorch、TensorFlow对视频模型的支持已经非常完善,OpenMMLab把常用的行为识别模型全打包好了,开箱即用。这一点对工程落地尤为重要,我不需要从零复现一篇论文,只要在成熟框架上做适配和调优就行。
1.3 技术路线图:从输入视频到输出动作标签
整体流程可以拆成下面五个环节:
- 视频解码与抽帧:把原始视频按固定帧率拆成图像序列,或者按时间段剪辑成短视频片段。
- 预处理与数据增强:对帧做resize、归一化、随机裁剪、水平翻转等操作,目的是增加数据多样性。
- 特征提取:用预训练的2D CNN或3D CNN对帧序列提取空间与时间特征。
- 时序建模:通过时序卷积、Transformer或者LSTM等结构,捕捉动作在时间维上的演变规律。
- 分类输出:把时序特征映射到具体的动作类别上,输出每个类别的置信度得分。
这个流程里,特征提取和时序建模是整个系统的核心,也是后续模型选型时要重点考量的部分。
2. 数据集构建与预处理细节
2.1 数据从哪来:公开数据集与自采数据的取舍
做行为识别,数据是第一道坎。公开数据集方面,Kinetics系列是绕不开的。Kinetics-400有大约30万段视频,覆盖400个动作类别,是目前预训练的主流选择。Something-Something系列则强调了人与物体的交互关系,类别设计更细粒度,例如“把东西从左边移到右边”这种动作。还有一个我经常用的UCF101,虽然规模不大,只有1.3万段视频、101个类别,但胜在下载快、标注质量高,非常适合做模型验证和基线测试。
不过公开数据集和实际业务场景之间通常存在明显差异。公开数据集里的动作大多是“干净的”,主体居中、背景简单,而实际业务中的视频往往画面杂乱、机位刁钻、目标小且存在多目标交叉。所以如果你的项目面向真实生产环境,建议采用“公开预训练+自采数据微调”的组合策略——先用Kinetics预训练模型初始化权重,再用自己标注的业务数据做迁移学习,这比纯靠自采数据从零训练高效得多。
2.2 视频抽帧:帧率、分辨率和片段长度的选择
视频不能直接塞进模型,必须先抽帧。抽帧参数直接影响模型效果和训练速度。
- 帧率:我常用的做法是抽到25到30帧每秒。过高的帧率会带来大量冗余帧,增加计算负担;过低的帧率会丢失运动细节,导致快速动作识别不准。
- 分辨率:综合考虑算力和信息量,短边resize到256像素是比较常见的选择。训练时再随机裁剪成224x224或256x256的块。
- 片段长度:这是影响最大的参数。比如SlowFast模型,通常取32帧或64帧作为输入,大约对应1到2秒的视频长度。行为识别里的典型做法是,训练时随机在视频里采样一个片段,推理时均匀采样多个片段做集成投票,能显著提升稳定性。
2.3 数据标注的工程化经验
标注是项目里最容易被低估的环节。我第一次做标注时直接在Excel里写视频名和标签,结果几百条之后就对不上了,后期清洗浪费了大量时间。
更合理的做法是用CVAT或者Label Studio这类开源标注工具。以CVAT为例,标注人员可以直接在时间轴上框出动作发生的起止帧,并打上行为类别,导出格式支持COCO、YOLO等多种标准。导出后还需要做一次数据校验,至少抽查10%的标注结果,计算标注人员之间的一致性(比如用Cohen's Kappa系数),低于0.7的标注批次建议退回重标。
注意:行为识别对时间边界的敏感度很高,起止帧标得不准,模型学到的就是错误的动作节奏。我建议标注规则明确写清楚“动作开始以肢体明显移动为标志,结束以肢体回归静止为标志”,并配上示例视频让标注人员对齐标准。
3. 核心模型选型与原理拆解
3.1 主流模型家族的演进脉络
行为识别模型大致经历了四个阶段,理解这条演进线对选型非常有帮助。
- 双流网络(Two-Stream CNN):分为空间流和时间流,空间流吃RGB帧,时间流吃堆叠的光流图,最后融合分类。优点是可解释性强,缺点是光流计算非常耗时,在线推理基本跑不动。
- 3D CNN系列:代表是C3D,后来I3D把2D卷积核扩展到3D,并在Kinetics上取得不错效果;接着SlowFast提出双帧率分支设计,慢路径捕捉空间语义,快路径捕捉运动变化。SlowFast在精度和计算量之间取得了不错的平衡,我在多个项目中都把它作为默认基线。
- 时序建模迁移方案:TSN和TSM。TSN的思路是稀疏采样多段视频,分别过2D CNN再融合,大幅降低计算量;TSM则是把部分通道沿时间维平移,用2D卷积模拟出3D卷积的效果,效率极高,非常适合边缘设备。
- Transformer架构:Video Swin Transformer把图像领域的Swin Transformer拓展到视频领域,使用了3D局部注意力,长程建模能力强,精度普遍高于同量级的CNN模型。在计算资源充裕的情况下,我会优先拿Video Swin做精度上限测试。
3.2 SlowFast核心原理与参数解读
这里挑SlowFast展开讲一下,因为它在整个生态里可以说是“性价比”标杆。核心思路是让网络同时观察事物的“静态内容”和“动态变化”:慢路径用小帧率(比如每秒2帧)全面分析画面细节;快路径用大帧率(比如每秒16帧)捕捉快速运动,但通道数更少,计算量不会爆炸。
慢路径和快路径之间通过侧向连接(lateral connection)融合信息,把运动特征注入到语义特征中。实际用OpenMMLab实现时,我就用默认的slowfast_r50,输入为32帧,训练时采样策略设为随机裁剪加随机翻转。在UCF101上微调后,top-1准确率可以做到92%以上,这个效果已经能覆盖不少业务场景了。
3.3 模型选型决策表
| 模型 | 输入规模 | 计算量 | 精度水平 | 适用场景 |
|---|---|---|---|---|
| TSM | 8帧 | 低 | 中 | 边缘设备、实时性优先 |
| SlowFast | 32帧+快路径 | 中高 | 高 | 服务器端、精度优先 |
| Video Swin | 32帧 | 高 | 很高 | 学术实验、算力充足 |
| TSN | 稀疏8段 | 低 | 中 | 快速原型验证 |
如果你手里只有一张消费级显卡,想快速看到效果,直接上TSM最现实。如果要做比赛冲精度,或者业务允许离线分析,那耐心调SlowFast和Video Swin会更值得。
4. 实操:基于OpenMMLab从零跑通一个行为识别模型
4.1 环境准备与依赖安装
我建议使用Linux系统配合Anaconda管理Python环境。Python版本选3.8或3.9,PyTorch选1.12以上。安装命令整理如下:
# 创建独立环境,避免依赖冲突
conda create -n mmaction2 python=3.9 -y
conda activate mmaction2
# 安装PyTorch(以CUDA 11.3为例)
conda install pytorch=1.12.1 torchvision=0.13.1 torchaudio=0.12.1 cudatoolkit=11.3 -c pytorch
# 安装MMCV和MMAction2
pip install mmcv-full -f https://download.openmmlab.com/mmcv/dist/cu113/torch1.12/index.html
pip install mmaction2
# 验证安装
python -c "import mmaction; print(mmaction.__version__)"
4.2 数据准备:从原始视频到训练格式
假设你的数据放在data/raw_videos/目录下,每段视频以动作类别作为子目录名。
第一步是整理成标准文件列表。每个视频对应一行,格式为“视频路径 帧数 类别编号 类别名”。如果不知道帧数,可以用OpenCV快速读取:
import cv2
import os
video_path = "data/raw_videos/falling/fall_001.mp4"
cap = cv2.VideoCapture(video_path)
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
cap.release()
print(f"帧数: {frame_count}")
第二步是修改mmaction2里的配置文件。一般需要改动这几个地方:数据集路径、类别数量、采样策略、模型路径、训练轮数和学习率。
4.3 训练与评估高效流程
以下是我用过多次、比较稳定的训练命令:
python tools/train.py configs/recognition/slowfast/slowfast_r50_8x8x1_256e_kinetics400_rgb.py \
--work-dir work_dirs/slowfast_ucf101
训练完会自动生成最好权重的checkpoint。评估命令如下:
python tools/test.py configs/recognition/slowfast/slowfast_r50_8x8x1_256e_kinetics400_rgb.py \
work_dirs/slowfast_ucf101/best_acc_top1_epoch_45.pth \
--eval top_k_accuracy
如果数据集较小,建议在配置文件里做两件事:第一,从Kinetics预训练权重加载初始化;第二,把分类层替换成自己的类别数,并降低初始学习率,设置为0.001乘以一个小系数。这样微调后收敛速度会快很多。
4.4 推理部署:把模型用起来
训练只是中点,推理部署才是项目价值的体现。我推荐两种部署路径:
- 在线实时场景:用ONNX Runtime或TensorRT做加速。先导出ONNX,再转TensorRT的engine文件,在NVIDIA平台上推理速度能比PyTorch原生快2到4倍。
- 离线分析场景:直接用PyTorch做batch推理,配合多线程流水线,也能达到不错的吞吐量。
一个实用的推理代码框架大致如下:
import torch
from mmaction.apis import init_recognizer, inference_recognizer
config = "configs/recognition/slowfast/slowfast_r50_8x8x1_256e_kinetics400_rgb.py"
checkpoint = "checkpoints/best_acc_top1_epoch_45.pth"
model = init_recognizer(config, checkpoint, device="cuda:0")
video_path = "data/test_videos/test_001.mp4"
result = inference_recognizer(model, video_path)
print(f"预测类别: {result['pred_class']}, 置信度: {result['pred_score']:.4f}")
5. 常见问题与排查技巧实录
5.1 模型过拟合到训练集上,验证集精度上不去
这是行为识别项目中最常见的问题。表现是训练loss一路降到很低,但验证集精度在某个点之后开始下降。原因通常有三个:数据集太小、数据增强不够、模型容量过大。
我的解决思路是:先减少模型规模,比如从SlowFast R50换成TSM;同时增加随机裁剪、水平翻转、ColorJitter等增强手段;最后加入早停机制,监控验证集loss,连续多个epoch不降就停止训练。
5.2 推理速度达不到实时要求
很多场景要求延迟在300毫秒以内。如果模型推理一次要1秒以上,首先检查输入帧数是否过高,试着从32帧降到16帧,精度损失可能只有1到2个点,速度却能翻倍。其次是输出端做异步处理,先缓存一小段视频,异步推理,避免阻塞采集流程。
另外,TensorRT的FP16精度模式可以在几乎不掉点的情况下获得明显加速,值得优先尝试。
5.3 类别不均衡怎么处理
如果某个动作出现频率特别低,模型很容易把它忽略。调整方法是:
- 在采样器里为少数类别设置更高的采样权重。
- 损失函数改用带权重的CrossEntropyLoss。
- 增强少数类别的数据增强强度,人工扩充样本。
5.4 动作边界错位导致识别错误
模型把一段视频从头到尾判成同一个动作,但实际场景里动作是连续变化的,比如“走路”之后紧接着“跌倒”。这时需要把模型切换为时序动作检测(Temporal Action Detection)方案,用类似BMN的结构先预测动作区间,再对区间内容做分类,而不是简单地对整段视频做分类。
6. 一些我踩过的坑和总结
代码层面,容易踩的第一个坑是数据加载和模型输入尺寸不匹配。视频帧尺寸如果不统一,很可能在训练中途报维度错误。建议在预处理流水线里统一resize到固定短边,并在配置里写死crop尺寸。
第二个坑是存储IO成为瓶颈。视频数据量大了以后,训练速度往往受制于硬盘读取而不是GPU算力。我把视频提前抽帧成JPEG图片并打包成LMDB格式后,训练速度提升了近3倍。如果你的数据还在机械硬盘上,建议直接换SSD,收益非常明显。
还有一个感受比较深的问题是“先跑通再调优”的节奏。很多初学者一上来就追求最先进的模型架构,结果环境配置一周都搞不定。我自己的经验是,先用最轻量的TSM跑通完整流程,哪怕精度一般,也能验证数据和代码管线的正确性,然后再逐步换更重的模型。这套思路帮我少走了很多弯路。
最后想说的是,行为识别这个方向虽然涉及不少基础理论,但工程落地路径已经相当清晰了。选一个好用的开源框架、准备一份高质量的数据、明确你的精度和速度目标,剩下的就是耐心迭代的事情。如果你正在做相关项目,建议先从公开数据集上跑通一个基线,再结合自己的业务数据做微调,这个路径投入产出比最高。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)