【人工智能学习之动作识别TSM训练与部署】

news2025/5/10 18:39:23

【人工智能学习之动作识别TSM训练与部署】

  • 基于MMAction2动作识别项目的开发
    • 一、MMAction2的安装
    • 二、数据集制作
    • 三、模型训练
      • 1. 配置文件准备
      • 2. 关键参数修改
      • 3. 启动训练
      • 4. 启动成功
  • ONNX模型部署方案
    • 一、环境准备
    • 二、执行转换命令

基于MMAction2动作识别项目的开发

一、MMAction2的安装

MMAction2 适用于 Linux、Windows 和 MacOS。

需要 Python 3.7+,CUDA 10.2+ 和 PyTorch 1.8+。

——————————————华丽的分割线—————————————————

第一步:从官方网站下载并安装 Miniconda。
第二步: 创建一个 conda 环境并激活它。

conda create --name openmmlab python=3.8 -y
conda activate openmmlab

第三步: 安装 PyTorch,按照官方说明进行操作。
第四步: 使用 MIM 安装依赖(其中MMDetection和 MMPose是可选的,非必须安装),注意MMCV需要根据前几步的版本进行选择安装版本。版本选择

在这里插入图片描述

pip install -U openmim
mim install mmengine
mim install mmcv
mim install mmdet
mim install mmpose

第五步:从源代码构建 MMAction2。

git clone https://github.com/open-mmlab/mmaction2.git
cd mmaction2
pip install -v -e .
# "-v" 表示输出更多安装相关的信息
# "-e" 表示以可编辑形式安装,这样可以在不重新安装的情况下,让本地修改直接生效。

第六步:验证 MMAction2 是否安装正确。
1.下载配置文件和权重文件

mim download mmaction2 --config tsn_imagenet-pretrained-r50_8xb32-1x1x8-100e_kinetics400-rgb --dest .

2.验证推理演示

# demo.mp4 和 label_map_k400.txt 都来自于 Kinetics-400
python demo/demo.py tsn_imagenet-pretrained-r50_8xb32-1x1x8-100e_kinetics400-rgb.py \
    tsn_imagenet-pretrained-r50_8xb32-1x1x8-100e_kinetics400-rgb_20220906-2692d16c.pth \
    demo/demo.mp4 tools/data/kinetics/label_map_k400.txt

如果在终端看到前5个标签及其对应的分数则已经安装成功。

