1. 项目背景与核心目标
在计算机视觉领域,动作识别技术正逐渐成为研究热点。PoseC3D作为基于骨骼点的三维卷积网络,通过分析人体关键点的时空变化来识别动作类别,在健身指导、安防监控、人机交互等场景展现出巨大潜力。与传统的RGB视频分析方法相比,骨骼点数据具有背景无关、计算量小的优势,特别适合移动端和边缘设备部署。
这个项目的核心目标是从零开始构建自定义动作数据集,并完整走通PoseC3D模型的训练流程。不同于直接使用公开数据集(如NTU-RGB+D或Kinetics),自建数据集能更好地适配特定业务场景的需求。比如针对康复训练中的特定动作,或是工业生产中的标准操作流程,都需要定制化的数据支持。
2. 环境配置与数据准备
2.1 开发环境搭建
推荐使用Python 3.8+和PyTorch 1.8+的组合,这是经过验证的稳定版本。MMAction2框架作为PoseC3D的官方实现,需要额外安装:
pip install mmcv-full==1.6.0 -f https://download.openmmlab.com/mmcv/dist/cu111/torch1.8.0/index.html pip install mmaction2==0.24.1对于GPU加速,建议使用CUDA 11.1及以上版本。环境验证可以通过以下命令进行:
import torch, mmaction print(torch.__version__, torch.cuda.is_available()) print(mmaction.__version__)2.2 数据采集规范
构建高质量动作数据集需要注意以下要点:
- 动作类别设计:每个类别至少包含20个样本,确保类间差异明显。例如"挥手"和"鼓掌"容易混淆,需设计区分度更大的动作
- 拍摄标准:
- 使用1080p以上分辨率相机
- 固定相机位置避免抖动
- 保证拍摄对象全身入镜
- 每个动作持续3-5秒(约90-150帧)
- 人员多样性:不同身高、体型的人员参与采集,增强模型泛化能力
2.3 骨骼点提取与标注
使用MMPose或OpenPose提取2D关键点坐标,推荐采用COCO格式的17个关键点。对于时序数据,需要按视频帧顺序保存为如下结构的pkl文件:
{ "keypoint": np.array([ # 形状为(N,17,3) [[x1,y1,score1], [x2,y2,score2], ...], # 第1帧 [[x1,y1,score1], [x2,y2,score2], ...], # 第2帧 ... ]), "label": int, # 动作类别ID "total_frames": int # 总帧数 }关键提示:骨骼点置信度score低于0.3时建议视为无效点,可通过插值或均值填充处理缺失数据
3. 模型训练全流程
3.1 配置文件定制
复制configs/skeleton/posec3d/slowonly_r50_u48_240e_gym_keypoint.py为基础模板,主要修改以下参数:
dataset_type = 'PoseDataset' ann_file_train = 'data/custom/train.pkl' # 训练集路径 ann_file_val = 'data/custom/val.pkl' # 验证集路径 # 关键修改点 train_pipeline = [ dict(type='UniformSampleFrames', clip_len=48), # 根据实际动作时长调整 dict(type='PoseDecode'), dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), dict(type='Resize', scale=(-1, 64)), # 输入尺寸 dict(type='RandomRot', degree=10), # 数据增强参数 dict(type='FormatShape', input_format='NCTHW'), dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), dict(type='ToTensor', keys=['imgs', 'label']) ] data = dict( videos_per_gpu=16, # 根据GPU显存调整(batch_size) workers_per_gpu=2, train=dict( type=dataset_type, ann_file=ann_file_train, pipeline=train_pipeline), val=dict( type=dataset_type, ann_file=ann_file_val, pipeline=val_pipeline) )3.2 启动训练任务
单卡训练命令示例:
python tools/train.py configs/custom/posec3d_custom.py \ --work-dir work_dirs/posec3d_custom \ --validate --seed 42 --deterministic多卡分布式训练(以4卡为例):
./tools/dist_train.sh configs/custom/posec3d_custom.py 4 \ --work-dir work_dirs/posec3d_custom \ --validate --seed 42 --deterministic关键参数说明:
--validate:每轮训练后执行验证集评估--seed:固定随机种子保证可复现性--deterministic:启用确定性算法模式
3.3 训练过程监控
通过TensorBoard可以实时观察指标变化:
tensorboard --logdir work_dirs/posec3d_custom --port 6006重点关注以下曲线:
- 训练损失:应呈现平稳下降趋势
- 验证准确率:正常情况应逐步上升并最终收敛
- 学习率:检查是否符合预设的衰减策略
4. 常见问题与解决方案
4.1 显存不足处理
当出现CUDA out of memory错误时,可通过以下方式缓解:
- 减小
videos_per_gpu(最直接有效) - 使用梯度累积(修改配置):
optimizer_config = dict(grad_clip=None, cumulative_iters=4) - 降低输入分辨率(调整Resize的scale参数)
4.2 过拟合应对策略
若验证集准确率明显低于训练集,建议:
- 增加数据增强强度(如将
RandomRot角度范围扩大到20度) - 添加Dropout层(修改模型配置):
model = dict( backbone=dict(dropout_ratio=0.5), cls_head=dict(dropout_ratio=0.5) ) - 使用早停法(Early Stopping),当验证指标连续5轮不提升时终止训练
4.3 关键点噪声处理
对于质量较差的骨骼点数据,可在数据预处理阶段加入滤波:
train_pipeline = [ ... dict(type='GaussianFilter', sigma=1.5), # 高斯平滑 dict(type='PoseNormalize', mean='data/custom/mean.pkl', std='data/custom/std.pkl'), ... ]5. 模型评估与优化
5.1 性能测试
使用最佳检查点进行测试:
python tools/test.py configs/custom/posec3d_custom.py \ work_dirs/posec3d_custom/best_top1_acc_epoch_50.pth \ --eval top_k_accuracy mean_class_accuracy \ --out result.pkl输出结果包含:
top1_acc:最可能类别的准确率top5_acc:前五可能类别的准确率mean_class_accuracy:各类别准确率的平均值(应对类别不平衡)
5.2 模型轻量化
针对端侧部署的需求,可通过以下方式压缩模型:
- 知识蒸馏:使用大模型指导小模型训练
model = dict( type='PoseRecognizer3D', backbone=..., cls_head=dict( type='DistillHead', teacher_config='configs/posec3d_large.py', teacher_ckpt='large_model.pth', alpha=0.5 ) ) - 通道剪枝:使用MMRazor工具包减少卷积通道数
- 量化部署:转换为INT8格式(需TensorRT支持)
5.3 实际应用建议
- 实时性优化:
- 将48帧的clip_len缩减至32甚至16帧
- 采用滑动窗口重叠采样提升检测连续性
- 多模态融合:
model = dict( type='MultiModalRecognizer', rgb_stream=dict(...), # RGB分支 pose_stream=dict(...), # 骨骼点分支 fusion_head=dict(type='LateFusionHead') ) - 持续学习:通过mmaction2的
--resume-from参数实现增量训练