PoseClassificationNet
PoseClassificationNet 接受骨骼(身体姿势)序列作为网络输入,并预测这些帧中一个或多个人的动作。当前版本中支持的模型基于空间-时间图卷积网络 (ST-GCN),由于其简单性和计算效率,它是基于骨骼的动作识别最常用的基线。与基于像素的动作识别不同,ST-GCN 能够利用人体骨骼空间-时间图中的局部模式和相关性。此模型可通过迁移学习用于训练图卷积网络 (GCN),以实现其他目的。未来将发布具有最先进性能的更新架构。TAO 为 3D 姿势提供网络主干。
PoseClassificationNet 需要骨骼(身体姿势)序列作为输入。坐标需要归一化。例如,3D 关节是相对于根关键点(即骨盆)生成的,并按焦距(1080P 为 1200.0)归一化。数据集转换的入口点基于 deepstream-bodypose-3d 应用程序的输出 JSON 元数据生成时空序列数组。
用于训练或推理的输入数据格式为五维 NumPy 数组 (N, C, T, V, M)
N
:序列数C
:输入通道数,在 NGC 模型中设置为 3T
:帧中的最大序列长度,在 NGC 模型中为 300(30 FPS 为 10 秒)V
:关节点的数量,对于 NVIDIA 格式设置为 34M
:人数。预训练模型假定为单个对象,但也支持多人
模型推理的输出是一个 N
元素的数组,其中给出了每个序列的预测动作类别。
用于训练或评估的标签存储为 pickle 文件,其中包含两个列表的列表,每个列表包含 N
个元素。第一个列表包含 N
个样本名称的字符串。第二个列表包含每个序列的标记动作类别 ID。以下是一个示例
[["xl6vmD0XBS0.json", "OkLnSMGCWSw.json", "IBopZFDKfYk.json", "HpoFylcrYT4.json", "mlAtn_zi0bY.json", ...], [235, 388, 326, 306, 105, ...]]
用于建模骨骼的图由两个配置参数定义
graph_layout
(字符串):必须是以下候选者之一graph_strategy
(字符串):必须是以下候选者之一(有关更多信息,请参阅 本文 中的“分区策略”部分)uniform
:统一标记distance
:距离分区spatial
:空间配置
PoseClassificationNet 的规范文件包括 model
、dataset
和 train
参数。以下是在 NVIDIA 数据集上训练基于 3D 姿势的模型的示例规范。它包含六个类别:“sitting_down”、“getting_up”、“sitting”、“standing”、“walking”、“jumping”
model:
model_type: ST-GCN
pretrained_model_path: "/path/to/pretrained_model.pth"
input_channels: 3
dropout: 0.5
graph_layout: "nvidia"
graph_strategy: "spatial"
edge_importance_weighting: True
dataset:
train_dataset:
data_path: "/path/to/train_data.npy"
label_path: "/path/to/train_label.pkl"
val_dataset:
data_path: "/path/to/val_data.npy"
label_path: "/path/to/val_label.pkl"
num_classes: 6
label_map:
sitting_down: 0
getting_up: 1
sitting: 2
standing: 3
walking: 4
jumping: 5
batch_size: 16
num_workers: 1
train:
optim:
lr: 0.1
momentum: 0.9
nesterov: True
weight_decay: 0.0001
lr_scheduler: "MultiStep"
lr_steps:
- 10
- 60
lr_decay: 0.1
num_epochs: 10
checkpoint_interval: 5
validation_interval: 5
seed: 1234
参数 | 数据类型 | 默认值 | 描述 | 支持的值 |
model |
dict 配置 | – | 模型架构的配置 | |
dataset |
dict 配置 | – | 数据集的配置 | |
train |
dict 配置 | – | 训练任务的配置 | |
evaluate |
dict 配置 | – | 评估任务的配置 | |
inference |
dict 配置 | – | 推理任务的配置 | |
encryption_key |
字符串 | 无 | 用于加密和解密模型文件的加密密钥 | |
results_dir |
字符串 | /results | 保存实验结果的目录 | |
export |
dict 配置 | – | ONNX 导出任务的配置 | |
gen_trt_engine |
dict 配置 | – | TensorRT 生成任务的配置。仅在 TAO 部署中使用 |
model
model
参数提供用于更改 PoseClassificationNet 架构的选项。
model:
model_type: ST-GCN
pretrained_model_path: "/path/to/pretrained_model.pth"
input_channels: 3
dropout: 0.5
graph_layout: "nvidia"
graph_strategy: "spatial"
edge_importance_weighting: True
参数 | 数据类型 | 默认值 | 描述 | 支持的值 |
model_type |
字符串 | ST-GCN | 模型类型,目前只能是 ST-GCN。未来将支持更新的架构。 | ST-GCN |
pretrained_model_path |
字符串 | 预训练模型的路径 | ||
input_channels |
无符号整数 | 3 | 输入通道数(身体姿势的维度) | >0 |
dropout |
浮点数 | 0.5 | 丢弃隐藏单元的概率 | 0.0 ~ 1.0 |
graph_layout |
字符串 | nvidia | 用于建模骨骼的图的布局。可以是 nvidia、openpose、human3.6m、ntu-rgb+d、ntu_edge 或 coco。 | nvidia/openpose/human3.6m/ntu-rgb+d/ntu_edge/coco |
graph_strategy |
字符串 | spatial | 用于建模骨骼的图的策略。可以是 uniform、distance 或 spatial。 | uniform/distance/spatial |
edge_importance_weighting |
布尔值 | True | 指定是否启用边缘重要性加权 | True/False |
dataset
dataset
参数定义数据集来源、训练批次大小和增强。
dataset:
train_dataset:
data_path: "/path/to/train_data.npy"
label_path: "/path/to/train_label.pkl"
val_dataset:
data_path: "/path/to/val_data.npy"
label_path: "/path/to/val_label.pkl"
num_classes: 6
label_map:
sitting_down: 0
getting_up: 1
sitting: 2
standing: 3
walking: 4
jumping: 5
batch_size: 16
num_workers: 1
参数 | 数据类型 | 默认值 | 描述 | 支持的值 |
train_dataset |
dict | 训练的 NumPy 数组中数据的 data_path 和 pickle 文件中标签的 label_path | ||
val_dataset |
dict | 验证的 NumPy 数组中数据的 data_path 和 pickle 文件中标签的 label_path | ||
num_classes |
无符号整数 | 6 | 动作类别的数量 | >0 |
label_map |
dict | 将类名称映射到索引的 dict | ||
random_choose |
布尔值 | False | 指定是否随机选择输入序列的一部分。 | True/False |
random_move |
布尔值 | False | 指定是否随机移动输入序列。 | True/False |
window_size |
无符号整数 | -1 | 输出序列的长度。值为 -1 指定原始长度。 | |
batch_size |
无符号整数 | 64 | 训练和验证的批次大小 | >0 |
num_workers |
无符号整数 | 1 | 并行处理数据的工作人员数量 | >0 |
输入布局为 NCTVM
,其中 N
是批次大小,C
是输入通道数,T
是序列长度,V
是关键点数量,M
是人数。
train
train
参数定义训练过程的超参数。
train:
optim:
lr: 0.1
momentum: 0.9
nesterov: True
weight_decay: 0.0001
lr_scheduler: "MultiStep"
lr_steps:
- 10
- 60
lr_decay: 0.1
num_epochs: 10
checkpoint_interval: 5
validation_interval: 5
seed: 1234
参数 | 数据类型 | 默认值 | 描述 | 支持的值 |
num_gpus |
无符号整数 | 1 | 用于分布式训练的 GPU 数量 | >0 |
gpu_ids |
List[int] | [0] | 用于分布式训练的 GPU 索引 | |
seed |
无符号整数 | 1234 | 用于 random、NumPy 和 torch 的随机种子 | >0 |
num_epochs |
无符号整数 | 10 | 运行实验的总 epoch 数 | >0 |
checkpoint_interval |
无符号整数 | 1 | 保存检查点的 epoch 间隔 | >0 |
validation_interval |
无符号整数 | 1 | 运行验证的 epoch 间隔 | >0 |
resume_training_checkpoint_path |
字符串 | 从中恢复训练的中间 PyTorch Lightning 检查点 | ||
results_dir |
字符串 | /results/train | 用于保存训练结果的目录 | |
optim |
dict 配置 | SGD 优化器的配置,包括学习率、学习率调度器、权重衰减等。 | ||
grad_clip |
浮点数 | 0.0 | 按 L2 范数裁剪梯度的量。值为 0.0 指定不裁剪。 | >=0 |
optim
optim
参数定义训练中 SGD 优化器的配置,包括学习率、学习率调度器和权重衰减。
optim:
lr: 0.1
momentum: 0.9
nesterov: True
weight_decay: 0.0001
lr_scheduler: "MultiStep"
lr_steps:
- 10
- 60
lr_decay: 0.1
参数 |
数据类型 |
默认值 |
描述 |
支持的值 |
---|---|---|---|---|
lr |
浮点数 | 0.1 | 训练的初始学习率 | >0.0 |
momentum |
浮点数 | 0.9 | SGD 优化器的动量 | >0.0 |
nesterov |
布尔值 | True | 指定是否启用 Nesterov 动量。 | True/False |
weight_decay |
浮点数 | 1e-4 | 权重衰减系数 | >0.0 |
|
字符串 |
MultiStep |
学习率调度器。提供了两个调度器 |
MultiStep/AutoReduce |
lr_monitor |
字符串 | val_loss | AutoReduce 调度器的监视器值 |
val_loss/train_loss |
patience |
无符号整数 | 1 | 在没有改进的情况下 epoch 的数量,之后学习率将降低 | >0 |
min_lr |
浮点数 | 1e-4 | 训练中的最小学习率 | >0.0 |
lr_steps |
int 列表 | [10, 60] | 降低 MultiStep 调度器的学习率的步长 |
int 列表 |
lr_decay |
浮点数 | 0.1 | 学习率调度器的递减因子 | >0.0 |
使用以下命令运行 PoseClassificationNet 训练
tao model pose_classification train [-h] -e <experiment_spec>
[results_dir=<global_results_dir>]
[model.<model_option>=<model_option_value>]
[dataset.<dataset_option>=<dataset_option_value>]
[train.<train_option>=<train_option_value>]
[train.gpu_ids=<gpu indices>]
[train.num_gpus=<number of gpus>]
必需参数
唯一必需的参数是实验规范的路径
-e, --experiment_spec
:用于设置训练实验的实验规范文件
可选参数
您可以设置可选参数以覆盖实验规范文件中的选项值。
-h, --help
:显示此帮助消息并退出。model.<model_option>
:模型选项。dataset.<dataset_option>
:数据集选项。train.<train_option>
:训练选项。train.optim.<optim_option>
:优化器选项
对于训练、评估和推理,我们为每个各自的任务公开 2 个变量:num_gpus
和 gpu_ids
,默认值分别为 1
和 [0]
。如果两者都已传递,但不一致,例如 num_gpus = 1
,gpu_ids = [0, 1]
,则会修改它们以遵循具有更多 GPU 的设置,例如 num_gpus = 1 -> num_gpus = 2
。
检查点和恢复训练
在每个 train.checkpoint_interval
,都会保存 PyTorch Lightning 检查点。它被称为 model_epoch_<epoch_num>.pth
。它们保存在 train.results_dir
中,如下所示
$ ls /results/train
'model_epoch_000.pth'
'model_epoch_001.pth'
'model_epoch_002.pth'
'model_epoch_003.pth'
'model_epoch_004.pth'
最新的检查点保存为 pc_model_latest.pth
。如果 pc_model_latest.pth
存在于 train.results_dir
中,则训练会自动从它恢复。如果提供了 train.resume_training_checkpoint_path
,它将被 train.resume_training_checkpoint_path
取代。
此逻辑的主要含义是,如果您希望从头开始触发全新训练,请执行以下操作之一:
指定新的空结果目录(推荐)
从结果目录中删除最新的检查点
预训练模型并非旨在用不同维度的输入数据重新训练。ST-GCN
是一个轻量级网络,利用预训练模型通常不会显着影响最终准确性。
PoseClassificationNet 的评估指标是动作识别的准确率。
使用以下命令运行 PoseClassificationNet 评估
tao model pose_classification evaluate [-h] -e <experiment_spec_file>
evaluate.checkpoint=<model to be evaluated>
evaluate.test_dataset.data_path=<path to test data>
evaluate.test_dataset.label_path=<path to test labels>
[evaluate.<evaluate_option>=<evaluate_option_value>]
[evaluate.gpu_ids=<gpu indices>]
[evaluate.num_gpus=<number of gpus>]
Pose Classification 目前不支持多 GPU 评估。
必需参数
-e, --experiment_spec
:用于设置评估实验的实验规范文件。evaluate.checkpoint
:要评估的.pth
模型。evaluate.test_dataset.data_path
:测试数据的路径。evaluate.test_dataset.label_path
:测试标签的路径。
可选参数
evaluate.gpu_ids
:运行评估的 GPU 索引。默认为[0]
。evaluate.num_gpus
:运行评估的 GPU 数量。默认为1
。evaluate.results_dir
:用于保存评估结果的目录。默认为/results/evaluate
。
使用以下命令在 PoseClassificationNet 上运行推理。
tao model pose_classification inference [-h] -e <experiment_spec>
inference.checkpoint=<inference model>
inference.output_file=<path to output file>
inference.test_dataset.data_path=<path to inference data>
[inference.<infer_option>=<infer_option_value>]
[inference.gpu_ids=<gpu indices>]
[inference.num_gpus=<number of gpus>]
输出将是一个文本文件,其中每行对应于输入序列的预测动作类别。
Pose Classification 目前不支持多 GPU 推理。
必需参数
-e, --experiment_spec
:用于设置推理实验的实验规范文件。inference.checkpoint
:要进行推理的.pth
模型。inference.output_file
:输出文本文件的路径。inference.test_dataset.data_path
:测试数据的路径。
可选参数
inference.gpu_ids
:运行推理的 GPU 索引。默认为[0]
。inference.num_gpus
:运行推理的 GPU 数量。默认为1
。inference.results_dir
:用于保存推理结果的目录。默认为/results/inference
。
NVIDIA 测试数据的预期输出如下
sit
sit
sit_down
...
使用以下命令将 PoseClassificationNet 导出为 .onnx
格式以进行部署
tao model pose_classification export -e <experiment_spec>
export.checkpoint=<tlt checkpoint to be exported>
export.onnx_file=<path to exported file>
[export.gpu_id=<gpu index>]
必需参数
-e, --experiment_spec
:实验规范文件的路径。export.checkpoint
:要导出的.pth
模型。export.onnx_file
:保存.etlt
或.onnx
模型的路径。
可选参数
export.gpu_id
:用于运行导出的 GPU 索引。如果机器有多个 GPU,您可以指定用于运行导出的 GPU 索引。请注意,导出只能在单个 GPU 上运行。
使用以下命令转换来自 deepstream-bodypose-3d 应用程序的输出 JSON 元数据,并生成用于推理的身体姿势时空序列
tao model pose_classification dataset_convert -e <experiment_spec>
dataset_convert.data=<path to deepstream-bodypose-3d output data>
[dataset_convert.pose_type=<pose type>]
[dataset_convert.num_joints=<number of joints>]
[dataset_convert.input_width=<input width>]
[dataset_convert.input_height=<input height>]
[dataset_convert.focal_length=<focal length>]
[dataset_convert.sequence_length_max=<maximum sequence length>]
[dataset_convert.sequence_length_min=<minimum sequence length>]
[dataset_convert.sequence_length=<sequence length for sampling>]
[dataset_convert.sequence_overlap=<sequence overlap for sampling>]
必需参数
-e, --experiment_spec
:用于设置数据集转换的实验规范文件dataset_convert.data
:来自 deepstream-bodypose-3d 应用程序的输出 JSON 数据
可选参数
dataset_convert.results_dir
:应该写入实验输出的文件夹的路径dataset_convert.pose_type
:可以从 3dbp、25dbp、2dbp 中选择姿势类型dataset_convert.num_joints
:图布局中关节点的数量dataset_convert.input_width
:像素中输入图像的宽度,用于归一化dataset_convert.input_height
:像素中输入图像的高度,用于归一化dataset_convert.focal_length
:用于归一化的相机焦距dataset_convert.sequence_length_max
:用于定义数组形状的最大序列长度dataset_convert.sequence_length_min
:用于过滤短序列的最小序列长度dataset_convert.sequence_length
:用于采样的常规序列长度dataset_convert.sequence_overlap
:采样序列之间的重叠
预期的输出将是针对每个单独跟踪的 ID 采样的数组,该数组保存在结果目录下。
您可以在边缘设备(如 Jetson Xavier、Jetson Nano、Tesla)或云端(使用 NVIDIA GPU)上部署训练好的深度学习和计算机视觉模型。导出的 \*.onnx
模型可以在 TAO Triton 应用程序中使用。
在 Triton 示例上运行 PoseClassificationNet 推理
TAO Triton 应用程序为姿势分类提供了一个推理示例。它消耗 TensorRT 引擎,并支持使用 (1) 骨骼序列的 NumPy 数组或 (2) 来自 deepstream-bodypose-3d 应用程序的输出 JSON 元数据运行。
要使用此示例,您需要使用 trtexec
从 \*.onnx
模型生成 TensorRT 引擎,这在下一节中介绍。
使用 trtexec
生成 TensorRT 引擎
有关使用 trtexec
命令生成 TensorRT 引擎的说明,请参阅 PoseClassificationNet 的 trtexec 指南。
运行 Triton 推理示例
您可以在启动 Triton 服务器时使用以下命令生成 TensorRT 引擎
bash scripts/start_server.sh
当服务器运行时,您可以使用以下命令从客户端获取带有测试数据 NumPy 数组的结果
python tao_client.py <path_to_test_data> \
-m pose_classification_tao model \
-x 1 \
-b 1 \
--mode Pose_classification \
-i https \
-u localhost:8000 \
--async \
--output_path <path_to_output_directory>
服务器对输入测试数据执行推理。结果保存为文本文件,其中每行的格式为 [sequence_index], [rank1_pred_score]([rank1_class_index])=[rank1_class_name], [rank2_pred_score]([rank2_class_index])=[rank2_class_name], ..., [rankN_pred_score]([rankN_class_index])=[rankN_class_name]
。NVIDIA 测试数据的预期输出如下
0, 27.6388(2)=sitting, 12.0806(3)=standing, 7.0409(1)=getting_up, -3.4164(0)=sitting_down, -16.4449(4)=walking, -26.9046(5)=jumping
1, 21.5809(2)=sitting, 8.4994(3)=standing, 5.1917(1)=getting_up, -2.3813(0)=sitting_down, -12.4322(4)=walking, -20.4436(5)=jumping
2, 5.6206(0)=sitting_down, 4.7264(4)=walking, -1.0996(5)=jumping, -2.3501(1)=getting_up, -3.2933(3)=standing, -3.5337(2)=sitting
....
您还可以使用以下命令从 deepstream-bodypose-3d 应用程序的 JSON 输出中获取推理结果
python tao_client.py <path_to_json_file> \
--dataset_convert_config ../dataset_convert_specs/dataset_convert_config_pose_classification.yaml \
-m pose_classification_tao model \
-x 1 \
-b 1 \
--mode Pose_classification \
-i https \
-u localhost:8000 \
--async \
--output_path <path_to_output_directory>
- 服务器对输入 JSON 文件执行推理。结果也保存为 JSON
文件,该文件遵循与输入相同的格式,并在每帧的每个对象中添加预测的
"action"
。JSON 输出的示例如下[ ..., { "batches": [{ "batch_id": 0, "frame_num": 120, "ntp_timestamp": 1651865934597373000, "objects": [{ "action": "sitting", "bbox": [1058.529785, 566.782471, 223.130005, 341.585083], "object_id": 3, "pose25d": [1179.673828, 815.848633, -8.2e-05, 0.48291, 219.287964, 814.737305, -0.016891, 0.357422,...], "pose3d": [692.748474, 869.897461, 3784.238281, 0.48291, 815.966187, 864.584229, 3776.338867, 0.357422,...] }, { "action": "standing", "bbox": [1652.608154, 29.364517, 151.506958, 285.322723], "object_id": 5, "pose25d": [1730.824219, 166.724609, -0.000231, 0.827148, 1745.931641, 171.605469, -0.092529, 0.803711,...], "pose3d": [4327.349121, -2095.539795, 6736.708984, 0.827148, 4384.155762, -2055.012207, 6693.950195, 0.803711,...] },... ] }], "num_frames_in_batch": 1 },... ]
每个对象的骨骼序列都由数据集转换器分成多个段(请参阅下图)。sequence_length
和 sequence_overlap
可在 dataset_convert_config_pose_classification.yaml
中配置。输出标签在一段时间后分配给帧。

使用 Triton 的端到端推理
在 TAO Triton 应用程序中还提供了视频端到端推理的示例。该示例运行 deepstream-bodypose-3d 以生成边界框、跟踪 ID 和以 JSON 格式保存的 2D/3D 姿势的元数据。客户端隐式地将元数据转换为骨骼序列数组,并将它们发送到 Triton 服务器。每个序列的预测动作都会返回并附加到相应帧的 JSON 元数据中。还会生成带有叠加元数据的视频以进行可视化。
您可以使用以下命令启动 Triton 服务器(仅 Pose Classification 模型将被下载并转换为 TensorRT 引擎)
bash scripts/pose_cls_e2e_inference/start_server.sh
Triton 服务器启动后,打开另一个终端并运行以下命令,开始使用 DeepStream 进行身体姿势估计,并使用您之前启动的 Triton 服务器实例在 DeepStream 输出上运行 Pose Classification
bash scripts/pose_cls_e2e_inference/start_client.sh