二、数据集制作

  1. RawFrameDataset格式的原始帧注释

    • 数据目录结构:

      dataset_root/
      ├── rawframes/
      │   ├── train/
      │   │   ├── video1/
      │   │   │   ├── img_00001.jpg
      │   │   │   └── ...
      │   └── val/
      ├── annotations/
      │   ├── train.txt
      │   └── val.txt
      
    • 标注文件格式示例:

      video1 150 0
      video2 180 1
      

      原始帧数据集的注释是一个包含多行的文本文件,每一行表示一个视频的 frame_directory(相对路径)、视频的 total_frames 和视频的 label,用空格分隔。以上是一个示例。
      这里分享我的俩个脚本,用于抽帧和标注:
      抽帧脚本:

      import os
      import cv2
      
      
      def extract_frames(video_path, output_dir):
          cap = cv2.VideoCapture(video_path)
          if not cap.isOpened():
              print(f"无法打开视频文件: {video_path}")
              return
          frame_count = 0
          while True:
              ret, frame = cap.read()
              if not ret:
                  break
              frame_name = f"img_{frame_count + 1:05d}.jpg"
              frame_path = os.path.join(output_dir, frame_name)
              cv2.imwrite(frame_path, frame)
              frame_count += 1
          cap.release()
      
      
      def process_videos(root_dir):
          for sub_dir in os.listdir(root_dir):
              sub_dir_path = os.path.join(root_dir, sub_dir)
              if os.path.isdir(sub_dir_path):
                  for video_file in os.listdir(sub_dir_path):
                      if video_file.endswith('.mp4'):
                          video_path = os.path.join(sub_dir_path, video_file)
                          video_name = os.path.splitext(video_file)[0]
                          output_dir = os.path.join(sub_dir_path, video_name)
                          if not os.path.exists(output_dir):
                              os.makedirs(output_dir)
                          extract_frames(video_path, output_dir)
      
      
      if __name__ == "__main__":
          root_directory = r'C:\WorkFiles\company_server_SSH\fight\TSM\dataset\dataset'  # 这里可以修改为你的一级目录路径
          process_videos(root_directory)
      
      

      标注脚本:

      import os
      
      
      def count_images_and_save(root_dir, output_file):
          results = []
          for root, dirs, files in os.walk(root_dir):
              # 若当前目录没有子目录,就认定为末级目录
              if not dirs:
                  jpg_files = [f for f in files if f.lower().endswith('.jpg')]
                  image_count = len(jpg_files)
                  # 把上级目录名当作标签
                  label = os.path.basename(os.path.dirname(root))
                  # 仅保留从 train 开始的相对路径
                  relative_path = os.path.relpath(root, start=os.path.dirname(root_dir))
                  results.append(f"{relative_path} {image_count} {label}")
      
          with open(output_file, 'w') as f:
              for line in results:
                  f.write(line + '\n')
      
      
      if __name__ == "__main__":
          root_directory = r'C:\WorkFiles\company_server_SSH\fight\TSM\dataset\dataset\images\val'  # 替换成你的根目录
          output_txt_file = 'val_videofolder.txt'  # 替换成你想要的输出文件名
          count_images_and_save(root_directory, output_txt_file)
          print(f"结果已保存到 {output_txt_file}")
      
      
  2. VideoDataset格式的视频注释

    • 数据目录结构:

      dataset_root/
      ├── videos/
      │   ├── video1.mp4
      │   └── video2.avi
      ├── annotations/
      │   ├── train.txt
      │   └── val.txt
      
    • 执行格式转换:

      python tools/data/build_rawframes.py [原始视频路径] [输出路径] --ext mp4
      
    • 标注文件格式示例:

      some/path/000.mp4 1
      some/path/001.mp4 1
      some/path/002.mp4 2
      

      视频数据集的注释是一个包含多行的文本文件,每一行表示一个样本视频,包括 filepath(相对路径)和 label,用空格分隔。以上是一个示例。

      通常,我会将相同分类的视频放在同一个文件夹中,并将分类序号作为文件夹名称,通过脚本直接生成标注文件。

      具体操作如下:在这里插入图片描述
      脚本如下:

      import os
      
      
      def generate_video_labels(root_dir, output_file):
          with open(output_file, 'w') as f:
              for root, dirs, files in os.walk(root_dir):
                  for file in files:
                      if file.lower().endswith(('.mp4', '.avi', '.mov', '.mkv')):
                          label = os.path.basename(root)
                          file_path = os.path.join(root, file)
                          relative_path = os.path.relpath(file_path, root_dir)
                          f.write(f"{relative_path} {label}\n")
      
      
      if __name__ == "__main__":
          root_directory = r'C:\WorkFiles\dataset\fight\dataset'
          output_txt = 'video_labels.txt'
          generate_video_labels(root_directory, output_txt)
      
      

      在这里插入图片描述

三、模型训练

1. 配置文件准备

本项目选择的是TSM模型,读者可以根据自己的需求选择其他模型。

先复制一份构建模型训练的配置文件,并将其重命名。这里我们复制到configs目录下以免后面找不到。

cp mmaction2/configs/recognition/tsm/tsm_r50_1x1x8_50e_kinetics400_rgb.py configs/my_tsm.py

2. 关键参数修改

打开我们的配置文件,首先需要修改我们的数据集配置:

# 数据集配置
# dataset settings
 data_root = '/home/OpenMMLAB/mmaction2/fight/dataset/'
 data_root_val = '/home/OpenMMLAB/mmaction2/fight/dataset/'
 ann_file_train = '/home/OpenMMLAB/mmaction2/fight/dataset/video_labels_train.txt'
 ann_file_val = '/home/OpenMMLAB/mmaction2/fight/dataset/video_labels_val.txt'

其次,我们还需要对模型进行修改分类输出:

# model settings
		model = dict(
		    cls_head=dict(
		        type='TSMHead',
		        num_classes=6  # 将 400 修改为 101
		        ))

其他的训练策略看个人情况,我没有做训练器等其他方面的修改。

3. 启动训练

接下来通过命令启动训练:

python tools/train.py configs/my_tsm.py \
    --seed=0 \
    --deterministic \
    --validate \
    --work-dir work_dirs/my_tsm

