From 4d290ec7139c0858aebc81a7a7eb7ce8d564e899 Mon Sep 17 00:00:00 2001 From: Haodong Duan Date: Sat, 2 Apr 2022 22:15:54 +0800 Subject: [PATCH] Initial Commit --- .github/workflows/lint.yml | 27 + .gitignore | 141 +++ .pre-commit-config.yaml | 38 + LICENSE | 203 ++++ README.md | 47 + configs/posec3d/README.md | 118 ++ configs/posec3d/c3d_light_gym/joint.py | 73 ++ configs/posec3d/c3d_light_gym/limb.py | 80 ++ configs/posec3d/c3d_light_ntu60_xsub/joint.py | 73 ++ configs/posec3d/c3d_light_ntu60_xsub/limb.py | 79 ++ configs/posec3d/slowonly_r50_gym/joint.py | 79 ++ configs/posec3d/slowonly_r50_gym/limb.py | 86 ++ .../slowonly_r50_hmdb51_k400p/s1_joint.py | 81 ++ .../posec3d/slowonly_r50_ntu120_xset/joint.py | 79 ++ .../posec3d/slowonly_r50_ntu120_xset/limb.py | 85 ++ .../posec3d/slowonly_r50_ntu120_xsub/joint.py | 85 ++ .../posec3d/slowonly_r50_ntu120_xsub/limb.py | 91 ++ .../posec3d/slowonly_r50_ntu60_xsub/joint.py | 79 ++ .../posec3d/slowonly_r50_ntu60_xsub/limb.py | 85 ++ .../posec3d/slowonly_r50_ntu60_xview/joint.py | 79 ++ .../posec3d/slowonly_r50_ntu60_xview/limb.py | 85 ++ .../slowonly_r50_ucf101_k400p/s1_joint.py | 81 ++ configs/posec3d/x3d_shallow_gym/joint.py | 77 ++ configs/posec3d/x3d_shallow_gym/limb.py | 84 ++ .../posec3d/x3d_shallow_ntu60_xsub/joint.py | 77 ++ .../posec3d/x3d_shallow_ntu60_xsub/limb.py | 83 ++ configs/stgcn++/README.md | 55 + configs/stgcn++/stgcn++_ntu120_xset_3dkp/b.py | 63 ++ .../stgcn++/stgcn++_ntu120_xset_3dkp/bm.py | 63 ++ configs/stgcn++/stgcn++_ntu120_xset_3dkp/j.py | 63 ++ .../stgcn++/stgcn++_ntu120_xset_3dkp/jm.py | 63 ++ .../stgcn++/stgcn++_ntu120_xset_hrnet/b.py | 63 ++ .../stgcn++/stgcn++_ntu120_xset_hrnet/bm.py | 63 ++ .../stgcn++/stgcn++_ntu120_xset_hrnet/j.py | 63 ++ .../stgcn++/stgcn++_ntu120_xset_hrnet/jm.py | 63 ++ configs/stgcn++/stgcn++_ntu120_xsub_3dkp/b.py | 63 ++ .../stgcn++/stgcn++_ntu120_xsub_3dkp/bm.py | 63 ++ configs/stgcn++/stgcn++_ntu120_xsub_3dkp/j.py | 63 ++ .../stgcn++/stgcn++_ntu120_xsub_3dkp/jm.py | 63 ++ .../stgcn++/stgcn++_ntu120_xsub_hrnet/b.py | 63 ++ .../stgcn++/stgcn++_ntu120_xsub_hrnet/bm.py | 63 ++ .../stgcn++/stgcn++_ntu120_xsub_hrnet/j.py | 63 ++ .../stgcn++/stgcn++_ntu120_xsub_hrnet/jm.py | 63 ++ configs/stgcn++/stgcn++_ntu60_xsub_3dkp/b.py | 63 ++ configs/stgcn++/stgcn++_ntu60_xsub_3dkp/bm.py | 63 ++ configs/stgcn++/stgcn++_ntu60_xsub_3dkp/j.py | 63 ++ configs/stgcn++/stgcn++_ntu60_xsub_3dkp/jm.py | 63 ++ configs/stgcn++/stgcn++_ntu60_xsub_hrnet/b.py | 63 ++ .../stgcn++/stgcn++_ntu60_xsub_hrnet/bm.py | 63 ++ configs/stgcn++/stgcn++_ntu60_xsub_hrnet/j.py | 63 ++ .../stgcn++/stgcn++_ntu60_xsub_hrnet/jm.py | 63 ++ configs/stgcn++/stgcn++_ntu60_xview_3dkp/b.py | 63 ++ .../stgcn++/stgcn++_ntu60_xview_3dkp/bm.py | 63 ++ configs/stgcn++/stgcn++_ntu60_xview_3dkp/j.py | 63 ++ .../stgcn++/stgcn++_ntu60_xview_3dkp/jm.py | 63 ++ .../stgcn++/stgcn++_ntu60_xview_hrnet/b.py | 63 ++ .../stgcn++/stgcn++_ntu60_xview_hrnet/bm.py | 63 ++ .../stgcn++/stgcn++_ntu60_xview_hrnet/j.py | 63 ++ .../stgcn++/stgcn++_ntu60_xview_hrnet/jm.py | 63 ++ configs/stgcn/README.md | 66 ++ .../stgcn/stgcn_pyskl_ntu120_xset_3dkp/b.py | 60 + .../stgcn/stgcn_pyskl_ntu120_xset_3dkp/bm.py | 60 + .../stgcn/stgcn_pyskl_ntu120_xset_3dkp/j.py | 60 + .../stgcn/stgcn_pyskl_ntu120_xset_3dkp/jm.py | 60 + .../stgcn/stgcn_pyskl_ntu120_xset_hrnet/b.py | 60 + .../stgcn/stgcn_pyskl_ntu120_xset_hrnet/bm.py | 60 + .../stgcn/stgcn_pyskl_ntu120_xset_hrnet/j.py | 60 + .../stgcn/stgcn_pyskl_ntu120_xset_hrnet/jm.py | 60 + .../stgcn/stgcn_pyskl_ntu120_xsub_3dkp/b.py | 60 + .../stgcn/stgcn_pyskl_ntu120_xsub_3dkp/bm.py | 60 + .../stgcn/stgcn_pyskl_ntu120_xsub_3dkp/j.py | 60 + .../stgcn/stgcn_pyskl_ntu120_xsub_3dkp/jm.py | 60 + .../stgcn/stgcn_pyskl_ntu120_xsub_hrnet/b.py | 60 + .../stgcn/stgcn_pyskl_ntu120_xsub_hrnet/bm.py | 60 + .../stgcn/stgcn_pyskl_ntu120_xsub_hrnet/j.py | 60 + .../stgcn/stgcn_pyskl_ntu120_xsub_hrnet/jm.py | 60 + .../stgcn/stgcn_pyskl_ntu60_xsub_3dkp/b.py | 60 + .../stgcn/stgcn_pyskl_ntu60_xsub_3dkp/bm.py | 60 + .../stgcn/stgcn_pyskl_ntu60_xsub_3dkp/j.py | 60 + .../stgcn/stgcn_pyskl_ntu60_xsub_3dkp/jm.py | 60 + .../stgcn/stgcn_pyskl_ntu60_xsub_hrnet/b.py | 60 + .../stgcn/stgcn_pyskl_ntu60_xsub_hrnet/bm.py | 60 + .../stgcn/stgcn_pyskl_ntu60_xsub_hrnet/j.py | 60 + .../stgcn/stgcn_pyskl_ntu60_xsub_hrnet/jm.py | 60 + .../stgcn/stgcn_pyskl_ntu60_xview_3dkp/b.py | 60 + .../stgcn/stgcn_pyskl_ntu60_xview_3dkp/bm.py | 60 + .../stgcn/stgcn_pyskl_ntu60_xview_3dkp/j.py | 60 + .../stgcn/stgcn_pyskl_ntu60_xview_3dkp/jm.py | 60 + .../stgcn/stgcn_pyskl_ntu60_xview_hrnet/b.py | 60 + .../stgcn/stgcn_pyskl_ntu60_xview_hrnet/bm.py | 60 + .../stgcn/stgcn_pyskl_ntu60_xview_hrnet/j.py | 60 + .../stgcn/stgcn_pyskl_ntu60_xview_hrnet/jm.py | 60 + .../stgcn/stgcn_vanilla_ntu60_xsub_3dkp/b.py | 43 + .../stgcn/stgcn_vanilla_ntu60_xsub_3dkp/bm.py | 43 + .../stgcn/stgcn_vanilla_ntu60_xsub_3dkp/j.py | 43 + .../stgcn/stgcn_vanilla_ntu60_xsub_3dkp/jm.py | 43 + .../stgcn/stgcn_vanilla_ntu60_xsub_hrnet/b.py | 43 + .../stgcn_vanilla_ntu60_xsub_hrnet/bm.py | 43 + .../stgcn/stgcn_vanilla_ntu60_xsub_hrnet/j.py | 43 + .../stgcn_vanilla_ntu60_xsub_hrnet/jm.py | 43 + .../stgcn/stgcn_vanilla_ntu60_xview_3dkp/b.py | 43 + .../stgcn_vanilla_ntu60_xview_3dkp/bm.py | 43 + .../stgcn/stgcn_vanilla_ntu60_xview_3dkp/j.py | 43 + .../stgcn_vanilla_ntu60_xview_3dkp/jm.py | 43 + .../stgcn_vanilla_ntu60_xview_hrnet/b.py | 43 + .../stgcn_vanilla_ntu60_xview_hrnet/bm.py | 43 + .../stgcn_vanilla_ntu60_xview_hrnet/j.py | 43 + .../stgcn_vanilla_ntu60_xview_hrnet/jm.py | 43 + demo/demo_posec3d.py | 255 +++++ demo/faster_rcnn_r50_fpn_2x_coco.py | 181 +++ demo/hrnet_w32_coco_256x192.py | 172 +++ demo/ntu_sample.avi | Bin 0 -> 1119546 bytes demo/vis_skeleton.ipynb | 113 ++ demo/visualize_heatmap_volume.ipynb | 403 +++++++ pyskl/__init__.py | 16 + pyskl/apis/__init__.py | 10 + pyskl/apis/inference.py | 182 +++ pyskl/apis/train.py | 215 ++++ pyskl/core/__init__.py | 3 + pyskl/core/evaluation.py | 191 ++++ pyskl/core/hooks.py | 68 ++ pyskl/datasets/__init__.py | 11 + pyskl/datasets/base.py | 308 +++++ pyskl/datasets/builder.py | 124 ++ pyskl/datasets/dataset_wrappers.py | 73 ++ pyskl/datasets/pipelines/__init__.py | 8 + pyskl/datasets/pipelines/augmentations.py | 1004 +++++++++++++++++ pyskl/datasets/pipelines/compose.py | 53 + pyskl/datasets/pipelines/formatting.py | 234 ++++ pyskl/datasets/pipelines/loading.py | 166 +++ pyskl/datasets/pipelines/pose_related.py | 354 ++++++ pyskl/datasets/pipelines/posec3d_related.py | 259 +++++ pyskl/datasets/pipelines/sampling.py | 384 +++++++ pyskl/datasets/pose_dataset.py | 108 ++ pyskl/datasets/samplers/__init__.py | 4 + .../datasets/samplers/distributed_sampler.py | 112 ++ pyskl/datasets/video_dataset.py | 60 + pyskl/models/__init__.py | 7 + pyskl/models/builder.py | 38 + pyskl/models/cnns/__init__.py | 11 + pyskl/models/cnns/c3d.py | 98 ++ pyskl/models/cnns/resnet.py | 477 ++++++++ pyskl/models/cnns/resnet3d.py | 625 ++++++++++ pyskl/models/cnns/resnet3d_slowfast.py | 327 ++++++ pyskl/models/cnns/resnet3d_slowonly.py | 17 + pyskl/models/cnns/x3d.py | 503 +++++++++ pyskl/models/gcns/__init__.py | 4 + pyskl/models/gcns/stgcn.py | 145 +++ pyskl/models/gcns/utils/__init__.py | 4 + pyskl/models/gcns/utils/gcn.py | 79 ++ pyskl/models/gcns/utils/tcn.py | 105 ++ pyskl/models/heads/__init__.py | 4 + pyskl/models/heads/base.py | 88 ++ pyskl/models/heads/simple_head.py | 156 +++ pyskl/models/losses/__init__.py | 5 + pyskl/models/losses/base.py | 45 + pyskl/models/losses/cross_entropy_loss.py | 121 ++ pyskl/models/recognizers/__init__.py | 6 + pyskl/models/recognizers/base.py | 196 ++++ pyskl/models/recognizers/recognizer2d.py | 58 + pyskl/models/recognizers/recognizer3d.py | 85 ++ pyskl/models/recognizers/recognizergcn.py | 96 ++ pyskl/smp.py | 105 ++ pyskl/utils/__init__.py | 9 + pyskl/utils/collect_env.py | 17 + pyskl/utils/graph.py | 149 +++ pyskl/utils/misc.py | 48 + pyskl/utils/visualize.py | 143 +++ pyskl/version.py | 18 + requirements.txt | 10 + setup.cfg | 24 + setup.py | 127 +++ tools/data_list.md | 59 + tools/dist_test.sh | 11 + tools/dist_train.sh | 10 + tools/slurm_test.sh | 24 + tools/slurm_train.sh | 24 + tools/test.py | 221 ++++ tools/train.py | 178 +++ 179 files changed, 16488 insertions(+) create mode 100644 .github/workflows/lint.yml create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 configs/posec3d/README.md create mode 100644 configs/posec3d/c3d_light_gym/joint.py create mode 100644 configs/posec3d/c3d_light_gym/limb.py create mode 100644 configs/posec3d/c3d_light_ntu60_xsub/joint.py create mode 100644 configs/posec3d/c3d_light_ntu60_xsub/limb.py create mode 100644 configs/posec3d/slowonly_r50_gym/joint.py create mode 100644 configs/posec3d/slowonly_r50_gym/limb.py create mode 100644 configs/posec3d/slowonly_r50_hmdb51_k400p/s1_joint.py create mode 100644 configs/posec3d/slowonly_r50_ntu120_xset/joint.py create mode 100644 configs/posec3d/slowonly_r50_ntu120_xset/limb.py create mode 100644 configs/posec3d/slowonly_r50_ntu120_xsub/joint.py create mode 100644 configs/posec3d/slowonly_r50_ntu120_xsub/limb.py create mode 100644 configs/posec3d/slowonly_r50_ntu60_xsub/joint.py create mode 100644 configs/posec3d/slowonly_r50_ntu60_xsub/limb.py create mode 100644 configs/posec3d/slowonly_r50_ntu60_xview/joint.py create mode 100644 configs/posec3d/slowonly_r50_ntu60_xview/limb.py create mode 100644 configs/posec3d/slowonly_r50_ucf101_k400p/s1_joint.py create mode 100644 configs/posec3d/x3d_shallow_gym/joint.py create mode 100644 configs/posec3d/x3d_shallow_gym/limb.py create mode 100644 configs/posec3d/x3d_shallow_ntu60_xsub/joint.py create mode 100644 configs/posec3d/x3d_shallow_ntu60_xsub/limb.py create mode 100644 configs/stgcn++/README.md create mode 100644 configs/stgcn++/stgcn++_ntu120_xset_3dkp/b.py create mode 100644 configs/stgcn++/stgcn++_ntu120_xset_3dkp/bm.py create mode 100644 configs/stgcn++/stgcn++_ntu120_xset_3dkp/j.py create mode 100644 configs/stgcn++/stgcn++_ntu120_xset_3dkp/jm.py create mode 100644 configs/stgcn++/stgcn++_ntu120_xset_hrnet/b.py create mode 100644 configs/stgcn++/stgcn++_ntu120_xset_hrnet/bm.py create mode 100644 configs/stgcn++/stgcn++_ntu120_xset_hrnet/j.py create mode 100644 configs/stgcn++/stgcn++_ntu120_xset_hrnet/jm.py create mode 100644 configs/stgcn++/stgcn++_ntu120_xsub_3dkp/b.py create mode 100644 configs/stgcn++/stgcn++_ntu120_xsub_3dkp/bm.py create mode 100644 configs/stgcn++/stgcn++_ntu120_xsub_3dkp/j.py create mode 100644 configs/stgcn++/stgcn++_ntu120_xsub_3dkp/jm.py create mode 100644 configs/stgcn++/stgcn++_ntu120_xsub_hrnet/b.py create mode 100644 configs/stgcn++/stgcn++_ntu120_xsub_hrnet/bm.py create mode 100644 configs/stgcn++/stgcn++_ntu120_xsub_hrnet/j.py create mode 100644 configs/stgcn++/stgcn++_ntu120_xsub_hrnet/jm.py create mode 100644 configs/stgcn++/stgcn++_ntu60_xsub_3dkp/b.py create mode 100644 configs/stgcn++/stgcn++_ntu60_xsub_3dkp/bm.py create mode 100644 configs/stgcn++/stgcn++_ntu60_xsub_3dkp/j.py create mode 100644 configs/stgcn++/stgcn++_ntu60_xsub_3dkp/jm.py create mode 100644 configs/stgcn++/stgcn++_ntu60_xsub_hrnet/b.py create mode 100644 configs/stgcn++/stgcn++_ntu60_xsub_hrnet/bm.py create mode 100644 configs/stgcn++/stgcn++_ntu60_xsub_hrnet/j.py create mode 100644 configs/stgcn++/stgcn++_ntu60_xsub_hrnet/jm.py create mode 100644 configs/stgcn++/stgcn++_ntu60_xview_3dkp/b.py create mode 100644 configs/stgcn++/stgcn++_ntu60_xview_3dkp/bm.py create mode 100644 configs/stgcn++/stgcn++_ntu60_xview_3dkp/j.py create mode 100644 configs/stgcn++/stgcn++_ntu60_xview_3dkp/jm.py create mode 100644 configs/stgcn++/stgcn++_ntu60_xview_hrnet/b.py create mode 100644 configs/stgcn++/stgcn++_ntu60_xview_hrnet/bm.py create mode 100644 configs/stgcn++/stgcn++_ntu60_xview_hrnet/j.py create mode 100644 configs/stgcn++/stgcn++_ntu60_xview_hrnet/jm.py create mode 100644 configs/stgcn/README.md create mode 100644 configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/b.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/bm.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/j.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/jm.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/b.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/bm.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/j.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/jm.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/b.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/bm.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/j.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/jm.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/b.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/bm.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/j.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/jm.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/b.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/bm.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/j.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/jm.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/b.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/bm.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/j.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/jm.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/b.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/bm.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/j.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/jm.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/b.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/bm.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/j.py create mode 100644 configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/jm.py create mode 100644 configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/b.py create mode 100644 configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/bm.py create mode 100644 configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/j.py create mode 100644 configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/jm.py create mode 100644 configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/b.py create mode 100644 configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/bm.py create mode 100644 configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/j.py create mode 100644 configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/jm.py create mode 100644 configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/b.py create mode 100644 configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/bm.py create mode 100644 configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/j.py create mode 100644 configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/jm.py create mode 100644 configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/b.py create mode 100644 configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/bm.py create mode 100644 configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/j.py create mode 100644 configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/jm.py create mode 100644 demo/demo_posec3d.py create mode 100644 demo/faster_rcnn_r50_fpn_2x_coco.py create mode 100644 demo/hrnet_w32_coco_256x192.py create mode 100644 demo/ntu_sample.avi create mode 100644 demo/vis_skeleton.ipynb create mode 100644 demo/visualize_heatmap_volume.ipynb create mode 100644 pyskl/__init__.py create mode 100644 pyskl/apis/__init__.py create mode 100644 pyskl/apis/inference.py create mode 100644 pyskl/apis/train.py create mode 100644 pyskl/core/__init__.py create mode 100644 pyskl/core/evaluation.py create mode 100644 pyskl/core/hooks.py create mode 100644 pyskl/datasets/__init__.py create mode 100644 pyskl/datasets/base.py create mode 100644 pyskl/datasets/builder.py create mode 100644 pyskl/datasets/dataset_wrappers.py create mode 100644 pyskl/datasets/pipelines/__init__.py create mode 100644 pyskl/datasets/pipelines/augmentations.py create mode 100644 pyskl/datasets/pipelines/compose.py create mode 100644 pyskl/datasets/pipelines/formatting.py create mode 100644 pyskl/datasets/pipelines/loading.py create mode 100644 pyskl/datasets/pipelines/pose_related.py create mode 100644 pyskl/datasets/pipelines/posec3d_related.py create mode 100644 pyskl/datasets/pipelines/sampling.py create mode 100644 pyskl/datasets/pose_dataset.py create mode 100644 pyskl/datasets/samplers/__init__.py create mode 100644 pyskl/datasets/samplers/distributed_sampler.py create mode 100644 pyskl/datasets/video_dataset.py create mode 100644 pyskl/models/__init__.py create mode 100644 pyskl/models/builder.py create mode 100644 pyskl/models/cnns/__init__.py create mode 100644 pyskl/models/cnns/c3d.py create mode 100644 pyskl/models/cnns/resnet.py create mode 100644 pyskl/models/cnns/resnet3d.py create mode 100644 pyskl/models/cnns/resnet3d_slowfast.py create mode 100644 pyskl/models/cnns/resnet3d_slowonly.py create mode 100644 pyskl/models/cnns/x3d.py create mode 100644 pyskl/models/gcns/__init__.py create mode 100644 pyskl/models/gcns/stgcn.py create mode 100644 pyskl/models/gcns/utils/__init__.py create mode 100644 pyskl/models/gcns/utils/gcn.py create mode 100644 pyskl/models/gcns/utils/tcn.py create mode 100644 pyskl/models/heads/__init__.py create mode 100644 pyskl/models/heads/base.py create mode 100644 pyskl/models/heads/simple_head.py create mode 100644 pyskl/models/losses/__init__.py create mode 100644 pyskl/models/losses/base.py create mode 100644 pyskl/models/losses/cross_entropy_loss.py create mode 100644 pyskl/models/recognizers/__init__.py create mode 100644 pyskl/models/recognizers/base.py create mode 100644 pyskl/models/recognizers/recognizer2d.py create mode 100644 pyskl/models/recognizers/recognizer3d.py create mode 100644 pyskl/models/recognizers/recognizergcn.py create mode 100644 pyskl/smp.py create mode 100644 pyskl/utils/__init__.py create mode 100644 pyskl/utils/collect_env.py create mode 100644 pyskl/utils/graph.py create mode 100644 pyskl/utils/misc.py create mode 100644 pyskl/utils/visualize.py create mode 100644 pyskl/version.py create mode 100644 requirements.txt create mode 100644 setup.cfg create mode 100644 setup.py create mode 100644 tools/data_list.md create mode 100644 tools/dist_test.sh create mode 100644 tools/dist_train.sh create mode 100644 tools/slurm_test.sh create mode 100644 tools/slurm_train.sh create mode 100644 tools/test.py create mode 100644 tools/train.py diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..be297e79 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,27 @@ +name: lint + +on: [push, pull_request] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python 3.7 + uses: actions/setup-python@v2 + with: + python-version: 3.7 + - name: Install pre-commit hook + run: | + # markdownlint requires ruby >= 2.7 + sudo apt-add-repository ppa:brightbox/ruby-ng -y + sudo apt-get update + sudo apt-get install -y ruby2.7 + pip install pre-commit + pre-commit install + - name: Linting + run: pre-commit run --all-files diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..86ffaaed --- /dev/null +++ b/.gitignore @@ -0,0 +1,141 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class +**/*.pyc + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# custom +/data +.vscode +.idea +*.pkl +*.pkl.json +*.log.json +benchlist.txt +work_dirs/ + +# Pytorch +*.pth + +# Profile +*.prof + +# lmdb +*.mdb + +# unignore some data file in tests/data +!tests/data/**/*.pkl +!tests/data/**/*.pkl.json +!tests/data/**/*.log.json +!tests/data/**/*.pth + +# avoid soft links created by MIM +pyskl/configs/* +pyskl/tools/* +*.ipynb + +# unignore ipython notebook files in demo +!demo/*.ipynb +pyskl/.mim +.VScodeCounter +tmp/* diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..f535789b --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,38 @@ +exclude: > + (?x)^( + ^tests/data/ + ^configs/ + )$ +repos: + - repo: https://gitlab.com/pycqa/flake8.git + rev: 3.8.3 + hooks: + - id: flake8 + args: ["--max-line-length=120"] + exclude: ^configs/ + - repo: https://github.com/asottile/seed-isort-config + rev: v2.2.0 + hooks: + - id: seed-isort-config + - repo: https://github.com/timothycrosley/isort + rev: 4.3.21 + hooks: + - id: isort + - repo: https://github.com/pre-commit/mirrors-yapf + rev: v0.30.0 + hooks: + - id: yapf + args: ["--style={column_limit=120}"] + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v3.1.0 + hooks: + - id: trailing-whitespace + - id: check-yaml + - id: end-of-file-fixer + - id: requirements-txt-fixer + - id: double-quote-string-fixer + - id: check-merge-conflict + - id: fix-encoding-pragma + args: ["--remove"] + - id: mixed-line-ending + args: ["--fix=lf"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..04adf5cb --- /dev/null +++ b/LICENSE @@ -0,0 +1,203 @@ +Copyright 2018-2019 Open-MMLab. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018-2019 Open-MMLab. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 00000000..b6ccd028 --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# PYSKL + +PYSKL is a toolbox focusing on action recognition based on **SK**e**L**eton data with **PY**Torch. Various algorithms will be supported for skeleton-based action recognition. We build this project based on the OpenSource Project [MMAction2](https://github.com/open-mmlab/mmaction2). + +This repo is the official implementation of [PoseConv3D](https://arxiv.org/abs/2104.13586) and [STGCN++](). + +## Supported Algorithms + +- [x] ST-GCN (AAAI 2018): https://arxiv.org/abs/1801.07455 [[MODELZOO](/configs/stgcn/README.md)] +- [x] ST-GCN++ (PYSKL): [Tech Report Coming Soon]() [[MODELZOO](/configs/stgcn++/README.md)] +- [x] PoseConv3D (CVPR 2022 Oral): https://arxiv.org/abs/2104.13586 [[MODELZOO](/configs/posec3d/README.md)] + +## Installation +```shell +git clone https://github.com/kennymckormick/pyskl.git +cd pyskl +pip install -r requirements.txt +pip install -e . +``` + +## Data Preparation +For data pre-processing, we estimate 2D skeletons with a two-stage pose estimator (Faster-RCNN + HRNet). For 3D skeletons, we follow the pre-processing procedure of [CTR-GCN](https://github.com/Uason-Chen/CTR-GCN). Currently, we do not provide the pre-processing scripts. Instead, we directly provide the [processed skeleton data](/tools/data_list.md) as pickle files, which can be directly used in training and evaluation. You can use [vis_skeleton](/demo/vis_skeleton.ipynb) to visualize the provided skeleton data. + + +## Training & Testing +You can use following commands for training and testing. Basically, we support distribued training on a single server with multiple GPUs. +```shell +# Training +bash tools/dist_train.sh {config_name} {num_gpus} {other_options} +# Testing +bash tools/dist_test.sh {config_name} {checkpoint} {num_gpus} --out {output_file} --eval top_k_accuracy mean_class_accuracy +``` +For specific examples, please go to the README for each specific algorithm we supported. + +## Citation + +If you use PYSKL in your research or wish to refer to the baseline results published in the Model Zoo, please use the following BibTeX entry and the BibTex entry corresponding to the specific algorithm you used. + +```BibTeX +% Tech Report Coming Soon! +@misc{duan2022pyskl, + title={PYSKL: a toolbox for skeleton-based video understanding}, + author={PYSKL Contributors}, + howpublished = {\url{https://github.com/kennymckormick/pyskl}}, + year={2022} +} +``` diff --git a/configs/posec3d/README.md b/configs/posec3d/README.md new file mode 100644 index 00000000..9528cb7f --- /dev/null +++ b/configs/posec3d/README.md @@ -0,0 +1,118 @@ +# PoseC3D + +## Introduction + +PoseC3D is the first framework that formats 2D human skeletons as 3D voxels and processes human skeletons with 3D ConvNets. We release multiple PoseC3D variants instantiated with different backbones and trained on different datasets. + +
+ +
+ + +## Citation + +```BibTeX +@misc{duan2021revisiting, + title={Revisiting Skeleton-based Action Recognition}, + author={Haodong Duan and Yue Zhao and Kai Chen and Dian Shao and Dahua Lin and Bo Dai}, + year={2021}, + eprint={2104.13586}, + archivePrefix={arXiv}, + primaryClass={cs.CV} +} +``` + +## Model Zoo + +We release numerous weights trained on various datasets and with multiple 3D backbones. The accuracy of each modality links to the weight file. + +| Dataset | Backbone | Annotation | Pretrain | GPUs | Joint Top-1 | Limb Top-1 | Two-Stream Top1 | +| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| NTURGB+D XSub | SlowOnly-R50 | HRNet 2D Pose | None | 8 | [joint_config](/configs/posec3d/slowonly_r50_ntu60_xsub/joint.py): [93.7](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/slowonly_r50_ntu60_xsub/joint.pth) | [limb_config](/configs/posec3d/slowonly_r50_ntu60_xsub/limb.py): [93.4](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/slowonly_r50_ntu60_xsub/limb.pth) | 94.1 | +| NTURGB+D XSub | C3D-light | HRNet 2D Pose | None | 8 | [joint_config](/configs/posec3d/c3d_light_ntu60_xsub/joint.py): [92.7](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/c3d_light_ntu60_xsub/joint.pth) | [limb_config](/configs/posec3d/c3d_light_ntu60_xsub/limb.py): [92.6](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/c3d_light_ntu60_xsub/limb.pth) | 93.3 | +| NTURGB+D XSub | X3D-Shallow | HRNet 2D Pose | None | 8 | [joint_config](/configs/posec3d/x3d_shallow_ntu60_xsub/joint.py): [92.1](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/x3d_shallow_ntu60_xsub/joint.pth) | [limb_config](/configs/posec3d/x3d_shallow_ntu60_xsub/limb.py): [91.6](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/x3d_shallow_ntu60_xsub/limb.pth) | 92.4 | +| NTURGB+D XView | SlowOnly-R50 | HRNet 2D Pose | None | 8 | [joint_config](/configs/posec3d/slowonly_r50_ntu60_xview/joint.py): [96.5](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/slowonly_r50_ntu60_xview/joint.pth) | [limb_config](/configs/posec3d/slowonly_r50_ntu60_xview/limb.py): [96.0](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/slowonly_r50_ntu60_xview/limb.pth) | 96.9 | +| NTURGB+D 120 XSub | SlowOnly-R50 | HRNet 2D Pose | None | 8 | [joint_config](/configs/posec3d/slowonly_r50_ntu120_xsub/joint.py): [85.9](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/slowonly_r50_ntu120_xsub/joint.pth) | [limb_config](/configs/posec3d/slowonly_r50_ntu120_xsub/limb.py): [85.9](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/slowonly_r50_ntu120_xsub/limb.pth) | 86.7 | +| NTURGB+D 120 XSet | SlowOnly-R50 | HRNet 2D Pose | None | 8 | [joint_config](/configs/posec3d/slowonly_r50_ntu120_xset/joint.py): [89.7](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/slowonly_r50_ntu120_xset/joint.pth) | [limb_config](/configs/posec3d/slowonly_r50_ntu120_xset/limb.py): [89.7](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/slowonly_r50_ntu120_xset/limb.pth) | 90.3 | +| FineGYM¹ | SlowOnly-R50 | HRNet 2D Pose | None | 8 | [joint_config](/configs/posec3d/slowonly_r50_gym/joint.py): [93.8](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/slowonly_r50_gym/joint.pth) | [limb_config](/configs/posec3d/slowonly_r50_gym/limb.py): [93.8](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/slowonly_r50_gym/limb.pth) | 94.1 | +| FineGYM¹ | C3D-light | HRNet 2D Pose | None | 8 | [joint_config](/configs/posec3d/c3d_light_gym/joint.py): [91.8](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/c3d_light_gym/joint.pth) | [limb_config](/configs/posec3d/c3d_light_gym/limb.py): [91.2](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/c3d_light_gym/limb.pth) | 92.1 | +| FineGYM¹ | X3D-shallow | HRNet 2D Pose | None | 8 | [joint_config](/configs/posec3d/x3d_shallow_gym/joint.py): [91.4](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/x3d_shallow_gym/joint.pth) | [limb_config](/configs/posec3d/x3d_shallow_gym/limb.py): [90.0](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/x3d_shallow_gym/limb.pth) | 91.8 | +| UCF101² | SlowOnly-R50 | HRNet 2D Pose | Kinetics-400 | 8 | [joint_config](/configs/posec3d/slowonly_r50_ucf101_k400p/s1_joint.py): [86.9](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/slowonly_r50_ucf101_k400p/s1_joint.pth) | | | +| HMDB51² | SlowOnly-R50 | HRNet 2D Pose | Kinetics-400 | 8 | [joint_config](/configs/posec3d/slowonly_r50_hmdb51_k400p/s1_joint.py): [69.4](http://download.openmmlab.com/mmaction/pyskl/ckpt/posec3d/slowonly_r50_hmdb51_k400p/s1_joint.pth) | | | + +**Note** + +1. For FineGYM, we report the mean class Top-1 accuracy instead of the Top-1 accuracy. + +2. For UCF101 and HMDB51, we provide the checkpoints trained on the official split 1. + +3. We use linear scaling learning rate (`Initial LR` ∝ `Batch Size`). If you change the training batch size, remember to change the initial LR proportionally. + +4. Though optimized, multi-clip testing may consumes large amounts of time. For faster inference, you may change the test_pipeline to disable the multi-clip testing, this may lead to a small drop in recognition performance. Below is the guide: + + ```python + test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), # Change `num_clips=10` to `num_clips=1` + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False, double=True, left_kp=left_kp, right_kp=right_kp), # Change `double=True` to `double=False` + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) + ] + ``` + +## Demonstration of heatmap volumes + + + + + + + + + +
+
+ Pose Estimation Results +
+ +
+
+ +
+
+ Keypoint Heatmap Volume Visualization +
+ +
+
+ +
+
+ Limb Heatmap Volume Visualization +
+ +
+
+ +
+ +## Training & Testing + +You can use the following command to train a model. + +```shell +bash tools/dist_train.sh ${CONFIG_FILE} ${NUM_GPUS} [optional arguments] +# For example: train PoseC3D on FineGYM (HRNet 2D skeleton, Joint Modality) with 8 GPUs, with validation, and test the last and the best (with best validation metric) checkpoint. +bash tools/dist_train.sh configs/posec3d/slowonly_r50_gym/joint.py 8 --validate --test-last --test-best +``` + +You can use the following command to test a model. + +```shell +bash tools/dist_test.sh ${CONFIG_FILE} ${CHECKPOINT_FILE} ${NUM_GPUS} [optional arguments] +# For example: test PoseC3D on FineGYM (HRNet 2D skeleton, Joint Modality) with metrics `top_k_accuracy` and `mean_class_accuracy`, and dump the result to `result.pkl`. +bash tools/dist_test.sh configs/posec3d/slowonly_r50_gym/joint.py checkpoints/SOME_CHECKPOINT.pth 8 --eval top_k_accuracy mean_class_accuracy --out result.pkl +``` diff --git a/configs/posec3d/c3d_light_gym/joint.py b/configs/posec3d/c3d_light_gym/joint.py new file mode 100644 index 00000000..d8037abd --- /dev/null +++ b/configs/posec3d/c3d_light_gym/joint.py @@ -0,0 +1,73 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='C3D', + in_channels=17, + base_channels=32, + num_stages=3, + temporal_downsample=False), + cls_head=dict( + type='I3DHead', + in_channels=256, + num_classes=99, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/gym/gym_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False, double=True, left_kp=left_kp, right_kp=right_kp), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='train', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +log_level = 'INFO' +work_dir = './work_dirs/posec3d/c3d_light_gym/joint' diff --git a/configs/posec3d/c3d_light_gym/limb.py b/configs/posec3d/c3d_light_gym/limb.py new file mode 100644 index 00000000..33d692e5 --- /dev/null +++ b/configs/posec3d/c3d_light_gym/limb.py @@ -0,0 +1,80 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='C3D', + in_channels=17, + base_channels=32, + num_stages=3, + temporal_downsample=False), + cls_head=dict( + type='I3DHead', + in_channels=256, + num_classes=99, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/gym/gym_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +skeletons = [[0, 5], [0, 6], [5, 7], [7, 9], [6, 8], [8, 10], [5, 11], + [11, 13], [13, 15], [6, 12], [12, 14], [14, 16], [0, 1], [0, 2], + [1, 3], [2, 4], [11, 12]] +left_limb = [0, 2, 3, 6, 7, 8, 12, 14] +right_limb = [1, 4, 5, 9, 10, 11, 13, 15] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons, + double=True, left_kp=left_kp, right_kp=right_kp, left_limb=left_limb, right_limb=right_limb), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='train', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) # this lr is used for 8 gpus +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +dist_params = dict(backend='nccl') +log_level = 'INFO' +work_dir = './work_dirs/posec3d/c3d_light_gym/limb' diff --git a/configs/posec3d/c3d_light_ntu60_xsub/joint.py b/configs/posec3d/c3d_light_ntu60_xsub/joint.py new file mode 100644 index 00000000..d4f51309 --- /dev/null +++ b/configs/posec3d/c3d_light_ntu60_xsub/joint.py @@ -0,0 +1,73 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='C3D', + in_channels=17, + base_channels=32, + num_stages=3, + temporal_downsample=False), + cls_head=dict( + type='I3DHead', + in_channels=256, + num_classes=60, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False, double=True, left_kp=left_kp, right_kp=right_kp), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='xsub_train', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='xsub_val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='xsub_val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) # this lr is used for 8 gpus +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +log_level = 'INFO' +work_dir = './work_dirs/posec3d/c3d_light_ntu60_xsub/joint' diff --git a/configs/posec3d/c3d_light_ntu60_xsub/limb.py b/configs/posec3d/c3d_light_ntu60_xsub/limb.py new file mode 100644 index 00000000..def2f596 --- /dev/null +++ b/configs/posec3d/c3d_light_ntu60_xsub/limb.py @@ -0,0 +1,79 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='C3D', + in_channels=17, + base_channels=32, + num_stages=3, + temporal_downsample=False), + cls_head=dict( + type='I3DHead', + in_channels=256, + num_classes=60, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +skeletons = [[0, 5], [0, 6], [5, 7], [7, 9], [6, 8], [8, 10], [5, 11], + [11, 13], [13, 15], [6, 12], [12, 14], [14, 16], [0, 1], [0, 2], + [1, 3], [2, 4], [11, 12]] +left_limb = [0, 2, 3, 6, 7, 8, 12, 14] +right_limb = [1, 4, 5, 9, 10, 11, 13, 15] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons, + double=True, left_kp=left_kp, right_kp=right_kp, left_limb=left_limb, right_limb=right_limb), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='xsub_train', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='xsub_val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='xsub_val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) # this lr is used for 8 gpus +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +log_level = 'INFO' +work_dir = './work_dirs/posec3d/c3d_light_ntu60_xsub/limb' diff --git a/configs/posec3d/slowonly_r50_gym/joint.py b/configs/posec3d/slowonly_r50_gym/joint.py new file mode 100644 index 00000000..84bcb135 --- /dev/null +++ b/configs/posec3d/slowonly_r50_gym/joint.py @@ -0,0 +1,79 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='ResNet3dSlowOnly', + in_channels=17, + base_channels=32, + num_stages=3, + out_indices=(2, ), + stage_blocks=(4, 6, 3), + conv1_stride=(1, 1), + pool1_stride=(1, 1), + inflate=(0, 1, 1), + spatial_strides=(2, 2, 2), + temporal_strides=(1, 1, 2)), + cls_head=dict( + type='I3DHead', + in_channels=512, + num_classes=99, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/gym/gym_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False, double=True, left_kp=left_kp, right_kp=right_kp), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='train', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +log_level = 'INFO' +work_dir = './work_dirs/posec3d/slowonly_r50_gym/joint' diff --git a/configs/posec3d/slowonly_r50_gym/limb.py b/configs/posec3d/slowonly_r50_gym/limb.py new file mode 100644 index 00000000..60bec9f8 --- /dev/null +++ b/configs/posec3d/slowonly_r50_gym/limb.py @@ -0,0 +1,86 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='ResNet3dSlowOnly', + in_channels=17, + base_channels=32, + num_stages=3, + out_indices=(2, ), + stage_blocks=(4, 6, 3), + conv1_stride=(1, 1), + pool1_stride=(1, 1), + inflate=(0, 1, 1), + spatial_strides=(2, 2, 2), + temporal_strides=(1, 1, 2)), + cls_head=dict( + type='I3DHead', + in_channels=512, + num_classes=99, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/gym/gym_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +skeletons = [[0, 5], [0, 6], [5, 7], [7, 9], [6, 8], [8, 10], [5, 11], + [11, 13], [13, 15], [6, 12], [12, 14], [14, 16], [0, 1], [0, 2], + [1, 3], [2, 4], [11, 12]] +left_limb = [0, 2, 3, 6, 7, 8, 12, 14] +right_limb = [1, 4, 5, 9, 10, 11, 13, 15] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons, + double=True, left_kp=left_kp, right_kp=right_kp, left_limb=left_limb, right_limb=right_limb), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='train', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) # this lr is used for 8 gpus +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +dist_params = dict(backend='nccl') +log_level = 'INFO' +work_dir = './work_dirs/posec3d/slowonly_r50_gym/limb' diff --git a/configs/posec3d/slowonly_r50_hmdb51_k400p/s1_joint.py b/configs/posec3d/slowonly_r50_hmdb51_k400p/s1_joint.py new file mode 100644 index 00000000..713afdba --- /dev/null +++ b/configs/posec3d/slowonly_r50_hmdb51_k400p/s1_joint.py @@ -0,0 +1,81 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='ResNet3dSlowOnly', + in_channels=17, + base_channels=32, + num_stages=3, + out_indices=(2, ), + stage_blocks=(3, 4, 6), + conv1_stride=(1, 1), + pool1_stride=(1, 1), + inflate=(0, 1, 1), + spatial_strides=(2, 2, 2), + temporal_strides=(1, 1, 2)), + cls_head=dict( + type='I3DHead', + in_channels=512, + num_classes=51, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/hmdb51/hmdb51_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(48, 48), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False, double=True, left_kp=left_kp, right_kp=right_kp), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='train1', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='test1', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='test1', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001) # this lr is used for 8 gpus +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='step', step=[9, 11]) +total_epochs = 12 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +log_level = 'INFO' +work_dir = './work_dirs/posec3d/slowonly_r50_hmdb51_k400p/s1_joint' +load_from = 'https://download.openmmlab.com/mmaction/skeleton/posec3d/k400_posec3d-041f49c6.pth' # noqa: E501 +find_unused_parameters = True diff --git a/configs/posec3d/slowonly_r50_ntu120_xset/joint.py b/configs/posec3d/slowonly_r50_ntu120_xset/joint.py new file mode 100644 index 00000000..f7bb2d3b --- /dev/null +++ b/configs/posec3d/slowonly_r50_ntu120_xset/joint.py @@ -0,0 +1,79 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='ResNet3dSlowOnly', + in_channels=17, + base_channels=32, + num_stages=3, + out_indices=(2, ), + stage_blocks=(4, 6, 3), + conv1_stride=(1, 1), + pool1_stride=(1, 1), + inflate=(0, 1, 1), + spatial_strides=(2, 2, 2), + temporal_strides=(1, 1, 2)), + cls_head=dict( + type='I3DHead', + in_channels=512, + num_classes=120, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, double=True, left_kp=left_kp, right_kp=right_kp), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='xset_train', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='xset_val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='xset_val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) # this lr is used for 8 gpus +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +log_level = 'INFO' +work_dir = './work_dirs/posec3d/slowonly_r50_ntu120_xset/joint' diff --git a/configs/posec3d/slowonly_r50_ntu120_xset/limb.py b/configs/posec3d/slowonly_r50_ntu120_xset/limb.py new file mode 100644 index 00000000..860dc8b9 --- /dev/null +++ b/configs/posec3d/slowonly_r50_ntu120_xset/limb.py @@ -0,0 +1,85 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='ResNet3dSlowOnly', + in_channels=17, + base_channels=32, + num_stages=3, + out_indices=(2, ), + stage_blocks=(4, 6, 3), + conv1_stride=(1, 1), + pool1_stride=(1, 1), + inflate=(0, 1, 1), + spatial_strides=(2, 2, 2), + temporal_strides=(1, 1, 2)), + cls_head=dict( + type='I3DHead', + in_channels=512, + num_classes=120, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +skeletons = [[0, 5], [0, 6], [5, 7], [7, 9], [6, 8], [8, 10], [5, 11], + [11, 13], [13, 15], [6, 12], [12, 14], [14, 16], [0, 1], [0, 2], + [1, 3], [2, 4], [11, 12]] +left_limb = [0, 2, 3, 6, 7, 8, 12, 14] +right_limb = [1, 4, 5, 9, 10, 11, 13, 15] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons, + double=True, left_kp=left_kp, right_kp=right_kp, left_limb=left_limb, right_limb=right_limb), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='xset_train', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='xset_val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='xset_val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) # this lr is used for 8 gpus +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +log_level = 'INFO' +work_dir = './work_dirs/posec3d/slowonly_r50_ntu120_xset/limb' diff --git a/configs/posec3d/slowonly_r50_ntu120_xsub/joint.py b/configs/posec3d/slowonly_r50_ntu120_xsub/joint.py new file mode 100644 index 00000000..998f379c --- /dev/null +++ b/configs/posec3d/slowonly_r50_ntu120_xsub/joint.py @@ -0,0 +1,85 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='ResNet3dSlowOnly', + in_channels=17, + base_channels=32, + num_stages=3, + out_indices=(2, ), + stage_blocks=(4, 6, 3), + conv1_stride=(1, 1), + pool1_stride=(1, 1), + inflate=(0, 1, 1), + spatial_strides=(2, 2, 2), + temporal_strides=(1, 1, 2)), + cls_head=dict( + type='I3DHead', + in_channels=512, + num_classes=120, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +class_prob = [1] * 60 + [2] * 60 +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, double=True, left_kp=left_kp, right_kp=right_kp), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict( + type=dataset_type, + ann_file=ann_file, + split='xsub_train', + pipeline=train_pipeline, + class_prob=class_prob)), + val=dict(type=dataset_type, ann_file=ann_file, split='xsub_val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='xsub_val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) # this lr is used for 8 gpus +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +log_level = 'INFO' +work_dir = './work_dirs/posec3d/slowonly_r50_ntu120_xsub/joint' diff --git a/configs/posec3d/slowonly_r50_ntu120_xsub/limb.py b/configs/posec3d/slowonly_r50_ntu120_xsub/limb.py new file mode 100644 index 00000000..091df9b1 --- /dev/null +++ b/configs/posec3d/slowonly_r50_ntu120_xsub/limb.py @@ -0,0 +1,91 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='ResNet3dSlowOnly', + in_channels=17, + base_channels=32, + num_stages=3, + out_indices=(2, ), + stage_blocks=(4, 6, 3), + conv1_stride=(1, 1), + pool1_stride=(1, 1), + inflate=(0, 1, 1), + spatial_strides=(2, 2, 2), + temporal_strides=(1, 1, 2)), + cls_head=dict( + type='I3DHead', + in_channels=512, + num_classes=120, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +skeletons = [[0, 5], [0, 6], [5, 7], [7, 9], [6, 8], [8, 10], [5, 11], + [11, 13], [13, 15], [6, 12], [12, 14], [14, 16], [0, 1], [0, 2], + [1, 3], [2, 4], [11, 12]] +left_limb = [0, 2, 3, 6, 7, 8, 12, 14] +right_limb = [1, 4, 5, 9, 10, 11, 13, 15] +class_prob = [1] * 60 + [2] * 60 +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons, + double=True, left_kp=left_kp, right_kp=right_kp, left_limb=left_limb, right_limb=right_limb), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict( + type=dataset_type, + ann_file=ann_file, + split='xsub_train', + pipeline=train_pipeline, + class_prob=class_prob)), + val=dict(type=dataset_type, ann_file=ann_file, split='xsub_val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='xsub_val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) # this lr is used for 8 gpus +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +log_level = 'INFO' +work_dir = './work_dirs/posec3d/slowonly_r50_ntu120_xsub/limb' diff --git a/configs/posec3d/slowonly_r50_ntu60_xsub/joint.py b/configs/posec3d/slowonly_r50_ntu60_xsub/joint.py new file mode 100644 index 00000000..6428de92 --- /dev/null +++ b/configs/posec3d/slowonly_r50_ntu60_xsub/joint.py @@ -0,0 +1,79 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='ResNet3dSlowOnly', + in_channels=17, + base_channels=32, + num_stages=3, + out_indices=(2, ), + stage_blocks=(4, 6, 3), + conv1_stride=(1, 1), + pool1_stride=(1, 1), + inflate=(0, 1, 1), + spatial_strides=(2, 2, 2), + temporal_strides=(1, 1, 2)), + cls_head=dict( + type='I3DHead', + in_channels=512, + num_classes=60, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False, double=True, left_kp=left_kp, right_kp=right_kp), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='xsub_train', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='xsub_val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='xsub_val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) # this lr is used for 8 gpus +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +log_level = 'INFO' +work_dir = './work_dirs/posec3d/slowonly_r50_ntu60_xsub/joint' diff --git a/configs/posec3d/slowonly_r50_ntu60_xsub/limb.py b/configs/posec3d/slowonly_r50_ntu60_xsub/limb.py new file mode 100644 index 00000000..d38d81b0 --- /dev/null +++ b/configs/posec3d/slowonly_r50_ntu60_xsub/limb.py @@ -0,0 +1,85 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='ResNet3dSlowOnly', + in_channels=17, + base_channels=32, + num_stages=3, + out_indices=(2, ), + stage_blocks=(4, 6, 3), + conv1_stride=(1, 1), + pool1_stride=(1, 1), + inflate=(0, 1, 1), + spatial_strides=(2, 2, 2), + temporal_strides=(1, 1, 2)), + cls_head=dict( + type='I3DHead', + in_channels=512, + num_classes=60, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +skeletons = [[0, 5], [0, 6], [5, 7], [7, 9], [6, 8], [8, 10], [5, 11], + [11, 13], [13, 15], [6, 12], [12, 14], [14, 16], [0, 1], [0, 2], + [1, 3], [2, 4], [11, 12]] +left_limb = [0, 2, 3, 6, 7, 8, 12, 14] +right_limb = [1, 4, 5, 9, 10, 11, 13, 15] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons, + double=True, left_kp=left_kp, right_kp=right_kp, left_limb=left_limb, right_limb=right_limb), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='xsub_train', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='xsub_val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='xsub_val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) # this lr is used for 8 gpus +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +log_level = 'INFO' +work_dir = './work_dirs/posec3d/slowonly_r50_ntu60_xsub/limb' diff --git a/configs/posec3d/slowonly_r50_ntu60_xview/joint.py b/configs/posec3d/slowonly_r50_ntu60_xview/joint.py new file mode 100644 index 00000000..63ed9ae8 --- /dev/null +++ b/configs/posec3d/slowonly_r50_ntu60_xview/joint.py @@ -0,0 +1,79 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='ResNet3dSlowOnly', + in_channels=17, + base_channels=32, + num_stages=3, + out_indices=(2, ), + stage_blocks=(4, 6, 3), + conv1_stride=(1, 1), + pool1_stride=(1, 1), + inflate=(0, 1, 1), + spatial_strides=(2, 2, 2), + temporal_strides=(1, 1, 2)), + cls_head=dict( + type='I3DHead', + in_channels=512, + num_classes=60, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False, double=True, left_kp=left_kp, right_kp=right_kp), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='xview_train', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='xview_val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='xview_val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) # this lr is used for 8 gpus +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +log_level = 'INFO' +work_dir = './work_dirs/posec3d/slowonly_r50_ntu60_xview/joint' diff --git a/configs/posec3d/slowonly_r50_ntu60_xview/limb.py b/configs/posec3d/slowonly_r50_ntu60_xview/limb.py new file mode 100644 index 00000000..09d0a5aa --- /dev/null +++ b/configs/posec3d/slowonly_r50_ntu60_xview/limb.py @@ -0,0 +1,85 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='ResNet3dSlowOnly', + in_channels=17, + base_channels=32, + num_stages=3, + out_indices=(2, ), + stage_blocks=(4, 6, 3), + conv1_stride=(1, 1), + pool1_stride=(1, 1), + inflate=(0, 1, 1), + spatial_strides=(2, 2, 2), + temporal_strides=(1, 1, 2)), + cls_head=dict( + type='I3DHead', + in_channels=512, + num_classes=60, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +skeletons = [[0, 5], [0, 6], [5, 7], [7, 9], [6, 8], [8, 10], [5, 11], + [11, 13], [13, 15], [6, 12], [12, 14], [14, 16], [0, 1], [0, 2], + [1, 3], [2, 4], [11, 12]] +left_limb = [0, 2, 3, 6, 7, 8, 12, 14] +right_limb = [1, 4, 5, 9, 10, 11, 13, 15] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons, + double=True, left_kp=left_kp, right_kp=right_kp, left_limb=left_limb, right_limb=right_limb), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='xview_train', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='xview_val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='xview_val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) # this lr is used for 8 gpus +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +log_level = 'INFO' +work_dir = './work_dirs/posec3d/slowonly_r50_ntu60_xview/limb' diff --git a/configs/posec3d/slowonly_r50_ucf101_k400p/s1_joint.py b/configs/posec3d/slowonly_r50_ucf101_k400p/s1_joint.py new file mode 100644 index 00000000..d487daf1 --- /dev/null +++ b/configs/posec3d/slowonly_r50_ucf101_k400p/s1_joint.py @@ -0,0 +1,81 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='ResNet3dSlowOnly', + in_channels=17, + base_channels=32, + num_stages=3, + out_indices=(2, ), + stage_blocks=(3, 4, 6), + conv1_stride=(1, 1), + pool1_stride=(1, 1), + inflate=(0, 1, 1), + spatial_strides=(2, 2, 2), + temporal_strides=(1, 1, 2)), + cls_head=dict( + type='I3DHead', + in_channels=512, + num_classes=101, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/ucf101/ucf101_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(48, 48), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False, double=True, left_kp=left_kp, right_kp=right_kp), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='train1', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='test1', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='test1', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0003) # this lr is used for 8 gpus +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='step', step=[9, 11]) +total_epochs = 12 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +log_level = 'INFO' +work_dir = './work_dirs/posec3d/slowonly_r50_ucf101_k400p/s1_joint' +load_from = 'https://download.openmmlab.com/mmaction/skeleton/posec3d/k400_posec3d-041f49c6.pth' # noqa: E501 +find_unused_parameters = True diff --git a/configs/posec3d/x3d_shallow_gym/joint.py b/configs/posec3d/x3d_shallow_gym/joint.py new file mode 100644 index 00000000..bfa4ec86 --- /dev/null +++ b/configs/posec3d/x3d_shallow_gym/joint.py @@ -0,0 +1,77 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='X3D', + gamma_d=1, + in_channels=17, + base_channels=24, + num_stages=3, + se_ratio=None, + use_swish=False, + stage_blocks=(2, 5, 3), + spatial_strides=(2, 2, 2)), + cls_head=dict( + type='I3DHead', + in_channels=216, + num_classes=99, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/gym/gym_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False, double=True, left_kp=left_kp, right_kp=right_kp), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='train', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +log_level = 'INFO' +work_dir = './work_dirs/posec3d/x3d_shallow_gym/joint' diff --git a/configs/posec3d/x3d_shallow_gym/limb.py b/configs/posec3d/x3d_shallow_gym/limb.py new file mode 100644 index 00000000..db4313a0 --- /dev/null +++ b/configs/posec3d/x3d_shallow_gym/limb.py @@ -0,0 +1,84 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='X3D', + gamma_d=1, + in_channels=17, + base_channels=24, + num_stages=3, + se_ratio=None, + use_swish=False, + stage_blocks=(2, 5, 3), + spatial_strides=(2, 2, 2)), + cls_head=dict( + type='I3DHead', + in_channels=216, + num_classes=99, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/gym/gym_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +skeletons = [[0, 5], [0, 6], [5, 7], [7, 9], [6, 8], [8, 10], [5, 11], + [11, 13], [13, 15], [6, 12], [12, 14], [14, 16], [0, 1], [0, 2], + [1, 3], [2, 4], [11, 12]] +left_limb = [0, 2, 3, 6, 7, 8, 12, 14] +right_limb = [1, 4, 5, 9, 10, 11, 13, 15] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons, + double=True, left_kp=left_kp, right_kp=right_kp, left_limb=left_limb, right_limb=right_limb), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='train', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) # this lr is used for 8 gpus +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +dist_params = dict(backend='nccl') +log_level = 'INFO' +work_dir = './work_dirs/posec3d/x3d_shallow_gym/limb' diff --git a/configs/posec3d/x3d_shallow_ntu60_xsub/joint.py b/configs/posec3d/x3d_shallow_ntu60_xsub/joint.py new file mode 100644 index 00000000..70129504 --- /dev/null +++ b/configs/posec3d/x3d_shallow_ntu60_xsub/joint.py @@ -0,0 +1,77 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='X3D', + gamma_d=1, + in_channels=17, + base_channels=24, + num_stages=3, + se_ratio=None, + use_swish=False, + stage_blocks=(2, 5, 3), + spatial_strides=(2, 2, 2)), + cls_head=dict( + type='I3DHead', + in_channels=216, + num_classes=60, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=True, with_limb=False, double=True, left_kp=left_kp, right_kp=right_kp), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='xsub_train', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='xsub_val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='xsub_val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) # this lr is used for 8 gpus +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +log_level = 'INFO' +work_dir = './work_dirs/posec3d/x3d_shallow_ntu60_xsub/joint' diff --git a/configs/posec3d/x3d_shallow_ntu60_xsub/limb.py b/configs/posec3d/x3d_shallow_ntu60_xsub/limb.py new file mode 100644 index 00000000..4a53cc5c --- /dev/null +++ b/configs/posec3d/x3d_shallow_ntu60_xsub/limb.py @@ -0,0 +1,83 @@ +model = dict( + type='Recognizer3D', + backbone=dict( + type='X3D', + gamma_d=1, + in_channels=17, + base_channels=24, + num_stages=3, + se_ratio=None, + use_swish=False, + stage_blocks=(2, 5, 3), + spatial_strides=(2, 2, 2)), + cls_head=dict( + type='I3DHead', + in_channels=216, + num_classes=60, + dropout=0.5), + test_cfg=dict(average_clips='prob')) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +left_kp = [1, 3, 5, 7, 9, 11, 13, 15] +right_kp = [2, 4, 6, 8, 10, 12, 14, 16] +skeletons = [[0, 5], [0, 6], [5, 7], [7, 9], [6, 8], [8, 10], [5, 11], + [11, 13], [13, 15], [6, 12], [12, 14], [14, 16], [0, 1], [0, 2], + [1, 3], [2, 4], [11, 12]] +left_limb = [0, 2, 3, 6, 7, 8, 12, 14] +right_limb = [1, 4, 5, 9, 10, 11, 13, 15] +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='RandomResizedCrop', area_range=(0.56, 1.0)), + dict(type='Resize', scale=(56, 56), keep_ratio=False), + dict(type='Flip', flip_ratio=0.5, left_kp=left_kp, right_kp=right_kp), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs', 'label']) +] +val_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +test_pipeline = [ + dict(type='UniformSampleFrames', clip_len=48, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True), + dict(type='Resize', scale=(64, 64), keep_ratio=False), + dict(type='GeneratePoseTarget', with_kp=False, with_limb=True, skeletons=skeletons, + double=True, left_kp=left_kp, right_kp=right_kp, left_limb=left_limb, right_limb=right_limb), + dict(type='FormatShape', input_format='NCTHW_Heatmap'), + dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['imgs']) +] +data = dict( + videos_per_gpu=32, + workers_per_gpu=4, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=10, + dataset=dict(type=dataset_type, ann_file=ann_file, split='xsub_train', pipeline=train_pipeline)), + val=dict(type=dataset_type, ann_file=ann_file, split='xsub_val', pipeline=val_pipeline), + test=dict(type=dataset_type, ann_file=ann_file, split='xsub_val', pipeline=test_pipeline)) +# optimizer +optimizer = dict(type='SGD', lr=0.4, momentum=0.9, weight_decay=0.0003) # this lr is used for 8 gpus +optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) +# learning policy +lr_config = dict(policy='CosineAnnealing', by_epoch=False, min_lr=0) +total_epochs = 24 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy', 'mean_class_accuracy'], topk=(1, 5)) +log_config = dict(interval=20, hooks=[dict(type='TextLoggerHook')]) +log_level = 'INFO' +work_dir = './work_dirs/posec3d/x3d_shallow_ntu60_xsub/limb' diff --git a/configs/stgcn++/README.md b/configs/stgcn++/README.md new file mode 100644 index 00000000..bedeb8f9 --- /dev/null +++ b/configs/stgcn++/README.md @@ -0,0 +1,55 @@ +# STGCN++ + +## Introduction + +STGCN++ is a variant of STGCN we developed in PYSKL with some modifications in the architecture of the spatial module and the temporal module. We provide STGCN++ trained on NTURGB+D with 2D skeletons (HRNet) and 3D skeletons with **PYSKL** training setting. We provide checkpoints for four modalities: Joint, Bone, Joint Motion, and Bone Motion. We will describe the architecture of STGCN++ in the upcoming tech report. + +## Citation + +```BibTeX +@misc{duan2022pyskl, + title={PYSKL: a toolbox for skeleton-based video understanding}, + author={PYSKL Contributors}, + howpublished = {\url{https://github.com/kennymckormick/pyskl}}, + year={2022} +} +``` + +## Model Zoo + +We release numerous checkpoints trained with various modalities, annotations on NTURGB+D and NTURGB+D 120. The accuracy of each modality links to the weight file. + +| Dataset | Annotation | GPUs | Joint Top1 | Bone Top1 | Joint Motion Top1 | Bone-Motion Top1 | Two-Stream Top1 | Four Stream Top1 | +| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| NTURGB+D XSub | Official 3D Skeleton | 8 | [joint_config](/configs/stgcn++/stgcn++_ntu60_xsub_3dkp/j.py): [89.3](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu60_xsub_3dkp/j.pth) | [bone_config](/configs/stgcn++/stgcn++_ntu60_xsub_3dkp/b.py): [90.1](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu60_xsub_3dkp/b.pth) | [joint_motion_config](/configs/stgcn++/stgcn++_ntu60_xsub_3dkp/jm.py): [87.5](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu60_xsub_3dkp/jm.pth) | [bone_motion_config](/configs/stgcn++/stgcn++_ntu60_xsub_3dkp/bm.py): [87.3](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu60_xsub_3dkp/bm.pth) | 91.4 | 92.1 | +| NTURGB+D XSub | HRNet 2D Skeleton | 8 | [joint_config](/configs/stgcn++/stgcn++_ntu60_xsub_hrnet/j.py): [89.3](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu60_xsub_hrnet/j.pth) | [bone_config](/configs/stgcn++/stgcn++_ntu60_xsub_hrnet/b.py): [92.3](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu60_xsub_hrnet/b.pth) | [joint_motion_config](/configs/stgcn++/stgcn++_ntu60_xsub_hrnet/jm.py): [84.0](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu60_xsub_hrnet/jm.pth) | [bone_motion_config](/configs/stgcn++/stgcn++_ntu60_xsub_hrnet/bm.py): [88.8](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu60_xsub_hrnet/bm.pth) | 92.8 | 93.2 | +| NTURGB+D XView | Official 3D Skeleton | 8 | [joint_config](/configs/stgcn++/stgcn++_ntu60_xview_3dkp/j.py): [95.6](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu60_xview_3dkp/j.pth) | [bone_config](/configs/stgcn++/stgcn++_ntu60_xview_3dkp/b.py): [95.5](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu60_xview_3dkp/b.pth) | [joint_motion_config](/configs/stgcn++/stgcn++_ntu60_xview_3dkp/jm.py): [94.3](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu60_xview_3dkp/jm.pth) | [bone_motion_config](/configs/stgcn++/stgcn++_ntu60_xview_3dkp/bm.py): [93.8](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu60_xview_3dkp/bm.pth) | 96.7 | 97.0 | +| NTURGB+D XView | HRNet 2D Skeleton | 8 | [joint_config](/configs/stgcn++/stgcn++_ntu60_xview_hrnet/j.py): [97.4](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu60_xview_hrnet/j.pth) | [bone_config](/configs/stgcn++/stgcn++_ntu60_xview_hrnet/b.py): [97.2](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu60_xview_hrnet/b.pth) | [joint_motion_config](/configs/stgcn++/stgcn++_ntu60_xview_hrnet/jm.py): [93.4](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu60_xview_hrnet/jm.pth) | [bone_motion_config](/configs/stgcn++/stgcn++_ntu60_xview_hrnet/bm.py): [95.4](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu60_xview_hrnet/bm.pth) | 98.4 | 98.5 | +| NTURGB+D 120 XSub | Official 3D Skeleton | 8 | [joint_config](/configs/stgcn++/stgcn++_ntu120_xsub_3dkp/j.py): [83.2](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu120_xsub_3dkp/j.pth) | [bone_config](/configs/stgcn++/stgcn++_ntu120_xsub_3dkp/b.py): [85.6](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu120_xsub_3dkp/b.pth) | [joint_motion_config](/configs/stgcn++/stgcn++_ntu120_xsub_3dkp/jm.py): [80.4](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu120_xsub_3dkp/jm.pth) | [bone_motion_config](/configs/stgcn++/stgcn++_ntu120_xsub_3dkp/bm.py): [81.5](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu120_xsub_3dkp/bm.pth) | 87.0 | 87.5 | +| NTURGB+D 120 XSub | HRNet 2D Skeleton | 8 | [joint_config](/configs/stgcn++/stgcn++_ntu120_xsub_hrnet/j.py): [84.4](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu120_xsub_hrnet/j.pth) | [bone_config](/configs/stgcn++/stgcn++_ntu120_xsub_hrnet/b.py): [84.8](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu120_xsub_hrnet/b.pth) | [joint_motion_config](/configs/stgcn++/stgcn++_ntu120_xsub_hrnet/jm.py): [76.4](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu120_xsub_hrnet/jm.pth) | [bone_motion_config](/configs/stgcn++/stgcn++_ntu120_xsub_hrnet/bm.py): [81.1](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu120_xsub_hrnet/bm.pth) | 86.4 | 86.4 | +| NTURGB+D 120 XSet | Official 3D Skeleton | 8 | [joint_config](/configs/stgcn++/stgcn++_ntu120_xset_3dkp/j.py): [85.6](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu120_xset_3dkp/j.pth) | [bone_config](/configs/stgcn++/stgcn++_ntu120_xset_3dkp/b.py): [87.5](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu120_xset_3dkp/b.pth) | [joint_motion_config](/configs/stgcn++/stgcn++_ntu120_xset_3dkp/jm.py): [84.3](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu120_xset_3dkp/jm.pth) | [bone_motion_config](/configs/stgcn++/stgcn++_ntu120_xset_3dkp/bm.py): [83.0](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu120_xset_3dkp/bm.pth) | 89.1 | 89.8 | +| NTURGB+D 120 XSet | HRNet 2D Skeleton | 8 | [joint_config](/configs/stgcn++/stgcn++_ntu120_xset_hrnet/j.py): [88.1](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu120_xset_hrnet/j.pth) | [bone_config](/configs/stgcn++/stgcn++_ntu120_xset_hrnet/b.py): [88.5](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu120_xset_hrnet/b.pth) | [joint_motion_config](/configs/stgcn++/stgcn++_ntu120_xset_hrnet/jm.py): [82.6](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu120_xset_hrnet/jm.pth) | [bone_motion_config](/configs/stgcn++/stgcn++_ntu120_xset_hrnet/bm.py): [84.1](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn++/stgcn++_ntu120_xset_hrnet/bm.pth) | 90.0 | 90.3 | + +**Note** + +1. We use the linear-scaling learning rate (**Initial LR ∝ Batch Size**). If you change the training batch size, remember to change the initial LR proportionally. +2. For Two-Stream results, we adopt the **1 (Joint):1 (Bone)** fusion. For Four-Stream results, we adopt the **2 (Joint):2 (Bone):1 (Joint Motion):1 (Bone Motion)** fusion. + + +## Training & Testing + +You can use the following command to train a model. + +```shell +bash tools/dist_train.sh ${CONFIG_FILE} ${NUM_GPUS} [optional arguments] +# For example: train STGCN++ on NTURGB+D XSub (3D skeleton, Joint Modality) with 8 GPUs, with validation, and test the last and the best (with best validation metric) checkpoint. +bash tools/dist_train.sh configs/stgcn++/stgcn++_ntu60_xsub_3dkp/j.py 8 --validate --test-last --test-best +``` + +You can use the following command to test a model. + +```shell +bash tools/dist_test.sh ${CONFIG_FILE} ${CHECKPOINT_FILE} ${NUM_GPUS} [optional arguments] +# For example: test STGCN++ on NTURGB+D XSub (3D skeleton, Joint Modality) with metrics `top_k_accuracy`, and dump the result to `result.pkl`. +bash tools/dist_test.sh configs/stgcn++/stgcn++_ntu60_xsub_3dkp/j.py checkpoints/SOME_CHECKPOINT.pth 8 --eval top_k_accuracy --out result.pkl +``` diff --git a/configs/stgcn++/stgcn++_ntu120_xset_3dkp/b.py b/configs/stgcn++/stgcn++_ntu120_xset_3dkp/b.py new file mode 100644 index 00000000..0c66a4e5 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu120_xset_3dkp/b.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='nturgb+d', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xset_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xset_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xset_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu120_xset_3dkp/b' diff --git a/configs/stgcn++/stgcn++_ntu120_xset_3dkp/bm.py b/configs/stgcn++/stgcn++_ntu120_xset_3dkp/bm.py new file mode 100644 index 00000000..e322a3a8 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu120_xset_3dkp/bm.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='nturgb+d', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xset_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xset_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xset_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu120_xset_3dkp/bm' diff --git a/configs/stgcn++/stgcn++_ntu120_xset_3dkp/j.py b/configs/stgcn++/stgcn++_ntu120_xset_3dkp/j.py new file mode 100644 index 00000000..312fac2e --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu120_xset_3dkp/j.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='nturgb+d', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xset_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xset_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xset_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu120_xset_3dkp/j' diff --git a/configs/stgcn++/stgcn++_ntu120_xset_3dkp/jm.py b/configs/stgcn++/stgcn++_ntu120_xset_3dkp/jm.py new file mode 100644 index 00000000..75db3fb3 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu120_xset_3dkp/jm.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='nturgb+d', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xset_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xset_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xset_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu120_xset_3dkp/jm' diff --git a/configs/stgcn++/stgcn++_ntu120_xset_hrnet/b.py b/configs/stgcn++/stgcn++_ntu120_xset_hrnet/b.py new file mode 100644 index 00000000..dfb679e9 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu120_xset_hrnet/b.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='coco', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xset_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xset_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xset_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu120_xset_hrnet/b' diff --git a/configs/stgcn++/stgcn++_ntu120_xset_hrnet/bm.py b/configs/stgcn++/stgcn++_ntu120_xset_hrnet/bm.py new file mode 100644 index 00000000..622eec46 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu120_xset_hrnet/bm.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='coco', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xset_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xset_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xset_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu120_xset_hrnet/bm' diff --git a/configs/stgcn++/stgcn++_ntu120_xset_hrnet/j.py b/configs/stgcn++/stgcn++_ntu120_xset_hrnet/j.py new file mode 100644 index 00000000..56ddaed5 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu120_xset_hrnet/j.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='coco', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xset_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xset_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xset_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu120_xset_hrnet/j' diff --git a/configs/stgcn++/stgcn++_ntu120_xset_hrnet/jm.py b/configs/stgcn++/stgcn++_ntu120_xset_hrnet/jm.py new file mode 100644 index 00000000..899bc0c2 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu120_xset_hrnet/jm.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='coco', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xset_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xset_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xset_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu120_xset_hrnet/jm' diff --git a/configs/stgcn++/stgcn++_ntu120_xsub_3dkp/b.py b/configs/stgcn++/stgcn++_ntu120_xsub_3dkp/b.py new file mode 100644 index 00000000..24430f47 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu120_xsub_3dkp/b.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='nturgb+d', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu120_xsub_3dkp/b' diff --git a/configs/stgcn++/stgcn++_ntu120_xsub_3dkp/bm.py b/configs/stgcn++/stgcn++_ntu120_xsub_3dkp/bm.py new file mode 100644 index 00000000..dbbf4437 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu120_xsub_3dkp/bm.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='nturgb+d', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu120_xsub_3dkp/bm' diff --git a/configs/stgcn++/stgcn++_ntu120_xsub_3dkp/j.py b/configs/stgcn++/stgcn++_ntu120_xsub_3dkp/j.py new file mode 100644 index 00000000..14e33433 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu120_xsub_3dkp/j.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='nturgb+d', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu120_xsub_3dkp/j' diff --git a/configs/stgcn++/stgcn++_ntu120_xsub_3dkp/jm.py b/configs/stgcn++/stgcn++_ntu120_xsub_3dkp/jm.py new file mode 100644 index 00000000..30013625 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu120_xsub_3dkp/jm.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='nturgb+d', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu120_xsub_3dkp/jm' diff --git a/configs/stgcn++/stgcn++_ntu120_xsub_hrnet/b.py b/configs/stgcn++/stgcn++_ntu120_xsub_hrnet/b.py new file mode 100644 index 00000000..88d7b468 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu120_xsub_hrnet/b.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='coco', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu120_xsub_hrnet/b' diff --git a/configs/stgcn++/stgcn++_ntu120_xsub_hrnet/bm.py b/configs/stgcn++/stgcn++_ntu120_xsub_hrnet/bm.py new file mode 100644 index 00000000..1e3e47a4 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu120_xsub_hrnet/bm.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='coco', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu120_xsub_hrnet/bm' diff --git a/configs/stgcn++/stgcn++_ntu120_xsub_hrnet/j.py b/configs/stgcn++/stgcn++_ntu120_xsub_hrnet/j.py new file mode 100644 index 00000000..4cd84071 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu120_xsub_hrnet/j.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='coco', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu120_xsub_hrnet/j' diff --git a/configs/stgcn++/stgcn++_ntu120_xsub_hrnet/jm.py b/configs/stgcn++/stgcn++_ntu120_xsub_hrnet/jm.py new file mode 100644 index 00000000..21ae77f2 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu120_xsub_hrnet/jm.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='coco', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu120_xsub_hrnet/jm' diff --git a/configs/stgcn++/stgcn++_ntu60_xsub_3dkp/b.py b/configs/stgcn++/stgcn++_ntu60_xsub_3dkp/b.py new file mode 100644 index 00000000..a2d44a7c --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu60_xsub_3dkp/b.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='nturgb+d', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu60_xsub_3dkp/b' diff --git a/configs/stgcn++/stgcn++_ntu60_xsub_3dkp/bm.py b/configs/stgcn++/stgcn++_ntu60_xsub_3dkp/bm.py new file mode 100644 index 00000000..740b2dd7 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu60_xsub_3dkp/bm.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='nturgb+d', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu60_xsub_3dkp/bm' diff --git a/configs/stgcn++/stgcn++_ntu60_xsub_3dkp/j.py b/configs/stgcn++/stgcn++_ntu60_xsub_3dkp/j.py new file mode 100644 index 00000000..f2eca778 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu60_xsub_3dkp/j.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='nturgb+d', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu60_xsub_3dkp/j' diff --git a/configs/stgcn++/stgcn++_ntu60_xsub_3dkp/jm.py b/configs/stgcn++/stgcn++_ntu60_xsub_3dkp/jm.py new file mode 100644 index 00000000..f8c6258b --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu60_xsub_3dkp/jm.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='nturgb+d', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu60_xsub_3dkp/jm' diff --git a/configs/stgcn++/stgcn++_ntu60_xsub_hrnet/b.py b/configs/stgcn++/stgcn++_ntu60_xsub_hrnet/b.py new file mode 100644 index 00000000..d67c0c1c --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu60_xsub_hrnet/b.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='coco', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu60_xsub_hrnet/b' diff --git a/configs/stgcn++/stgcn++_ntu60_xsub_hrnet/bm.py b/configs/stgcn++/stgcn++_ntu60_xsub_hrnet/bm.py new file mode 100644 index 00000000..7379fa37 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu60_xsub_hrnet/bm.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='coco', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu60_xsub_hrnet/bm' diff --git a/configs/stgcn++/stgcn++_ntu60_xsub_hrnet/j.py b/configs/stgcn++/stgcn++_ntu60_xsub_hrnet/j.py new file mode 100644 index 00000000..f4532265 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu60_xsub_hrnet/j.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='coco', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu60_xsub_hrnet/j' diff --git a/configs/stgcn++/stgcn++_ntu60_xsub_hrnet/jm.py b/configs/stgcn++/stgcn++_ntu60_xsub_hrnet/jm.py new file mode 100644 index 00000000..a4519522 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu60_xsub_hrnet/jm.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='coco', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu60_xsub_hrnet/jm' diff --git a/configs/stgcn++/stgcn++_ntu60_xview_3dkp/b.py b/configs/stgcn++/stgcn++_ntu60_xview_3dkp/b.py new file mode 100644 index 00000000..6e531695 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu60_xview_3dkp/b.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='nturgb+d', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xview_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xview_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu60_xview_3dkp/b' diff --git a/configs/stgcn++/stgcn++_ntu60_xview_3dkp/bm.py b/configs/stgcn++/stgcn++_ntu60_xview_3dkp/bm.py new file mode 100644 index 00000000..a7eb023a --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu60_xview_3dkp/bm.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='nturgb+d', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xview_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xview_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu60_xview_3dkp/bm' diff --git a/configs/stgcn++/stgcn++_ntu60_xview_3dkp/j.py b/configs/stgcn++/stgcn++_ntu60_xview_3dkp/j.py new file mode 100644 index 00000000..ac847d70 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu60_xview_3dkp/j.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='nturgb+d', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xview_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xview_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu60_xview_3dkp/j' diff --git a/configs/stgcn++/stgcn++_ntu60_xview_3dkp/jm.py b/configs/stgcn++/stgcn++_ntu60_xview_3dkp/jm.py new file mode 100644 index 00000000..e53d8879 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu60_xview_3dkp/jm.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='nturgb+d', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xview_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xview_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu60_xview_3dkp/jm' diff --git a/configs/stgcn++/stgcn++_ntu60_xview_hrnet/b.py b/configs/stgcn++/stgcn++_ntu60_xview_hrnet/b.py new file mode 100644 index 00000000..8ed196e3 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu60_xview_hrnet/b.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='coco', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xview_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xview_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu60_xview_hrnet/b' diff --git a/configs/stgcn++/stgcn++_ntu60_xview_hrnet/bm.py b/configs/stgcn++/stgcn++_ntu60_xview_hrnet/bm.py new file mode 100644 index 00000000..f8a9cf97 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu60_xview_hrnet/bm.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='coco', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xview_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xview_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu60_xview_hrnet/bm' diff --git a/configs/stgcn++/stgcn++_ntu60_xview_hrnet/j.py b/configs/stgcn++/stgcn++_ntu60_xview_hrnet/j.py new file mode 100644 index 00000000..af521ea8 --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu60_xview_hrnet/j.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='coco', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xview_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xview_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu60_xview_hrnet/j' diff --git a/configs/stgcn++/stgcn++_ntu60_xview_hrnet/jm.py b/configs/stgcn++/stgcn++_ntu60_xview_hrnet/jm.py new file mode 100644 index 00000000..cf436d8b --- /dev/null +++ b/configs/stgcn++/stgcn++_ntu60_xview_hrnet/jm.py @@ -0,0 +1,63 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + gcn_adaptive='init', + gcn_with_res=True, + tcn_type='mstcn', + graph_cfg=dict(layout='coco', mode='spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xview_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xview_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn++/stgcn++_ntu60_xview_hrnet/jm' diff --git a/configs/stgcn/README.md b/configs/stgcn/README.md new file mode 100644 index 00000000..7b7eccf5 --- /dev/null +++ b/configs/stgcn/README.md @@ -0,0 +1,66 @@ +# STGCN + +## Introduction + +STGCN is one of the first algorithms that adopt Graph Convolution Neural Networks for skeleton processing. We provide STGCN trained on NTURGB+D with 2D skeletons (HRNet) and 3D skeletons in both the original training setting and the **PYSKL** training setting. We provide checkpoints for four modalities: Joint, Bone, Joint Motion, and Bone Motion. The accuracy of each modality links to the weight file. + +## Citation + +```BibTeX +@inproceedings{yan2018spatial, + title={Spatial temporal graph convolutional networks for skeleton-based action recognition}, + author={Yan, Sijie and Xiong, Yuanjun and Lin, Dahua}, + booktitle={Thirty-second AAAI conference on artificial intelligence}, + year={2018} +} +# If you use the STGCN with PYSKL practices in your work +@misc{duan2022pyskl, + title={PYSKL: a toolbox for skeleton-based video understanding}, + author={PYSKL Contributors}, + howpublished = {\url{https://github.com/kennymckormick/pyskl}}, + year={2022} +} +``` + +## Model Zoo + +We release numerous checkpoints trained with various modalities, annotations on NTURGB+D and NTURGB+D 120. The accuracy of each modality links to the weight file. + +| Dataset | Practice | Annotation | GPUs | Joint Top1 | Bone Top1 | Joint Motion Top1 | Bone-Motion Top1 | Two-Stream Top1 | Four Stream Top1 | +| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| NTURGB+D XSub | Vanilla | Official 3D Skeleton | 8 | [joint_config](/configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/j.py): [81.5](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/j.pth) | [bone_config](/configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/b.py): [81.0](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/b.pth) | [joint_motion_config](/configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/jm.py): [79.9](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/jm.pth) | [bone_motion_config](/configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/bm.py): [81.2](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/bm.pth) | 84.3 | 86.6 | +| NTURGB+D XSub | Vanilla | HRNet 2D Skeleton | 8 | [joint_config](/configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/j.py): [85.7](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/j.pth) | [bone_config](/configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/b.py): [85.8](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/b.pth) | [joint_motion_config](/configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/jm.py): [81.6](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/jm.pth) | [bone_motion_config](/configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/bm.py): [83.9](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/bm.pth) | 88.8 | 90.1 | +| NTURGB+D XSub | PYSKL | Official 3D Skeleton | 8 | [joint_config](/configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/j.py): [87.8](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/j.pth) | [bone_config](/configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/b.py): [88.6](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/b.pth) | [joint_motion_config](/configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/jm.py): [85.8](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/jm.pth) | [bone_motion_config](/configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/bm.py): [86.2](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/bm.pth) | 90.0 | 90.7 | +| NTURGB+D XSub | PYSKL | HRNet 2D Skeleton | 8 | [joint_config](/configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/j.py): [89.0](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/j.pth) | [bone_config](/configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/b.py): [91.2](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/b.pth) | [joint_motion_config](/configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/jm.py): [86.7](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/jm.pth) | [bone_motion_config](/configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/bm.py): [87.8](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/bm.pth) | 92.0 | 92.4 | +| NTURGB+D XView | Vanilla | Official 3D Skeleton | 8 | [joint_config](/configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/j.py): [90.1](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_vanilla_ntu60_xview_3dkp/j.pth) | [bone_config](/configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/b.py): [87.7](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_vanilla_ntu60_xview_3dkp/b.pth) | [joint_motion_config](/configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/jm.py): [88.8](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_vanilla_ntu60_xview_3dkp/jm.pth) | [bone_motion_config](/configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/bm.py): [88.3](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_vanilla_ntu60_xview_3dkp/bm.pth) | 91.4 | 93.2 | +| NTURGB+D XView | Vanilla | HRNet 2D Skeleton | 8 | [joint_config](/configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/j.py): [92.4](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_vanilla_ntu60_xview_hrnet/j.pth) | [bone_config](/configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/b.py): [90.0](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_vanilla_ntu60_xview_hrnet/b.pth) | [joint_motion_config](/configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/jm.py): [92.0](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_vanilla_ntu60_xview_hrnet/jm.pth) | [bone_motion_config](/configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/bm.py): [86.5](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_vanilla_ntu60_xview_hrnet/bm.pth) | 93.8 | 95.1 | +| NTURGB+D XView | PYSKL | Official 3D Skeleton | 8 | [joint_config](/configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/j.py): [95.5](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu60_xview_3dkp/j.pth) | [bone_config](/configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/b.py): [95.0](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu60_xview_3dkp/b.pth) | [joint_motion_config](/configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/jm.py): [93.7](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu60_xview_3dkp/jm.pth) | [bone_motion_config](/configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/bm.py): [92.8](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu60_xview_3dkp/bm.pth) | 96.2 | 96.5 | +| NTURGB+D XView | PYSKL | HRNet 2D Skeleton | 8 | [joint_config](/configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/j.py): [98.0](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu60_xview_hrnet/j.pth) | [bone_config](/configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/b.py): [96.5](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu60_xview_hrnet/b.pth) | [joint_motion_config](/configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/jm.py): [95.6](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu60_xview_hrnet/jm.pth) | [bone_motion_config](/configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/bm.py): [95.4](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu60_xview_hrnet/bm.pth) | 98.2 | 98.3 | +| NTURGB+D 120 XSub | PYSKL | Official 3D Skeleton | 8 | [joint_config](/configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/j.py): [82.1](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/j.pth) | [bone_config](/configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/b.py): [83.7](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/b.pth) | [joint_motion_config](/configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/jm.py): [80.3](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/jm.pth) | [bone_motion_config](/configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/bm.py): [80.6](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/bm.pth) | 85.6 | 86.2 | +| NTURGB+D 120 XSub | PYSKL | HRNet 2D Skeleton | 8 | [joint_config](/configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/j.py): [80.1](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/j.pth) | [bone_config](/configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/b.py): [83.4](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/b.pth) | [joint_motion_config](/configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/jm.py): [78.6](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/jm.pth) | [bone_motion_config](/configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/bm.py): [79.8](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/bm.pth) | 84.0 | 84.7 | +| NTURGB+D 120 XSet | PYSKL | Official 3D Skeleton | 8 | [joint_config](/configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/j.py): [84.5](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu120_xset_3dkp/j.pth) | [bone_config](/configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/b.py): [85.8](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu120_xset_3dkp/b.pth) | [joint_motion_config](/configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/jm.py): [82.7](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu120_xset_3dkp/jm.pth) | [bone_motion_config](/configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/bm.py): [83.0](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu120_xset_3dkp/bm.pth) | 87.5 | 88.4 | +| NTURGB+D 120 XSet | PYSKL | HRNet 2D Skeleton | 8 | [joint_config](/configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/j.py): [84.2](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu120_xset_hrnet/j.pth) | [bone_config](/configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/b.py): [87.7](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu120_xset_hrnet/b.pth) | [joint_motion_config](/configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/jm.py): [82.5](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu120_xset_hrnet/jm.pth) | [bone_motion_config](/configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/bm.py): [83.5](http://download.openmmlab.com/mmaction/pyskl/ckpt/stgcn/stgcn_pyskl_ntu120_xset_hrnet/bm.pth) | 88.3 | 89.0 | + +**Note** + +1. We use the linear-scaling learning rate (**Initial LR ∝ Batch Size**). If you change the training batch size, remember to change the initial LR proportionally. +2. For Two-Stream results, we adopt the **1 (Joint):1 (Bone)** fusion. For Four-Stream results, we adopt the **2 (Joint):2 (Bone):1 (Joint Motion):1 (Bone Motion)** fusion. + + +## Training & Testing + +You can use the following command to train a model. + +```shell +bash tools/dist_train.sh ${CONFIG_FILE} ${NUM_GPUS} [optional arguments] +# For example: train STGCN on NTURGB+D XSub (3D skeleton, Joint Modality) with 8 GPUs, with validation, with PYSKL practice, and test the last and the best (with best validation metric) checkpoint. +bash tools/dist_train.sh configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/j.py 8 --validate --test-last --test-best +``` + +You can use the following command to test a model. + +```shell +bash tools/dist_test.sh ${CONFIG_FILE} ${CHECKPOINT_FILE} ${NUM_GPUS} [optional arguments] +# For example: test STGCN on NTURGB+D XSub (3D skeleton, Joint Modality) with metrics `top_k_accuracy`, and dump the result to `result.pkl`. +bash tools/dist_test.sh configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/j.py checkpoints/SOME_CHECKPOINT.pth 8 --eval top_k_accuracy --out result.pkl +``` diff --git a/configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/b.py b/configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/b.py new file mode 100644 index 00000000..55b48a28 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/b.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xset_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xset_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xset_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/b' diff --git a/configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/bm.py b/configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/bm.py new file mode 100644 index 00000000..7b8ae202 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/bm.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xset_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xset_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xset_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/bm' diff --git a/configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/j.py b/configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/j.py new file mode 100644 index 00000000..031f84aa --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/j.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xset_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xset_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xset_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/j' diff --git a/configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/jm.py b/configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/jm.py new file mode 100644 index 00000000..9225bba0 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/jm.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xset_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xset_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xset_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu120_xset_3dkp/jm' diff --git a/configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/b.py b/configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/b.py new file mode 100644 index 00000000..e88904a1 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/b.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xset_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xset_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xset_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/b' diff --git a/configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/bm.py b/configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/bm.py new file mode 100644 index 00000000..45c9717c --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/bm.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xset_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xset_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xset_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/bm' diff --git a/configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/j.py b/configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/j.py new file mode 100644 index 00000000..f7b309b8 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/j.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xset_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xset_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xset_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/j' diff --git a/configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/jm.py b/configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/jm.py new file mode 100644 index 00000000..9ba990af --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/jm.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xset_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xset_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xset_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu120_xset_hrnet/jm' diff --git a/configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/b.py b/configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/b.py new file mode 100644 index 00000000..1bf1fbb2 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/b.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/b' diff --git a/configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/bm.py b/configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/bm.py new file mode 100644 index 00000000..d4c48d6e --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/bm.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/bm' diff --git a/configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/j.py b/configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/j.py new file mode 100644 index 00000000..3b9afd16 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/j.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/j' diff --git a/configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/jm.py b/configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/jm.py new file mode 100644 index 00000000..01574cb0 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/jm.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu120_xsub_3dkp/jm' diff --git a/configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/b.py b/configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/b.py new file mode 100644 index 00000000..70d599c6 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/b.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/b' diff --git a/configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/bm.py b/configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/bm.py new file mode 100644 index 00000000..5767889f --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/bm.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/bm' diff --git a/configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/j.py b/configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/j.py new file mode 100644 index 00000000..3d9f9afe --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/j.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/j' diff --git a/configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/jm.py b/configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/jm.py new file mode 100644 index 00000000..32173bf9 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/jm.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=120, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu120_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu120_xsub_hrnet/jm' diff --git a/configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/b.py b/configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/b.py new file mode 100644 index 00000000..721c6a8c --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/b.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/b' diff --git a/configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/bm.py b/configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/bm.py new file mode 100644 index 00000000..27b05a72 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/bm.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/bm' diff --git a/configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/j.py b/configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/j.py new file mode 100644 index 00000000..1d4e594a --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/j.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/j' diff --git a/configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/jm.py b/configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/jm.py new file mode 100644 index 00000000..d0fbbb1c --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/jm.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu60_xsub_3dkp/jm' diff --git a/configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/b.py b/configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/b.py new file mode 100644 index 00000000..0f6486da --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/b.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/b' diff --git a/configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/bm.py b/configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/bm.py new file mode 100644 index 00000000..409efaa7 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/bm.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/bm' diff --git a/configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/j.py b/configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/j.py new file mode 100644 index 00000000..9115cc07 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/j.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/j' diff --git a/configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/jm.py b/configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/jm.py new file mode 100644 index 00000000..00d9bccf --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/jm.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xsub_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xsub_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu60_xsub_hrnet/jm' diff --git a/configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/b.py b/configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/b.py new file mode 100644 index 00000000..fe730cf9 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/b.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xview_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xview_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/b' diff --git a/configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/bm.py b/configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/bm.py new file mode 100644 index 00000000..d5d8a01a --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/bm.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xview_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xview_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/bm' diff --git a/configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/j.py b/configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/j.py new file mode 100644 index 00000000..ec6418c3 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/j.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xview_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xview_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/j' diff --git a/configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/jm.py b/configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/jm.py new file mode 100644 index 00000000..cc032eb7 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/jm.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +train_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xview_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xview_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu60_xview_3dkp/jm' diff --git a/configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/b.py b/configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/b.py new file mode 100644 index 00000000..db67f705 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/b.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xview_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xview_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/b' diff --git a/configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/bm.py b/configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/bm.py new file mode 100644 index 00000000..02837741 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/bm.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xview_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xview_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/bm' diff --git a/configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/j.py b/configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/j.py new file mode 100644 index 00000000..577190e1 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/j.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xview_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xview_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/j' diff --git a/configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/jm.py b/configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/jm.py new file mode 100644 index 00000000..f3abafc2 --- /dev/null +++ b/configs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/jm.py @@ -0,0 +1,60 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +train_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +val_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=1, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +test_pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='UniformSample', clip_len=100, num_clips=10, test_mode=True), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=train_pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=val_pipeline, split='xview_val'), + test=dict(type=dataset_type, ann_file=ann_file, pipeline=test_pipeline, split='xview_val')) + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0005, nesterov=True) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='CosineAnnealing', min_lr=0, by_epoch=False) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_pyskl_ntu60_xview_hrnet/jm' diff --git a/configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/b.py b/configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/b.py new file mode 100644 index 00000000..6450da5c --- /dev/null +++ b/configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/b.py @@ -0,0 +1,43 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + tcn_dropout=0.5, + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='PadTo', length=300, mode='zero'), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xsub_val')) +data['test'] = data['val'] + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='step', step=[2, 10]) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/b' diff --git a/configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/bm.py b/configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/bm.py new file mode 100644 index 00000000..29ff054e --- /dev/null +++ b/configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/bm.py @@ -0,0 +1,43 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + tcn_dropout=0.5, + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='PadTo', length=300, mode='zero'), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xsub_val')) +data['test'] = data['val'] + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='step', step=[2, 10]) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/bm' diff --git a/configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/j.py b/configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/j.py new file mode 100644 index 00000000..f4061032 --- /dev/null +++ b/configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/j.py @@ -0,0 +1,43 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + tcn_dropout=0.5, + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='PadTo', length=300, mode='zero'), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xsub_val')) +data['test'] = data['val'] + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='step', step=[2, 10]) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/j' diff --git a/configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/jm.py b/configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/jm.py new file mode 100644 index 00000000..7ccb1ef4 --- /dev/null +++ b/configs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/jm.py @@ -0,0 +1,43 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + tcn_dropout=0.5, + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='PadTo', length=300, mode='zero'), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xsub_val')) +data['test'] = data['val'] + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='step', step=[2, 10]) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_vanilla_ntu60_xsub_3dkp/jm' diff --git a/configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/b.py b/configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/b.py new file mode 100644 index 00000000..c7f719b9 --- /dev/null +++ b/configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/b.py @@ -0,0 +1,43 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + tcn_dropout=0.5, + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='PadTo', length=300, mode='zero'), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xsub_val')) +data['test'] = data['val'] + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='step', step=[2, 10]) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/b' diff --git a/configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/bm.py b/configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/bm.py new file mode 100644 index 00000000..a3c3df85 --- /dev/null +++ b/configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/bm.py @@ -0,0 +1,43 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + tcn_dropout=0.5, + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='PadTo', length=300, mode='zero'), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xsub_val')) +data['test'] = data['val'] + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='step', step=[2, 10]) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/bm' diff --git a/configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/j.py b/configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/j.py new file mode 100644 index 00000000..748bcc13 --- /dev/null +++ b/configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/j.py @@ -0,0 +1,43 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + tcn_dropout=0.5, + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='PadTo', length=300, mode='zero'), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xsub_val')) +data['test'] = data['val'] + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='step', step=[2, 10]) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/j' diff --git a/configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/jm.py b/configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/jm.py new file mode 100644 index 00000000..c4595538 --- /dev/null +++ b/configs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/jm.py @@ -0,0 +1,43 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + tcn_dropout=0.5, + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='PadTo', length=300, mode='zero'), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xsub_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xsub_val')) +data['test'] = data['val'] + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='step', step=[2, 10]) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_vanilla_ntu60_xsub_hrnet/jm' diff --git a/configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/b.py b/configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/b.py new file mode 100644 index 00000000..c34cebf6 --- /dev/null +++ b/configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/b.py @@ -0,0 +1,43 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + tcn_dropout=0.5, + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['b']), + dict(type='PadTo', length=300, mode='zero'), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xview_val')) +data['test'] = data['val'] + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='step', step=[2, 10]) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/b' diff --git a/configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/bm.py b/configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/bm.py new file mode 100644 index 00000000..72aea45b --- /dev/null +++ b/configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/bm.py @@ -0,0 +1,43 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + tcn_dropout=0.5, + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['bm']), + dict(type='PadTo', length=300, mode='zero'), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xview_val')) +data['test'] = data['val'] + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='step', step=[2, 10]) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/bm' diff --git a/configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/j.py b/configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/j.py new file mode 100644 index 00000000..311e4686 --- /dev/null +++ b/configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/j.py @@ -0,0 +1,43 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + tcn_dropout=0.5, + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['j']), + dict(type='PadTo', length=300, mode='zero'), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xview_val')) +data['test'] = data['val'] + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='step', step=[2, 10]) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/j' diff --git a/configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/jm.py b/configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/jm.py new file mode 100644 index 00000000..843ad830 --- /dev/null +++ b/configs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/jm.py @@ -0,0 +1,43 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + tcn_dropout=0.5, + graph_cfg=dict(layout='nturgb+d', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_3danno.pkl' +pipeline = [ + dict(type='PreNormalize3D'), + dict(type='GenSkeFeat', dataset='nturgb+d', feats=['jm']), + dict(type='PadTo', length=300, mode='zero'), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xview_val')) +data['test'] = data['val'] + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='step', step=[2, 10]) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_vanilla_ntu60_xview_3dkp/jm' diff --git a/configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/b.py b/configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/b.py new file mode 100644 index 00000000..76f5cf0d --- /dev/null +++ b/configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/b.py @@ -0,0 +1,43 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + tcn_dropout=0.5, + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['b']), + dict(type='PadTo', length=300, mode='zero'), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xview_val')) +data['test'] = data['val'] + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='step', step=[2, 10]) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/b' diff --git a/configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/bm.py b/configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/bm.py new file mode 100644 index 00000000..bca45534 --- /dev/null +++ b/configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/bm.py @@ -0,0 +1,43 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + tcn_dropout=0.5, + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['bm']), + dict(type='PadTo', length=300, mode='zero'), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xview_val')) +data['test'] = data['val'] + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='step', step=[2, 10]) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/bm' diff --git a/configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/j.py b/configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/j.py new file mode 100644 index 00000000..d3073e80 --- /dev/null +++ b/configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/j.py @@ -0,0 +1,43 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + tcn_dropout=0.5, + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['j']), + dict(type='PadTo', length=300, mode='zero'), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xview_val')) +data['test'] = data['val'] + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='step', step=[2, 10]) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/j' diff --git a/configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/jm.py b/configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/jm.py new file mode 100644 index 00000000..138e1a8e --- /dev/null +++ b/configs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/jm.py @@ -0,0 +1,43 @@ +model = dict( + type='RecognizerGCN', + backbone=dict( + type='STGCN', + tcn_dropout=0.5, + graph_cfg=dict(layout='coco', mode='stgcn_spatial')), + cls_head=dict(type='GCNHead', num_classes=60, in_channels=256)) + +dataset_type = 'PoseDataset' +ann_file = 'data/nturgbd/ntu60_hrnet.pkl' +pipeline = [ + dict(type='PreNormalize2D'), + dict(type='GenSkeFeat', dataset='coco', feats=['jm']), + dict(type='PadTo', length=300, mode='zero'), + dict(type='PoseDecode'), + dict(type='FormatGCNInput', num_person=2), + dict(type='Collect', keys=['keypoint', 'label'], meta_keys=[]), + dict(type='ToTensor', keys=['keypoint']) +] +data = dict( + videos_per_gpu=16, + workers_per_gpu=2, + test_dataloader=dict(videos_per_gpu=1), + train=dict( + type='RepeatDataset', + times=5, + dataset=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xview_train')), + val=dict(type=dataset_type, ann_file=ann_file, pipeline=pipeline, split='xview_val')) +data['test'] = data['val'] + +# optimizer +optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict(policy='step', step=[2, 10]) +total_epochs = 16 +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metrics=['top_k_accuracy']) +log_config = dict(interval=100, hooks=[dict(type='TextLoggerHook')]) + +# runtime settings +log_level = 'INFO' +work_dir = './work_dirs/stgcn/stgcn_vanilla_ntu60_xview_hrnet/jm' diff --git a/demo/demo_posec3d.py b/demo/demo_posec3d.py new file mode 100644 index 00000000..18d06e23 --- /dev/null +++ b/demo/demo_posec3d.py @@ -0,0 +1,255 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import argparse +import os +import os.path as osp +import shutil +import warnings + +import cv2 +import mmcv +import numpy as np +import torch + +from pyskl.apis import inference_recognizer, init_recognizer + +try: + from mmdet.apis import inference_detector, init_detector +except (ImportError, ModuleNotFoundError): + def inference_detector(*args, **kwargs): + pass + + def init_detector(*args, **kwargs): + pass + warnings.warn( + 'Failed to import `inference_detector` and `init_detector` from `mmdet.apis`. ' + 'Make sure you can successfully import these if you want to use related features. ' + ) + +try: + from mmpose.apis import init_pose_model, inference_top_down_pose_model, vis_pose_result +except (ImportError, ModuleNotFoundError): + def init_pose_model(*args, **kwargs): + pass + + def inference_top_down_pose_model(*args, **kwargs): + pass + + def vis_pose_result(*args, **kwargs): + pass + + warnings.warn( + 'Failed to import `init_pose_model`, `inference_top_down_pose_model`, `vis_pose_result` from ' + '`mmpose.apis`. Make sure you can successfully import these if you want to use related features. ' + ) + + +try: + import moviepy.editor as mpy +except ImportError: + raise ImportError('Please install moviepy to enable output file') + +FONTFACE = cv2.FONT_HERSHEY_DUPLEX +FONTSCALE = 0.75 +FONTCOLOR = (255, 255, 255) # BGR, white +THICKNESS = 1 +LINETYPE = 1 + + +def parse_args(): + parser = argparse.ArgumentParser(description='PoseC3D demo') + parser.add_argument('video', help='video file/url') + parser.add_argument('out_filename', help='output filename') + parser.add_argument( + '--config', + default=('configs/posec3d/slowonly_r50_u48_240e_ntu120_xsub_keypoint.py'), + help='posec3d config file path') + parser.add_argument( + '--checkpoint', + default=('https://download.openmmlab.com/mmaction/skeleton/posec3d/' + 'slowonly_r50_u48_240e_ntu120_xsub_keypoint/' + 'slowonly_r50_u48_240e_ntu120_xsub_keypoint-6736b03f.pth'), + help='posec3d checkpoint file/url') + parser.add_argument( + '--det-config', + default='demo/faster_rcnn_r50_fpn_2x_coco.py', + help='human detection config file path (from mmdet)') + parser.add_argument( + '--det-checkpoint', + default=('http://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/' + 'faster_rcnn_r50_fpn_2x_coco/' + 'faster_rcnn_r50_fpn_2x_coco_' + 'bbox_mAP-0.384_20200504_210434-a5d8aa15.pth'), + help='human detection checkpoint file/url') + parser.add_argument( + '--pose-config', + default='demo/hrnet_w32_coco_256x192.py', + help='human pose estimation config file path (from mmpose)') + parser.add_argument( + '--pose-checkpoint', + default=('https://download.openmmlab.com/mmpose/top_down/hrnet/' + 'hrnet_w32_coco_256x192-c78dce93_20200708.pth'), + help='human pose estimation checkpoint file/url') + parser.add_argument( + '--det-score-thr', + type=float, + default=0.9, + help='the threshold of human detection score') + parser.add_argument( + '--label-map', + default='tools/data/skeleton/label_map_ntu120.txt', + help='label map file') + parser.add_argument( + '--device', type=str, default='cuda:0', help='CPU/CUDA device option') + parser.add_argument( + '--short-side', + type=int, + default=480, + help='specify the short-side length of the image') + args = parser.parse_args() + return args + + +def frame_extraction(video_path, short_side): + """Extract frames given video_path. + + Args: + video_path (str): The video_path. + """ + # Load the video, extract frames into ./tmp/video_name + target_dir = osp.join('./tmp', osp.basename(osp.splitext(video_path)[0])) + os.makedirs(target_dir, exist_ok=True) + # Should be able to handle videos up to several hours + frame_tmpl = osp.join(target_dir, 'img_{:06d}.jpg') + vid = cv2.VideoCapture(video_path) + frames = [] + frame_paths = [] + flag, frame = vid.read() + cnt = 0 + new_h, new_w = None, None + while flag: + if new_h is None: + h, w, _ = frame.shape + new_w, new_h = mmcv.rescale_size((w, h), (short_side, np.Inf)) + + frame = mmcv.imresize(frame, (new_w, new_h)) + + frames.append(frame) + frame_path = frame_tmpl.format(cnt + 1) + frame_paths.append(frame_path) + + cv2.imwrite(frame_path, frame) + cnt += 1 + flag, frame = vid.read() + + return frame_paths, frames + + +def detection_inference(args, frame_paths): + """Detect human boxes given frame paths. + + Args: + args (argparse.Namespace): The arguments. + frame_paths (list[str]): The paths of frames to do detection inference. + + Returns: + list[np.ndarray]: The human detection results. + """ + model = init_detector(args.det_config, args.det_checkpoint, args.device) + assert model.CLASSES[0] == 'person', ('We require you to use a detector ' + 'trained on COCO') + results = [] + print('Performing Human Detection for each frame') + prog_bar = mmcv.ProgressBar(len(frame_paths)) + for frame_path in frame_paths: + result = inference_detector(model, frame_path) + # We only keep human detections with score larger than det_score_thr + result = result[0][result[0][:, 4] >= args.det_score_thr] + results.append(result) + prog_bar.update() + return results + + +def pose_inference(args, frame_paths, det_results): + model = init_pose_model(args.pose_config, args.pose_checkpoint, + args.device) + ret = [] + print('Performing Human Pose Estimation for each frame') + prog_bar = mmcv.ProgressBar(len(frame_paths)) + for f, d in zip(frame_paths, det_results): + # Align input format + d = [dict(bbox=x) for x in list(d)] + pose = inference_top_down_pose_model(model, f, d, format='xyxy')[0] + ret.append(pose) + prog_bar.update() + return ret + + +def main(): + args = parse_args() + + frame_paths, original_frames = frame_extraction(args.video, + args.short_side) + num_frame = len(frame_paths) + h, w, _ = original_frames[0].shape + + # Get clip_len, frame_interval and calculate center index of each clip + config = mmcv.Config.fromfile(args.config) + + model = init_recognizer(config, args.checkpoint, args.device) + + # Load label_map + label_map = [x.strip() for x in open(args.label_map).readlines()] + + # Get Human detection results + det_results = detection_inference(args, frame_paths) + torch.cuda.empty_cache() + + pose_results = pose_inference(args, frame_paths, det_results) + torch.cuda.empty_cache() + + fake_anno = dict( + frame_dir='', + label=-1, + img_shape=(h, w), + original_shape=(h, w), + start_index=0, + modality='Pose', + total_frames=num_frame) + num_person = max([len(x) for x in pose_results]) + # Current PoseC3D models are trained on COCO-keypoints (17 keypoints) + num_keypoint = 17 + keypoint = np.zeros((num_person, num_frame, num_keypoint, 2), + dtype=np.float16) + keypoint_score = np.zeros((num_person, num_frame, num_keypoint), + dtype=np.float16) + for i, poses in enumerate(pose_results): + for j, pose in enumerate(poses): + pose = pose['keypoints'] + keypoint[j, i] = pose[:, :2] + keypoint_score[j, i] = pose[:, 2] + fake_anno['keypoint'] = keypoint + fake_anno['keypoint_score'] = keypoint_score + + results = inference_recognizer(model, fake_anno) + + action_label = label_map[results[0][0]] + + pose_model = init_pose_model(args.pose_config, args.pose_checkpoint, + args.device) + vis_frames = [ + vis_pose_result(pose_model, frame_paths[i], pose_results[i]) + for i in range(num_frame) + ] + for frame in vis_frames: + cv2.putText(frame, action_label, (10, 30), FONTFACE, FONTSCALE, + FONTCOLOR, THICKNESS, LINETYPE) + + vid = mpy.ImageSequenceClip([x[:, :, ::-1] for x in vis_frames], fps=24) + vid.write_videofile(args.out_filename, remove_temp=True) + + tmp_frame_dir = osp.dirname(frame_paths[0]) + shutil.rmtree(tmp_frame_dir) + + +if __name__ == '__main__': + main() diff --git a/demo/faster_rcnn_r50_fpn_2x_coco.py b/demo/faster_rcnn_r50_fpn_2x_coco.py new file mode 100644 index 00000000..33fc5645 --- /dev/null +++ b/demo/faster_rcnn_r50_fpn_2x_coco.py @@ -0,0 +1,181 @@ +# model config +model = dict( + type='FasterRCNN', + pretrained='torchvision://resnet50', + backbone=dict( + type='ResNet', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + frozen_stages=1, + norm_cfg=dict(type='BN', requires_grad=True), + norm_eval=True, + style='pytorch'), + neck=dict( + type='FPN', + in_channels=[256, 512, 1024, 2048], + out_channels=256, + num_outs=5), + rpn_head=dict( + type='RPNHead', + in_channels=256, + feat_channels=256, + anchor_generator=dict( + type='AnchorGenerator', + scales=[8], + ratios=[0.5, 1.0, 2.0], + strides=[4, 8, 16, 32, 64]), + bbox_coder=dict( + type='DeltaXYWHBBoxCoder', + target_means=[.0, .0, .0, .0], + target_stds=[1.0, 1.0, 1.0, 1.0]), + loss_cls=dict( + type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0), + loss_bbox=dict(type='L1Loss', loss_weight=1.0)), + roi_head=dict( + type='StandardRoIHead', + bbox_roi_extractor=dict( + type='SingleRoIExtractor', + roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0), + out_channels=256, + featmap_strides=[4, 8, 16, 32]), + bbox_head=dict( + type='Shared2FCBBoxHead', + in_channels=256, + fc_out_channels=1024, + roi_feat_size=7, + num_classes=80, + bbox_coder=dict( + type='DeltaXYWHBBoxCoder', + target_means=[0., 0., 0., 0.], + target_stds=[0.1, 0.1, 0.2, 0.2]), + reg_class_agnostic=False, + loss_cls=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0), + loss_bbox=dict(type='L1Loss', loss_weight=1.0))), + # model training and testing settings + train_cfg=dict( + rpn=dict( + assigner=dict( + type='MaxIoUAssigner', + pos_iou_thr=0.7, + neg_iou_thr=0.3, + min_pos_iou=0.3, + match_low_quality=True, + ignore_iof_thr=-1), + sampler=dict( + type='RandomSampler', + num=256, + pos_fraction=0.5, + neg_pos_ub=-1, + add_gt_as_proposals=False), + allowed_border=-1, + pos_weight=-1, + debug=False), + rpn_proposal=dict( + nms_pre=2000, + max_per_img=1000, + nms=dict(type='nms', iou_threshold=0.7), + min_bbox_size=0), + rcnn=dict( + assigner=dict( + type='MaxIoUAssigner', + pos_iou_thr=0.5, + neg_iou_thr=0.5, + min_pos_iou=0.5, + match_low_quality=False, + ignore_iof_thr=-1), + sampler=dict( + type='RandomSampler', + num=512, + pos_fraction=0.25, + neg_pos_ub=-1, + add_gt_as_proposals=True), + pos_weight=-1, + debug=False)), + test_cfg=dict( + rpn=dict( + nms_pre=1000, + max_per_img=1000, + nms=dict(type='nms', iou_threshold=0.7), + min_bbox_size=0), + rcnn=dict( + score_thr=0.05, + nms=dict(type='nms', iou_threshold=0.5), + max_per_img=100))) + +# dataset config +dataset_type = 'CocoDataset' +data_root = 'data/coco/' +img_norm_cfg = dict( + mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations', with_bbox=True), + dict(type='Resize', img_scale=(1333, 800), keep_ratio=True), + dict(type='RandomFlip', flip_ratio=0.5), + dict(type='Normalize', **img_norm_cfg), + dict(type='Pad', size_divisor=32), + dict(type='DefaultFormatBundle'), + dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']), +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict( + type='MultiScaleFlipAug', + img_scale=(1333, 800), + flip=False, + transforms=[ + dict(type='Resize', keep_ratio=True), + dict(type='RandomFlip'), + dict(type='Normalize', **img_norm_cfg), + dict(type='Pad', size_divisor=32), + dict(type='ImageToTensor', keys=['img']), + dict(type='Collect', keys=['img']), + ]) +] +data = dict( + samples_per_gpu=2, + workers_per_gpu=2, + train=dict( + type=dataset_type, + ann_file=data_root + 'annotations/instances_train2017.json', + img_prefix=data_root + 'train2017/', + pipeline=train_pipeline), + val=dict( + type=dataset_type, + ann_file=data_root + 'annotations/instances_val2017.json', + img_prefix=data_root + 'val2017/', + pipeline=test_pipeline), + test=dict( + type=dataset_type, + ann_file=data_root + 'annotations/instances_val2017.json', + img_prefix=data_root + 'val2017/', + pipeline=test_pipeline)) +evaluation = dict(interval=1, metric='bbox') +# Schedule +# optimizer +optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict( + policy='step', + warmup='linear', + warmup_iters=500, + warmup_ratio=0.001, + step=[16, 22]) +total_epochs = 24 +# runtime +checkpoint_config = dict(interval=1) +# yapf:disable +log_config = dict( + interval=50, + hooks=[ + dict(type='TextLoggerHook'), + ]) +# yapf:enable +dist_params = dict(backend='nccl') +log_level = 'INFO' +load_from = None +resume_from = None +workflow = [('train', 1)] diff --git a/demo/hrnet_w32_coco_256x192.py b/demo/hrnet_w32_coco_256x192.py new file mode 100644 index 00000000..6ef3b6ef --- /dev/null +++ b/demo/hrnet_w32_coco_256x192.py @@ -0,0 +1,172 @@ +log_level = 'INFO' +load_from = None +resume_from = None +dist_params = dict(backend='nccl') +workflow = [('train', 1)] +checkpoint_config = dict(interval=10) +evaluation = dict(interval=10, metric='mAP', key_indicator='AP') + +optimizer = dict( + type='Adam', + lr=5e-4, +) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict( + policy='step', + warmup='linear', + warmup_iters=500, + warmup_ratio=0.001, + step=[170, 200]) +total_epochs = 210 +log_config = dict( + interval=50, + hooks=[ + dict(type='TextLoggerHook'), + # dict(type='TensorboardLoggerHook') + ]) + +channel_cfg = dict( + num_output_channels=17, + dataset_joints=17, + dataset_channel=[ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + ], + inference_channel=[ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + ]) + +# model settings +model = dict( + type='TopDown', + pretrained='https://download.openmmlab.com/mmpose/' + 'pretrain_models/hrnet_w32-36af842e.pth', + backbone=dict( + type='HRNet', + in_channels=3, + extra=dict( + stage1=dict( + num_modules=1, + num_branches=1, + block='BOTTLENECK', + num_blocks=(4, ), + num_channels=(64, )), + stage2=dict( + num_modules=1, + num_branches=2, + block='BASIC', + num_blocks=(4, 4), + num_channels=(32, 64)), + stage3=dict( + num_modules=4, + num_branches=3, + block='BASIC', + num_blocks=(4, 4, 4), + num_channels=(32, 64, 128)), + stage4=dict( + num_modules=3, + num_branches=4, + block='BASIC', + num_blocks=(4, 4, 4, 4), + num_channels=(32, 64, 128, 256))), + ), + keypoint_head=dict( + type='TopdownHeatmapSimpleHead', + in_channels=32, + out_channels=channel_cfg['num_output_channels'], + num_deconv_layers=0, + extra=dict(final_conv_kernel=1, ), + loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True)), + train_cfg=dict(), + test_cfg=dict( + flip_test=True, + post_process='default', + shift_heatmap=True, + modulate_kernel=11)) + +data_cfg = dict( + image_size=[192, 256], + heatmap_size=[48, 64], + num_output_channels=channel_cfg['num_output_channels'], + num_joints=channel_cfg['dataset_joints'], + dataset_channel=channel_cfg['dataset_channel'], + inference_channel=channel_cfg['inference_channel'], + soft_nms=False, + nms_thr=1.0, + oks_thr=0.9, + vis_thr=0.2, + use_gt_bbox=False, + det_bbox_thr=0.0, + bbox_file='data/coco/person_detection_results/' + 'COCO_val2017_detections_AP_H_56_person.json', +) + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownRandomFlip', flip_prob=0.5), + dict( + type='TopDownHalfBodyTransform', + num_joints_half_body=8, + prob_half_body=0.3), + dict( + type='TopDownGetRandomScaleRotation', rot_factor=40, scale_factor=0.5), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict(type='TopDownGenerateTarget', sigma=2), + dict( + type='Collect', + keys=['img', 'target', 'target_weight'], + meta_keys=[ + 'image_file', 'joints_3d', 'joints_3d_visible', 'center', 'scale', + 'rotation', 'bbox_score', 'flip_pairs' + ]), +] + +val_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict( + type='Collect', + keys=['img'], + meta_keys=[ + 'image_file', 'center', 'scale', 'rotation', 'bbox_score', + 'flip_pairs' + ]), +] + +test_pipeline = val_pipeline + +data_root = 'data/coco' +data = dict( + samples_per_gpu=64, + workers_per_gpu=2, + val_dataloader=dict(samples_per_gpu=32), + test_dataloader=dict(samples_per_gpu=32), + train=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/person_keypoints_train2017.json', + img_prefix=f'{data_root}/train2017/', + data_cfg=data_cfg, + pipeline=train_pipeline), + val=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/person_keypoints_val2017.json', + img_prefix=f'{data_root}/val2017/', + data_cfg=data_cfg, + pipeline=val_pipeline), + test=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/person_keypoints_val2017.json', + img_prefix=f'{data_root}/val2017/', + data_cfg=data_cfg, + pipeline=val_pipeline), +) diff --git a/demo/ntu_sample.avi b/demo/ntu_sample.avi new file mode 100644 index 0000000000000000000000000000000000000000..42f8e03b1e3a294e026b340ac8bb3b94e66effb0 GIT binary patch literal 1119546 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° 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 P_~4-3LguabJPZ?A{-c8jU|j^{cwQm0R)o4;s!~ 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⋘3!T>JMjROvmnzilxH1N=|2pOBSFfW&RT)Y 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 C|h}QzjvZ_E=h8{B07oC>lC-1)7EI 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 Ul;(6x@oj-&~% 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:skG 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

Ux+Qt!J@v;F=gLHkVI3Q3V0c#QiL4bsg*9 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

9@rw)c4@QBfCTi*=659 z;IXX4Y{@dR2tGi|ey54-$LuaVXTdC_&x>jl()d~i`5!^tE2aRj@IvwO@H$HWR*76X zwH9fgG!Um!4Dt=d&}2L(U~-22miDvdp}f9cn~x!?y9L6$J4g` zDMmk7IEhTrVbC-HFjG#AjZOev_joZ+t>XJZQ)_Q!bkm9hW+@1(po%pOmuOUgQaEqb ziDOQJD^v$PySouZU25ysK7ZMTV%50QVq34a!DRLRfcrXqSF>Eryf(T{rda)p>Teo* zMy*TIAH66WsNNlFi(v$(4!STcs4(TYMd%zRQ^1ttfd{P6}H+gzR zd~KPO#;{l!IC}2Py3d*3q%k_Z96q-(2J|o)7GJ*?cmYjfm4J8?J8|&JU3&3Nv6Dnq zrCv;HR1M|68g%uIikMTcA2x`$?SyzRLSEMzxW3V`K3JOT$4u^4N`tSe5JHWol6ZhR z+}xfXrs2*Tq;#bfLblLOxW{-}>!DvUPeRl_>)Op3gbmn8_3rhPM@j#LLl#v$9v7l#baNRy!-=K@K{jH%xVGo9YB4Rr_<}+%AZpV77aXLv! zrF$fu!r8zH)eZ(rl}9?gD5`QX8?Er5IQ1tA(VklZW5~GsY&1go+ef4Tex^Q3^-6$3 zCpq87=<;!pKplR0MDC^bwRtNxgS=Pg)WJqJYsVBkX;OI?fPx0y1xm}SpE2%+h^Lv{ z-|~U;>Q67!aQJqX5N?&9cNwUY>Im-9a#I6Z^V*I&57UHeJ#-;aABhrm@ss@r$*V=ce#IDX|FpA;p zU!Mj{oyfs42&zH>G#E8YRP&Gz-~D=g@o$KX|Mt>har3a(RLkt`E)%GL=wlr~b$sWs zzo6tdi&O&{Zqy7O!k77OLbVU4=Cp%mfDAf?s5@bg=4IgqM?$Q8r`K1$JknGm?uJ-U@x#3e{^vLIU0UP8H59H*#XS#VP(lNesh`~#Kj<3 z{%7-uJ?pM6q1xroN10|2J5_yRXUbpCFbWE6PjY>>s%_+?vEios&#( z=!w&>!*2tC`pw-0uODivR7$2xrL+EGQWH)85l)&Z_q+iju z$MaypY@dJr_92e!5gP2 z4Mr4Ce1a~Sv&#uU09#Z(9?x59({(zD9)0Ol#|Ro9fQ6$r$gQta1UCDta9i%r&_GUX zIm_B)G(poU>Rd(~+1ifo$lGP?O+AHr6tQ<%u!kHpJu9>Hi?Y9K&F8F_AIfmmG-RZGj(lG&nLlZZrcjShZ!jfv zPPK{3NaRGMiKtI~{jN%SfXxRU$jqz2w`4fx4)Wf$+(ClSuR4951ynx{!!c@^B3x&8 zo8mz1oQOS>3Wr#ofo&>r8W~&|BL@}w8a??s-U!MbAs%2TvDjrO9nydCBm|B=aIz)H z6fCH03OLJ%b3#}qh*soZhQvD)rdd3;e|vQTL^homJZE7M6G<)Zyf!iRE$b8GC-=ZW zSWhi-A$st2Vd_lP9w0;7fIFmlmE9Nv1BH7Jlvsn~?IB3ItLFtr^jC+RENajdv9ew;wP{az<9yANCaLCjdpZx%6#6lD= zzg)Pp@BA7_A^4ScO(ce}!qTNw~rZ^GfFMcLLE#)$z#R>eK*&_FO3?T6i+E2$oC1M;>rZ9lYLK@2+8TF@hYxM zr+N=cG}6C+8d-kx08_Hc-l!L$YrQrWTJ&rz4*!*4-(7;T6R~P;fGM246BLp=t~7B$xYB* zv>u1K_!dNsnr~#<$l!M&qa8njqtH#HsktSIE1RDPg_Nh|N7RNm79VVQyWTqpd{R(C zc}fO;Px?sk>A5|L#j^RQtBd)Rn`^y_MkyNQ6&p}2IYE#U!_$^pZlTNzVgWvsbuf0Z z8jC&Lx-9h#-r|u)dei-eK_^8%j+Lz)L(!lG4q7kasBZ1h7Ha9x`yYldB=0ep{me8# z?(>fF#Td{upU|L@X|=FkPS@r$fujD5=@gR@4hv4rqrlz@Zk9IP*+XO$-N2AgHsI@z z5Fkl~-*58qth|FcqBBnGORq(eGQnG?hEKFh^Ms4au0w(kU2%M(s?E4mK}`{u7UZnkHY({HLEv-r;MD1Qb) zV+Y;#UyQ&Ftz?h#0sO@*QuS@wk;b$e3y5e}J;>cLcwDV>jW!6Ho7q^#xSl$u0gTL9 z0P6A4KF2V@5ja7`MZ3k6s;b|tNAE(P$k)ZKMv)*A(iXDT>D{3}mqlk>)?j#EZSUbU zL(0MUEWhb#t<irj})h zkq#hZo*I+gPkK1Yca zJpPD>RRf!}BBpG$rIkV3l?uJ(aoYSTtbhQ zh`GuQB5838TB25QI-*&H=71O1bI5^GPvWq8&NC__05Kc znuqn2!-f^yBH1@4Id65O>4M12QhSKxxNz_{UOQuL_C5&;{H-30?T%54dm2&t5#DM% z2lD4aK=CmAZaF^Ax-N?x)2H>Oc7PNQBy&sKaa)|u7;sg#O~hCzRX#d&WMO|`%Soeu ze@Xeacw)y>FJ3n$gAIs#qbs|Z7PA!>ue--f__iD*OV@|*lL zlTu5GGp3!|uP#!9&5u0fV~|y#uP6i^Is?h~qF_61*Ul1`<|%xwN9)^+>Z7Z|o~X(a zO>v4L8?r;R{fh6skG^L(Ft5-AU~jZY56ZF=ReS1<)(Xm3(;KL&oEFitt*Uo>jZ05G zvvjG}2Ng}lzgzlS$!6q1Yg!IRPk;P=_Rirg?W=kbE zEGv=r&i8L>M+hg9w+qfU}$(MXs^Cno@hq* zLOX&E{W^YCZ&G)Z)M-?8wQ1H-hDn&#X!hP`%?k zMpZs{U&nfotcm<&(MJhQ){p}JSWJ~K9})#zN{E^zHLG+6jt}RNX&9wT*X~v zP|&%Q|IL4SSW+UMAU#0QA>YtLQFz!)3#+2}82bb?6+jCtgW@(R56OiQM=!S{&4gIS zc(kKji&X01(S}#~4fkicd$Pobwpo622w-UOy9wSz^1GT@aDL_$a;c-KR!5|M;9w7LG1{qel4vDXD!f@>JS)6`zK>J ziq9^Pg3qH(U;Kl;4$n#zzt>Ts_0`M|TC&E~(g_hq3-j}wr&_p#i6aTL6~(g*Shn%L z3UEZHrwQK>e=W%ZRhp1Tq<-|%Q^g8b_JVb_19Nphl{jGMpuqFBkVpwnjrP}&H_m;r zpnlAAFBR3z^rNzgP~q$=i(eSDOBp!2^T##6Gg@DpVdpQ8cJ9Em3XvY3PG!JF*LICo zNsC!}{k78%7CVsFL3LF+nbyn0lI@OR1`XWf(XH{OBL>cYs=CHM)nT*}ono(da1TRQ zre1m~W<_~IT97gL@CUEX!7syLn9-GB@J1XxbR&iz$z_#V{eEPMnN!gfiFJOLtHHfc zjeb!N#S~4C^$)1t*FL?sNotJF5%8*deg6>y@`}C!mXNtt-wRTHQK&29_ptjO*xya# zXyhoC-rdu1$LwR@VVnqOAnUuJMish<&;I+W(rx-~qPy}aBql#CyOkI$cUB;CTV^$1 zE3-HEQ)cg#G$ELClG}9SqL;~Q*$y5cSMzBM{f3D+&sC!Jl_8{m|ws072Vo+tbqdy!EJNp&77=GFLd zq+^6iEJj=>NIlu*+9A3#{N@Nr1bbA0@%=~K(Di%7XmI38P9yISs2ho0Cu(rewVH2$ zT4pm>2##mS@gLXIT1AWIis)spnZhUaR~H*AzJx_PtR6;%Fk!_wb#g~~T-#q=eQ0{( zlbpQEO-}+?(2B#TQVKvSvXot` z!9prIK3T|mx^v`>ZXozbf;lXU=^DZ~ww__77CjIq92=h2zQ^umK`6S_Vqu^7 zdNRF-_^4OM;LOBpdU~AP4;b{ty(DQj@kdRFi=8?R-YXQBvY^q&+Q8;en3u>gXTVu0Q+6R~-Wwd2KU=gT-LPSuQ*1$GkCD!t0JS!p zh{*d8f7@e=UXG-uU7Xsm!OhDx4dE&Y9!-*7CmfHs;Msj{@x%e!E(iKIQ}vh zNVuCeOw>Lv)U~^%Dg88(=t*FYQBlRC}*u6KEE%tuh(SIRH+iXHT^kR1sDAz zH+yBY5Ek{$Tb#=GrA=UK}pyNV}?+aI!oUI zVh$dauo)w;m@(4Uxg%K{Zt;USrSv2SDumY zHF2(7zbhoGG_dY>Rs$iQ*>H!AWu4@STv{B<9(f@`jd>iarN)(&I0to2E%wxzE>pj6+#(@lF(|=)D5nh`($k5{Q6O*e zVb_Ko3{RVm33f(I4oc`i4Zi_*Q9Um5H-jwiy3(0^#@ zo-vLy9`KTD+BU4VnV*J!=WA2Rygtx@c{P|C(X4pB6~q|Ivm5VI#uKSp4yG9nM*S15 zv?cIzj)gXSo&@f;)}MT#s$Ee{aNND3V1z4{V7Iz>27O&k#Rk2$r=g$hW06bKQ zu@@bA$^PfhkMSFG{1^VQT#ys08jV2dnhWXPHS-O|253Ihnjhc-8H?w(ZMS{=ZqZm_ zsuVWIpZ0~cyWc~-mOP^2HAl1VC$2u7-*QZ)FPg-$1UTb3^2~XRLSzxJ63e{}pE}v6 z-um_QQABH1kPcHmoSyS3qJD|c1yn+Ybr?3215jjC3>yEoGj^Oa@-c6oPsI|h+(E&f zymA;E7E{gYF@Ex{faJ(f&)qZg?@3V7qtfeWu5o||MS0XA?+AVC?TPg;`2Njx#$PZf z-R{GQeu=D0%%mkjuA2B_;aQNGiQj+6iaqjS@>BZEWexDel1%!TP7U+8uqs&`MCTl% zUUhdGO_Zrv$NP54PAbK2q(9t{A)= zDrj*Ja8dA08Y~Ds|H!x%xk`~o-)J}j`IQSrG5U&!1Lh*(69dgajsr2`-r{hk$!XjN zuk~9Z{~&M;$`B5sbk`0$FjUVKg*lpDGd?56B!Ti0t>5uY4RkQK?P)UTjM>Ngc6+Ao zkH=^*mW5YL>gE%`O2G&VCrDR&#dY2?7TB+>}YLJO<%M@dTLDf=V#ZVL(`K%4_)eb#z8u-&5OJNS== z%<(=`9j)7ARA41aE>m^s8wfe;eTw8kg*QNt7rsXu@E>BHvcg#zlPr|zi0`2{FOKeK z&TkuzP}$|xitMU4>@L8`oW5N7A01~z#A)kmzRcN?$U}lfO-X~7=q`G#8~(XAyItT= z$^%~N5>Bway5-Sn2d0M*Dtk-VWp-TVJp9l==+4}p@n>vZ2gB@W->#j@Dyc50`h<_E zrKBUdE=Y40CG1vUgpw(BOzAuqhlba-*MmJoQJ=i~)M<-`ow{JI>oaFr3E$|v=3Za#Egv7j)R`53VkAG6UNySJyn49(GYfI_=f|x@ zbs03scc7!pJs+opS};U5l91vax<+`Mce&@0#uLKb-=iLkZ{mph+o1ezvBM2$oh2rehCEqDJSnwDKt>u48(<&r!W}xm$$$)3>)NOu!r)q@f8q^)YKZPgJ|`aN%43qTt%uVRSsN()2f^<-aW}RL>qOp{?6mLY++& zY0TuVwIo;DX-~6hL`>2kPmV|YDu2BcrK%?@(TSN8w5*-XksL}fbL%@<2mU!fDGWbS z9=AY3d$uyvU*5S=-0bb4=B;CZ=vSNq1Kvm;2%n;0U^IGnrynoZK4QZWXh)`jwCri9 ztm3H<+&?rK|DX(P)0}RW83_1}k#)7CYTCX7yRwhBJZm7ejWhU#&w$n1l8p5X%v~EK>x_4p*T%WU&$x-1VPp$#U0d>fLknEL> zRwi(G1g&OCc&#$zg}R`Nd$RK;GR-c&Wc7e1C``EAB5{C&*X_n-&r!;NzquXxg;1`C zt)j*Zcw%sujf2$Puoo`|0~~~6r1Z=NA!&>KX&A0bk`HLw!dZES5K0)&-n6L#jamqI ziii7%o~A58>)r$>MB9;L&K5t1*b>nR16;`^scWUJ_T|OdXqQ+I-wvPE^m7H6r)!5t zBnw0NXdLrY$slZ%zicAnJeXxUFXelP5VeanZpSiA@INe(q z4ZS(^(d*G>jG;$&n8CiJo&@altPIzbl2SsGF8urL69BN`! zFEgzAd!^+ay+{rDEr=Tei7L?UE$nra+F;xp9T1qkh>izb z>KAm$%c2`S4IXV`u$^+dMwKEi7o2A0AtKN1$$)Da-GtA=0q|bueq);bBrJ4k zQ{`-zB9Ck{&ib4_AJ`n6AWH_sNjA8?cs)>e5v5Cxyg84a5x{EjT`6%Yk*U{$ulRr! zCST%OtM1sNaZ(WMD4jA7e20RYL~B*p#6YBPcJ#o+mm&3q3jy5TP8AoT!Bi<8u~D%< z>?B{Wrcg9N<`E}5^IKI%TXXBDMs-GhbN1T#OT27z|zE>(GL{xzunOh|E3H6Jp?RY{6GJfJ$Uf< znA`cwRK`Gn8=o(e>;M4@7{5G;0t`^H`Z9$NFkqSN%h1KZfEK+kkAi>z%!$9uMGgWG zRrzw5CkVig=*x&XAb{6`FQW>A0zR3)jOzjlSflwepa2xmtM=vLCs2T%`IqSozyL4Q zUuK8`1Duwr3OipM3_dnJ#hXyeIvwkUw&;UWoukl-*(0~QwFLx8b0Mh>Enf{k=`rrMc zCjg8N86J@N z&we}=zyoytiR(1M1ISFj#z$Zy0J6S)nT`Viz=Qo|M0Y$-}kQn0Ua RL6T literal 0 HcmV?d00001 diff --git a/demo/vis_skeleton.ipynb b/demo/vis_skeleton.ipynb new file mode 100644 index 00000000..b0028331 --- /dev/null +++ b/demo/vis_skeleton.ipynb @@ -0,0 +1,113 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import glob\n", + "from pyskl.smp import *\n", + "from pyskl.utils.visualize import Vis3DPose, Vis2DPose\n", + "from mmcv import load, dump" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Download annotations\n", + "download_file('http://download.openmmlab.com/mmaction/pyskl/demo/annotations/ntu60_samples_hrnet.pkl', 'ntu60_2d.pkl')\n", + "download_file('http://download.openmmlab.com/mmaction/pyskl/demo/annotations/ntu60_samples_3danno.pkl', 'ntu60_3d.pkl')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Visualize 2D Skeletons without video\n", + "annotations = load('ntu60_2d.pkl')\n", + "index = 0\n", + "anno = annotations[index]\n", + "vid = Vis2DPose(anno, thre=0.2, out_shape=(540, 960), layout='coco', fps=12, video=None)\n", + "vid.ipython_display()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Visualize 2D Skeletons with the original RGB Video\n", + "annotations = load('ntu60_2d.pkl')\n", + "index = 0\n", + "anno = annotations[index]\n", + "frame_dir = anno['frame_dir']\n", + "video_url = f\"http://download.openmmlab.com/mmaction/pyskl/demo/nturgbd/{frame_dir}.avi\"\n", + "download_file(video_url, frame_dir + '.avi')\n", + "vid = Vis2DPose(anno, thre=0.2, out_shape=(540, 960), layout='coco', fps=12, video=frame_dir + '.avi')\n", + "vid.ipython_display()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Visualize 3D Skeletons\n", + "from pyskl.datasets.pipelines import PreNormalize3D\n", + "annotations = load('ntu60_3d.pkl')\n", + "index = 0\n", + "anno = annotations[index]\n", + "anno = PreNormalize3D()(anno) # * Need Pre-Normalization before Visualization\n", + "vid = Vis3DPose(anno, layout='nturgb+d', fps=12, angle=(30, 45), fig_size=(8, 8), dpi=80)\n", + "vid = vid.vis()\n", + "vid.ipython_display()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Clean directories\n", + "os.remove('ntu60_3d.pkl')\n", + "os.remove('ntu60_2d.pkl')\n", + "for f in glob.glob(\"S*.avi\"):\n", + " os.remove(f)\n", + "os.remove('__temp__.mp4')" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "8516388d98336f8f25b57d66898c29467d9fc2c465b9ee1e16d04a4702b7bff1" + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/demo/visualize_heatmap_volume.ipynb b/demo/visualize_heatmap_volume.ipynb new file mode 100644 index 00000000..39d4ff37 --- /dev/null +++ b/demo/visualize_heatmap_volume.ipynb @@ -0,0 +1,403 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 6, + "id": "speaking-algebra", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import cv2\n", + "import os.path as osp\n", + "import decord\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import urllib\n", + "import moviepy.editor as mpy\n", + "import random as rd\n", + "from mmpose.apis import vis_pose_result\n", + "from mmpose.models import TopDown\n", + "from mmcv import load, dump\n", + "\n", + "# We assume the annotation is already prepared\n", + "gym_train_ann_file = '../data/skeleton/gym_train.pkl'\n", + "gym_val_ann_file = '../data/skeleton/gym_val.pkl'\n", + "ntu60_xsub_train_ann_file = '../data/skeleton/ntu60_xsub_train.pkl'\n", + "ntu60_xsub_val_ann_file = '../data/skeleton/ntu60_xsub_val.pkl'" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "alive-consolidation", + "metadata": {}, + "outputs": [], + "source": [ + "FONTFACE = cv2.FONT_HERSHEY_DUPLEX\n", + "FONTSCALE = 0.6\n", + "FONTCOLOR = (255, 255, 255)\n", + "BGBLUE = (0, 119, 182)\n", + "THICKNESS = 1\n", + "LINETYPE = 1" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "ranging-conjunction", + "metadata": {}, + "outputs": [], + "source": [ + "def add_label(frame, label, BGCOLOR=BGBLUE):\n", + " threshold = 30\n", + " def split_label(label):\n", + " label = label.split()\n", + " lines, cline = [], ''\n", + " for word in label:\n", + " if len(cline) + len(word) < threshold:\n", + " cline = cline + ' ' + word\n", + " else:\n", + " lines.append(cline)\n", + " cline = word\n", + " if cline != '':\n", + " lines += [cline]\n", + " return lines\n", + " \n", + " if len(label) > 30:\n", + " label = split_label(label)\n", + " else:\n", + " label = [label]\n", + " label = ['Action: '] + label\n", + " \n", + " sizes = []\n", + " for line in label:\n", + " sizes.append(cv2.getTextSize(line, FONTFACE, FONTSCALE, THICKNESS)[0])\n", + " box_width = max([x[0] for x in sizes]) + 10\n", + " text_height = sizes[0][1]\n", + " box_height = len(sizes) * (text_height + 6)\n", + " \n", + " cv2.rectangle(frame, (0, 0), (box_width, box_height), BGCOLOR, -1)\n", + " for i, line in enumerate(label):\n", + " location = (5, (text_height + 6) * i + text_height + 3)\n", + " cv2.putText(frame, line, location, FONTFACE, FONTSCALE, FONTCOLOR, THICKNESS, LINETYPE)\n", + " return frame\n", + " \n", + "\n", + "def vis_skeleton(vid_path, anno, category_name=None, ratio=0.5):\n", + " vid = decord.VideoReader(vid_path)\n", + " frames = [x.asnumpy() for x in vid]\n", + " \n", + " h, w, _ = frames[0].shape\n", + " new_shape = (int(w * ratio), int(h * ratio))\n", + " frames = [cv2.resize(f, new_shape) for f in frames]\n", + " \n", + " assert len(frames) == anno['total_frames']\n", + " # The shape is N x T x K x 3\n", + " kps = np.concatenate([anno['keypoint'], anno['keypoint_score'][..., None]], axis=-1)\n", + " kps[..., :2] *= ratio\n", + " # Convert to T x N x K x 3\n", + " kps = kps.transpose([1, 0, 2, 3])\n", + " vis_frames = []\n", + "\n", + " # we need an instance of TopDown model, so build a minimal one\n", + " model = TopDown(backbone=dict(type='ShuffleNetV1'))\n", + "\n", + " for f, kp in zip(frames, kps):\n", + " bbox = np.zeros([0, 4], dtype=np.float32)\n", + " result = [dict(bbox=bbox, keypoints=k) for k in kp]\n", + " vis_frame = vis_pose_result(model, f, result)\n", + " \n", + " if category_name is not None:\n", + " vis_frame = add_label(vis_frame, category_name)\n", + " \n", + " vis_frames.append(vis_frame)\n", + " return vis_frames" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "applied-humanity", + "metadata": {}, + "outputs": [], + "source": [ + "keypoint_pipeline = [\n", + " dict(type='PoseDecode'),\n", + " dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True),\n", + " dict(type='Resize', scale=(-1, 64)),\n", + " dict(type='CenterCrop', crop_size=64),\n", + " dict(type='GeneratePoseTarget', with_kp=True, with_limb=False)\n", + "]\n", + "\n", + "limb_pipeline = [\n", + " dict(type='PoseDecode'),\n", + " dict(type='PoseCompact', hw_ratio=1., allow_imgpad=True),\n", + " dict(type='Resize', scale=(-1, 64)),\n", + " dict(type='CenterCrop', crop_size=64),\n", + " dict(type='GeneratePoseTarget', with_kp=False, with_limb=True)\n", + "]\n", + "\n", + "from pyskl.datasets.pipelines import Compose\n", + "def get_pseudo_heatmap(anno, flag='keypoint'):\n", + " assert flag in ['keypoint', 'limb']\n", + " pipeline = Compose(keypoint_pipeline if flag == 'keypoint' else limb_pipeline)\n", + " return pipeline(anno)['imgs']\n", + "\n", + "def vis_heatmaps(heatmaps, channel=-1, ratio=8):\n", + " # if channel is -1, draw all keypoints / limbs on the same map\n", + " import matplotlib.cm as cm\n", + " h, w, _ = heatmaps[0].shape\n", + " newh, neww = int(h * ratio), int(w * ratio)\n", + " \n", + " if channel == -1:\n", + " heatmaps = [np.max(x, axis=-1) for x in heatmaps]\n", + " cmap = cm.viridis\n", + " heatmaps = [(cmap(x)[..., :3] * 255).astype(np.uint8) for x in heatmaps]\n", + " heatmaps = [cv2.resize(x, (neww, newh)) for x in heatmaps]\n", + " return heatmaps" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "automatic-commons", + "metadata": {}, + "outputs": [], + "source": [ + "# Load GYM annotations\n", + "lines = list(urllib.request.urlopen('https://sdolivia.github.io/FineGym/resources/dataset/gym99_categories.txt'))\n", + "gym_categories = [x.decode().strip().split('; ')[-1] for x in lines]\n", + "gym_annos = load(gym_train_ann_file) + load(gym_val_ann_file)" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "id": "numerous-bristol", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--2021-04-25 22:18:53-- https://download.openmmlab.com/mmaction/posec3d/gym_samples.tar\n", + "Resolving download.openmmlab.com (download.openmmlab.com)... 124.160.145.22\n", + "Connecting to download.openmmlab.com (download.openmmlab.com)|124.160.145.22|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 36300800 (35M) [application/x-tar]\n", + "Saving to: ‘gym_samples.tar’\n", + "\n", + "100%[======================================>] 36,300,800 11.5MB/s in 3.0s \n", + "\n", + "2021-04-25 22:18:58 (11.5 MB/s) - ‘gym_samples.tar’ saved [36300800/36300800]\n", + "\n" + ] + } + ], + "source": [ + "# download sample videos of GYM\n", + "!wget https://download.openmmlab.com/mmaction/posec3d/gym_samples.tar\n", + "!tar -xf gym_samples.tar\n", + "!rm gym_samples.tar" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "id": "ranging-harrison", + "metadata": {}, + "outputs": [], + "source": [ + "gym_root = 'gym_samples/'\n", + "gym_vids = os.listdir(gym_root)\n", + "# visualize pose of which video? index in 0 - 50.\n", + "idx = 1\n", + "vid = gym_vids[idx]\n", + "\n", + "frame_dir = vid.split('.')[0]\n", + "vid_path = osp.join(gym_root, vid)\n", + "anno = [x for x in gym_annos if x['frame_dir'] == frame_dir][0]" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "id": "fitting-courage", + "metadata": {}, + "outputs": [], + "source": [ + "# Visualize Skeleton\n", + "vis_frames = vis_skeleton(vid_path, anno, gym_categories[anno['label']])\n", + "vid = mpy.ImageSequenceClip(vis_frames, fps=24)\n", + "vid.ipython_display()" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "id": "orange-logging", + "metadata": {}, + "outputs": [], + "source": [ + "keypoint_heatmap = get_pseudo_heatmap(anno)\n", + "keypoint_mapvis = vis_heatmaps(keypoint_heatmap)\n", + "keypoint_mapvis = [add_label(f, gym_categories[anno['label']]) for f in keypoint_mapvis]\n", + "vid = mpy.ImageSequenceClip(keypoint_mapvis, fps=24)\n", + "vid.ipython_display()" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "id": "residential-conjunction", + "metadata": {}, + "outputs": [], + "source": [ + "limb_heatmap = get_pseudo_heatmap(anno, 'limb')\n", + "limb_mapvis = vis_heatmaps(limb_heatmap)\n", + "limb_mapvis = [add_label(f, gym_categories[anno['label']]) for f in limb_mapvis]\n", + "vid = mpy.ImageSequenceClip(limb_mapvis, fps=24)\n", + "vid.ipython_display()" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "id": "coupled-stranger", + "metadata": {}, + "outputs": [], + "source": [ + "# The name list of \n", + "ntu_categories = ['drink water', 'eat meal/snack', 'brushing teeth', 'brushing hair', 'drop', 'pickup', \n", + " 'throw', 'sitting down', 'standing up (from sitting position)', 'clapping', 'reading', \n", + " 'writing', 'tear up paper', 'wear jacket', 'take off jacket', 'wear a shoe', \n", + " 'take off a shoe', 'wear on glasses', 'take off glasses', 'put on a hat/cap', \n", + " 'take off a hat/cap', 'cheer up', 'hand waving', 'kicking something', \n", + " 'reach into pocket', 'hopping (one foot jumping)', 'jump up', \n", + " 'make a phone call/answer phone', 'playing with phone/tablet', 'typing on a keyboard', \n", + " 'pointing to something with finger', 'taking a selfie', 'check time (from watch)', \n", + " 'rub two hands together', 'nod head/bow', 'shake head', 'wipe face', 'salute', \n", + " 'put the palms together', 'cross hands in front (say stop)', 'sneeze/cough', \n", + " 'staggering', 'falling', 'touch head (headache)', 'touch chest (stomachache/heart pain)', \n", + " 'touch back (backache)', 'touch neck (neckache)', 'nausea or vomiting condition', \n", + " 'use a fan (with hand or paper)/feeling warm', 'punching/slapping other person', \n", + " 'kicking other person', 'pushing other person', 'pat on back of other person', \n", + " 'point finger at the other person', 'hugging other person', \n", + " 'giving something to other person', \"touch other person's pocket\", 'handshaking', \n", + " 'walking towards each other', 'walking apart from each other']\n", + "ntu_annos = load(ntu60_xsub_train_ann_file) + load(ntu60_xsub_val_ann_file)" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "id": "critical-review", + "metadata": {}, + "outputs": [], + "source": [ + "ntu_root = 'ntu_samples/'\n", + "ntu_vids = os.listdir(ntu_root)\n", + "# visualize pose of which video? index in 0 - 50.\n", + "idx = 20\n", + "vid = ntu_vids[idx]\n", + "\n", + "frame_dir = vid.split('.')[0]\n", + "vid_path = osp.join(ntu_root, vid)\n", + "anno = [x for x in ntu_annos if x['frame_dir'] == frame_dir.split('_')[0]][0]\n" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "id": "seasonal-palmer", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--2021-04-25 22:21:16-- https://download.openmmlab.com/mmaction/posec3d/ntu_samples.tar\n", + "Resolving download.openmmlab.com (download.openmmlab.com)... 124.160.145.22\n", + "Connecting to download.openmmlab.com (download.openmmlab.com)|124.160.145.22|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 121753600 (116M) [application/x-tar]\n", + "Saving to: ‘ntu_samples.tar’\n", + "\n", + "100%[======================================>] 121,753,600 14.4MB/s in 9.2s \n", + "\n", + "2021-04-25 22:21:26 (12.6 MB/s) - ‘ntu_samples.tar’ saved [121753600/121753600]\n", + "\n" + ] + } + ], + "source": [ + "# download sample videos of NTU-60\n", + "!wget https://download.openmmlab.com/mmaction/posec3d/ntu_samples.tar\n", + "!tar -xf ntu_samples.tar\n", + "!rm ntu_samples.tar" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "id": "accompanied-invitation", + "metadata": {}, + "outputs": [], + "source": [ + "vis_frames = vis_skeleton(vid_path, anno, ntu_categories[anno['label']])\n", + "vid = mpy.ImageSequenceClip(vis_frames, fps=24)\n", + "vid.ipython_display()" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "id": "respiratory-conclusion", + "metadata": {}, + "outputs": [], + "source": [ + "keypoint_heatmap = get_pseudo_heatmap(anno)\n", + "keypoint_mapvis = vis_heatmaps(keypoint_heatmap)\n", + "keypoint_mapvis = [add_label(f, gym_categories[anno['label']]) for f in keypoint_mapvis]\n", + "vid = mpy.ImageSequenceClip(keypoint_mapvis, fps=24)\n", + "vid.ipython_display()" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "id": "thirty-vancouver", + "metadata": {}, + "outputs": [], + "source": [ + "limb_heatmap = get_pseudo_heatmap(anno, 'limb')\n", + "limb_mapvis = vis_heatmaps(limb_heatmap)\n", + "limb_mapvis = [add_label(f, gym_categories[anno['label']]) for f in limb_mapvis]\n", + "vid = mpy.ImageSequenceClip(limb_mapvis, fps=24)\n", + "vid.ipython_display()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/pyskl/__init__.py b/pyskl/__init__.py new file mode 100644 index 00000000..72a2a34d --- /dev/null +++ b/pyskl/__init__.py @@ -0,0 +1,16 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import mmcv +from mmcv import digit_version + +from .version import __version__ + +mmcv_minimum_version = '1.3.6' +mmcv_maximum_version = '1.5.0' +mmcv_version = digit_version(mmcv.__version__) + +assert (digit_version(mmcv_minimum_version) <= mmcv_version + <= digit_version(mmcv_maximum_version)), \ + f'MMCV=={mmcv.__version__} is used but incompatible. ' \ + f'Please install mmcv>={mmcv_minimum_version}, <={mmcv_maximum_version}.' + +__all__ = ['__version__'] diff --git a/pyskl/apis/__init__.py b/pyskl/apis/__init__.py new file mode 100644 index 00000000..777f6eb8 --- /dev/null +++ b/pyskl/apis/__init__.py @@ -0,0 +1,10 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from mmcv.engine import multi_gpu_test, single_gpu_test + +from .inference import inference_recognizer, init_recognizer +from .train import init_random_seed, train_model + +__all__ = [ + 'train_model', 'init_recognizer', 'inference_recognizer', 'multi_gpu_test', + 'single_gpu_test', 'init_random_seed' +] diff --git a/pyskl/apis/inference.py b/pyskl/apis/inference.py new file mode 100644 index 00000000..2c005438 --- /dev/null +++ b/pyskl/apis/inference.py @@ -0,0 +1,182 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os +import os.path as osp +import re +import warnings +from operator import itemgetter + +import mmcv +import numpy as np +import torch +from mmcv.parallel import collate, scatter +from mmcv.runner import load_checkpoint + +from pyskl.core import OutputHook +from pyskl.datasets.pipelines import Compose +from pyskl.models import build_recognizer + + +def init_recognizer(config, checkpoint=None, device='cuda:0', **kwargs): + """Initialize a recognizer from config file. + + Args: + config (str | :obj:`mmcv.Config`): Config file path or the config + object. + checkpoint (str | None, optional): Checkpoint path/url. If set to None, + the model will not load any weights. Default: None. + device (str | :obj:`torch.device`): The desired device of returned + tensor. Default: 'cuda:0'. + + Returns: + nn.Module: The constructed recognizer. + """ + if 'use_frames' in kwargs: + warnings.warn('The argument `use_frames` is deprecated PR #1191. ' + 'Now you can use models trained with frames or videos ' + 'arbitrarily. ') + + if isinstance(config, str): + config = mmcv.Config.fromfile(config) + elif not isinstance(config, mmcv.Config): + raise TypeError('config must be a filename or Config object, ' + f'but got {type(config)}') + + # pretrained model is unnecessary since we directly load checkpoint later + config.model.backbone.pretrained = None + model = build_recognizer(config.model) + + if checkpoint is not None: + load_checkpoint(model, checkpoint, map_location='cpu') + model.cfg = config + model.to(device) + model.eval() + return model + + +def inference_recognizer(model, video, outputs=None, as_tensor=True, **kwargs): + """Inference a video with the recognizer. + + Args: + model (nn.Module): The loaded recognizer. + video (str | dict | ndarray): The video file path / url or the + rawframes directory path / results dictionary (the input of + pipeline) / a 4D array T x H x W x 3 (The input video). + outputs (list(str) | tuple(str) | str | None) : Names of layers whose + outputs need to be returned, default: None. + as_tensor (bool): Same as that in ``OutputHook``. Default: True. + + Returns: + dict[tuple(str, float)]: Top-5 recognition result dict. + dict[torch.tensor | np.ndarray]: + Output feature maps from layers specified in `outputs`. + """ + if 'use_frames' in kwargs: + warnings.warn('The argument `use_frames` is deprecated PR #1191. ' + 'Now you can use models trained with frames or videos ' + 'arbitrarily. ') + if 'label_path' in kwargs: + warnings.warn('The argument `use_frames` is deprecated PR #1191. ' + 'Now the label file is not needed in ' + 'inference_recognizer. ') + + input_flag = None + if isinstance(video, dict): + input_flag = 'dict' + elif isinstance(video, np.ndarray): + assert len(video.shape) == 4, 'The shape should be T x H x W x C' + input_flag = 'array' + elif isinstance(video, str) and video.startswith('http'): + input_flag = 'video' + elif isinstance(video, str) and osp.exists(video): + if osp.isfile(video): + input_flag = 'video' + if osp.isdir(video): + input_flag = 'rawframes' + else: + raise RuntimeError('The type of argument video is not supported: ' + f'{type(video)}') + + if isinstance(outputs, str): + outputs = (outputs, ) + assert outputs is None or isinstance(outputs, (tuple, list)) + + cfg = model.cfg + device = next(model.parameters()).device # model device + # build the data pipeline + test_pipeline = cfg.data.test.pipeline + # Alter data pipelines & prepare inputs + if input_flag == 'dict': + data = video + if input_flag == 'array': + modality_map = {2: 'Flow', 3: 'RGB'} + modality = modality_map.get(video.shape[-1]) + data = dict( + total_frames=video.shape[0], + label=-1, + start_index=0, + array=video, + modality=modality) + for i in range(len(test_pipeline)): + if 'Decode' in test_pipeline[i]['type']: + test_pipeline[i] = dict(type='ArrayDecode') + if input_flag == 'video': + data = dict(filename=video, label=-1, start_index=0, modality='RGB') + if 'Init' not in test_pipeline[0]['type']: + test_pipeline = [dict(type='OpenCVInit')] + test_pipeline + else: + test_pipeline[0] = dict(type='OpenCVInit') + for i in range(len(test_pipeline)): + if 'Decode' in test_pipeline[i]['type']: + test_pipeline[i] = dict(type='OpenCVDecode') + if input_flag == 'rawframes': + filename_tmpl = cfg.data.test.get('filename_tmpl', 'img_{:05}.jpg') + modality = cfg.data.test.get('modality', 'RGB') + start_index = cfg.data.test.get('start_index', 1) + + # count the number of frames that match the format of `filename_tmpl` + # RGB pattern example: img_{:05}.jpg -> ^img_\d+.jpg$ + # Flow patteren example: {}_{:05d}.jpg -> ^x_\d+.jpg$ + pattern = f'^{filename_tmpl}$' + if modality == 'Flow': + pattern = pattern.replace('{}', 'x') + pattern = pattern.replace( + pattern[pattern.find('{'):pattern.find('}') + 1], '\\d+') + total_frames = len( + list( + filter(lambda x: re.match(pattern, x) is not None, + os.listdir(video)))) + data = dict( + frame_dir=video, + total_frames=total_frames, + label=-1, + start_index=start_index, + filename_tmpl=filename_tmpl, + modality=modality) + if 'Init' in test_pipeline[0]['type']: + test_pipeline = test_pipeline[1:] + for i in range(len(test_pipeline)): + if 'Decode' in test_pipeline[i]['type']: + test_pipeline[i] = dict(type='RawFrameDecode') + + test_pipeline = Compose(test_pipeline) + data = test_pipeline(data) + data = collate([data], samples_per_gpu=1) + + if next(model.parameters()).is_cuda: + # scatter to specified GPU + data = scatter(data, [device])[0] + + # forward the model + with OutputHook(model, outputs=outputs, as_tensor=as_tensor) as h: + with torch.no_grad(): + scores = model(return_loss=False, **data)[0] + returned_features = h.layer_outputs if outputs else None + + num_classes = scores.shape[-1] + score_tuples = tuple(zip(range(num_classes), scores)) + score_sorted = sorted(score_tuples, key=itemgetter(1), reverse=True) + + top5_label = score_sorted[:5] + if outputs: + return top5_label, returned_features + return top5_label diff --git a/pyskl/apis/train.py b/pyskl/apis/train.py new file mode 100644 index 00000000..615cc777 --- /dev/null +++ b/pyskl/apis/train.py @@ -0,0 +1,215 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os +import os.path as osp +import time + +import numpy as np +import torch +import torch.distributed as dist +from mmcv.engine import multi_gpu_test +from mmcv.parallel import MMDistributedDataParallel +from mmcv.runner import DistSamplerSeedHook, EpochBasedRunner, OptimizerHook, build_optimizer, get_dist_info + +from ..core import DistEvalHook +from ..datasets import build_dataloader, build_dataset +from ..utils import get_root_logger + + +def init_random_seed(seed=None, device='cuda'): + """Initialize random seed. + + If the seed is not set, the seed will be automatically randomized, + and then broadcast to all processes to prevent some potential bugs. + Args: + seed (int, Optional): The seed. Default to None. + device (str): The device where the seed will be put on. + Default to 'cuda'. + Returns: + int: Seed to be used. + """ + if seed is not None: + return seed + + # Make sure all ranks share the same random seed to prevent + # some potential bugs. Please refer to + # https://github.com/open-mmlab/mmdetection/issues/6339 + rank, world_size = get_dist_info() + seed = np.random.randint(2**31) + + if world_size == 1: + return seed + + if rank == 0: + random_num = torch.tensor(seed, dtype=torch.int32, device=device) + else: + random_num = torch.tensor(0, dtype=torch.int32, device=device) + + dist.broadcast(random_num, src=0) + return random_num.item() + + +def train_model(model, + dataset, + cfg, + validate=False, + test=dict(test_best=False, test_last=False), + timestamp=None, + meta=None): + """Train model entry function. + + Args: + model (nn.Module): The model to be trained. + dataset (:obj:`Dataset`): Train dataset. + cfg (dict): The config dict for training. + validate (bool): Whether to do evaluation. Default: False. + test (dict): The testing option, with two keys: test_last & test_best. + The value is True or False, indicating whether to test the + corresponding checkpoint. + Default: dict(test_best=False, test_last=False). + timestamp (str | None): Local time for runner. Default: None. + meta (dict | None): Meta dict to record some important information. + Default: None + """ + logger = get_root_logger(log_level=cfg.log_level) + + # prepare data loaders + dataset = dataset if isinstance(dataset, (list, tuple)) else [dataset] + + dataloader_setting = dict( + videos_per_gpu=cfg.data.get('videos_per_gpu', 1), + workers_per_gpu=cfg.data.get('workers_per_gpu', 1), + persistent_workers=cfg.data.get('persistent_workers', False), + seed=cfg.seed) + dataloader_setting = dict(dataloader_setting, + **cfg.data.get('train_dataloader', {})) + + data_loaders = [ + build_dataloader(ds, **dataloader_setting) for ds in dataset + ] + + # put model on gpus + find_unused_parameters = cfg.get('find_unused_parameters', False) + # Sets the `find_unused_parameters` parameter in + # torch.nn.parallel.DistributedDataParallel + model = MMDistributedDataParallel( + model.cuda(), + device_ids=[torch.cuda.current_device()], + broadcast_buffers=False, + find_unused_parameters=find_unused_parameters) + + # build runner + optimizer = build_optimizer(model, cfg.optimizer) + + Runner = EpochBasedRunner + runner = Runner( + model, + optimizer=optimizer, + work_dir=cfg.work_dir, + logger=logger, + meta=meta) + # an ugly workaround to make .log and .log.json filenames the same + runner.timestamp = timestamp + + if 'type' not in cfg.optimizer_config: + optimizer_config = OptimizerHook(**cfg.optimizer_config) + else: + optimizer_config = cfg.optimizer_config + + # register hooks + runner.register_training_hooks(cfg.lr_config, optimizer_config, + cfg.checkpoint_config, cfg.log_config, + cfg.get('momentum_config', None)) + runner.register_hook(DistSamplerSeedHook()) + + eval_hook = None + if validate: + eval_cfg = cfg.get('evaluation', {}) + val_dataset = build_dataset(cfg.data.val, dict(test_mode=True)) + dataloader_setting = dict( + videos_per_gpu=cfg.data.get('videos_per_gpu', 1), + workers_per_gpu=cfg.data.get('workers_per_gpu', 1), + persistent_workers=cfg.data.get('persistent_workers', False), + shuffle=False) + dataloader_setting = dict(dataloader_setting, + **cfg.data.get('val_dataloader', {})) + val_dataloader = build_dataloader(val_dataset, **dataloader_setting) + eval_hook = DistEvalHook(val_dataloader, **eval_cfg) + runner.register_hook(eval_hook) + + if cfg.get('resume_from', None): + runner.resume(cfg.resume_from) + elif cfg.get('load_from', None): + runner.load_checkpoint(cfg.load_from) + + runner.run(data_loaders, cfg.workflow, cfg.total_epochs) + + dist.barrier() + time.sleep(2) + + if test['test_last'] or test['test_best']: + best_ckpt_path = None + if test['test_best']: + assert eval_hook is not None + best_ckpt_path = None + ckpt_paths = [x for x in os.listdir(cfg.work_dir) if 'best' in x] + ckpt_paths = [x for x in ckpt_paths if x.endswith('.pth')] + if len(ckpt_paths) == 0: + logger.info('Warning: test_best set, but no ckpt found') + test['test_best'] = False + if not test['test_last']: + return + elif len(ckpt_paths) > 1: + epoch_ids = [ + int(x.split('epoch_')[-1][:-4]) for x in ckpt_paths + ] + best_ckpt_path = ckpt_paths[np.argmax(epoch_ids)] + else: + best_ckpt_path = ckpt_paths[0] + if best_ckpt_path: + best_ckpt_path = osp.join(cfg.work_dir, best_ckpt_path) + + test_dataset = build_dataset(cfg.data.test, dict(test_mode=True)) + gpu_collect = cfg.get('evaluation', {}).get('gpu_collect', False) + tmpdir = cfg.get('evaluation', {}).get('tmpdir', + osp.join(cfg.work_dir, 'tmp')) + dataloader_setting = dict( + videos_per_gpu=cfg.data.get('videos_per_gpu', 1), + workers_per_gpu=cfg.data.get('workers_per_gpu', 1), + persistent_workers=cfg.data.get('persistent_workers', False), + shuffle=False) + dataloader_setting = dict(dataloader_setting, + **cfg.data.get('test_dataloader', {})) + + test_dataloader = build_dataloader(test_dataset, **dataloader_setting) + + names, ckpts = [], [] + + if test['test_last']: + names.append('last') + ckpts.append(None) + if test['test_best']: + names.append('best') + ckpts.append(best_ckpt_path) + + for name, ckpt in zip(names, ckpts): + if ckpt is not None: + runner.load_checkpoint(ckpt) + + outputs = multi_gpu_test(runner.model, test_dataloader, tmpdir, + gpu_collect) + rank, _ = get_dist_info() + if rank == 0: + out = osp.join(cfg.work_dir, f'{name}_pred.pkl') + test_dataset.dump_results(outputs, out) + + eval_cfg = cfg.get('evaluation', {}) + for key in [ + 'interval', 'tmpdir', 'start', 'gpu_collect', + 'save_best', 'rule', 'by_epoch', 'broadcast_bn_buffers' + ]: + eval_cfg.pop(key, None) + + eval_res = test_dataset.evaluate(outputs, **eval_cfg) + logger.info(f'Testing results of the {name} checkpoint') + for metric_name, val in eval_res.items(): + logger.info(f'{metric_name}: {val:.04f}') diff --git a/pyskl/core/__init__.py b/pyskl/core/__init__.py new file mode 100644 index 00000000..fdba2bb4 --- /dev/null +++ b/pyskl/core/__init__.py @@ -0,0 +1,3 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .evaluation import * # noqa: F401, F403 +from .hooks import * # noqa: F401, F403 diff --git a/pyskl/core/evaluation.py b/pyskl/core/evaluation.py new file mode 100644 index 00000000..8f355199 --- /dev/null +++ b/pyskl/core/evaluation.py @@ -0,0 +1,191 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import numpy as np +from mmcv.runner import DistEvalHook as BasicDistEvalHook + + +class DistEvalHook(BasicDistEvalHook): + greater_keys = [ + 'acc', 'top', 'AR@', 'auc', 'precision', 'mAP@', 'Recall@' + ] + less_keys = ['loss'] + + def __init__(self, *args, save_best='auto', **kwargs): + super().__init__(*args, save_best=save_best, **kwargs) + + +def confusion_matrix(y_pred, y_real, normalize=None): + """Compute confusion matrix. + + Args: + y_pred (list[int] | np.ndarray[int]): Prediction labels. + y_real (list[int] | np.ndarray[int]): Ground truth labels. + normalize (str | None): Normalizes confusion matrix over the true + (rows), predicted (columns) conditions or all the population. + If None, confusion matrix will not be normalized. Options are + "true", "pred", "all", None. Default: None. + + Returns: + np.ndarray: Confusion matrix. + """ + if normalize not in ['true', 'pred', 'all', None]: + raise ValueError("normalize must be one of {'true', 'pred', " + "'all', None}") + + if isinstance(y_pred, list): + y_pred = np.array(y_pred) + if not isinstance(y_pred, np.ndarray): + raise TypeError( + f'y_pred must be list or np.ndarray, but got {type(y_pred)}') + if not y_pred.dtype == np.int64: + raise TypeError( + f'y_pred dtype must be np.int64, but got {y_pred.dtype}') + + if isinstance(y_real, list): + y_real = np.array(y_real) + if not isinstance(y_real, np.ndarray): + raise TypeError( + f'y_real must be list or np.ndarray, but got {type(y_real)}') + if not y_real.dtype == np.int64: + raise TypeError( + f'y_real dtype must be np.int64, but got {y_real.dtype}') + + label_set = np.unique(np.concatenate((y_pred, y_real))) + num_labels = len(label_set) + max_label = label_set[-1] + label_map = np.zeros(max_label + 1, dtype=np.int64) + for i, label in enumerate(label_set): + label_map[label] = i + + y_pred_mapped = label_map[y_pred] + y_real_mapped = label_map[y_real] + + confusion_mat = np.bincount( + num_labels * y_real_mapped + y_pred_mapped, + minlength=num_labels**2).reshape(num_labels, num_labels) + + with np.errstate(all='ignore'): + if normalize == 'true': + confusion_mat = ( + confusion_mat / confusion_mat.sum(axis=1, keepdims=True)) + elif normalize == 'pred': + confusion_mat = ( + confusion_mat / confusion_mat.sum(axis=0, keepdims=True)) + elif normalize == 'all': + confusion_mat = (confusion_mat / confusion_mat.sum()) + confusion_mat = np.nan_to_num(confusion_mat) + + return confusion_mat + + +def mean_class_accuracy(scores, labels): + """Calculate mean class accuracy. + + Args: + scores (list[np.ndarray]): Prediction scores for each class. + labels (list[int]): Ground truth labels. + + Returns: + np.ndarray: Mean class accuracy. + """ + pred = np.argmax(scores, axis=1) + cf_mat = confusion_matrix(pred, labels).astype(float) + + cls_cnt = cf_mat.sum(axis=1) + cls_hit = np.diag(cf_mat) + + mean_class_acc = np.mean( + [hit / cnt if cnt else 0.0 for cnt, hit in zip(cls_cnt, cls_hit)]) + + return mean_class_acc + + +def top_k_accuracy(scores, labels, topk=(1, )): + """Calculate top k accuracy score. + + Args: + scores (list[np.ndarray]): Prediction scores for each class. + labels (list[int]): Ground truth labels. + topk (tuple[int]): K value for top_k_accuracy. Default: (1, ). + + Returns: + list[float]: Top k accuracy score for each k. + """ + res = [] + labels = np.array(labels)[:, np.newaxis] + for k in topk: + max_k_preds = np.argsort(scores, axis=1)[:, -k:][:, ::-1] + match_array = np.logical_or.reduce(max_k_preds == labels, axis=1) + topk_acc_score = match_array.sum() / match_array.shape[0] + res.append(topk_acc_score) + + return res + + +def mean_average_precision(scores, labels): + """Mean average precision for multi-label recognition. + + Args: + scores (list[np.ndarray]): Prediction scores of different classes for + each sample. + labels (list[np.ndarray]): Ground truth many-hot vector for each + sample. + + Returns: + np.float: The mean average precision. + """ + results = [] + scores = np.stack(scores).T + labels = np.stack(labels).T + + for score, label in zip(scores, labels): + precision, recall, _ = binary_precision_recall_curve(score, label) + ap = -np.sum(np.diff(recall) * np.array(precision)[:-1]) + results.append(ap) + results = [x for x in results if not np.isnan(x)] + if results == []: + return np.nan + return np.mean(results) + + +def binary_precision_recall_curve(y_score, y_true): + """Calculate the binary precision recall curve at step thresholds. + + Args: + y_score (np.ndarray): Prediction scores for each class. + Shape should be (num_classes, ). + y_true (np.ndarray): Ground truth many-hot vector. + Shape should be (num_classes, ). + + Returns: + precision (np.ndarray): The precision of different thresholds. + recall (np.ndarray): The recall of different thresholds. + thresholds (np.ndarray): Different thresholds at which precision and + recall are tested. + """ + assert isinstance(y_score, np.ndarray) + assert isinstance(y_true, np.ndarray) + assert y_score.shape == y_true.shape + + # make y_true a boolean vector + y_true = (y_true == 1) + # sort scores and corresponding truth values + desc_score_indices = np.argsort(y_score, kind='mergesort')[::-1] + y_score = y_score[desc_score_indices] + y_true = y_true[desc_score_indices] + # There may be ties in values, therefore find the `distinct_value_inds` + distinct_value_inds = np.where(np.diff(y_score))[0] + threshold_inds = np.r_[distinct_value_inds, y_true.size - 1] + # accumulate the true positives with decreasing threshold + tps = np.cumsum(y_true)[threshold_inds] + fps = 1 + threshold_inds - tps + thresholds = y_score[threshold_inds] + + precision = tps / (tps + fps) + precision[np.isnan(precision)] = 0 + recall = tps / tps[-1] + # stop when full recall attained + # and reverse the outputs so recall is decreasing + last_ind = tps.searchsorted(tps[-1]) + sl = slice(last_ind, None, -1) + + return np.r_[precision[sl], 1], np.r_[recall[sl], 0], thresholds[sl] diff --git a/pyskl/core/hooks.py b/pyskl/core/hooks.py new file mode 100644 index 00000000..fb30beba --- /dev/null +++ b/pyskl/core/hooks.py @@ -0,0 +1,68 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import functools +import warnings + +import torch + + +class OutputHook: + """Output feature map of some layers. + + Args: + module (nn.Module): The whole module to get layers. + outputs (tuple[str] | list[str]): Layer name to output. Default: None. + as_tensor (bool): Determine to return a tensor or a numpy array. + Default: False. + """ + + def __init__(self, module, outputs=None, as_tensor=False): + self.outputs = outputs + self.as_tensor = as_tensor + self.layer_outputs = {} + self.handles = [] + self.register(module) + + def register(self, module): + + def hook_wrapper(name): + + def hook(model, input, output): + if not isinstance(output, torch.Tensor): + warnings.warn(f'Directly return the output from {name}, ' + f'since it is not a tensor') + self.layer_outputs[name] = output + elif self.as_tensor: + self.layer_outputs[name] = output + else: + self.layer_outputs[name] = output.detach().cpu().numpy() + + return hook + + if isinstance(self.outputs, (list, tuple)): + for name in self.outputs: + try: + layer = rgetattr(module, name) + h = layer.register_forward_hook(hook_wrapper(name)) + except AttributeError: + raise AttributeError(f'Module {name} not found') + self.handles.append(h) + + def remove(self): + for h in self.handles: + h.remove() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.remove() + + +# using wonder's beautiful simplification: +# https://stackoverflow.com/questions/31174295/getattr-and-setattr-on-nested-objects +def rgetattr(obj, attr, *args): + + def _getattr(obj, attr): + return getattr(obj, attr, *args) + + return functools.reduce(_getattr, [obj] + attr.split('.')) diff --git a/pyskl/datasets/__init__.py b/pyskl/datasets/__init__.py new file mode 100644 index 00000000..a2f6ed8f --- /dev/null +++ b/pyskl/datasets/__init__.py @@ -0,0 +1,11 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .base import BaseDataset +from .builder import DATASETS, PIPELINES, build_dataloader, build_dataset +from .dataset_wrappers import ConcatDataset, RepeatDataset +from .pose_dataset import PoseDataset +from .video_dataset import VideoDataset + +__all__ = [ + 'VideoDataset', 'build_dataloader', 'build_dataset', 'RepeatDataset', + 'BaseDataset', 'DATASETS', 'PIPELINES', 'PoseDataset', 'ConcatDataset' +] diff --git a/pyskl/datasets/base.py b/pyskl/datasets/base.py new file mode 100644 index 00000000..a03e4e03 --- /dev/null +++ b/pyskl/datasets/base.py @@ -0,0 +1,308 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import copy +import os.path as osp +import warnings +from abc import ABCMeta, abstractmethod +from collections import OrderedDict, defaultdict + +import mmcv +import numpy as np +import torch +from mmcv.utils import print_log +from torch.utils.data import Dataset + +from ..core import mean_average_precision, mean_class_accuracy, top_k_accuracy +from .pipelines import Compose + + +class BaseDataset(Dataset, metaclass=ABCMeta): + """Base class for datasets. + + All datasets to process video should subclass it. + All subclasses should overwrite: + + - Methods:`load_annotations`, supporting to load information from an + annotation file. + - Methods:`prepare_train_frames`, providing train data. + - Methods:`prepare_test_frames`, providing test data. + + Args: + ann_file (str): Path to the annotation file. + pipeline (list[dict | callable]): A sequence of data transforms. + data_prefix (str): Path to a directory where videos are held. Default: ''. + test_mode (bool): Store True when building test or validation dataset. + Default: False. + multi_class (bool): Determines whether the dataset is a multi-class + dataset. Default: False. + num_classes (int | None): Number of classes of the dataset, used in + multi-class datasets. Default: None. + start_index (int): Specify a start index for frames in consideration of + different filename format. However, when taking videos as input, + it should be set to 0, since frames loaded from videos count + from 0. Default: 1. + modality (str): Modality of data. Support 'RGB', 'Flow', 'Audio'. + Default: 'RGB'. + sample_by_class (bool): Sampling by class, should be set `True` when + performing inter-class data balancing. Only compatible with + `multi_class == False`. Only applies for training. Default: False. + power (float): We support sampling data with the probability + proportional to the power of its label frequency (freq ^ power) + when sampling data. `power == 1` indicates uniformly sampling all + data; `power == 0` indicates uniformly sampling all classes. + Default: 0. + dynamic_length (bool): If the dataset length is dynamic (used by + ClassSpecificDistributedSampler). Default: False. + """ + + def __init__(self, + ann_file, + pipeline, + data_prefix='', + test_mode=False, + multi_class=False, + num_classes=None, + start_index=1, + modality='RGB', + memcached=False, + mc_cfg=('localhost', 11211), + sample_by_class=False, + power=0, + dynamic_length=False): + super().__init__() + + self.ann_file = ann_file + self.data_prefix = data_prefix + self.test_mode = test_mode + self.multi_class = multi_class + self.num_classes = num_classes + self.start_index = start_index + self.modality = modality + self.sample_by_class = sample_by_class + self.power = power + self.dynamic_length = dynamic_length + # Note: Currently, memcached only works for PoseDataset + self.memcached = memcached + self.mc_cfg = mc_cfg + self.cli = None + + assert not (self.multi_class and self.sample_by_class) + + self.pipeline = Compose(pipeline) + self.video_infos = self.load_annotations() + if self.memcached: + for item in self.video_infos: + assert 'key' in item and isinstance(item['key'], str) + + if self.sample_by_class: + self.video_infos_by_class = self.parse_by_class() + + class_prob = [] + for _, samples in self.video_infos_by_class.items(): + class_prob.append(len(samples) / len(self.video_infos)) + class_prob = [x**self.power for x in class_prob] + + summ = sum(class_prob) + class_prob = [x / summ for x in class_prob] + + self.class_prob = dict(zip(self.video_infos_by_class, class_prob)) + + @abstractmethod + def load_annotations(self): + """Load the annotation according to ann_file into video_infos.""" + + # json annotations already looks like video_infos, so for each dataset, + # this func should be the same + def load_json_annotations(self): + """Load json annotation file to get video information.""" + video_infos = mmcv.load(self.ann_file) + num_videos = len(video_infos) + path_key = 'frame_dir' if 'frame_dir' in video_infos[0] else 'filename' + for i in range(num_videos): + path_value = video_infos[i][path_key] + path_value = osp.join(self.data_prefix, path_value) + video_infos[i][path_key] = path_value + if self.multi_class: + assert self.num_classes is not None + else: + assert len(video_infos[i]['label']) == 1 + video_infos[i]['label'] = video_infos[i]['label'][0] + return video_infos + + def parse_by_class(self): + video_infos_by_class = defaultdict(list) + for item in self.video_infos: + label = item['label'] + video_infos_by_class[label].append(item) + return video_infos_by_class + + @staticmethod + def label2array(num, label): + arr = np.zeros(num, dtype=np.float32) + arr[label] = 1. + return arr + + def evaluate(self, + results, + metrics='top_k_accuracy', + metric_options=dict(top_k_accuracy=dict(topk=(1, 5))), + logger=None, + **deprecated_kwargs): + """Perform evaluation for common datasets. + + Args: + results (list): Output results. + metrics (str | sequence[str]): Metrics to be performed. + Defaults: 'top_k_accuracy'. + metric_options (dict): Dict for metric options. Options are + ``topk`` for ``top_k_accuracy``. + Default: ``dict(top_k_accuracy=dict(topk=(1, 5)))``. + logger (logging.Logger | None): Logger for recording. + Default: None. + deprecated_kwargs (dict): Used for containing deprecated arguments. + See 'https://github.com/open-mmlab/mmaction2/pull/286'. + + Returns: + dict: Evaluation results dict. + """ + if not isinstance(results, list): + raise TypeError(f'results must be a list, but got {type(results)}') + assert len(results) == len(self), ( + f'The length of results is not equal to the dataset len: ' + f'{len(results)} != {len(self)}') + + if isinstance(results[0], list) or isinstance(results[0], tuple): + num_results = len(results[0]) + eval_results = dict() + for i in range(num_results): + eval_results_cur = self.evaluate( + [x[i] for x in results], metrics, metric_options, logger, **deprecated_kwargs) + eval_results.update({f'{k}_{i}': v for k, v in eval_results_cur.items()}) + return eval_results + + # Protect ``metric_options`` since it uses mutable value as default + metric_options = copy.deepcopy(metric_options) + if deprecated_kwargs != {}: + warnings.warn( + 'Option arguments for metrics has been changed to ' + "`metric_options`, See 'https://github.com/open-mmlab/mmaction2/pull/286' " # noqa: E501 + 'for more details') + metric_options['top_k_accuracy'] = dict( + metric_options['top_k_accuracy'], **deprecated_kwargs) + + metrics = metrics if isinstance(metrics, (list, tuple)) else [metrics] + allowed_metrics = ['top_k_accuracy', 'mean_class_accuracy', 'mean_average_precision'] + + for metric in metrics: + if metric not in allowed_metrics: + raise KeyError(f'metric {metric} is not supported') + + eval_results = OrderedDict() + gt_labels = [ann['label'] for ann in self.video_infos] + + for metric in metrics: + msg = f'Evaluating {metric} ...' + if logger is None: + msg = '\n' + msg + print_log(msg, logger=logger) + + if metric == 'top_k_accuracy': + topk = metric_options.setdefault('top_k_accuracy', + {}).setdefault( + 'topk', (1, 5)) + if not isinstance(topk, (int, tuple)): + raise TypeError('topk must be int or tuple of int, ' + f'but got {type(topk)}') + if isinstance(topk, int): + topk = (topk, ) + + top_k_acc = top_k_accuracy(results, gt_labels, topk) + log_msg = [] + for k, acc in zip(topk, top_k_acc): + eval_results[f'top{k}_acc'] = acc + log_msg.append(f'\ntop{k}_acc\t{acc:.4f}') + log_msg = ''.join(log_msg) + print_log(log_msg, logger=logger) + continue + + if metric == 'mean_class_accuracy': + mean_acc = mean_class_accuracy(results, gt_labels) + eval_results['mean_class_accuracy'] = mean_acc + log_msg = f'\nmean_acc\t{mean_acc:.4f}' + print_log(log_msg, logger=logger) + continue + + if metric == 'mean_average_precision': + gt_labels_arrays = [ + self.label2array(self.num_classes, label) + for label in gt_labels + ] + mAP = mean_average_precision(results, gt_labels_arrays) + eval_results['mean_average_precision'] = mAP + log_msg = f'\nmean_average_precision\t{mAP:.4f}' + print_log(log_msg, logger=logger) + continue + + return eval_results + + @staticmethod + def dump_results(results, out): + """Dump data to json/yaml/pickle strings or files.""" + return mmcv.dump(results, out) + + def prepare_train_frames(self, idx): + """Prepare the frames for training given the index.""" + results = copy.deepcopy(self.video_infos[idx]) + if self.memcached and 'key' in results: + if self.cli is None: + from pymemcache.client.base import Client + from pymemcache import serde + self.cli = Client(self.mc_cfg, serde=serde.pickle_serde) + key = results.pop('key') + pack = self.cli.get(key) + for k in pack: + results[k] = pack[k] + + results['modality'] = self.modality + results['start_index'] = self.start_index + + # prepare tensor in getitem + # If HVU, type(results['label']) is dict + if self.multi_class and isinstance(results['label'], list): + onehot = torch.zeros(self.num_classes) + onehot[results['label']] = 1. + results['label'] = onehot + + return self.pipeline(results) + + def prepare_test_frames(self, idx): + """Prepare the frames for testing given the index.""" + results = copy.deepcopy(self.video_infos[idx]) + if self.memcached and 'key' in results: + if self.cli is None: + from pymemcache.client.base import Client + from pymemcache import serde + self.cli = Client(self.mc_cfg, serde=serde.pickle_serde) + key = results.pop('key') + pack = self.cli.get(key) + for k in pack: + results[k] = pack[k] + + results['modality'] = self.modality + results['start_index'] = self.start_index + + # prepare tensor in getitem + # If HVU, type(results['label']) is dict + if self.multi_class and isinstance(results['label'], list): + onehot = torch.zeros(self.num_classes) + onehot[results['label']] = 1. + results['label'] = onehot + + return self.pipeline(results) + + def __len__(self): + """Get the size of the dataset.""" + return len(self.video_infos) + + def __getitem__(self, idx): + """Get the sample for either training or testing given index.""" + return self.prepare_test_frames(idx) if self.test_mode else self.prepare_train_frames(idx) diff --git a/pyskl/datasets/builder.py b/pyskl/datasets/builder.py new file mode 100644 index 00000000..de38e334 --- /dev/null +++ b/pyskl/datasets/builder.py @@ -0,0 +1,124 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import platform +import random +from functools import partial + +import numpy as np +import torch +from mmcv.parallel import collate +from mmcv.runner import get_dist_info +from mmcv.utils import Registry, build_from_cfg, digit_version +from torch.utils.data import DataLoader + +from .samplers import ClassSpecificDistributedSampler, DistributedSampler + +if platform.system() != 'Windows': + # https://github.com/pytorch/pytorch/issues/973 + import resource + rlimit = resource.getrlimit(resource.RLIMIT_NOFILE) + hard_limit = rlimit[1] + soft_limit = min(4096, hard_limit) + resource.setrlimit(resource.RLIMIT_NOFILE, (soft_limit, hard_limit)) + +DATASETS = Registry('dataset') +PIPELINES = Registry('pipeline') + + +def build_dataset(cfg, default_args=None): + """Build a dataset from config dict. + + Args: + cfg (dict): Config dict. It should at least contain the key "type". + default_args (dict | None, optional): Default initialization arguments. + Default: None. + + Returns: + Dataset: The constructed dataset. + """ + dataset = build_from_cfg(cfg, DATASETS, default_args) + return dataset + + +def build_dataloader(dataset, + videos_per_gpu, + workers_per_gpu, + shuffle=True, + seed=None, + drop_last=False, + pin_memory=True, + persistent_workers=False, + **kwargs): + """Build PyTorch DataLoader. + + In distributed training, each GPU/process has a dataloader. + + Args: + dataset (:obj:`Dataset`): A PyTorch dataset. + videos_per_gpu (int): Number of videos on each GPU, i.e., + batch size of each GPU. + workers_per_gpu (int): How many subprocesses to use for data + loading for each GPU. + shuffle (bool): Whether to shuffle the data at every epoch. + Default: True. + seed (int | None): Seed to be used. Default: None. + drop_last (bool): Whether to drop the last incomplete batch in epoch. + Default: False + pin_memory (bool): Whether to use pin_memory in DataLoader. + Default: True + persistent_workers (bool): If True, the data loader will not shutdown + the worker processes after a dataset has been consumed once. + This allows to maintain the workers Dataset instances alive. + The argument also has effect in PyTorch>=1.8.0. + Default: False + kwargs (dict, optional): Any keyword argument to be used to initialize + DataLoader. + + Returns: + DataLoader: A PyTorch dataloader. + """ + rank, world_size = get_dist_info() + + if hasattr(dataset, 'class_prob') and dataset.class_prob is not None: + sampler = ClassSpecificDistributedSampler( + dataset, + world_size, + rank, + class_prob=dataset.class_prob, + shuffle=shuffle, + seed=seed) + else: + sampler = DistributedSampler( + dataset, world_size, rank, shuffle=shuffle, seed=seed) + shuffle = False + batch_size = videos_per_gpu + num_workers = workers_per_gpu + + init_fn = partial( + worker_init_fn, num_workers=num_workers, rank=rank, + seed=seed) if seed is not None else None + + if digit_version(torch.__version__) >= digit_version('1.8.0'): + kwargs['persistent_workers'] = persistent_workers + + data_loader = DataLoader( + dataset, + batch_size=batch_size, + sampler=sampler, + num_workers=num_workers, + collate_fn=partial(collate, samples_per_gpu=videos_per_gpu), + pin_memory=pin_memory, + shuffle=shuffle, + worker_init_fn=init_fn, + drop_last=drop_last, + **kwargs) + + return data_loader + + +def worker_init_fn(worker_id, num_workers, rank, seed): + """Init the random seed for various workers.""" + # The seed of each worker equals to + # num_worker * rank + worker_id + user_seed + worker_seed = num_workers * rank + worker_id + seed + np.random.seed(worker_seed) + random.seed(worker_seed) diff --git a/pyskl/datasets/dataset_wrappers.py b/pyskl/datasets/dataset_wrappers.py new file mode 100644 index 00000000..5de7584c --- /dev/null +++ b/pyskl/datasets/dataset_wrappers.py @@ -0,0 +1,73 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import numpy as np + +from .builder import DATASETS, build_dataset + + +@DATASETS.register_module() +class RepeatDataset: + """A wrapper of repeated dataset. + + The length of repeated dataset will be ``times`` larger than the original + dataset. This is useful when the data loading time is long but the dataset + is small. Using RepeatDataset can reduce the data loading time between + epochs. + + Args: + dataset (dict): The config of the dataset to be repeated. + times (int): Repeat times. + test_mode (bool): Store True when building test or validation dataset. + Default: False. + """ + + def __init__(self, dataset, times, test_mode=False): + dataset['test_mode'] = test_mode + self.dataset = build_dataset(dataset) + self.times = times + if hasattr(dataset, 'class_prob'): + self.class_prob = dataset.class_prob + + self._ori_len = len(self.dataset) + + def __getitem__(self, idx): + """Get data.""" + return self.dataset[idx % self._ori_len] + + def __len__(self): + """Length after repetition.""" + return self.times * self._ori_len + + +@DATASETS.register_module() +class ConcatDataset: + """A wrapper of concatenated dataset. + + The length of concatenated dataset will be the sum of lengths of all + datasets. This is useful when you want to train a model with multiple data + sources. + + Args: + datasets (list[dict]): The configs of the datasets. + test_mode (bool): Store True when building test or validation dataset. + Default: False. + """ + + def __init__(self, datasets, test_mode=False): + + for item in datasets: + item['test_mode'] = test_mode + + datasets = [build_dataset(cfg) for cfg in datasets] + self.datasets = datasets + self.lens = [len(x) for x in self.datasets] + self.cumsum = np.cumsum(self.lens) + + def __getitem__(self, idx): + """Get data.""" + dataset_idx = np.searchsorted(self.cumsum, idx, side='right') + item_idx = idx if dataset_idx == 0 else idx - self.cumsum[dataset_idx] + return self.datasets[dataset_idx][item_idx] + + def __len__(self): + """Length after repetition.""" + return sum(self.lens) diff --git a/pyskl/datasets/pipelines/__init__.py b/pyskl/datasets/pipelines/__init__.py new file mode 100644 index 00000000..3776b3c2 --- /dev/null +++ b/pyskl/datasets/pipelines/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .augmentations import * # noqa: F401, F403 +from .compose import Compose # noqa: F401, F403 +from .formatting import * # noqa: F401, F403 +from .loading import * # noqa: F401, F403 +from .pose_related import * # noqa: F401, F403 +from .posec3d_related import * # noqa: F401, F403 +from .sampling import * # noqa: F401, F403 diff --git a/pyskl/datasets/pipelines/augmentations.py b/pyskl/datasets/pipelines/augmentations.py new file mode 100644 index 00000000..2b653ef7 --- /dev/null +++ b/pyskl/datasets/pipelines/augmentations.py @@ -0,0 +1,1004 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import random +import warnings +from collections.abc import Sequence + +import cv2 +import mmcv +import numpy as np +from torch.nn.modules.utils import _pair + +from ..builder import PIPELINES + + +def _combine_quadruple(a, b): + return (a[0] + a[2] * b[0], a[1] + a[3] * b[1], a[2] * b[2], a[3] * b[3]) + + +def _flip_quadruple(a): + return (1 - a[0] - a[2], a[1], a[2], a[3]) + + +@PIPELINES.register_module() +class PoseCompact: + """Convert the coordinates of keypoints to make it more compact. + Specifically, it first find a tight bounding box that surrounds all joints + in each frame, then we expand the tight box by a given padding ratio. For + example, if 'padding == 0.25', then the expanded box has unchanged center, + and 1.25x width and height. + + Required keys in results are "img_shape", "keypoint", add or modified keys + are "img_shape", "keypoint", "crop_quadruple". + + Args: + padding (float): The padding size. Default: 0.25. + threshold (int): The threshold for the tight bounding box. If the width + or height of the tight bounding box is smaller than the threshold, + we do not perform the compact operation. Default: 10. + hw_ratio (float | tuple[float] | None): The hw_ratio of the expanded + box. Float indicates the specific ratio and tuple indicates a + ratio range. If set as None, it means there is no requirement on + hw_ratio. Default: None. + allow_imgpad (bool): Whether to allow expanding the box outside the + image to meet the hw_ratio requirement. Default: True. + + Returns: + type: Description of returned object. + """ + + def __init__(self, + padding=0.25, + threshold=10, + hw_ratio=None, + allow_imgpad=True): + + self.padding = padding + self.threshold = threshold + if hw_ratio is not None: + hw_ratio = _pair(hw_ratio) + + self.hw_ratio = hw_ratio + + self.allow_imgpad = allow_imgpad + assert self.padding >= 0 + + def __call__(self, results): + img_shape = results['img_shape'] + h, w = img_shape + kp = results['keypoint'] + + # Make NaN zero + kp[np.isnan(kp)] = 0. + kp_x = kp[..., 0] + kp_y = kp[..., 1] + + min_x = np.min(kp_x[kp_x != 0], initial=np.Inf) + min_y = np.min(kp_y[kp_y != 0], initial=np.Inf) + max_x = np.max(kp_x[kp_x != 0], initial=-np.Inf) + max_y = np.max(kp_y[kp_y != 0], initial=-np.Inf) + + # The compact area is too small + if max_x - min_x < self.threshold or max_y - min_y < self.threshold: + return results + + center = ((max_x + min_x) / 2, (max_y + min_y) / 2) + half_width = (max_x - min_x) / 2 * (1 + self.padding) + half_height = (max_y - min_y) / 2 * (1 + self.padding) + + if self.hw_ratio is not None: + half_height = max(self.hw_ratio[0] * half_width, half_height) + half_width = max(1 / self.hw_ratio[1] * half_height, half_width) + + min_x, max_x = center[0] - half_width, center[0] + half_width + min_y, max_y = center[1] - half_height, center[1] + half_height + + # hot update + if not self.allow_imgpad: + min_x, min_y = int(max(0, min_x)), int(max(0, min_y)) + max_x, max_y = int(min(w, max_x)), int(min(h, max_y)) + else: + min_x, min_y = int(min_x), int(min_y) + max_x, max_y = int(max_x), int(max_y) + + kp_x[kp_x != 0] -= min_x + kp_y[kp_y != 0] -= min_y + + new_shape = (max_y - min_y, max_x - min_x) + results['img_shape'] = new_shape + + # the order is x, y, w, h (in [0, 1]), a tuple + crop_quadruple = results.get('crop_quadruple', (0., 0., 1., 1.)) + new_crop_quadruple = (min_x / w, min_y / h, (max_x - min_x) / w, + (max_y - min_y) / h) + crop_quadruple = _combine_quadruple(crop_quadruple, new_crop_quadruple) + results['crop_quadruple'] = crop_quadruple + return results + + def __repr__(self): + repr_str = (f'{self.__class__.__name__}(padding={self.padding}, ' + f'threshold={self.threshold}, ' + f'hw_ratio={self.hw_ratio}, ' + f'allow_imgpad={self.allow_imgpad})') + return repr_str + + +@PIPELINES.register_module() +class RandomCrop: + """Vanilla square random crop that specifics the output size. + + Required keys in results are "img_shape", "keypoint" (optional), "imgs" + (optional), added or modified keys are "keypoint", "imgs". + + Args: + size (int): The output size of the images. + """ + + def __init__(self, size): + if not isinstance(size, int): + raise TypeError(f'Size must be an int, but got {type(size)}') + self.size = size + + @staticmethod + def _crop_kps(kps, crop_bbox): + return kps - crop_bbox[:2] + + @staticmethod + def _crop_imgs(imgs, crop_bbox): + x1, y1, x2, y2 = crop_bbox + return [img[y1:y2, x1:x2] for img in imgs] + + @staticmethod + def _box_crop(box, crop_bbox): + """Crop the bounding boxes according to the crop_bbox. + + Args: + box (np.ndarray): The bounding boxes. + crop_bbox(np.ndarray): The bbox used to crop the original image. + """ + + x1, y1, x2, y2 = crop_bbox + img_w, img_h = x2 - x1, y2 - y1 + + box_ = box.copy() + box_[..., 0::2] = np.clip(box[..., 0::2] - x1, 0, img_w - 1) + box_[..., 1::2] = np.clip(box[..., 1::2] - y1, 0, img_h - 1) + return box_ + + def _all_box_crop(self, results, crop_bbox): + """Crop the gt_bboxes and proposals in results according to crop_bbox. + + Args: + results (dict): All information about the sample, which contain + 'gt_bboxes' and 'proposals' (optional). + crop_bbox(np.ndarray): The bbox used to crop the original image. + """ + results['gt_bboxes'] = self._box_crop(results['gt_bboxes'], crop_bbox) + if 'proposals' in results and results['proposals'] is not None: + assert results['proposals'].shape[1] == 4 + results['proposals'] = self._box_crop(results['proposals'], + crop_bbox) + return results + + def __call__(self, results): + """Performs the RandomCrop augmentation. + + Args: + results (dict): The resulting dict to be modified and passed + to the next transform in pipeline. + """ + img_h, img_w = results['img_shape'] + assert self.size <= img_h and self.size <= img_w + + y_offset = 0 + x_offset = 0 + if img_h > self.size: + y_offset = int(np.random.randint(0, img_h - self.size)) + if img_w > self.size: + x_offset = int(np.random.randint(0, img_w - self.size)) + + if 'crop_quadruple' not in results: + results['crop_quadruple'] = np.array( + [0, 0, 1, 1], # x, y, w, h + dtype=np.float32) + + x_ratio, y_ratio = x_offset / img_w, y_offset / img_h + w_ratio, h_ratio = self.size / img_w, self.size / img_h + + old_crop_quadruple = results['crop_quadruple'] + old_x_ratio, old_y_ratio = old_crop_quadruple[0], old_crop_quadruple[1] + old_w_ratio, old_h_ratio = old_crop_quadruple[2], old_crop_quadruple[3] + new_crop_quadruple = [ + old_x_ratio + x_ratio * old_w_ratio, + old_y_ratio + y_ratio * old_h_ratio, w_ratio * old_w_ratio, + h_ratio * old_h_ratio + ] + results['crop_quadruple'] = np.array( + new_crop_quadruple, dtype=np.float32) + + new_h, new_w = self.size, self.size + + crop_bbox = np.array( + [x_offset, y_offset, x_offset + new_w, y_offset + new_h]) + results['crop_bbox'] = crop_bbox + + results['img_shape'] = (new_h, new_w) + + if 'keypoint' in results: + results['keypoint'] = self._crop_kps(results['keypoint'], crop_bbox) + if 'imgs' in results: + results['imgs'] = self._crop_imgs(results['imgs'], crop_bbox) + + # Process entity boxes + if 'gt_bboxes' in results: + results = self._all_box_crop(results, results['crop_bbox']) + + return results + + def __repr__(self): + repr_str = f'{self.__class__.__name__}(size={self.size})' + return repr_str + + +@PIPELINES.register_module() +class RandomResizedCrop(RandomCrop): + """Random crop that specifics the area and height-weight ratio range. + + Required keys in results are "img_shape", "crop_bbox", "imgs" (optional), + "keypoint" (optional), added or modified keys are "imgs", "keypoint", + "crop_bbox". + + Args: + area_range (Tuple[float]): The candidate area scales range of + output cropped images. Default: (0.08, 1.0). + aspect_ratio_range (Tuple[float]): The candidate aspect ratio range of + output cropped images. Default: (3 / 4, 4 / 3). + """ + + def __init__(self, + area_range=(0.08, 1.0), + aspect_ratio_range=(3 / 4, 4 / 3)): + self.area_range = area_range + self.aspect_ratio_range = aspect_ratio_range + if not mmcv.is_tuple_of(self.area_range, float): + raise TypeError(f'Area_range must be a tuple of float, ' + f'but got {type(area_range)}') + if not mmcv.is_tuple_of(self.aspect_ratio_range, float): + raise TypeError(f'Aspect_ratio_range must be a tuple of float, ' + f'but got {type(aspect_ratio_range)}') + + @staticmethod + def get_crop_bbox(img_shape, + area_range, + aspect_ratio_range, + max_attempts=10): + """Get a crop bbox given the area range and aspect ratio range. + + Args: + img_shape (Tuple[int]): Image shape + area_range (Tuple[float]): The candidate area scales range of + output cropped images. Default: (0.08, 1.0). + aspect_ratio_range (Tuple[float]): The candidate aspect + ratio range of output cropped images. Default: (3 / 4, 4 / 3). + max_attempts (int): The maximum of attempts. Default: 10. + max_attempts (int): Max attempts times to generate random candidate + bounding box. If it doesn't qualified one, the center bounding + box will be used. + Returns: + (list[int]) A random crop bbox within the area range and aspect + ratio range. + """ + assert 0 < area_range[0] <= area_range[1] <= 1 + assert 0 < aspect_ratio_range[0] <= aspect_ratio_range[1] + + img_h, img_w = img_shape + area = img_h * img_w + + min_ar, max_ar = aspect_ratio_range + aspect_ratios = np.exp( + np.random.uniform( + np.log(min_ar), np.log(max_ar), size=max_attempts)) + target_areas = np.random.uniform(*area_range, size=max_attempts) * area + candidate_crop_w = np.round(np.sqrt(target_areas * + aspect_ratios)).astype(np.int32) + candidate_crop_h = np.round(np.sqrt(target_areas / + aspect_ratios)).astype(np.int32) + + for i in range(max_attempts): + crop_w = candidate_crop_w[i] + crop_h = candidate_crop_h[i] + if crop_h <= img_h and crop_w <= img_w: + x_offset = random.randint(0, img_w - crop_w) + y_offset = random.randint(0, img_h - crop_h) + return x_offset, y_offset, x_offset + crop_w, y_offset + crop_h + + # Fallback + crop_size = min(img_h, img_w) + x_offset = (img_w - crop_size) // 2 + y_offset = (img_h - crop_size) // 2 + return x_offset, y_offset, x_offset + crop_size, y_offset + crop_size + + def __call__(self, results): + """Performs the RandomResizeCrop augmentation. + + Args: + results (dict): The resulting dict to be modified and passed + to the next transform in pipeline. + """ + img_h, img_w = results['img_shape'] + + left, top, right, bottom = self.get_crop_bbox( + (img_h, img_w), self.area_range, self.aspect_ratio_range) + new_h, new_w = bottom - top, right - left + + if 'crop_quadruple' not in results: + results['crop_quadruple'] = np.array( + [0, 0, 1, 1], # x, y, w, h + dtype=np.float32) + + x_ratio, y_ratio = left / img_w, top / img_h + w_ratio, h_ratio = new_w / img_w, new_h / img_h + + old_crop_quadruple = results['crop_quadruple'] + old_x_ratio, old_y_ratio = old_crop_quadruple[0], old_crop_quadruple[1] + old_w_ratio, old_h_ratio = old_crop_quadruple[2], old_crop_quadruple[3] + new_crop_quadruple = [ + old_x_ratio + x_ratio * old_w_ratio, + old_y_ratio + y_ratio * old_h_ratio, w_ratio * old_w_ratio, + h_ratio * old_h_ratio + ] + results['crop_quadruple'] = np.array( + new_crop_quadruple, dtype=np.float32) + + crop_bbox = np.array([left, top, right, bottom]) + results['crop_bbox'] = crop_bbox + results['img_shape'] = (new_h, new_w) + + if 'keypoint' in results: + results['keypoint'] = self._crop_kps(results['keypoint'], crop_bbox) + if 'imgs' in results: + results['imgs'] = self._crop_imgs(results['imgs'], crop_bbox) + + if 'gt_bboxes' in results: + results = self._all_box_crop(results, results['crop_bbox']) + + return results + + def __repr__(self): + repr_str = (f'{self.__class__.__name__}(' + f'area_range={self.area_range}, ' + f'aspect_ratio_range={self.aspect_ratio_range})') + return repr_str + + +@PIPELINES.register_module() +class Resize: + """Resize images to a specific size. + + Required keys are "img_shape", "modality", "imgs" (optional), "keypoint" + (optional), added or modified keys are "imgs", "img_shape", "keep_ratio", + "scale_factor", "resize_size". + + Args: + scale (float | Tuple[int]): If keep_ratio is True, it serves as scaling + factor or maximum size: + If it is a float number, the image will be rescaled by this + factor, else if it is a tuple of 2 integers, the image will + be rescaled as large as possible within the scale. + Otherwise, it serves as (w, h) of output size. + keep_ratio (bool): If set to True, Images will be resized without + changing the aspect ratio. Otherwise, it will resize images to a + given size. Default: True. + interpolation (str): Algorithm used for interpolation: + "nearest" | "bilinear". Default: "bilinear". + """ + + def __init__(self, + scale, + keep_ratio=True, + interpolation='bilinear'): + if isinstance(scale, float): + if scale <= 0: + raise ValueError(f'Invalid scale {scale}, must be positive.') + elif isinstance(scale, tuple): + max_long_edge = max(scale) + max_short_edge = min(scale) + if max_short_edge == -1: + # assign np.inf to long edge for rescaling short edge later. + scale = (np.inf, max_long_edge) + else: + raise TypeError( + f'Scale must be float or tuple of int, but got {type(scale)}') + self.scale = scale + self.keep_ratio = keep_ratio + self.interpolation = interpolation + + def _resize_imgs(self, imgs, new_w, new_h): + return [ + mmcv.imresize( + img, (new_w, new_h), interpolation=self.interpolation) + for img in imgs + ] + + @staticmethod + def _resize_kps(kps, scale_factor): + return kps * scale_factor + + @staticmethod + def _box_resize(box, scale_factor): + """Rescale the bounding boxes according to the scale_factor. + + Args: + box (np.ndarray): The bounding boxes. + scale_factor (np.ndarray): The scale factor used for rescaling. + """ + assert len(scale_factor) == 2 + scale_factor = np.concatenate([scale_factor, scale_factor]) + return box * scale_factor + + def __call__(self, results): + """Performs the Resize augmentation. + + Args: + results (dict): The resulting dict to be modified and passed + to the next transform in pipeline. + """ + if 'scale_factor' not in results: + results['scale_factor'] = np.array([1, 1], dtype=np.float32) + img_h, img_w = results['img_shape'] + + if self.keep_ratio: + new_w, new_h = mmcv.rescale_size((img_w, img_h), self.scale) + else: + new_w, new_h = self.scale + + self.scale_factor = np.array([new_w / img_w, new_h / img_h], + dtype=np.float32) + + results['img_shape'] = (new_h, new_w) + results['keep_ratio'] = self.keep_ratio + results['scale_factor'] = results['scale_factor'] * self.scale_factor + + if 'imgs' in results: + results['imgs'] = self._resize_imgs(results['imgs'], new_w, new_h) + if 'keypoint' in results: + results['keypoint'] = self._resize_kps(results['keypoint'], self.scale_factor) + + if 'gt_bboxes' in results: + results['gt_bboxes'] = self._box_resize(results['gt_bboxes'], self.scale_factor) + if 'proposals' in results and results['proposals'] is not None: + assert results['proposals'].shape[1] == 4 + results['proposals'] = self._box_resize( + results['proposals'], self.scale_factor) + + return results + + def __repr__(self): + repr_str = (f'{self.__class__.__name__}(' + f'scale={self.scale}, keep_ratio={self.keep_ratio}, ' + f'interpolation={self.interpolation})') + return repr_str + + +@PIPELINES.register_module() +class Flip: + """Flip the input images with a probability. + + Reverse the order of elements in the given imgs with a specific direction. + The shape of the imgs is preserved, but the elements are reordered. + + Required keys are "img_shape", "modality", "imgs" (optional), "keypoint" + (optional), added or modified keys are "imgs", "keypoint", "flip_direction". + The Flip augmentation should be placed after any cropping / reshaping + augmentations, to make sure crop_quadruple is calculated properly. + + Args: + flip_ratio (float): Probability of implementing flip. Default: 0.5. + direction (str): Flip imgs horizontally or vertically. Options are + "horizontal" | "vertical". Default: "horizontal". + flip_label_map (Dict[int, int] | None): Transform the label of the + flipped image with the specific label. Default: None. + left_kp (list[int]): Indexes of left keypoints, used to flip keypoints. + Default: None. + right_kp (list[ind]): Indexes of right keypoints, used to flip + keypoints. Default: None. + """ + _directions = ['horizontal', 'vertical'] + + def __init__(self, + flip_ratio=0.5, + direction='horizontal', + flip_label_map=None, + left_kp=None, + right_kp=None): + if direction not in self._directions: + raise ValueError(f'Direction {direction} is not supported. ' + f'Currently support ones are {self._directions}') + self.flip_ratio = flip_ratio + self.direction = direction + self.flip_label_map = flip_label_map + self.left_kp = left_kp + self.right_kp = right_kp + + def _flip_imgs(self, imgs, modality): + _ = [mmcv.imflip_(img, self.direction) for img in imgs] + lt = len(imgs) + if modality == 'Flow': + # The 1st frame of each 2 frames is flow-x + for i in range(0, lt, 2): + imgs[i] = mmcv.iminvert(imgs[i]) + return imgs + + def _flip_kps(self, kps, kpscores, img_width): + kp_x = kps[..., 0] + kp_x[kp_x != 0] = img_width - kp_x[kp_x != 0] + new_order = list(range(kps.shape[2])) + if self.left_kp is not None and self.right_kp is not None: + for left, right in zip(self.left_kp, self.right_kp): + new_order[left] = right + new_order[right] = left + kps = kps[:, :, new_order] + if kpscores is not None: + kpscores = kpscores[:, :, new_order] + return kps, kpscores + + @staticmethod + def _box_flip(box, img_width): + """Flip the bounding boxes given the width of the image. + + Args: + box (np.ndarray): The bounding boxes. + img_width (int): The img width. + """ + box_ = box.copy() + box_[..., 0::4] = img_width - box[..., 2::4] + box_[..., 2::4] = img_width - box[..., 0::4] + return box_ + + def __call__(self, results): + """Performs the Flip augmentation. + + Args: + results (dict): The resulting dict to be modified and passed + to the next transform in pipeline. + """ + if 'keypoint' in results: + assert self.direction == 'horizontal', ( + 'Only horizontal flips are' + 'supported for human keypoints') + + modality = results['modality'] + if modality == 'Flow': + assert self.direction == 'horizontal' + + flip = np.random.rand() < self.flip_ratio + + results['flip'] = flip + results['flip_direction'] = self.direction + img_width = results['img_shape'][1] + + if self.flip_label_map is not None and flip: + results['label'] = self.flip_label_map.get(results['label'], + results['label']) + + if flip: + if 'imgs' in results: + results['imgs'] = self._flip_imgs(results['imgs'], modality) + if 'keypoint' in results: + kp = results['keypoint'] + kpscore = results.get('keypoint_score', None) + kp, kpscore = self._flip_kps(kp, kpscore, img_width) + results['keypoint'] = kp + if 'keypoint_score' in results: + results['keypoint_score'] = kpscore + + if 'gt_bboxes' in results and flip: + assert self.direction == 'horizontal' + width = results['img_shape'][1] + results['gt_bboxes'] = self._box_flip(results['gt_bboxes'], width) + if 'proposals' in results and results['proposals'] is not None: + assert results['proposals'].shape[1] == 4 + results['proposals'] = self._box_flip(results['proposals'], + width) + + return results + + def __repr__(self): + repr_str = ( + f'{self.__class__.__name__}(' + f'flip_ratio={self.flip_ratio}, direction={self.direction}, ' + f'flip_label_map={self.flip_label_map})') + return repr_str + + +@PIPELINES.register_module() +class Normalize: + """Normalize images with the given mean and std value. + + Required keys are "imgs", "img_shape", "modality", added or modified + keys are "imgs" and "img_norm_cfg". If modality is 'Flow', additional + keys "scale_factor" is required + + Args: + mean (Sequence[float]): Mean values of different channels. + std (Sequence[float]): Std values of different channels. + to_bgr (bool): Whether to convert channels from RGB to BGR. + Default: False. + adjust_magnitude (bool): Indicate whether to adjust the flow magnitude + on 'scale_factor' when modality is 'Flow'. Default: False. + """ + + def __init__(self, mean, std, to_bgr=False, adjust_magnitude=False): + if not isinstance(mean, Sequence): + raise TypeError( + f'Mean must be list, tuple or np.ndarray, but got {type(mean)}' + ) + + if not isinstance(std, Sequence): + raise TypeError( + f'Std must be list, tuple or np.ndarray, but got {type(std)}') + + self.mean = np.array(mean, dtype=np.float32) + self.std = np.array(std, dtype=np.float32) + self.to_bgr = to_bgr + self.adjust_magnitude = adjust_magnitude + + def __call__(self, results): + modality = results['modality'] + + if modality == 'RGB': + n = len(results['imgs']) + h, w, c = results['imgs'][0].shape + imgs = np.empty((n, h, w, c), dtype=np.float32) + for i, img in enumerate(results['imgs']): + imgs[i] = img + + for img in imgs: + mmcv.imnormalize_(img, self.mean, self.std, self.to_bgr) + + results['imgs'] = imgs + results['img_norm_cfg'] = dict( + mean=self.mean, std=self.std, to_bgr=self.to_bgr) + return results + if modality == 'Flow': + num_imgs = len(results['imgs']) + assert num_imgs % 2 == 0 + assert self.mean.shape[0] == 2 + assert self.std.shape[0] == 2 + n = num_imgs // 2 + h, w = results['imgs'][0].shape + x_flow = np.empty((n, h, w), dtype=np.float32) + y_flow = np.empty((n, h, w), dtype=np.float32) + for i in range(n): + x_flow[i] = results['imgs'][2 * i] + y_flow[i] = results['imgs'][2 * i + 1] + x_flow = (x_flow - self.mean[0]) / self.std[0] + y_flow = (y_flow - self.mean[1]) / self.std[1] + if self.adjust_magnitude: + x_flow = x_flow * results['scale_factor'][0] + y_flow = y_flow * results['scale_factor'][1] + imgs = np.stack([x_flow, y_flow], axis=-1) + results['imgs'] = imgs + args = dict( + mean=self.mean, + std=self.std, + to_bgr=self.to_bgr, + adjust_magnitude=self.adjust_magnitude) + results['img_norm_cfg'] = args + return results + raise NotImplementedError + + def __repr__(self): + repr_str = (f'{self.__class__.__name__}(' + f'mean={self.mean}, ' + f'std={self.std}, ' + f'to_bgr={self.to_bgr}, ' + f'adjust_magnitude={self.adjust_magnitude})') + return repr_str + + +@PIPELINES.register_module() +class ColorJitter: + """Perform ColorJitter to each img. + + Required keys are "imgs", added or modified keys are "imgs". + + Args: + brightness (float | tuple[float]): The jitter range for brightness, if + set as a float, the range will be (1 - brightness, 1 + brightness). + Default: 0.5. + contrast (float | tuple[float]): The jitter range for contrast, if set + as a float, the range will be (1 - contrast, 1 + contrast). + Default: 0.5. + saturation (float | tuple[float]): The jitter range for saturation, if + set as a float, the range will be (1 - saturation, 1 + saturation). + Default: 0.5. + hue (float | tuple[float]): The jitter range for hue, if set as a + float, the range will be (-hue, hue). Default: 0.1. + """ + + @staticmethod + def check_input(val, max, base): + if isinstance(val, tuple): + assert base - max <= val[0] <= val[1] <= base + max + return val + assert val <= max + return (base - val, base + val) + + @staticmethod + def rgb_to_grayscale(img): + return 0.2989 * img[..., 0] + 0.587 * img[..., 1] + 0.114 * img[..., 2] + + @staticmethod + def adjust_contrast(img, factor): + val = np.mean(ColorJitter.rgb_to_grayscale(img)) + return factor * img + (1 - factor) * val + + @staticmethod + def adjust_saturation(img, factor): + gray = np.stack([ColorJitter.rgb_to_grayscale(img)] * 3, axis=-1) + return factor * img + (1 - factor) * gray + + @staticmethod + def adjust_hue(img, factor): + img = np.clip(img, 0, 255).astype(np.uint8) + hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV) + offset = int(factor * 255) + hsv[..., 0] = (hsv[..., 0] + offset) % 180 + img = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB) + return img.astype(np.float32) + + def __init__(self, brightness=0.5, contrast=0.5, saturation=0.5, hue=0.1): + self.brightness = self.check_input(brightness, 1, 1) + self.contrast = self.check_input(contrast, 1, 1) + self.saturation = self.check_input(saturation, 1, 1) + self.hue = self.check_input(hue, 0.5, 0) + self.fn_idx = np.random.permutation(4) + + def __call__(self, results): + imgs = results['imgs'] + num_clips, clip_len = 1, len(imgs) + + new_imgs = [] + for i in range(num_clips): + b = np.random.uniform( + low=self.brightness[0], high=self.brightness[1]) + c = np.random.uniform(low=self.contrast[0], high=self.contrast[1]) + s = np.random.uniform( + low=self.saturation[0], high=self.saturation[1]) + h = np.random.uniform(low=self.hue[0], high=self.hue[1]) + start, end = i * clip_len, (i + 1) * clip_len + + for img in imgs[start:end]: + img = img.astype(np.float32) + for fn_id in self.fn_idx: + if fn_id == 0 and b != 1: + img *= b + if fn_id == 1 and c != 1: + img = self.adjust_contrast(img, c) + if fn_id == 2 and s != 1: + img = self.adjust_saturation(img, s) + if fn_id == 3 and h != 0: + img = self.adjust_hue(img, h) + img = np.clip(img, 0, 255).astype(np.uint8) + new_imgs.append(img) + results['imgs'] = new_imgs + return results + + def __repr__(self): + repr_str = (f'{self.__class__.__name__}(' + f'brightness={self.brightness}, ' + f'contrast={self.contrast}, ' + f'saturation={self.saturation}, ' + f'hue={self.hue})') + return repr_str + + +@PIPELINES.register_module() +class CenterCrop(RandomCrop): + """Crop the center area from images. + + Required keys are "img_shape", "imgs" (optional), "keypoint" (optional), + added or modified keys are "imgs", "keypoint", "crop_bbox", "img_shape". + + Args: + crop_size (int | tuple[int]): (w, h) of crop size. + """ + + def __init__(self, crop_size): + self.crop_size = _pair(crop_size) + if not mmcv.is_tuple_of(self.crop_size, int): + raise TypeError(f'Crop_size must be int or tuple of int, ' + f'but got {type(crop_size)}') + + def __call__(self, results): + """Performs the CenterCrop augmentation. + + Args: + results (dict): The resulting dict to be modified and passed + to the next transform in pipeline. + """ + img_h, img_w = results['img_shape'] + crop_w, crop_h = self.crop_size + + left = (img_w - crop_w) // 2 + top = (img_h - crop_h) // 2 + right = left + crop_w + bottom = top + crop_h + new_h, new_w = bottom - top, right - left + + crop_bbox = np.array([left, top, right, bottom]) + results['crop_bbox'] = crop_bbox + results['img_shape'] = (new_h, new_w) + + if 'crop_quadruple' not in results: + results['crop_quadruple'] = np.array( + [0, 0, 1, 1], # x, y, w, h + dtype=np.float32) + + x_ratio, y_ratio = left / img_w, top / img_h + w_ratio, h_ratio = new_w / img_w, new_h / img_h + + old_crop_quadruple = results['crop_quadruple'] + old_x_ratio, old_y_ratio = old_crop_quadruple[0], old_crop_quadruple[1] + old_w_ratio, old_h_ratio = old_crop_quadruple[2], old_crop_quadruple[3] + new_crop_quadruple = [ + old_x_ratio + x_ratio * old_w_ratio, + old_y_ratio + y_ratio * old_h_ratio, w_ratio * old_w_ratio, + h_ratio * old_h_ratio + ] + results['crop_quadruple'] = np.array( + new_crop_quadruple, dtype=np.float32) + + if 'keypoint' in results: + results['keypoint'] = self._crop_kps(results['keypoint'], crop_bbox) + if 'imgs' in results: + results['imgs'] = self._crop_imgs(results['imgs'], crop_bbox) + + if 'gt_bboxes' in results: + results = self._all_box_crop(results, results['crop_bbox']) + + return results + + def __repr__(self): + repr_str = (f'{self.__class__.__name__}(crop_size={self.crop_size})') + return repr_str + + +@PIPELINES.register_module() +class ThreeCrop: + """Crop images into three crops. + + Crop the images equally into three crops with equal intervals along the + shorter side. Required keys are "imgs", "img_shape", added or modified keys + are "imgs", "crop_bbox" and "img_shape". + + Args: + crop_size(int | tuple[int]): (w, h) of crop size. + """ + + def __init__(self, crop_size): + self.crop_size = _pair(crop_size) + if not mmcv.is_tuple_of(self.crop_size, int): + raise TypeError(f'Crop_size must be int or tuple of int, ' + f'but got {type(crop_size)}') + + def __call__(self, results): + """Performs the ThreeCrop augmentation. + + Args: + results (dict): The resulting dict to be modified and passed + to the next transform in pipeline. + """ + if 'gt_bboxes' in results or 'proposals' in results: + warnings.warn('ThreeCrop cannot process bounding boxes') + + imgs = results['imgs'] + img_h, img_w = results['imgs'][0].shape[:2] + crop_w, crop_h = self.crop_size + assert crop_h == img_h or crop_w == img_w + + if crop_h == img_h: + w_step = (img_w - crop_w) // 2 + offsets = [ + (0, 0), # left + (2 * w_step, 0), # right + (w_step, 0), # middle + ] + elif crop_w == img_w: + h_step = (img_h - crop_h) // 2 + offsets = [ + (0, 0), # top + (0, 2 * h_step), # down + (0, h_step), # middle + ] + + cropped = [] + crop_bboxes = [] + for x_offset, y_offset in offsets: + bbox = [x_offset, y_offset, x_offset + crop_w, y_offset + crop_h] + crop = [ + img[y_offset:y_offset + crop_h, x_offset:x_offset + crop_w] + for img in imgs + ] + cropped.extend(crop) + crop_bboxes.extend([bbox for _ in range(len(imgs))]) + + crop_bboxes = np.array(crop_bboxes) + results['imgs'] = cropped + results['crop_bbox'] = crop_bboxes + results['img_shape'] = results['imgs'][0].shape[:2] + + return results + + def __repr__(self): + repr_str = f'{self.__class__.__name__}(crop_size={self.crop_size})' + return repr_str + + +@PIPELINES.register_module() +class TenCrop: + """Crop the images into 10 crops (corner + center + flip). + + Crop the four corners and the center part of the image with the same + given crop_size, and flip it horizontally. Required keys are "imgs", + "img_shape", added or modified keys are "imgs", "crop_bbox" and "img_shape". + + Args: + crop_size(int | tuple[int]): (w, h) of crop size. + """ + + def __init__(self, crop_size): + self.crop_size = _pair(crop_size) + if not mmcv.is_tuple_of(self.crop_size, int): + raise TypeError(f'Crop_size must be int or tuple of int, ' + f'but got {type(crop_size)}') + + def __call__(self, results): + """Performs the TenCrop augmentation. + + Args: + results (dict): The resulting dict to be modified and passed + to the next transform in pipeline. + """ + if 'gt_bboxes' in results or 'proposals' in results: + warnings.warn('TenCrop cannot process bounding boxes') + + imgs = results['imgs'] + + img_h, img_w = results['imgs'][0].shape[:2] + crop_w, crop_h = self.crop_size + + w_step = (img_w - crop_w) // 4 + h_step = (img_h - crop_h) // 4 + + offsets = [ + (0, 0), # upper left + (4 * w_step, 0), # upper right + (0, 4 * h_step), # lower left + (4 * w_step, 4 * h_step), # lower right + (2 * w_step, 2 * h_step), # center + ] + + img_crops = list() + crop_bboxes = list() + for x_offset, y_offsets in offsets: + crop = [ + img[y_offsets:y_offsets + crop_h, x_offset:x_offset + crop_w] + for img in imgs + ] + flip_crop = [np.flip(c, axis=1).copy() for c in crop] + bbox = [x_offset, y_offsets, x_offset + crop_w, y_offsets + crop_h] + img_crops.extend(crop) + img_crops.extend(flip_crop) + crop_bboxes.extend([bbox for _ in range(len(imgs) * 2)]) + + crop_bboxes = np.array(crop_bboxes) + results['imgs'] = img_crops + results['crop_bbox'] = crop_bboxes + results['img_shape'] = results['imgs'][0].shape[:2] + + return results + + def __repr__(self): + repr_str = f'{self.__class__.__name__}(crop_size={self.crop_size})' + return repr_str diff --git a/pyskl/datasets/pipelines/compose.py b/pyskl/datasets/pipelines/compose.py new file mode 100644 index 00000000..a60604ad --- /dev/null +++ b/pyskl/datasets/pipelines/compose.py @@ -0,0 +1,53 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from collections.abc import Sequence + +from mmcv.utils import build_from_cfg + +from ..builder import PIPELINES + + +@PIPELINES.register_module() +class Compose: + """Compose a data pipeline with a sequence of transforms. + + Args: + transforms (list[dict | callable]): + Either config dicts of transforms or transform objects. + """ + + def __init__(self, transforms): + assert isinstance(transforms, Sequence) + self.transforms = [] + for transform in transforms: + if isinstance(transform, dict): + transform = build_from_cfg(transform, PIPELINES) + self.transforms.append(transform) + elif callable(transform): + self.transforms.append(transform) + else: + raise TypeError(f'transform must be callable or a dict, ' + f'but got {type(transform)}') + + def __call__(self, data): + """Call function to apply transforms sequentially. + + Args: + data (dict): A result dict contains the data to transform. + + Returns: + dict: Transformed data. + """ + + for t in self.transforms: + data = t(data) + if data is None: + return None + return data + + def __repr__(self): + format_string = self.__class__.__name__ + '(' + for t in self.transforms: + format_string += '\n' + format_string += ' {0}'.format(t) + format_string += '\n)' + return format_string diff --git a/pyskl/datasets/pipelines/formatting.py b/pyskl/datasets/pipelines/formatting.py new file mode 100644 index 00000000..a7e05dde --- /dev/null +++ b/pyskl/datasets/pipelines/formatting.py @@ -0,0 +1,234 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from collections.abc import Sequence + +import mmcv +import numpy as np +import torch +from mmcv.parallel import DataContainer as DC + +from ..builder import PIPELINES + + +def to_tensor(data): + """Convert objects of various python types to :obj:`torch.Tensor`. + + Supported types are: :class:`numpy.ndarray`, :class:`torch.Tensor`, + :class:`Sequence`, :class:`int` and :class:`float`. + """ + if isinstance(data, torch.Tensor): + return data + if isinstance(data, np.ndarray): + return torch.from_numpy(data) + if isinstance(data, Sequence) and not mmcv.is_str(data): + return torch.tensor(data) + if isinstance(data, int): + return torch.LongTensor([data]) + if isinstance(data, float): + return torch.FloatTensor([data]) + raise TypeError(f'type {type(data)} cannot be converted to tensor.') + + +@PIPELINES.register_module() +class ToTensor: + """Convert some values in results dict to `torch.Tensor` type in data + loader pipeline. + + Args: + keys (Sequence[str]): Required keys to be converted. + """ + + def __init__(self, keys): + self.keys = keys + + def __call__(self, results): + """Performs the ToTensor formatting. + + Args: + results (dict): The resulting dict to be modified and passed + to the next transform in pipeline. + """ + for key in self.keys: + results[key] = to_tensor(results[key]) + return results + + def __repr__(self): + return f'{self.__class__.__name__}(keys={self.keys})' + + +@PIPELINES.register_module() +class Rename: + """Rename the key in results. + + Args: + mapping (dict): The keys in results that need to be renamed. The key of + the dict is the original name, while the value is the new name. If + the original name not found in results, do nothing. + Default: dict(). + """ + + def __init__(self, mapping): + self.mapping = mapping + + def __call__(self, results): + for key, value in self.mapping.items(): + if key in results: + assert isinstance(key, str) and isinstance(value, str) + assert value not in results, ('the new name already exists in ' + 'results') + results[value] = results[key] + results.pop(key) + return results + + +@PIPELINES.register_module() +class Collect: + """Collect data from the loader relevant to the specific task. + + This keeps the items in ``keys`` as it is, and collect items in + ``meta_keys`` into a meta item called ``meta_name``.This is usually + the last stage of the data loader pipeline. + For example, when keys='imgs', meta_keys=('filename', 'label', + 'original_shape'), meta_name='img_metas', the results will be a dict with + keys 'imgs' and 'img_metas', where 'img_metas' is a DataContainer of + another dict with keys 'filename', 'label', 'original_shape'. + + Args: + keys (Sequence[str]): Required keys to be collected. + meta_name (str): The name of the key that contains meta information. + This key is always populated. Default: "img_metas". + meta_keys (Sequence[str]): Keys that are collected under meta_name. + The contents of the ``meta_name`` dictionary depends on + ``meta_keys``. + By default this includes: + + - "filename": path to the image file + - "label": label of the image file + - "original_shape": original shape of the image as a tuple + (h, w, c) + - "img_shape": shape of the image input to the network as a tuple + (h, w, c). Note that images may be zero padded on the + bottom/right, if the batch tensor is larger than this shape. + - "pad_shape": image shape after padding + - "flip_direction": a str in ("horiziontal", "vertival") to + indicate if the image is fliped horizontally or vertically. + - "img_norm_cfg": a dict of normalization information: + - mean - per channel mean subtraction + - std - per channel std divisor + - to_rgb - bool indicating if bgr was converted to rgb + nested (bool): If set as True, will apply data[x] = [data[x]] to all + items in data. The arg is added for compatibility. Default: False. + """ + + def __init__(self, + keys, + meta_keys=('filename', 'label', 'original_shape', 'img_shape', + 'pad_shape', 'flip_direction', 'img_norm_cfg'), + meta_name='img_metas', + nested=False): + self.keys = keys + self.meta_keys = meta_keys + self.meta_name = meta_name + self.nested = nested + + def __call__(self, results): + """Performs the Collect formatting. + + Args: + results (dict): The resulting dict to be modified and passed + to the next transform in pipeline. + """ + data = {} + for key in self.keys: + data[key] = results[key] + + if len(self.meta_keys) != 0: + meta = {} + for key in self.meta_keys: + meta[key] = results[key] + data[self.meta_name] = DC(meta, cpu_only=True) + if self.nested: + for k in data: + data[k] = [data[k]] + + return data + + def __repr__(self): + return (f'{self.__class__.__name__}(' + f'keys={self.keys}, meta_keys={self.meta_keys}, ' + f'nested={self.nested})') + + +@PIPELINES.register_module() +class FormatShape: + """Format final imgs shape to the given input_format. + + Required keys are "imgs", "num_clips" and "clip_len", added or modified + keys are "imgs" and "input_shape". + + Args: + input_format (str): Define the final imgs format. + collapse (bool): To collpase input_format N... to ... (NCTHW to CTHW, + etc.) if N is 1. Should be set as True when training and testing + detectors. Default: False. + """ + + def __init__(self, input_format, collapse=False): + self.input_format = input_format + self.collapse = collapse + if self.input_format not in ['NCTHW', 'NCHW', 'NCTHW_Heatmap']: + raise ValueError( + f'The input format {self.input_format} is invalid.') + + def __call__(self, results): + """Performs the FormatShape formatting. + + Args: + results (dict): The resulting dict to be modified and passed + to the next transform in pipeline. + """ + if not isinstance(results['imgs'], np.ndarray): + results['imgs'] = np.array(results['imgs']) + imgs = results['imgs'] + # [M x H x W x C] + # M = 1 * N_crops * N_clips * L + if self.collapse: + assert results['num_clips'] == 1 + + if self.input_format == 'NCTHW': + num_clips = results['num_clips'] + clip_len = results['clip_len'] + + imgs = imgs.reshape((-1, num_clips, clip_len) + imgs.shape[1:]) + # N_crops x N_clips x L x H x W x C + imgs = np.transpose(imgs, (0, 1, 5, 2, 3, 4)) + # N_crops x N_clips x C x L x H x W + imgs = imgs.reshape((-1, ) + imgs.shape[2:]) + # M' x C x L x H x W + # M' = N_crops x N_clips + elif self.input_format == 'NCTHW_Heatmap': + num_clips = results['num_clips'] + clip_len = results['clip_len'] + + imgs = imgs.reshape((-1, num_clips, clip_len) + imgs.shape[1:]) + # N_crops x N_clips x L x C x H x W + imgs = np.transpose(imgs, (0, 1, 3, 2, 4, 5)) + # N_crops x N_clips x C x L x H x W + imgs = imgs.reshape((-1, ) + imgs.shape[2:]) + # M' x C x L x H x W + # M' = N_crops x N_clips + elif self.input_format == 'NCHW': + imgs = np.transpose(imgs, (0, 3, 1, 2)) + # M x C x H x W + + if self.collapse: + assert imgs.shape[0] == 1 + imgs = imgs.squeeze(0) + + results['imgs'] = imgs + results['input_shape'] = imgs.shape + return results + + def __repr__(self): + repr_str = self.__class__.__name__ + repr_str += f"(input_format='{self.input_format}')" + return repr_str diff --git a/pyskl/datasets/pipelines/loading.py b/pyskl/datasets/pipelines/loading.py new file mode 100644 index 00000000..e495c108 --- /dev/null +++ b/pyskl/datasets/pipelines/loading.py @@ -0,0 +1,166 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import io + +import numpy as np +from mmcv.fileio import FileClient + +from ..builder import PIPELINES + + +@PIPELINES.register_module() +class DecordInit: + """Using decord to initialize the video_reader. + + Decord: https://github.com/dmlc/decord + + Required keys are "filename", + added or modified keys are "video_reader" and "total_frames". + + Args: + io_backend (str): io backend where frames are store. + Default: 'disk'. + num_threads (int): Number of thread to decode the video. Default: 1. + kwargs (dict): Args for file client. + """ + + def __init__(self, io_backend='disk', num_threads=1, **kwargs): + self.io_backend = io_backend + self.num_threads = num_threads + self.kwargs = kwargs + self.file_client = None + + def __call__(self, results): + """Perform the Decord initialization. + + Args: + results (dict): The resulting dict to be modified and passed + to the next transform in pipeline. + """ + try: + import decord + except ImportError: + raise ImportError( + 'Please run "pip install decord" to install Decord first.') + + if self.file_client is None: + self.file_client = FileClient(self.io_backend, **self.kwargs) + + file_obj = io.BytesIO(self.file_client.get(results['filename'])) + container = decord.VideoReader(file_obj, num_threads=self.num_threads) + results['video_reader'] = container + results['total_frames'] = len(container) + return results + + def __repr__(self): + repr_str = (f'{self.__class__.__name__}(' + f'io_backend={self.io_backend}, ' + f'num_threads={self.num_threads})') + return repr_str + + +@PIPELINES.register_module() +class DecordDecode: + """Using decord to decode the video. + + Decord: https://github.com/dmlc/decord + + Required keys are "video_reader", "filename" and "frame_inds", + added or modified keys are "imgs" and "original_shape". + + Args: + mode (str): Decoding mode. Options are 'accurate' and 'efficient'. + If set to 'accurate', it will decode videos into accurate frames. + If set to 'efficient', it will adopt fast seeking but only return + key frames, which may be duplicated and inaccurate, and more + suitable for large scene-based video datasets. Default: 'accurate'. + """ + + def __init__(self, mode='accurate'): + self.mode = mode + assert mode in ['accurate', 'efficient'] + + def __call__(self, results): + """Perform the Decord decoding. + + Args: + results (dict): The resulting dict to be modified and passed + to the next transform in pipeline. + """ + container = results['video_reader'] + + if results['frame_inds'].ndim != 1: + results['frame_inds'] = np.squeeze(results['frame_inds']) + + frame_inds = results['frame_inds'] + + if self.mode == 'accurate': + imgs = container.get_batch(frame_inds).asnumpy() + imgs = list(imgs) + elif self.mode == 'efficient': + # This mode is faster, however it always returns I-FRAME + container.seek(0) + imgs = list() + for idx in frame_inds: + container.seek(idx) + frame = container.next() + imgs.append(frame.asnumpy()) + + results['video_reader'] = None + del container + + results['imgs'] = imgs + results['original_shape'] = imgs[0].shape[:2] + results['img_shape'] = imgs[0].shape[:2] + + return results + + def __repr__(self): + repr_str = f'{self.__class__.__name__}(mode={self.mode})' + return repr_str + + +@PIPELINES.register_module() +class ArrayDecode: + """Load and decode frames with given indices from a 4D array. + + Required keys are "array and "frame_inds", added or modified keys are + "imgs", "img_shape" and "original_shape". + """ + + def __call__(self, results): + """Perform the ``RawFrameDecode`` to pick frames given indices. + + Args: + results (dict): The resulting dict to be modified and passed + to the next transform in pipeline. + """ + + modality = results['modality'] + array = results['array'] + + imgs = list() + + if results['frame_inds'].ndim != 1: + results['frame_inds'] = np.squeeze(results['frame_inds']) + + offset = results.get('offset', 0) + + for i, frame_idx in enumerate(results['frame_inds']): + + frame_idx += offset + if modality == 'RGB': + imgs.append(array[frame_idx]) + elif modality == 'Flow': + imgs.extend( + [array[frame_idx, ..., 0], array[frame_idx, ..., 1]]) + else: + raise NotImplementedError + + results['imgs'] = imgs + results['original_shape'] = imgs[0].shape[:2] + results['img_shape'] = imgs[0].shape[:2] + + return results + + def __repr__(self): + return f'{self.__class__.__name__}()' diff --git a/pyskl/datasets/pipelines/pose_related.py b/pyskl/datasets/pipelines/pose_related.py new file mode 100644 index 00000000..1ac63666 --- /dev/null +++ b/pyskl/datasets/pipelines/pose_related.py @@ -0,0 +1,354 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import numpy as np + +from ..builder import PIPELINES +from .compose import Compose +from .formatting import Rename + +EPS = 1e-4 + + +@PIPELINES.register_module() +class PoseDecode: + """Load and decode pose with given indices. + + Required keys are "keypoint", "frame_inds" (optional), "keypoint_score" (optional), added or modified keys are + "keypoint", "keypoint_score" (if applicable). + """ + + @staticmethod + def _load_kp(kp, frame_inds): + return kp[:, frame_inds].astype(np.float32) + + @staticmethod + def _load_kpscore(kpscore, frame_inds): + return kpscore[:, frame_inds].astype(np.float32) + + def __call__(self, results): + + if 'frame_inds' not in results: + results['frame_inds'] = np.arange(results['total_frames']) + + if results['frame_inds'].ndim != 1: + results['frame_inds'] = np.squeeze(results['frame_inds']) + + offset = results.get('offset', 0) + frame_inds = results['frame_inds'] + offset + + if 'keypoint_score' in results: + results['keypoint_score'] = self._load_kpscore(results['keypoint_score'], frame_inds) + + if 'keypoint' in results: + results['keypoint'] = self._load_kp(results['keypoint'], frame_inds) + + return results + + def __repr__(self): + repr_str = f'{self.__class__.__name__}()' + return repr_str + + +@PIPELINES.register_module() +class PreNormalize2D: + """Normalize the range of keypoint values. """ + + def __init__(self, img_shape=(1080, 1920)): + self.img_shape = img_shape + + def __call__(self, results): + h, w = results.get('img_shape', self.img_shape) + results['keypoint'][..., 0] = (results['keypoint'][..., 0] - (w / 2)) / (w / 2) + results['keypoint'][..., 1] = (results['keypoint'][..., 1] - (h / 2)) / (h / 2) + return results + + +@PIPELINES.register_module() +class RandomRot: + + def __init__(self, theta=0.3): + self.theta = theta + + def _rot(self, theta): + cos, sin = np.cos(theta), np.sin(theta) + rx = np.array([[1, 0, 0], [0, cos[0], sin[0]], [0, -sin[0], cos[0]]]) + ry = np.array([[cos[1], 0, -sin[1]], [0, 1, 0], [sin[1], 0, cos[1]]]) + rz = np.array([[cos[2], sin[2], 0], [-sin[2], cos[2], 0], [0, 0, 1]]) + + rot = np.matmul(rz, np.matmul(ry, rx)) + return rot + + def __call__(self, results): + theta = np.random.uniform(-self.theta, self.theta, size=3) + rot_mat = self._rot(theta) + + skeleton = results['keypoint'] + if np.all(np.isclose(skeleton, 0)): + return results + + M, T, V, C = skeleton.shape + assert M in [1, 2] and C == 3 + + results['keypoint'] = np.einsum('ab,mtvb->mtva', rot_mat, skeleton) + return results + + +@PIPELINES.register_module() +class PreNormalize3D: + """PreNormalize for NTURGB+D 3D keypoints (x, y, z). Codes adapted from https://github.com/lshiwjx/2s-AGCN. """ + + def unit_vector(self, vector): + """Returns the unit vector of the vector. """ + return vector / np.linalg.norm(vector) + + def angle_between(self, v1, v2): + """Returns the angle in radians between vectors 'v1' and 'v2'. """ + if np.abs(v1).sum() < 1e-6 or np.abs(v2).sum() < 1e-6: + return 0 + v1_u = self.unit_vector(v1) + v2_u = self.unit_vector(v2) + return np.arccos(np.clip(np.dot(v1_u, v2_u), -1.0, 1.0)) + + def rotation_matrix(self, axis, theta): + """Return the rotation matrix associated with counterclockwise rotation + about the given axis by theta radians.""" + if np.abs(axis).sum() < 1e-6 or np.abs(theta) < 1e-6: + return np.eye(3) + axis = np.asarray(axis) + axis = axis / np.sqrt(np.dot(axis, axis)) + a = np.cos(theta / 2.0) + b, c, d = -axis * np.sin(theta / 2.0) + aa, bb, cc, dd = a * a, b * b, c * c, d * d + bc, ad, ac, ab, bd, cd = b * c, a * d, a * c, a * b, b * d, c * d + return np.array([[aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac)], + [2 * (bc - ad), aa + cc - bb - dd, 2 * (cd + ab)], + [2 * (bd + ac), 2 * (cd - ab), aa + dd - bb - cc]]) + + def __init__(self, zaxis=[0, 1], xaxis=[8, 4], align_spine=True, align_center=True): + self.zaxis = zaxis + self.xaxis = xaxis + self.align_spine = align_spine + self.align_center = align_center + + def __call__(self, results): + skeleton = results['keypoint'] + total_frames = results.get('total_frames', skeleton.shape[1]) + + M, T, V, C = skeleton.shape + assert T == total_frames + if skeleton.sum() == 0: + return results + + index0 = [i for i in range(T) if not np.all(np.isclose(skeleton[0, i], 0))] + + assert M in [1, 2] + if M == 2: + index1 = [i for i in range(T) if not np.all(np.isclose(skeleton[1, i], 0))] + if len(index0) < len(index1): + skeleton = skeleton[:, np.array(index1)] + skeleton = skeleton[[1, 0]] + else: + skeleton = skeleton[:, np.array(index0)] + else: + skeleton = skeleton[:, np.array(index0)] + + T_new = skeleton.shape[1] + + if self.align_center: + if skeleton.shape[2] == 25: + main_body_center = skeleton[0, 0, 1].copy() + else: + main_body_center = skeleton[0, 0, -1].copy() + mask = ((skeleton != 0).sum(-1) > 0)[..., None] + skeleton = (skeleton - main_body_center) * mask + + if self.align_spine: + joint_bottom = skeleton[0, 0, self.zaxis[0]] + joint_top = skeleton[0, 0, self.zaxis[1]] + axis = np.cross(joint_top - joint_bottom, [0, 0, 1]) + angle = self.angle_between(joint_top - joint_bottom, [0, 0, 1]) + matrix_z = self.rotation_matrix(axis, angle) + skeleton = np.einsum('abcd,kd->abck', skeleton, matrix_z) + + joint_rshoulder = skeleton[0, 0, self.xaxis[0]] + joint_lshoulder = skeleton[0, 0, self.xaxis[1]] + axis = np.cross(joint_rshoulder - joint_lshoulder, [1, 0, 0]) + angle = self.angle_between(joint_rshoulder - joint_lshoulder, [1, 0, 0]) + matrix_x = self.rotation_matrix(axis, angle) + skeleton = np.einsum('abcd,kd->abck', skeleton, matrix_x) + + results['keypoint'] = skeleton + results['total_frames'] = T_new + results['body_center'] = main_body_center + return results + + +@PIPELINES.register_module() +class JointToBone: + + def __init__(self, dataset='nturgb+d', target='keypoint'): + self.dataset = dataset + self.target = target + if self.dataset not in ['nturgb+d', 'openpose', 'coco']: + raise ValueError( + f'The dataset type {self.dataset} is not supported') + if self.dataset == 'nturgb+d': + self.pairs = [(0, 1), (1, 20), (2, 20), (3, 2), (4, 20), (5, 4), (6, 5), (7, 6), (8, 20), (9, 8), + (10, 9), (11, 10), (12, 0), (13, 12), (14, 13), (15, 14), (16, 0), (17, 16), (18, 17), + (19, 18), (21, 22), (20, 20), (22, 7), (23, 24), (24, 11)] + elif self.dataset == 'openpose': + self.pairs = ((0, 0), (1, 0), (2, 1), (3, 2), (4, 3), (5, 1), (6, 5), (7, 6), (8, 2), (9, 8), (10, 9), + (11, 5), (12, 11), (13, 12), (14, 0), (15, 0), (16, 14), (17, 15)) + elif self.dataset == 'coco': + self.pairs = ((0, 0), (1, 0), (2, 0), (3, 1), (4, 2), (5, 0), (6, 0), (7, 5), (8, 6), (9, 7), (10, 8), + (11, 0), (12, 0), (13, 11), (14, 12), (15, 13), (16, 14)) + + def __call__(self, results): + + keypoint = results['keypoint'] + M, T, V, C = keypoint.shape + bone = np.zeros((M, T, V, C), dtype=np.float32) + + assert C in [2, 3] + for v1, v2 in self.pairs: + bone[..., v1, :] = keypoint[..., v1, :] - keypoint[..., v2, :] + if C == 3 and self.dataset in ['openpose', 'coco']: + score = (keypoint[..., v1, 2] + keypoint[..., v2, 2]) / 2 + bone[..., v1, 2] = score + + results[self.target] = bone + return results + + +@PIPELINES.register_module() +class ToMotion: + + def __init__(self, dataset='nturgb+d', source='keypoint', target='motion'): + self.dataset = dataset + self.source = source + self.target = target + + def __call__(self, results): + data = results[self.source] + M, T, V, C = data.shape + motion = np.zeros_like(data) + + assert C in [2, 3] + motion[:, :T - 1] = np.diff(data, axis=1) + if C == 3 and self.dataset in ['openpose', 'coco']: + score = (data[:, :T - 1, :, 2] + data[:, 1:, :, 2]) / 2 + motion[:, :T - 1, :, 2] = score + + results[self.target] = motion + + return results + + +@PIPELINES.register_module() +class MergeSkeFeat: + def __init__(self, feat_list=['keypoint'], target='keypoint', axis=-1): + """Merge different feats (ndarray) by concatenate them in the last axis. """ + + self.feat_list = feat_list + self.target = target + self.axis = axis + + def __call__(self, results): + feats = [] + for name in self.feat_list: + feats.append(results.pop(name)) + feats = np.concatenate(feats, axis=self.axis) + results[self.target] = feats + return results + + +@PIPELINES.register_module() +class GenSkeFeat: + def __init__(self, dataset='nturgb+d', feats=['j'], axis=-1): + self.dataset = dataset + self.feats = feats + self.axis = axis + ops = [] + if 'b' in feats or 'bm' in feats: + ops.append(JointToBone(dataset=dataset, target='b')) + ops.append(Rename({'keypoint': 'j'})) + if 'jm' in feats: + ops.append(ToMotion(dataset=dataset, source='j', target='jm')) + if 'bm' in feats: + ops.append(ToMotion(dataset=dataset, source='b', target='bm')) + ops.append(MergeSkeFeat(feat_list=feats, axis=axis)) + self.ops = Compose(ops) + + def __call__(self, results): + if 'keypoint_score' in results and 'keypoint' in results: + assert self.dataset != 'nturgb+d' + assert results['keypoint'].shape[-1] == 2, 'Only 2D keypoints have keypoint_score. ' + keypoint = results.pop('keypoint') + keypoint_score = results.pop('keypoint_score') + results['keypoint'] = np.concatenate([keypoint, keypoint_score[..., None]], -1) + return self.ops(results) + + +@PIPELINES.register_module() +class PadTo: + + def __init__(self, length, mode='loop'): + self.length = length + assert mode in ['loop', 'zero'] + self.mode = mode + + def __call__(self, results): + total_frames = results['total_frames'] + assert total_frames <= self.length + inds = np.arange(self.length) + inds = np.mod(inds, total_frames) + + keypoint = results['keypoint'][:, inds].copy() + if self.mode == 'zero': + keypoint[:, total_frames:] = 0 + results['keypoint'] = keypoint + results['total_frames'] = self.length + return results + + +@PIPELINES.register_module() +class FormatGCNInput: + """Format final skeleton shape to the given input_format. """ + + def __init__(self, num_person=2, mode='zero'): + self.num_person = num_person + assert mode in ['zero', 'loop'] + self.mode = mode + + def __call__(self, results): + """Performs the FormatShape formatting. + + Args: + results (dict): The resulting dict to be modified and passed + to the next transform in pipeline. + """ + keypoint = results['keypoint'] + if 'keypoint_score' in results: + keypoint = np.concatenate((keypoint, results['keypoint_score'][..., None]), axis=-1) + + # M T V C + if keypoint.shape[0] < self.num_person: + pad_dim = self.num_person - keypoint.shape[0] + pad = np.zeros((pad_dim, ) + keypoint.shape[1:], dtype=keypoint.dtype) + keypoint = np.concatenate((keypoint, pad), axis=0) + if self.mode == 'loop' and keypoint.shape[0] == 1: + for i in range(1, self.num_person): + keypoint[i] = keypoint[0] + + elif keypoint.shape[0] > self.num_person: + keypoint = keypoint[:self.num_person] + + M, T, V, C = keypoint.shape + nc = results.get('num_clips', 1) + assert T % nc == 0 + keypoint = keypoint.reshape((M, nc, T // nc, V, C)).transpose(1, 0, 2, 3, 4) + results['keypoint'] = np.ascontiguousarray(keypoint) + return results + + def __repr__(self): + repr_str = self.__class__.__name__ + f'(num_person={self.num_person}, mode={self.mode})' + return repr_str diff --git a/pyskl/datasets/pipelines/posec3d_related.py b/pyskl/datasets/pipelines/posec3d_related.py new file mode 100644 index 00000000..8c6560cb --- /dev/null +++ b/pyskl/datasets/pipelines/posec3d_related.py @@ -0,0 +1,259 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import numpy as np + +from ..builder import PIPELINES + +EPS = 1e-3 + + +@PIPELINES.register_module() +class GeneratePoseTarget: + """Generate pseudo heatmaps based on joint coordinates and confidence. + + Required keys are "keypoint", "img_shape", "keypoint_score" (optional), + added or modified keys are "imgs". + + Args: + sigma (float): The sigma of the generated gaussian map. Default: 0.6. + use_score (bool): Use the confidence score of keypoints as the maximum + of the gaussian maps. Default: True. + with_kp (bool): Generate pseudo heatmaps for keypoints. Default: True. + with_limb (bool): Generate pseudo heatmaps for limbs. At least one of + 'with_kp' and 'with_limb' should be True. Default: False. + skeletons (tuple[tuple]): The definition of human skeletons. + Default: ((0, 1), (0, 2), (1, 3), (2, 4), (0, 5), (5, 7), (7, 9), + (0, 6), (6, 8), (8, 10), (5, 11), (11, 13), (13, 15), + (6, 12), (12, 14), (14, 16), (11, 12)), + which is the definition of COCO-17p skeletons. + double (bool): Output both original heatmaps and flipped heatmaps. + Default: False. + left_kp (tuple[int]): Indexes of left keypoints, which is used when + flipping heatmaps. Default: (1, 3, 5, 7, 9, 11, 13, 15), + which is left keypoints in COCO-17p. + right_kp (tuple[int]): Indexes of right keypoints, which is used when + flipping heatmaps. Default: (2, 4, 6, 8, 10, 12, 14, 16), + which is right keypoints in COCO-17p. + """ + + def __init__(self, + sigma=0.6, + use_score=True, + with_kp=True, + with_limb=False, + skeletons=((0, 1), (0, 2), (1, 3), (2, 4), (0, 5), (5, 7), + (7, 9), (0, 6), (6, 8), (8, 10), (5, 11), (11, 13), + (13, 15), (6, 12), (12, 14), (14, 16), (11, 12)), + double=False, + left_kp=(1, 3, 5, 7, 9, 11, 13, 15), + right_kp=(2, 4, 6, 8, 10, 12, 14, 16), + left_limb=(0, 2, 4, 5, 6, 10, 11, 12), + right_limb=(1, 3, 7, 8, 9, 13, 14, 15)): + + self.sigma = sigma + self.use_score = use_score + self.with_kp = with_kp + self.with_limb = with_limb + self.double = double + + assert self.with_kp + self.with_limb == 1, ('One of "with_limb" and "with_kp" should be set as True.') + self.left_kp = left_kp + self.right_kp = right_kp + self.skeletons = skeletons + self.left_limb = left_limb + self.right_limb = right_limb + + def generate_a_heatmap(self, arr, centers, max_values): + """Generate pseudo heatmap for one keypoint in one frame. + + Args: + arr (np.ndarray): The array to store the generated heatmaps. Shape: img_h * img_w. + centers (np.ndarray): The coordinates of corresponding keypoints (of multiple persons). Shape: M * 2. + max_values (np.ndarray): The max values of each keypoint. Shape: M. + + Returns: + np.ndarray: The generated pseudo heatmap. + """ + + sigma = self.sigma + img_h, img_w = arr.shape + + for center, max_value in zip(centers, max_values): + if max_value < EPS: + continue + + mu_x, mu_y = center[0], center[1] + st_x = max(int(mu_x - 3 * sigma), 0) + ed_x = min(int(mu_x + 3 * sigma) + 1, img_w) + st_y = max(int(mu_y - 3 * sigma), 0) + ed_y = min(int(mu_y + 3 * sigma) + 1, img_h) + x = np.arange(st_x, ed_x, 1, np.float32) + y = np.arange(st_y, ed_y, 1, np.float32) + + # if the keypoint not in the heatmap coordinate system + if not (len(x) and len(y)): + continue + y = y[:, None] + + patch = np.exp(-((x - mu_x)**2 + (y - mu_y)**2) / 2 / sigma**2) + patch = patch * max_value + arr[st_y:ed_y, st_x:ed_x] = np.maximum(arr[st_y:ed_y, st_x:ed_x], patch) + + def generate_a_limb_heatmap(self, arr, starts, ends, start_values, end_values): + """Generate pseudo heatmap for one limb in one frame. + + Args: + arr (np.ndarray): The array to store the generated heatmaps. Shape: img_h * img_w. + starts (np.ndarray): The coordinates of one keypoint in the corresponding limbs. Shape: M * 2. + ends (np.ndarray): The coordinates of the other keypoint in the corresponding limbs. Shape: M * 2. + start_values (np.ndarray): The max values of one keypoint in the corresponding limbs. Shape: M. + end_values (np.ndarray): The max values of the other keypoint in the corresponding limbs. Shape: M. + + Returns: + np.ndarray: The generated pseudo heatmap. + """ + + sigma = self.sigma + img_h, img_w = arr.shape + + for start, end, start_value, end_value in zip(starts, ends, start_values, end_values): + value_coeff = min(start_value, end_value) + if value_coeff < EPS: + continue + + min_x, max_x = min(start[0], end[0]), max(start[0], end[0]) + min_y, max_y = min(start[1], end[1]), max(start[1], end[1]) + + min_x = max(int(min_x - 3 * sigma), 0) + max_x = min(int(max_x + 3 * sigma) + 1, img_w) + min_y = max(int(min_y - 3 * sigma), 0) + max_y = min(int(max_y + 3 * sigma) + 1, img_h) + + x = np.arange(min_x, max_x, 1, np.float32) + y = np.arange(min_y, max_y, 1, np.float32) + + if not (len(x) and len(y)): + continue + + y = y[:, None] + x_0 = np.zeros_like(x) + y_0 = np.zeros_like(y) + + # distance to start keypoints + d2_start = ((x - start[0])**2 + (y - start[1])**2) + + # distance to end keypoints + d2_end = ((x - end[0])**2 + (y - end[1])**2) + + # the distance between start and end keypoints. + d2_ab = ((start[0] - end[0])**2 + (start[1] - end[1])**2) + + if d2_ab < 1: + self.generate_a_heatmap(arr, start[None], start_value[None]) + continue + + coeff = (d2_start - d2_end + d2_ab) / 2. / d2_ab + + a_dominate = coeff <= 0 + b_dominate = coeff >= 1 + seg_dominate = 1 - a_dominate - b_dominate + + position = np.stack([x + y_0, y + x_0], axis=-1) + projection = start + np.stack([coeff, coeff], axis=-1) * (end - start) + d2_line = position - projection + d2_line = d2_line[:, :, 0]**2 + d2_line[:, :, 1]**2 + d2_seg = a_dominate * d2_start + b_dominate * d2_end + seg_dominate * d2_line + + patch = np.exp(-d2_seg / 2. / sigma**2) + patch = patch * value_coeff + + arr[min_y:max_y, min_x:max_x] = np.maximum(arr[min_y:max_y, min_x:max_x], patch) + + def generate_heatmap(self, arr, kps, max_values): + """Generate pseudo heatmap for all keypoints and limbs in one frame (if + needed). + + Args: + arr (np.ndarray): The array to store the generated heatmaps. Shape: V * img_h * img_w. + kps (np.ndarray): The coordinates of keypoints in this frame. Shape: M * V * 2. + max_values (np.ndarray): The confidence score of each keypoint. Shape: M * V. + + Returns: + np.ndarray: The generated pseudo heatmap. + """ + + if self.with_kp: + num_kp = kps.shape[1] + for i in range(num_kp): + self.generate_a_heatmap(arr[i], kps[:, i], max_values[:, i]) + + if self.with_limb: + for i, limb in enumerate(self.skeletons): + start_idx, end_idx = limb + starts = kps[:, start_idx] + ends = kps[:, end_idx] + + start_values = max_values[:, start_idx] + end_values = max_values[:, end_idx] + self.generate_a_limb_heatmap(arr[i], starts, ends, start_values, end_values) + + def gen_an_aug(self, results): + """Generate pseudo heatmaps for all frames. + + Args: + results (dict): The dictionary that contains all info of a sample. + + Returns: + list[np.ndarray]: The generated pseudo heatmaps. + """ + + all_kps = results['keypoint'] + kp_shape = all_kps.shape + + if 'keypoint_score' in results: + all_kpscores = results['keypoint_score'] + else: + all_kpscores = np.ones(kp_shape[:-1], dtype=np.float32) + + img_h, img_w = results['img_shape'] + num_frame = kp_shape[1] + num_c = 0 + if self.with_kp: + num_c += all_kps.shape[2] + if self.with_limb: + num_c += len(self.skeletons) + ret = np.zeros([num_frame, num_c, img_h, img_w], dtype=np.float32) + + for i in range(num_frame): + # M, V, C + kps = all_kps[:, i] + # M, C + kpscores = all_kpscores[:, i] if self.use_score else np.ones_like(all_kpscores[:, i]) + + self.generate_heatmap(ret[i], kps, kpscores) + return ret + + def __call__(self, results): + heatmap = self.gen_an_aug(results) + + if self.double: + indices = np.arange(heatmap.shape[1], dtype=np.int64) + left, right = (self.left_kp, self.right_kp) if self.with_kp else (self.left_limb, self.right_limb) + for l, r in zip(left, right): # noqa: E741 + indices[l] = r + indices[r] = l + heatmap_flip = heatmap[..., ::-1][:, indices] + heatmap = np.concatenate([heatmap, heatmap_flip]) + results['imgs'] = heatmap + return results + + def __repr__(self): + repr_str = (f'{self.__class__.__name__}(' + f'sigma={self.sigma}, ' + f'use_score={self.use_score}, ' + f'with_kp={self.with_kp}, ' + f'with_limb={self.with_limb}, ' + f'skeletons={self.skeletons}, ' + f'double={self.double}, ' + f'left_kp={self.left_kp}, ' + f'right_kp={self.right_kp})') + return repr_str diff --git a/pyskl/datasets/pipelines/sampling.py b/pyskl/datasets/pipelines/sampling.py new file mode 100644 index 00000000..71300319 --- /dev/null +++ b/pyskl/datasets/pipelines/sampling.py @@ -0,0 +1,384 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import warnings + +import numpy as np + +from ..builder import PIPELINES + + +@PIPELINES.register_module() +class UniformSampleFrames: + """Uniformly sample frames from the video. + + To sample an n-frame clip from the video. UniformSampleFrames basically + divide the video into n segments of equal length and randomly sample one + frame from each segment. To make the testing results reproducible, a + random seed is set during testing, to make the sampling results + deterministic. + + Required keys are "total_frames", "start_index" , added or modified keys + are "frame_inds", "clip_len", "frame_interval" and "num_clips". + + Args: + clip_len (int): Frames of each sampled output clip. + num_clips (int): Number of clips to be sampled. Default: 1. + test_mode (bool): Store True when building test or validation dataset. + Default: False. + seed (int): The random seed used during test time. Default: 255. + """ + + def __init__(self, + clip_len, + num_clips=1, + test_mode=False, + float_ok=False, + p_interval=1, + seed=255): + + self.clip_len = clip_len + self.num_clips = num_clips + self.test_mode = test_mode + self.float_ok = float_ok + self.seed = seed + self.p_interval = p_interval + if not isinstance(p_interval, tuple): + self.p_interval = (p_interval, p_interval) + + if self.float_ok: + warnings.warn('When float_ok == True, there will be no loop.') + + def _get_train_clips(self, num_frames, clip_len): + """Uniformly sample indices for training clips. + + Args: + num_frames (int): The number of frames. + clip_len (int): The length of the clip. + """ + allinds = [] + for clip_idx in range(self.num_clips): + old_num_frames = num_frames + pi = self.p_interval + ratio = np.random.rand() * (pi[1] - pi[0]) + pi[0] + num_frames = int(ratio * num_frames) + off = np.random.randint(old_num_frames - num_frames + 1) + + if self.float_ok: + interval = (num_frames - 1) / clip_len + offsets = np.arange(clip_len) * interval + inds = np.random.rand(clip_len) * interval + offsets + inds = inds.astype(np.float32) + elif num_frames < clip_len: + start = np.random.randint(0, num_frames) + inds = np.arange(start, start + clip_len) + elif clip_len <= num_frames < 2 * clip_len: + basic = np.arange(clip_len) + inds = np.random.choice( + clip_len + 1, num_frames - clip_len, replace=False) + offset = np.zeros(clip_len + 1, dtype=np.int64) + offset[inds] = 1 + offset = np.cumsum(offset) + inds = basic + offset[:-1] + else: + bids = np.array( + [i * num_frames // clip_len for i in range(clip_len + 1)]) + bsize = np.diff(bids) + bst = bids[:clip_len] + offset = np.random.randint(bsize) + inds = bst + offset + + inds = inds + off + num_frames = old_num_frames + + allinds.append(inds) + + return np.concatenate(allinds) + + def _get_test_clips(self, num_frames, clip_len): + """Uniformly sample indices for testing clips. + + Args: + num_frames (int): The number of frames. + clip_len (int): The length of the clip. + """ + np.random.seed(self.seed) + if self.float_ok: + interval = (num_frames - 1) / clip_len + offsets = np.arange(clip_len) * interval + inds = np.concatenate([ + np.random.rand(clip_len) * interval + offsets + for i in range(self.num_clips) + ]).astype(np.float32) + + all_inds = [] + + for i in range(self.num_clips): + + old_num_frames = num_frames + pi = self.p_interval + ratio = np.random.rand() * (pi[1] - pi[0]) + pi[0] + num_frames = int(ratio * num_frames) + off = np.random.randint(old_num_frames - num_frames + 1) + + if num_frames < clip_len: + start_ind = i if num_frames < self.num_clips else i * num_frames // self.num_clips + inds = np.arange(start_ind, start_ind + clip_len) + elif clip_len <= num_frames < clip_len * 2: + basic = np.arange(clip_len) + inds = np.random.choice(clip_len + 1, num_frames - clip_len, replace=False) + offset = np.zeros(clip_len + 1, dtype=np.int64) + offset[inds] = 1 + offset = np.cumsum(offset) + inds = basic + offset[:-1] + else: + bids = np.array([i * num_frames // clip_len for i in range(clip_len + 1)]) + bsize = np.diff(bids) + bst = bids[:clip_len] + offset = np.random.randint(bsize) + inds = bst + offset + + all_inds.append(inds + off) + num_frames = old_num_frames + + return np.concatenate(all_inds) + + def __call__(self, results): + num_frames = results['total_frames'] + + if self.test_mode: + inds = self._get_test_clips(num_frames, self.clip_len) + else: + inds = self._get_train_clips(num_frames, self.clip_len) + + inds = np.mod(inds, num_frames) + start_index = results['start_index'] + inds = inds + start_index + + if 'keypoint' in results: + kp = results['keypoint'] + assert num_frames == kp.shape[1] + num_person = kp.shape[0] + num_persons = [num_person] * num_frames + for i in range(num_frames): + j = num_person - 1 + while j >= 0 and np.all(np.abs(kp[j, i]) < 1e-5): + j -= 1 + num_persons[i] = j + 1 + transitional = [False] * num_frames + for i in range(1, num_frames - 1): + if num_persons[i] != num_persons[i - 1]: + transitional[i] = transitional[i - 1] = True + if num_persons[i] != num_persons[i + 1]: + transitional[i] = transitional[i + 1] = True + inds_int = inds.astype(np.int) + coeff = np.array([transitional[i] for i in inds_int]) + inds = (coeff * inds_int + (1 - coeff) * inds).astype(np.float32) + + results['frame_inds'] = inds if self.float_ok else inds.astype(np.int) + results['clip_len'] = self.clip_len + results['frame_interval'] = None + results['num_clips'] = self.num_clips + return results + + def __repr__(self): + repr_str = (f'{self.__class__.__name__}(' + f'clip_len={self.clip_len}, ' + f'num_clips={self.num_clips}, ' + f'test_mode={self.test_mode}, ' + f'seed={self.seed})') + return repr_str + + +@PIPELINES.register_module() +class UniformSample(UniformSampleFrames): + pass + + +@PIPELINES.register_module() +class SampleFrames: + """Sample frames from the video. + + Required keys are "total_frames", "start_index" , added or modified keys + are "frame_inds", "frame_interval" and "num_clips". + + Args: + clip_len (int): Frames of each sampled output clip. + frame_interval (int): Temporal interval of adjacent sampled frames. + Default: 1. + num_clips (int): Number of clips to be sampled. Default: 1. + temporal_jitter (bool): Whether to apply temporal jittering. + Default: False. + twice_sample (bool): Whether to use twice sample when testing. + If set to True, it will sample frames with and without fixed shift, + which is commonly used for testing in TSM model. Default: False. + out_of_bound_opt (str): The way to deal with out of bounds frame + indexes. Available options are 'loop', 'repeat_last'. + Default: 'loop'. + test_mode (bool): Store True when building test or validation dataset. + Default: False. + start_index (None): This argument is deprecated and moved to dataset + class (``BaseDataset``, ``VideoDatset``, ``RawframeDataset``, etc), + see this: https://github.com/open-mmlab/mmaction2/pull/89. + keep_tail_frames (bool): Whether to keep tail frames when sampling. + Default: False. + """ + + def __init__(self, + clip_len, + frame_interval=1, + num_clips=1, + temporal_jitter=False, + twice_sample=False, + out_of_bound_opt='loop', + test_mode=False, + start_index=None, + keep_tail_frames=False): + + self.clip_len = clip_len + self.frame_interval = frame_interval + self.num_clips = num_clips + self.temporal_jitter = temporal_jitter + self.twice_sample = twice_sample + self.out_of_bound_opt = out_of_bound_opt + self.test_mode = test_mode + self.keep_tail_frames = keep_tail_frames + assert self.out_of_bound_opt in ['loop', 'repeat_last'] + + if start_index is not None: + warnings.warn('No longer support "start_index" in "SampleFrames", ' + 'it should be set in dataset class, see this pr: ' + 'https://github.com/open-mmlab/mmaction2/pull/89') + + def _get_train_clips(self, num_frames): + """Get clip offsets in train mode. + + It will calculate the average interval for selected frames, + and randomly shift them within offsets between [0, avg_interval]. + If the total number of frames is smaller than clips num or origin + frames length, it will return all zero indices. + + Args: + num_frames (int): Total number of frame in the video. + + Returns: + np.ndarray: Sampled frame indices in train mode. + """ + ori_clip_len = self.clip_len * self.frame_interval + + if self.keep_tail_frames: + avg_interval = (num_frames - ori_clip_len + 1) / float( + self.num_clips) + if num_frames > ori_clip_len - 1: + base_offsets = np.arange(self.num_clips) * avg_interval + clip_offsets = (base_offsets + np.random.uniform( + 0, avg_interval, self.num_clips)).astype(np.int) + else: + clip_offsets = np.zeros((self.num_clips, ), dtype=np.int) + else: + avg_interval = (num_frames - ori_clip_len + 1) // self.num_clips + + if avg_interval > 0: + base_offsets = np.arange(self.num_clips) * avg_interval + clip_offsets = base_offsets + np.random.randint( + avg_interval, size=self.num_clips) + elif num_frames > max(self.num_clips, ori_clip_len): + clip_offsets = np.sort( + np.random.randint( + num_frames - ori_clip_len + 1, size=self.num_clips)) + elif avg_interval == 0: + ratio = (num_frames - ori_clip_len + 1.0) / self.num_clips + clip_offsets = np.around(np.arange(self.num_clips) * ratio) + else: + clip_offsets = np.zeros((self.num_clips, ), dtype=np.int) + + return clip_offsets + + def _get_test_clips(self, num_frames): + """Get clip offsets in test mode. + + Calculate the average interval for selected frames, and shift them + fixedly by avg_interval/2. If set twice_sample True, it will sample + frames together without fixed shift. If the total number of frames is + not enough, it will return all zero indices. + + Args: + num_frames (int): Total number of frame in the video. + + Returns: + np.ndarray: Sampled frame indices in test mode. + """ + ori_clip_len = self.clip_len * self.frame_interval + avg_interval = (num_frames - ori_clip_len + 1) / float(self.num_clips) + if num_frames > ori_clip_len - 1: + base_offsets = np.arange(self.num_clips) * avg_interval + clip_offsets = (base_offsets + avg_interval / 2.0).astype(np.int) + if self.twice_sample: + clip_offsets = np.concatenate([clip_offsets, base_offsets]) + else: + clip_offsets = np.zeros((self.num_clips, ), dtype=np.int) + return clip_offsets + + def _sample_clips(self, num_frames): + """Choose clip offsets for the video in a given mode. + + Args: + num_frames (int): Total number of frame in the video. + + Returns: + np.ndarray: Sampled frame indices. + """ + if self.test_mode: + clip_offsets = self._get_test_clips(num_frames) + else: + clip_offsets = self._get_train_clips(num_frames) + + return clip_offsets + + def __call__(self, results): + """Perform the SampleFrames loading. + + Args: + results (dict): The resulting dict to be modified and passed + to the next transform in pipeline. + """ + total_frames = results['total_frames'] + + clip_offsets = self._sample_clips(total_frames) + frame_inds = clip_offsets[:, None] + np.arange( + self.clip_len)[None, :] * self.frame_interval + frame_inds = np.concatenate(frame_inds) + + if self.temporal_jitter: + perframe_offsets = np.random.randint( + self.frame_interval, size=len(frame_inds)) + frame_inds += perframe_offsets + + frame_inds = frame_inds.reshape((-1, self.clip_len)) + if self.out_of_bound_opt == 'loop': + frame_inds = np.mod(frame_inds, total_frames) + elif self.out_of_bound_opt == 'repeat_last': + safe_inds = frame_inds < total_frames + unsafe_inds = 1 - safe_inds + last_ind = np.max(safe_inds * frame_inds, axis=1) + new_inds = (safe_inds * frame_inds + (unsafe_inds.T * last_ind).T) + frame_inds = new_inds + else: + raise ValueError('Illegal out_of_bound option.') + + start_index = results['start_index'] + frame_inds = np.concatenate(frame_inds) + start_index + results['frame_inds'] = frame_inds.astype(np.int) + results['clip_len'] = self.clip_len + results['frame_interval'] = self.frame_interval + results['num_clips'] = self.num_clips + return results + + def __repr__(self): + repr_str = (f'{self.__class__.__name__}(' + f'clip_len={self.clip_len}, ' + f'frame_interval={self.frame_interval}, ' + f'num_clips={self.num_clips}, ' + f'temporal_jitter={self.temporal_jitter}, ' + f'twice_sample={self.twice_sample}, ' + f'out_of_bound_opt={self.out_of_bound_opt}, ' + f'test_mode={self.test_mode})') + return repr_str diff --git a/pyskl/datasets/pose_dataset.py b/pyskl/datasets/pose_dataset.py new file mode 100644 index 00000000..7d4e6d1a --- /dev/null +++ b/pyskl/datasets/pose_dataset.py @@ -0,0 +1,108 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os.path as osp + +import mmcv +import numpy as np + +from ..utils import get_root_logger +from .base import BaseDataset +from .builder import DATASETS + + +@DATASETS.register_module() +class PoseDataset(BaseDataset): + """Pose dataset for action recognition. + + The dataset loads pose and apply specified transforms to return a + dict containing pose information. + + The ann_file is a pickle file, the json file contains a list of + annotations, the fields of an annotation include frame_dir(video_id), + total_frames, label, kp, kpscore. + + Args: + ann_file (str): Path to the annotation file. + pipeline (list[dict | callable]): A sequence of data transforms. + split (str | None): The dataset split used. For UCF101 and HMDB51, allowed choices are 'train1', 'test1', + 'train2', 'test2', 'train3', 'test3'. For NTURGB+D, allowed choices are 'xsub_train', 'xsub_val', + 'xview_train', 'xview_val'. For NTURGB+D 120, allowed choices are 'xsub_train', 'xsub_val', 'xset_train', + 'xset_val'. For FineGYM, allowed choices are 'train', 'val'. Default: None. + valid_ratio (float | None): The valid_ratio for videos in KineticsPose. For a video with n frames, it is a + valid training sample only if n * valid_ratio frames have human pose. None means not applicable (only + applicable to Kinetics Pose). Default: None. + box_thr (str | None): The threshold for human proposals. Only boxes with confidence score larger than `box_thr` + is kept. None means not applicable (only applicable to Kinetics Pose [ours]). Allowed choices are '0.5', + '0.6', '0.7', '0.8', '0.9'. Default: None. + class_prob (list | None): The class-specific multiplier, which should be a list of length 'num_classes', each + element >= 1. The goal is to resample some rare classes to improve the overall performance. None means no + resampling performed. Default: None. + **kwargs: Keyword arguments for 'BaseDataset'. + """ + + def __init__(self, + ann_file, + pipeline, + split=None, + valid_ratio=None, + box_thr=None, + class_prob=None, + **kwargs): + modality = 'Pose' + self.split = split + + super().__init__( + ann_file, pipeline, start_index=0, modality=modality, **kwargs) + + # box_thr, which should be a string + self.box_thr = box_thr + self.class_prob = class_prob + if self.box_thr is not None: + assert box_thr in ['0.5', '0.6', '0.7', '0.8', '0.9'] + + # Thresholding Training Examples + self.valid_ratio = valid_ratio + if self.valid_ratio is not None: + assert isinstance(self.valid_ratio, float) + if self.box_thr is None: + self.video_infos = [ + x for x in self.video_infos + if x['valid_frames'] / x['total_frames'] >= valid_ratio + ] + else: + key = f'valid@{self.box_thr}' + self.video_infos = [ + x for x in self.video_infos + if x[key] / x['total_frames'] >= valid_ratio + ] + if self.box_thr != '0.5': + box_thr = float(self.box_thr) + for item in self.video_infos: + inds = [ + i for i, score in enumerate(item['box_score']) + if score >= box_thr + ] + item['anno_inds'] = np.array(inds) + + logger = get_root_logger() + logger.info(f'{len(self)} videos remain after valid thresholding') + + def load_annotations(self): + """Load annotation file to get video information.""" + assert self.ann_file.endswith('.pkl') + return self.load_pkl_annotations() + + def load_pkl_annotations(self): + data = mmcv.load(self.ann_file) + + if self.split: + split, data = data['split'], data['annotations'] + identifier = 'filename' if 'filename' in data[0] else 'frame_dir' + data = [x for x in data if x[identifier] in split[self.split]] + + for item in data: + # Sometimes we may need to load anno from the file + if 'filename' in item: + item['filename'] = osp.join(self.data_prefix, item['filename']) + if 'frame_dir' in item: + item['frame_dir'] = osp.join(self.data_prefix, item['frame_dir']) + return data diff --git a/pyskl/datasets/samplers/__init__.py b/pyskl/datasets/samplers/__init__.py new file mode 100644 index 00000000..ca7f3c96 --- /dev/null +++ b/pyskl/datasets/samplers/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .distributed_sampler import ClassSpecificDistributedSampler, DistributedSampler + +__all__ = ['DistributedSampler', 'ClassSpecificDistributedSampler'] diff --git a/pyskl/datasets/samplers/distributed_sampler.py b/pyskl/datasets/samplers/distributed_sampler.py new file mode 100644 index 00000000..76655fd2 --- /dev/null +++ b/pyskl/datasets/samplers/distributed_sampler.py @@ -0,0 +1,112 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import math +from collections import defaultdict + +import torch +from torch.utils.data import DistributedSampler as _DistributedSampler + + +class DistributedSampler(_DistributedSampler): + """DistributedSampler inheriting from + ``torch.utils.data.DistributedSampler``. + + In pytorch of lower versions, there is no ``shuffle`` argument. This child + class will port one to DistributedSampler. + """ + + def __init__(self, + dataset, + num_replicas=None, + rank=None, + shuffle=True, + seed=0): + super().__init__(dataset, num_replicas=num_replicas, rank=rank, shuffle=shuffle) + # for the compatibility from PyTorch 1.3+ + self.seed = seed if seed is not None else 0 + + def __iter__(self): + # deterministically shuffle based on epoch + if self.shuffle: + g = torch.Generator() + g.manual_seed(self.epoch + self.seed) + indices = torch.randperm(len(self.dataset), generator=g).tolist() + else: + indices = torch.arange(len(self.dataset)).tolist() + + # add extra samples to make it evenly divisible + indices += indices[:(self.total_size - len(indices))] + assert len(indices) == self.total_size + + # subsample + indices = indices[self.rank:self.total_size:self.num_replicas] + assert len(indices) == self.num_samples + return iter(indices) + + +class ClassSpecificDistributedSampler(_DistributedSampler): + """ClassSpecificDistributedSampler inheriting from 'torch.utils.data.DistributedSampler'. + + Samples are sampled with a class specific probability (class_prob). This sampler is only applicable to single class + recognition dataset. This sampler is also compatible with RepeatDataset. + """ + + def __init__(self, + dataset, + num_replicas=None, + rank=None, + class_prob=None, + shuffle=True, + seed=0): + + super().__init__(dataset, num_replicas=num_replicas, rank=rank) + self.shuffle = shuffle + if class_prob is not None: + if isinstance(class_prob, list): + class_prob = {i: n for i, n in enumerate(class_prob)} + assert isinstance(class_prob, dict) + self.class_prob = class_prob + # for the compatibility from PyTorch 1.3+ + self.seed = seed if seed is not None else 0 + + def __iter__(self): + g = torch.Generator() + g.manual_seed(self.seed + self.epoch) + + class_prob = self.class_prob + dataset_name = type(self.dataset).__name__ + dataset = self.dataset if dataset_name != 'RepeatDataset' else self.dataset.dataset + times = 1 + if dataset_name == 'RepeatDataset': + times = self.dataset.times + class_prob = {k: v * times for k, v in class_prob.items()} + + labels = [x['label'] for x in dataset.video_infos] + samples = defaultdict(list) + for i, lb in enumerate(labels): + samples[lb].append(i) + + indices = [] + for class_idx, class_indices in samples.items(): + mul = class_prob.get(class_idx, times) + for i in range(int(mul // 1)): + indices.extend(class_indices) + rem = int((mul % 1) * len(class_indices)) + inds = torch.randperm(len(class_indices), generator=g).tolist() + indices.extend([class_indices[inds[i]] for i in range(rem)]) + + if self.shuffle: + shuffle = torch.randperm(len(indices), generator=g).tolist() + indices = [indices[i] for i in shuffle] + + # reset num_samples and total_size here. + self.num_samples = math.ceil(len(indices) / self.num_replicas) + self.total_size = self.num_samples * self.num_replicas + + # add extra samples to make it evenly divisible + indices += indices[:(self.total_size - len(indices))] + assert len(indices) == self.total_size + + # subsample + indices = indices[self.rank:self.total_size:self.num_replicas] + assert len(indices) == self.num_samples + return iter(indices) diff --git a/pyskl/datasets/video_dataset.py b/pyskl/datasets/video_dataset.py new file mode 100644 index 00000000..3f8f03c3 --- /dev/null +++ b/pyskl/datasets/video_dataset.py @@ -0,0 +1,60 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os.path as osp + +from .base import BaseDataset +from .builder import DATASETS + + +@DATASETS.register_module() +class VideoDataset(BaseDataset): + """Video dataset for action recognition. + + The dataset loads raw videos and apply specified transforms to return a + dict containing the frame tensors and other information. + + The ann_file is a text file with multiple lines, and each line indicates + a sample video with the filepath and label, which are split with a + whitespace. Example of a annotation file: + + .. code-block:: txt + + some/path/000.mp4 1 + some/path/001.mp4 1 + some/path/002.mp4 2 + some/path/003.mp4 2 + some/path/004.mp4 3 + some/path/005.mp4 3 + + + Args: + ann_file (str): Path to the annotation file. + pipeline (list[dict | callable]): A sequence of data transforms. + start_index (int): Specify a start index for frames in consideration of + different filename format. However, when taking videos as input, + it should be set to 0, since frames loaded from videos count + from 0. Default: 0. + **kwargs: Keyword arguments for ``BaseDataset``. + """ + + def __init__(self, ann_file, pipeline, start_index=0, **kwargs): + super().__init__(ann_file, pipeline, start_index=start_index, **kwargs) + + def load_annotations(self): + """Load annotation file to get video information.""" + if self.ann_file.endswith('.json'): + return self.load_json_annotations() + + video_infos = [] + with open(self.ann_file, 'r') as fin: + for line in fin: + line_split = line.strip().split() + if self.multi_class: + assert self.num_classes is not None + filename, label = line_split[0], line_split[1:] + label = list(map(int, label)) + else: + filename, label = line_split + label = int(label) + filename = osp.join(self.data_prefix, filename) + video_infos.append(dict(filename=filename, label=label)) + return video_infos diff --git a/pyskl/models/__init__.py b/pyskl/models/__init__.py new file mode 100644 index 00000000..4b3c9e79 --- /dev/null +++ b/pyskl/models/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .builder import * # noqa: F401, F403 +from .cnns import * # noqa: F401, F403 +from .gcns import * # noqa: F401, F403 +from .heads import * # noqa: F401, F403 +from .losses import * # noqa: F401, F403 +from .recognizers import * # noqa: F401, F403 diff --git a/pyskl/models/builder.py b/pyskl/models/builder.py new file mode 100644 index 00000000..d1a8b11b --- /dev/null +++ b/pyskl/models/builder.py @@ -0,0 +1,38 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from mmcv.cnn import MODELS as MMCV_MODELS +from mmcv.utils import Registry + +MODELS = Registry('models', parent=MMCV_MODELS) +BACKBONES = MODELS +HEADS = MODELS +RECOGNIZERS = MODELS +LOSSES = MODELS + + +def build_backbone(cfg): + """Build backbone.""" + return BACKBONES.build(cfg) + + +def build_head(cfg): + """Build head.""" + return HEADS.build(cfg) + + +def build_recognizer(cfg): + """Build recognizer.""" + return RECOGNIZERS.build(cfg) + + +def build_loss(cfg): + """Build loss.""" + return LOSSES.build(cfg) + + +def build_model(cfg): + """Build model.""" + args = cfg.copy() + obj_type = args.pop('type') + if obj_type in RECOGNIZERS: + return build_recognizer(cfg) + raise ValueError(f'{obj_type} is not registered') diff --git a/pyskl/models/cnns/__init__.py b/pyskl/models/cnns/__init__.py new file mode 100644 index 00000000..7420f9b4 --- /dev/null +++ b/pyskl/models/cnns/__init__.py @@ -0,0 +1,11 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .c3d import C3D +from .resnet import ResNet +from .resnet3d import ResNet3d +from .resnet3d_slowfast import ResNet3dSlowFast +from .resnet3d_slowonly import ResNet3dSlowOnly +from .x3d import X3D + +__all__ = [ + 'C3D', 'X3D', 'ResNet', 'ResNet3d', 'ResNet3dSlowFast', 'ResNet3dSlowOnly' +] diff --git a/pyskl/models/cnns/c3d.py b/pyskl/models/cnns/c3d.py new file mode 100644 index 00000000..f657190f --- /dev/null +++ b/pyskl/models/cnns/c3d.py @@ -0,0 +1,98 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch.nn as nn +from mmcv.cnn import ConvModule, kaiming_init +from mmcv.runner import load_checkpoint + +from ...utils import get_root_logger +from ..builder import BACKBONES + + +@BACKBONES.register_module() +class C3D(nn.Module): + """C3D backbone, without flatten and mlp. + + Args: + pretrained (str | None): Name of pretrained model. + """ + + def __init__(self, + in_channels=3, + base_channels=64, + num_stages=4, + temporal_downsample=True, + pretrained=None): + super().__init__() + conv_cfg = dict(type='Conv3d') + norm_cfg = dict(type='BN3d') + act_cfg = dict(type='ReLU') + self.pretrained = pretrained + self.in_channels = in_channels + self.base_channels = base_channels + assert num_stages in [3, 4] + self.num_stages = num_stages + self.temporal_downsample = temporal_downsample + pool_kernel, pool_stride = 2, 2 + if not self.temporal_downsample: + pool_kernel, pool_stride = (1, 2, 2), (1, 2, 2) + + c3d_conv_param = dict(kernel_size=3, padding=1, conv_cfg=conv_cfg, norm_cfg=norm_cfg, act_cfg=act_cfg) + + self.conv1a = ConvModule(self.in_channels, self.base_channels, **c3d_conv_param) + self.pool1 = nn.AvgPool3d(kernel_size=(1, 2, 2), stride=(1, 2, 2)) + + self.conv2a = ConvModule(self.base_channels, self.base_channels * 2, **c3d_conv_param) + self.pool2 = nn.AvgPool3d(kernel_size=pool_kernel, stride=pool_stride) + + self.conv3a = ConvModule(self.base_channels * 2, self.base_channels * 4, **c3d_conv_param) + self.conv3b = ConvModule(self.base_channels * 4, self.base_channels * 4, **c3d_conv_param) + self.pool3 = nn.AvgPool3d(kernel_size=pool_kernel, stride=pool_stride) + + self.conv4a = ConvModule(self.base_channels * 4, self.base_channels * 8, **c3d_conv_param) + self.conv4b = ConvModule(self.base_channels * 8, self.base_channels * 8, **c3d_conv_param) + + if self.num_stages == 4: + self.pool4 = nn.AvgPool3d(kernel_size=pool_kernel, stride=pool_stride) + self.conv5a = ConvModule(self.base_channels * 8, self.base_channels * 8, **c3d_conv_param) + self.conv5b = ConvModule(self.base_channels * 8, self.base_channels * 8, **c3d_conv_param) + + def init_weights(self): + """Initiate the parameters either from existing checkpoint or from + scratch.""" + for m in self.modules(): + if isinstance(m, nn.Conv3d): + kaiming_init(m) + if isinstance(self.pretrained, str): + logger = get_root_logger() + logger.info(f'load model from: {self.pretrained}') + load_checkpoint(self, self.pretrained, strict=False, logger=logger) + + def forward(self, x): + """Defines the computation performed at every call. + + Args: + x (torch.Tensor): The input data. The size of x is (num_batches, 3, 16, 112, 112). + + Returns: + torch.Tensor: The feature of the input samples extracted by the backbone. + """ + x = self.conv1a(x) + + x = self.pool1(x) + x = self.conv2a(x) + + x = self.pool2(x) + x = self.conv3a(x) + x = self.conv3b(x) + + x = self.pool3(x) + x = self.conv4a(x) + x = self.conv4b(x) + + if self.num_stages == 3: + return x + + x = self.pool4(x) + x = self.conv5a(x) + x = self.conv5b(x) + + return x diff --git a/pyskl/models/cnns/resnet.py b/pyskl/models/cnns/resnet.py new file mode 100644 index 00000000..b11978ba --- /dev/null +++ b/pyskl/models/cnns/resnet.py @@ -0,0 +1,477 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch.nn as nn +from mmcv.cnn import ConvModule, constant_init, kaiming_init +from mmcv.runner import _load_checkpoint, load_checkpoint +from mmcv.utils import _BatchNorm + +from ...utils import get_root_logger +from ..builder import BACKBONES + + +class BasicBlock(nn.Module): + """Basic block for ResNet. + + Args: + inplanes (int): Number of channels for the input in first conv2d layer. + planes (int): Number of channels produced by some norm/conv2d layers. + stride (int): Stride in the conv layer. Default: 1. + downsample (nn.Module | None): Downsample layer. Default: None. + conv_cfg (dict): Config for norm layers. Default: dict(type='Conv'). + norm_cfg (dict): Config for norm layers. required keys are 'type' and 'requires_grad'. + Default: dict(type='BN2d', requires_grad=True). + act_cfg (dict): Config for activate layers. Default: dict(type='ReLU', inplace=True). + """ + expansion = 1 + + def __init__(self, + inplanes, + planes, + stride=1, + downsample=None, + conv_cfg=dict(type='Conv'), + norm_cfg=dict(type='BN', requires_grad=True), + act_cfg=dict(type='ReLU', inplace=True)): + super().__init__() + self.conv1 = ConvModule( + inplanes, + planes, + kernel_size=3, + stride=stride, + padding=1, + bias=False, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + + self.conv2 = ConvModule( + planes, + planes, + kernel_size=3, + stride=1, + padding=1, + bias=False, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=None) + + self.relu = nn.ReLU(inplace=True) + self.downsample = downsample + self.stride = stride + self.norm_cfg = norm_cfg + + def forward(self, x): + """Defines the computation performed at every call. + + Args: + x (torch.Tensor): The input data. + + Returns: + torch.Tensor: The output of the module. + """ + identity = x + + out = self.conv1(x) + out = self.conv2(out) + + if self.downsample is not None: + identity = self.downsample(x) + + out = out + identity + out = self.relu(out) + + return out + + +class Bottleneck(nn.Module): + """Bottleneck block for ResNet. + + Args: + inplanes (int): Number of channels for the input feature in first conv layer. + planes (int): Number of channels produced by some norm layes and conv layers. + stride (int): Spatial stride in the conv layer. Default: 1. + downsample (nn.Module | None): Downsample layer. Default: None. + conv_cfg (dict): Config for norm layers. Default: dict(type='Conv'). + norm_cfg (dict): Config for norm layers. required keys are 'type' and 'requires_grad'. + Default: dict(type='BN2d', requires_grad=True). + act_cfg (dict): Config for activate layers. Default: dict(type='ReLU', inplace=True). + """ + + expansion = 4 + + def __init__(self, + inplanes, + planes, + stride=1, + downsample=None, + conv_cfg=dict(type='Conv'), + norm_cfg=dict(type='BN', requires_grad=True), + act_cfg=dict(type='ReLU', inplace=True)): + super().__init__() + self.inplanes = inplanes + self.planes = planes + self.conv1_stride = 1 + self.conv2_stride = stride + self.conv1 = ConvModule( + inplanes, + planes, + kernel_size=1, + stride=self.conv1_stride, + bias=False, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + self.conv2 = ConvModule( + planes, + planes, + kernel_size=3, + stride=self.conv2_stride, + padding=1, + bias=False, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + + self.conv3 = ConvModule( + planes, + planes * self.expansion, + kernel_size=1, + bias=False, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=None) + + self.relu = nn.ReLU(inplace=True) + self.downsample = downsample + self.stride = stride + self.norm_cfg = norm_cfg + + def forward(self, x): + """Defines the computation performed at every call. + + Args: + x (torch.Tensor): The input data. + + Returns: + torch.Tensor: The output of the module. + """ + + def _inner_forward(x): + """Forward wrapper for utilizing checkpoint.""" + identity = x + + out = self.conv1(x) + out = self.conv2(out) + out = self.conv3(out) + + if self.downsample is not None: + identity = self.downsample(x) + + out = out + identity + + return out + + out = _inner_forward(x) + out = self.relu(out) + + return out + + +def make_res_layer(block, + inplanes, + planes, + blocks, + stride=1, + conv_cfg=None, + norm_cfg=None, + act_cfg=None): + """Build residual layer for ResNet. + + Args: + block: (nn.Module): Residual module to be built. + inplanes (int): Number of channels for the input feature in each block. + planes (int): Number of channels for the output feature in each block. + blocks (int): Number of residual blocks. + stride (int): Stride in the conv layer. Default: 1. + conv_cfg (dict | None): Config for norm layers. Default: None. + norm_cfg (dict | None): Config for norm layers. Default: None. + act_cfg (dict | None): Config for activate layers. Default: None. + + Returns: + nn.Module: A residual layer for the given config. + """ + downsample = None + if stride != 1 or inplanes != planes * block.expansion: + downsample = ConvModule( + inplanes, + planes * block.expansion, + kernel_size=1, + stride=stride, + bias=False, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=None) + + layers = [] + layers.append( + block( + inplanes, + planes, + stride, + downsample, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg)) + inplanes = planes * block.expansion + for _ in range(1, blocks): + layers.append( + block( + inplanes, + planes, + 1, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg)) + + return nn.Sequential(*layers) + + +@BACKBONES.register_module() +class ResNet(nn.Module): + """ResNet backbone. + + Args: + depth (int): Depth of resnet, from {18, 34, 50, 101, 152}. Default: 50. + pretrained (str | None): Name of pretrained model. Default: None. + in_channels (int): Channel num of input features. Default: 3. + num_stages (int): Resnet stages. Default: 4. + strides (Sequence[int]): Strides of the first block of each stage. + out_indices (Sequence[int]): Indices of output feature. Default: (3, ). + frozen_stages (int): Stages to be frozen (all param fixed). -1 means not freezing any parameters. Default: -1. + conv_cfg (dict): Config for norm layers. Default: dict(type='Conv'). + norm_cfg (dict): Config for norm layers. required keys are 'type' and 'requires_grad'. + Default: dict(type='BN2d', requires_grad=True). + act_cfg (dict): Config for activate layers. Default: dict(type='ReLU', inplace=True). + norm_eval (bool): Whether to set BN layers to eval mode, namely, freeze running stats (mean and var). + Default: False. + """ + + arch_settings = { + 18: (BasicBlock, (2, 2, 2, 2)), + 34: (BasicBlock, (3, 4, 6, 3)), + 50: (Bottleneck, (3, 4, 6, 3)), + 101: (Bottleneck, (3, 4, 23, 3)), + 152: (Bottleneck, (3, 8, 36, 3)) + } + + def __init__(self, + depth=50, + pretrained=None, + torchvision_pretrain=True, + in_channels=3, + num_stages=4, + out_indices=(3, ), + strides=(1, 2, 2, 2), + frozen_stages=-1, + conv_cfg=dict(type='Conv'), + norm_cfg=dict(type='BN2d', requires_grad=True), + act_cfg=dict(type='ReLU', inplace=True), + norm_eval=False): + super().__init__() + if depth not in self.arch_settings: + raise KeyError(f'invalid depth {depth} for resnet') + self.depth = depth + self.in_channels = in_channels + self.pretrained = pretrained + self.torchvision_pretrain = torchvision_pretrain + self.num_stages = num_stages + assert 1 <= num_stages <= 4 + self.out_indices = out_indices + assert max(out_indices) < num_stages + self.strides = strides + assert len(strides) == num_stages + self.frozen_stages = frozen_stages + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + self.norm_eval = norm_eval + + self.block, stage_blocks = self.arch_settings[depth] + self.stage_blocks = stage_blocks[:num_stages] + self.inplanes = 64 + + self._make_stem_layer() + + self.res_layers = [] + for i, num_blocks in enumerate(self.stage_blocks): + stride = strides[i] + planes = 64 * 2**i + res_layer = make_res_layer( + self.block, + self.inplanes, + planes, + num_blocks, + stride=stride, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + self.inplanes = planes * self.block.expansion + layer_name = f'layer{i + 1}' + self.add_module(layer_name, res_layer) + self.res_layers.append(layer_name) + + self.feat_dim = self.block.expansion * 64 * 2**( + len(self.stage_blocks) - 1) + + def _make_stem_layer(self): + """Construct the stem layers consists of a conv+norm+act module and a + pooling layer.""" + self.conv1 = ConvModule( + self.in_channels, + 64, + kernel_size=7, + stride=2, + padding=3, + bias=False, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) + + @staticmethod + def _load_conv_params(conv, state_dict_tv, module_name_tv, loaded_param_names): + """Load the conv parameters of resnet from torchvision. + + Args: + conv (nn.Module): The destination conv module. + state_dict_tv (OrderedDict): The state dict of pretrained torchvision model. + module_name_tv (str): The name of corresponding conv module in the torchvision model. + loaded_param_names (list[str]): List of parameters that have been loaded. + """ + + weight_tv_name = module_name_tv + '.weight' + if conv.weight.data.shape == state_dict_tv[weight_tv_name].shape: + conv.weight.data.copy_(state_dict_tv[weight_tv_name]) + loaded_param_names.append(weight_tv_name) + + if getattr(conv, 'bias') is not None: + bias_tv_name = module_name_tv + '.bias' + if conv.bias.data.shape == state_dict_tv[bias_tv_name].shape: + conv.bias.data.copy_(state_dict_tv[bias_tv_name]) + loaded_param_names.append(bias_tv_name) + + @staticmethod + def _load_bn_params(bn, state_dict_tv, module_name_tv, loaded_param_names): + """Load the bn parameters of resnet from torchvision. + + Args: + bn (nn.Module): The destination bn module. + state_dict_tv (OrderedDict): The state dict of pretrained torchvision model. + module_name_tv (str): The name of corresponding bn module in the torchvision model. + loaded_param_names (list[str]): List of parameters that have been loaded. + """ + + for param_name, param in bn.named_parameters(): + param_tv_name = f'{module_name_tv}.{param_name}' + param_tv = state_dict_tv[param_tv_name] + if param.data.shape == param_tv.shape: + param.data.copy_(param_tv) + loaded_param_names.append(param_tv_name) + + for param_name, param in bn.named_buffers(): + param_tv_name = f'{module_name_tv}.{param_name}' + # some buffers like num_batches_tracked may not exist + if param_tv_name in state_dict_tv: + param_tv = state_dict_tv[param_tv_name] + if param.data.shape == param_tv.shape: + param.data.copy_(param_tv) + loaded_param_names.append(param_tv_name) + + def _load_torchvision_checkpoint(self, logger=None): + """Initiate the parameters from torchvision pretrained checkpoint.""" + state_dict_torchvision = _load_checkpoint(self.pretrained) + if 'state_dict' in state_dict_torchvision: + state_dict_torchvision = state_dict_torchvision['state_dict'] + + loaded_param_names = [] + for name, module in self.named_modules(): + if isinstance(module, ConvModule): + # we use a ConvModule to wrap conv+bn+relu layers, thus the name mapping is needed + if 'downsample' in name: + # layer{X}.{Y}.downsample.conv->layer{X}.{Y}.downsample.0 + original_conv_name = name + '.0' + # layer{X}.{Y}.downsample.bn->layer{X}.{Y}.downsample.1 + original_bn_name = name + '.1' + else: + # layer{X}.{Y}.conv{n}.conv->layer{X}.{Y}.conv{n} + original_conv_name = name + # layer{X}.{Y}.conv{n}.bn->layer{X}.{Y}.bn{n} + original_bn_name = name.replace('conv', 'bn') + self._load_conv_params(module.conv, state_dict_torchvision, original_conv_name, loaded_param_names) + self._load_bn_params(module.bn, state_dict_torchvision, original_bn_name, loaded_param_names) + + # check if any parameters in the 2d checkpoint are not loaded + remaining_names = set(state_dict_torchvision.keys()) - set(loaded_param_names) + if remaining_names: + logger.info(f'These parameters in pretrained checkpoint are not loaded: {remaining_names}') + + def init_weights(self): + """Initiate the parameters either from existing checkpoint or from + scratch.""" + for m in self.modules(): + if isinstance(m, nn.Conv2d): + kaiming_init(m) + elif isinstance(m, nn.BatchNorm2d): + constant_init(m, 1) + + if isinstance(self.pretrained, str): + logger = get_root_logger() + if self.torchvision_pretrain: + self._load_torchvision_checkpoint(logger) + else: + load_checkpoint(self, self.pretrained, strict=False, logger=logger) + + def forward(self, x): + """Defines the computation performed at every call. + + Args: + x (torch.Tensor): The input data. + + Returns: + torch.Tensor: The feature of the input samples extracted + by the backbone. + """ + x = self.conv1(x) + x = self.maxpool(x) + outs = [] + for i, layer_name in enumerate(self.res_layers): + res_layer = getattr(self, layer_name) + x = res_layer(x) + if i in self.out_indices: + outs.append(x) + if len(outs) == 1: + return outs[0] + + return tuple(outs) + + def _freeze_stages(self): + """Prevent all the parameters from being optimized before self.frozen_stages.""" + if self.frozen_stages >= 0: + self.conv1.bn.eval() + for m in self.conv1.modules(): + for param in m.parameters(): + param.requires_grad = False + + for i in range(1, self.frozen_stages + 1): + m = getattr(self, f'layer{i}') + m.eval() + for param in m.parameters(): + param.requires_grad = False + + def train(self, mode=True): + """Set the optimization status when training.""" + super().train(mode) + self._freeze_stages() + if mode and self.norm_eval: + for m in self.modules(): + if isinstance(m, _BatchNorm): + m.eval() diff --git a/pyskl/models/cnns/resnet3d.py b/pyskl/models/cnns/resnet3d.py new file mode 100644 index 00000000..4901f917 --- /dev/null +++ b/pyskl/models/cnns/resnet3d.py @@ -0,0 +1,625 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import warnings + +import torch.nn as nn +from mmcv.cnn import ConvModule, build_activation_layer, constant_init, kaiming_init +from mmcv.runner import _load_checkpoint, load_checkpoint +from mmcv.utils import _BatchNorm +from torch.nn.modules.utils import _ntuple, _triple + +from ...utils import get_root_logger +from ..builder import BACKBONES + + +class BasicBlock3d(nn.Module): + """BasicBlock 3d block for ResNet3D. + + Args: + inplanes (int): Number of channels for the input in first conv3d layer. + planes (int): Number of channels produced by some norm/conv3d layers. + stride (tuple): Stride is a two element tuple (temporal, spatial). Default: (1, 1). + downsample (nn.Module | None): Downsample layer. Default: None. + inflate (bool): Whether to inflate kernel. Default: True. + conv_cfg (dict): Config dict for convolution layer. Default: 'dict(type='Conv3d')'. + norm_cfg (dict): Config for norm layers. required keys are 'type'. Default: 'dict(type='BN3d')'. + act_cfg (dict): Config dict for activation layer. Default: 'dict(type='ReLU')'. + """ + expansion = 1 + + def __init__(self, + inplanes, + planes, + stride=(1, 1), + downsample=None, + inflate=True, + inflate_style='3x3x3', + conv_cfg=dict(type='Conv3d'), + norm_cfg=dict(type='BN3d'), + act_cfg=dict(type='ReLU')): + super().__init__() + assert inflate_style == '3x3x3' + + self.inplanes = inplanes + self.planes = planes + self.stride = stride + self.inflate = inflate + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + + self.conv1 = ConvModule( + inplanes, + planes, + 3 if self.inflate else (1, 3, 3), + stride=(self.stride[0], self.stride[1], self.stride[1]), + padding=1 if self.inflate else (0, 1, 1), + bias=False, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + self.conv2 = ConvModule( + planes, + planes * self.expansion, + 3 if self.inflate else (1, 3, 3), + stride=1, + padding=1 if self.inflate else (0, 1, 1), + bias=False, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=None) + + self.downsample = downsample + self.relu = build_activation_layer(self.act_cfg) + + def forward(self, x): + """Defines the computation performed at every call.""" + + def _inner_forward(x): + """Forward wrapper for utilizing checkpoint.""" + identity = x + + out = self.conv1(x) + out = self.conv2(out) + + if self.downsample is not None: + identity = self.downsample(x) + + out = out + identity + return out + + out = _inner_forward(x) + out = self.relu(out) + + return out + + +class Bottleneck3d(nn.Module): + """Bottleneck 3d block for ResNet3D. + + Args: + inplanes (int): Number of channels for the input in first conv3d layer. + planes (int): Number of channels produced by some norm/conv3d layers. + stride (tuple): Stride is a two element tuple (temporal, spatial). Default: (1, 1). + downsample (nn.Module | None): Downsample layer. Default: None. + inflate (bool): Whether to inflate kernel. Default: True. + inflate_style (str): '3x1x1' or '3x3x3'. which determines the kernel sizes and padding strides + for conv1 and conv2 in each block. Default: '3x1x1'. + conv_cfg (dict): Config dict for convolution layer. Default: 'dict(type='Conv3d')'. + norm_cfg (dict): Config for norm layers. required keys are 'type'. Default: 'dict(type='BN3d')'. + act_cfg (dict): Config dict for activation layer. Default: 'dict(type='ReLU')'. + """ + expansion = 4 + + def __init__(self, + inplanes, + planes, + stride=(1, 1), + downsample=None, + inflate=True, + inflate_style='3x1x1', + conv_cfg=dict(type='Conv3d'), + norm_cfg=dict(type='BN3d'), + act_cfg=dict(type='ReLU')): + super().__init__() + assert inflate_style in ['3x1x1', '3x3x3'] + + self.inplanes = inplanes + self.planes = planes + self.stride = stride + self.inflate = inflate + self.inflate_style = inflate_style + self.norm_cfg = norm_cfg + self.conv_cfg = conv_cfg + self.act_cfg = act_cfg + + mode = 'no_inflate' if not self.inflate else self.inflate_style + conv1_kernel_size = {'no_inflate': 1, '3x1x1': (3, 1, 1), '3x3x3': 1} + conv1_padding = {'no_inflate': 0, '3x1x1': (1, 0, 0), '3x3x3': 0} + conv2_kernel_size = {'no_inflate': (1, 3, 3), '3x1x1': (1, 3, 3), '3x3x3': 3} + conv2_padding = {'no_inflate': (0, 1, 1), '3x1x1': (0, 1, 1), '3x3x3': 1} + + self.conv1 = ConvModule( + inplanes, + planes, + conv1_kernel_size[mode], + stride=1, + padding=conv1_padding[mode], + bias=False, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + self.conv2 = ConvModule( + planes, + planes, + conv2_kernel_size[mode], + stride=(self.stride[0], self.stride[1], self.stride[1]), + padding=conv2_padding[mode], + bias=False, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + self.conv3 = ConvModule( + planes, + planes * self.expansion, + 1, + bias=False, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + # No activation in the third ConvModule for bottleneck + act_cfg=None) + + self.downsample = downsample + self.relu = build_activation_layer(self.act_cfg) + + def forward(self, x): + """Defines the computation performed at every call.""" + + def _inner_forward(x): + """Forward wrapper for utilizing checkpoint.""" + identity = x + + out = self.conv1(x) + out = self.conv2(out) + out = self.conv3(out) + + if self.downsample is not None: + identity = self.downsample(x) + + out = out + identity + return out + + out = _inner_forward(x) + out = self.relu(out) + + return out + + +@BACKBONES.register_module() +class ResNet3d(nn.Module): + """ResNet 3d backbone. + + Args: + depth (int): Depth of resnet, from {18, 34, 50, 101, 152}. Default: 50. + pretrained (str | None): Name of pretrained model. + stage_blocks (tuple | None): Set number of stages for each res layer. Default: None. + pretrained2d (bool): Whether to load pretrained 2D model. Default: True. + in_channels (int): Channel num of input features. Default: 3. + base_channels (int): Channel num of stem output features. Default: 64. + out_indices (tuple[int]): Indices of output feature. Default: (3, ). + num_stages (int): Resnet stages. Default: 4. + spatial_strides (tuple[int]): Spatial strides of residual blocks of each stage. Default: (1, 2, 2, 2). + temporal_strides (tuple[int]): Temporal strides of residual blocks of each stage. Default: (1, 1, 1, 1). + conv1_kernel (tuple[int]): Kernel size of the first conv layer. Default: (3, 7, 7). + conv1_stride (tuple[int]): Stride of the first conv layer. Default: (1, 2). + pool1_stride (tuple[int]): Stride of the first pooling layer. Default: (1, 2). + advanced (bool): Flag indicating if an advanced design for downsample is adopted. Default: False. + frozen_stages (int): Stages to be frozen (all param fixed). -1 means not freezing any parameters. Default: -1. + inflate (tuple[int]): Inflate Dims of each block. Default: (1, 1, 1, 1). + inflate_style (str): '3x1x1' or '3x3x3'. which determines the kernel sizes and padding strides + for conv1 and conv2 in each block. Default: '3x1x1'. + conv_cfg (dict): Config for conv layers. required keys are 'type'. Default: 'dict(type='Conv3d')'. + norm_cfg (dict): Config for norm layers. required keys are 'type' and 'requires_grad'. + Default: 'dict(type='BN3d', requires_grad=True)'. + act_cfg (dict): Config dict for activation layer. Default: 'dict(type='ReLU', inplace=True)'. + norm_eval (bool): Whether to set BN layers to eval mode, namely, freeze running stats (mean and var). + Default: False. + zero_init_residual (bool): Whether to use zero initialization for residual block. Default: True. + """ + + arch_settings = { + 18: (BasicBlock3d, (2, 2, 2, 2)), + 34: (BasicBlock3d, (3, 4, 6, 3)), + 50: (Bottleneck3d, (3, 4, 6, 3)), + 101: (Bottleneck3d, (3, 4, 23, 3)), + 152: (Bottleneck3d, (3, 8, 36, 3)) + } + + def __init__(self, + depth=50, + pretrained=None, + stage_blocks=None, + pretrained2d=True, + in_channels=3, + num_stages=4, + base_channels=64, + out_indices=(3, ), + spatial_strides=(1, 2, 2, 2), + temporal_strides=(1, 1, 1, 1), + conv1_kernel=(3, 7, 7), + conv1_stride=(1, 2), + pool1_stride=(1, 2), + advanced=False, + frozen_stages=-1, + inflate=(1, 1, 1, 1), + inflate_style='3x1x1', + conv_cfg=dict(type='Conv3d'), + norm_cfg=dict(type='BN3d', requires_grad=True), + act_cfg=dict(type='ReLU', inplace=True), + norm_eval=False, + zero_init_residual=True): + super().__init__() + if depth not in self.arch_settings: + raise KeyError(f'invalid depth {depth} for resnet') + self.depth = depth + self.pretrained = pretrained + self.pretrained2d = pretrained2d + self.in_channels = in_channels + self.base_channels = base_channels + self.num_stages = num_stages + assert 1 <= num_stages <= 4 + self.stage_blocks = stage_blocks + self.out_indices = out_indices + assert max(out_indices) < num_stages + self.spatial_strides = spatial_strides + self.temporal_strides = temporal_strides + assert len(spatial_strides) == len(temporal_strides) == num_stages + if self.stage_blocks is not None: + assert len(self.stage_blocks) == num_stages + + self.conv1_kernel = conv1_kernel + self.conv1_stride = conv1_stride + self.pool1_stride = pool1_stride + self.advanced = advanced + self.frozen_stages = frozen_stages + self.stage_inflations = _ntuple(num_stages)(inflate) + self.inflate_style = inflate_style + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + self.norm_eval = norm_eval + self.zero_init_residual = zero_init_residual + + self.block, stage_blocks = self.arch_settings[depth] + + if self.stage_blocks is None: + self.stage_blocks = stage_blocks[:num_stages] + + self.inplanes = self.base_channels + + self._make_stem_layer() + + self.res_layers = [] + for i, num_blocks in enumerate(self.stage_blocks): + spatial_stride = spatial_strides[i] + temporal_stride = temporal_strides[i] + planes = self.base_channels * 2**i + res_layer = self.make_res_layer( + self.block, + self.inplanes, + planes, + num_blocks, + stride=(temporal_stride, spatial_stride), + norm_cfg=self.norm_cfg, + conv_cfg=self.conv_cfg, + act_cfg=self.act_cfg, + advanced=self.advanced, + inflate=self.stage_inflations[i], + inflate_style=self.inflate_style) + self.inplanes = planes * self.block.expansion + layer_name = f'layer{i + 1}' + self.add_module(layer_name, res_layer) + self.res_layers.append(layer_name) + + self.feat_dim = self.block.expansion * self.base_channels * 2 ** (len(self.stage_blocks) - 1) + + @staticmethod + def make_res_layer(block, + inplanes, + planes, + blocks, + stride=(1, 1), + inflate=1, + inflate_style='3x1x1', + advanced=False, + norm_cfg=None, + act_cfg=None, + conv_cfg=None): + """Build residual layer for ResNet3D. + + Args: + block (nn.Module): Residual module to be built. + inplanes (int): Number of channels for the input feature in each block. + planes (int): Number of channels for the output feature in each block. + blocks (int): Number of residual blocks. + stride (tuple[int]): Stride (temporal, spatial) in residual and conv layers. Default: (1, 1). + inflate (int | tuple[int]): Determine whether to inflate for each block. Default: 1. + inflate_style (str): '3x1x1' or '3x3x3'. which determines the kernel sizes and padding strides + for conv1 and conv2 in each block. Default: '3x1x1'. + conv_cfg (dict | None): Config for norm layers. Default: None. + norm_cfg (dict | None): Config for norm layers. Default: None. + act_cfg (dict | None): Config for activate layers. Default: None. + + Returns: + nn.Module: A residual layer for the given config. + """ + inflate = inflate if not isinstance(inflate, int) else (inflate, ) * blocks + assert len(inflate) == blocks + downsample = None + if stride[1] != 1 or inplanes != planes * block.expansion: + if advanced: + conv = ConvModule( + inplanes, + planes * block.expansion, + kernel_size=1, + stride=1, + bias=False, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=None) + pool = nn.AvgPool3d( + kernel_size=(stride[0], stride[1], stride[1]), + stride=(stride[0], stride[1], stride[1]), + ceil_mode=True) + downsample = nn.Sequential(conv, pool) + else: + downsample = ConvModule( + inplanes, + planes * block.expansion, + kernel_size=1, + stride=(stride[0], stride[1], stride[1]), + bias=False, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=None) + + layers = [] + layers.append( + block( + inplanes, + planes, + stride=stride, + downsample=downsample, + inflate=(inflate[0] == 1), + inflate_style=inflate_style, + norm_cfg=norm_cfg, + conv_cfg=conv_cfg, + act_cfg=act_cfg)) + inplanes = planes * block.expansion + for i in range(1, blocks): + layers.append( + block( + inplanes, + planes, + stride=(1, 1), + inflate=(inflate[i] == 1), + inflate_style=inflate_style, + norm_cfg=norm_cfg, + conv_cfg=conv_cfg, + act_cfg=act_cfg)) + + return nn.Sequential(*layers) + + @staticmethod + def _inflate_conv_params(conv3d, state_dict_2d, module_name_2d, inflated_param_names): + """Inflate a conv module from 2d to 3d. + + Args: + conv3d (nn.Module): The destination conv3d module. + state_dict_2d (OrderedDict): The state dict of pretrained 2d model. + module_name_2d (str): The name of corresponding conv module in the 2d model. + inflated_param_names (list[str]): List of parameters that have been inflated. + """ + weight_2d_name = module_name_2d + '.weight' + + conv2d_weight = state_dict_2d[weight_2d_name] + kernel_t = conv3d.weight.data.shape[2] + + new_weight = conv2d_weight.data.unsqueeze(2).expand_as(conv3d.weight) / kernel_t + conv3d.weight.data.copy_(new_weight) + inflated_param_names.append(weight_2d_name) + + if getattr(conv3d, 'bias') is not None: + bias_2d_name = module_name_2d + '.bias' + conv3d.bias.data.copy_(state_dict_2d[bias_2d_name]) + inflated_param_names.append(bias_2d_name) + + @staticmethod + def _inflate_bn_params(bn3d, state_dict_2d, module_name_2d, + inflated_param_names): + """Inflate a norm module from 2d to 3d. + + Args: + bn3d (nn.Module): The destination bn3d module. + state_dict_2d (OrderedDict): The state dict of pretrained 2d model. + module_name_2d (str): The name of corresponding bn module in the 2d model. + inflated_param_names (list[str]): List of parameters that have been inflated. + """ + for param_name, param in bn3d.named_parameters(): + param_2d_name = f'{module_name_2d}.{param_name}' + param_2d = state_dict_2d[param_2d_name] + if param.data.shape != param_2d.shape: + warnings.warn(f'The parameter of {module_name_2d} is not loaded due to incompatible shapes. ') + return + + param.data.copy_(param_2d) + inflated_param_names.append(param_2d_name) + + for param_name, param in bn3d.named_buffers(): + param_2d_name = f'{module_name_2d}.{param_name}' + # some buffers like num_batches_tracked may not exist in old checkpoints + if param_2d_name in state_dict_2d: + param_2d = state_dict_2d[param_2d_name] + param.data.copy_(param_2d) + inflated_param_names.append(param_2d_name) + + @staticmethod + def _inflate_weights(self, logger): + """Inflate the resnet2d parameters to resnet3d. + + The differences between resnet3d and resnet2d mainly lie in an extra + axis of conv kernel. To utilize the pretrained parameters in 2d model, + the weight of conv2d models should be inflated to fit in the shapes of + the 3d counterpart. + + Args: + logger (logging.Logger): The logger used to print + debugging information. + """ + + state_dict_r2d = _load_checkpoint(self.pretrained) + if 'state_dict' in state_dict_r2d: + state_dict_r2d = state_dict_r2d['state_dict'] + + inflated_param_names = [] + for name, module in self.named_modules(): + if isinstance(module, ConvModule): + # we use a ConvModule to wrap conv+bn+relu layers, thus the name mapping is needed + if 'downsample' in name: + # layer{X}.{Y}.downsample.conv->layer{X}.{Y}.downsample.0 + original_conv_name = name + '.0' + # layer{X}.{Y}.downsample.bn->layer{X}.{Y}.downsample.1 + original_bn_name = name + '.1' + else: + # layer{X}.{Y}.conv{n}.conv->layer{X}.{Y}.conv{n} + original_conv_name = name + # layer{X}.{Y}.conv{n}.bn->layer{X}.{Y}.bn{n} + original_bn_name = name.replace('conv', 'bn') + if original_conv_name + '.weight' not in state_dict_r2d: + logger.warning(f'Module not exist in the state_dict_r2d: {original_conv_name}') + else: + shape_2d = state_dict_r2d[original_conv_name + '.weight'].shape + shape_3d = module.conv.weight.data.shape + if shape_2d != shape_3d[:2] + shape_3d[3:]: + logger.warning(f'Weight shape mismatch for: {original_conv_name}: ' + f'3d weight shape: {shape_3d}; 2d weight shape: {shape_2d}.') + else: + self._inflate_conv_params( + module.conv, state_dict_r2d, original_conv_name, inflated_param_names + ) + + if original_bn_name + '.weight' not in state_dict_r2d: + logger.warning(f'Module not exist in the state_dict_r2d: {original_bn_name}') + else: + self._inflate_bn_params(module.bn, state_dict_r2d, original_bn_name, inflated_param_names) + + # check if any parameters in the 2d checkpoint are not loaded + remaining_names = set(state_dict_r2d.keys()) - set(inflated_param_names) + if remaining_names: + logger.info(f'These parameters in the 2d checkpoint are not loaded: {remaining_names}') + + def inflate_weights(self, logger): + self._inflate_weights(self, logger) + + def _make_stem_layer(self): + """Construct the stem layers consists of a conv+norm+act module and a + pooling layer.""" + self.conv1 = ConvModule( + self.in_channels, + self.base_channels, + kernel_size=self.conv1_kernel, + stride=(self.conv1_stride[0], self.conv1_stride[1], self.conv1_stride[1]), + padding=tuple([(k - 1) // 2 for k in _triple(self.conv1_kernel)]), + bias=False, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + self.maxpool = nn.MaxPool3d( + kernel_size=(1, 3, 3), + stride=(self.pool1_stride[0], self.pool1_stride[1], self.pool1_stride[1]), + padding=(0, 1, 1)) + + def _freeze_stages(self): + """Prevent all the parameters from being optimized before + 'self.frozen_stages'.""" + if self.frozen_stages >= 0: + self.conv1.eval() + for param in self.conv1.parameters(): + param.requires_grad = False + + for i in range(1, self.frozen_stages + 1): + m = getattr(self, f'layer{i}') + m.eval() + for param in m.parameters(): + param.requires_grad = False + + @staticmethod + def _init_weights(self, pretrained=None): + """Initiate the parameters either from existing checkpoint or from + scratch. + + Args: + pretrained (str | None): The path of the pretrained weight. Will override the original 'pretrained' if set. + The arg is added to be compatible with mmdet. Default: None. + """ + for m in self.modules(): + if isinstance(m, nn.Conv3d): + kaiming_init(m) + elif isinstance(m, _BatchNorm): + constant_init(m, 1) + + if self.zero_init_residual: + for m in self.modules(): + if isinstance(m, Bottleneck3d): + constant_init(m.conv3.bn, 0) + elif isinstance(m, BasicBlock3d): + constant_init(m.conv2.bn, 0) + + if pretrained: + self.pretrained = pretrained + if isinstance(self.pretrained, str): + logger = get_root_logger() + logger.info(f'load model from: {self.pretrained}') + + if self.pretrained2d: + self.inflate_weights(logger) + else: + load_checkpoint(self, self.pretrained, strict=False, logger=logger) + + def init_weights(self, pretrained=None): + self._init_weights(self, pretrained) + + def forward(self, x): + """Defines the computation performed at every call. + + Args: + x (torch.Tensor): The input data. + + Returns: + torch.Tensor: The feature of the input + samples extracted by the backbone. + """ + x = self.conv1(x) + x = self.maxpool(x) + outs = [] + for i, layer_name in enumerate(self.res_layers): + res_layer = getattr(self, layer_name) + x = res_layer(x) + if i in self.out_indices: + outs.append(x) + if len(outs) == 1: + return outs[0] + + return tuple(outs) + + def train(self, mode=True): + """Set the optimization status when training.""" + super().train(mode) + self._freeze_stages() + if mode and self.norm_eval: + for m in self.modules(): + if isinstance(m, _BatchNorm): + m.eval() diff --git a/pyskl/models/cnns/resnet3d_slowfast.py b/pyskl/models/cnns/resnet3d_slowfast.py new file mode 100644 index 00000000..04f6b717 --- /dev/null +++ b/pyskl/models/cnns/resnet3d_slowfast.py @@ -0,0 +1,327 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import warnings + +import torch +import torch.nn as nn +from mmcv.cnn import ConvModule, kaiming_init +from mmcv.runner import _load_checkpoint, load_checkpoint +from mmcv.utils import print_log + +from ...utils import get_root_logger +from ..builder import BACKBONES +from .resnet3d import ResNet3d + + +class ResNet3dPathway(ResNet3d): + """A pathway of Slowfast based on ResNet3d. + + Args: + lateral (bool): Determines whether to enable the lateral connection from another pathway. Default: False. + speed_ratio (int): Speed ratio indicating the ratio between time dimension of the fast and slow pathway, + corresponding to the 'alpha' in the paper. Default: 8. + channel_ratio (int): Reduce the channel number of fast pathway by 'channel_ratio', + corresponding to 'beta' in the paper. Default: 8. + fusion_kernel (int): The kernel size of lateral fusion. Default: 7. + **kwargs (keyword arguments): Keywords arguments for ResNet3d. + """ + + def __init__(self, + lateral=False, + speed_ratio=8, + channel_ratio=8, + fusion_kernel=7, + **kwargs): + self.lateral = lateral + self.speed_ratio = speed_ratio + self.channel_ratio = channel_ratio + self.fusion_kernel = fusion_kernel + super().__init__(**kwargs) + self.inplanes = self.base_channels + if self.lateral: + self.conv1_lateral = ConvModule( + self.inplanes // self.channel_ratio, + self.inplanes * 2 // self.channel_ratio, + kernel_size=(fusion_kernel, 1, 1), + stride=(self.speed_ratio, 1, 1), + padding=((fusion_kernel - 1) // 2, 0, 0), + bias=False, + conv_cfg=self.conv_cfg, + norm_cfg=None, + act_cfg=None) + + self.lateral_connections = [] + for i in range(len(self.stage_blocks)): + planes = self.base_channels * 2**i + self.inplanes = planes * self.block.expansion + + if lateral and i != self.num_stages - 1: + # no lateral connection needed in final stage + lateral_name = f'layer{(i + 1)}_lateral' + setattr( + self, lateral_name, + ConvModule( + self.inplanes // self.channel_ratio, + self.inplanes * 2 // self.channel_ratio, + kernel_size=(fusion_kernel, 1, 1), + stride=(self.speed_ratio, 1, 1), + padding=((fusion_kernel - 1) // 2, 0, 0), + bias=False, + conv_cfg=self.conv_cfg, + norm_cfg=None, + act_cfg=None)) + self.lateral_connections.append(lateral_name) + + def make_res_layer(self, + block, + inplanes, + planes, + blocks, + **kwargs): + """ + Build residual layer for Slowfast. Basically, it's the same as ResNet3d make_res_layer. + However, the inplanes used will be: self.lateral * inplanes * (2 // self.channel_ratio) + inplanes. + + Args: + block (nn.Module): Residual module to be built. + inplanes (int): Number of channels for the input feature in each block. + planes (int): Number of channels for the output feature in each block. + blocks (int): Number of residual blocks. + + Returns: + nn.Module: A residual layer for the given config. + """ + lateral_inplanes = inplanes * 2 // self.channel_ratio if self.lateral else 0 + return super().make_res_layer(block, inplanes + lateral_inplanes, planes, blocks) + + def inflate_weights(self, logger): + """Inflate the resnet2d parameters to resnet3d pathway. + + The differences between resnet3d and resnet2d mainly lie in an extra + axis of conv kernel. To utilize the pretrained parameters in 2d model, + the weight of conv2d models should be inflated to fit in the shapes of + the 3d counterpart. For pathway the 'lateral_connection' part should + not be inflated from 2d weights. + + Args: + logger (logging.Logger): The logger used to print debugging information. + """ + + state_dict_r2d = _load_checkpoint(self.pretrained) + if 'state_dict' in state_dict_r2d: + state_dict_r2d = state_dict_r2d['state_dict'] + + inflated_param_names = [] + for name, module in self.named_modules(): + if 'lateral' in name: + continue + if isinstance(module, ConvModule): + # we use a ConvModule to wrap conv+bn+relu layers, thus the name mapping is needed + if 'downsample' in name: + # layer{X}.{Y}.downsample.conv->layer{X}.{Y}.downsample.0 + original_conv_name = name + '.0' + # layer{X}.{Y}.downsample.bn->layer{X}.{Y}.downsample.1 + original_bn_name = name + '.1' + else: + # layer{X}.{Y}.conv{n}.conv->layer{X}.{Y}.conv{n} + original_conv_name = name + # layer{X}.{Y}.conv{n}.bn->layer{X}.{Y}.bn{n} + original_bn_name = name.replace('conv', 'bn') + if original_conv_name + '.weight' not in state_dict_r2d: + logger.warning(f'Module not exist in the state_dict_r2d: {original_conv_name}') + else: + self._inflate_conv_params(module.conv, state_dict_r2d, original_conv_name, inflated_param_names) + if original_bn_name + '.weight' not in state_dict_r2d: + logger.warning(f'Module not exist in the state_dict_r2d: {original_bn_name}') + else: + self._inflate_bn_params(module.bn, state_dict_r2d, original_bn_name, inflated_param_names) + + # check if any parameters in the 2d checkpoint are not loaded + remaining_names = set(state_dict_r2d.keys()) - set(inflated_param_names) + if remaining_names: + logger.info(f'These parameters in the 2d checkpoint are not loaded: {remaining_names}') + + def _inflate_conv_params(self, conv3d, state_dict_2d, module_name_2d, inflated_param_names): + """Inflate a conv module from 2d to 3d. + + The differences of conv modules betweene 2d and 3d in Pathway + mainly lie in the inplanes due to lateral connections. To fit the + shapes of the lateral connection counterpart, it will expand + parameters by concatting conv2d parameters and extra zero paddings. + + Args: + conv3d (nn.Module): The destination conv3d module. + state_dict_2d (OrderedDict): The state dict of pretrained 2d model. + module_name_2d (str): The name of corresponding conv module in the 2d model. + inflated_param_names (list[str]): List of parameters that have been inflated. + """ + weight_2d_name = module_name_2d + '.weight' + conv2d_weight = state_dict_2d[weight_2d_name] + old_shape = conv2d_weight.shape + new_shape = conv3d.weight.data.shape + kernel_t = new_shape[2] + + if new_shape[1] != old_shape[1]: + if new_shape[1] < old_shape[1]: + warnings.warn(f'The parameter of {module_name_2d} is not' + 'loaded due to incompatible shapes. ') + return + # Inplanes may be different due to lateral connections + new_channels = new_shape[1] - old_shape[1] + pad_shape = old_shape + pad_shape = pad_shape[:1] + (new_channels, ) + pad_shape[2:] + # Expand parameters by concat extra channels + conv2d_weight = torch.cat( + (conv2d_weight, torch.zeros(pad_shape).type_as(conv2d_weight).to(conv2d_weight.device)), dim=1) + + new_weight = conv2d_weight.data.unsqueeze(2).expand_as(conv3d.weight) / kernel_t + conv3d.weight.data.copy_(new_weight) + inflated_param_names.append(weight_2d_name) + + if getattr(conv3d, 'bias') is not None: + bias_2d_name = module_name_2d + '.bias' + conv3d.bias.data.copy_(state_dict_2d[bias_2d_name]) + inflated_param_names.append(bias_2d_name) + + def _freeze_stages(self): + """Prevent all the parameters from being optimized before'self.frozen_stages'. """ + if self.frozen_stages >= 0: + self.conv1.eval() + for param in self.conv1.parameters(): + param.requires_grad = False + + for i in range(1, self.frozen_stages + 1): + m = getattr(self, f'layer{i}') + m.eval() + for param in m.parameters(): + param.requires_grad = False + + if i != len(self.res_layers) and self.lateral: + # No fusion needed in the final stage + lateral_name = self.lateral_connections[i - 1] + conv_lateral = getattr(self, lateral_name) + conv_lateral.eval() + for param in conv_lateral.parameters(): + param.requires_grad = False + + def init_weights(self, pretrained=None): + """Initiate the parameters either from existing checkpoint or from + scratch.""" + if pretrained: + self.pretrained = pretrained + + super().init_weights() + for module_name in self.lateral_connections: + layer = getattr(self, module_name) + for m in layer.modules(): + if isinstance(m, (nn.Conv3d, nn.Conv2d)): + kaiming_init(m) + + +@BACKBONES.register_module() +class ResNet3dSlowFast(nn.Module): + """Slowfast backbone. + + This module is proposed in `SlowFast Networks for Video Recognition + `_ + + Args: + pretrained (str): The file path to a pretrained model. + resample_rate (int): A large temporal stride 'resample_rate' on input frames. The actual resample rate is + calculated by multipling the 'interval' in 'SampleFrames' in the pipeline with 'resample_rate', equivalent + to the :math:`\\tau` in the paper, i.e. it processes only one out of 'resample_rate * interval' frames. + Default: 8. + speed_ratio (int): Speed ratio indicating the ratio between time dimension of the fast and slow pathway, + corresponding to the :math:`\\alpha` in the paper. Default: 8. + channel_ratio (int): Reduce the channel number of fast pathway by 'channel_ratio', corresponding to + :math:`\\beta` in the paper. Default: 8. + slow_pathway (dict): Configuration of slow branch. + Default: dict(lateral=True, depth=50, conv1_kernel=(1, 7, 7), inflate=(0, 0, 1, 1)) + fast_pathway (dict): Configuration of fast branch. + Default: dict(lateral=False, depth=50, base_channels=8, conv1_kernel=(5, 7, 7)) + """ + + def __init__(self, + pretrained=None, + resample_rate=8, + speed_ratio=8, + channel_ratio=8, + slow_pathway=dict( + depth=50, + lateral=True, + conv1_kernel=(1, 7, 7), + inflate=(0, 0, 1, 1)), + fast_pathway=dict( + depth=50, + lateral=False, + base_channels=8, + conv1_kernel=(5, 7, 7))): + super().__init__() + self.pretrained = pretrained + self.resample_rate = resample_rate + self.speed_ratio = speed_ratio + self.channel_ratio = channel_ratio + + if slow_pathway['lateral']: + slow_pathway['speed_ratio'] = speed_ratio + slow_pathway['channel_ratio'] = channel_ratio + + self.slow_path = ResNet3dPathway(**slow_pathway) + self.fast_path = ResNet3dPathway(**fast_pathway) + + def init_weights(self, pretrained=None): + """Initiate the parameters either from existing checkpoint or from + scratch.""" + if pretrained: + self.pretrained = pretrained + + if isinstance(self.pretrained, str): + logger = get_root_logger() + msg = f'load model from: {self.pretrained}' + print_log(msg, logger=logger) + # Directly load 3D model. + load_checkpoint(self, self.pretrained, strict=True, logger=logger) + elif self.pretrained is None: + # Init two branch separately. + self.fast_path.init_weights() + self.slow_path.init_weights() + else: + raise TypeError('pretrained must be a str or None') + + def forward(self, x): + """Defines the computation performed at every call. + + Args: + x (torch.Tensor): The input data. + + Returns: + tuple[torch.Tensor]: The feature of the input samples extracted by the backbone. + """ + x_slow = nn.functional.interpolate( + x, mode='nearest', scale_factor=(1.0 / self.resample_rate, 1.0, 1.0)) + x_slow = self.slow_path.conv1(x_slow) + x_slow = self.slow_path.maxpool(x_slow) + + x_fast = nn.functional.interpolate( + x, mode='nearest', scale_factor=(1.0 / (self.resample_rate // self.speed_ratio), 1.0, 1.0)) + x_fast = self.fast_path.conv1(x_fast) + x_fast = self.fast_path.maxpool(x_fast) + + if self.slow_path.lateral: + x_fast_lateral = self.slow_path.conv1_lateral(x_fast) + x_slow = torch.cat((x_slow, x_fast_lateral), dim=1) + + for i, layer_name in enumerate(self.slow_path.res_layers): + res_layer = getattr(self.slow_path, layer_name) + x_slow = res_layer(x_slow) + res_layer_fast = getattr(self.fast_path, layer_name) + x_fast = res_layer_fast(x_fast) + if (i != len(self.slow_path.res_layers) - 1 and self.slow_path.lateral): + # No fusion needed in the final stage + lateral_name = self.slow_path.lateral_connections[i] + conv_lateral = getattr(self.slow_path, lateral_name) + x_fast_lateral = conv_lateral(x_fast) + x_slow = torch.cat((x_slow, x_fast_lateral), dim=1) + + out = (x_slow, x_fast) + + return out diff --git a/pyskl/models/cnns/resnet3d_slowonly.py b/pyskl/models/cnns/resnet3d_slowonly.py new file mode 100644 index 00000000..dc86d7c3 --- /dev/null +++ b/pyskl/models/cnns/resnet3d_slowonly.py @@ -0,0 +1,17 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from ..builder import BACKBONES +from .resnet3d import ResNet3d + + +@BACKBONES.register_module() +class ResNet3dSlowOnly(ResNet3d): + """SlowOnly backbone based on ResNet3d. + + Args: + conv1_kernel (tuple[int]): Kernel size of the first conv layer. Default: (1, 7, 7). + inflate (tuple[int]): Inflate Dims of each block. Default: (0, 0, 1, 1). + **kwargs (keyword arguments): Other keywords arguments for 'ResNet3d'. + """ + + def __init__(self, conv1_kernel=(1, 7, 7), inflate=(0, 0, 1, 1), **kwargs): + super().__init__(conv1_kernel=conv1_kernel, inflate=inflate, **kwargs) diff --git a/pyskl/models/cnns/x3d.py b/pyskl/models/cnns/x3d.py new file mode 100644 index 00000000..6ee33cf4 --- /dev/null +++ b/pyskl/models/cnns/x3d.py @@ -0,0 +1,503 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import math + +import torch.nn as nn +from mmcv.cnn import ConvModule, Swish, build_activation_layer, constant_init, kaiming_init +from mmcv.runner import load_checkpoint +from mmcv.utils import _BatchNorm + +from ...utils import get_root_logger +from ..builder import BACKBONES + + +class SEModule(nn.Module): + + def __init__(self, channels, reduction): + super().__init__() + self.avg_pool = nn.AdaptiveAvgPool3d(1) + self.bottleneck = self._round_width(channels, reduction) + self.fc1 = nn.Conv3d( + channels, self.bottleneck, kernel_size=1, padding=0) + self.relu = nn.ReLU() + self.fc2 = nn.Conv3d( + self.bottleneck, channels, kernel_size=1, padding=0) + self.sigmoid = nn.Sigmoid() + + @staticmethod + def _round_width(width, multiplier, min_width=8, divisor=8): + width *= multiplier + min_width = min_width or divisor + width_out = max(min_width, + int(width + divisor / 2) // divisor * divisor) + if width_out < 0.9 * width: + width_out += divisor + return int(width_out) + + def forward(self, x): + module_input = x + x = self.avg_pool(x) + x = self.fc1(x) + x = self.relu(x) + x = self.fc2(x) + x = self.sigmoid(x) + return module_input * x + + +class BlockX3D(nn.Module): + """BlockX3D 3d building block for X3D. + + Args: + inplanes (int): Number of channels for the input in first conv3d layer. + planes (int): Number of channels produced by some norm/conv3d layers. + outplanes (int): Number of channels produced by final the conv3d layer. + spatial_stride (int): Spatial stride in the conv3d layer. Default: 1. + downsample (nn.Module | None): Downsample layer. Default: None. + se_ratio (float | None): The reduction ratio of squeeze and excitation + unit. If set as None, it means not using SE unit. Default: None. + use_swish (bool): Whether to use swish as the activation function + before and after the 3x3x3 conv. Default: True. + conv_cfg (dict): Config dict for convolution layer. + Default: ``dict(type='Conv3d')``. + norm_cfg (dict): Config for norm layers. required keys are ``type``, + Default: ``dict(type='BN3d')``. + act_cfg (dict): Config dict for activation layer. + Default: ``dict(type='ReLU')``. + """ + + def __init__(self, + inplanes, + planes, + outplanes, + spatial_stride=1, + downsample=None, + se_ratio=None, + use_swish=True, + conv_cfg=dict(type='Conv3d'), + norm_cfg=dict(type='BN3d'), + act_cfg=dict(type='ReLU')): + super().__init__() + + self.inplanes = inplanes + self.planes = planes + self.outplanes = outplanes + self.spatial_stride = spatial_stride + self.downsample = downsample + self.se_ratio = se_ratio + self.use_swish = use_swish + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + self.act_cfg_swish = dict(type='Swish') + + self.conv1 = ConvModule( + in_channels=inplanes, + out_channels=planes, + kernel_size=1, + stride=1, + padding=0, + bias=False, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + # Here we use the channel-wise conv + self.conv2 = ConvModule( + in_channels=planes, + out_channels=planes, + kernel_size=3, + stride=(1, self.spatial_stride, self.spatial_stride), + padding=1, + groups=planes, + bias=False, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=None) + + self.swish = Swish() if self.use_swish else nn.Identity() + + self.conv3 = ConvModule( + in_channels=planes, + out_channels=outplanes, + kernel_size=1, + stride=1, + padding=0, + bias=False, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=None) + + if self.se_ratio is not None: + self.se_module = SEModule(planes, self.se_ratio) + + self.relu = build_activation_layer(self.act_cfg) + + def forward(self, x): + """Defines the computation performed at every call.""" + + def _inner_forward(x): + """Forward wrapper for utilizing checkpoint.""" + identity = x + + out = self.conv1(x) + out = self.conv2(out) + if self.se_ratio is not None: + out = self.se_module(out) + + out = self.swish(out) + + out = self.conv3(out) + + if self.downsample is not None: + identity = self.downsample(x) + + out = out + identity + return out + + out = _inner_forward(x) + out = self.relu(out) + return out + + +# We do not support initialize with 2D pretrain weight for X3D +@BACKBONES.register_module() +class X3D(nn.Module): + """X3D backbone. https://arxiv.org/pdf/2004.04730.pdf. + + Args: + gamma_w (float): Global channel width expansion factor. Default: 1. + gamma_b (float): Bottleneck channel width expansion factor. Default: 1. + gamma_d (float): Network depth expansion factor. Default: 1. + pretrained (str | None): Name of pretrained model. Default: None. + in_channels (int): Channel num of input features. Default: 3. + num_stages (int): Resnet stages. Default: 4. + spatial_strides (Sequence[int]): + Spatial strides of residual blocks of each stage. + Default: ``(1, 2, 2, 2)``. + frozen_stages (int): Stages to be frozen (all param fixed). If set to + -1, it means not freezing any parameters. Default: -1. + se_style (str): The style of inserting SE modules into BlockX3D, 'half' + denotes insert into half of the blocks, while 'all' denotes insert + into all blocks. Default: 'half'. + se_ratio (float | None): The reduction ratio of squeeze and excitation + unit. If set as None, it means not using SE unit. Default: 1 / 16. + use_swish (bool): Whether to use swish as the activation function + before and after the 3x3x3 conv. Default: True. + conv_cfg (dict): Config for conv layers. required keys are ``type`` + Default: ``dict(type='Conv3d')``. + norm_cfg (dict): Config for norm layers. required keys are ``type`` and + ``requires_grad``. + Default: ``dict(type='BN3d', requires_grad=True)``. + act_cfg (dict): Config dict for activation layer. + Default: ``dict(type='ReLU', inplace=True)``. + norm_eval (bool): Whether to set BN layers to eval mode, namely, freeze + running stats (mean and var). Default: False. + zero_init_residual (bool): + Whether to use zero initialization for residual block, + Default: True. + kwargs (dict, optional): Key arguments for "make_res_layer". + """ + + def __init__(self, + gamma_w=1.0, + gamma_b=2.25, + gamma_d=2.2, + pretrained=None, + in_channels=3, + base_channels=24, + num_stages=4, + stage_blocks=(1, 2, 5, 3), + spatial_strides=(2, 2, 2, 2), + frozen_stages=-1, + se_style='half', + se_ratio=1 / 16, + use_swish=True, + conv_cfg=dict(type='Conv3d'), + norm_cfg=dict(type='BN3d', requires_grad=True), + act_cfg=dict(type='ReLU', inplace=True), + norm_eval=False, + zero_init_residual=True, + **kwargs): + super().__init__() + self.gamma_w = gamma_w + self.gamma_b = gamma_b + self.gamma_d = gamma_d + + self.pretrained = pretrained + self.in_channels = in_channels + # Hard coded, can be changed by gamma_w + self.base_channels = base_channels + self.stage_blocks = stage_blocks + + # apply parameters gamma_w and gamma_d + self.base_channels = self._round_width(self.base_channels, + self.gamma_w) + + self.stage_blocks = [ + self._round_repeats(x, self.gamma_d) for x in self.stage_blocks + ] + + self.num_stages = num_stages + assert 1 <= num_stages <= 4 + self.spatial_strides = spatial_strides + assert len(spatial_strides) == num_stages + self.frozen_stages = frozen_stages + + self.se_style = se_style + assert self.se_style in ['all', 'half'] + self.se_ratio = se_ratio + assert (self.se_ratio is None) or (self.se_ratio > 0) + self.use_swish = use_swish + + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + self.norm_eval = norm_eval + self.zero_init_residual = zero_init_residual + + self.block = BlockX3D + self.stage_blocks = self.stage_blocks[:num_stages] + self.layer_inplanes = self.base_channels + self._make_stem_layer() + + self.res_layers = [] + for i, num_blocks in enumerate(self.stage_blocks): + spatial_stride = spatial_strides[i] + inplanes = self.base_channels * 2**i + planes = int(inplanes * self.gamma_b) + + res_layer = self.make_res_layer( + self.block, + self.layer_inplanes, + inplanes, + planes, + num_blocks, + spatial_stride=spatial_stride, + se_style=self.se_style, + se_ratio=self.se_ratio, + use_swish=self.use_swish, + norm_cfg=self.norm_cfg, + conv_cfg=self.conv_cfg, + act_cfg=self.act_cfg, + **kwargs) + self.layer_inplanes = inplanes + layer_name = f'layer{i + 1}' + self.add_module(layer_name, res_layer) + self.res_layers.append(layer_name) + + self.feat_dim = self.base_channels * 2**(len(self.stage_blocks) - 1) + self.conv5 = ConvModule( + self.feat_dim, + int(self.feat_dim * self.gamma_b), + kernel_size=1, + stride=1, + padding=0, + bias=False, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + self.feat_dim = int(self.feat_dim * self.gamma_b) + + @staticmethod + def _round_width(width, multiplier, min_depth=8, divisor=8): + """Round width of filters based on width multiplier.""" + if not multiplier: + return width + + width *= multiplier + min_depth = min_depth or divisor + new_filters = max(min_depth, + int(width + divisor / 2) // divisor * divisor) + if new_filters < 0.9 * width: + new_filters += divisor + return int(new_filters) + + @staticmethod + def _round_repeats(repeats, multiplier): + """Round number of layers based on depth multiplier.""" + if not multiplier: + return repeats + return int(math.ceil(multiplier * repeats)) + + # the module is parameterized with gamma_b + # no temporal_stride + def make_res_layer(self, + block, + layer_inplanes, + inplanes, + planes, + blocks, + spatial_stride=1, + se_style='half', + se_ratio=None, + use_swish=True, + norm_cfg=None, + act_cfg=None, + conv_cfg=None, + **kwargs): + """Build residual layer for ResNet3D. + + Args: + block (nn.Module): Residual module to be built. + layer_inplanes (int): Number of channels for the input feature + of the res layer. + inplanes (int): Number of channels for the input feature in each + block, which equals to base_channels * gamma_w. + planes (int): Number of channels for the output feature in each + block, which equals to base_channel * gamma_w * gamma_b. + blocks (int): Number of residual blocks. + spatial_stride (int): Spatial strides in residual and conv layers. + Default: 1. + se_style (str): The style of inserting SE modules into BlockX3D, + 'half' denotes insert into half of the blocks, while 'all' + denotes insert into all blocks. Default: 'half'. + se_ratio (float | None): The reduction ratio of squeeze and + excitation unit. If set as None, it means not using SE unit. + Default: None. + use_swish (bool): Whether to use swish as the activation function + before and after the 3x3x3 conv. Default: True. + conv_cfg (dict | None): Config for norm layers. Default: None. + norm_cfg (dict | None): Config for norm layers. Default: None. + act_cfg (dict | None): Config for activate layers. Default: None. + + Returns: + nn.Module: A residual layer for the given config. + """ + downsample = None + if spatial_stride != 1 or layer_inplanes != inplanes: + downsample = ConvModule( + layer_inplanes, + inplanes, + kernel_size=1, + stride=(1, spatial_stride, spatial_stride), + padding=0, + bias=False, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=None) + + use_se = [False] * blocks + if self.se_style == 'all': + use_se = [True] * blocks + elif self.se_style == 'half': + use_se = [i % 2 == 0 for i in range(blocks)] + else: + raise NotImplementedError + + layers = [] + layers.append( + block( + layer_inplanes, + planes, + inplanes, + spatial_stride=spatial_stride, + downsample=downsample, + se_ratio=se_ratio if use_se[0] else None, + use_swish=use_swish, + norm_cfg=norm_cfg, + conv_cfg=conv_cfg, + act_cfg=act_cfg, + **kwargs)) + + for i in range(1, blocks): + layers.append( + block( + inplanes, + planes, + inplanes, + spatial_stride=1, + se_ratio=se_ratio if use_se[i] else None, + use_swish=use_swish, + norm_cfg=norm_cfg, + conv_cfg=conv_cfg, + act_cfg=act_cfg, + **kwargs)) + + return nn.Sequential(*layers) + + def _make_stem_layer(self): + """Construct the stem layers consists of a conv+norm+act module and a + pooling layer.""" + self.conv1_s = ConvModule( + self.in_channels, + self.base_channels, + kernel_size=(1, 3, 3), + stride=(1, 2, 2), + padding=(0, 1, 1), + bias=False, + conv_cfg=self.conv_cfg, + norm_cfg=None, + act_cfg=None) + self.conv1_t = ConvModule( + self.base_channels, + self.base_channels, + kernel_size=(5, 1, 1), + stride=(1, 1, 1), + padding=(2, 0, 0), + groups=self.base_channels, + bias=False, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + def _freeze_stages(self): + """Prevent all the parameters from being optimized before + ``self.frozen_stages``.""" + if self.frozen_stages >= 0: + self.conv1_s.eval() + self.conv1_t.eval() + for param in self.conv1_s.parameters(): + param.requires_grad = False + for param in self.conv1_t.parameters(): + param.requires_grad = False + + for i in range(1, self.frozen_stages + 1): + m = getattr(self, f'layer{i}') + m.eval() + for param in m.parameters(): + param.requires_grad = False + + def init_weights(self): + """Initiate the parameters either from existing checkpoint or from + scratch.""" + for m in self.modules(): + if isinstance(m, nn.Conv3d): + kaiming_init(m) + elif isinstance(m, _BatchNorm): + constant_init(m, 1) + + if self.zero_init_residual: + for m in self.modules(): + if isinstance(m, BlockX3D): + constant_init(m.conv3.bn, 0) + + if isinstance(self.pretrained, str): + logger = get_root_logger() + logger.info(f'load model from: {self.pretrained}') + + load_checkpoint(self, self.pretrained, strict=False, logger=logger) + + def forward(self, x): + """Defines the computation performed at every call. + + Args: + x (torch.Tensor): The input data. + + Returns: + torch.Tensor: The feature of the input + samples extracted by the backbone. + """ + x = self.conv1_s(x) + x = self.conv1_t(x) + for layer_name in self.res_layers: + res_layer = getattr(self, layer_name) + x = res_layer(x) + x = self.conv5(x) + return x + + def train(self, mode=True): + """Set the optimization status when training.""" + super().train(mode) + self._freeze_stages() + if mode and self.norm_eval: + for m in self.modules(): + if isinstance(m, _BatchNorm): + m.eval() diff --git a/pyskl/models/gcns/__init__.py b/pyskl/models/gcns/__init__.py new file mode 100644 index 00000000..82248441 --- /dev/null +++ b/pyskl/models/gcns/__init__.py @@ -0,0 +1,4 @@ +from .stgcn import STGCN +from .utils import mstcn, unit_gcn, unit_tcn + +__all__ = ['unit_gcn', 'unit_tcn', 'mstcn', 'STGCN'] diff --git a/pyskl/models/gcns/stgcn.py b/pyskl/models/gcns/stgcn.py new file mode 100644 index 00000000..42c77c5f --- /dev/null +++ b/pyskl/models/gcns/stgcn.py @@ -0,0 +1,145 @@ +import copy as cp + +import torch +import torch.nn as nn +from mmcv.runner import load_checkpoint + +from ...utils import Graph +from ..builder import BACKBONES +from .utils import mstcn, unit_gcn, unit_tcn + +EPS = 1e-4 + + +class STGCNBlock(nn.Module): + + def __init__(self, + in_channels, + out_channels, + A, + stride=1, + residual=True, + **kwargs): + super().__init__() + # prepare kwargs for gcn and tcn + common_args = ['norm'] + for arg in common_args: + if arg in kwargs: + value = kwargs.pop(arg) + kwargs['tcn_' + arg] = value + kwargs['gcn_' + arg] = value + + gcn_kwargs = {k[4:]: v for k, v in kwargs.items() if k[:4] == 'gcn_'} + tcn_kwargs = {k[4:]: v for k, v in kwargs.items() if k[:4] == 'tcn_'} + kwargs = {k: v for k, v in kwargs.items() if k[:4] not in ['gcn_', 'tcn_']} + assert len(kwargs) == 0, f'Invalid arguments: {kwargs}' + + tcn_type = tcn_kwargs.pop('type', 'unit_tcn') + assert tcn_type in ['unit_tcn', 'mstcn'] + gcn_type = gcn_kwargs.pop('type', 'unit_gcn') + assert gcn_type in ['unit_gcn'] + + self.gcn = unit_gcn(in_channels, out_channels, A, **gcn_kwargs) + + if tcn_type == 'unit_tcn': + self.tcn = unit_tcn(out_channels, out_channels, 9, stride=stride, **tcn_kwargs) + elif tcn_type == 'mstcn': + self.tcn = mstcn(out_channels, out_channels, stride=stride, **tcn_kwargs) + self.relu = nn.ReLU() + + if not residual: + self.residual = lambda x: 0 + elif (in_channels == out_channels) and (stride == 1): + self.residual = lambda x: x + else: + self.residual = unit_tcn(in_channels, out_channels, kernel_size=1, stride=stride) + + def forward(self, x, A=None): + """Defines the computation performed at every call.""" + res = self.residual(x) + x = self.tcn(self.gcn(x, A)) + res + return self.relu(x) + + +@BACKBONES.register_module() +class STGCN(nn.Module): + + def __init__(self, + graph_cfg, + in_channels=3, + base_channels=64, + ch_ratio=2, + num_stages=10, + inflate_stages=[5, 8], + down_stages=[5, 8], + data_bn_type='VC', + num_person=2, # * Only used when data_bn_type == 'MVC' + pretrained=None, + **kwargs): + super().__init__() + + self.graph = Graph(**graph_cfg) + A = torch.tensor(self.graph.A, dtype=torch.float32, requires_grad=False) + self.data_bn_type = data_bn_type + self.kwargs = kwargs + + if data_bn_type == 'MVC': + self.data_bn = nn.BatchNorm1d(num_person * in_channels * A.size(1)) + elif data_bn_type == 'VC': + self.data_bn = nn.BatchNorm1d(in_channels * A.size(1)) + else: + self.data_bn = nn.Identity() + + lw_kwargs = [cp.deepcopy(kwargs) for i in range(num_stages)] + for k, v in kwargs.items(): + if isinstance(v, tuple) and len(v) == num_stages: + for i in range(num_stages): + lw_kwargs[i][k] = v[i] + lw_kwargs[0].pop('tcn_dropout', None) + + self.in_channels = in_channels + self.base_channels = base_channels + self.ch_ratio = ch_ratio + self.inflate_stages = inflate_stages + self.down_stages = down_stages + + modules = [] + if self.in_channels != self.base_channels: + modules = [STGCNBlock(in_channels, base_channels, A.clone(), 1, residual=False, **lw_kwargs[0])] + + inflate_times = 0 + for i in range(2, num_stages + 1): + stride = 1 + (i in down_stages) + in_channels = base_channels + res_channels = 0 + if i in inflate_stages: + inflate_times += 1 + out_channels = int(self.base_channels * self.ch_ratio ** inflate_times + EPS) + base_channels = out_channels + modules.append(STGCNBlock(in_channels + res_channels, out_channels, A.clone(), stride, **lw_kwargs[i - 1])) + + if self.in_channels == self.base_channels: + num_stages -= 1 + + self.num_stages = num_stages + self.gcn = nn.ModuleList(modules) + self.pretrained = pretrained + + def init_weights(self): + if isinstance(self.pretrained, str): + load_checkpoint(self, self.pretrained, strict=False) + + def forward(self, x): + N, M, T, V, C = x.size() + x = x.permute(0, 1, 3, 4, 2).contiguous() + if self.data_bn_type == 'MVC': + x = self.data_bn(x.view(N, M * V * C, T)) + else: + x = self.data_bn(x.view(N * M, V * C, T)) + x = x.view(N, M, V, C, T).permute(0, 1, 3, 4, 2).contiguous().view(N * M, C, T, V) + + for i in range(self.num_stages): + x = self.gcn[i](x) + + x = x.reshape((N, M) + x.shape[1:]) + return x diff --git a/pyskl/models/gcns/utils/__init__.py b/pyskl/models/gcns/utils/__init__.py new file mode 100644 index 00000000..78d29052 --- /dev/null +++ b/pyskl/models/gcns/utils/__init__.py @@ -0,0 +1,4 @@ +from .gcn import unit_gcn +from .tcn import mstcn, unit_tcn + +__all__ = ['unit_gcn', 'unit_tcn', 'mstcn'] diff --git a/pyskl/models/gcns/utils/gcn.py b/pyskl/models/gcns/utils/gcn.py new file mode 100644 index 00000000..7042ed0c --- /dev/null +++ b/pyskl/models/gcns/utils/gcn.py @@ -0,0 +1,79 @@ +import torch +import torch.nn as nn +from mmcv.cnn import build_activation_layer, build_norm_layer + +EPS = 1e-4 + + +class unit_gcn(nn.Module): + + def __init__(self, + in_channels, + out_channels, + A, + adaptive='importance', + conv_pos='pre', + with_res=False, + norm='BN', + act='ReLU'): + super().__init__() + self.in_channels = in_channels + self.out_channels = out_channels + self.num_subsets = A.size(0) + + assert adaptive in [None, 'init', 'offset', 'importance'] + self.adaptive = adaptive + assert conv_pos in ['pre', 'post'] + self.conv_pos = conv_pos + self.with_res = with_res + + self.norm_cfg = norm if isinstance(norm, dict) else dict(type=norm) + self.act_cfg = act if isinstance(act, dict) else dict(type=act) + self.bn = build_norm_layer(self.norm_cfg, out_channels)[1] + self.act = build_activation_layer(self.act_cfg) + + if self.adaptive == 'init': + self.A = nn.Parameter(A.clone()) + else: + self.register_buffer('A', A) + + if self.adaptive in ['offset', 'importance']: + self.PA = nn.Parameter(A.clone()) + if self.adaptive == 'offset': + nn.init.uniform_(self.PA, -1e-6, 1e-6) + elif self.adaptive == 'importance': + nn.init.constant_(self.PA, 1) + + if self.conv_pos == 'pre': + self.conv = nn.Conv2d(in_channels, out_channels * A.size(0), 1) + elif self.conv_pos == 'post': + self.conv = nn.Conv2d(A.size(0) * in_channels, out_channels, 1) + + if self.with_res: + if in_channels != out_channels: + self.down = nn.Sequential( + nn.Conv2d(in_channels, out_channels, 1), + build_norm_layer(self.norm_cfg, out_channels)[1]) + else: + self.down = lambda x: x + + def forward(self, x, A=None): + """Defines the computation performed at every call.""" + n, c, t, v = x.shape + res = self.down(x) if self.with_res else 0 + + A_switch = {None: self.A, 'init': self.A} + if hasattr(self, 'PA'): + A_switch.update({'offset': self.A + self.PA, 'importance': self.A * self.PA}) + A = A_switch[self.adaptive] + + if self.conv_pos == 'pre': + x = self.conv(x) + x = x.view(n, self.num_subsets, -1, t, v) + x = torch.einsum('nkctv,kvw->nctw', (x, A)).contiguous() + elif self.conv_pos == 'post': + x = torch.einsum('nctv,kvw->nkctw', (x, A)).contiguous() + x = x.view(n, -1, t, v) + x = self.conv(x) + + return self.act(self.bn(x) + res) diff --git a/pyskl/models/gcns/utils/tcn.py b/pyskl/models/gcns/utils/tcn.py new file mode 100644 index 00000000..3aea8d1c --- /dev/null +++ b/pyskl/models/gcns/utils/tcn.py @@ -0,0 +1,105 @@ +import torch +import torch.nn as nn +from mmcv.cnn import build_norm_layer + + +class unit_tcn(nn.Module): + + def __init__(self, in_channels, out_channels, kernel_size=9, stride=1, dilation=1, norm='BN', dropout=0): + + super().__init__() + + self.in_channels = in_channels + self.out_channels = out_channels + self.norm_cfg = norm if isinstance(norm, dict) else dict(type=norm) + pad = (kernel_size + (kernel_size - 1) * (dilation - 1) - 1) // 2 + + self.conv = nn.Conv2d( + in_channels, + out_channels, + kernel_size=(kernel_size, 1), + padding=(pad, 0), + stride=(stride, 1), + dilation=(dilation, 1)) + self.bn = build_norm_layer(self.norm_cfg, out_channels)[1] if norm is not None else nn.Identity() + self.drop = nn.Dropout(dropout, inplace=True) + self.stride = stride + + def forward(self, x): + return self.drop(self.bn(self.conv(x))) + + +class mstcn(nn.Module): + + def __init__(self, + in_channels, + out_channels, + mid_channels=None, + dropout=0., + ms_cfg=[(3, 1), (3, 2), (3, 3), (3, 4), ('max', 3), '1x1'], + stride=1): + + super().__init__() + # Multiple branches of temporal convolution + self.ms_cfg = ms_cfg + num_branches = len(ms_cfg) + self.num_branches = num_branches + self.in_channels = in_channels + self.out_channels = out_channels + self.act = nn.ReLU() + + if mid_channels is None: + mid_channels = out_channels // num_branches + rem_mid_channels = out_channels - mid_channels * (num_branches - 1) + else: + assert isinstance(mid_channels, float) and mid_channels > 0 + mid_channels = int(out_channels * mid_channels) + rem_mid_channels = mid_channels + + self.mid_channels = mid_channels + self.rem_mid_channels = rem_mid_channels + + branches = [] + for i, cfg in enumerate(ms_cfg): + branch_c = rem_mid_channels if i == 0 else mid_channels + if cfg == '1x1': + branches.append(nn.Conv2d(in_channels, branch_c, kernel_size=1, stride=(stride, 1))) + continue + assert isinstance(cfg, tuple) + if cfg[0] == 'max': + branches.append( + nn.Sequential( + nn.Conv2d(in_channels, branch_c, kernel_size=1), nn.BatchNorm2d(branch_c), self.act, + nn.MaxPool2d(kernel_size=(cfg[1], 1), stride=(stride, 1), padding=(1, 0)))) + continue + assert isinstance(cfg[0], int) and isinstance(cfg[1], int) + branch = nn.Sequential( + nn.Conv2d(in_channels, branch_c, kernel_size=1), nn.BatchNorm2d(branch_c), self.act, + unit_tcn(branch_c, branch_c, kernel_size=cfg[0], stride=stride, dilation=cfg[1], norm=None)) + branches.append(branch) + + self.branches = nn.ModuleList(branches) + tin_channels = mid_channels * (num_branches - 1) + rem_mid_channels + + self.transform = nn.Sequential( + nn.BatchNorm2d(tin_channels), self.act, nn.Conv2d(tin_channels, out_channels, kernel_size=1)) + + self.bn = nn.BatchNorm2d(out_channels) + self.drop = nn.Dropout(dropout, inplace=True) + + def inner_forward(self, x): + N, C, T, V = x.shape + + branch_outs = [] + for tempconv in self.branches: + out = tempconv(x) + branch_outs.append(out) + + feat = torch.cat(branch_outs, dim=1) + feat = self.transform(feat) + return feat + + def forward(self, x): + out = self.inner_forward(x) + out = self.bn(out) + return self.drop(out) diff --git a/pyskl/models/heads/__init__.py b/pyskl/models/heads/__init__.py new file mode 100644 index 00000000..1958f674 --- /dev/null +++ b/pyskl/models/heads/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) OpenMMLab. All rights reserved. +# flake8: noqa: F401 +from .base import BaseHead +from .simple_head import GCNHead, I3DHead, SimpleHead, SlowFastHead, TSNHead diff --git a/pyskl/models/heads/base.py b/pyskl/models/heads/base.py new file mode 100644 index 00000000..3c862664 --- /dev/null +++ b/pyskl/models/heads/base.py @@ -0,0 +1,88 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from abc import ABCMeta, abstractmethod + +import torch +import torch.nn as nn + +from ...core import top_k_accuracy +from ..builder import build_loss + + +class BaseHead(nn.Module, metaclass=ABCMeta): + """Base class for head. + + All Head should subclass it. + All subclass should overwrite: + - Methods:``init_weights``, initializing weights in some modules. + - Methods:``forward``, supporting to forward both for training and testing. + + Args: + num_classes (int): Number of classes to be classified. + in_channels (int): Number of channels in input feature. + loss_cls (dict): Config for building loss. + Default: dict(type='CrossEntropyLoss', loss_weight=1.0). + multi_class (bool): Determines whether it is a multi-class + recognition task. Default: False. + label_smooth_eps (float): Epsilon used in label smooth. + Reference: arxiv.org/abs/1906.02629. Default: 0. + """ + + def __init__(self, + num_classes, + in_channels, + loss_cls=dict(type='CrossEntropyLoss', loss_weight=1.0), + multi_class=False, + label_smooth_eps=0.0): + super().__init__() + self.num_classes = num_classes + self.in_channels = in_channels + self.loss_cls = build_loss(loss_cls) + self.multi_class = multi_class + self.label_smooth_eps = label_smooth_eps + + @abstractmethod + def init_weights(self): + """Initiate the parameters either from existing checkpoint or from + scratch.""" + + @abstractmethod + def forward(self, x): + """Defines the computation performed at every call.""" + + def loss(self, cls_score, label, **kwargs): + """Calculate the loss given output ``cls_score``, target ``label``. + + Args: + cls_score (torch.Tensor): The output of the model. + label (torch.Tensor): The target output of the model. + + Returns: + dict: A dict containing field 'loss_cls'(mandatory) + and 'top1_acc', 'top5_acc'(optional). + """ + losses = dict() + if label.shape == torch.Size([]): + label = label.unsqueeze(0) + elif label.dim() == 1 and label.size()[0] == self.num_classes \ + and cls_score.size()[0] == 1: + label = label.unsqueeze(0) + + if not self.multi_class and cls_score.size() != label.size(): + top_k_acc = top_k_accuracy(cls_score.detach().cpu().numpy(), + label.detach().cpu().numpy(), (1, 5)) + losses['top1_acc'] = torch.tensor( + top_k_acc[0], device=cls_score.device) + losses['top5_acc'] = torch.tensor( + top_k_acc[1], device=cls_score.device) + + elif self.multi_class and self.label_smooth_eps != 0: + label = ((1 - self.label_smooth_eps) * label + self.label_smooth_eps / self.num_classes) + + loss_cls = self.loss_cls(cls_score, label, **kwargs) + # loss_cls may be dictionary or single tensor + if isinstance(loss_cls, dict): + losses.update(loss_cls) + else: + losses['loss_cls'] = loss_cls + + return losses diff --git a/pyskl/models/heads/simple_head.py b/pyskl/models/heads/simple_head.py new file mode 100644 index 00000000..2c6e73d6 --- /dev/null +++ b/pyskl/models/heads/simple_head.py @@ -0,0 +1,156 @@ +import torch +import torch.nn as nn +from mmcv.cnn import normal_init + +from ..builder import HEADS +from .base import BaseHead + + +@HEADS.register_module() +class SimpleHead(BaseHead): + """ A simple classification head. + + Args: + num_classes (int): Number of classes to be classified. + in_channels (int): Number of channels in input feature. + loss_cls (dict): Config for building loss. Default: dict(type='CrossEntropyLoss') + dropout (float): Probability of dropout layer. Default: 0.5. + init_std (float): Std value for Initiation. Default: 0.01. + kwargs (dict, optional): Any keyword argument to be used to initialize + the head. + """ + + def __init__(self, + num_classes, + in_channels, + loss_cls=dict(type='CrossEntropyLoss'), + dropout=0.5, + init_std=0.01, + mode='3D', + **kwargs): + super().__init__(num_classes, in_channels, loss_cls, **kwargs) + + self.dropout_ratio = dropout + self.init_std = init_std + if self.dropout_ratio != 0: + self.dropout = nn.Dropout(p=self.dropout_ratio) + else: + self.dropout = None + assert mode in ['3D', 'GCN', '2D'] + self.mode = mode + + self.in_c = in_channels + self.fc_cls = nn.Linear(self.in_c, num_classes) + + def init_weights(self): + """Initiate the parameters from scratch.""" + normal_init(self.fc_cls, std=self.init_std) + + def forward(self, x): + """Defines the computation performed at every call. + + Args: + x (torch.Tensor): The input data. + + Returns: + torch.Tensor: The classification scores for input samples. + """ + + if isinstance(x, list): + for item in x: + assert len(item.shape) == 2 + x = [item.mean(dim=0) for item in x] + x = torch.stack(x) + + if len(x.shape) != 2: + if self.mode == '2D': + assert len(x.shape) == 5 + N, S, C, H, W = x.shape + pool = nn.AdaptiveAvgPool2d(1) + x = x.reshape(N * S, C, H, W) + x = pool(x) + x = x.reshape(N, S, C) + x = x.mean(dim=1) + if self.mode == '3D': + pool = nn.AdaptiveAvgPool3d(1) + if isinstance(x, tuple) or isinstance(x, list): + x = torch.cat(x, dim=1) + x = pool(x) + x = x.view(x.shape[:2]) + if self.mode == 'GCN': + pool = nn.AdaptiveAvgPool2d(1) + N, M, C, T, V = x.shape + x = x.reshape(N * M, C, T, V) + + x = pool(x) + x = x.reshape(N, M, C) + x = x.mean(dim=1) + + assert x.shape[1] == self.in_c + if self.dropout is not None: + x = self.dropout(x) + + cls_score = self.fc_cls(x) + return cls_score + + +@HEADS.register_module() +class I3DHead(SimpleHead): + + def __init__(self, + num_classes, + in_channels, + loss_cls=dict(type='CrossEntropyLoss'), + dropout=0.5, + init_std=0.01, + **kwargs): + super().__init__(num_classes, + in_channels, + loss_cls=loss_cls, + dropout=dropout, + init_std=init_std, + mode='3D', + **kwargs) + + +@HEADS.register_module() +class SlowFastHead(I3DHead): + pass + + +@HEADS.register_module() +class GCNHead(SimpleHead): + + def __init__(self, + num_classes, + in_channels, + loss_cls=dict(type='CrossEntropyLoss'), + dropout=0., + init_std=0.01, + **kwargs): + super().__init__(num_classes, + in_channels, + loss_cls=loss_cls, + dropout=dropout, + init_std=init_std, + mode='GCN', + **kwargs) + + +@HEADS.register_module() +class TSNHead(BaseHead): + + def __init__(self, + num_classes, + in_channels, + loss_cls=dict(type='CrossEntropyLoss'), + dropout=0.5, + init_std=0.01, + **kwargs): + super().__init__(num_classes, + in_channels, + loss_cls=loss_cls, + dropout=dropout, + init_std=init_std, + mode='2D', + **kwargs) diff --git a/pyskl/models/losses/__init__.py b/pyskl/models/losses/__init__.py new file mode 100644 index 00000000..e398ae5a --- /dev/null +++ b/pyskl/models/losses/__init__.py @@ -0,0 +1,5 @@ +# Copyright (c) OpenMMLab. All rights reserved. +# flake8: noqa: F401 + +from .base import BaseWeightedLoss +from .cross_entropy_loss import BCELossWithLogits, CrossEntropyLoss diff --git a/pyskl/models/losses/base.py b/pyskl/models/losses/base.py new file mode 100644 index 00000000..9e1df07d --- /dev/null +++ b/pyskl/models/losses/base.py @@ -0,0 +1,45 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from abc import ABCMeta, abstractmethod + +import torch.nn as nn + + +class BaseWeightedLoss(nn.Module, metaclass=ABCMeta): + """Base class for loss. + + All subclass should overwrite the ``_forward()`` method which returns the + normal loss without loss weights. + + Args: + loss_weight (float): Factor scalar multiplied on the loss. + Default: 1.0. + """ + + def __init__(self, loss_weight=1.0): + super().__init__() + self.loss_weight = loss_weight + + @abstractmethod + def _forward(self, *args, **kwargs): + pass + + def forward(self, *args, **kwargs): + """Defines the computation performed at every call. + + Args: + *args: The positional arguments for the corresponding + loss. + **kwargs: The keyword arguments for the corresponding + loss. + + Returns: + torch.Tensor: The calculated loss. + """ + ret = self._forward(*args, **kwargs) + if isinstance(ret, dict): + for k in ret: + if 'loss' in k: + ret[k] *= self.loss_weight + else: + ret *= self.loss_weight + return ret diff --git a/pyskl/models/losses/cross_entropy_loss.py b/pyskl/models/losses/cross_entropy_loss.py new file mode 100644 index 00000000..5c84c6b4 --- /dev/null +++ b/pyskl/models/losses/cross_entropy_loss.py @@ -0,0 +1,121 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.nn.functional as F + +from ..builder import LOSSES +from .base import BaseWeightedLoss + + +@LOSSES.register_module() +class CrossEntropyLoss(BaseWeightedLoss): + """Cross Entropy Loss. + + Support two kinds of labels and their corresponding loss type. It's worth + mentioning that loss type will be detected by the shape of ``cls_score`` + and ``label``. + 1) Hard label: This label is an integer array and all of the elements are + in the range [0, num_classes - 1]. This label's shape should be + ``cls_score``'s shape with the `num_classes` dimension removed. + 2) Soft label(probablity distribution over classes): This label is a + probability distribution and all of the elements are in the range + [0, 1]. This label's shape must be the same as ``cls_score``. For now, + only 2-dim soft label is supported. + + Args: + loss_weight (float): Factor scalar multiplied on the loss. + Default: 1.0. + class_weight (list[float] | None): Loss weight for each class. If set + as None, use the same weight 1 for all classes. Only applies + to CrossEntropyLoss and BCELossWithLogits (should not be set when + using other losses). Default: None. + """ + + def __init__(self, loss_weight=1.0, class_weight=None): + super().__init__(loss_weight=loss_weight) + self.class_weight = None + if class_weight is not None: + self.class_weight = torch.Tensor(class_weight) + + def _forward(self, cls_score, label, **kwargs): + """Forward function. + + Args: + cls_score (torch.Tensor): The class score. + label (torch.Tensor): The ground truth label. + kwargs: Any keyword argument to be used to calculate + CrossEntropy loss. + + Returns: + torch.Tensor: The returned CrossEntropy loss. + """ + if cls_score.size() == label.size(): + # calculate loss for soft label + + assert cls_score.dim() == 2, 'Only support 2-dim soft label' + assert len(kwargs) == 0, \ + ('For now, no extra args are supported for soft label, ' + f'but get {kwargs}') + + lsm = F.log_softmax(cls_score, 1) + if self.class_weight is not None: + self.class_weight = self.class_weight.to(cls_score.device) + lsm = lsm * self.class_weight.unsqueeze(0) + loss_cls = -(label * lsm).sum(1) + + # default reduction 'mean' + if self.class_weight is not None: + # Use weighted average as pytorch CrossEntropyLoss does. + # For more information, please visit https://pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html # noqa + loss_cls = loss_cls.sum() / torch.sum( + self.class_weight.unsqueeze(0) * label) + else: + loss_cls = loss_cls.mean() + else: + # calculate loss for hard label + + if self.class_weight is not None: + assert 'weight' not in kwargs, \ + "The key 'weight' already exists." + kwargs['weight'] = self.class_weight.to(cls_score.device) + loss_cls = F.cross_entropy(cls_score, label, **kwargs) + + return loss_cls + + +@LOSSES.register_module() +class BCELossWithLogits(BaseWeightedLoss): + """Binary Cross Entropy Loss with logits. + + Args: + loss_weight (float): Factor scalar multiplied on the loss. + Default: 1.0. + class_weight (list[float] | None): Loss weight for each class. If set + as None, use the same weight 1 for all classes. Only applies + to CrossEntropyLoss and BCELossWithLogits (should not be set when + using other losses). Default: None. + """ + + def __init__(self, loss_weight=1.0, class_weight=None): + super().__init__(loss_weight=loss_weight) + self.class_weight = None + if class_weight is not None: + self.class_weight = torch.Tensor(class_weight) + + def _forward(self, cls_score, label, **kwargs): + """Forward function. + + Args: + cls_score (torch.Tensor): The class score. + label (torch.Tensor): The ground truth label. + kwargs: Any keyword argument to be used to calculate + bce loss with logits. + + Returns: + torch.Tensor: The returned bce loss with logits. + """ + if self.class_weight is not None: + assert 'weight' not in kwargs, "The key 'weight' already exists." + kwargs['weight'] = self.class_weight.to(cls_score.device) + loss_cls = F.binary_cross_entropy_with_logits(cls_score, label, + **kwargs) + return loss_cls diff --git a/pyskl/models/recognizers/__init__.py b/pyskl/models/recognizers/__init__.py new file mode 100644 index 00000000..0a11c08e --- /dev/null +++ b/pyskl/models/recognizers/__init__.py @@ -0,0 +1,6 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .recognizer2d import Recognizer2D +from .recognizer3d import Recognizer3D +from .recognizergcn import RecognizerGCN + +__all__ = ['Recognizer2D', 'Recognizer3D', 'RecognizerGCN'] diff --git a/pyskl/models/recognizers/base.py b/pyskl/models/recognizers/base.py new file mode 100644 index 00000000..49b98adb --- /dev/null +++ b/pyskl/models/recognizers/base.py @@ -0,0 +1,196 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import functools +from abc import ABCMeta, abstractmethod +from collections import OrderedDict + +import torch +import torch.distributed as dist +import torch.nn as nn +import torch.nn.functional as F + +from .. import builder + + +def rgetattr(obj, attr, *args): + def _getattr(obj, attr): + return getattr(obj, attr, *args) + + return functools.reduce(_getattr, [obj] + attr.split('.')) + + +class BaseRecognizer(nn.Module, metaclass=ABCMeta): + """Base class for recognizers. + + All recognizers should subclass it. + All subclass should overwrite: + + - Methods:``forward_train``, supporting to forward when training. + - Methods:``forward_test``, supporting to forward when testing. + + Args: + backbone (dict): Backbone modules to extract feature. + cls_head (dict | None): Classification head to process feature. Default: None. + train_cfg (dict): Config for training. Default: {}. + test_cfg (dict): Config for testing. Default: {}. + """ + + def __init__(self, + backbone, + cls_head=None, + train_cfg=dict(), + test_cfg=dict()): + super().__init__() + # record the source of the backbone + self.backbone = builder.build_backbone(backbone) + self.cls_head = builder.build_head(cls_head) if cls_head else None + + if train_cfg is None: + train_cfg = dict() + if test_cfg is None: + test_cfg = dict() + + assert isinstance(train_cfg, dict) + assert isinstance(test_cfg, dict) + + self.train_cfg = train_cfg + self.test_cfg = test_cfg + + # max_testing_views should be int + self.max_testing_views = test_cfg.get('max_testing_views', None) + self.init_weights() + + @property + def with_cls_head(self): + """bool: whether the recognizer has a cls_head""" + return hasattr(self, 'cls_head') and self.cls_head is not None + + def init_weights(self): + """Initialize the model network weights.""" + self.backbone.init_weights() + if self.with_cls_head: + self.cls_head.init_weights() + + def extract_feat(self, imgs): + """Extract features through a backbone. + + Args: + imgs (torch.Tensor): The input images. + + Returns: + torch.tensor: The extracted features. + """ + x = self.backbone(imgs) + return x + + def average_clip(self, cls_score): + """Averaging class score over multiple clips. + + Using different averaging types ('score' or 'prob' or None, which defined in test_cfg) to computed the final + averaged class score. Only called in test mode. By default, we use 'prob' mode. + + Args: + cls_score (torch.Tensor): Class score to be averaged. + + Returns: + torch.Tensor: Averaged class score. + """ + assert len(cls_score.shape) == 3 # * (Batch, NumSegs, Dim) + average_clips = self.test_cfg.get('average_clips', 'prob') + if average_clips not in ['score', 'prob', None]: + raise ValueError(f'{average_clips} is not supported. Supported: ["score", "prob", None]') + + if average_clips is None: + return cls_score + + if average_clips == 'prob': + return F.softmax(cls_score, dim=2).mean(dim=1) + elif average_clips == 'score': + return cls_score.mean(dim=1) + + @abstractmethod + def forward_train(self, imgs, label, **kwargs): + """Defines the computation performed at every call when training.""" + + @abstractmethod + def forward_test(self, imgs, **kwargs): + """Defines the computation performed at every call when evaluation and + testing.""" + + def _parse_losses(self, losses): + """Parse the ra w outputs (losses) of the network. + + Args: + losses (dict): Raw output of the network, which usually contain + losses and other necessary information. + + Returns: + tuple[Tensor, dict]: (loss, log_vars), loss is the loss tensor + which may be a weighted sum of all losses, log_vars contains + all the variables to be sent to the logger. + """ + log_vars = OrderedDict() + for loss_name, loss_value in losses.items(): + if isinstance(loss_value, torch.Tensor): + log_vars[loss_name] = loss_value.mean() + elif isinstance(loss_value, list): + log_vars[loss_name] = sum(_loss.mean() for _loss in loss_value) + else: + raise TypeError(f'{loss_name} is not a tensor or list of tensors') + + loss = sum(_value for _key, _value in log_vars.items() if 'loss' in _key) + + log_vars['loss'] = loss + for loss_name, loss_value in log_vars.items(): + # reduce loss when distributed training + if dist.is_available() and dist.is_initialized(): + loss_value = loss_value.data.clone() + dist.all_reduce(loss_value.div_(dist.get_world_size())) + log_vars[loss_name] = loss_value.item() + + return loss, log_vars + + def forward(self, imgs, label=None, return_loss=True, **kwargs): + """Define the computation performed at every call.""" + if return_loss: + if label is None: + raise ValueError('Label should not be None.') + return self.forward_train(imgs, label, **kwargs) + + return self.forward_test(imgs, **kwargs) + + def train_step(self, data_batch, optimizer, **kwargs): + """The iteration step during training. + + This method defines an iteration step during training, except for the + back propagation and optimizer updating, which are done in an optimizer + hook. Note that in some complicated cases or models, the whole process + including back propagation and optimizer updating is also defined in + this method, such as GAN. + + Args: + data_batch (dict): The output of dataloader. + optimizer (:obj:`torch.optim.Optimizer` | dict): The optimizer of + runner is passed to ``train_step()``. This argument is unused + and reserved. + + Returns: + dict: It should contain at least 3 keys: ``loss``, ``log_vars``, + ``num_samples``. + ``loss`` is a tensor for back propagation, which can be a + weighted sum of multiple losses. + ``log_vars`` contains all the variables to be sent to the + logger. + ``num_samples`` indicates the batch size (when the model is + DDP, it means the batch size on each GPU), which is used for + averaging the logs. + """ + losses = self(**data_batch, return_loss=True) + + loss, log_vars = self._parse_losses(losses) + + outputs = dict( + loss=loss, + log_vars=log_vars, + num_samples=len(next(iter(data_batch.values())))) + + return outputs diff --git a/pyskl/models/recognizers/recognizer2d.py b/pyskl/models/recognizers/recognizer2d.py new file mode 100644 index 00000000..995069d1 --- /dev/null +++ b/pyskl/models/recognizers/recognizer2d.py @@ -0,0 +1,58 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from torch import nn + +from ..builder import RECOGNIZERS +from .base import BaseRecognizer + + +@RECOGNIZERS.register_module() +class Recognizer2D(BaseRecognizer): + """2D recognizer model framework.""" + + def forward_train(self, imgs, label, **kwargs): + """Defines the computation performed at every call when training.""" + + assert self.with_cls_head + batches = imgs.shape[0] + imgs = imgs.reshape((-1, ) + imgs.shape[2:]) + num_segs = imgs.shape[0] // batches + + losses = dict() + + x = self.extract_feat(imgs) + x = x.reshape((batches, num_segs) + x.shape[1:]) + + cls_score = self.cls_head(x) + gt_label = label.squeeze() + loss_cls = self.cls_head.loss(cls_score, gt_label, **kwargs) + losses.update(loss_cls) + + return losses + + def forward_test(self, imgs, **kwargs): + """Defines the computation performed at every call when evaluation and testing.""" + batches = imgs.shape[0] + imgs = imgs.reshape((-1, ) + imgs.shape[2:]) + + x = self.extract_feat(imgs) + assert 'num_segs' in self.test_cfg + num_segs = self.test_cfg['num_segs'] + assert x.shape[0] % (batches * num_segs) == 0 + num_crops = x.shape[0] // (batches * num_segs) + + if self.test_cfg.get('feat_ext', False): + # perform spatial pooling + avg_pool = nn.AdaptiveAvgPool2d(1) + x = avg_pool(x) + # squeeze dimensions + x = x.reshape((batches, num_crops, num_segs, -1)) + # temporal average pooling + x = x.mean(axis=1).mean(axis=1) + return x.cpu().numpy() + + x = x.reshape((batches * num_crops, num_segs) + x.shape[1:]) + cls_score = self.cls_head(x) + cls_score = cls_score.reshape(batches, num_crops, cls_score.shape[-1]) + # calculate num_crops automatically + cls_score = self.average_clip(cls_score) + return cls_score.cpu().numpy() diff --git a/pyskl/models/recognizers/recognizer3d.py b/pyskl/models/recognizers/recognizer3d.py new file mode 100644 index 00000000..c416d6a0 --- /dev/null +++ b/pyskl/models/recognizers/recognizer3d.py @@ -0,0 +1,85 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +from torch import nn + +from ..builder import RECOGNIZERS +from .base import BaseRecognizer + + +@RECOGNIZERS.register_module() +class Recognizer3D(BaseRecognizer): + """3D recognizer model framework.""" + + def forward_train(self, imgs, label, **kwargs): + """Defines the computation performed at every call when training.""" + + assert self.with_cls_head + imgs = imgs.reshape((-1, ) + imgs.shape[2:]) + losses = dict() + + x = self.extract_feat(imgs) + + cls_score = self.cls_head(x) + gt_label = label.squeeze() + loss_cls = self.cls_head.loss(cls_score, gt_label, **kwargs) + losses.update(loss_cls) + + return losses + + def forward_test(self, imgs, **kwargs): + """Defines the computation performed at every call when evaluation, testing.""" + batches = imgs.shape[0] + num_segs = imgs.shape[1] + imgs = imgs.reshape((-1, ) + imgs.shape[2:]) + + if self.max_testing_views is not None: + total_views = imgs.shape[0] + assert num_segs == total_views, ( + 'max_testing_views is only compatible ' + 'with batch_size == 1') + view_ptr = 0 + feats = [] + while view_ptr < total_views: + batch_imgs = imgs[view_ptr:view_ptr + self.max_testing_views] + x = self.extract_feat(batch_imgs) + feats.append(x) + view_ptr += self.max_testing_views + # should consider the case that feat is a tuple + if isinstance(feats[0], tuple): + len_tuple = len(feats[0]) + feat = [ + torch.cat([x[i] for x in feats]) for i in range(len_tuple) + ] + feat = tuple(feat) + else: + feat = torch.cat(feats) + else: + feat = self.extract_feat(imgs) + + if self.test_cfg.get('feat_ext', False): + feat_dim = len(feat[0].size()) if isinstance(feat, tuple) else len(feat.size()) + assert feat_dim in [5, 2], ( + 'Got feature of unknown architecture, ' + 'only 3D-CNN-like ([N, in_channels, T, H, W]), and ' + 'transformer-like ([N, in_channels]) features are supported.') + if feat_dim == 5: # 3D-CNN architecture + # perform spatio-temporal pooling + avg_pool = nn.AdaptiveAvgPool3d(1) + if isinstance(feat, tuple): + feat = [avg_pool(x) for x in feat] + # concat them + feat = torch.cat(feat, axis=1) + else: + feat = avg_pool(feat) + # squeeze dimensions + feat = feat.reshape((batches, num_segs, -1)) + # temporal average pooling + feat = feat.mean(axis=1) + return feat.cpu().numpy() + + # should have cls_head if not extracting features + assert self.with_cls_head + cls_score = self.cls_head(feat) + cls_score = cls_score.reshape(batches, num_segs, cls_score.shape[-1]) + cls_score = self.average_clip(cls_score) + return cls_score.cpu().numpy() diff --git a/pyskl/models/recognizers/recognizergcn.py b/pyskl/models/recognizers/recognizergcn.py new file mode 100644 index 00000000..ae905629 --- /dev/null +++ b/pyskl/models/recognizers/recognizergcn.py @@ -0,0 +1,96 @@ +import numpy as np +import torch + +from ..builder import RECOGNIZERS +from .base import BaseRecognizer + + +@RECOGNIZERS.register_module() +class RecognizerGCN(BaseRecognizer): + """GCN-based recognizer for skeleton-based action recognition. """ + + def forward_train(self, keypoint, label, **kwargs): + """Defines the computation performed at every call when training.""" + assert self.with_cls_head + assert keypoint.shape[1] == 1 + keypoint = keypoint[:, 0] + + losses = dict() + x = self.extract_feat(keypoint) + cls_score = self.cls_head(x) + gt_label = label.squeeze(-1) + loss = self.cls_head.loss(cls_score, gt_label) + losses.update(loss) + + return losses + + def forward_test(self, keypoint, **kwargs): + """Defines the computation performed at every call when evaluation and + testing.""" + assert self.with_cls_head or self.feat_ext + bs, nc = keypoint.shape[:2] + keypoint = keypoint.reshape((bs * nc, ) + keypoint.shape[2:]) + + x = self.extract_feat(keypoint) + feat_ext = self.test_cfg.get('feat_ext', False) + pool_opt = self.test_cfg.get('pool_opt', 'all') + score_ext = self.test_cfg.get('score_ext', False) + if feat_ext or score_ext: + assert bs == 1 + assert isinstance(pool_opt, str) + dim_idx = dict(n=0, m=1, t=3, v=4) + + if pool_opt == 'all': + pool_opt == 'nmtv' + if pool_opt != 'none': + for digit in pool_opt: + assert digit in dim_idx + + if isinstance(x, tuple) or isinstance(x, list): + x = torch.cat(x, dim=2) + assert len(x.shape) == 5, 'The shape is N, M, C, T, V' + if pool_opt != 'none': + for d in pool_opt: + x = x.mean(dim_idx[d], keepdim=True) + + if score_ext: + w = self.cls_head.fc_cls.weight + b = self.cls_head.fc_cls.bias + x = torch.einsum('nmctv,oc->nmotv', x, w) + if b is not None: + x = x + b[..., None, None] + x = x[None] + return x.data.cpu().numpy().astype(np.float16) + + cls_score = self.cls_head(x) + cls_score = cls_score.reshape(bs, nc, cls_score.shape[-1]) + # harmless patch + if 'average_clips' not in self.test_cfg: + self.test_cfg['average_clips'] = 'prob' + + cls_score = self.average_clip(cls_score) + if isinstance(cls_score, tuple) or isinstance(cls_score, list): + cls_score = [x.data.cpu().numpy() for x in cls_score] + return [[x[i] for x in cls_score] for i in range(bs)] + + return cls_score.data.cpu().numpy() + + def forward(self, keypoint, label=None, return_loss=True, **kwargs): + """Define the computation performed at every call.""" + if return_loss: + if label is None: + raise ValueError('Label should not be None.') + return self.forward_train(keypoint, label, **kwargs) + + return self.forward_test(keypoint, **kwargs) + + def extract_feat(self, keypoint): + """Extract features through a backbone. + + Args: + keypoint (torch.Tensor): The input keypoints. + + Returns: + torch.tensor: The extracted features. + """ + return self.backbone(keypoint) diff --git a/pyskl/smp.py b/pyskl/smp.py new file mode 100644 index 00000000..751b641a --- /dev/null +++ b/pyskl/smp.py @@ -0,0 +1,105 @@ +# flake8: noqa: F401, F403 +import collections +import json +import multiprocessing as mp +import os +import os.path as osp +import pickle +import random as rd +import subprocess +import sys +from collections import defaultdict +from functools import reduce + +import cv2 +import numpy as np +import requests +from tqdm import tqdm + + +def mrlines(fname, sp='\n'): + f = open(fname).read().split(sp) + while f != [] and f[-1] == '': + f = f[:-1] + return f + +def mwlines(lines, fname): + with open(fname, 'w') as fout: + fout.write('\n'.join(lines)) + +def default_set(self, args, name, default): + if hasattr(args, name): + val = getattr(args, name) + setattr(self, name, val) + else: + setattr(self, name, default) + +def youtube_dl(url, output_name): + cmd = 'youtube-dl -f best -f mp4 "{}" -o {}'.format(url, output_name) + os.system(cmd) + +def run_command(cmd): + return subprocess.check_output(cmd) + +def ls(dirname='.', full=True): + if not full: + return os.listdir(dirname) + return [osp.join(dirname, x) for x in os.listdir(dirname)] + +def add(x, y): + return x + y + +def lpkl(pth): + return pickle.load(open(pth, 'rb')) + +def ljson(pth): + return json.load(open(pth, 'r')) + +def intop(pred, label, n): + pred = [np.argsort(x)[-n:] for x in pred] + hit = [(l in p) for l, p in zip(label, pred)] + return hit + +def comb(scores, coeffs): + ret = [x * coeffs[0] for x in scores[0]] + for i in range(1, len(scores)): + ret = [x + y for x, y in zip(ret, [x * coeffs[i] for x in scores[i]])] + return ret + +def top1(score, label): + return np.mean(intop(score, label, 1)) + +def load_label(ann, split=None): + if ann.endswith('.txt'): + lines = mrlines(ann) + return [int(x.split()[-1]) for x in lines] + elif ann.endswith('.pkl'): + data = lpkl(ann) + if split is not None: + split, annotations = set(data['split'][split]), data['annotations'] + key_name = 'frame_dir' if 'frame_dir' in annotations[0] else 'filename' + data = [x for x in annotations if x[key_name] in split] + return [x['label'] for x in data] + else: + raise NotImplemented + +def mean_acc(pred, label, with_class_acc=False): + hits = defaultdict(list) + for p, g in zip(pred, label): + hits[g].append(np.argmax(p) == g) + class_acc = [np.mean(x) for x in hits.values()] + return np.mean(class_acc), class_acc if with_class_acc else np.mean(class_acc) + +def match_dict(s, d): + values = [] + for k, v in d.items(): + if k in s: + values.append(v) + assert len(values) == 1 + return values[0] + +def download_file(url, filename=None): + if filename is None: + filename = url.split('/')[-1] + response = requests.get(url) + open(filename, 'wb').write(response.content) diff --git a/pyskl/utils/__init__.py b/pyskl/utils/__init__.py new file mode 100644 index 00000000..fa45efd3 --- /dev/null +++ b/pyskl/utils/__init__.py @@ -0,0 +1,9 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .collect_env import collect_env # noqa: F401, F403 +from .graph import Graph # noqa: F401, F403 +from .misc import get_root_logger, mc_off, mc_on, test_port # noqa: F401, F403 + +try: + from .visualize import Vis3DPose, Vis2DPose # noqa: F401, F403 +except ImportError: + pass diff --git a/pyskl/utils/collect_env.py b/pyskl/utils/collect_env.py new file mode 100644 index 00000000..432450f5 --- /dev/null +++ b/pyskl/utils/collect_env.py @@ -0,0 +1,17 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from mmcv.utils import collect_env as collect_basic_env +from mmcv.utils import get_git_hash + +import pyskl + + +def collect_env(): + env_info = collect_basic_env() + env_info['pyskl'] = ( + pyskl.__version__ + '+' + get_git_hash(digits=7)) + return env_info + + +if __name__ == '__main__': + for name, val in collect_env().items(): + print(f'{name}: {val}') diff --git a/pyskl/utils/graph.py b/pyskl/utils/graph.py new file mode 100644 index 00000000..e5c37462 --- /dev/null +++ b/pyskl/utils/graph.py @@ -0,0 +1,149 @@ +import numpy as np +import torch + + +def k_adjacency(A, k, with_self=False, self_factor=1): + # A is a 2D square array + if isinstance(A, torch.Tensor): + A = A.data.cpu().numpy() + assert isinstance(A, np.ndarray) + Iden = np.eye(len(A), dtype=A.dtype) + if k == 0: + return Iden + Ak = np.minimum(np.linalg.matrix_power(A + Iden, k), 1) - np.minimum(np.linalg.matrix_power(A + Iden, k - 1), 1) + if with_self: + Ak += (self_factor * Iden) + return Ak + + +def edge2mat(link, num_node): + A = np.zeros((num_node, num_node)) + for i, j in link: + A[j, i] = 1 + return A + + +def normalize_digraph(A, dim=0): + # A is a 2D square array + Dl = np.sum(A, dim) + h, w = A.shape + Dn = np.zeros((w, w)) + + for i in range(w): + if Dl[i] > 0: + Dn[i, i] = Dl[i] ** (-1) + + AD = np.dot(A, Dn) + return AD + + +def get_hop_distance(num_node, edge, max_hop=1): + A = np.eye(num_node) + + for i, j in edge: + A[i, j] = 1 + A[j, i] = 1 + + # compute hop steps + hop_dis = np.zeros((num_node, num_node)) + np.inf + transfer_mat = [ + np.linalg.matrix_power(A, d) for d in range(max_hop + 1) + ] + arrive_mat = (np.stack(transfer_mat) > 0) + for d in range(max_hop, -1, -1): + hop_dis[arrive_mat[d]] = d + return hop_dis + + +class Graph: + """The Graph to model the skeletons. + + Args: + layout (str): must be one of the following candidates: 'openpose', 'nturgb+d', 'coco'. Default: 'coco'. + mode (str): must be one of the following candidates: 'stgcn_spatial', 'spatial'. Default: 'spatial'. + max_hop (int): the maximal distance between two connected nodes. + Default: 1 + """ + + def __init__(self, + layout='coco', + mode='spatial', + max_hop=1): + + self.max_hop = max_hop + self.layout = layout + self.mode = mode + + assert layout in ['openpose', 'nturgb+d', 'coco'] + + self.get_layout(layout) + self.hop_dis = get_hop_distance(self.num_node, self.inward, max_hop) + + assert hasattr(self, mode), f'Do Not Exist This Mode: {mode}' + self.A = getattr(self, mode)() + + def __str__(self): + return self.A + + def get_layout(self, layout): + if layout == 'openpose': + self.num_node = 18 + self.inward = [ + (4, 3), (3, 2), (7, 6), (6, 5), (13, 12), (12, 11), (10, 9), + (9, 8), (11, 5), (8, 2), (5, 1), (2, 1), (0, 1), (15, 0), + (14, 0), (17, 15), (16, 14) + ] + self.center = 1 + elif layout == 'nturgb+d': + self.num_node = 25 + neighbor_base = [ + (1, 2), (2, 21), (3, 21), (4, 3), (5, 21), (6, 5), (7, 6), + (8, 7), (9, 21), (10, 9), (11, 10), (12, 11), (13, 1), + (14, 13), (15, 14), (16, 15), (17, 1), (18, 17), (19, 18), + (20, 19), (22, 8), (23, 8), (24, 12), (25, 12) + ] + self.inward = [(i - 1, j - 1) for (i, j) in neighbor_base] + self.center = 21 - 1 + elif layout == 'coco': + self.num_node = 17 + self.inward = [ + (15, 13), (13, 11), (16, 14), (14, 12), (11, 5), (12, 6), + (9, 7), (7, 5), (10, 8), (8, 6), (5, 0), (6, 0), + (1, 0), (3, 1), (2, 0), (4, 2) + ] + self.center = 0 + else: + raise ValueError(f'Do Not Exist This Layout: {layout}') + self.self_link = [(i, i) for i in range(self.num_node)] + self.outward = [(j, i) for (i, j) in self.inward] + self.neighbor = self.inward + self.outward + + def stgcn_spatial(self): + adj = np.zeros((self.num_node, self.num_node)) + adj[self.hop_dis <= self.max_hop] = 1 + normalize_adj = normalize_digraph(adj) + hop_dis = self.hop_dis + center = self.center + + A = [] + for hop in range(self.max_hop + 1): + a_close = np.zeros((self.num_node, self.num_node)) + a_further = np.zeros((self.num_node, self.num_node)) + for i in range(self.num_node): + for j in range(self.num_node): + if hop_dis[j, i] == hop: + if hop_dis[j, center] >= hop_dis[i, center]: + a_close[j, i] = normalize_adj[j, i] + else: + a_further[j, i] = normalize_adj[j, i] + A.append(a_close) + if hop > 0: + A.append(a_further) + return np.stack(A) + + def spatial(self): + Iden = edge2mat(self.self_link, self.num_node) + In = normalize_digraph(edge2mat(self.inward, self.num_node)) + Out = normalize_digraph(edge2mat(self.outward, self.num_node)) + A = np.stack((Iden, In, Out)) + return A diff --git a/pyskl/utils/misc.py b/pyskl/utils/misc.py new file mode 100644 index 00000000..4e328633 --- /dev/null +++ b/pyskl/utils/misc.py @@ -0,0 +1,48 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import logging +import os +import socket + +from mmcv.utils import get_logger + + +def mc_on(port=22077, launcher='pytorch', size=24000): + # size is mb, allocate 24GB memory by default. + mc_exe = 'memcached' if launcher == 'pytorch' else '/mnt/lustre/share/memcached/bin/memcached' + os.system(f'{mc_exe} -p {port} -m {size}m -d') + + +def mc_off(): + os.system('killall memcached') + + +def test_port(ip, port): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(2) + assert isinstance(ip, str) + if isinstance(port, str): + port = int(port) + assert 1 <= port <= 65535 + result = sock.connect_ex((ip, port)) + return result == 0 + + +def get_root_logger(log_file=None, log_level=logging.INFO): + """Use ``get_logger`` method in mmcv to get the root logger. + + The logger will be initialized if it has not been initialized. By default a + StreamHandler will be added. If ``log_file`` is specified, a FileHandler + will also be added. The name of the root logger is the top-level package + name, e.g., "pyskl". + + Args: + log_file (str | None): The log filename. If specified, a FileHandler + will be added to the root logger. + log_level (int): The root logger level. Note that only the process of + rank 0 is affected, while other processes will set the level to + "Error" and be silent most of the time. + + Returns: + :obj:`logging.Logger`: The root logger. + """ + return get_logger(__name__.split('.')[0], log_file, log_level) diff --git a/pyskl/utils/visualize.py b/pyskl/utils/visualize.py new file mode 100644 index 00000000..de181350 --- /dev/null +++ b/pyskl/utils/visualize.py @@ -0,0 +1,143 @@ +import io + +import cv2 +import decord +import matplotlib.pyplot as plt +import moviepy.editor as mpy +import numpy as np +from mmcv import load +from tqdm import tqdm + + +class Vis3DPose: + + def __init__(self, item, layout='nturgb+d', fps=12, angle=(30, 45), fig_size=(8, 8), dpi=80): + kp = item['keypoint'] + self.kp = kp + assert self.kp.shape[-1] == 3 + self.layout = layout + self.fps = fps + self.angle = angle # For 3D data only + self.colors = ('#3498db', '#000000', '#e74c3c') # l, m, r + self.fig_size = fig_size + self.dpi = dpi + + assert layout == 'nturgb+d' + if self.layout == 'nturgb+d': + self.num_joint = 25 + self.links = np.array([ + (1, 2), (2, 21), (3, 21), (4, 3), (5, 21), (6, 5), + (7, 6), (8, 7), (9, 21), (10, 9), (11, 10), (12, 11), + (13, 1), (14, 13), (15, 14), (16, 15), (17, 1), (18, 17), + (19, 18), (20, 19), (22, 8), (23, 8), (24, 12), (25, 12)], dtype=np.int) - 1 + self.left = np.array([5, 6, 7, 8, 13, 14, 15, 16, 22, 23], dtype=np.int) - 1 + self.right = np.array([9, 10, 11, 12, 17, 18, 19, 20, 24, 25], dtype=np.int) - 1 + self.num_link = len(self.links) + self.limb_tag = [1] * self.num_link + + for i, link in enumerate(self.links): + if link[0] in self.left or link[1] in self.left: + self.limb_tag[i] = 0 + elif link[0] in self.right or link[1] in self.right: + self.limb_tag[i] = 2 + + assert len(kp.shape) == 4 and kp.shape[3] == 3 and kp.shape[2] == self.num_joint + x, y, z = kp[..., 0], kp[..., 1], kp[..., 2] + + min_x, max_x = min(x[x != 0]), max(x[x != 0]) + min_y, max_y = min(y[y != 0]), max(y[y != 0]) + min_z, max_z = min(z[z != 0]), max(z[z != 0]) + max_axis = max(max_x - min_x, max_y - min_y, max_z - min_z) + mid_x, mid_y, mid_z = (min_x + max_x) / 2, (min_y + max_y) / 2, (min_z + max_z) / 2 + self.min_x, self.max_x = mid_x - max_axis / 2, mid_x + max_axis / 2 + self.min_y, self.max_y = mid_y - max_axis / 2, mid_y + max_axis / 2 + self.min_z, self.max_z = mid_z - max_axis / 2, mid_z + max_axis / 2 + + self.images = [] + + def get_img(self, dpi=80): + buf = io.BytesIO() + plt.savefig(buf, format='png', dpi=dpi) + buf.seek(0) + img = np.frombuffer(buf.getvalue(), dtype=np.uint8) + buf.close() + return cv2.imdecode(img, -1) + + def vis(self): + self.images = [] + plt.figure(figsize=self.fig_size) + for t in range(self.kp.shape[1]): + ax = plt.gca(projection='3d') + ax.set_xlim3d([self.min_x, self.max_x]) + ax.set_ylim3d([self.min_y, self.max_y]) + ax.set_zlim3d([self.min_z, self.max_z]) + ax.view_init(*self.angle) + ax.set_aspect('auto') + for i in range(self.num_link): + for m in range(self.kp.shape[0]): + link = self.links[i] + color = self.colors[self.limb_tag[i]] + j1, j2 = self.kp[m, t, link[0]], self.kp[m, t, link[1]] + if not ((np.allclose(j1, 0) or np.allclose(j2, 0)) and link[0] != 1 and link[1] != 1): + ax.plot([j1[0], j2[0]], [j1[1], j2[1]], [j1[2], j2[2]], lw=1, c=color) + self.images.append(self.get_img(dpi=self.dpi)) + ax.cla() + return mpy.ImageSequenceClip(self.images, fps=self.fps) + + +def Vis2DPose(item, thre=0.2, out_shape=(540, 960), layout='coco', fps=24, video=None): + if isinstance(item, str): + item = load(item) + + assert layout == 'coco' + + kp = item['keypoint'] + if 'keypoint_score' in item: + kpscore = item['keypoint_score'] + kp = np.concatenate([kp, kpscore[..., None]], -1) + + assert kp.shape[-1] == 3 + img_shape = item.get('img_shape', out_shape) + kp[..., 0] *= out_shape[1] / img_shape[1] + kp[..., 1] *= out_shape[0] / img_shape[0] + + total_frames = item.get('total_frames', kp.shape[1]) + assert total_frames == kp.shape[1] + + if video is None: + frames = [np.ones([out_shape[0], out_shape[1], 3], dtype=np.uint8) * 255 for i in range(total_frames)] + else: + vid = decord.VideoReader(video) + frames = [x.asnumpy() for x in vid] + frames = [cv2.resize(x, (out_shape[1], out_shape[0])) for x in frames] + if len(frames) != total_frames: + frames = [frames[int(i / total_frames * len(frames))] for i in range(total_frames)] + + if layout == 'coco': + edges = [ + (0, 1, 'f'), (0, 2, 'f'), (1, 3, 'f'), (2, 4, 'f'), (0, 5, 't'), (0, 6, 't'), + (5, 7, 'ru'), (6, 8, 'lu'), (7, 9, 'ru'), (8, 10, 'lu'), (5, 11, 't'), (6, 12, 't'), + (11, 13, 'ld'), (12, 14, 'rd'), (13, 15, 'ld'), (14, 16, 'rd') + ] + color_map = { + 'ru': ((0, 0x96, 0xc7), (0x3, 0x4, 0x5e)), + 'rd': ((0xca, 0xf0, 0xf8), (0x48, 0xca, 0xe4)), + 'lu': ((0x9d, 0x2, 0x8), (0x3, 0x7, 0x1e)), + 'ld': ((0xff, 0xba, 0x8), (0xe8, 0x5d, 0x4)), + 't': ((0xee, 0x8b, 0x98), (0xd9, 0x4, 0x29)), + 'f': ((0x8d, 0x99, 0xae), (0x2b, 0x2d, 0x42))} + + for i in tqdm(range(total_frames)): + for m in range(kp.shape[0]): + ske = kp[m, i] + for e in edges: + st, ed, co = e + co_tup = color_map[co] + j1, j2 = ske[st], ske[ed] + j1x, j1y, j2x, j2y = int(j1[0]), int(j1[1]), int(j2[0]), int(j2[1]) + conf = min(j1[2], j2[2]) + if conf > thre: + color = [x + (y - x) * (conf - thre) / 0.8 for x, y in zip(co_tup[0], co_tup[1])] + color = tuple([int(x) for x in color]) + frames[i] = cv2.line(frames[i], (j1x, j1y), (j2x, j2y), color, thickness=2) + return mpy.ImageSequenceClip(frames, fps=fps) diff --git a/pyskl/version.py b/pyskl/version.py new file mode 100644 index 00000000..275595c2 --- /dev/null +++ b/pyskl/version.py @@ -0,0 +1,18 @@ +# Copyright (c) Open-MMLab. All rights reserved. + +__version__ = '0.1.0' + + +def parse_version_info(version_str): + version_info = [] + for x in version_str.split('.'): + if x.isdigit(): + version_info.append(int(x)) + elif x.find('rc') != -1: + patch_version = x.split('rc') + version_info.append(int(patch_version[0])) + version_info.append(f'rc{patch_version[1]}') + return tuple(version_info) + + +version_info = parse_version_info(__version__) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..a3f953ee --- /dev/null +++ b/requirements.txt @@ -0,0 +1,10 @@ +decord>=0.6.0 +matplotlib +mmcv +moviepy +numpy>=1.19.5 +opencv-contrib-python +opencv-python +scipy +torch>=1.5 +tqdm diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..7309a8d5 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,24 @@ +[bdist_wheel] +universal=1 + +[aliases] +test=pytest + +[tool:pytest] +addopts=tests/ + +[yapf] +based_on_style = pep8 +blank_line_before_nested_class_or_def = true +split_before_expression_after_opening_paren = true +split_penalty_import_names=0 +SPLIT_PENALTY_AFTER_OPENING_BRACKET=800 + +[isort] +line_length = 119 +multi_line_output = 0 +known_standard_library = pkg_resources,setuptools +known_first_party = pyskl +known_third_party = cv2,decord,matplotlib,mmcv,moviepy,numpy,requests,torch,tqdm +no_lines_before = STDLIB,LOCALFOLDER +default_section = THIRDPARTY diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..c4b0b357 --- /dev/null +++ b/setup.py @@ -0,0 +1,127 @@ +# Copyright (c) OpenMMLab. All rights reserved. +# test doublepush +import re +import sys +from os.path import exists +from setuptools import find_packages, setup + + +def readme(): + with open('README.md', encoding='utf-8') as f: + content = f.read() + return content + + +version_file = 'pyskl/version.py' + + +def get_version(): + with open(version_file, 'r') as f: + exec(compile(f.read(), version_file, 'exec')) + return locals()['__version__'] + + +def parse_requirements(fname='requirements.txt', with_version=True): + """Parse the package dependencies listed in a requirements file but strips + specific versioning information. + + Args: + fname (str): path to requirements file + with_version (bool, default=False): if True include version specs + + Returns: + List[str]: list of requirements items + + CommandLine: + python -c "import setup; print(setup.parse_requirements())" + """ + + require_fpath = fname + + def parse_line(line): + """Parse information from a line in a requirements text file.""" + if line.startswith('-r '): + # Allow specifying requirements in other files + target = line.split(' ')[1] + for info in parse_require_file(target): + yield info + else: + info = {'line': line} + if line.startswith('-e '): + info['package'] = line.split('#egg=')[1] + elif '@git+' in line: + info['package'] = line + else: + # Remove versioning from the package + pat = '(' + '|'.join(['>=', '==', '>']) + ')' + parts = re.split(pat, line, maxsplit=1) + parts = [p.strip() for p in parts] + + info['package'] = parts[0] + if len(parts) > 1: + op, rest = parts[1:] + if ';' in rest: + # Handle platform specific dependencies + # http://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-platform-specific-dependencies + version, platform_deps = map(str.strip, + rest.split(';')) + info['platform_deps'] = platform_deps + else: + version = rest # NOQA + info['version'] = (op, version) + yield info + + def parse_require_file(fpath): + with open(fpath, 'r') as f: + for line in f.readlines(): + line = line.strip() + if line and not line.startswith('#'): + for info in parse_line(line): + yield info + + def gen_packages_items(): + if exists(require_fpath): + for info in parse_require_file(require_fpath): + parts = [info['package']] + if with_version and 'version' in info: + parts.extend(info['version']) + if not sys.version.startswith('3.4'): + # apparently package_deps are broken in 3.4 + platform_deps = info.get('platform_deps') + if platform_deps is not None: + parts.append(';' + platform_deps) + item = ''.join(parts) + yield item + + packages = list(gen_packages_items()) + return packages + + +if __name__ == '__main__': + setup( + name='pyskl', + version=get_version(), + description='A Toolbox for skeleton-based action recognition', + long_description=readme(), + long_description_content_type='text/markdown', + author='Haodong Duan', + author_email='dhd.efz@gmail.com', + maintainer='Haodong Duan', + maintainer_email='dhd.efz@gmail.com', + packages=find_packages(exclude=('configs', 'tools', 'demo')), + keywords='computer vision, video understanding', + include_package_data=True, + classifiers=[ + 'Development Status :: 4 - Beta', + 'License :: OSI Approved :: Apache Software License', + 'Operating System :: OS Independent', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + ], + url='https://github.com/kennymckormick/pyskl', + license='Apache License 2.0', + install_requires=parse_requirements('requirement.txt'), + zip_safe=False) diff --git a/tools/data_list.md b/tools/data_list.md new file mode 100644 index 00000000..23e6a321 --- /dev/null +++ b/tools/data_list.md @@ -0,0 +1,59 @@ +# Download the Pre-processed Skeletons + +We provide links to the pre-processed skeleton annotations, you can directly download them and use them for training & testing. + +- NTURGB+D [2D Skeleton]: https://download.openmmlab.com/mmaction/pyskl/data/nturgbd/ntu60_hrnet.pkl +- NTURGB+D [3D Skeleton]: https://download.openmmlab.com/mmaction/pyskl/data/nturgbd/ntu60_3danno.pkl +- NTURGB+D 120 [2D Skeleton]: https://download.openmmlab.com/mmaction/pyskl/data/nturgbd/ntu120_hrnet.pkl +- NTURGB+D 120 [3D Skeleton]: https://download.openmmlab.com/mmaction/pyskl/data/nturgbd/ntu120_3danno.pkl +- GYM [2D Skeleton]: https://download.openmmlab.com/mmaction/pyskl/data/gym/gym_hrnet.pkl +- UCF101 [2D Skeleton]: https://download.openmmlab.com/mmaction/pyskl/data/ucf101/ucf101_hrnet.pkl +- HMDB51 [2D Skeleton]: https://download.openmmlab.com/mmaction/pyskl/data/hmdb51/hmdb51_hrnet.pkl + +Here are the BibTex items for each dataset: + +```BibTex +% NTURGB+D +@inproceedings{shahroudy2016ntu, + title={Ntu rgb+ d: A large scale dataset for 3d human activity analysis}, + author={Shahroudy, Amir and Liu, Jun and Ng, Tian-Tsong and Wang, Gang}, + booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition}, + pages={1010--1019}, + year={2016} +} +% NTURGB+D 120 +@article{liu2019ntu, + title={Ntu rgb+ d 120: A large-scale benchmark for 3d human activity understanding}, + author={Liu, Jun and Shahroudy, Amir and Perez, Mauricio and Wang, Gang and Duan, Ling-Yu and Kot, Alex C}, + journal={IEEE transactions on pattern analysis and machine intelligence}, + volume={42}, + number={10}, + pages={2684--2701}, + year={2019}, + publisher={IEEE} +} +% GYM +@inproceedings{shao2020finegym, + title={Finegym: A hierarchical video dataset for fine-grained action understanding}, + author={Shao, Dian and Zhao, Yue and Dai, Bo and Lin, Dahua}, + booktitle={Proceedings of the IEEE/CVF conference on computer vision and pattern recognition}, + pages={2616--2625}, + year={2020} +} +% UCF101 +@article{soomro2012ucf101, + title={UCF101: A dataset of 101 human actions classes from videos in the wild}, + author={Soomro, Khurram and Zamir, Amir Roshan and Shah, Mubarak}, + journal={arXiv preprint arXiv:1212.0402}, + year={2012} +} +% HMDB51 +@inproceedings{kuehne2011hmdb, + title={HMDB: a large video database for human motion recognition}, + author={Kuehne, Hildegard and Jhuang, Hueihan and Garrote, Est{\'\i}baliz and Poggio, Tomaso and Serre, Thomas}, + booktitle={2011 International conference on computer vision}, + pages={2556--2563}, + year={2011}, + organization={IEEE} +} +``` diff --git a/tools/dist_test.sh b/tools/dist_test.sh new file mode 100644 index 00000000..bf321bc3 --- /dev/null +++ b/tools/dist_test.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +CONFIG=$1 +CHECKPOINT=$2 +GPUS=$3 +PORT=${PORT:-29500} + +MKL_SERVICE_FORCE_INTEL=1 PYTHONPATH="$(dirname $0)/..":$PYTHONPATH \ +# Arguments starting from the forth one are captured by ${@:4} +python -m torch.distributed.launch --nproc_per_node=$GPUS --master_port=$PORT \ + $(dirname "$0")/test.py $CONFIG -C $CHECKPOINT --launcher pytorch ${@:4} diff --git a/tools/dist_train.sh b/tools/dist_train.sh new file mode 100644 index 00000000..be416939 --- /dev/null +++ b/tools/dist_train.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +CONFIG=$1 +GPUS=$2 +PORT=${PORT:-29500} + +MKL_SERVICE_FORCE_INTEL=1 PYTHONPATH="$(dirname $0)/..":$PYTHONPATH \ +python -m torch.distributed.launch --nproc_per_node=$GPUS --master_port=$PORT \ + $(dirname "$0")/train.py $CONFIG --launcher pytorch ${@:3} +# Any arguments from the third one are captured by ${@:3} diff --git a/tools/slurm_test.sh b/tools/slurm_test.sh new file mode 100644 index 00000000..fdea5da7 --- /dev/null +++ b/tools/slurm_test.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +set -x + +PARTITION=$1 +JOB_NAME=$2 +CONFIG=$3 +CHECKPOINT=$4 +GPUS=${GPUS:-8} +GPUS_PER_NODE=${GPUS_PER_NODE:-8} +CPUS_PER_TASK=${CPUS_PER_TASK:-5} +PY_ARGS=${@:5} # Arguments starting from the fifth one are captured +SRUN_ARGS=${SRUN_ARGS:-""} + +PYTHONPATH="$(dirname $0)/..":$PYTHONPATH \ +srun -p ${PARTITION} \ + --job-name=${JOB_NAME} \ + --gres=gpu:${GPUS_PER_NODE} \ + --ntasks=${GPUS} \ + --ntasks-per-node=${GPUS_PER_NODE} \ + --cpus-per-task=${CPUS_PER_TASK} \ + --kill-on-bad-exit=1 \ + ${SRUN_ARGS} \ + python -u tools/test.py ${CONFIG} ${CHECKPOINT} --launcher="slurm" ${PY_ARGS} diff --git a/tools/slurm_train.sh b/tools/slurm_train.sh new file mode 100644 index 00000000..2cff8aae --- /dev/null +++ b/tools/slurm_train.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +export MASTER_PORT=$((12000 + $RANDOM % 20000)) +set -x + +PARTITION=$1 +JOB_NAME=$2 +CONFIG=$3 +GPUS=${GPUS:-8} +GPUS_PER_NODE=${GPUS_PER_NODE:-8} +CPUS_PER_TASK=${CPUS_PER_TASK:-5} +SRUN_ARGS=${SRUN_ARGS:-""} +PY_ARGS=${@:4} # Any arguments from the forth one are captured by this + +PYTHONPATH="$(dirname $0)/..":$PYTHONPATH \ +srun -p ${PARTITION} \ + --job-name=${JOB_NAME} \ + --gres=gpu:${GPUS_PER_NODE} \ + --ntasks=${GPUS} \ + --ntasks-per-node=${GPUS_PER_NODE} \ + --cpus-per-task=${CPUS_PER_TASK} \ + --kill-on-bad-exit=1 \ + ${SRUN_ARGS} \ + python -u tools/train.py ${CONFIG} --launcher="slurm" ${PY_ARGS} diff --git a/tools/test.py b/tools/test.py new file mode 100644 index 00000000..ffa48b6c --- /dev/null +++ b/tools/test.py @@ -0,0 +1,221 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import argparse +import os +import os.path as osp +import time +import warnings + +import mmcv +import torch +import torch.distributed as dist +from mmcv import Config, DictAction, load +from mmcv.cnn import fuse_conv_bn +from mmcv.engine import multi_gpu_test +from mmcv.fileio.io import file_handlers +from mmcv.parallel import MMDistributedDataParallel +from mmcv.runner import get_dist_info, init_dist, load_checkpoint + +from pyskl.datasets import build_dataloader, build_dataset +from pyskl.models import build_model +from pyskl.utils import mc_off, mc_on, test_port + + +def parse_args(): + parser = argparse.ArgumentParser( + description='pyskl test (and eval) a model') + parser.add_argument('config', help='test config file path') + parser.add_argument('-C', '--checkpoint', help='checkpoint file', default=None) + parser.add_argument( + '--out', + default=None, + help='output result file in pkl/yaml/json format') + parser.add_argument( + '--fuse-conv-bn', + action='store_true', + help='Whether to fuse conv and bn, this will slightly increase' + 'the inference speed') + parser.add_argument( + '--eval', + type=str, + nargs='+', + default=['top_k_accuracy', 'mean_class_accuracy'], + help='evaluation metrics, which depends on the dataset, e.g.,' + ' "top_k_accuracy", "mean_class_accuracy" for video dataset') + parser.add_argument( + '--gpu-collect', + action='store_true', + help='whether to use gpu to collect results') + parser.add_argument( + '--tmpdir', + help='tmp directory used for collecting results from multiple ' + 'workers, available when gpu-collect is not specified') + parser.add_argument( + '--options', + nargs='+', + action=DictAction, + default={}, + help='custom options for evaluation, the key-value pair in xxx=yyy ' + 'format will be kwargs for dataset.evaluate() function (deprecate), ' + 'change to --eval-options instead.') + parser.add_argument( + '--eval-options', + nargs='+', + action=DictAction, + default={}, + help='custom options for evaluation, the key-value pair in xxx=yyy ' + 'format will be kwargs for dataset.evaluate() function') + parser.add_argument( + '--average-clips', + choices=['score', 'prob', None], + default=None, + help='average type when averaging test clips') + parser.add_argument( + '--launcher', + choices=['pytorch', 'slurm'], + default='pytorch', + help='job launcher') + parser.add_argument('--local_rank', type=int, default=0) + args = parser.parse_args() + if 'LOCAL_RANK' not in os.environ: + os.environ['LOCAL_RANK'] = str(args.local_rank) + + if args.options and args.eval_options: + raise ValueError( + '--options and --eval-options cannot be both ' + 'specified, --options is deprecated in favor of --eval-options') + if args.options: + warnings.warn('--options is deprecated in favor of --eval-options') + args.eval_options = args.options + return args + + +def inference_pytorch(args, cfg, data_loader): + """Get predictions by pytorch models.""" + if args.average_clips is not None: + # You can set average_clips during testing, it will override the + # original setting + if cfg.model.get('test_cfg') is None and cfg.get('test_cfg') is None: + cfg.model.setdefault('test_cfg', + dict(average_clips=args.average_clips)) + else: + if cfg.model.get('test_cfg') is not None: + cfg.model.test_cfg.average_clips = args.average_clips + else: + cfg.test_cfg.average_clips = args.average_clips + + # build the model and load checkpoint + model = build_model(cfg.model) + + if args.checkpoint is None: + work_dir = cfg.work_dir + args.checkpoint = osp.join(work_dir, 'latest.pth') + + load_checkpoint(model, args.checkpoint, map_location='cpu') + + if args.fuse_conv_bn: + model = fuse_conv_bn(model) + + model = MMDistributedDataParallel( + model.cuda(), + device_ids=[torch.cuda.current_device()], + broadcast_buffers=False) + outputs = multi_gpu_test(model, data_loader, args.tmpdir, args.gpu_collect) + + return outputs + + +def main(): + args = parse_args() + + cfg = Config.fromfile(args.config) + + out = osp.join(cfg.work_dir, 'result.pkl') if args.out is None else args.out + + # Load eval_config from cfg + eval_cfg = cfg.get('evaluation', {}) + keys = ['interval', 'tmpdir', 'start', 'gpu_collect', 'save_best', 'rule', 'by_epoch', 'broadcast_bn_buffers'] + for key in keys: + eval_cfg.pop(key, None) + if args.eval: + eval_cfg['metrics'] = args.eval + + dataset_type = cfg.data.test.type + + mmcv.mkdir_or_exist(osp.dirname(out)) + _, suffix = osp.splitext(out) + if dataset_type == 'AVADataset': + assert suffix[1:] == 'csv', ('For AVADataset, the format of the output file should be csv') + else: + assert suffix[1:] in file_handlers, ('The format of the output file should be json, pickle or yaml') + + # set cudnn benchmark + if cfg.get('cudnn_benchmark', False): + torch.backends.cudnn.benchmark = True + cfg.data.test.test_mode = True + + if not hasattr(cfg, 'dist_params'): + cfg.dist_params = dict(backend='nccl') + + init_dist(args.launcher, **cfg.dist_params) + rank, world_size = get_dist_info() + cfg.gpu_ids = range(world_size) + + # build the dataloader + dataset = build_dataset(cfg.data.test, dict(test_mode=True)) + dataloader_setting = dict( + videos_per_gpu=cfg.data.get('videos_per_gpu', 1), + workers_per_gpu=cfg.data.get('workers_per_gpu', 1), + shuffle=False) + dataloader_setting = dict(dataloader_setting, **cfg.data.get('test_dataloader', {})) + data_loader = build_dataloader(dataset, **dataloader_setting) + + so_keys, cli = set(), None + if rank == 0: + mc_list = cfg.get('mc_list', None) + if mc_list is not None: + mc_cfg = cfg.get('mc_cfg', ('localhost', 11211)) + assert isinstance(mc_cfg, tuple) and mc_cfg[0] == 'localhost' + if not test_port(mc_cfg[0], mc_cfg[1]): + mc_on(port=mc_cfg[1], launcher=args.launcher) + retry = 3 + while not test_port(mc_cfg[0], mc_cfg[1]) and retry > 0: + time.sleep(5) + retry -= 1 + assert retry >= 0, 'Failed to launch memcached. ' + assert isinstance(mc_list, list) + from pymemcache.client.base import Client + from pymemcache import serde + cli = Client(mc_cfg, serde=serde.pickle_serde) + for data_file in mc_list: + assert osp.exists(data_file) + kv_dict = load(data_file) + if isinstance(kv_dict, list): + assert ('frame_dir' in kv_dict[0]) != ('filename' in kv_dict[0]) + key = 'frame_dir' if 'frame_dir' in kv_dict[0] else 'filename' + kv_dict = {x[key]: x for x in kv_dict} + for k, v in kv_dict.items(): + assert k not in so_keys + cli.set(k, v) + so_keys.add(k) + dist.barrier() + + outputs = inference_pytorch(args, cfg, data_loader) + + rank, _ = get_dist_info() + if rank == 0: + print(f'\nwriting results to {out}') + dataset.dump_results(outputs, out=out) + if eval_cfg: + eval_res = dataset.evaluate(outputs, **eval_cfg) + for name, val in eval_res.items(): + print(f'{name}: {val:.04f}') + + dist.barrier() + if rank == 0 and cli is not None: + for k in so_keys: + cli.delete(k) + mc_off() + + +if __name__ == '__main__': + main() diff --git a/tools/train.py b/tools/train.py new file mode 100644 index 00000000..548db17d --- /dev/null +++ b/tools/train.py @@ -0,0 +1,178 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import argparse +import os +import os.path as osp +import time + +import mmcv +import torch +import torch.distributed as dist +from mmcv import Config, load +from mmcv.runner import get_dist_info, init_dist, set_random_seed +from mmcv.utils import get_git_hash + +from pyskl import __version__ +from pyskl.apis import init_random_seed, train_model +from pyskl.datasets import build_dataset +from pyskl.models import build_model +from pyskl.utils import collect_env, get_root_logger, mc_off, mc_on, test_port + + +def parse_args(): + parser = argparse.ArgumentParser(description='Train a recognizer') + parser.add_argument('config', help='train config file path') + parser.add_argument('--work-dir', help='the dir to save logs and models') + parser.add_argument( + '--validate', + action='store_true', + help='whether to evaluate the checkpoint during training') + parser.add_argument( + '--test-last', + action='store_true', + help='whether to test the checkpoint after training') + parser.add_argument( + '--test-best', + action='store_true', + help=('whether to test the best checkpoint (if applicable) after ' + 'training')) + parser.add_argument('--seed', type=int, default=None, help='random seed') + parser.add_argument( + '--deterministic', + action='store_true', + help='whether to set deterministic options for CUDNN backend.') + parser.add_argument( + '--launcher', + choices=['pytorch', 'slurm'], + default='pytorch', + help='job launcher') + parser.add_argument('--local_rank', type=int, default=0) + args = parser.parse_args() + if 'LOCAL_RANK' not in os.environ: + os.environ['LOCAL_RANK'] = str(args.local_rank) + + return args + + +def main(): + args = parse_args() + + cfg = Config.fromfile(args.config) + + # set cudnn_benchmark + if cfg.get('cudnn_benchmark', False): + torch.backends.cudnn.benchmark = True + + # work_dir is determined in this priority: + # CLI > config file > default (base filename) + if args.work_dir is not None: + # update configs according to CLI args if args.work_dir is not None + cfg.work_dir = args.work_dir + elif cfg.get('work_dir', None) is None: + # use config filename as default work_dir if cfg.work_dir is None + cfg.work_dir = osp.join('./work_dirs', osp.splitext(osp.basename(args.config))[0]) + + if not hasattr(cfg, 'dist_params'): + cfg.dist_params = dict(backend='nccl') + + init_dist(args.launcher, **cfg.dist_params) + rank, world_size = get_dist_info() + cfg.gpu_ids = range(world_size) + + # create work_dir + mmcv.mkdir_or_exist(osp.abspath(cfg.work_dir)) + # dump config + cfg.dump(osp.join(cfg.work_dir, osp.basename(args.config))) + # init logger before other steps + timestamp = time.strftime('%Y%m%d_%H%M%S', time.localtime()) + log_file = osp.join(cfg.work_dir, f'{timestamp}.log') + logger = get_root_logger(log_file=log_file, log_level=cfg.log_level) + + # init the meta dict to record some important information such as + # environment info and seed, which will be logged + meta = dict() + # log env info + env_info_dict = collect_env() + env_info = '\n'.join([f'{k}: {v}' for k, v in env_info_dict.items()]) + dash_line = '-' * 60 + '\n' + logger.info('Environment info:\n' + dash_line + env_info + '\n' + + dash_line) + meta['env_info'] = env_info + + # log some basic info + logger.info(f'Config: {cfg.pretty_text}') + + # set random seeds + seed = init_random_seed(args.seed) + logger.info(f'Set random seed to {seed}, deterministic: {args.deterministic}') + set_random_seed(seed, deterministic=args.deterministic) + + cfg.seed = seed + meta['seed'] = seed + meta['config_name'] = osp.basename(args.config) + meta['work_dir'] = osp.basename(cfg.work_dir.rstrip('/\\')) + + model = build_model(cfg.model) + + datasets = [build_dataset(cfg.data.train)] + + cfg.workflow = cfg.get('workflow', [('train', 1)]) + assert len(cfg.workflow) == 1 + if cfg.checkpoint_config is not None: + # save pyskl version, config file content and class names in + # checkpoints as meta data + cfg.checkpoint_config.meta = dict( + pyskl_version=__version__ + get_git_hash(digits=7), + tag=['nturgb+d graph changed', 'scale A > 1 in training, unchanged in testing'], + config=cfg.pretty_text) + + test_option = dict(test_last=args.test_last, test_best=args.test_best) + + # We need to write the keys into memcache + so_keys, cli = set(), None + if rank == 0: + mc_list = cfg.get('mc_list', None) + if mc_list is not None: + mc_cfg = cfg.get('mc_cfg', ('localhost', 11211)) + assert isinstance(mc_cfg, tuple) and mc_cfg[0] == 'localhost' + if not test_port(mc_cfg[0], mc_cfg[1]): + mc_on(port=mc_cfg[1], launcher=args.launcher) + retry = 3 + while not test_port(mc_cfg[0], mc_cfg[1]) and retry > 0: + time.sleep(5) + retry -= 1 + assert retry >= 0, 'Failed to launch memcached. ' + assert isinstance(mc_list, list) + from pymemcache.client.base import Client + from pymemcache import serde + cli = Client(mc_cfg, serde=serde.pickle_serde) + for data_file in mc_list: + assert osp.exists(data_file) + kv_dict = load(data_file) + if isinstance(kv_dict, list): + assert ('frame_dir' in kv_dict[0]) != ('filename' in kv_dict[0]) + key = 'frame_dir' if 'frame_dir' in kv_dict[0] else 'filename' + kv_dict = {x[key]: x for x in kv_dict} + for k, v in kv_dict.items(): + assert k not in so_keys + cli.set(k, v) + so_keys.add(k) + dist.barrier() + + train_model( + model, + datasets, + cfg, + validate=args.validate, + test=test_option, + timestamp=timestamp, + meta=meta) + + dist.barrier() + if rank == 0 and cli is not None: + for k in so_keys: + cli.delete(k) + mc_off() + + +if __name__ == '__main__': + main()