脚本完整用法:

 python tools/train.py ${CONFIG_FILE} [ARGS]
参数描述
CONFIG_FILE配置文件的路径。
–work-dir WORK_DIR保存日志和权重的目标文件夹。默认为与配置文件相同名称的文件夹,位于 ./work_dirs 下。
–resume [RESUME]恢复训练。如果指定了路径,则从该路径恢复,如果未指定,则尝试从最新的权重自动恢复。
–amp启用自动混合精度训练。
–no-validate不建议使用。在训练期间禁用权重评估。
–auto-scale-lr根据实际批次大小和原始批次大小自动缩放学习率。
–seed随机种子。
–diff-rank-seed是否为不同的 rank 设置不同的种子。
–deterministic是否为 CUDNN 后端设置确定性选项。
–cfg-options CFG_OPTIONS覆盖使用的配置中的某些设置,xxx=yyy 格式的键值对将合并到配置文件中。如果要覆盖的值是一个列表,则应采用 key=“[a,b]” 或 key=a,b 的形式。该参数还允许嵌套的列表/元组值,例如 key=“[(a,b),(c,d)]”。请注意,引号是必需的,且不允许有空格。
–launcher {none,pytorch,slurm,mpi}作业启动器的选项。默认为 none。

注意:默认情况下,MMAction2 更倾向于使用 GPU 而不是 CPU 进行训练。如果您想在 CPU 上训练模型,请清空 CUDA_VISIBLE_DEVICES 或将其设置为 -1 以使 GPU 对程序不可见。

CUDA_VISIBLE_DEVICES=-1 python tools/train.py ${CONFIG_FILE} [ARGS]

当然,也可以使用多卡训练,官方提供了一个 shell 脚本使用torch.distributed.launch 来启动多个 GPU 的训练任务。

bash tools/dist_train.sh ${CONFIG} ${GPUS} [PY_ARGS]
参数描述
CONFIG_FILE配置文件的路径。
GPUS要使用的 GPU 数量。
[PYARGS]tools/train.py 的其他可选参数。

4. 启动成功

开始输出loss则标志模型开始训练了。
在这里插入图片描述
最后训练完成会得到:
在这里插入图片描述
top1达到best并不意味着top5也是best。
我们根据自己的需求选择其中表现最好的即可。

ONNX模型部署方案

一、环境准备

先决条件
为了进行端到端的模型部署,MMDeploy 需要 Python 3.6+ 和 PyTorch 1.8+。

——————————————华丽的分割线—————————————————
第一步:从官方网站下载并安装 Miniconda。
第二步:创建 conda 环境并激活它,也可以直接使用我们之前创建的openmmlab
第三步:按照官方说明安装 PyTorch(如果没装的话)
第四步:安装mmcv和mmengine,如果是之前创建的环境在已有mmengine和mmcv的基础上,我们只需要安装mmdeploy即可。
第五步:下载Github最新版MMDeploy

git clone https://github.com/open-mmlab/mmdeploy.git --recursive
cd mmdeploy

第六步:根据需求安装对应依赖,engine或onnx,这里我安装的onnx部署环境

# 1. install MMDeploy model converter
pip install mmdeploy==1.3.1

# 2. install MMDeploy sdk inference
# you can install one to install according whether you need gpu inference
# 2.1 support onnxruntime
pip install mmdeploy-runtime==1.3.1
# 2.2 support onnxruntime-gpu, tensorrt
pip install mmdeploy-runtime-gpu==1.3.1

# 3. install inference engine
# 3.1 install TensorRT
# !!! If you want to convert a tensorrt model or inference with tensorrt,
# download TensorRT-8.2.3.0 CUDA 11.x tar package from NVIDIA, and extract it to the current directory
pip install TensorRT-8.2.3.0/python/tensorrt-8.2.3.0-cp38-none-linux_x86_64.whl
pip install pycuda
export TENSORRT_DIR=$(pwd)/TensorRT-8.2.3.0
export LD_LIBRARY_PATH=${TENSORRT_DIR}/lib:$LD_LIBRARY_PATH
# !!! Moreover, download cuDNN 8.2.1 CUDA 11.x tar package from NVIDIA, and extract it to the current directory
export CUDNN_DIR=$(pwd)/cuda
export LD_LIBRARY_PATH=$CUDNN_DIR/lib64:$LD_LIBRARY_PATH

# 3.2 install ONNX Runtime
# you can install one to install according whether you need gpu inference
# 3.2.1 onnxruntime
wget https://github.com/microsoft/onnxruntime/releases/download/v1.8.1/onnxruntime-linux-x64-1.8.1.tgz
tar -zxvf onnxruntime-linux-x64-1.8.1.tgz
export ONNXRUNTIME_DIR=$(pwd)/onnxruntime-linux-x64-1.8.1
export LD_LIBRARY_PATH=$ONNXRUNTIME_DIR/lib:$LD_LIBRARY_PATH
# 3.2.2 onnxruntime-gpu
pip install onnxruntime-gpu==1.8.1
wget https://github.com/microsoft/onnxruntime/releases/download/v1.8.1/onnxruntime-linux-x64-gpu-1.8.1.tgz
tar -zxvf onnxruntime-linux-x64-gpu-1.8.1.tgz
export ONNXRUNTIME_DIR=$(pwd)/onnxruntime-linux-x64-gpu-1.8.1
export LD_LIBRARY_PATH=$ONNXRUNTIME_DIR/lib:$LD_LIBRARY_PATH

二、执行转换命令

通过命令我们就得到了着四个文件,分别为onnx和三个json:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2372531.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

sqli-labs靶场18-22关(http头)

目录 less18(user-agent) less19(referer) less20(cookie) less21(cookie) less22(cookie) less18(user-agent) 这里尝试了多次…

Android系统架构模式分析

本文系统梳理Android系统架构模式的演进路径与设计哲学,希望能够借此探索未来系统的发展方向。有想法的同学可以留言讨论。 1 Android层次化架构体系 1.1 整体分层架构 Android系统采用五层垂直架构,各层之间通过严格接口定义实现解耦: 应用…

Web前端VSCode如何解决打开html页面中文乱码的问题(方法2)

Web前端—VSCode如何解决打开html页面中文乱码的问题(方法2) 1.打开VScode后,依次点击 文件 >> 首选项 >> 设置 2.打开设置后,依次点击 文本编辑器 >> 文件(或在搜索框直接搜索“files.autoGuessEnc…

单调栈模版型题目(3)

单调栈型题目贡献法 基本模版 这是数组a中的 首先我们要明白什么叫做贡献,在一个数组b{1,3,5}中,连续包含1的连续子数组为{1},{1,3},{1,3,5},一共有三个,这三个数一共能组成6个连续子数组,而其…

ts axios中报 Property ‘code‘ does not exist on type ‘AxiosResponse<any, any>‘

ts语法有严格的格式,如果我们在处理响应数据时,出现了axios响应中非默认字段,就会出现标题那样的警告,我们可以通过创建axios.dt.ts解决这个问题 下面是我在开发中遇到的警告,code并不是axios默认返回的字段&#xff0…

[AI Tools] Dify 工具插件上传指南:如何将插件发布到官方市场

Dify 作为开源的 LLM 应用开发平台,不仅支持本地化插件开发,也提供了插件市场机制,让开发者能够将自己构建的插件发布并供他人使用。本文将详细介绍如何将你开发的 Dify Tools 插件上传至官方插件市场,包括 README 编写、插件打包、仓库 PR 等核心步骤。 一、准备 README 文…

用react实现一个简单的三页应用

下面是一个使用 React Router 的简单示例,演示了如何在 React 应用中实现页面之间的导航。 🛠️ 第一步:使用 Vite 创建项目 npm create vitelatest my-router-app -- --template react cd my-router-app npm install🚀 第二步&a…

Go使用Gin写一个对MySQL的增删改查服务

首先用SQL创建一个包含id、name属性的users表 create table users (id int auto_incrementprimary key,name varchar(255) null );查询所有用户信息: func queryData(db *sql.DB, w http.ResponseWriter) {rows, err : db.Query("SELECT * FROM users"…

Xcode16.3配置越狱开发环境

首先先在https://developer.apple.com/xcode/resources/ 这里面登陆Apple账号,然后访问url下载 https://download.developer.apple.com/Developer_Tools/Xcode_16.3/Xcode_16.3.xip 1、安装theos https://theos.dev/docs/installation-macos 会安装到默认位置~/th…

SCADA|KIO程序导出变量错误处理办法

哈喽,你好啊,我是雷工! 最近在用KingSCADA3.52版本的软件做程序时,在导出变量进行批量操作时遇到问题,现将解决办法记录如下。 以下为解决过程。 01 问题描述 在导出KIO变量时,选择*.xls格式和*.xlsx时均会报错: 报如下错误: Unknown error 0x800A0E7A ADODB Connectio…

【漫话机器学习系列】249.Word2Vec自然语言训练模型

【自然语言处理】用 Word2Vec 将词语映射到向量空间详解 一、背景介绍 在自然语言处理(NLP)领域,我们常常需要将文本信息转化为机器能够理解和处理的形式。传统的方法,如 one-hot编码,虽然简单,但存在严重…

云轴科技ZStack入选赛迪顾问2025AI Infra平台市场发展报告代表厂商

DeepSeek凭借低成本、高性能、开源优势带来的蝴蝶效应依然在持续影响企业AI应用部署。尤其在数据安全备受关注的背景下,私有化部署已经成为企业应用AI大模型的优选方案。赛迪顾问在近期发布的《2025中国AI Infra平台市场发展研究报告》中认为,在推理算力…

安达发|人力、机器、物料——APS排程软件如何实现资源最优配置?

引言:制造业资源优化的核心挑战 在现代制造业中,人力、机器、物料是生产运营的三大核心资源。如何让这些资源高效协同,避免浪费,是企业降本增效的关键。然而,许多制造企业仍面临以下问题: 人力安排不合理…

【软件测试】软件缺陷(Bug)的详细描述

目录 一、软件缺陷(Bug) 1.1 缺陷的判定标准 1.2 缺陷的生命周期 1.3 软件缺陷的描述 1.3.1 提交缺陷的要素 1.3.2 Bug 的级别 1.4 如何发现更多的 Bug? 1.5 缺陷的有效管理 1.5.1 缺陷的编写 1.5.2 缺陷管理工具 1.5.2.1 缺陷管理 1.5.2.2 用例管理 一、软件缺陷…

HTTP传输大文件的方法、连接管理以及重定向

目录 1. HTTP传输大文件的方法 1.1. 数据压缩 1.2. 分块传输 1.3. 范围请求 1.4. 多段数据 2. HTTP的连接管理 2.1. 短连接 2.2. 长连接 2.3. 队头阻塞 3. HTTP的重定向和跳转 3.1. 重定向的过程 3.2. 重定向状态码 3.3. 重定向的应用场景 3.4. 重定向的相关问题…

图像来源:基于协同推理的双视角超声造影分类隐式数据增强方法|文献速递-深度学习医疗AI最新文献

Title 题目 Image by co-reasoning: A collaborative reasoning-based implicit data augmentation method for dual-view CEUS classification 图像来源:基于协同推理的双视角超声造影分类隐式数据增强方法 01 文献速递介绍 结合了B型超声(BUS&…

dotnet core c#调用Linux c++导出函数

1.声明C++导出函数 platform_export.h // // Created by dev on 5/6/25. //#ifndef PLATFORM_EXPORT_H #define PLATFORM_EXPORT_H #if defined(_WIN32)#ifdef LIB_EXPORTS#define LIB_API __declspec(dllimport)#else#define LIB_API __declspec(dllimport)#endif #else#ifde…

宁德时代区块链+数字孪生专利解析:去中心化身份认证重构产业安全底座

引言:当动力电池巨头瞄准数字孪生安全 2025年5月6日,金融界披露宁德时代未来能源(上海)研究院与母公司宁德时代新能源科技股份有限公司联合申请的一项关键专利——“身份验证方法、系统、电子设备及存储介质”。这项技术将区块链…

1.微服务概念

1.单体、分布式、集群 先理解单体、集群、分布式这些概念 1.单体 一个系统业务量很小的时候,所有的代码都放在一个项目中,然后这个项目部署在一台服务器上就好了。整个项目所有的服务都由这台服务器提供。这就是单机结构. 1.1 优点 单体应用开发简单,部署测试简单 …

基于SSM实现的健身房系统功能实现八

一、前言介绍: 1.1 项目摘要 随着社会的快速发展和人们健康意识的不断提升,健身行业也在迅速扩展。越来越多的人加入到健身行列,健身房的数量也在不断增加。这种趋势使得健身房的管理变得越来越复杂,传统的手工或部分自动化的管…