From cd340c210e305259133bbdc8d8780541d15e31f4 Mon Sep 17 00:00:00 2001 From: Hacker 17082006 Date: Sun, 31 Mar 2024 15:46:19 +0700 Subject: [PATCH] Add 4DHuman --- __init__.py | 20 +- mogen/smpl/render_mesh.py | 2 - motiondiff_modules/__init__.py | 0 motiondiff_modules/hmr2/README.md | 107 ++ motiondiff_modules/hmr2/__init__.py | 0 motiondiff_modules/hmr2/configs/__init__.py | 116 ++ .../cascade_mask_rcnn_vitdet_h_75ep.py | 129 ++ .../hmr2/configs/datasets_eval.yaml | 31 + .../hmr2/configs/datasets_tar.yaml | 38 + .../hmr2/configs_hydra/data/mix_all.yaml | 27 + .../configs_hydra/data_filtering/low1.yaml | 13 + .../configs_hydra/experiment/default.yaml | 29 + .../experiment/hmr_vit_transformer.yaml | 51 + .../hmr2/configs_hydra/extras/default.yaml | 8 + .../hmr2/configs_hydra/hydra/default.yaml | 26 + .../hmr2/configs_hydra/launcher/local.yaml | 13 + .../hmr2/configs_hydra/launcher/slurm.yaml | 22 + .../hmr2/configs_hydra/paths/default.yaml | 18 + .../hmr2/configs_hydra/train.yaml | 47 + .../hmr2/configs_hydra/trainer/cpu.yaml | 6 + .../hmr2/configs_hydra/trainer/ddp.yaml | 14 + .../hmr2/configs_hydra/trainer/default.yaml | 10 + .../configs_hydra/trainer/default_hmr.yaml | 8 + .../hmr2/configs_hydra/trainer/gpu.yaml | 6 + .../hmr2/configs_hydra/trainer/mps.yaml | 6 + motiondiff_modules/hmr2/datasets/__init__.py | 88 ++ motiondiff_modules/hmr2/datasets/dataset.py | 27 + .../hmr2/datasets/image_dataset.py | 454 ++++++ .../hmr2/datasets/mocap_dataset.py | 25 + .../hmr2/datasets/preprocess/lspet_to_npz.py | 74 + .../datasets/preprocess/posetrack_to_npz.py | 92 ++ .../hmr2/datasets/smplh_prob_filter.py | 154 ++ motiondiff_modules/hmr2/datasets/utils.py | 1025 +++++++++++++ .../hmr2/datasets/vitdet_dataset.py | 88 ++ motiondiff_modules/hmr2/models/__init__.py | 90 ++ .../hmr2/models/backbones/__init__.py | 7 + .../hmr2/models/backbones/vit.py | 348 +++++ .../hmr2/models/backbones/vit_vitpose.py | 17 + .../hmr2/models/components/__init__.py | 0 .../models/components/pose_transformer.py | 358 +++++ .../hmr2/models/components/t_cond_mlp.py | 199 +++ .../hmr2/models/discriminator.py | 99 ++ .../hmr2/models/heads/__init__.py | 1 + .../hmr2/models/heads/smpl_head.py | 111 ++ motiondiff_modules/hmr2/models/hmr2_arch.py | 355 +++++ motiondiff_modules/hmr2/models/losses.py | 92 ++ .../hmr2/models/smpl_wrapper.py | 41 + motiondiff_modules/hmr2/utils/__init__.py | 25 + motiondiff_modules/hmr2/utils/download.py | 67 + motiondiff_modules/hmr2/utils/geometry.py | 102 ++ .../hmr2/utils/mesh_renderer.py | 149 ++ motiondiff_modules/hmr2/utils/misc.py | 203 +++ motiondiff_modules/hmr2/utils/pck_accuracy.py | 94 ++ motiondiff_modules/hmr2/utils/pose_utils.py | 310 ++++ motiondiff_modules/hmr2/utils/pylogger.py | 17 + .../hmr2/utils/render_openpose.py | 149 ++ motiondiff_modules/hmr2/utils/renderer.py | 399 +++++ motiondiff_modules/hmr2/utils/rich_utils.py | 105 ++ .../hmr2/utils/skeleton_renderer.py | 122 ++ .../hmr2/utils/texture_utils.py | 85 ++ .../hmr2/utils/utils_detectron2.py | 93 ++ motiondiff_modules/mGPT/__init__.py | 0 motiondiff_modules/mGPT/archs/__init__.py | 0 motiondiff_modules/mGPT/archs/mgpt_lm.py | 592 ++++++++ motiondiff_modules/mGPT/archs/mgpt_vq.py | 190 +++ .../mGPT/archs/tm2t_evaluator.py | 111 ++ .../mGPT/archs/tools/embeddings.py | 322 +++++ .../mGPT/archs/tools/quantize_cnn.py | 414 ++++++ motiondiff_modules/mGPT/archs/tools/resnet.py | 82 ++ .../mGPT/archs/tools/token_emb.py | 73 + .../mGPT/archs/tools/transformer_layers.py | 285 ++++ motiondiff_modules/mGPT/callback.py | 200 +++ motiondiff_modules/mGPT/config.py | 217 +++ .../mGPT/configs/inference.yaml | 175 +++ motiondiff_modules/mGPT/data/HumanML3D.py | 118 ++ motiondiff_modules/mGPT/data/Kit.py | 88 ++ motiondiff_modules/mGPT/data/__init__.py | 103 ++ motiondiff_modules/mGPT/data/build_data.py | 15 + .../mGPT/data/humanml/README.md | 1 + .../mGPT/data/humanml/__init__.py | 7 + .../mGPT/data/humanml/common/quaternion.py | 423 ++++++ .../mGPT/data/humanml/common/skeleton.py | 199 +++ .../mGPT/data/humanml/dataset_m.py | 156 ++ .../mGPT/data/humanml/dataset_m_vq.py | 54 + .../mGPT/data/humanml/dataset_t2m.py | 211 +++ .../mGPT/data/humanml/dataset_t2m_cb.py | 211 +++ .../mGPT/data/humanml/dataset_t2m_eval.py | 92 ++ .../mGPT/data/humanml/dataset_t2m_m2t.py | 119 ++ .../mGPT/data/humanml/dataset_t2m_token.py | 86 ++ .../data/humanml/scripts/motion_process.py | 529 +++++++ .../mGPT/data/humanml/utils/paramUtil.py | 63 + .../data/humanml/utils/word_vectorizer.py | 79 + motiondiff_modules/mGPT/data/mean.npy | Bin 0 -> 2232 bytes motiondiff_modules/mGPT/data/mean_eval.npy | Bin 0 -> 2232 bytes motiondiff_modules/mGPT/data/std.npy | Bin 0 -> 2232 bytes motiondiff_modules/mGPT/data/std_eval.npy | Bin 0 -> 2232 bytes .../mGPT/data/tools/__init__.py | 2 + motiondiff_modules/mGPT/data/tools/collate.py | 99 ++ .../mGPT/data/tools/easyconvert.py | 72 + .../mGPT/data/tools/geometry.py | 566 ++++++++ motiondiff_modules/mGPT/data/tools/tensors.py | 26 + .../mGPT/data/transforms/__init__.py | 15 + .../mGPT/data/transforms/base.py | 84 ++ .../mGPT/data/transforms/identity.py | 44 + .../data/transforms/joints2jfeats/__init__.py | 2 + .../data/transforms/joints2jfeats/base.py | 59 + .../data/transforms/joints2jfeats/rifke.py | 159 ++ .../data/transforms/joints2jfeats/tools.py | 97 ++ .../data/transforms/joints2rots/config.py | 119 ++ .../data/transforms/joints2rots/customloss.py | 217 +++ .../mGPT/data/transforms/joints2rots/prior.py | 229 +++ .../data/transforms/joints2rots/smplify.py | 284 ++++ .../data/transforms/rots2joints/__init__.py | 3 + .../mGPT/data/transforms/rots2joints/base.py | 56 + .../mGPT/data/transforms/rots2joints/smplh.py | 192 +++ .../mGPT/data/transforms/rots2joints/smplx.py | 201 +++ .../data/transforms/rots2rfeats/__init__.py | 5 + .../mGPT/data/transforms/rots2rfeats/base.py | 60 + .../transforms/rots2rfeats/globvelandy.py | 128 ++ .../mGPT/data/transforms/smpl.py | 191 +++ .../mGPT/data/transforms/xyz.py | 81 ++ motiondiff_modules/mGPT/data/utils.py | 81 ++ motiondiff_modules/mGPT/losses/__init__.py | 1 + motiondiff_modules/mGPT/losses/base.py | 61 + motiondiff_modules/mGPT/losses/mgpt.py | 97 ++ motiondiff_modules/mGPT/metrics/__init__.py | 1 + motiondiff_modules/mGPT/metrics/base.py | 46 + motiondiff_modules/mGPT/metrics/m2m.py | 95 ++ motiondiff_modules/mGPT/metrics/m2t.py | 345 +++++ motiondiff_modules/mGPT/metrics/mm.py | 129 ++ motiondiff_modules/mGPT/metrics/mr.py | 97 ++ motiondiff_modules/mGPT/metrics/t2m.py | 259 ++++ motiondiff_modules/mGPT/metrics/utils.py | 607 ++++++++ motiondiff_modules/mGPT/models/__init__.py | 0 motiondiff_modules/mGPT/models/base.py | 204 +++ motiondiff_modules/mGPT/models/build_model.py | 8 + motiondiff_modules/mGPT/models/mgpt.py | 492 +++++++ .../mGPT/models/utils/__init__.py | 0 motiondiff_modules/mGPT/models/utils/adain.py | 66 + .../mGPT/models/utils/blocks.py | 146 ++ .../mGPT/models/utils/cross_attention.py | 412 ++++++ .../mGPT/models/utils/position_encoding.py | 192 +++ .../models/utils/position_encoding_layer.py | 30 + motiondiff_modules/mGPT/models/utils/tools.py | 37 + motiondiff_modules/mGPT/utils/__init__.py | 0 motiondiff_modules/mGPT/utils/demo_utils.py | 79 + motiondiff_modules/mGPT/utils/easyconvert.py | 84 ++ motiondiff_modules/mGPT/utils/fixseed.py | 18 + .../mGPT/utils/geometry_conver.py | 550 +++++++ .../mGPT/utils/geometry_tools.py | 566 ++++++++ motiondiff_modules/mGPT/utils/joints.py | 444 ++++++ .../mGPT/utils/load_checkpoint.py | 34 + motiondiff_modules/mGPT/utils/logger.py | 68 + motiondiff_modules/mGPT/utils/misc.py | 29 + .../mGPT/utils/rotation_conversions.py | 551 +++++++ motiondiff_modules/mGPT/utils/sample_utils.py | 18 + motiondiff_modules/mGPT/utils/temos_utils.py | 133 ++ motiondiff_modules/mGPT/utils/tensors.py | 74 + motiondiff_modules/mogen/__init__.py | 56 + motiondiff_modules/mogen/apis/__init__.py | 13 + motiondiff_modules/mogen/apis/test.py | 160 ++ motiondiff_modules/mogen/apis/train.py | 165 +++ motiondiff_modules/mogen/core/__init__.py | 0 .../mogen/core/distributed_wrapper.py | 136 ++ .../mogen/core/evaluation/__init__.py | 4 + .../mogen/core/evaluation/builder.py | 29 + .../mogen/core/evaluation/eval_hooks.py | 138 ++ .../core/evaluation/evaluators/__init__.py | 0 .../evaluation/evaluators/base_evaluator.py | 144 ++ .../evaluators/diversity_evaluator.py | 52 + .../evaluation/evaluators/fid_evaluator.py | 58 + .../evaluators/matching_score_evaluator.py | 71 + .../evaluators/multimodality_evaluator.py | 63 + .../evaluators/precision_evaluator.py | 74 + .../mogen/core/evaluation/get_model.py | 46 + .../mogen/core/evaluation/utils.py | 130 ++ .../mogen/core/optimizer/__init__.py | 3 + .../mogen/core/optimizer/builder.py | 52 + motiondiff_modules/mogen/datasets/__init__.py | 11 + .../mogen/datasets/base_dataset.py | 117 ++ motiondiff_modules/mogen/datasets/builder.py | 113 ++ .../mogen/datasets/dataset_wrappers.py | 42 + .../mogen/datasets/pipelines/__init__.py | 18 + .../mogen/datasets/pipelines/compose.py | 42 + .../mogen/datasets/pipelines/formatting.py | 134 ++ .../mogen/datasets/pipelines/transforms.py | 120 ++ .../mogen/datasets/samplers/__init__.py | 3 + .../datasets/samplers/distributed_sampler.py | 42 + .../mogen/datasets/text_motion_dataset.py | 93 ++ motiondiff_modules/mogen/models/__init__.py | 7 + .../mogen/models/architectures/__init__.py | 6 + .../models/architectures/base_architecture.py | 135 ++ .../architectures/diffusion_architecture.py | 127 ++ .../models/architectures/vae_architecture.py | 118 ++ .../mogen/models/attentions/__init__.py | 6 + .../mogen/models/attentions/base_attention.py | 146 ++ .../models/attentions/efficient_attention.py | 87 ++ .../models/attentions/semantics_modulated.py | 82 ++ motiondiff_modules/mogen/models/builder.py | 32 + .../mogen/models/losses/__init__.py | 13 + .../mogen/models/losses/mse_loss.py | 70 + .../mogen/models/losses/utils.py | 109 ++ .../mogen/models/rnns/__init__.py | 1 + .../mogen/models/rnns/t2m_bigru.py | 260 ++++ .../mogen/models/transformers/__init__.py | 5 + .../mogen/models/transformers/actor.py | 189 +++ .../transformers/diffusion_transformer.py | 251 ++++ .../mogen/models/transformers/mdm.py | 212 +++ .../models/transformers/motiondiffuse.py | 41 + .../models/transformers/position_encoding.py | 35 + .../mogen/models/transformers/remodiffuse.py | 361 +++++ .../mogen/models/utils/__init__.py | 0 .../mogen/models/utils/gaussian_diffusion.py | 1281 +++++++++++++++++ motiondiff_modules/mogen/models/utils/mlp.py | 13 + .../mogen/models/utils/stylization_block.py | 40 + .../mogen/models/utils/word_vectorizer.py | 80 + .../body_models/smpl/J_regressor_extra.npy | Bin 0 -> 496160 bytes .../smpl/body_models/smpl/kintree_table.pkl | Bin 0 -> 349 bytes .../mogen/smpl/body_models/smpl/smplfaces.npy | Bin 0 -> 165440 bytes motiondiff_modules/mogen/smpl/human-skin.png | Bin 0 -> 5299542 bytes .../smpl_models/SMPL_downsample_index.pkl | Bin 0 -> 3556 bytes .../smpl/joints2smpl/smpl_models/gmm_08.pkl | 56 + .../smpl_models/neutral_smpl_mean_params.h5 | Bin 0 -> 4848 bytes .../smpl_models/smplx_parts_segm.pkl | 56 + .../mogen/smpl/joints2smpl/src/config.py | 41 + .../mogen/smpl/joints2smpl/src/customloss.py | 222 +++ .../mogen/smpl/joints2smpl/src/prior.py | 240 +++ .../mogen/smpl/joints2smpl/src/smplify.py | 294 ++++ motiondiff_modules/mogen/smpl/render_mesh.py | 442 ++++++ motiondiff_modules/mogen/smpl/rotation2xyz.py | 92 ++ .../mogen/smpl/rotation_conversions.py | 532 +++++++ .../mogen/smpl/shaders/mesh.frag | 13 + .../mogen/smpl/shaders/mesh.vert | 25 + .../mogen/smpl/simplify_loc2rot.py | 135 ++ motiondiff_modules/mogen/smpl/smpl.py | 124 ++ motiondiff_modules/mogen/utils/__init__.py | 18 + motiondiff_modules/mogen/utils/collect_env.py | 16 + motiondiff_modules/mogen/utils/dist_utils.py | 59 + motiondiff_modules/mogen/utils/logger.py | 7 + motiondiff_modules/mogen/utils/misc.py | 14 + motiondiff_modules/mogen/utils/path_utils.py | 232 +++ motiondiff_modules/mogen/utils/plot_utils.py | 251 ++++ motiondiff_modules/mogen/version.py | 25 + nodes/__init__.py | 0 nodes/human4d_nodes.py | 144 ++ nodes/mgpt_nodes.py | 91 ++ nodes/smpl_nodes.py | 344 +++++ requirements.txt | 10 +- utils.py | 2 +- 249 files changed, 29981 insertions(+), 12 deletions(-) create mode 100644 motiondiff_modules/__init__.py create mode 100644 motiondiff_modules/hmr2/README.md create mode 100644 motiondiff_modules/hmr2/__init__.py create mode 100644 motiondiff_modules/hmr2/configs/__init__.py create mode 100644 motiondiff_modules/hmr2/configs/cascade_mask_rcnn_vitdet_h_75ep.py create mode 100644 motiondiff_modules/hmr2/configs/datasets_eval.yaml create mode 100644 motiondiff_modules/hmr2/configs/datasets_tar.yaml create mode 100644 motiondiff_modules/hmr2/configs_hydra/data/mix_all.yaml create mode 100644 motiondiff_modules/hmr2/configs_hydra/data_filtering/low1.yaml create mode 100644 motiondiff_modules/hmr2/configs_hydra/experiment/default.yaml create mode 100644 motiondiff_modules/hmr2/configs_hydra/experiment/hmr_vit_transformer.yaml create mode 100644 motiondiff_modules/hmr2/configs_hydra/extras/default.yaml create mode 100644 motiondiff_modules/hmr2/configs_hydra/hydra/default.yaml create mode 100644 motiondiff_modules/hmr2/configs_hydra/launcher/local.yaml create mode 100644 motiondiff_modules/hmr2/configs_hydra/launcher/slurm.yaml create mode 100644 motiondiff_modules/hmr2/configs_hydra/paths/default.yaml create mode 100644 motiondiff_modules/hmr2/configs_hydra/train.yaml create mode 100644 motiondiff_modules/hmr2/configs_hydra/trainer/cpu.yaml create mode 100644 motiondiff_modules/hmr2/configs_hydra/trainer/ddp.yaml create mode 100644 motiondiff_modules/hmr2/configs_hydra/trainer/default.yaml create mode 100644 motiondiff_modules/hmr2/configs_hydra/trainer/default_hmr.yaml create mode 100644 motiondiff_modules/hmr2/configs_hydra/trainer/gpu.yaml create mode 100644 motiondiff_modules/hmr2/configs_hydra/trainer/mps.yaml create mode 100644 motiondiff_modules/hmr2/datasets/__init__.py create mode 100644 motiondiff_modules/hmr2/datasets/dataset.py create mode 100644 motiondiff_modules/hmr2/datasets/image_dataset.py create mode 100644 motiondiff_modules/hmr2/datasets/mocap_dataset.py create mode 100644 motiondiff_modules/hmr2/datasets/preprocess/lspet_to_npz.py create mode 100644 motiondiff_modules/hmr2/datasets/preprocess/posetrack_to_npz.py create mode 100644 motiondiff_modules/hmr2/datasets/smplh_prob_filter.py create mode 100644 motiondiff_modules/hmr2/datasets/utils.py create mode 100644 motiondiff_modules/hmr2/datasets/vitdet_dataset.py create mode 100644 motiondiff_modules/hmr2/models/__init__.py create mode 100644 motiondiff_modules/hmr2/models/backbones/__init__.py create mode 100644 motiondiff_modules/hmr2/models/backbones/vit.py create mode 100644 motiondiff_modules/hmr2/models/backbones/vit_vitpose.py create mode 100644 motiondiff_modules/hmr2/models/components/__init__.py create mode 100644 motiondiff_modules/hmr2/models/components/pose_transformer.py create mode 100644 motiondiff_modules/hmr2/models/components/t_cond_mlp.py create mode 100644 motiondiff_modules/hmr2/models/discriminator.py create mode 100644 motiondiff_modules/hmr2/models/heads/__init__.py create mode 100644 motiondiff_modules/hmr2/models/heads/smpl_head.py create mode 100644 motiondiff_modules/hmr2/models/hmr2_arch.py create mode 100644 motiondiff_modules/hmr2/models/losses.py create mode 100644 motiondiff_modules/hmr2/models/smpl_wrapper.py create mode 100644 motiondiff_modules/hmr2/utils/__init__.py create mode 100644 motiondiff_modules/hmr2/utils/download.py create mode 100644 motiondiff_modules/hmr2/utils/geometry.py create mode 100644 motiondiff_modules/hmr2/utils/mesh_renderer.py create mode 100644 motiondiff_modules/hmr2/utils/misc.py create mode 100644 motiondiff_modules/hmr2/utils/pck_accuracy.py create mode 100644 motiondiff_modules/hmr2/utils/pose_utils.py create mode 100644 motiondiff_modules/hmr2/utils/pylogger.py create mode 100644 motiondiff_modules/hmr2/utils/render_openpose.py create mode 100644 motiondiff_modules/hmr2/utils/renderer.py create mode 100644 motiondiff_modules/hmr2/utils/rich_utils.py create mode 100644 motiondiff_modules/hmr2/utils/skeleton_renderer.py create mode 100644 motiondiff_modules/hmr2/utils/texture_utils.py create mode 100644 motiondiff_modules/hmr2/utils/utils_detectron2.py create mode 100644 motiondiff_modules/mGPT/__init__.py create mode 100644 motiondiff_modules/mGPT/archs/__init__.py create mode 100644 motiondiff_modules/mGPT/archs/mgpt_lm.py create mode 100644 motiondiff_modules/mGPT/archs/mgpt_vq.py create mode 100644 motiondiff_modules/mGPT/archs/tm2t_evaluator.py create mode 100644 motiondiff_modules/mGPT/archs/tools/embeddings.py create mode 100644 motiondiff_modules/mGPT/archs/tools/quantize_cnn.py create mode 100644 motiondiff_modules/mGPT/archs/tools/resnet.py create mode 100644 motiondiff_modules/mGPT/archs/tools/token_emb.py create mode 100644 motiondiff_modules/mGPT/archs/tools/transformer_layers.py create mode 100644 motiondiff_modules/mGPT/callback.py create mode 100644 motiondiff_modules/mGPT/config.py create mode 100644 motiondiff_modules/mGPT/configs/inference.yaml create mode 100644 motiondiff_modules/mGPT/data/HumanML3D.py create mode 100644 motiondiff_modules/mGPT/data/Kit.py create mode 100644 motiondiff_modules/mGPT/data/__init__.py create mode 100644 motiondiff_modules/mGPT/data/build_data.py create mode 100644 motiondiff_modules/mGPT/data/humanml/README.md create mode 100644 motiondiff_modules/mGPT/data/humanml/__init__.py create mode 100644 motiondiff_modules/mGPT/data/humanml/common/quaternion.py create mode 100644 motiondiff_modules/mGPT/data/humanml/common/skeleton.py create mode 100644 motiondiff_modules/mGPT/data/humanml/dataset_m.py create mode 100644 motiondiff_modules/mGPT/data/humanml/dataset_m_vq.py create mode 100644 motiondiff_modules/mGPT/data/humanml/dataset_t2m.py create mode 100644 motiondiff_modules/mGPT/data/humanml/dataset_t2m_cb.py create mode 100644 motiondiff_modules/mGPT/data/humanml/dataset_t2m_eval.py create mode 100644 motiondiff_modules/mGPT/data/humanml/dataset_t2m_m2t.py create mode 100644 motiondiff_modules/mGPT/data/humanml/dataset_t2m_token.py create mode 100644 motiondiff_modules/mGPT/data/humanml/scripts/motion_process.py create mode 100644 motiondiff_modules/mGPT/data/humanml/utils/paramUtil.py create mode 100644 motiondiff_modules/mGPT/data/humanml/utils/word_vectorizer.py create mode 100644 motiondiff_modules/mGPT/data/mean.npy create mode 100644 motiondiff_modules/mGPT/data/mean_eval.npy create mode 100644 motiondiff_modules/mGPT/data/std.npy create mode 100644 motiondiff_modules/mGPT/data/std_eval.npy create mode 100644 motiondiff_modules/mGPT/data/tools/__init__.py create mode 100644 motiondiff_modules/mGPT/data/tools/collate.py create mode 100644 motiondiff_modules/mGPT/data/tools/easyconvert.py create mode 100644 motiondiff_modules/mGPT/data/tools/geometry.py create mode 100644 motiondiff_modules/mGPT/data/tools/tensors.py create mode 100644 motiondiff_modules/mGPT/data/transforms/__init__.py create mode 100644 motiondiff_modules/mGPT/data/transforms/base.py create mode 100644 motiondiff_modules/mGPT/data/transforms/identity.py create mode 100644 motiondiff_modules/mGPT/data/transforms/joints2jfeats/__init__.py create mode 100644 motiondiff_modules/mGPT/data/transforms/joints2jfeats/base.py create mode 100644 motiondiff_modules/mGPT/data/transforms/joints2jfeats/rifke.py create mode 100644 motiondiff_modules/mGPT/data/transforms/joints2jfeats/tools.py create mode 100644 motiondiff_modules/mGPT/data/transforms/joints2rots/config.py create mode 100644 motiondiff_modules/mGPT/data/transforms/joints2rots/customloss.py create mode 100644 motiondiff_modules/mGPT/data/transforms/joints2rots/prior.py create mode 100644 motiondiff_modules/mGPT/data/transforms/joints2rots/smplify.py create mode 100644 motiondiff_modules/mGPT/data/transforms/rots2joints/__init__.py create mode 100644 motiondiff_modules/mGPT/data/transforms/rots2joints/base.py create mode 100644 motiondiff_modules/mGPT/data/transforms/rots2joints/smplh.py create mode 100644 motiondiff_modules/mGPT/data/transforms/rots2joints/smplx.py create mode 100644 motiondiff_modules/mGPT/data/transforms/rots2rfeats/__init__.py create mode 100644 motiondiff_modules/mGPT/data/transforms/rots2rfeats/base.py create mode 100644 motiondiff_modules/mGPT/data/transforms/rots2rfeats/globvelandy.py create mode 100644 motiondiff_modules/mGPT/data/transforms/smpl.py create mode 100644 motiondiff_modules/mGPT/data/transforms/xyz.py create mode 100644 motiondiff_modules/mGPT/data/utils.py create mode 100644 motiondiff_modules/mGPT/losses/__init__.py create mode 100644 motiondiff_modules/mGPT/losses/base.py create mode 100644 motiondiff_modules/mGPT/losses/mgpt.py create mode 100644 motiondiff_modules/mGPT/metrics/__init__.py create mode 100644 motiondiff_modules/mGPT/metrics/base.py create mode 100644 motiondiff_modules/mGPT/metrics/m2m.py create mode 100644 motiondiff_modules/mGPT/metrics/m2t.py create mode 100644 motiondiff_modules/mGPT/metrics/mm.py create mode 100644 motiondiff_modules/mGPT/metrics/mr.py create mode 100644 motiondiff_modules/mGPT/metrics/t2m.py create mode 100644 motiondiff_modules/mGPT/metrics/utils.py create mode 100644 motiondiff_modules/mGPT/models/__init__.py create mode 100644 motiondiff_modules/mGPT/models/base.py create mode 100644 motiondiff_modules/mGPT/models/build_model.py create mode 100644 motiondiff_modules/mGPT/models/mgpt.py create mode 100644 motiondiff_modules/mGPT/models/utils/__init__.py create mode 100644 motiondiff_modules/mGPT/models/utils/adain.py create mode 100644 motiondiff_modules/mGPT/models/utils/blocks.py create mode 100644 motiondiff_modules/mGPT/models/utils/cross_attention.py create mode 100644 motiondiff_modules/mGPT/models/utils/position_encoding.py create mode 100644 motiondiff_modules/mGPT/models/utils/position_encoding_layer.py create mode 100644 motiondiff_modules/mGPT/models/utils/tools.py create mode 100644 motiondiff_modules/mGPT/utils/__init__.py create mode 100644 motiondiff_modules/mGPT/utils/demo_utils.py create mode 100644 motiondiff_modules/mGPT/utils/easyconvert.py create mode 100644 motiondiff_modules/mGPT/utils/fixseed.py create mode 100644 motiondiff_modules/mGPT/utils/geometry_conver.py create mode 100644 motiondiff_modules/mGPT/utils/geometry_tools.py create mode 100644 motiondiff_modules/mGPT/utils/joints.py create mode 100644 motiondiff_modules/mGPT/utils/load_checkpoint.py create mode 100644 motiondiff_modules/mGPT/utils/logger.py create mode 100644 motiondiff_modules/mGPT/utils/misc.py create mode 100644 motiondiff_modules/mGPT/utils/rotation_conversions.py create mode 100644 motiondiff_modules/mGPT/utils/sample_utils.py create mode 100644 motiondiff_modules/mGPT/utils/temos_utils.py create mode 100644 motiondiff_modules/mGPT/utils/tensors.py create mode 100644 motiondiff_modules/mogen/__init__.py create mode 100644 motiondiff_modules/mogen/apis/__init__.py create mode 100644 motiondiff_modules/mogen/apis/test.py create mode 100644 motiondiff_modules/mogen/apis/train.py create mode 100644 motiondiff_modules/mogen/core/__init__.py create mode 100644 motiondiff_modules/mogen/core/distributed_wrapper.py create mode 100644 motiondiff_modules/mogen/core/evaluation/__init__.py create mode 100644 motiondiff_modules/mogen/core/evaluation/builder.py create mode 100644 motiondiff_modules/mogen/core/evaluation/eval_hooks.py create mode 100644 motiondiff_modules/mogen/core/evaluation/evaluators/__init__.py create mode 100644 motiondiff_modules/mogen/core/evaluation/evaluators/base_evaluator.py create mode 100644 motiondiff_modules/mogen/core/evaluation/evaluators/diversity_evaluator.py create mode 100644 motiondiff_modules/mogen/core/evaluation/evaluators/fid_evaluator.py create mode 100644 motiondiff_modules/mogen/core/evaluation/evaluators/matching_score_evaluator.py create mode 100644 motiondiff_modules/mogen/core/evaluation/evaluators/multimodality_evaluator.py create mode 100644 motiondiff_modules/mogen/core/evaluation/evaluators/precision_evaluator.py create mode 100644 motiondiff_modules/mogen/core/evaluation/get_model.py create mode 100644 motiondiff_modules/mogen/core/evaluation/utils.py create mode 100644 motiondiff_modules/mogen/core/optimizer/__init__.py create mode 100644 motiondiff_modules/mogen/core/optimizer/builder.py create mode 100644 motiondiff_modules/mogen/datasets/__init__.py create mode 100644 motiondiff_modules/mogen/datasets/base_dataset.py create mode 100644 motiondiff_modules/mogen/datasets/builder.py create mode 100644 motiondiff_modules/mogen/datasets/dataset_wrappers.py create mode 100644 motiondiff_modules/mogen/datasets/pipelines/__init__.py create mode 100644 motiondiff_modules/mogen/datasets/pipelines/compose.py create mode 100644 motiondiff_modules/mogen/datasets/pipelines/formatting.py create mode 100644 motiondiff_modules/mogen/datasets/pipelines/transforms.py create mode 100644 motiondiff_modules/mogen/datasets/samplers/__init__.py create mode 100644 motiondiff_modules/mogen/datasets/samplers/distributed_sampler.py create mode 100644 motiondiff_modules/mogen/datasets/text_motion_dataset.py create mode 100644 motiondiff_modules/mogen/models/__init__.py create mode 100644 motiondiff_modules/mogen/models/architectures/__init__.py create mode 100644 motiondiff_modules/mogen/models/architectures/base_architecture.py create mode 100644 motiondiff_modules/mogen/models/architectures/diffusion_architecture.py create mode 100644 motiondiff_modules/mogen/models/architectures/vae_architecture.py create mode 100644 motiondiff_modules/mogen/models/attentions/__init__.py create mode 100644 motiondiff_modules/mogen/models/attentions/base_attention.py create mode 100644 motiondiff_modules/mogen/models/attentions/efficient_attention.py create mode 100644 motiondiff_modules/mogen/models/attentions/semantics_modulated.py create mode 100644 motiondiff_modules/mogen/models/builder.py create mode 100644 motiondiff_modules/mogen/models/losses/__init__.py create mode 100644 motiondiff_modules/mogen/models/losses/mse_loss.py create mode 100644 motiondiff_modules/mogen/models/losses/utils.py create mode 100644 motiondiff_modules/mogen/models/rnns/__init__.py create mode 100644 motiondiff_modules/mogen/models/rnns/t2m_bigru.py create mode 100644 motiondiff_modules/mogen/models/transformers/__init__.py create mode 100644 motiondiff_modules/mogen/models/transformers/actor.py create mode 100644 motiondiff_modules/mogen/models/transformers/diffusion_transformer.py create mode 100644 motiondiff_modules/mogen/models/transformers/mdm.py create mode 100644 motiondiff_modules/mogen/models/transformers/motiondiffuse.py create mode 100644 motiondiff_modules/mogen/models/transformers/position_encoding.py create mode 100644 motiondiff_modules/mogen/models/transformers/remodiffuse.py create mode 100644 motiondiff_modules/mogen/models/utils/__init__.py create mode 100644 motiondiff_modules/mogen/models/utils/gaussian_diffusion.py create mode 100644 motiondiff_modules/mogen/models/utils/mlp.py create mode 100644 motiondiff_modules/mogen/models/utils/stylization_block.py create mode 100644 motiondiff_modules/mogen/models/utils/word_vectorizer.py create mode 100644 motiondiff_modules/mogen/smpl/body_models/smpl/J_regressor_extra.npy create mode 100644 motiondiff_modules/mogen/smpl/body_models/smpl/kintree_table.pkl create mode 100644 motiondiff_modules/mogen/smpl/body_models/smpl/smplfaces.npy create mode 100644 motiondiff_modules/mogen/smpl/human-skin.png create mode 100644 motiondiff_modules/mogen/smpl/joints2smpl/smpl_models/SMPL_downsample_index.pkl create mode 100644 motiondiff_modules/mogen/smpl/joints2smpl/smpl_models/gmm_08.pkl create mode 100644 motiondiff_modules/mogen/smpl/joints2smpl/smpl_models/neutral_smpl_mean_params.h5 create mode 100644 motiondiff_modules/mogen/smpl/joints2smpl/smpl_models/smplx_parts_segm.pkl create mode 100644 motiondiff_modules/mogen/smpl/joints2smpl/src/config.py create mode 100644 motiondiff_modules/mogen/smpl/joints2smpl/src/customloss.py create mode 100644 motiondiff_modules/mogen/smpl/joints2smpl/src/prior.py create mode 100644 motiondiff_modules/mogen/smpl/joints2smpl/src/smplify.py create mode 100644 motiondiff_modules/mogen/smpl/render_mesh.py create mode 100644 motiondiff_modules/mogen/smpl/rotation2xyz.py create mode 100644 motiondiff_modules/mogen/smpl/rotation_conversions.py create mode 100644 motiondiff_modules/mogen/smpl/shaders/mesh.frag create mode 100644 motiondiff_modules/mogen/smpl/shaders/mesh.vert create mode 100644 motiondiff_modules/mogen/smpl/simplify_loc2rot.py create mode 100644 motiondiff_modules/mogen/smpl/smpl.py create mode 100644 motiondiff_modules/mogen/utils/__init__.py create mode 100644 motiondiff_modules/mogen/utils/collect_env.py create mode 100644 motiondiff_modules/mogen/utils/dist_utils.py create mode 100644 motiondiff_modules/mogen/utils/logger.py create mode 100644 motiondiff_modules/mogen/utils/misc.py create mode 100644 motiondiff_modules/mogen/utils/path_utils.py create mode 100644 motiondiff_modules/mogen/utils/plot_utils.py create mode 100644 motiondiff_modules/mogen/version.py create mode 100644 nodes/__init__.py create mode 100644 nodes/human4d_nodes.py create mode 100644 nodes/mgpt_nodes.py create mode 100644 nodes/smpl_nodes.py diff --git a/__init__.py b/__init__.py index 8805f4a..5a96b40 100644 --- a/__init__.py +++ b/__init__.py @@ -8,9 +8,9 @@ sys.path.insert(0, str(EXTENSION_PATH.resolve())) import custom_mmpkg.custom_mmcv as mmcv import numpy as np import torch -from mogen.models import build_architecture +from motiondiff_modules.mogen.models import build_architecture from custom_mmpkg.custom_mmcv.runner import load_checkpoint -from mogen.utils.plot_utils import ( +from motiondiff_modules.mogen.utils.plot_utils import ( plot_3d_motion, t2m_kinematic_chain ) @@ -20,10 +20,12 @@ from .utils import * #from custom_mmpkg.custom_mmhuman3d.core.conventions.keypoints_mapping import convert_kps #from custom_mmpkg.custom_mmhuman3d.core.visualization.visualize_keypoints3d import visualize_kp3d from pathlib import Path -from .smpl_nodes import NODE_CLASS_MAPPINGS as SMPL_NODE_CLASS_MAPPINGS -from .smpl_nodes import NODE_DISPLAY_NAME_MAPPINGS as SMPL_NODE_DISPLAY_NAME_MAPPINGS -from .mgpt_nodes import NODE_CLASS_MAPPINGS as MGPT_NODE_CLASS_MAPPINGS -from .mgpt_nodes import NODE_DISPLAY_NAME_MAPPINGS as MGPT_NODE_DISPLAY_NAME_MAPPINGS +from .nodes.smpl_nodes import NODE_CLASS_MAPPINGS as SMPL_NODE_CLASS_MAPPINGS +from .nodes.smpl_nodes import NODE_DISPLAY_NAME_MAPPINGS as SMPL_NODE_DISPLAY_NAME_MAPPINGS +from .nodes.mgpt_nodes import NODE_CLASS_MAPPINGS as MGPT_NODE_CLASS_MAPPINGS +from .nodes.mgpt_nodes import NODE_DISPLAY_NAME_MAPPINGS as MGPT_NODE_DISPLAY_NAME_MAPPINGS +from .nodes.human4d_nodes import NODE_CLASS_MAPPINGS as HUMAN4D_NODE_CLASS_MAPPINGS +from .nodes.human4d_nodes import NODE_DISPLAY_NAME_MAPPINGS as HUMAN4D_NODE_DISPLAY_NAME_MAPPINGS def create_mdm_model(model_config): cfg = mmcv.Config.fromstring(model_config.config_code, '.py') @@ -279,7 +281,8 @@ NODE_CLASS_MAPPINGS = { "EmptyMotionData": EmptyMotionData, "MotionDataVisualizer": MotionDataVisualizer, **SMPL_NODE_CLASS_MAPPINGS, - **MGPT_NODE_CLASS_MAPPINGS + **MGPT_NODE_CLASS_MAPPINGS, + **HUMAN4D_NODE_CLASS_MAPPINGS } NODE_DISPLAY_NAME_MAPPINGS = { @@ -289,5 +292,6 @@ NODE_DISPLAY_NAME_MAPPINGS = { "EmptyMotionData": "Empty Motion Data", "MotionDataVisualizer": "Motion Data Visualizer", **SMPL_NODE_DISPLAY_NAME_MAPPINGS, - **MGPT_NODE_DISPLAY_NAME_MAPPINGS + **MGPT_NODE_DISPLAY_NAME_MAPPINGS, + **HUMAN4D_NODE_DISPLAY_NAME_MAPPINGS } diff --git a/mogen/smpl/render_mesh.py b/mogen/smpl/render_mesh.py index e15a370..2a876f4 100644 --- a/mogen/smpl/render_mesh.py +++ b/mogen/smpl/render_mesh.py @@ -67,7 +67,6 @@ def render(motions): vertstrans=True) frames = vertices.shape[3] # shape: 1, nb_frames, 3, nb_joints - print (vertices.shape) MINS = torch.min(torch.min(vertices[0], axis=0)[0], axis=1)[0] MAXS = torch.max(torch.max(vertices[0], axis=0)[0], axis=1)[0] # vertices[:,:,1,:] -= MINS[1] + 1e-5 @@ -178,7 +177,6 @@ def render_from_smpl(thetas, yfov, move_x, move_y, move_z, x_rot, y_rot, z_rot, vertstrans=True) frames = vertices.shape[3] # shape: 1, nb_frames, 3, nb_joints - #print (vertices.shape) MINS = torch.min(torch.min(vertices[0], axis=0)[0], axis=1)[0] MAXS = torch.max(torch.max(vertices[0], axis=0)[0], axis=1)[0] minx = MINS[0] - 0.5 diff --git a/motiondiff_modules/__init__.py b/motiondiff_modules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/motiondiff_modules/hmr2/README.md b/motiondiff_modules/hmr2/README.md new file mode 100644 index 0000000..c544e5c --- /dev/null +++ b/motiondiff_modules/hmr2/README.md @@ -0,0 +1,107 @@ +# 4DHumans: Reconstructing and Tracking Humans with Transformers +Code repository for the paper: +**Humans in 4D: Reconstructing and Tracking Humans with Transformers** +[Shubham Goel](https://people.eecs.berkeley.edu/~shubham-goel/), [Georgios Pavlakos](https://geopavlakos.github.io/), [Jathushan Rajasegaran](http://people.eecs.berkeley.edu/~jathushan/), [Angjoo Kanazawa](https://people.eecs.berkeley.edu/~kanazawa/)\*, [Jitendra Malik](http://people.eecs.berkeley.edu/~malik/)\* + +[![arXiv](https://img.shields.io/badge/arXiv-2305.20091-00ff00.svg)](https://arxiv.org/pdf/2305.20091.pdf) [![Website shields.io](https://img.shields.io/website-up-down-green-red/http/shields.io.svg)](https://shubham-goel.github.io/4dhumans/) [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1Ex4gE5v1bPR3evfhtG7sDHxQGsWwNwby?usp=sharing) [![Hugging Face Spaces](https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Spaces-blue)](https://huggingface.co/spaces/brjathu/HMR2.0) + + +![teaser](assets/teaser.png) + +## Installation and Setup +First, clone the repo. Then, we recommend creating a clean [conda](https://docs.conda.io/) environment, installing all dependencies, and finally activating the environment, as follows: +```bash +git clone https://github.com/shubham-goel/4D-Humans.git +cd 4D-Humans +conda env create -f environment.yml +conda activate 4D-humans +``` + +If conda is too slow, you can use pip: +```bash +conda create --name 4D-humans python=3.10 +conda activate 4D-humans +pip install torch +pip install -e .[all] +``` + +All checkpoints and data will automatically be downloaded to `$HOME/.cache/4DHumans` the first time you run the demo code. + +Besides these files, you also need to download the *SMPL* model. You will need the [neutral model](http://smplify.is.tue.mpg.de) for training and running the demo code. Please go to the corresponding website and register to get access to the downloads section. Download the model and place `basicModel_neutral_lbs_10_207_0_v1.0.0.pkl` in `./data/`. + +## Run demo on images +The following command will run ViTDet and HMR2.0 on all images in the specified `--img_folder`, and save renderings of the reconstructions in `--out_folder`. `--batch_size` batches the images together for faster processing. The `--side_view` flags additionally renders the side view of the reconstructed mesh, `--full_frame` renders all people together in front view, `--save_mesh` saves meshes as `.obj`s. +```bash +python demo.py \ + --img_folder example_data/images \ + --out_folder demo_out \ + --batch_size=48 --side_view --save_mesh --full_frame +``` + +## Run tracking demo on videos +Our tracker builds on PHALP, please install that first: +```bash +pip install git+https://github.com/brjathu/PHALP.git +``` + +Now, run `track.py` to reconstruct and track humans in any video. Input video source may be a video file, a folder of frames, or a youtube link: +```bash +# Run on video file +python track.py video.source="example_data/videos/gymnasts.mp4" + +# Run on extracted frames +python track.py video.source="/path/to/frames_folder/" + +# Run on a youtube link (depends on pytube working properly) +python track.py video.source=\'"https://www.youtube.com/watch?v=xEH_5T9jMVU"\' +``` +The output directory (`./outputs` by default) will contain a video rendering of the tracklets and a `.pkl` file containing the tracklets with 3D pose and shape. Please see the [PHALP](https://github.com/brjathu/PHALP) repository for details. + +## Training +Download the [training data](https://www.dropbox.com/sh/mjdwu59fxuhls5h/AACQ6FCGSrggUXmRzuubRHXIa) to `./hmr2_training_data/`, then start training using the following command: +``` +bash fetch_training_data.sh +python train.py exp_name=hmr2 data=mix_all experiment=hmr_vit_transformer trainer=gpu launcher=local +``` +Checkpoints and logs will be saved to `./logs/`. We trained on 8 A100 GPUs for 7 days using PyTorch 1.13.1 and PyTorch-Lightning 1.8.1 with CUDA 11.6 on a Linux system. You may adjust batch size and number of GPUs per your convenience. + +## Evaluation +Download the [evaluation metadata](https://www.dropbox.com/scl/fi/kl79djemdgqcl6d691er7/hmr2_evaluation_data.tar.gz?rlkey=ttmbdu3x5etxwqqyzwk581zjl) to `./hmr2_evaluation_data/`. Additionally, download the Human3.6M, 3DPW, LSP-Extended, COCO, and PoseTrack dataset images and update the corresponding paths in `hmr2/configs/datasets_eval.yaml`. + +Run evaluation on multiple datasets as follows, results are stored in `results/eval_regression.csv`. +```bash +python eval.py --dataset 'H36M-VAL-P2,3DPW-TEST,LSP-EXTENDED,POSETRACK-VAL,COCO-VAL' +``` + +By default, our code uses the released checkpoint (mentioned as HMR2.0b in the paper). To use the HMR2.0a checkpoint, you may download and untar from [here](https://people.eecs.berkeley.edu/~jathushan/projects/4dhumans/hmr2a_model.tar.gz) + +## Preprocess code +To preprocess LSP Extended and Posetrack into metadata zip files for evaluation, see `hmr2/datasets/preprocess`. + +Training data preprocessing coming soon. + +## Open Source Contributions +[carlosedubarreto](https://github.com/carlosedubarreto/) has created a tutorial to import 4D Humans in Blender: https://www.patreon.com/posts/86992009 + +## Acknowledgements +Parts of the code are taken or adapted from the following repos: +- [ProHMR](https://github.com/nkolot/ProHMR) +- [SPIN](https://github.com/nkolot/SPIN) +- [SMPLify-X](https://github.com/vchoutas/smplify-x) +- [HMR](https://github.com/akanazawa/hmr) +- [ViTPose](https://github.com/ViTAE-Transformer/ViTPose) +- [Detectron2](https://github.com/facebookresearch/detectron2) + +Additionally, we thank [StabilityAI](https://stability.ai/) for a generous compute grant that enabled this work. + +## Citing +If you find this code useful for your research, please consider citing the following paper: + +```bibtex +@inproceedings{goel2023humans, + title={Humans in 4{D}: Reconstructing and Tracking Humans with Transformers}, + author={Goel, Shubham and Pavlakos, Georgios and Rajasegaran, Jathushan and Kanazawa, Angjoo and Malik, Jitendra}, + booktitle={ICCV}, + year={2023} +} +``` \ No newline at end of file diff --git a/motiondiff_modules/hmr2/__init__.py b/motiondiff_modules/hmr2/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/motiondiff_modules/hmr2/configs/__init__.py b/motiondiff_modules/hmr2/configs/__init__.py new file mode 100644 index 0000000..c10e9c9 --- /dev/null +++ b/motiondiff_modules/hmr2/configs/__init__.py @@ -0,0 +1,116 @@ +import os +from typing import Dict +from yacs.config import CfgNode as CN +from pathlib import Path + +CACHE_DIR_4DHUMANS = os.environ.get("4DHUMAN_CACHE", str(Path(__file__).parent.parent.parent.parent / "ckpts")) + +def to_lower(x: Dict) -> Dict: + """ + Convert all dictionary keys to lowercase + Args: + x (dict): Input dictionary + Returns: + dict: Output dictionary with all keys converted to lowercase + """ + return {k.lower(): v for k, v in x.items()} + +_C = CN(new_allowed=True) + +_C.GENERAL = CN(new_allowed=True) +_C.GENERAL.RESUME = True +_C.GENERAL.TIME_TO_RUN = 3300 +_C.GENERAL.VAL_STEPS = 100 +_C.GENERAL.LOG_STEPS = 100 +_C.GENERAL.CHECKPOINT_STEPS = 20000 +_C.GENERAL.CHECKPOINT_DIR = "checkpoints" +_C.GENERAL.SUMMARY_DIR = "tensorboard" +_C.GENERAL.NUM_GPUS = 1 +_C.GENERAL.NUM_WORKERS = 4 +_C.GENERAL.MIXED_PRECISION = True +_C.GENERAL.ALLOW_CUDA = True +_C.GENERAL.PIN_MEMORY = False +_C.GENERAL.DISTRIBUTED = False +_C.GENERAL.LOCAL_RANK = 0 +_C.GENERAL.USE_SYNCBN = False +_C.GENERAL.WORLD_SIZE = 1 + +_C.TRAIN = CN(new_allowed=True) +_C.TRAIN.NUM_EPOCHS = 100 +_C.TRAIN.BATCH_SIZE = 32 +_C.TRAIN.SHUFFLE = True +_C.TRAIN.WARMUP = False +_C.TRAIN.NORMALIZE_PER_IMAGE = False +_C.TRAIN.CLIP_GRAD = False +_C.TRAIN.CLIP_GRAD_VALUE = 1.0 +_C.LOSS_WEIGHTS = CN(new_allowed=True) + +_C.DATASETS = CN(new_allowed=True) + +_C.MODEL = CN(new_allowed=True) +_C.MODEL.IMAGE_SIZE = 224 + +_C.EXTRA = CN(new_allowed=True) +_C.EXTRA.FOCAL_LENGTH = 5000 + +_C.DATASETS.CONFIG = CN(new_allowed=True) +_C.DATASETS.CONFIG.SCALE_FACTOR = 0.3 +_C.DATASETS.CONFIG.ROT_FACTOR = 30 +_C.DATASETS.CONFIG.TRANS_FACTOR = 0.02 +_C.DATASETS.CONFIG.COLOR_SCALE = 0.2 +_C.DATASETS.CONFIG.ROT_AUG_RATE = 0.6 +_C.DATASETS.CONFIG.TRANS_AUG_RATE = 0.5 +_C.DATASETS.CONFIG.DO_FLIP = True +_C.DATASETS.CONFIG.FLIP_AUG_RATE = 0.5 +_C.DATASETS.CONFIG.EXTREME_CROP_AUG_RATE = 0.10 + +def default_config() -> CN: + """ + Get a yacs CfgNode object with the default config values. + """ + # Return a clone so that the defaults will not be altered + # This is for the "local variable" use pattern + return _C.clone() + +def dataset_config(name='datasets_tar.yaml') -> CN: + """ + Get dataset config file + Returns: + CfgNode: Dataset config as a yacs CfgNode object. + """ + cfg = CN(new_allowed=True) + config_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), name) + cfg.merge_from_file(config_file) + cfg.freeze() + return cfg + +def dataset_eval_config() -> CN: + return dataset_config('datasets_eval.yaml') + +def get_config(config_file: str, merge: bool = True, update_cachedir: bool = False) -> CN: + """ + Read a config file and optionally merge it with the default config file. + Args: + config_file (str): Path to config file. + merge (bool): Whether to merge with the default config or not. + Returns: + CfgNode: Config as a yacs CfgNode object. + """ + if merge: + cfg = default_config() + else: + cfg = CN(new_allowed=True) + cfg.merge_from_file(config_file) + + if update_cachedir: + def update_path(path: str) -> str: + if os.path.isabs(path): + return path + return os.path.join(CACHE_DIR_4DHUMANS, path) + + cfg.SMPL.MODEL_PATH = update_path(cfg.SMPL.MODEL_PATH) + cfg.SMPL.JOINT_REGRESSOR_EXTRA = update_path(cfg.SMPL.JOINT_REGRESSOR_EXTRA) + cfg.SMPL.MEAN_PARAMS = update_path(cfg.SMPL.MEAN_PARAMS) + + cfg.freeze() + return cfg diff --git a/motiondiff_modules/hmr2/configs/cascade_mask_rcnn_vitdet_h_75ep.py b/motiondiff_modules/hmr2/configs/cascade_mask_rcnn_vitdet_h_75ep.py new file mode 100644 index 0000000..0c6ae0e --- /dev/null +++ b/motiondiff_modules/hmr2/configs/cascade_mask_rcnn_vitdet_h_75ep.py @@ -0,0 +1,129 @@ +## coco_loader_lsj.py + +import detectron2.data.transforms as T +from detectron2 import model_zoo +from detectron2.config import LazyCall as L + +# Data using LSJ +image_size = 1024 +dataloader = model_zoo.get_config("common/data/coco.py").dataloader +dataloader.train.mapper.augmentations = [ + L(T.RandomFlip)(horizontal=True), # flip first + L(T.ResizeScale)( + min_scale=0.1, max_scale=2.0, target_height=image_size, target_width=image_size + ), + L(T.FixedSizeCrop)(crop_size=(image_size, image_size), pad=False), +] +dataloader.train.mapper.image_format = "RGB" +dataloader.train.total_batch_size = 64 +# recompute boxes due to cropping +dataloader.train.mapper.recompute_boxes = True + +dataloader.test.mapper.augmentations = [ + L(T.ResizeShortestEdge)(short_edge_length=image_size, max_size=image_size), +] + +from functools import partial +from fvcore.common.param_scheduler import MultiStepParamScheduler + +from detectron2 import model_zoo +from detectron2.config import LazyCall as L +from detectron2.solver import WarmupParamScheduler +from detectron2.modeling.backbone.vit import get_vit_lr_decay_rate + +# mask_rcnn_vitdet_b_100ep.py + +model = model_zoo.get_config("common/models/mask_rcnn_vitdet.py").model + +# Initialization and trainer settings +train = model_zoo.get_config("common/train.py").train +train.amp.enabled = True +train.ddp.fp16_compression = True +train.init_checkpoint = "detectron2://ImageNetPretrained/MAE/mae_pretrain_vit_base.pth" + + +# Schedule +# 100 ep = 184375 iters * 64 images/iter / 118000 images/ep +train.max_iter = 184375 + +lr_multiplier = L(WarmupParamScheduler)( + scheduler=L(MultiStepParamScheduler)( + values=[1.0, 0.1, 0.01], + milestones=[163889, 177546], + num_updates=train.max_iter, + ), + warmup_length=250 / train.max_iter, + warmup_factor=0.001, +) + +# Optimizer +optimizer = model_zoo.get_config("common/optim.py").AdamW +optimizer.params.lr_factor_func = partial(get_vit_lr_decay_rate, num_layers=12, lr_decay_rate=0.7) +optimizer.params.overrides = {"pos_embed": {"weight_decay": 0.0}} + +# cascade_mask_rcnn_vitdet_b_100ep.py + +from detectron2.config import LazyCall as L +from detectron2.layers import ShapeSpec +from detectron2.modeling.box_regression import Box2BoxTransform +from detectron2.modeling.matcher import Matcher +from detectron2.modeling.roi_heads import ( + FastRCNNOutputLayers, + FastRCNNConvFCHead, + CascadeROIHeads, +) + +# arguments that don't exist for Cascade R-CNN +[model.roi_heads.pop(k) for k in ["box_head", "box_predictor", "proposal_matcher"]] + +model.roi_heads.update( + _target_=CascadeROIHeads, + box_heads=[ + L(FastRCNNConvFCHead)( + input_shape=ShapeSpec(channels=256, height=7, width=7), + conv_dims=[256, 256, 256, 256], + fc_dims=[1024], + conv_norm="LN", + ) + for _ in range(3) + ], + box_predictors=[ + L(FastRCNNOutputLayers)( + input_shape=ShapeSpec(channels=1024), + test_score_thresh=0.05, + box2box_transform=L(Box2BoxTransform)(weights=(w1, w1, w2, w2)), + cls_agnostic_bbox_reg=True, + num_classes="${...num_classes}", + ) + for (w1, w2) in [(10, 5), (20, 10), (30, 15)] + ], + proposal_matchers=[ + L(Matcher)(thresholds=[th], labels=[0, 1], allow_low_quality_matches=False) + for th in [0.5, 0.6, 0.7] + ], +) + +# cascade_mask_rcnn_vitdet_h_75ep.py + +from functools import partial + +train.init_checkpoint = "detectron2://ImageNetPretrained/MAE/mae_pretrain_vit_huge_p14to16.pth" + +model.backbone.net.embed_dim = 1280 +model.backbone.net.depth = 32 +model.backbone.net.num_heads = 16 +model.backbone.net.drop_path_rate = 0.5 +# 7, 15, 23, 31 for global attention +model.backbone.net.window_block_indexes = ( + list(range(0, 7)) + list(range(8, 15)) + list(range(16, 23)) + list(range(24, 31)) +) + +optimizer.params.lr_factor_func = partial(get_vit_lr_decay_rate, lr_decay_rate=0.9, num_layers=32) +optimizer.params.overrides = {} +optimizer.params.weight_decay_norm = None + +train.max_iter = train.max_iter * 3 // 4 # 100ep -> 75ep +lr_multiplier.scheduler.milestones = [ + milestone * 3 // 4 for milestone in lr_multiplier.scheduler.milestones +] +lr_multiplier.scheduler.num_updates = train.max_iter diff --git a/motiondiff_modules/hmr2/configs/datasets_eval.yaml b/motiondiff_modules/hmr2/configs/datasets_eval.yaml new file mode 100644 index 0000000..b0c75d6 --- /dev/null +++ b/motiondiff_modules/hmr2/configs/datasets_eval.yaml @@ -0,0 +1,31 @@ +H36M-VAL-P2: + TYPE: ImageDataset + DATASET_FILE: hmr2_evaluation_data/h36m_val_p2.npz + IMG_DIR: /shared/pavlakos/datasets/h36m/images/ + KEYPOINT_LIST: [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 43] + USE_HIPS: True + +3DPW-TEST: + TYPE: ImageDataset + DATASET_FILE: hmr2_evaluation_data/3dpw_test.npz + IMG_DIR: /shared/pavlakos/datasets/3DPW/ + KEYPOINT_LIST: [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 43] + USE_HIPS: False + +POSETRACK-VAL: + TYPE: ImageDataset + DATASET_FILE: hmr2_evaluation_data/posetrack_2018_val.npz + IMG_DIR: /shared/pavlakos/datasets/posetrack/posetrack2018/posetrack_data/ + KEYPOINT_LIST: [0] # Dummy + +LSP-EXTENDED: + TYPE: ImageDataset + DATASET_FILE: hmr2_evaluation_data/hr-lspet_train.npz + IMG_DIR: /shared/pavlakos/datasets/hr-lspet/ + KEYPOINT_LIST: [0] # Dummy + +COCO-VAL: + TYPE: ImageDataset + DATASET_FILE: hmr2_evaluation_data/coco_val.npz + IMG_DIR: /shared/pavlakos/datasets/coco/ + KEYPOINT_LIST: [0] # Dummy diff --git a/motiondiff_modules/hmr2/configs/datasets_tar.yaml b/motiondiff_modules/hmr2/configs/datasets_tar.yaml new file mode 100644 index 0000000..2bac331 --- /dev/null +++ b/motiondiff_modules/hmr2/configs/datasets_tar.yaml @@ -0,0 +1,38 @@ +MPI-INF-TRAIN-PRUNED: + TYPE: ImageDataset + URLS: hmr2_training_data/dataset_tars/mpi-inf-train-pruned/{000000..00006}.tar + epoch_size: 12_000 +H36M-TRAIN-WMASK: + TYPE: ImageDataset + URLS: hmr2_training_data/dataset_tars/h36m-train/{000000..000312}.tar + epoch_size: 314_000 # Can be changed arbitrarily. Enables resampling. +MPII-TRAIN-WMASK: + TYPE: ImageDataset + URLS: hmr2_training_data/dataset_tars/mpii-train/{000000..000009}.tar + epoch_size: 100_000 # Increase to ensure dataset doesn't end before epoch +COCO-TRAIN-2014-WMASK-PRUNED: + TYPE: ImageDataset + URLS: hmr2_training_data/dataset_tars/coco-train-2014-pruned/{000000..000017}.tar + epoch_size: 18_000 +AVA-TRAIN-MIDFRAMES-1FPS-WMASK: + TYPE: ImageDataset + URLS: hmr2_training_data/dataset_tars/ava-train-midframes-1fps-vitpose/{000000..000092}.tar + epoch_size: 200_000 +AIC-TRAIN-WMASK: + TYPE: ImageDataset + URLS: hmr2_training_data/dataset_tars/aic-train-vitpose/{000000..000104}.tar + epoch_size: 200_000 +INSTA-TRAIN-WMASK: + TYPE: ImageDataset + URLS: hmr2_training_data/dataset_tars/insta-train-vitpose-replicate/{000000..003657}.tar + epoch_size: 4_000_000 +COCO-TRAIN-2014-VITPOSE-REPLICATE-PRUNED12: + TYPE: ImageDataset + URLS: hmr2_training_data/dataset_tars/coco-train-2014-vitpose-pruned/{000000..000044}.tar + epoch_size: 45_000 +COCO-VAL: + TYPE: ImageDataset + URLS: hmr2_training_data/dataset_tars/coco-val/{000000..000000}.tar + KEYPOINT_LIST: [0] # Dummy +CMU-MOCAP: + DATASET_FILE: hmr2_training_data/cmu_mocap.npz diff --git a/motiondiff_modules/hmr2/configs_hydra/data/mix_all.yaml b/motiondiff_modules/hmr2/configs_hydra/data/mix_all.yaml new file mode 100644 index 0000000..ed11a88 --- /dev/null +++ b/motiondiff_modules/hmr2/configs_hydra/data/mix_all.yaml @@ -0,0 +1,27 @@ +# @package _global_ +defaults: + - /data_filtering: low1 + +DATASETS: + TRAIN: + H36M-TRAIN-WMASK: + WEIGHT: 0.1 + MPII-TRAIN-WMASK: + WEIGHT: 0.1 + COCO-TRAIN-2014-WMASK-PRUNED: + WEIGHT: 0.1 + COCO-TRAIN-2014-VITPOSE-REPLICATE-PRUNED12: + WEIGHT: 0.1 + MPI-INF-TRAIN-PRUNED: + WEIGHT: 0.02 + AVA-TRAIN-MIDFRAMES-1FPS-WMASK: + WEIGHT: 0.19 + AIC-TRAIN-WMASK: + WEIGHT: 0.19 + INSTA-TRAIN-WMASK: + WEIGHT: 0.2 + VAL: + COCO-VAL: + WEIGHT: 1.0 + + MOCAP: CMU-MOCAP diff --git a/motiondiff_modules/hmr2/configs_hydra/data_filtering/low1.yaml b/motiondiff_modules/hmr2/configs_hydra/data_filtering/low1.yaml new file mode 100644 index 0000000..7d40adf --- /dev/null +++ b/motiondiff_modules/hmr2/configs_hydra/data_filtering/low1.yaml @@ -0,0 +1,13 @@ +# @package _global_ + +DATASETS: + # Data filtering during training + SUPPRESS_KP_CONF_THRESH: 0.3 + FILTER_NUM_KP: 4 + FILTER_NUM_KP_THRESH: 0.0 + FILTER_REPROJ_THRESH: 31000 + + SUPPRESS_BETAS_THRESH: 3.0 + SUPPRESS_BAD_POSES: True + POSES_BETAS_SIMULTANEOUS: True + FILTER_NO_POSES: False # If True, filters images that don't have poses diff --git a/motiondiff_modules/hmr2/configs_hydra/experiment/default.yaml b/motiondiff_modules/hmr2/configs_hydra/experiment/default.yaml new file mode 100644 index 0000000..2a0312c --- /dev/null +++ b/motiondiff_modules/hmr2/configs_hydra/experiment/default.yaml @@ -0,0 +1,29 @@ +# @package _global_ + +SMPL: + DATA_DIR: ${oc.env:HOME}/.cache/4DHumans/data/ + MODEL_PATH: ${SMPL.DATA_DIR}/smpl + GENDER: neutral + NUM_BODY_JOINTS: 23 + JOINT_REGRESSOR_EXTRA: ${SMPL.DATA_DIR}/SMPL_to_J19.pkl + MEAN_PARAMS: ${SMPL.DATA_DIR}/smpl_mean_params.npz + +EXTRA: + FOCAL_LENGTH: 5000 + NUM_LOG_IMAGES: 4 + NUM_LOG_SAMPLES_PER_IMAGE: 8 + PELVIS_IND: 39 + +DATASETS: + BETAS_REG: True + CONFIG: + SCALE_FACTOR: 0.3 + ROT_FACTOR: 30 + TRANS_FACTOR: 0.02 + COLOR_SCALE: 0.2 + ROT_AUG_RATE: 0.6 + TRANS_AUG_RATE: 0.5 + DO_FLIP: True + FLIP_AUG_RATE: 0.5 + EXTREME_CROP_AUG_RATE: 0.10 + EXTREME_CROP_AUG_LEVEL: 1 diff --git a/motiondiff_modules/hmr2/configs_hydra/experiment/hmr_vit_transformer.yaml b/motiondiff_modules/hmr2/configs_hydra/experiment/hmr_vit_transformer.yaml new file mode 100644 index 0000000..75df38a --- /dev/null +++ b/motiondiff_modules/hmr2/configs_hydra/experiment/hmr_vit_transformer.yaml @@ -0,0 +1,51 @@ +# @package _global_ + +defaults: + - default.yaml + +GENERAL: + TOTAL_STEPS: 1_000_000 + LOG_STEPS: 1000 + VAL_STEPS: 1000 + CHECKPOINT_STEPS: 10000 + CHECKPOINT_SAVE_TOP_K: 1 + NUM_WORKERS: 6 + PREFETCH_FACTOR: 2 + +TRAIN: + LR: 1e-5 + WEIGHT_DECAY: 1e-4 + BATCH_SIZE: 48 + LOSS_REDUCTION: mean + NUM_TRAIN_SAMPLES: 2 + NUM_TEST_SAMPLES: 64 + POSE_2D_NOISE_RATIO: 0.01 + SMPL_PARAM_NOISE_RATIO: 0.005 + +MODEL: + IMAGE_SIZE: 256 + IMAGE_MEAN: [0.485, 0.456, 0.406] + IMAGE_STD: [0.229, 0.224, 0.225] + BACKBONE: + TYPE: vit + PRETRAINED_WEIGHTS: hmr2_training_data/vitpose_backbone.pth + SMPL_HEAD: + TYPE: transformer_decoder + IN_CHANNELS: 2048 + TRANSFORMER_DECODER: + depth: 6 + heads: 8 + mlp_dim: 1024 + dim_head: 64 + dropout: 0.0 + emb_dropout: 0.0 + norm: layer + context_dim: 1280 # from vitpose-H + +LOSS_WEIGHTS: + KEYPOINTS_3D: 0.05 + KEYPOINTS_2D: 0.01 + GLOBAL_ORIENT: 0.001 + BODY_POSE: 0.001 + BETAS: 0.0005 + ADVERSARIAL: 0.0005 diff --git a/motiondiff_modules/hmr2/configs_hydra/extras/default.yaml b/motiondiff_modules/hmr2/configs_hydra/extras/default.yaml new file mode 100644 index 0000000..b9c6b62 --- /dev/null +++ b/motiondiff_modules/hmr2/configs_hydra/extras/default.yaml @@ -0,0 +1,8 @@ +# disable python warnings if they annoy you +ignore_warnings: False + +# ask user for tags if none are provided in the config +enforce_tags: True + +# pretty print config tree at the start of the run using Rich library +print_config: True diff --git a/motiondiff_modules/hmr2/configs_hydra/hydra/default.yaml b/motiondiff_modules/hmr2/configs_hydra/hydra/default.yaml new file mode 100644 index 0000000..c30c188 --- /dev/null +++ b/motiondiff_modules/hmr2/configs_hydra/hydra/default.yaml @@ -0,0 +1,26 @@ +# @package _global_ +# https://hydra.cc/docs/configure_hydra/intro/ + +# enable color logging +defaults: + - override /hydra/hydra_logging: colorlog + - override /hydra/job_logging: colorlog + +# exp_name: ovrd_${hydra:job.override_dirname} +exp_name: ${now:%Y-%m-%d}_${now:%H-%M-%S} + +hydra: + run: + dir: ${paths.log_dir}/${task_name}/runs/${exp_name} + sweep: + dir: ${paths.log_dir}/${task_name}/multiruns/${exp_name} + subdir: ${hydra.job.num} + job: + config: + override_dirname: + exclude_keys: + - trainer + - trainer.devices + - trainer.num_nodes + - callbacks + - debug diff --git a/motiondiff_modules/hmr2/configs_hydra/launcher/local.yaml b/motiondiff_modules/hmr2/configs_hydra/launcher/local.yaml new file mode 100644 index 0000000..7f27718 --- /dev/null +++ b/motiondiff_modules/hmr2/configs_hydra/launcher/local.yaml @@ -0,0 +1,13 @@ +# @package _global_ + +defaults: + - override /hydra/launcher: submitit_local + +hydra: + launcher: + timeout_min: 10_080 # 7 days + nodes: 1 + tasks_per_node: ${trainer.devices} + cpus_per_task: 6 + gpus_per_node: ${trainer.devices} + name: hmr2 diff --git a/motiondiff_modules/hmr2/configs_hydra/launcher/slurm.yaml b/motiondiff_modules/hmr2/configs_hydra/launcher/slurm.yaml new file mode 100644 index 0000000..4537f5d --- /dev/null +++ b/motiondiff_modules/hmr2/configs_hydra/launcher/slurm.yaml @@ -0,0 +1,22 @@ +# @package _global_ + +defaults: + - override /hydra/launcher: submitit_slurm + +hydra: + launcher: + timeout_min: 10_080 # 7 days + max_num_timeout: 3 + partition: g40 + qos: idle + nodes: 1 + tasks_per_node: ${trainer.devices} + gpus_per_task: null + cpus_per_task: 12 + gpus_per_node: ${trainer.devices} + cpus_per_gpu: null + comment: laion + name: hmr2 + setup: + - module load cuda openmpi libfabric-aws + - export CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 diff --git a/motiondiff_modules/hmr2/configs_hydra/paths/default.yaml b/motiondiff_modules/hmr2/configs_hydra/paths/default.yaml new file mode 100644 index 0000000..b2afd22 --- /dev/null +++ b/motiondiff_modules/hmr2/configs_hydra/paths/default.yaml @@ -0,0 +1,18 @@ +# path to root directory +# this requires PROJECT_ROOT environment variable to exist +# PROJECT_ROOT is inferred and set by pyrootutils package in `train.py` and `eval.py` +root_dir: ${oc.env:PROJECT_ROOT} + +# path to data directory +data_dir: ${paths.root_dir}/data/ + +# path to logging directory +log_dir: logs/ + +# path to output directory, created dynamically by hydra +# path generation pattern is specified in `configs/hydra/default.yaml` +# use it to store all files generated during the run, like ckpts and metrics +output_dir: ${hydra:runtime.output_dir} + +# path to working directory +work_dir: ${hydra:runtime.cwd} diff --git a/motiondiff_modules/hmr2/configs_hydra/train.yaml b/motiondiff_modules/hmr2/configs_hydra/train.yaml new file mode 100644 index 0000000..5021b4c --- /dev/null +++ b/motiondiff_modules/hmr2/configs_hydra/train.yaml @@ -0,0 +1,47 @@ +# @package _global_ + +# specify here default configuration +# order of defaults determines the order in which configs override each other +defaults: + - _self_ + - data: mix_all.yaml + - trainer: ddp.yaml + - paths: default.yaml + - extras: default.yaml + - hydra: default.yaml + + # experiment configs allow for version control of specific hyperparameters + # e.g. best hyperparameters for given model and datamodule + - experiment: null + - texture_exp: null + + # optional local config for machine/user specific settings + # it's optional since it doesn't need to exist and is excluded from version control + - optional launcher: local.yaml + # - optional launcher: slurm.yaml + + # debugging config (enable through command line, e.g. `python train.py debug=default) + - debug: null + +# task name, determines output directory path +task_name: "train" + +# tags to help you identify your experiments +# you can overwrite this in experiment configs +# overwrite from command line with `python train.py tags="[first_tag, second_tag]"` +# appending lists from command line is currently not supported :( +# https://github.com/facebookresearch/hydra/issues/1547 +tags: ["dev"] + +# set False to skip model training +train: True + +# evaluate on test set, using best model weights achieved during training +# lightning chooses best weights based on the metric specified in checkpoint callback +test: False + +# simply provide checkpoint path to resume training +ckpt_path: null + +# seed for random number generators in pytorch, numpy and python.random +seed: null diff --git a/motiondiff_modules/hmr2/configs_hydra/trainer/cpu.yaml b/motiondiff_modules/hmr2/configs_hydra/trainer/cpu.yaml new file mode 100644 index 0000000..e9ab459 --- /dev/null +++ b/motiondiff_modules/hmr2/configs_hydra/trainer/cpu.yaml @@ -0,0 +1,6 @@ +defaults: + - default.yaml + - default_hmr.yaml + +accelerator: cpu +devices: 1 diff --git a/motiondiff_modules/hmr2/configs_hydra/trainer/ddp.yaml b/motiondiff_modules/hmr2/configs_hydra/trainer/ddp.yaml new file mode 100644 index 0000000..d8f4271 --- /dev/null +++ b/motiondiff_modules/hmr2/configs_hydra/trainer/ddp.yaml @@ -0,0 +1,14 @@ +defaults: + - default.yaml + - default_hmr.yaml + +# use "ddp_spawn" instead of "ddp", +# it's slower but normal "ddp" currently doesn't work ideally with hydra +# https://github.com/facebookresearch/hydra/issues/2070 +# https://pytorch-lightning.readthedocs.io/en/latest/accelerators/gpu_intermediate.html#distributed-data-parallel-spawn +strategy: ddp + +accelerator: gpu +devices: 8 +num_nodes: 1 +sync_batchnorm: True diff --git a/motiondiff_modules/hmr2/configs_hydra/trainer/default.yaml b/motiondiff_modules/hmr2/configs_hydra/trainer/default.yaml new file mode 100644 index 0000000..7d444f4 --- /dev/null +++ b/motiondiff_modules/hmr2/configs_hydra/trainer/default.yaml @@ -0,0 +1,10 @@ +_target_: pytorch_lightning.Trainer + +default_root_dir: ${paths.output_dir} + +accelerator: cpu +devices: 1 + +# set True to to ensure deterministic results +# makes training slower but gives more reproducibility than just setting seeds +deterministic: False diff --git a/motiondiff_modules/hmr2/configs_hydra/trainer/default_hmr.yaml b/motiondiff_modules/hmr2/configs_hydra/trainer/default_hmr.yaml new file mode 100644 index 0000000..963b239 --- /dev/null +++ b/motiondiff_modules/hmr2/configs_hydra/trainer/default_hmr.yaml @@ -0,0 +1,8 @@ +num_sanity_val_steps: 0 +log_every_n_steps: ${GENERAL.LOG_STEPS} +val_check_interval: ${GENERAL.VAL_STEPS} +precision: 16 +max_steps: ${GENERAL.TOTAL_STEPS} +# move_metrics_to_cpu: True +limit_val_batches: 1 +# track_grad_norm: -1 diff --git a/motiondiff_modules/hmr2/configs_hydra/trainer/gpu.yaml b/motiondiff_modules/hmr2/configs_hydra/trainer/gpu.yaml new file mode 100644 index 0000000..f817c61 --- /dev/null +++ b/motiondiff_modules/hmr2/configs_hydra/trainer/gpu.yaml @@ -0,0 +1,6 @@ +defaults: + - default.yaml + - default_hmr.yaml + +accelerator: gpu +devices: 1 diff --git a/motiondiff_modules/hmr2/configs_hydra/trainer/mps.yaml b/motiondiff_modules/hmr2/configs_hydra/trainer/mps.yaml new file mode 100644 index 0000000..7083026 --- /dev/null +++ b/motiondiff_modules/hmr2/configs_hydra/trainer/mps.yaml @@ -0,0 +1,6 @@ +defaults: + - default.yaml + - default_hmr.yaml + +accelerator: mps +devices: 1 diff --git a/motiondiff_modules/hmr2/datasets/__init__.py b/motiondiff_modules/hmr2/datasets/__init__.py new file mode 100644 index 0000000..4fad37d --- /dev/null +++ b/motiondiff_modules/hmr2/datasets/__init__.py @@ -0,0 +1,88 @@ +from typing import Dict, Optional + +import torch +import numpy as np +import pytorch_lightning as pl +from yacs.config import CfgNode + +import webdataset as wds +from ..configs import to_lower +from .dataset import Dataset +from .image_dataset import ImageDataset +from .mocap_dataset import MoCapDataset + +def create_dataset(cfg: CfgNode, dataset_cfg: CfgNode, train: bool = True, **kwargs) -> Dataset: + """ + Instantiate a dataset from a config file. + Args: + cfg (CfgNode): Model configuration file. + dataset_cfg (CfgNode): Dataset configuration info. + train (bool): Variable to select between train and val datasets. + """ + + dataset_type = Dataset.registry[dataset_cfg.TYPE] + return dataset_type(cfg, **to_lower(dataset_cfg), train=train, **kwargs) + +def create_webdataset(cfg: CfgNode, dataset_cfg: CfgNode, train: bool = True) -> Dataset: + """ + Like `create_dataset` but load data from tars. + """ + dataset_type = Dataset.registry[dataset_cfg.TYPE] + return dataset_type.load_tars_as_webdataset(cfg, **to_lower(dataset_cfg), train=train) + + +class MixedWebDataset(wds.WebDataset): + def __init__(self, cfg: CfgNode, dataset_cfg: CfgNode, train: bool = True) -> None: + super(wds.WebDataset, self).__init__() + dataset_list = cfg.DATASETS.TRAIN if train else cfg.DATASETS.VAL + datasets = [create_webdataset(cfg, dataset_cfg[dataset], train=train) for dataset, v in dataset_list.items()] + weights = np.array([v.WEIGHT for dataset, v in dataset_list.items()]) + weights = weights / weights.sum() # normalize + self.append(wds.RandomMix(datasets, weights)) + +class HMR2DataModule(pl.LightningDataModule): + + def __init__(self, cfg: CfgNode, dataset_cfg: CfgNode) -> None: + """ + Initialize LightningDataModule for HMR2 training + Args: + cfg (CfgNode): Config file as a yacs CfgNode containing necessary dataset info. + dataset_cfg (CfgNode): Dataset configuration file + """ + super().__init__() + self.cfg = cfg + self.dataset_cfg = dataset_cfg + self.train_dataset = None + self.val_dataset = None + self.test_dataset = None + self.mocap_dataset = None + + def setup(self, stage: Optional[str] = None) -> None: + """ + Load datasets necessary for training + Args: + cfg (CfgNode): Config file as a yacs CfgNode containing necessary dataset info. + """ + if self.train_dataset == None: + self.train_dataset = MixedWebDataset(self.cfg, self.dataset_cfg, train=True).with_epoch(100_000).shuffle(4000) + self.val_dataset = MixedWebDataset(self.cfg, self.dataset_cfg, train=False).shuffle(4000) + self.mocap_dataset = MoCapDataset(**to_lower(self.dataset_cfg[self.cfg.DATASETS.MOCAP])) + + def train_dataloader(self) -> Dict: + """ + Setup training data loader. + Returns: + Dict: Dictionary containing image and mocap data dataloaders + """ + train_dataloader = torch.utils.data.DataLoader(self.train_dataset, self.cfg.TRAIN.BATCH_SIZE, drop_last=True, num_workers=self.cfg.GENERAL.NUM_WORKERS, prefetch_factor=self.cfg.GENERAL.PREFETCH_FACTOR) + mocap_dataloader = torch.utils.data.DataLoader(self.mocap_dataset, self.cfg.TRAIN.NUM_TRAIN_SAMPLES * self.cfg.TRAIN.BATCH_SIZE, shuffle=True, drop_last=True, num_workers=1) + return {'img': train_dataloader, 'mocap': mocap_dataloader} + + def val_dataloader(self) -> torch.utils.data.DataLoader: + """ + Setup val data loader. + Returns: + torch.utils.data.DataLoader: Validation dataloader + """ + val_dataloader = torch.utils.data.DataLoader(self.val_dataset, self.cfg.TRAIN.BATCH_SIZE, drop_last=True, num_workers=self.cfg.GENERAL.NUM_WORKERS) + return val_dataloader diff --git a/motiondiff_modules/hmr2/datasets/dataset.py b/motiondiff_modules/hmr2/datasets/dataset.py new file mode 100644 index 0000000..22fc5bc --- /dev/null +++ b/motiondiff_modules/hmr2/datasets/dataset.py @@ -0,0 +1,27 @@ +""" +This file contains the defition of the base Dataset class. +""" + +class DatasetRegistration(type): + """ + Metaclass for registering different datasets + """ + def __init__(cls, name, bases, nmspc): + super().__init__(name, bases, nmspc) + if not hasattr(cls, 'registry'): + cls.registry = dict() + cls.registry[name] = cls + + # Metamethods, called on class objects: + def __iter__(cls): + return iter(cls.registry) + + def __str__(cls): + return str(cls.registry) + +class Dataset(metaclass=DatasetRegistration): + """ + Base Dataset class + """ + def __init__(self, *args, **kwargs): + pass \ No newline at end of file diff --git a/motiondiff_modules/hmr2/datasets/image_dataset.py b/motiondiff_modules/hmr2/datasets/image_dataset.py new file mode 100644 index 0000000..8af8a88 --- /dev/null +++ b/motiondiff_modules/hmr2/datasets/image_dataset.py @@ -0,0 +1,454 @@ +import copy +import os +import numpy as np +import torch +from typing import Any, Dict, List +from yacs.config import CfgNode +import braceexpand +import cv2 + +from .dataset import Dataset +from .utils import get_example, expand_to_aspect_ratio +from .smplh_prob_filter import poses_check_probable, load_amass_hist_smooth + +def expand(s): + return os.path.expanduser(os.path.expandvars(s)) +def expand_urls(urls: str|List[str]): + if isinstance(urls, str): + urls = [urls] + urls = [u for url in urls for u in braceexpand.braceexpand(expand(url))] + return urls + +AIC_TRAIN_CORRUPT_KEYS = { + '0a047f0124ae48f8eee15a9506ce1449ee1ba669', + '1a703aa174450c02fbc9cfbf578a5435ef403689', + '0394e6dc4df78042929b891dbc24f0fd7ffb6b6d', + '5c032b9626e410441544c7669123ecc4ae077058', + 'ca018a7b4c5f53494006ebeeff9b4c0917a55f07', + '4a77adb695bef75a5d34c04d589baf646fe2ba35', + 'a0689017b1065c664daef4ae2d14ea03d543217e', + '39596a45cbd21bed4a5f9c2342505532f8ec5cbb', + '3d33283b40610d87db660b62982f797d50a7366b', +} +CORRUPT_KEYS = { + *{f'aic-train/{k}' for k in AIC_TRAIN_CORRUPT_KEYS}, + *{f'aic-train-vitpose/{k}' for k in AIC_TRAIN_CORRUPT_KEYS}, +} + +body_permutation = [0, 1, 5, 6, 7, 2, 3, 4, 8, 12, 13, 14, 9, 10, 11, 16, 15, 18, 17, 22, 23, 24, 19, 20, 21] +extra_permutation = [5, 4, 3, 2, 1, 0, 11, 10, 9, 8, 7, 6, 12, 13, 14, 15, 16, 17, 18] +FLIP_KEYPOINT_PERMUTATION = body_permutation + [25 + i for i in extra_permutation] + +DEFAULT_MEAN = 255. * np.array([0.485, 0.456, 0.406]) +DEFAULT_STD = 255. * np.array([0.229, 0.224, 0.225]) +DEFAULT_IMG_SIZE = 256 + +class ImageDataset(Dataset): + + def __init__(self, + cfg: CfgNode, + dataset_file: str, + img_dir: str, + train: bool = True, + prune: Dict[str, Any] = {}, + **kwargs): + """ + Dataset class used for loading images and corresponding annotations. + Args: + cfg (CfgNode): Model config file. + dataset_file (str): Path to npz file containing dataset info. + img_dir (str): Path to image folder. + train (bool): Whether it is for training or not (enables data augmentation). + """ + super(ImageDataset, self).__init__() + self.train = train + self.cfg = cfg + + self.img_size = cfg.MODEL.IMAGE_SIZE + self.mean = 255. * np.array(self.cfg.MODEL.IMAGE_MEAN) + self.std = 255. * np.array(self.cfg.MODEL.IMAGE_STD) + + self.img_dir = img_dir + self.data = np.load(dataset_file, allow_pickle=True) + + self.imgname = self.data['imgname'] + self.personid = np.zeros(len(self.imgname), dtype=np.int32) + self.extra_info = self.data.get('extra_info', [{} for _ in range(len(self.imgname))]) + + self.flip_keypoint_permutation = copy.copy(FLIP_KEYPOINT_PERMUTATION) + + num_pose = 3 * (self.cfg.SMPL.NUM_BODY_JOINTS + 1) + + # Bounding boxes are assumed to be in the center and scale format + self.center = self.data['center'] + self.scale = self.data['scale'].reshape(len(self.center), -1) / 200.0 + if self.scale.shape[1] == 1: + self.scale = np.tile(self.scale, (1, 2)) + assert self.scale.shape == (len(self.center), 2) + + # Get gt SMPLX parameters, if available + try: + self.body_pose = self.data['body_pose'].astype(np.float32) + self.has_body_pose = self.data['has_body_pose'].astype(np.float32) + except KeyError: + self.body_pose = np.zeros((len(self.imgname), num_pose), dtype=np.float32) + self.has_body_pose = np.zeros(len(self.imgname), dtype=np.float32) + try: + self.betas = self.data['betas'].astype(np.float32) + self.has_betas = self.data['has_betas'].astype(np.float32) + except KeyError: + self.betas = np.zeros((len(self.imgname), 10), dtype=np.float32) + self.has_betas = np.zeros(len(self.imgname), dtype=np.float32) + + # Try to get 2d keypoints, if available + try: + body_keypoints_2d = self.data['body_keypoints_2d'] + except KeyError: + body_keypoints_2d = np.zeros((len(self.center), 25, 3)) + # Try to get extra 2d keypoints, if available + try: + extra_keypoints_2d = self.data['extra_keypoints_2d'] + except KeyError: + extra_keypoints_2d = np.zeros((len(self.center), 19, 3)) + + self.keypoints_2d = np.concatenate((body_keypoints_2d, extra_keypoints_2d), axis=1).astype(np.float32) + + # Try to get 3d keypoints, if available + try: + body_keypoints_3d = self.data['body_keypoints_3d'].astype(np.float32) + except KeyError: + body_keypoints_3d = np.zeros((len(self.center), 25, 4), dtype=np.float32) + # Try to get extra 3d keypoints, if available + try: + extra_keypoints_3d = self.data['extra_keypoints_3d'].astype(np.float32) + except KeyError: + extra_keypoints_3d = np.zeros((len(self.center), 19, 4), dtype=np.float32) + + body_keypoints_3d[:, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], -1] = 0 + + self.keypoints_3d = np.concatenate((body_keypoints_3d, extra_keypoints_3d), axis=1).astype(np.float32) + + def __len__(self) -> int: + return len(self.scale) + + def __getitem__(self, idx: int) -> Dict: + """ + Returns an example from the dataset. + """ + try: + image_file_rel = self.imgname[idx].decode('utf-8') + except AttributeError: + image_file_rel = self.imgname[idx] + image_file = os.path.join(self.img_dir, image_file_rel) + keypoints_2d = self.keypoints_2d[idx].copy() + keypoints_3d = self.keypoints_3d[idx].copy() + + center = self.center[idx].copy() + center_x = center[0] + center_y = center[1] + scale = self.scale[idx] + BBOX_SHAPE = self.cfg.MODEL.get('BBOX_SHAPE', None) + bbox_size = expand_to_aspect_ratio(scale*200, target_aspect_ratio=BBOX_SHAPE).max() + bbox_expand_factor = bbox_size / ((scale*200).max()) + body_pose = self.body_pose[idx].copy().astype(np.float32) + betas = self.betas[idx].copy().astype(np.float32) + + has_body_pose = self.has_body_pose[idx].copy() + has_betas = self.has_betas[idx].copy() + + smpl_params = {'global_orient': body_pose[:3], + 'body_pose': body_pose[3:], + 'betas': betas + } + + has_smpl_params = {'global_orient': has_body_pose, + 'body_pose': has_body_pose, + 'betas': has_betas + } + + smpl_params_is_axis_angle = {'global_orient': True, + 'body_pose': True, + 'betas': False + } + + augm_config = self.cfg.DATASETS.CONFIG + # Crop image and (possibly) perform data augmentation + img_patch, keypoints_2d, keypoints_3d, smpl_params, has_smpl_params, img_size = get_example(image_file, + center_x, center_y, + bbox_size, bbox_size, + keypoints_2d, keypoints_3d, + smpl_params, has_smpl_params, + self.flip_keypoint_permutation, + self.img_size, self.img_size, + self.mean, self.std, self.train, augm_config) + + item = {} + # These are the keypoints in the original image coordinates (before cropping) + orig_keypoints_2d = self.keypoints_2d[idx].copy() + + item['img'] = img_patch + item['keypoints_2d'] = keypoints_2d.astype(np.float32) + item['keypoints_3d'] = keypoints_3d.astype(np.float32) + item['orig_keypoints_2d'] = orig_keypoints_2d + item['box_center'] = self.center[idx].copy() + item['box_size'] = bbox_size + item['bbox_expand_factor'] = bbox_expand_factor + item['img_size'] = 1.0 * img_size[::-1].copy() + item['smpl_params'] = smpl_params + item['has_smpl_params'] = has_smpl_params + item['smpl_params_is_axis_angle'] = smpl_params_is_axis_angle + item['imgname'] = image_file + item['imgname_rel'] = image_file_rel + item['personid'] = int(self.personid[idx]) + item['extra_info'] = copy.deepcopy(self.extra_info[idx]) + item['idx'] = idx + item['_scale'] = scale + return item + + + @staticmethod + def load_tars_as_webdataset(cfg: CfgNode, urls: str|List[str], train: bool, + resampled=False, + epoch_size=None, + cache_dir=None, + **kwargs) -> Dataset: + """ + Loads the dataset from a webdataset tar file. + """ + + IMG_SIZE = cfg.MODEL.IMAGE_SIZE + BBOX_SHAPE = cfg.MODEL.get('BBOX_SHAPE', None) + MEAN = 255. * np.array(cfg.MODEL.IMAGE_MEAN) + STD = 255. * np.array(cfg.MODEL.IMAGE_STD) + + def split_data(source): + for item in source: + datas = item['data.pyd'] + for data in datas: + if 'detection.npz' in item: + det_idx = data['extra_info']['detection_npz_idx'] + mask = item['detection.npz']['masks'][det_idx] + else: + mask = np.ones_like(item['jpg'][:,:,0], dtype=bool) + yield { + '__key__': item['__key__'], + 'jpg': item['jpg'], + 'data.pyd': data, + 'mask': mask, + } + + def suppress_bad_kps(item, thresh=0.0): + if thresh > 0: + kp2d = item['data.pyd']['keypoints_2d'] + kp2d_conf = np.where(kp2d[:, 2] < thresh, 0.0, kp2d[:, 2]) + item['data.pyd']['keypoints_2d'] = np.concatenate([kp2d[:,:2], kp2d_conf[:,None]], axis=1) + return item + + def filter_numkp(item, numkp=4, thresh=0.0): + kp_conf = item['data.pyd']['keypoints_2d'][:, 2] + return (kp_conf > thresh).sum() > numkp + + def filter_reproj_error(item, thresh=10**4.5): + losses = item['data.pyd'].get('extra_info', {}).get('fitting_loss', np.array({})).item() + reproj_loss = losses.get('reprojection_loss', None) + return reproj_loss is None or reproj_loss < thresh + + def filter_bbox_size(item, thresh=1): + bbox_size_min = item['data.pyd']['scale'].min().item() * 200. + return bbox_size_min > thresh + + def filter_no_poses(item): + return (item['data.pyd']['has_body_pose'] > 0) + + def supress_bad_betas(item, thresh=3): + has_betas = item['data.pyd']['has_betas'] + if thresh > 0 and has_betas: + betas_abs = np.abs(item['data.pyd']['betas']) + if (betas_abs > thresh).any(): + item['data.pyd']['has_betas'] = False + return item + + amass_poses_hist100_smooth = load_amass_hist_smooth() + def supress_bad_poses(item): + has_body_pose = item['data.pyd']['has_body_pose'] + if has_body_pose: + body_pose = item['data.pyd']['body_pose'] + pose_is_probable = poses_check_probable(torch.from_numpy(body_pose)[None, 3:], amass_poses_hist100_smooth).item() + if not pose_is_probable: + item['data.pyd']['has_body_pose'] = False + return item + + def poses_betas_simultaneous(item): + # We either have both body_pose and betas, or neither + has_betas = item['data.pyd']['has_betas'] + has_body_pose = item['data.pyd']['has_body_pose'] + item['data.pyd']['has_betas'] = item['data.pyd']['has_body_pose'] = np.array(float((has_body_pose>0) and (has_betas>0))) + return item + + def set_betas_for_reg(item): + # Always have betas set to true + has_betas = item['data.pyd']['has_betas'] + betas = item['data.pyd']['betas'] + + if not (has_betas>0): + item['data.pyd']['has_betas'] = np.array(float((True))) + item['data.pyd']['betas'] = betas * 0 + return item + + # Load the dataset + if epoch_size is not None: + resampled = True + corrupt_filter = lambda sample: (sample['__key__'] not in CORRUPT_KEYS) + import webdataset as wds + dataset = wds.WebDataset(expand_urls(urls), + nodesplitter=wds.split_by_node, + shardshuffle=True, + resampled=resampled, + cache_dir=cache_dir, + ).select(corrupt_filter) + if train: + dataset = dataset.shuffle(100) + dataset = dataset.decode('rgb8').rename(jpg='jpg;jpeg;png') + + # Process the dataset + dataset = dataset.compose(split_data) + + # Filter/clean the dataset + SUPPRESS_KP_CONF_THRESH = cfg.DATASETS.get('SUPPRESS_KP_CONF_THRESH', 0.0) + SUPPRESS_BETAS_THRESH = cfg.DATASETS.get('SUPPRESS_BETAS_THRESH', 0.0) + SUPPRESS_BAD_POSES = cfg.DATASETS.get('SUPPRESS_BAD_POSES', False) + POSES_BETAS_SIMULTANEOUS = cfg.DATASETS.get('POSES_BETAS_SIMULTANEOUS', False) + BETAS_REG = cfg.DATASETS.get('BETAS_REG', False) + FILTER_NO_POSES = cfg.DATASETS.get('FILTER_NO_POSES', False) + FILTER_NUM_KP = cfg.DATASETS.get('FILTER_NUM_KP', 4) + FILTER_NUM_KP_THRESH = cfg.DATASETS.get('FILTER_NUM_KP_THRESH', 0.0) + FILTER_REPROJ_THRESH = cfg.DATASETS.get('FILTER_REPROJ_THRESH', 0.0) + FILTER_MIN_BBOX_SIZE = cfg.DATASETS.get('FILTER_MIN_BBOX_SIZE', 0.0) + if SUPPRESS_KP_CONF_THRESH > 0: + dataset = dataset.map(lambda x: suppress_bad_kps(x, thresh=SUPPRESS_KP_CONF_THRESH)) + if SUPPRESS_BETAS_THRESH > 0: + dataset = dataset.map(lambda x: supress_bad_betas(x, thresh=SUPPRESS_BETAS_THRESH)) + if SUPPRESS_BAD_POSES: + dataset = dataset.map(lambda x: supress_bad_poses(x)) + if POSES_BETAS_SIMULTANEOUS: + dataset = dataset.map(lambda x: poses_betas_simultaneous(x)) + if FILTER_NO_POSES: + dataset = dataset.select(lambda x: filter_no_poses(x)) + if FILTER_NUM_KP > 0: + dataset = dataset.select(lambda x: filter_numkp(x, numkp=FILTER_NUM_KP, thresh=FILTER_NUM_KP_THRESH)) + if FILTER_REPROJ_THRESH > 0: + dataset = dataset.select(lambda x: filter_reproj_error(x, thresh=FILTER_REPROJ_THRESH)) + if FILTER_MIN_BBOX_SIZE > 0: + dataset = dataset.select(lambda x: filter_bbox_size(x, thresh=FILTER_MIN_BBOX_SIZE)) + if BETAS_REG: + dataset = dataset.map(lambda x: set_betas_for_reg(x)) # NOTE: Must be at the end + + use_skimage_antialias = cfg.DATASETS.get('USE_SKIMAGE_ANTIALIAS', False) + border_mode = { + 'constant': cv2.BORDER_CONSTANT, + 'replicate': cv2.BORDER_REPLICATE, + }[cfg.DATASETS.get('BORDER_MODE', 'constant')] + + # Process the dataset further + dataset = dataset.map(lambda x: ImageDataset.process_webdataset_tar_item(x, train, + augm_config=cfg.DATASETS.CONFIG, + MEAN=MEAN, STD=STD, IMG_SIZE=IMG_SIZE, + BBOX_SHAPE=BBOX_SHAPE, + use_skimage_antialias=use_skimage_antialias, + border_mode=border_mode, + )) + if epoch_size is not None: + dataset = dataset.with_epoch(epoch_size) + + return dataset + + @staticmethod + def process_webdataset_tar_item(item, train, + augm_config=None, + MEAN=DEFAULT_MEAN, + STD=DEFAULT_STD, + IMG_SIZE=DEFAULT_IMG_SIZE, + BBOX_SHAPE=None, + use_skimage_antialias=False, + border_mode=cv2.BORDER_CONSTANT, + ): + # Read data from item + key = item['__key__'] + image = item['jpg'] + data = item['data.pyd'] + mask = item['mask'] + + keypoints_2d = data['keypoints_2d'] + keypoints_3d = data['keypoints_3d'] + center = data['center'] + scale = data['scale'] + body_pose = data['body_pose'] + betas = data['betas'] + has_body_pose = data['has_body_pose'] + has_betas = data['has_betas'] + # image_file = data['image_file'] + + # Process data + orig_keypoints_2d = keypoints_2d.copy() + center_x = center[0] + center_y = center[1] + bbox_size = expand_to_aspect_ratio(scale*200, target_aspect_ratio=BBOX_SHAPE).max() + if bbox_size < 1: + breakpoint() + + + smpl_params = {'global_orient': body_pose[:3], + 'body_pose': body_pose[3:], + 'betas': betas + } + + has_smpl_params = {'global_orient': has_body_pose, + 'body_pose': has_body_pose, + 'betas': has_betas + } + + smpl_params_is_axis_angle = {'global_orient': True, + 'body_pose': True, + 'betas': False + } + + augm_config = copy.deepcopy(augm_config) + # Crop image and (possibly) perform data augmentation + img_rgba = np.concatenate([image, mask.astype(np.uint8)[:,:,None]*255], axis=2) + img_patch_rgba, keypoints_2d, keypoints_3d, smpl_params, has_smpl_params, img_size, trans = get_example(img_rgba, + center_x, center_y, + bbox_size, bbox_size, + keypoints_2d, keypoints_3d, + smpl_params, has_smpl_params, + FLIP_KEYPOINT_PERMUTATION, + IMG_SIZE, IMG_SIZE, + MEAN, STD, train, augm_config, + is_bgr=False, return_trans=True, + use_skimage_antialias=use_skimage_antialias, + border_mode=border_mode, + ) + img_patch = img_patch_rgba[:3,:,:] + mask_patch = (img_patch_rgba[3,:,:] / 255.0).clip(0,1) + if (mask_patch < 0.5).all(): + mask_patch = np.ones_like(mask_patch) + + item = {} + + item['img'] = img_patch + item['mask'] = mask_patch + # item['img_og'] = image + # item['mask_og'] = mask + item['keypoints_2d'] = keypoints_2d.astype(np.float32) + item['keypoints_3d'] = keypoints_3d.astype(np.float32) + item['orig_keypoints_2d'] = orig_keypoints_2d + item['box_center'] = center.copy() + item['box_size'] = bbox_size + item['img_size'] = 1.0 * img_size[::-1].copy() + item['smpl_params'] = smpl_params + item['has_smpl_params'] = has_smpl_params + item['smpl_params_is_axis_angle'] = smpl_params_is_axis_angle + item['_scale'] = scale + item['_trans'] = trans + item['imgname'] = key + # item['idx'] = idx + return item diff --git a/motiondiff_modules/hmr2/datasets/mocap_dataset.py b/motiondiff_modules/hmr2/datasets/mocap_dataset.py new file mode 100644 index 0000000..7ed8c94 --- /dev/null +++ b/motiondiff_modules/hmr2/datasets/mocap_dataset.py @@ -0,0 +1,25 @@ +import numpy as np +from typing import Dict + +class MoCapDataset: + + def __init__(self, dataset_file: str): + """ + Dataset class used for loading a dataset of unpaired SMPL parameter annotations + Args: + cfg (CfgNode): Model config file. + dataset_file (str): Path to npz file containing dataset info. + """ + data = np.load(dataset_file) + self.pose = data['body_pose'].astype(np.float32)[:, 3:] + self.betas = data['betas'].astype(np.float32) + self.length = len(self.pose) + + def __getitem__(self, idx: int) -> Dict: + pose = self.pose[idx].copy() + betas = self.betas[idx].copy() + item = {'body_pose': pose, 'betas': betas} + return item + + def __len__(self) -> int: + return self.length diff --git a/motiondiff_modules/hmr2/datasets/preprocess/lspet_to_npz.py b/motiondiff_modules/hmr2/datasets/preprocess/lspet_to_npz.py new file mode 100644 index 0000000..228c3df --- /dev/null +++ b/motiondiff_modules/hmr2/datasets/preprocess/lspet_to_npz.py @@ -0,0 +1,74 @@ +# Adapted from https://raw.githubusercontent.com/nkolot/SPIN/master/datasets/preprocess/hr_lspet.py +import os +import glob +import numpy as np +import scipy.io as sio +# from .read_openpose import read_openpose + +def hr_lspet_extract(dataset_path, out_path): + + # training mode + png_path = os.path.join(dataset_path, '*.png') + imgs = glob.glob(png_path) + imgs.sort() + + # structs we use + imgnames_, scales_, centers_, parts_, openposes_= [], [], [], [], [] + + # scale factor + scaleFactor = 1.2 + + # annotation files + annot_file = os.path.join(dataset_path, 'joints.mat') + joints = sio.loadmat(annot_file)['joints'] + + # main loop + for i, imgname in enumerate(imgs): + # image name + imgname = imgname.split('/')[-1] + # read keypoints + part14 = joints[:,:2,i] + # scale and center + bbox = [min(part14[:,0]), min(part14[:,1]), + max(part14[:,0]), max(part14[:,1])] + center = [(bbox[2]+bbox[0])/2, (bbox[3]+bbox[1])/2] + # scale = scaleFactor*max(bbox[2]-bbox[0], bbox[3]-bbox[1]) # Don't /200 + scale = scaleFactor*np.array([bbox[2]-bbox[0], bbox[3]-bbox[1]]) # Don't /200 + # update keypoints + part = np.zeros([24,3]) + part[:14] = np.hstack([part14, np.ones([14,1])]) + + # # read openpose detections + # json_file = os.path.join(openpose_path, 'hrlspet', + # imgname.replace('.png', '_keypoints.json')) + # openpose = read_openpose(json_file, part, 'hrlspet') + + # store the data + imgnames_.append(imgname) + centers_.append(center) + scales_.append(scale) + parts_.append(part) + # openposes_.append(openpose) + + # Populate extra_keypoints_2d: N,19,3 + # extra_keypoints_2d[:14] = parts[:14] + extra_keypoints_2d = np.zeros((len(parts_), 19, 3)) + extra_keypoints_2d[:,:14,:] = np.stack(parts_)[:,:14,:3] + + print(f'{extra_keypoints_2d.shape=}') + + # store the data struct + if not os.path.isdir(out_path): + os.makedirs(out_path) + out_file = os.path.join(out_path, 'hr-lspet_train.npz') + np.savez(out_file, imgname=imgnames_, + center=centers_, + scale=scales_, + part=parts_, + extra_keypoints_2d=extra_keypoints_2d, + # openpose=openposes_ + ) + + +if __name__ == '__main__': + hr_lspet_extract('/shared/pavlakos/datasets/hr-lspet/', 'hmr2_evaluation_data/') diff --git a/motiondiff_modules/hmr2/datasets/preprocess/posetrack_to_npz.py b/motiondiff_modules/hmr2/datasets/preprocess/posetrack_to_npz.py new file mode 100644 index 0000000..7c999b5 --- /dev/null +++ b/motiondiff_modules/hmr2/datasets/preprocess/posetrack_to_npz.py @@ -0,0 +1,92 @@ +# Adapted from https://raw.githubusercontent.com/nkolot/SPIN/master/datasets/preprocess/coco.py +import os +from os.path import join +import sys +import json +import numpy as np +from pathlib import Path +# from .read_openpose import read_openpose + +def coco_extract(dataset_path, out_path): + + # # convert joints to global order + # joints_idx = [19, 20, 21, 22, 23, 9, 8, 10, 7, 11, 6, 3, 2, 4, 1, 5, 0] + + # bbox expansion factor + scaleFactor = 1.2 + + # structs we need + imgnames_, scales_, centers_, parts_, openposes_ = [], [], [], [], [] + + # json annotation file + SPLIT='val' + json_paths = (Path(dataset_path)/'posetrack_data/annotations'/SPLIT).glob('*.json') + for json_path in json_paths: + json_data = json.load(open(json_path, 'r')) + + imgs = {} + for img in json_data['images']: + imgs[img['id']] = img + + for annot in json_data['annotations']: + # keypoints processing + keypoints = annot['keypoints'] + keypoints = np.reshape(keypoints, (17,3)) + keypoints[keypoints[:,2]>0,2] = 1 + # check if all major body joints are annotated + if sum(keypoints[5:,2]>0) < 12: + continue + # image name + image_id = annot['image_id'] + img_name = str(imgs[image_id]['file_name']) + # img_name_full = f'images/{SPLIT}/{json_path.stem}/{img_name}' + img_name_full = img_name + + # keypoints + part = np.zeros([17,3]) + # part[joints_idx] = keypoints + part = keypoints + + # scale and center + bbox = annot['bbox'] + center = [bbox[0] + bbox[2]/2, bbox[1] + bbox[3]/2] + # scale = scaleFactor*max(bbox[2], bbox[3]) # Don't do /200 + scale = scaleFactor*np.array([bbox[2], bbox[3]]) # Don't /200 + # # read openpose detections + # json_file = os.path.join(openpose_path, 'coco', + # img_name.replace('.jpg', '_keypoints.json')) + # openpose = read_openpose(json_file, part, 'coco') + + # store data + imgnames_.append(img_name_full) + centers_.append(center) + scales_.append(scale) + parts_.append(part) + # openposes_.append(openpose) + + + # NOTE: Posetrack val doesn't annotate ears (17,18) + # But Posetrack does annotate head, neck so that wil have to live in extra_kps. + posetrack_to_op_extra = [0, 37, 38, 18, 17, 5, 2, 6, 3, 7, 4, 12, 9, 13, 10, 14, 11] # Will contain 15 keypoints. + all_keypoints_2d = np.zeros((len(parts_), 44, 3)) + all_keypoints_2d[:,posetrack_to_op_extra] = np.stack(parts_)[:,:len(posetrack_to_op_extra),:3] + body_keypoints_2d = all_keypoints_2d[:,:25,:] + extra_keypoints_2d = all_keypoints_2d[:,25:,:] + + print(f'{extra_keypoints_2d.shape=}') + + # store the data struct + if not os.path.isdir(out_path): + os.makedirs(out_path) + out_file = os.path.join(out_path, f'posetrack_2018_{SPLIT}.npz') + np.savez(out_file, imgname=imgnames_, + center=centers_, + scale=scales_, + part=parts_, + body_keypoints_2d=body_keypoints_2d, + extra_keypoints_2d=extra_keypoints_2d, + # openpose=openposes_ + ) + +if __name__ == '__main__': + coco_extract('/shared/pavlakos/datasets/posetrack/posetrack2018/', 'hmr2_evaluation_data/') diff --git a/motiondiff_modules/hmr2/datasets/smplh_prob_filter.py b/motiondiff_modules/hmr2/datasets/smplh_prob_filter.py new file mode 100644 index 0000000..e3d2c5c --- /dev/null +++ b/motiondiff_modules/hmr2/datasets/smplh_prob_filter.py @@ -0,0 +1,154 @@ +import os +import numpy as np +import torch +import torch.nn.functional as F + +JOINT_NAMES = [ + 'left_hip', + 'right_hip', + 'spine1', + 'left_knee', + 'right_knee', + 'spine2', + 'left_ankle', + 'right_ankle', + 'spine3', + 'left_foot', + 'right_foot', + 'neck', + 'left_collar', + 'right_collar', + 'head', + 'left_shoulder', + 'right_shoulder', + 'left_elbow', + 'right_elbow', + 'left_wrist', + 'right_wrist' +] + +# Manually chosen probability density thresholds for each joint +# Probablities computed using SIGMA=2 gaussian blur on AMASS pose 3D histogram for range (-pi,pi) with 100x100x100 bins +JOINT_NAME_PROB_THRESHOLDS = { + 'left_hip': 5e-5, + 'right_hip': 5e-5, + 'spine1': 2e-3, + 'left_knee': 5e-6, + 'right_knee': 5e-6, + 'spine2': 0.01, + 'left_ankle': 5e-6, + 'right_ankle': 5e-6, + 'spine3': 0.025, + 'left_foot': 0, + 'right_foot': 0, + 'neck': 2e-4, + 'left_collar': 4.5e-4 , + 'right_collar': 4.5e-4, + 'head': 5e-4, + 'left_shoulder': 2e-4, + 'right_shoulder': 2e-4, + 'left_elbow': 4e-5, + 'right_elbow': 4e-5, + 'left_wrist': 1e-3, + 'right_wrist': 1e-3, +} + +JOINT_IDX_PROB_THRESHOLDS = torch.tensor([JOINT_NAME_PROB_THRESHOLDS[joint_name] for joint_name in JOINT_NAMES]) + +################################################################### +POSE_RANGE_MIN = -np.pi +POSE_RANGE_MAX = np.pi + +# Create 21x100x100x100 histogram of all 21 AMASS body pose joints using `create_pose_hist(amass_poses, nbins=100)` +AMASS_HIST100_PATH = 'hmr2_training_data/amass_poses_hist100_SMPL+H_G.npy' +if not os.path.exists(AMASS_HIST100_PATH): + AMASS_HIST100_PATH = '/shared/shubham/code/hmr2023/amass_poses_hist100_SMPL+H_G.npy' +if not os.path.exists(AMASS_HIST100_PATH): + AMASS_HIST100_PATH = '/fsx/shubham/code/stable-humans/notebooks/amass_poses_hist100_SMPL+H_G.npy' + + +def create_pose_hist(poses: np.ndarray, nbins: int = 100) -> np.ndarray: + N,K,C = poses.shape + assert C==3, poses.shape + poses_21x3 = normalize_axis_angle(torch.fromnumpy(poses).view(N*K,3)).numpy().reshape(N, K, 3) + assert (poses_21x3 > -np.pi).all() and (poses_21x3 < np.pi).all() + + Hs, Es = [], [] + for i in range(K): + H, edges = np.histogramdd(poses_21x3[:, i, :], bins=nbins, range=[(-np.pi, np.pi)]*3) + Hs.append(H) + Es.append(edges) + Hs = np.stack(Hs, axis=0) + return Hs + +def load_amass_hist_smooth(sigma=2) -> torch.Tensor: + amass_poses_hist100 = np.load(AMASS_HIST100_PATH) + amass_poses_hist100 = torch.from_numpy(amass_poses_hist100) + assert amass_poses_hist100.shape == (21,100,100,100) + + nbins = amass_poses_hist100.shape[1] + amass_poses_hist100 = amass_poses_hist100/amass_poses_hist100.sum() / (2*np.pi/nbins)**3 + + # Gaussian filter on amass_poses_hist100 + from scipy.ndimage import gaussian_filter + amass_poses_hist100_smooth = gaussian_filter(amass_poses_hist100.numpy(), sigma=sigma, mode='constant') + amass_poses_hist100_smooth = torch.from_numpy(amass_poses_hist100_smooth) + return amass_poses_hist100_smooth + +# Normalize axis angle representation s.t. angle is in [-pi, pi] +def normalize_axis_angle(poses: torch.Tensor) -> torch.Tensor: + # poses: N, 3 + # print(f'normalize_axis_angle ...') + assert poses.shape[1] == 3, poses.shape + angle = poses.norm(dim=1) + axis = F.normalize(poses, p=2, dim=1, eps=1e-8) + + angle_fixed = angle.clone() + axis_fixed = axis.clone() + + eps = 1e-6 + ii = 0 + while True: + # print(f'normalize_axis_angle iter {ii}') + ii += 1 + angle_too_big = (angle_fixed > np.pi + eps) + if not angle_too_big.any(): + break + + angle_fixed[angle_too_big] -= 2 * np.pi + angle_too_small = (angle_fixed < -eps) + axis_fixed[angle_too_small] *= -1 + angle_fixed[angle_too_small] *= -1 + + return axis_fixed * angle_fixed[:,None] + +def poses_to_joint_probs(poses: torch.Tensor, amass_poses_100_smooth: torch.Tensor) -> torch.Tensor: + # poses: Nx69 + # amass_poses_100_smooth: 21xBINSxBINSxBINS + # returns: poses_prob: Nx21 + N=poses.shape[0] + assert poses.shape == (N,69) + poses = poses[:,:63].reshape(N*21,3) + + nbins = amass_poses_100_smooth.shape[1] + assert amass_poses_100_smooth.shape == (21,nbins,nbins,nbins) + + poses_bin = (poses - POSE_RANGE_MIN) / (POSE_RANGE_MAX - POSE_RANGE_MIN) * (nbins - 1e-6) + poses_bin = poses_bin.long().clip(0, nbins-1) + joint_id = torch.arange(21, device=poses.device).view(1,21).expand(N,21).reshape(N*21) + poses_prob = amass_poses_100_smooth[joint_id, poses_bin[:,0], poses_bin[:,1], poses_bin[:,2]] + + poses_bad = ((poses < POSE_RANGE_MIN) | (poses >= POSE_RANGE_MAX)).any(dim=1) + poses_prob[poses_bad] = 0 + + return poses_prob.view(N,21) + +def poses_check_probable( + poses: torch.Tensor, + amass_poses_100_smooth: torch.Tensor, + prob_thresholds: torch.Tensor = JOINT_IDX_PROB_THRESHOLDS + ) -> torch.Tensor: + N,C=poses.shape + poses_norm = normalize_axis_angle(poses.reshape(N*(C//3),3)).reshape(N,C) + poses_prob = poses_to_joint_probs(poses_norm, amass_poses_100_smooth) + return (poses_prob > prob_thresholds).all(dim=1) diff --git a/motiondiff_modules/hmr2/datasets/utils.py b/motiondiff_modules/hmr2/datasets/utils.py new file mode 100644 index 0000000..40365fb --- /dev/null +++ b/motiondiff_modules/hmr2/datasets/utils.py @@ -0,0 +1,1025 @@ +""" +Parts of the code are taken or adapted from +https://github.com/mkocabas/EpipolarPose/blob/master/lib/utils/img_utils.py +""" +import torch +import numpy as np +from skimage.transform import rotate, resize +from skimage.filters import gaussian +import random +import cv2 +from typing import List, Dict, Tuple +from yacs.config import CfgNode + +def expand_to_aspect_ratio(input_shape, target_aspect_ratio=None): + """Increase the size of the bounding box to match the target shape.""" + if target_aspect_ratio is None: + return input_shape + + try: + w , h = input_shape + except (ValueError, TypeError): + return input_shape + + w_t, h_t = target_aspect_ratio + if h / w < h_t / w_t: + h_new = max(w * h_t / w_t, h) + w_new = w + else: + h_new = h + w_new = max(h * w_t / h_t, w) + if h_new < h or w_new < w: + breakpoint() + return np.array([w_new, h_new]) + +def expand_bbox_to_aspect_ratio(bbox, target_aspect_ratio=None): + # bbox: np.array: (N,4) detectron2 bbox format + # target_aspect_ratio: (width, height) + if target_aspect_ratio is None: + return bbox + + is_singleton = (bbox.ndim == 1) + if is_singleton: + bbox = bbox[None,:] + + if bbox.shape[0] > 0: + center = np.stack(((bbox[:,0] + bbox[:,2]) / 2, (bbox[:,1] + bbox[:,3]) / 2), axis=1) + scale_wh = np.stack((bbox[:,2] - bbox[:,0], bbox[:,3] - bbox[:,1]), axis=1) + scale_wh = np.stack([expand_to_aspect_ratio(wh, target_aspect_ratio) for wh in scale_wh], axis=0) + bbox = np.stack([ + center[:,0] - scale_wh[:,0] / 2, + center[:,1] - scale_wh[:,1] / 2, + center[:,0] + scale_wh[:,0] / 2, + center[:,1] + scale_wh[:,1] / 2, + ], axis=1) + + if is_singleton: + bbox = bbox[0,:] + + return bbox + +def do_augmentation(aug_config: CfgNode) -> Tuple: + """ + Compute random augmentation parameters. + Args: + aug_config (CfgNode): Config containing augmentation parameters. + Returns: + scale (float): Box rescaling factor. + rot (float): Random image rotation. + do_flip (bool): Whether to flip image or not. + do_extreme_crop (bool): Whether to apply extreme cropping (as proposed in EFT). + color_scale (List): Color rescaling factor + tx (float): Random translation along the x axis. + ty (float): Random translation along the y axis. + """ + + tx = np.clip(np.random.randn(), -1.0, 1.0) * aug_config.TRANS_FACTOR + ty = np.clip(np.random.randn(), -1.0, 1.0) * aug_config.TRANS_FACTOR + scale = np.clip(np.random.randn(), -1.0, 1.0) * aug_config.SCALE_FACTOR + 1.0 + rot = np.clip(np.random.randn(), -2.0, + 2.0) * aug_config.ROT_FACTOR if random.random() <= aug_config.ROT_AUG_RATE else 0 + do_flip = aug_config.DO_FLIP and random.random() <= aug_config.FLIP_AUG_RATE + do_extreme_crop = random.random() <= aug_config.EXTREME_CROP_AUG_RATE + extreme_crop_lvl = aug_config.get('EXTREME_CROP_AUG_LEVEL', 0) + # extreme_crop_lvl = 0 + c_up = 1.0 + aug_config.COLOR_SCALE + c_low = 1.0 - aug_config.COLOR_SCALE + color_scale = [random.uniform(c_low, c_up), random.uniform(c_low, c_up), random.uniform(c_low, c_up)] + return scale, rot, do_flip, do_extreme_crop, extreme_crop_lvl, color_scale, tx, ty + +def rotate_2d(pt_2d: np.array, rot_rad: float) -> np.array: + """ + Rotate a 2D point on the x-y plane. + Args: + pt_2d (np.array): Input 2D point with shape (2,). + rot_rad (float): Rotation angle + Returns: + np.array: Rotated 2D point. + """ + x = pt_2d[0] + y = pt_2d[1] + sn, cs = np.sin(rot_rad), np.cos(rot_rad) + xx = x * cs - y * sn + yy = x * sn + y * cs + return np.array([xx, yy], dtype=np.float32) + + +def gen_trans_from_patch_cv(c_x: float, c_y: float, + src_width: float, src_height: float, + dst_width: float, dst_height: float, + scale: float, rot: float) -> np.array: + """ + Create transformation matrix for the bounding box crop. + Args: + c_x (float): Bounding box center x coordinate in the original image. + c_y (float): Bounding box center y coordinate in the original image. + src_width (float): Bounding box width. + src_height (float): Bounding box height. + dst_width (float): Output box width. + dst_height (float): Output box height. + scale (float): Rescaling factor for the bounding box (augmentation). + rot (float): Random rotation applied to the box. + Returns: + trans (np.array): Target geometric transformation. + """ + # augment size with scale + src_w = src_width * scale + src_h = src_height * scale + src_center = np.zeros(2) + src_center[0] = c_x + src_center[1] = c_y + # augment rotation + rot_rad = np.pi * rot / 180 + src_downdir = rotate_2d(np.array([0, src_h * 0.5], dtype=np.float32), rot_rad) + src_rightdir = rotate_2d(np.array([src_w * 0.5, 0], dtype=np.float32), rot_rad) + + dst_w = dst_width + dst_h = dst_height + dst_center = np.array([dst_w * 0.5, dst_h * 0.5], dtype=np.float32) + dst_downdir = np.array([0, dst_h * 0.5], dtype=np.float32) + dst_rightdir = np.array([dst_w * 0.5, 0], dtype=np.float32) + + src = np.zeros((3, 2), dtype=np.float32) + src[0, :] = src_center + src[1, :] = src_center + src_downdir + src[2, :] = src_center + src_rightdir + + dst = np.zeros((3, 2), dtype=np.float32) + dst[0, :] = dst_center + dst[1, :] = dst_center + dst_downdir + dst[2, :] = dst_center + dst_rightdir + + trans = cv2.getAffineTransform(np.float32(src), np.float32(dst)) + + return trans + + +def trans_point2d(pt_2d: np.array, trans: np.array): + """ + Transform a 2D point using translation matrix trans. + Args: + pt_2d (np.array): Input 2D point with shape (2,). + trans (np.array): Transformation matrix. + Returns: + np.array: Transformed 2D point. + """ + src_pt = np.array([pt_2d[0], pt_2d[1], 1.]).T + dst_pt = np.dot(trans, src_pt) + return dst_pt[0:2] + +def get_transform(center, scale, res, rot=0): + """Generate transformation matrix.""" + """Taken from PARE: https://github.com/mkocabas/PARE/blob/6e0caca86c6ab49ff80014b661350958e5b72fd8/pare/utils/image_utils.py""" + h = 200 * scale + t = np.zeros((3, 3)) + t[0, 0] = float(res[1]) / h + t[1, 1] = float(res[0]) / h + t[0, 2] = res[1] * (-float(center[0]) / h + .5) + t[1, 2] = res[0] * (-float(center[1]) / h + .5) + t[2, 2] = 1 + if not rot == 0: + rot = -rot # To match direction of rotation from cropping + rot_mat = np.zeros((3, 3)) + rot_rad = rot * np.pi / 180 + sn, cs = np.sin(rot_rad), np.cos(rot_rad) + rot_mat[0, :2] = [cs, -sn] + rot_mat[1, :2] = [sn, cs] + rot_mat[2, 2] = 1 + # Need to rotate around center + t_mat = np.eye(3) + t_mat[0, 2] = -res[1] / 2 + t_mat[1, 2] = -res[0] / 2 + t_inv = t_mat.copy() + t_inv[:2, 2] *= -1 + t = np.dot(t_inv, np.dot(rot_mat, np.dot(t_mat, t))) + return t + + +def transform(pt, center, scale, res, invert=0, rot=0, as_int=True): + """Transform pixel location to different reference.""" + """Taken from PARE: https://github.com/mkocabas/PARE/blob/6e0caca86c6ab49ff80014b661350958e5b72fd8/pare/utils/image_utils.py""" + t = get_transform(center, scale, res, rot=rot) + if invert: + t = np.linalg.inv(t) + new_pt = np.array([pt[0] - 1, pt[1] - 1, 1.]).T + new_pt = np.dot(t, new_pt) + if as_int: + new_pt = new_pt.astype(int) + return new_pt[:2] + 1 + +def crop_img(img, ul, br, border_mode=cv2.BORDER_CONSTANT, border_value=0): + c_x = (ul[0] + br[0])/2 + c_y = (ul[1] + br[1])/2 + bb_width = patch_width = br[0] - ul[0] + bb_height = patch_height = br[1] - ul[1] + trans = gen_trans_from_patch_cv(c_x, c_y, bb_width, bb_height, patch_width, patch_height, 1.0, 0) + img_patch = cv2.warpAffine(img, trans, (int(patch_width), int(patch_height)), + flags=cv2.INTER_LINEAR, + borderMode=border_mode, + borderValue=border_value + ) + + # Force borderValue=cv2.BORDER_CONSTANT for alpha channel + if (img.shape[2] == 4) and (border_mode != cv2.BORDER_CONSTANT): + img_patch[:,:,3] = cv2.warpAffine(img[:,:,3], trans, (int(patch_width), int(patch_height)), + flags=cv2.INTER_LINEAR, + borderMode=cv2.BORDER_CONSTANT, + ) + + return img_patch + +def generate_image_patch_skimage(img: np.array, c_x: float, c_y: float, + bb_width: float, bb_height: float, + patch_width: float, patch_height: float, + do_flip: bool, scale: float, rot: float, + border_mode=cv2.BORDER_CONSTANT, border_value=0) -> Tuple[np.array, np.array]: + """ + Crop image according to the supplied bounding box. + Args: + img (np.array): Input image of shape (H, W, 3) + c_x (float): Bounding box center x coordinate in the original image. + c_y (float): Bounding box center y coordinate in the original image. + bb_width (float): Bounding box width. + bb_height (float): Bounding box height. + patch_width (float): Output box width. + patch_height (float): Output box height. + do_flip (bool): Whether to flip image or not. + scale (float): Rescaling factor for the bounding box (augmentation). + rot (float): Random rotation applied to the box. + Returns: + img_patch (np.array): Cropped image patch of shape (patch_height, patch_height, 3) + trans (np.array): Transformation matrix. + """ + + img_height, img_width, img_channels = img.shape + if do_flip: + img = img[:, ::-1, :] + c_x = img_width - c_x - 1 + + trans = gen_trans_from_patch_cv(c_x, c_y, bb_width, bb_height, patch_width, patch_height, scale, rot) + + #img_patch = cv2.warpAffine(img, trans, (int(patch_width), int(patch_height)), flags=cv2.INTER_LINEAR) + + # skimage + center = np.zeros(2) + center[0] = c_x + center[1] = c_y + res = np.zeros(2) + res[0] = patch_width + res[1] = patch_height + # assumes bb_width = bb_height + # assumes patch_width = patch_height + assert bb_width == bb_height, f'{bb_width=} != {bb_height=}' + assert patch_width == patch_height, f'{patch_width=} != {patch_height=}' + scale1 = scale*bb_width/200. + + # Upper left point + ul = np.array(transform([1, 1], center, scale1, res, invert=1, as_int=False)) - 1 + # Bottom right point + br = np.array(transform([res[0] + 1, + res[1] + 1], center, scale1, res, invert=1, as_int=False)) - 1 + + # Padding so that when rotated proper amount of context is included + try: + pad = int(np.linalg.norm(br - ul) / 2 - float(br[1] - ul[1]) / 2) + 1 + except: + breakpoint() + if not rot == 0: + ul -= pad + br += pad + + + if False: + # Old way of cropping image + ul_int = ul.astype(int) + br_int = br.astype(int) + new_shape = [br_int[1] - ul_int[1], br_int[0] - ul_int[0]] + if len(img.shape) > 2: + new_shape += [img.shape[2]] + new_img = np.zeros(new_shape) + + # Range to fill new array + new_x = max(0, -ul_int[0]), min(br_int[0], len(img[0])) - ul_int[0] + new_y = max(0, -ul_int[1]), min(br_int[1], len(img)) - ul_int[1] + # Range to sample from original image + old_x = max(0, ul_int[0]), min(len(img[0]), br_int[0]) + old_y = max(0, ul_int[1]), min(len(img), br_int[1]) + new_img[new_y[0]:new_y[1], new_x[0]:new_x[1]] = img[old_y[0]:old_y[1], + old_x[0]:old_x[1]] + + # New way of cropping image + new_img = crop_img(img, ul, br, border_mode=border_mode, border_value=border_value).astype(np.float32) + + # print(f'{new_img.shape=}') + # print(f'{new_img1.shape=}') + # print(f'{np.allclose(new_img, new_img1)=}') + # print(f'{img.dtype=}') + + + if not rot == 0: + # Remove padding + + new_img = rotate(new_img, rot) # scipy.misc.imrotate(new_img, rot) + new_img = new_img[pad:-pad, pad:-pad] + + if new_img.shape[0] < 1 or new_img.shape[1] < 1: + print(f'{img.shape=}') + print(f'{new_img.shape=}') + print(f'{ul=}') + print(f'{br=}') + print(f'{pad=}') + print(f'{rot=}') + + breakpoint() + + # resize image + new_img = resize(new_img, res) # scipy.misc.imresize(new_img, res) + + new_img = np.clip(new_img, 0, 255).astype(np.uint8) + + return new_img, trans + + +def generate_image_patch_cv2(img: np.array, c_x: float, c_y: float, + bb_width: float, bb_height: float, + patch_width: float, patch_height: float, + do_flip: bool, scale: float, rot: float, + border_mode=cv2.BORDER_CONSTANT, border_value=0) -> Tuple[np.array, np.array]: + """ + Crop the input image and return the crop and the corresponding transformation matrix. + Args: + img (np.array): Input image of shape (H, W, 3) + c_x (float): Bounding box center x coordinate in the original image. + c_y (float): Bounding box center y coordinate in the original image. + bb_width (float): Bounding box width. + bb_height (float): Bounding box height. + patch_width (float): Output box width. + patch_height (float): Output box height. + do_flip (bool): Whether to flip image or not. + scale (float): Rescaling factor for the bounding box (augmentation). + rot (float): Random rotation applied to the box. + Returns: + img_patch (np.array): Cropped image patch of shape (patch_height, patch_height, 3) + trans (np.array): Transformation matrix. + """ + + img_height, img_width, img_channels = img.shape + if do_flip: + img = img[:, ::-1, :] + c_x = img_width - c_x - 1 + + + trans = gen_trans_from_patch_cv(c_x, c_y, bb_width, bb_height, patch_width, patch_height, scale, rot) + + img_patch = cv2.warpAffine(img, trans, (int(patch_width), int(patch_height)), + flags=cv2.INTER_LINEAR, + borderMode=border_mode, + borderValue=border_value, + ) + # Force borderValue=cv2.BORDER_CONSTANT for alpha channel + if (img.shape[2] == 4) and (border_mode != cv2.BORDER_CONSTANT): + img_patch[:,:,3] = cv2.warpAffine(img[:,:,3], trans, (int(patch_width), int(patch_height)), + flags=cv2.INTER_LINEAR, + borderMode=cv2.BORDER_CONSTANT, + ) + + return img_patch, trans + + +def convert_cvimg_to_tensor(cvimg: np.array): + """ + Convert image from HWC to CHW format. + Args: + cvimg (np.array): Image of shape (H, W, 3) as loaded by OpenCV. + Returns: + np.array: Output image of shape (3, H, W). + """ + # from h,w,c(OpenCV) to c,h,w + img = cvimg.copy() + img = np.transpose(img, (2, 0, 1)) + # from int to float + img = img.astype(np.float32) + return img + +def fliplr_params(smpl_params: Dict, has_smpl_params: Dict) -> Tuple[Dict, Dict]: + """ + Flip SMPL parameters when flipping the image. + Args: + smpl_params (Dict): SMPL parameter annotations. + has_smpl_params (Dict): Whether SMPL annotations are valid. + Returns: + Dict, Dict: Flipped SMPL parameters and valid flags. + """ + global_orient = smpl_params['global_orient'].copy() + body_pose = smpl_params['body_pose'].copy() + betas = smpl_params['betas'].copy() + has_global_orient = has_smpl_params['global_orient'].copy() + has_body_pose = has_smpl_params['body_pose'].copy() + has_betas = has_smpl_params['betas'].copy() + + body_pose_permutation = [6, 7, 8, 3, 4, 5, 9, 10, 11, 15, 16, 17, 12, 13, + 14 ,18, 19, 20, 24, 25, 26, 21, 22, 23, 27, 28, 29, 33, + 34, 35, 30, 31, 32, 36, 37, 38, 42, 43, 44, 39, 40, 41, + 45, 46, 47, 51, 52, 53, 48, 49, 50, 57, 58, 59, 54, 55, + 56, 63, 64, 65, 60, 61, 62, 69, 70, 71, 66, 67, 68] + body_pose_permutation = body_pose_permutation[:len(body_pose)] + body_pose_permutation = [i-3 for i in body_pose_permutation] + + body_pose = body_pose[body_pose_permutation] + + global_orient[1::3] *= -1 + global_orient[2::3] *= -1 + body_pose[1::3] *= -1 + body_pose[2::3] *= -1 + + smpl_params = {'global_orient': global_orient.astype(np.float32), + 'body_pose': body_pose.astype(np.float32), + 'betas': betas.astype(np.float32) + } + + has_smpl_params = {'global_orient': has_global_orient, + 'body_pose': has_body_pose, + 'betas': has_betas + } + + return smpl_params, has_smpl_params + + +def fliplr_keypoints(joints: np.array, width: float, flip_permutation: List[int]) -> np.array: + """ + Flip 2D or 3D keypoints. + Args: + joints (np.array): Array of shape (N, 3) or (N, 4) containing 2D or 3D keypoint locations and confidence. + flip_permutation (List): Permutation to apply after flipping. + Returns: + np.array: Flipped 2D or 3D keypoints with shape (N, 3) or (N, 4) respectively. + """ + joints = joints.copy() + # Flip horizontal + joints[:, 0] = width - joints[:, 0] - 1 + joints = joints[flip_permutation, :] + + return joints + +def keypoint_3d_processing(keypoints_3d: np.array, flip_permutation: List[int], rot: float, do_flip: float) -> np.array: + """ + Process 3D keypoints (rotation/flipping). + Args: + keypoints_3d (np.array): Input array of shape (N, 4) containing the 3D keypoints and confidence. + flip_permutation (List): Permutation to apply after flipping. + rot (float): Random rotation applied to the keypoints. + do_flip (bool): Whether to flip keypoints or not. + Returns: + np.array: Transformed 3D keypoints with shape (N, 4). + """ + if do_flip: + keypoints_3d = fliplr_keypoints(keypoints_3d, 1, flip_permutation) + # in-plane rotation + rot_mat = np.eye(3) + if not rot == 0: + rot_rad = -rot * np.pi / 180 + sn,cs = np.sin(rot_rad), np.cos(rot_rad) + rot_mat[0,:2] = [cs, -sn] + rot_mat[1,:2] = [sn, cs] + keypoints_3d[:, :-1] = np.einsum('ij,kj->ki', rot_mat, keypoints_3d[:, :-1]) + # flip the x coordinates + keypoints_3d = keypoints_3d.astype('float32') + return keypoints_3d + +def rot_aa(aa: np.array, rot: float) -> np.array: + """ + Rotate axis angle parameters. + Args: + aa (np.array): Axis-angle vector of shape (3,). + rot (np.array): Rotation angle in degrees. + Returns: + np.array: Rotated axis-angle vector. + """ + # pose parameters + R = np.array([[np.cos(np.deg2rad(-rot)), -np.sin(np.deg2rad(-rot)), 0], + [np.sin(np.deg2rad(-rot)), np.cos(np.deg2rad(-rot)), 0], + [0, 0, 1]]) + # find the rotation of the body in camera frame + per_rdg, _ = cv2.Rodrigues(aa) + # apply the global rotation to the global orientation + resrot, _ = cv2.Rodrigues(np.dot(R,per_rdg)) + aa = (resrot.T)[0] + return aa.astype(np.float32) + +def smpl_param_processing(smpl_params: Dict, has_smpl_params: Dict, rot: float, do_flip: bool) -> Tuple[Dict, Dict]: + """ + Apply random augmentations to the SMPL parameters. + Args: + smpl_params (Dict): SMPL parameter annotations. + has_smpl_params (Dict): Whether SMPL annotations are valid. + rot (float): Random rotation applied to the keypoints. + do_flip (bool): Whether to flip keypoints or not. + Returns: + Dict, Dict: Transformed SMPL parameters and valid flags. + """ + if do_flip: + smpl_params, has_smpl_params = fliplr_params(smpl_params, has_smpl_params) + smpl_params['global_orient'] = rot_aa(smpl_params['global_orient'], rot) + return smpl_params, has_smpl_params + + + +def get_example(img_path: str|np.ndarray, center_x: float, center_y: float, + width: float, height: float, + keypoints_2d: np.array, keypoints_3d: np.array, + smpl_params: Dict, has_smpl_params: Dict, + flip_kp_permutation: List[int], + patch_width: int, patch_height: int, + mean: np.array, std: np.array, + do_augment: bool, augm_config: CfgNode, + is_bgr: bool = True, + use_skimage_antialias: bool = False, + border_mode: int = cv2.BORDER_CONSTANT, + return_trans: bool = False) -> Tuple: + """ + Get an example from the dataset and (possibly) apply random augmentations. + Args: + img_path (str): Image filename + center_x (float): Bounding box center x coordinate in the original image. + center_y (float): Bounding box center y coordinate in the original image. + width (float): Bounding box width. + height (float): Bounding box height. + keypoints_2d (np.array): Array with shape (N,3) containing the 2D keypoints in the original image coordinates. + keypoints_3d (np.array): Array with shape (N,4) containing the 3D keypoints. + smpl_params (Dict): SMPL parameter annotations. + has_smpl_params (Dict): Whether SMPL annotations are valid. + flip_kp_permutation (List): Permutation to apply to the keypoints after flipping. + patch_width (float): Output box width. + patch_height (float): Output box height. + mean (np.array): Array of shape (3,) containing the mean for normalizing the input image. + std (np.array): Array of shape (3,) containing the std for normalizing the input image. + do_augment (bool): Whether to apply data augmentation or not. + aug_config (CfgNode): Config containing augmentation parameters. + Returns: + return img_patch, keypoints_2d, keypoints_3d, smpl_params, has_smpl_params, img_size + img_patch (np.array): Cropped image patch of shape (3, patch_height, patch_height) + keypoints_2d (np.array): Array with shape (N,3) containing the transformed 2D keypoints. + keypoints_3d (np.array): Array with shape (N,4) containing the transformed 3D keypoints. + smpl_params (Dict): Transformed SMPL parameters. + has_smpl_params (Dict): Valid flag for transformed SMPL parameters. + img_size (np.array): Image size of the original image. + """ + if isinstance(img_path, str): + # 1. load image + cvimg = cv2.imread(img_path, cv2.IMREAD_COLOR | cv2.IMREAD_IGNORE_ORIENTATION) + if not isinstance(cvimg, np.ndarray): + raise IOError("Fail to read %s" % img_path) + elif isinstance(img_path, np.ndarray): + cvimg = img_path + else: + raise TypeError('img_path must be either a string or a numpy array') + img_height, img_width, img_channels = cvimg.shape + + img_size = np.array([img_height, img_width]) + + # 2. get augmentation params + if do_augment: + scale, rot, do_flip, do_extreme_crop, extreme_crop_lvl, color_scale, tx, ty = do_augmentation(augm_config) + else: + scale, rot, do_flip, do_extreme_crop, extreme_crop_lvl, color_scale, tx, ty = 1.0, 0, False, False, 0, [1.0, 1.0, 1.0], 0., 0. + + if width < 1 or height < 1: + breakpoint() + + if do_extreme_crop: + if extreme_crop_lvl == 0: + center_x1, center_y1, width1, height1 = extreme_cropping(center_x, center_y, width, height, keypoints_2d) + elif extreme_crop_lvl == 1: + center_x1, center_y1, width1, height1 = extreme_cropping_aggressive(center_x, center_y, width, height, keypoints_2d) + + THRESH = 4 + if width1 < THRESH or height1 < THRESH: + # print(f'{do_extreme_crop=}') + # print(f'width: {width}, height: {height}') + # print(f'width1: {width1}, height1: {height1}') + # print(f'center_x: {center_x}, center_y: {center_y}') + # print(f'center_x1: {center_x1}, center_y1: {center_y1}') + # print(f'keypoints_2d: {keypoints_2d}') + # print(f'\n\n', flush=True) + # breakpoint() + pass + # print(f'skip ==> width1: {width1}, height1: {height1}, width: {width}, height: {height}') + else: + center_x, center_y, width, height = center_x1, center_y1, width1, height1 + + center_x += width * tx + center_y += height * ty + + # Process 3D keypoints + keypoints_3d = keypoint_3d_processing(keypoints_3d, flip_kp_permutation, rot, do_flip) + + # 3. generate image patch + if use_skimage_antialias: + # Blur image to avoid aliasing artifacts + downsampling_factor = (patch_width / (width*scale)) + if downsampling_factor > 1.1: + cvimg = gaussian(cvimg, sigma=(downsampling_factor-1)/2, channel_axis=2, preserve_range=True, truncate=3.0) + + img_patch_cv, trans = generate_image_patch_cv2(cvimg, + center_x, center_y, + width, height, + patch_width, patch_height, + do_flip, scale, rot, + border_mode=border_mode) + # img_patch_cv, trans = generate_image_patch_skimage(cvimg, + # center_x, center_y, + # width, height, + # patch_width, patch_height, + # do_flip, scale, rot, + # border_mode=border_mode) + + image = img_patch_cv.copy() + if is_bgr: + image = image[:, :, ::-1] + img_patch_cv = image.copy() + img_patch = convert_cvimg_to_tensor(image) + + + smpl_params, has_smpl_params = smpl_param_processing(smpl_params, has_smpl_params, rot, do_flip) + + # apply normalization + for n_c in range(min(img_channels, 3)): + img_patch[n_c, :, :] = np.clip(img_patch[n_c, :, :] * color_scale[n_c], 0, 255) + if mean is not None and std is not None: + img_patch[n_c, :, :] = (img_patch[n_c, :, :] - mean[n_c]) / std[n_c] + if do_flip: + keypoints_2d = fliplr_keypoints(keypoints_2d, img_width, flip_kp_permutation) + + + for n_jt in range(len(keypoints_2d)): + keypoints_2d[n_jt, 0:2] = trans_point2d(keypoints_2d[n_jt, 0:2], trans) + keypoints_2d[:, :-1] = keypoints_2d[:, :-1] / patch_width - 0.5 + + if not return_trans: + return img_patch, keypoints_2d, keypoints_3d, smpl_params, has_smpl_params, img_size + else: + return img_patch, keypoints_2d, keypoints_3d, smpl_params, has_smpl_params, img_size, trans + +def crop_to_hips(center_x: float, center_y: float, width: float, height: float, keypoints_2d: np.array) -> Tuple: + """ + Extreme cropping: Crop the box up to the hip locations. + Args: + center_x (float): x coordinate of the bounding box center. + center_y (float): y coordinate of the bounding box center. + width (float): Bounding box width. + height (float): Bounding box height. + keypoints_2d (np.array): Array of shape (N, 3) containing 2D keypoint locations. + Returns: + center_x (float): x coordinate of the new bounding box center. + center_y (float): y coordinate of the new bounding box center. + width (float): New bounding box width. + height (float): New bounding box height. + """ + keypoints_2d = keypoints_2d.copy() + lower_body_keypoints = [10, 11, 13, 14, 19, 20, 21, 22, 23, 24, 25+0, 25+1, 25+4, 25+5] + keypoints_2d[lower_body_keypoints, :] = 0 + if keypoints_2d[:, -1].sum() > 1: + center, scale = get_bbox(keypoints_2d) + center_x = center[0] + center_y = center[1] + width = 1.1 * scale[0] + height = 1.1 * scale[1] + return center_x, center_y, width, height + + +def crop_to_shoulders(center_x: float, center_y: float, width: float, height: float, keypoints_2d: np.array): + """ + Extreme cropping: Crop the box up to the shoulder locations. + Args: + center_x (float): x coordinate of the bounding box center. + center_y (float): y coordinate of the bounding box center. + width (float): Bounding box width. + height (float): Bounding box height. + keypoints_2d (np.array): Array of shape (N, 3) containing 2D keypoint locations. + Returns: + center_x (float): x coordinate of the new bounding box center. + center_y (float): y coordinate of the new bounding box center. + width (float): New bounding box width. + height (float): New bounding box height. + """ + keypoints_2d = keypoints_2d.copy() + lower_body_keypoints = [3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 19, 20, 21, 22, 23, 24] + [25 + i for i in [0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 14, 15, 16]] + keypoints_2d[lower_body_keypoints, :] = 0 + center, scale = get_bbox(keypoints_2d) + if keypoints_2d[:, -1].sum() > 1: + center, scale = get_bbox(keypoints_2d) + center_x = center[0] + center_y = center[1] + width = 1.2 * scale[0] + height = 1.2 * scale[1] + return center_x, center_y, width, height + +def crop_to_head(center_x: float, center_y: float, width: float, height: float, keypoints_2d: np.array): + """ + Extreme cropping: Crop the box and keep on only the head. + Args: + center_x (float): x coordinate of the bounding box center. + center_y (float): y coordinate of the bounding box center. + width (float): Bounding box width. + height (float): Bounding box height. + keypoints_2d (np.array): Array of shape (N, 3) containing 2D keypoint locations. + Returns: + center_x (float): x coordinate of the new bounding box center. + center_y (float): y coordinate of the new bounding box center. + width (float): New bounding box width. + height (float): New bounding box height. + """ + keypoints_2d = keypoints_2d.copy() + lower_body_keypoints = [3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 19, 20, 21, 22, 23, 24] + [25 + i for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 16]] + keypoints_2d[lower_body_keypoints, :] = 0 + if keypoints_2d[:, -1].sum() > 1: + center, scale = get_bbox(keypoints_2d) + center_x = center[0] + center_y = center[1] + width = 1.3 * scale[0] + height = 1.3 * scale[1] + return center_x, center_y, width, height + +def crop_torso_only(center_x: float, center_y: float, width: float, height: float, keypoints_2d: np.array): + """ + Extreme cropping: Crop the box and keep on only the torso. + Args: + center_x (float): x coordinate of the bounding box center. + center_y (float): y coordinate of the bounding box center. + width (float): Bounding box width. + height (float): Bounding box height. + keypoints_2d (np.array): Array of shape (N, 3) containing 2D keypoint locations. + Returns: + center_x (float): x coordinate of the new bounding box center. + center_y (float): y coordinate of the new bounding box center. + width (float): New bounding box width. + height (float): New bounding box height. + """ + keypoints_2d = keypoints_2d.copy() + nontorso_body_keypoints = [0, 3, 4, 6, 7, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] + [25 + i for i in [0, 1, 4, 5, 6, 7, 10, 11, 13, 17, 18]] + keypoints_2d[nontorso_body_keypoints, :] = 0 + if keypoints_2d[:, -1].sum() > 1: + center, scale = get_bbox(keypoints_2d) + center_x = center[0] + center_y = center[1] + width = 1.1 * scale[0] + height = 1.1 * scale[1] + return center_x, center_y, width, height + +def crop_rightarm_only(center_x: float, center_y: float, width: float, height: float, keypoints_2d: np.array): + """ + Extreme cropping: Crop the box and keep on only the right arm. + Args: + center_x (float): x coordinate of the bounding box center. + center_y (float): y coordinate of the bounding box center. + width (float): Bounding box width. + height (float): Bounding box height. + keypoints_2d (np.array): Array of shape (N, 3) containing 2D keypoint locations. + Returns: + center_x (float): x coordinate of the new bounding box center. + center_y (float): y coordinate of the new bounding box center. + width (float): New bounding box width. + height (float): New bounding box height. + """ + keypoints_2d = keypoints_2d.copy() + nonrightarm_body_keypoints = [0, 1, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] + [25 + i for i in [0, 1, 2, 3, 4, 5, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]] + keypoints_2d[nonrightarm_body_keypoints, :] = 0 + if keypoints_2d[:, -1].sum() > 1: + center, scale = get_bbox(keypoints_2d) + center_x = center[0] + center_y = center[1] + width = 1.1 * scale[0] + height = 1.1 * scale[1] + return center_x, center_y, width, height + +def crop_leftarm_only(center_x: float, center_y: float, width: float, height: float, keypoints_2d: np.array): + """ + Extreme cropping: Crop the box and keep on only the left arm. + Args: + center_x (float): x coordinate of the bounding box center. + center_y (float): y coordinate of the bounding box center. + width (float): Bounding box width. + height (float): Bounding box height. + keypoints_2d (np.array): Array of shape (N, 3) containing 2D keypoint locations. + Returns: + center_x (float): x coordinate of the new bounding box center. + center_y (float): y coordinate of the new bounding box center. + width (float): New bounding box width. + height (float): New bounding box height. + """ + keypoints_2d = keypoints_2d.copy() + nonleftarm_body_keypoints = [0, 1, 2, 3, 4, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] + [25 + i for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 13, 14, 15, 16, 17, 18]] + keypoints_2d[nonleftarm_body_keypoints, :] = 0 + if keypoints_2d[:, -1].sum() > 1: + center, scale = get_bbox(keypoints_2d) + center_x = center[0] + center_y = center[1] + width = 1.1 * scale[0] + height = 1.1 * scale[1] + return center_x, center_y, width, height + +def crop_legs_only(center_x: float, center_y: float, width: float, height: float, keypoints_2d: np.array): + """ + Extreme cropping: Crop the box and keep on only the legs. + Args: + center_x (float): x coordinate of the bounding box center. + center_y (float): y coordinate of the bounding box center. + width (float): Bounding box width. + height (float): Bounding box height. + keypoints_2d (np.array): Array of shape (N, 3) containing 2D keypoint locations. + Returns: + center_x (float): x coordinate of the new bounding box center. + center_y (float): y coordinate of the new bounding box center. + width (float): New bounding box width. + height (float): New bounding box height. + """ + keypoints_2d = keypoints_2d.copy() + nonlegs_body_keypoints = [0, 1, 2, 3, 4, 5, 6, 7, 15, 16, 17, 18] + [25 + i for i in [6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18]] + keypoints_2d[nonlegs_body_keypoints, :] = 0 + if keypoints_2d[:, -1].sum() > 1: + center, scale = get_bbox(keypoints_2d) + center_x = center[0] + center_y = center[1] + width = 1.1 * scale[0] + height = 1.1 * scale[1] + return center_x, center_y, width, height + +def crop_rightleg_only(center_x: float, center_y: float, width: float, height: float, keypoints_2d: np.array): + """ + Extreme cropping: Crop the box and keep on only the right leg. + Args: + center_x (float): x coordinate of the bounding box center. + center_y (float): y coordinate of the bounding box center. + width (float): Bounding box width. + height (float): Bounding box height. + keypoints_2d (np.array): Array of shape (N, 3) containing 2D keypoint locations. + Returns: + center_x (float): x coordinate of the new bounding box center. + center_y (float): y coordinate of the new bounding box center. + width (float): New bounding box width. + height (float): New bounding box height. + """ + keypoints_2d = keypoints_2d.copy() + nonrightleg_body_keypoints = [0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21] + [25 + i for i in [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]] + keypoints_2d[nonrightleg_body_keypoints, :] = 0 + if keypoints_2d[:, -1].sum() > 1: + center, scale = get_bbox(keypoints_2d) + center_x = center[0] + center_y = center[1] + width = 1.1 * scale[0] + height = 1.1 * scale[1] + return center_x, center_y, width, height + +def crop_leftleg_only(center_x: float, center_y: float, width: float, height: float, keypoints_2d: np.array): + """ + Extreme cropping: Crop the box and keep on only the left leg. + Args: + center_x (float): x coordinate of the bounding box center. + center_y (float): y coordinate of the bounding box center. + width (float): Bounding box width. + height (float): Bounding box height. + keypoints_2d (np.array): Array of shape (N, 3) containing 2D keypoint locations. + Returns: + center_x (float): x coordinate of the new bounding box center. + center_y (float): y coordinate of the new bounding box center. + width (float): New bounding box width. + height (float): New bounding box height. + """ + keypoints_2d = keypoints_2d.copy() + nonleftleg_body_keypoints = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15, 16, 17, 18, 22, 23, 24] + [25 + i for i in [0, 1, 2, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]] + keypoints_2d[nonleftleg_body_keypoints, :] = 0 + if keypoints_2d[:, -1].sum() > 1: + center, scale = get_bbox(keypoints_2d) + center_x = center[0] + center_y = center[1] + width = 1.1 * scale[0] + height = 1.1 * scale[1] + return center_x, center_y, width, height + +def full_body(keypoints_2d: np.array) -> bool: + """ + Check if all main body joints are visible. + Args: + keypoints_2d (np.array): Array of shape (N, 3) containing 2D keypoint locations. + Returns: + bool: True if all main body joints are visible. + """ + + body_keypoints_openpose = [2, 3, 4, 5, 6, 7, 10, 11, 13, 14] + body_keypoints = [25 + i for i in [8, 7, 6, 9, 10, 11, 1, 0, 4, 5]] + return (np.maximum(keypoints_2d[body_keypoints, -1], keypoints_2d[body_keypoints_openpose, -1]) > 0).sum() == len(body_keypoints) + +def upper_body(keypoints_2d: np.array): + """ + Check if all upper body joints are visible. + Args: + keypoints_2d (np.array): Array of shape (N, 3) containing 2D keypoint locations. + Returns: + bool: True if all main body joints are visible. + """ + lower_body_keypoints_openpose = [10, 11, 13, 14] + lower_body_keypoints = [25 + i for i in [1, 0, 4, 5]] + upper_body_keypoints_openpose = [0, 1, 15, 16, 17, 18] + upper_body_keypoints = [25+8, 25+9, 25+12, 25+13, 25+17, 25+18] + return ((keypoints_2d[lower_body_keypoints + lower_body_keypoints_openpose, -1] > 0).sum() == 0)\ + and ((keypoints_2d[upper_body_keypoints + upper_body_keypoints_openpose, -1] > 0).sum() >= 2) + +def get_bbox(keypoints_2d: np.array, rescale: float = 1.2) -> Tuple: + """ + Get center and scale for bounding box from openpose detections. + Args: + keypoints_2d (np.array): Array of shape (N, 3) containing 2D keypoint locations. + rescale (float): Scale factor to rescale bounding boxes computed from the keypoints. + Returns: + center (np.array): Array of shape (2,) containing the new bounding box center. + scale (float): New bounding box scale. + """ + valid = keypoints_2d[:,-1] > 0 + valid_keypoints = keypoints_2d[valid][:,:-1] + center = 0.5 * (valid_keypoints.max(axis=0) + valid_keypoints.min(axis=0)) + bbox_size = (valid_keypoints.max(axis=0) - valid_keypoints.min(axis=0)) + # adjust bounding box tightness + scale = bbox_size + scale *= rescale + return center, scale + +def extreme_cropping(center_x: float, center_y: float, width: float, height: float, keypoints_2d: np.array) -> Tuple: + """ + Perform extreme cropping + Args: + center_x (float): x coordinate of bounding box center. + center_y (float): y coordinate of bounding box center. + width (float): bounding box width. + height (float): bounding box height. + keypoints_2d (np.array): Array of shape (N, 3) containing 2D keypoint locations. + rescale (float): Scale factor to rescale bounding boxes computed from the keypoints. + Returns: + center_x (float): x coordinate of bounding box center. + center_y (float): y coordinate of bounding box center. + width (float): bounding box width. + height (float): bounding box height. + """ + p = torch.rand(1).item() + if full_body(keypoints_2d): + if p < 0.7: + center_x, center_y, width, height = crop_to_hips(center_x, center_y, width, height, keypoints_2d) + elif p < 0.9: + center_x, center_y, width, height = crop_to_shoulders(center_x, center_y, width, height, keypoints_2d) + else: + center_x, center_y, width, height = crop_to_head(center_x, center_y, width, height, keypoints_2d) + elif upper_body(keypoints_2d): + if p < 0.9: + center_x, center_y, width, height = crop_to_shoulders(center_x, center_y, width, height, keypoints_2d) + else: + center_x, center_y, width, height = crop_to_head(center_x, center_y, width, height, keypoints_2d) + + return center_x, center_y, max(width, height), max(width, height) + +def extreme_cropping_aggressive(center_x: float, center_y: float, width: float, height: float, keypoints_2d: np.array) -> Tuple: + """ + Perform aggressive extreme cropping + Args: + center_x (float): x coordinate of bounding box center. + center_y (float): y coordinate of bounding box center. + width (float): bounding box width. + height (float): bounding box height. + keypoints_2d (np.array): Array of shape (N, 3) containing 2D keypoint locations. + rescale (float): Scale factor to rescale bounding boxes computed from the keypoints. + Returns: + center_x (float): x coordinate of bounding box center. + center_y (float): y coordinate of bounding box center. + width (float): bounding box width. + height (float): bounding box height. + """ + p = torch.rand(1).item() + if full_body(keypoints_2d): + if p < 0.2: + center_x, center_y, width, height = crop_to_hips(center_x, center_y, width, height, keypoints_2d) + elif p < 0.3: + center_x, center_y, width, height = crop_to_shoulders(center_x, center_y, width, height, keypoints_2d) + elif p < 0.4: + center_x, center_y, width, height = crop_to_head(center_x, center_y, width, height, keypoints_2d) + elif p < 0.5: + center_x, center_y, width, height = crop_torso_only(center_x, center_y, width, height, keypoints_2d) + elif p < 0.6: + center_x, center_y, width, height = crop_rightarm_only(center_x, center_y, width, height, keypoints_2d) + elif p < 0.7: + center_x, center_y, width, height = crop_leftarm_only(center_x, center_y, width, height, keypoints_2d) + elif p < 0.8: + center_x, center_y, width, height = crop_legs_only(center_x, center_y, width, height, keypoints_2d) + elif p < 0.9: + center_x, center_y, width, height = crop_rightleg_only(center_x, center_y, width, height, keypoints_2d) + else: + center_x, center_y, width, height = crop_leftleg_only(center_x, center_y, width, height, keypoints_2d) + elif upper_body(keypoints_2d): + if p < 0.2: + center_x, center_y, width, height = crop_to_shoulders(center_x, center_y, width, height, keypoints_2d) + elif p < 0.4: + center_x, center_y, width, height = crop_to_head(center_x, center_y, width, height, keypoints_2d) + elif p < 0.6: + center_x, center_y, width, height = crop_torso_only(center_x, center_y, width, height, keypoints_2d) + elif p < 0.8: + center_x, center_y, width, height = crop_rightarm_only(center_x, center_y, width, height, keypoints_2d) + else: + center_x, center_y, width, height = crop_leftarm_only(center_x, center_y, width, height, keypoints_2d) + return center_x, center_y, max(width, height), max(width, height) diff --git a/motiondiff_modules/hmr2/datasets/vitdet_dataset.py b/motiondiff_modules/hmr2/datasets/vitdet_dataset.py new file mode 100644 index 0000000..c1ddfd6 --- /dev/null +++ b/motiondiff_modules/hmr2/datasets/vitdet_dataset.py @@ -0,0 +1,88 @@ +from typing import Dict + +import cv2 +import numpy as np +from skimage.filters import gaussian +from yacs.config import CfgNode +import torch + +from .utils import (convert_cvimg_to_tensor, + expand_to_aspect_ratio, + generate_image_patch_cv2) + +DEFAULT_MEAN = 255. * np.array([0.485, 0.456, 0.406]) +DEFAULT_STD = 255. * np.array([0.229, 0.224, 0.225]) + +class ViTDetDataset(torch.utils.data.Dataset): + + def __init__(self, + cfg: CfgNode, + img_cv2: np.array, + boxes: np.array, + train: bool = False, + **kwargs): + super().__init__() + self.cfg = cfg + self.img_cv2 = img_cv2 + # self.boxes = boxes + + assert train == False, "ViTDetDataset is only for inference" + self.train = train + self.img_size = cfg.MODEL.IMAGE_SIZE + self.mean = 255. * np.array(self.cfg.MODEL.IMAGE_MEAN) + self.std = 255. * np.array(self.cfg.MODEL.IMAGE_STD) + + # Preprocess annotations + boxes = boxes.astype(np.float32) + self.center = (boxes[:, 2:4] + boxes[:, 0:2]) / 2.0 + self.scale = (boxes[:, 2:4] - boxes[:, 0:2]) / 200.0 + self.personid = np.arange(len(boxes), dtype=np.int32) + + def __len__(self) -> int: + return len(self.personid) + + def __getitem__(self, idx: int) -> Dict[str, np.array]: + + center = self.center[idx].copy() + center_x = center[0] + center_y = center[1] + + scale = self.scale[idx] + BBOX_SHAPE = self.cfg.MODEL.get('BBOX_SHAPE', None) + bbox_size = expand_to_aspect_ratio(scale*200, target_aspect_ratio=BBOX_SHAPE).max() + + patch_width = patch_height = self.img_size + + # 3. generate image patch + # if use_skimage_antialias: + cvimg = self.img_cv2.copy() + if True: + # Blur image to avoid aliasing artifacts + downsampling_factor = ((bbox_size*1.0) / patch_width) + # print(f'{downsampling_factor=}') + downsampling_factor = downsampling_factor / 2.0 + if downsampling_factor > 1.1: + cvimg = gaussian(cvimg, sigma=(downsampling_factor-1)/2, channel_axis=2, preserve_range=True) + + + img_patch_cv, trans = generate_image_patch_cv2(cvimg, + center_x, center_y, + bbox_size, bbox_size, + patch_width, patch_height, + False, 1.0, 0, + border_mode=cv2.BORDER_CONSTANT) + img_patch_cv = img_patch_cv[:, :, ::-1] + img_patch = convert_cvimg_to_tensor(img_patch_cv) + + # apply normalization + for n_c in range(min(self.img_cv2.shape[2], 3)): + img_patch[n_c, :, :] = (img_patch[n_c, :, :] - self.mean[n_c]) / self.std[n_c] + + item = { + 'img': img_patch, + 'personid': int(self.personid[idx]), + } + item['box_center'] = self.center[idx].copy() + item['box_size'] = bbox_size + item['img_size'] = 1.0 * np.array([cvimg.shape[1], cvimg.shape[0]]) + return item diff --git a/motiondiff_modules/hmr2/models/__init__.py b/motiondiff_modules/hmr2/models/__init__.py new file mode 100644 index 0000000..e2d4dee --- /dev/null +++ b/motiondiff_modules/hmr2/models/__init__.py @@ -0,0 +1,90 @@ +from .smpl_wrapper import SMPL +from .hmr2_arch import HMR2 +from .discriminator import Discriminator + +from ..utils.download import cache_url +from ..configs import CACHE_DIR_4DHUMANS + + +def download_models(folder=CACHE_DIR_4DHUMANS, extra_filename_links={}): + """Download checkpoints and files for running inference. + """ + import os + os.makedirs(folder, exist_ok=True) + download_files = { + "model_config.yaml": ["https://huggingface.co/spaces/brjathu/HMR2.0/raw/main/logs/train/multiruns/hmr2/0/model_config.yaml", folder], + "epoch=35-step=1000000.ckpt": ["https://huggingface.co/spaces/brjathu/HMR2.0/resolve/main/logs/train/multiruns/hmr2/0/checkpoints/epoch%3D35-step%3D1000000.ckpt", folder], + "SMPL_NEUTRAL.pkl": ["https://huggingface.co/spaces/brjathu/HMR2.0/resolve/main/data/smpl/SMPL_NEUTRAL.pkl", os.path.join(folder, 'data', 'smpl')], + "SMPL_to_J19.pkl": ["https://huggingface.co/spaces/brjathu/HMR2.0/resolve/main/data/SMPL_to_J19.pkl", os.path.join(folder, 'data')], + "smpl_mean_params.npz": ["https://huggingface.co/spaces/brjathu/HMR2.0/resolve/main/data/smpl_mean_params.npz", os.path.join(folder, 'data')], + **{filename: [link, folder] for filename, link in extra_filename_links.items()} + } + for file_name, url in download_files.items(): + output_path = os.path.join(url[1], file_name) + if not os.path.exists(output_path): + log = "smpl" not in file_name.lower() + if log: + print("Downloading file: " + file_name) + # output = gdown.cached_download(url[0], output_path, fuzzy=True) + output = cache_url(url[0], output_path, log=log) + assert os.path.exists(output_path), f"{output} does not exist" + + # if ends with tar.gz, tar -xzf + if file_name.endswith(".tar.gz"): + print("Extracting file: " + file_name) + os.system("tar -xvf " + output_path + " -C " + url[1]) + +def check_smpl_exists(): + import os + candidates = [ + f'{CACHE_DIR_4DHUMANS}/data/smpl/SMPL_NEUTRAL.pkl' + ] + candidates_exist = [os.path.exists(c) for c in candidates] + if not any(candidates_exist): + raise FileNotFoundError(f"SMPL model not found. Please download it from https://smplify.is.tue.mpg.de/ and place it at {candidates[0]}") + + # Code edxpects SMPL model at CACHE_DIR_4DHUMANS/data/smpl/SMPL_NEUTRAL.pkl. Copy there if needed + if (not candidates_exist[0]) and candidates_exist[1]: + convert_pkl(candidates[1], candidates[0]) + + return True + +# Convert SMPL pkl file to be compatible with Python 3 +# Script is from https://rebeccabilbro.github.io/convert-py2-pickles-to-py3/ +def convert_pkl(old_pkl, new_pkl): + """ + Convert a Python 2 pickle to Python 3 + """ + import dill + import pickle + + # Convert Python 2 "ObjectType" to Python 3 object + dill._dill._reverse_typemap["ObjectType"] = object + + # Open the pickle using latin1 encoding + with open(old_pkl, "rb") as f: + loaded = pickle.load(f, encoding="latin1") + + # Re-save as Python 3 pickle + with open(new_pkl, "wb") as outfile: + pickle.dump(loaded, outfile) + +DEFAULT_CHECKPOINT=f'{CACHE_DIR_4DHUMANS}/epoch=35-step=1000000.ckpt' +def load_hmr2(checkpoint_path=DEFAULT_CHECKPOINT): + from pathlib import Path + from ..configs import get_config + model_cfg = str(Path(checkpoint_path).parent / 'model_config.yaml') + model_cfg = get_config(model_cfg, update_cachedir=True) + + # Override some config values, to crop bbox correctly + if (model_cfg.MODEL.BACKBONE.TYPE == 'vit') and ('BBOX_SHAPE' not in model_cfg.MODEL): + model_cfg.defrost() + assert model_cfg.MODEL.IMAGE_SIZE == 256, f"MODEL.IMAGE_SIZE ({model_cfg.MODEL.IMAGE_SIZE}) should be 256 for ViT backbone" + model_cfg.MODEL.BBOX_SHAPE = [192,256] + model_cfg.freeze() + + # Ensure SMPL model exists + check_smpl_exists() + + model = HMR2.load_from_checkpoint(checkpoint_path, strict=False, cfg=model_cfg) + return model, model_cfg diff --git a/motiondiff_modules/hmr2/models/backbones/__init__.py b/motiondiff_modules/hmr2/models/backbones/__init__.py new file mode 100644 index 0000000..d2b217b --- /dev/null +++ b/motiondiff_modules/hmr2/models/backbones/__init__.py @@ -0,0 +1,7 @@ +from .vit import vit + +def create_backbone(cfg): + if cfg.MODEL.BACKBONE.TYPE == 'vit': + return vit(cfg) + else: + raise NotImplementedError('Backbone type is not implemented') diff --git a/motiondiff_modules/hmr2/models/backbones/vit.py b/motiondiff_modules/hmr2/models/backbones/vit.py new file mode 100644 index 0000000..c56c718 --- /dev/null +++ b/motiondiff_modules/hmr2/models/backbones/vit.py @@ -0,0 +1,348 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import math + +import torch +from functools import partial +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.checkpoint as checkpoint + +from timm.models.layers import drop_path, to_2tuple, trunc_normal_ + +def vit(cfg): + return ViT( + img_size=(256, 192), + patch_size=16, + embed_dim=1280, + depth=32, + num_heads=16, + ratio=1, + use_checkpoint=False, + mlp_ratio=4, + qkv_bias=True, + drop_path_rate=0.55, + ) + +def get_abs_pos(abs_pos, h, w, ori_h, ori_w, has_cls_token=True): + """ + Calculate absolute positional embeddings. If needed, resize embeddings and remove cls_token + dimension for the original embeddings. + Args: + abs_pos (Tensor): absolute positional embeddings with (1, num_position, C). + has_cls_token (bool): If true, has 1 embedding in abs_pos for cls token. + hw (Tuple): size of input image tokens. + + Returns: + Absolute positional embeddings after processing with shape (1, H, W, C) + """ + cls_token = None + B, L, C = abs_pos.shape + if has_cls_token: + cls_token = abs_pos[:, 0:1] + abs_pos = abs_pos[:, 1:] + + if ori_h != h or ori_w != w: + new_abs_pos = F.interpolate( + abs_pos.reshape(1, ori_h, ori_w, -1).permute(0, 3, 1, 2), + size=(h, w), + mode="bicubic", + align_corners=False, + ).permute(0, 2, 3, 1).reshape(B, -1, C) + + else: + new_abs_pos = abs_pos + + if cls_token is not None: + new_abs_pos = torch.cat([cls_token, new_abs_pos], dim=1) + return new_abs_pos + +class DropPath(nn.Module): + """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). + """ + def __init__(self, drop_prob=None): + super(DropPath, self).__init__() + self.drop_prob = drop_prob + + def forward(self, x): + return drop_path(x, self.drop_prob, self.training) + + def extra_repr(self): + return 'p={}'.format(self.drop_prob) + +class Mlp(nn.Module): + def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.): + super().__init__() + out_features = out_features or in_features + hidden_features = hidden_features or in_features + self.fc1 = nn.Linear(in_features, hidden_features) + self.act = act_layer() + self.fc2 = nn.Linear(hidden_features, out_features) + self.drop = nn.Dropout(drop) + + def forward(self, x): + x = self.fc1(x) + x = self.act(x) + x = self.fc2(x) + x = self.drop(x) + return x + +class Attention(nn.Module): + def __init__( + self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0., + proj_drop=0., attn_head_dim=None,): + super().__init__() + self.num_heads = num_heads + head_dim = dim // num_heads + self.dim = dim + + if attn_head_dim is not None: + head_dim = attn_head_dim + all_head_dim = head_dim * self.num_heads + + self.scale = qk_scale or head_dim ** -0.5 + + self.qkv = nn.Linear(dim, all_head_dim * 3, bias=qkv_bias) + + self.attn_drop = nn.Dropout(attn_drop) + self.proj = nn.Linear(all_head_dim, dim) + self.proj_drop = nn.Dropout(proj_drop) + + def forward(self, x): + B, N, C = x.shape + qkv = self.qkv(x) + qkv = qkv.reshape(B, N, 3, self.num_heads, -1).permute(2, 0, 3, 1, 4) + q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple) + + q = q * self.scale + attn = (q @ k.transpose(-2, -1)) + + attn = attn.softmax(dim=-1) + attn = self.attn_drop(attn) + + x = (attn @ v).transpose(1, 2).reshape(B, N, -1) + x = self.proj(x) + x = self.proj_drop(x) + + return x + +class Block(nn.Module): + + def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, + drop=0., attn_drop=0., drop_path=0., act_layer=nn.GELU, + norm_layer=nn.LayerNorm, attn_head_dim=None + ): + super().__init__() + + self.norm1 = norm_layer(dim) + self.attn = Attention( + dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, + attn_drop=attn_drop, proj_drop=drop, attn_head_dim=attn_head_dim + ) + + # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here + self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity() + self.norm2 = norm_layer(dim) + mlp_hidden_dim = int(dim * mlp_ratio) + self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop) + + def forward(self, x): + x = x + self.drop_path(self.attn(self.norm1(x))) + x = x + self.drop_path(self.mlp(self.norm2(x))) + return x + + +class PatchEmbed(nn.Module): + """ Image to Patch Embedding + """ + def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768, ratio=1): + super().__init__() + img_size = to_2tuple(img_size) + patch_size = to_2tuple(patch_size) + num_patches = (img_size[1] // patch_size[1]) * (img_size[0] // patch_size[0]) * (ratio ** 2) + self.patch_shape = (int(img_size[0] // patch_size[0] * ratio), int(img_size[1] // patch_size[1] * ratio)) + self.origin_patch_shape = (int(img_size[0] // patch_size[0]), int(img_size[1] // patch_size[1])) + self.img_size = img_size + self.patch_size = patch_size + self.num_patches = num_patches + + self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=(patch_size[0] // ratio), padding=4 + 2 * (ratio//2-1)) + + def forward(self, x, **kwargs): + B, C, H, W = x.shape + x = self.proj(x) + Hp, Wp = x.shape[2], x.shape[3] + + x = x.flatten(2).transpose(1, 2) + return x, (Hp, Wp) + + +class HybridEmbed(nn.Module): + """ CNN Feature Map Embedding + Extract feature map from CNN, flatten, project to embedding dim. + """ + def __init__(self, backbone, img_size=224, feature_size=None, in_chans=3, embed_dim=768): + super().__init__() + assert isinstance(backbone, nn.Module) + img_size = to_2tuple(img_size) + self.img_size = img_size + self.backbone = backbone + if feature_size is None: + with torch.no_grad(): + training = backbone.training + if training: + backbone.eval() + o = self.backbone(torch.zeros(1, in_chans, img_size[0], img_size[1]))[-1] + feature_size = o.shape[-2:] + feature_dim = o.shape[1] + backbone.train(training) + else: + feature_size = to_2tuple(feature_size) + feature_dim = self.backbone.feature_info.channels()[-1] + self.num_patches = feature_size[0] * feature_size[1] + self.proj = nn.Linear(feature_dim, embed_dim) + + def forward(self, x): + x = self.backbone(x)[-1] + x = x.flatten(2).transpose(1, 2) + x = self.proj(x) + return x + + +class ViT(nn.Module): + + def __init__(self, + img_size=224, patch_size=16, in_chans=3, num_classes=80, embed_dim=768, depth=12, + num_heads=12, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop_rate=0., attn_drop_rate=0., + drop_path_rate=0., hybrid_backbone=None, norm_layer=None, use_checkpoint=False, + frozen_stages=-1, ratio=1, last_norm=True, + patch_padding='pad', freeze_attn=False, freeze_ffn=False, + ): + # Protect mutable default arguments + super(ViT, self).__init__() + norm_layer = norm_layer or partial(nn.LayerNorm, eps=1e-6) + self.num_classes = num_classes + self.num_features = self.embed_dim = embed_dim # num_features for consistency with other models + self.frozen_stages = frozen_stages + self.use_checkpoint = use_checkpoint + self.patch_padding = patch_padding + self.freeze_attn = freeze_attn + self.freeze_ffn = freeze_ffn + self.depth = depth + + if hybrid_backbone is not None: + self.patch_embed = HybridEmbed( + hybrid_backbone, img_size=img_size, in_chans=in_chans, embed_dim=embed_dim) + else: + self.patch_embed = PatchEmbed( + img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim, ratio=ratio) + num_patches = self.patch_embed.num_patches + + # since the pretraining model has class token + self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim)) + + dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)] # stochastic depth decay rule + + self.blocks = nn.ModuleList([ + Block( + dim=embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale, + drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i], norm_layer=norm_layer, + ) + for i in range(depth)]) + + self.last_norm = norm_layer(embed_dim) if last_norm else nn.Identity() + + if self.pos_embed is not None: + trunc_normal_(self.pos_embed, std=.02) + + self._freeze_stages() + + def _freeze_stages(self): + """Freeze parameters.""" + if self.frozen_stages >= 0: + self.patch_embed.eval() + for param in self.patch_embed.parameters(): + param.requires_grad = False + + for i in range(1, self.frozen_stages + 1): + m = self.blocks[i] + m.eval() + for param in m.parameters(): + param.requires_grad = False + + if self.freeze_attn: + for i in range(0, self.depth): + m = self.blocks[i] + m.attn.eval() + m.norm1.eval() + for param in m.attn.parameters(): + param.requires_grad = False + for param in m.norm1.parameters(): + param.requires_grad = False + + if self.freeze_ffn: + self.pos_embed.requires_grad = False + self.patch_embed.eval() + for param in self.patch_embed.parameters(): + param.requires_grad = False + for i in range(0, self.depth): + m = self.blocks[i] + m.mlp.eval() + m.norm2.eval() + for param in m.mlp.parameters(): + param.requires_grad = False + for param in m.norm2.parameters(): + param.requires_grad = False + + def init_weights(self): + """Initialize the weights in backbone. + Args: + pretrained (str, optional): Path to pre-trained weights. + Defaults to None. + """ + def _init_weights(m): + if isinstance(m, nn.Linear): + trunc_normal_(m.weight, std=.02) + if isinstance(m, nn.Linear) and m.bias is not None: + nn.init.constant_(m.bias, 0) + elif isinstance(m, nn.LayerNorm): + nn.init.constant_(m.bias, 0) + nn.init.constant_(m.weight, 1.0) + + self.apply(_init_weights) + + def get_num_layers(self): + return len(self.blocks) + + @torch.jit.ignore + def no_weight_decay(self): + return {'pos_embed', 'cls_token'} + + def forward_features(self, x): + B, C, H, W = x.shape + x, (Hp, Wp) = self.patch_embed(x) + + if self.pos_embed is not None: + # fit for multiple GPU training + # since the first element for pos embed (sin-cos manner) is zero, it will cause no difference + x = x + self.pos_embed[:, 1:] + self.pos_embed[:, :1] + + for blk in self.blocks: + if self.use_checkpoint: + x = checkpoint.checkpoint(blk, x) + else: + x = blk(x) + + x = self.last_norm(x) + + xp = x.permute(0, 2, 1).reshape(B, -1, Hp, Wp).contiguous() + + return xp + + def forward(self, x): + x = self.forward_features(x) + return x + + def train(self, mode=True): + """Convert the model into training mode.""" + super().train(mode) + self._freeze_stages() diff --git a/motiondiff_modules/hmr2/models/backbones/vit_vitpose.py b/motiondiff_modules/hmr2/models/backbones/vit_vitpose.py new file mode 100644 index 0000000..1ef5eaf --- /dev/null +++ b/motiondiff_modules/hmr2/models/backbones/vit_vitpose.py @@ -0,0 +1,17 @@ +# import mmcv +# import mmpose +# from mmpose.models import build_posenet +# from mmcv.runner import load_checkpoint +# from pathlib import Path + +# def vit(cfg): +# vitpose_dir = Path(mmpose.__file__).parent.parent +# config = f'{vitpose_dir}/configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/ViTPose_huge_coco_256x192.py' +# # checkpoint = f'{vitpose_dir}/models/vitpose-h-multi-coco.pth' + +# config = mmcv.Config.fromfile(config) +# config.model.pretrained = None +# model = build_posenet(config.model) +# # load_checkpoint(model, checkpoint, map_location='cpu') + +# return model.backbone diff --git a/motiondiff_modules/hmr2/models/components/__init__.py b/motiondiff_modules/hmr2/models/components/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/motiondiff_modules/hmr2/models/components/pose_transformer.py b/motiondiff_modules/hmr2/models/components/pose_transformer.py new file mode 100644 index 0000000..ac04971 --- /dev/null +++ b/motiondiff_modules/hmr2/models/components/pose_transformer.py @@ -0,0 +1,358 @@ +from inspect import isfunction +from typing import Callable, Optional + +import torch +from einops import rearrange +from einops.layers.torch import Rearrange +from torch import nn + +from .t_cond_mlp import ( + AdaptiveLayerNorm1D, + FrequencyEmbedder, + normalization_layer, +) +# from .vit import Attention, FeedForward + + +def exists(val): + return val is not None + + +def default(val, d): + if exists(val): + return val + return d() if isfunction(d) else d + + +class PreNorm(nn.Module): + def __init__(self, dim: int, fn: Callable, norm: str = "layer", norm_cond_dim: int = -1): + super().__init__() + self.norm = normalization_layer(norm, dim, norm_cond_dim) + self.fn = fn + + def forward(self, x: torch.Tensor, *args, **kwargs): + if isinstance(self.norm, AdaptiveLayerNorm1D): + return self.fn(self.norm(x, *args), **kwargs) + else: + return self.fn(self.norm(x), **kwargs) + + +class FeedForward(nn.Module): + def __init__(self, dim, hidden_dim, dropout=0.0): + super().__init__() + self.net = nn.Sequential( + nn.Linear(dim, hidden_dim), + nn.GELU(), + nn.Dropout(dropout), + nn.Linear(hidden_dim, dim), + nn.Dropout(dropout), + ) + + def forward(self, x): + return self.net(x) + + +class Attention(nn.Module): + def __init__(self, dim, heads=8, dim_head=64, dropout=0.0): + super().__init__() + inner_dim = dim_head * heads + project_out = not (heads == 1 and dim_head == dim) + + self.heads = heads + self.scale = dim_head**-0.5 + + self.attend = nn.Softmax(dim=-1) + self.dropout = nn.Dropout(dropout) + + self.to_qkv = nn.Linear(dim, inner_dim * 3, bias=False) + + self.to_out = ( + nn.Sequential(nn.Linear(inner_dim, dim), nn.Dropout(dropout)) + if project_out + else nn.Identity() + ) + + def forward(self, x): + qkv = self.to_qkv(x).chunk(3, dim=-1) + q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b h n d", h=self.heads), qkv) + + dots = torch.matmul(q, k.transpose(-1, -2)) * self.scale + + attn = self.attend(dots) + attn = self.dropout(attn) + + out = torch.matmul(attn, v) + out = rearrange(out, "b h n d -> b n (h d)") + return self.to_out(out) + + +class CrossAttention(nn.Module): + def __init__(self, dim, context_dim=None, heads=8, dim_head=64, dropout=0.0): + super().__init__() + inner_dim = dim_head * heads + project_out = not (heads == 1 and dim_head == dim) + + self.heads = heads + self.scale = dim_head**-0.5 + + self.attend = nn.Softmax(dim=-1) + self.dropout = nn.Dropout(dropout) + + context_dim = default(context_dim, dim) + self.to_kv = nn.Linear(context_dim, inner_dim * 2, bias=False) + self.to_q = nn.Linear(dim, inner_dim, bias=False) + + self.to_out = ( + nn.Sequential(nn.Linear(inner_dim, dim), nn.Dropout(dropout)) + if project_out + else nn.Identity() + ) + + def forward(self, x, context=None): + context = default(context, x) + k, v = self.to_kv(context).chunk(2, dim=-1) + q = self.to_q(x) + q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b h n d", h=self.heads), [q, k, v]) + + dots = torch.matmul(q, k.transpose(-1, -2)) * self.scale + + attn = self.attend(dots) + attn = self.dropout(attn) + + out = torch.matmul(attn, v) + out = rearrange(out, "b h n d -> b n (h d)") + return self.to_out(out) + + +class Transformer(nn.Module): + def __init__( + self, + dim: int, + depth: int, + heads: int, + dim_head: int, + mlp_dim: int, + dropout: float = 0.0, + norm: str = "layer", + norm_cond_dim: int = -1, + ): + super().__init__() + self.layers = nn.ModuleList([]) + for _ in range(depth): + sa = Attention(dim, heads=heads, dim_head=dim_head, dropout=dropout) + ff = FeedForward(dim, mlp_dim, dropout=dropout) + self.layers.append( + nn.ModuleList( + [ + PreNorm(dim, sa, norm=norm, norm_cond_dim=norm_cond_dim), + PreNorm(dim, ff, norm=norm, norm_cond_dim=norm_cond_dim), + ] + ) + ) + + def forward(self, x: torch.Tensor, *args): + for attn, ff in self.layers: + x = attn(x, *args) + x + x = ff(x, *args) + x + return x + + +class TransformerCrossAttn(nn.Module): + def __init__( + self, + dim: int, + depth: int, + heads: int, + dim_head: int, + mlp_dim: int, + dropout: float = 0.0, + norm: str = "layer", + norm_cond_dim: int = -1, + context_dim: Optional[int] = None, + ): + super().__init__() + self.layers = nn.ModuleList([]) + for _ in range(depth): + sa = Attention(dim, heads=heads, dim_head=dim_head, dropout=dropout) + ca = CrossAttention( + dim, context_dim=context_dim, heads=heads, dim_head=dim_head, dropout=dropout + ) + ff = FeedForward(dim, mlp_dim, dropout=dropout) + self.layers.append( + nn.ModuleList( + [ + PreNorm(dim, sa, norm=norm, norm_cond_dim=norm_cond_dim), + PreNorm(dim, ca, norm=norm, norm_cond_dim=norm_cond_dim), + PreNorm(dim, ff, norm=norm, norm_cond_dim=norm_cond_dim), + ] + ) + ) + + def forward(self, x: torch.Tensor, *args, context=None, context_list=None): + if context_list is None: + context_list = [context] * len(self.layers) + if len(context_list) != len(self.layers): + raise ValueError(f"len(context_list) != len(self.layers) ({len(context_list)} != {len(self.layers)})") + + for i, (self_attn, cross_attn, ff) in enumerate(self.layers): + x = self_attn(x, *args) + x + x = cross_attn(x, *args, context=context_list[i]) + x + x = ff(x, *args) + x + return x + + +class DropTokenDropout(nn.Module): + def __init__(self, p: float = 0.1): + super().__init__() + if p < 0 or p > 1: + raise ValueError( + "dropout probability has to be between 0 and 1, " "but got {}".format(p) + ) + self.p = p + + def forward(self, x: torch.Tensor): + # x: (batch_size, seq_len, dim) + if self.training and self.p > 0: + zero_mask = torch.full_like(x[0, :, 0], self.p).bernoulli().bool() + # TODO: permutation idx for each batch using torch.argsort + if zero_mask.any(): + x = x[:, ~zero_mask, :] + return x + + +class ZeroTokenDropout(nn.Module): + def __init__(self, p: float = 0.1): + super().__init__() + if p < 0 or p > 1: + raise ValueError( + "dropout probability has to be between 0 and 1, " "but got {}".format(p) + ) + self.p = p + + def forward(self, x: torch.Tensor): + # x: (batch_size, seq_len, dim) + if self.training and self.p > 0: + zero_mask = torch.full_like(x[:, :, 0], self.p).bernoulli().bool() + # Zero-out the masked tokens + x[zero_mask, :] = 0 + return x + + +class TransformerEncoder(nn.Module): + def __init__( + self, + num_tokens: int, + token_dim: int, + dim: int, + depth: int, + heads: int, + mlp_dim: int, + dim_head: int = 64, + dropout: float = 0.0, + emb_dropout: float = 0.0, + emb_dropout_type: str = "drop", + emb_dropout_loc: str = "token", + norm: str = "layer", + norm_cond_dim: int = -1, + token_pe_numfreq: int = -1, + ): + super().__init__() + if token_pe_numfreq > 0: + token_dim_new = token_dim * (2 * token_pe_numfreq + 1) + self.to_token_embedding = nn.Sequential( + Rearrange("b n d -> (b n) d", n=num_tokens, d=token_dim), + FrequencyEmbedder(token_pe_numfreq, token_pe_numfreq - 1), + Rearrange("(b n) d -> b n d", n=num_tokens, d=token_dim_new), + nn.Linear(token_dim_new, dim), + ) + else: + self.to_token_embedding = nn.Linear(token_dim, dim) + self.pos_embedding = nn.Parameter(torch.randn(1, num_tokens, dim)) + if emb_dropout_type == "drop": + self.dropout = DropTokenDropout(emb_dropout) + elif emb_dropout_type == "zero": + self.dropout = ZeroTokenDropout(emb_dropout) + else: + raise ValueError(f"Unknown emb_dropout_type: {emb_dropout_type}") + self.emb_dropout_loc = emb_dropout_loc + + self.transformer = Transformer( + dim, depth, heads, dim_head, mlp_dim, dropout, norm=norm, norm_cond_dim=norm_cond_dim + ) + + def forward(self, inp: torch.Tensor, *args, **kwargs): + x = inp + + if self.emb_dropout_loc == "input": + x = self.dropout(x) + x = self.to_token_embedding(x) + + if self.emb_dropout_loc == "token": + x = self.dropout(x) + b, n, _ = x.shape + x += self.pos_embedding[:, :n] + + if self.emb_dropout_loc == "token_afterpos": + x = self.dropout(x) + x = self.transformer(x, *args) + return x + + +class TransformerDecoder(nn.Module): + def __init__( + self, + num_tokens: int, + token_dim: int, + dim: int, + depth: int, + heads: int, + mlp_dim: int, + dim_head: int = 64, + dropout: float = 0.0, + emb_dropout: float = 0.0, + emb_dropout_type: str = 'drop', + norm: str = "layer", + norm_cond_dim: int = -1, + context_dim: Optional[int] = None, + skip_token_embedding: bool = False, + ): + super().__init__() + if not skip_token_embedding: + self.to_token_embedding = nn.Linear(token_dim, dim) + else: + self.to_token_embedding = nn.Identity() + if token_dim != dim: + raise ValueError( + f"token_dim ({token_dim}) != dim ({dim}) when skip_token_embedding is True" + ) + + self.pos_embedding = nn.Parameter(torch.randn(1, num_tokens, dim)) + if emb_dropout_type == "drop": + self.dropout = DropTokenDropout(emb_dropout) + elif emb_dropout_type == "zero": + self.dropout = ZeroTokenDropout(emb_dropout) + elif emb_dropout_type == "normal": + self.dropout = nn.Dropout(emb_dropout) + + self.transformer = TransformerCrossAttn( + dim, + depth, + heads, + dim_head, + mlp_dim, + dropout, + norm=norm, + norm_cond_dim=norm_cond_dim, + context_dim=context_dim, + ) + + def forward(self, inp: torch.Tensor, *args, context=None, context_list=None): + x = self.to_token_embedding(inp) + b, n, _ = x.shape + + x = self.dropout(x) + x += self.pos_embedding[:, :n] + + x = self.transformer(x, *args, context=context, context_list=context_list) + return x + diff --git a/motiondiff_modules/hmr2/models/components/t_cond_mlp.py b/motiondiff_modules/hmr2/models/components/t_cond_mlp.py new file mode 100644 index 0000000..44d5a09 --- /dev/null +++ b/motiondiff_modules/hmr2/models/components/t_cond_mlp.py @@ -0,0 +1,199 @@ +import copy +from typing import List, Optional + +import torch + + +class AdaptiveLayerNorm1D(torch.nn.Module): + def __init__(self, data_dim: int, norm_cond_dim: int): + super().__init__() + if data_dim <= 0: + raise ValueError(f"data_dim must be positive, but got {data_dim}") + if norm_cond_dim <= 0: + raise ValueError(f"norm_cond_dim must be positive, but got {norm_cond_dim}") + self.norm = torch.nn.LayerNorm( + data_dim + ) # TODO: Check if elementwise_affine=True is correct + self.linear = torch.nn.Linear(norm_cond_dim, 2 * data_dim) + torch.nn.init.zeros_(self.linear.weight) + torch.nn.init.zeros_(self.linear.bias) + + def forward(self, x: torch.Tensor, t: torch.Tensor) -> torch.Tensor: + # x: (batch, ..., data_dim) + # t: (batch, norm_cond_dim) + # return: (batch, data_dim) + x = self.norm(x) + alpha, beta = self.linear(t).chunk(2, dim=-1) + + # Add singleton dimensions to alpha and beta + if x.dim() > 2: + alpha = alpha.view(alpha.shape[0], *([1] * (x.dim() - 2)), alpha.shape[1]) + beta = beta.view(beta.shape[0], *([1] * (x.dim() - 2)), beta.shape[1]) + + return x * (1 + alpha) + beta + + +class SequentialCond(torch.nn.Sequential): + def forward(self, input, *args, **kwargs): + for module in self: + if isinstance(module, (AdaptiveLayerNorm1D, SequentialCond, ResidualMLPBlock)): + # print(f'Passing on args to {module}', [a.shape for a in args]) + input = module(input, *args, **kwargs) + else: + # print(f'Skipping passing args to {module}', [a.shape for a in args]) + input = module(input) + return input + + +def normalization_layer(norm: Optional[str], dim: int, norm_cond_dim: int = -1): + if norm == "batch": + return torch.nn.BatchNorm1d(dim) + elif norm == "layer": + return torch.nn.LayerNorm(dim) + elif norm == "ada": + assert norm_cond_dim > 0, f"norm_cond_dim must be positive, got {norm_cond_dim}" + return AdaptiveLayerNorm1D(dim, norm_cond_dim) + elif norm is None: + return torch.nn.Identity() + else: + raise ValueError(f"Unknown norm: {norm}") + + +def linear_norm_activ_dropout( + input_dim: int, + output_dim: int, + activation: torch.nn.Module = torch.nn.ReLU(), + bias: bool = True, + norm: Optional[str] = "layer", # Options: ada/batch/layer + dropout: float = 0.0, + norm_cond_dim: int = -1, +) -> SequentialCond: + layers = [] + layers.append(torch.nn.Linear(input_dim, output_dim, bias=bias)) + if norm is not None: + layers.append(normalization_layer(norm, output_dim, norm_cond_dim)) + layers.append(copy.deepcopy(activation)) + if dropout > 0.0: + layers.append(torch.nn.Dropout(dropout)) + return SequentialCond(*layers) + + +def create_simple_mlp( + input_dim: int, + hidden_dims: List[int], + output_dim: int, + activation: torch.nn.Module = torch.nn.ReLU(), + bias: bool = True, + norm: Optional[str] = "layer", # Options: ada/batch/layer + dropout: float = 0.0, + norm_cond_dim: int = -1, +) -> SequentialCond: + layers = [] + prev_dim = input_dim + for hidden_dim in hidden_dims: + layers.extend( + linear_norm_activ_dropout( + prev_dim, hidden_dim, activation, bias, norm, dropout, norm_cond_dim + ) + ) + prev_dim = hidden_dim + layers.append(torch.nn.Linear(prev_dim, output_dim, bias=bias)) + return SequentialCond(*layers) + + +class ResidualMLPBlock(torch.nn.Module): + def __init__( + self, + input_dim: int, + hidden_dim: int, + num_hidden_layers: int, + output_dim: int, + activation: torch.nn.Module = torch.nn.ReLU(), + bias: bool = True, + norm: Optional[str] = "layer", # Options: ada/batch/layer + dropout: float = 0.0, + norm_cond_dim: int = -1, + ): + super().__init__() + if not (input_dim == output_dim == hidden_dim): + raise NotImplementedError( + f"input_dim {input_dim} != output_dim {output_dim} is not implemented" + ) + + layers = [] + prev_dim = input_dim + for i in range(num_hidden_layers): + layers.append( + linear_norm_activ_dropout( + prev_dim, hidden_dim, activation, bias, norm, dropout, norm_cond_dim + ) + ) + prev_dim = hidden_dim + self.model = SequentialCond(*layers) + self.skip = torch.nn.Identity() + + def forward(self, x: torch.Tensor, *args, **kwargs) -> torch.Tensor: + return x + self.model(x, *args, **kwargs) + + +class ResidualMLP(torch.nn.Module): + def __init__( + self, + input_dim: int, + hidden_dim: int, + num_hidden_layers: int, + output_dim: int, + activation: torch.nn.Module = torch.nn.ReLU(), + bias: bool = True, + norm: Optional[str] = "layer", # Options: ada/batch/layer + dropout: float = 0.0, + num_blocks: int = 1, + norm_cond_dim: int = -1, + ): + super().__init__() + self.input_dim = input_dim + self.model = SequentialCond( + linear_norm_activ_dropout( + input_dim, hidden_dim, activation, bias, norm, dropout, norm_cond_dim + ), + *[ + ResidualMLPBlock( + hidden_dim, + hidden_dim, + num_hidden_layers, + hidden_dim, + activation, + bias, + norm, + dropout, + norm_cond_dim, + ) + for _ in range(num_blocks) + ], + torch.nn.Linear(hidden_dim, output_dim, bias=bias), + ) + + def forward(self, x: torch.Tensor, *args, **kwargs) -> torch.Tensor: + return self.model(x, *args, **kwargs) + + +class FrequencyEmbedder(torch.nn.Module): + def __init__(self, num_frequencies, max_freq_log2): + super().__init__() + frequencies = 2 ** torch.linspace(0, max_freq_log2, steps=num_frequencies) + self.register_buffer("frequencies", frequencies) + + def forward(self, x): + # x should be of size (N,) or (N, D) + N = x.size(0) + if x.dim() == 1: # (N,) + x = x.unsqueeze(1) # (N, D) where D=1 + x_unsqueezed = x.unsqueeze(-1) # (N, D, 1) + scaled = self.frequencies.view(1, 1, -1) * x_unsqueezed # (N, D, num_frequencies) + s = torch.sin(scaled) + c = torch.cos(scaled) + embedded = torch.cat([s, c, x_unsqueezed], dim=-1).view( + N, -1 + ) # (N, D * 2 * num_frequencies + D) + return embedded + diff --git a/motiondiff_modules/hmr2/models/discriminator.py b/motiondiff_modules/hmr2/models/discriminator.py new file mode 100644 index 0000000..4fa11b9 --- /dev/null +++ b/motiondiff_modules/hmr2/models/discriminator.py @@ -0,0 +1,99 @@ +import torch +import torch.nn as nn + +class Discriminator(nn.Module): + + def __init__(self): + """ + Pose + Shape discriminator proposed in HMR + """ + super(Discriminator, self).__init__() + + self.num_joints = 23 + # poses_alone + self.D_conv1 = nn.Conv2d(9, 32, kernel_size=1) + nn.init.xavier_uniform_(self.D_conv1.weight) + nn.init.zeros_(self.D_conv1.bias) + self.relu = nn.ReLU(inplace=True) + self.D_conv2 = nn.Conv2d(32, 32, kernel_size=1) + nn.init.xavier_uniform_(self.D_conv2.weight) + nn.init.zeros_(self.D_conv2.bias) + pose_out = [] + for i in range(self.num_joints): + pose_out_temp = nn.Linear(32, 1) + nn.init.xavier_uniform_(pose_out_temp.weight) + nn.init.zeros_(pose_out_temp.bias) + pose_out.append(pose_out_temp) + self.pose_out = nn.ModuleList(pose_out) + + # betas + self.betas_fc1 = nn.Linear(10, 10) + nn.init.xavier_uniform_(self.betas_fc1.weight) + nn.init.zeros_(self.betas_fc1.bias) + self.betas_fc2 = nn.Linear(10, 5) + nn.init.xavier_uniform_(self.betas_fc2.weight) + nn.init.zeros_(self.betas_fc2.bias) + self.betas_out = nn.Linear(5, 1) + nn.init.xavier_uniform_(self.betas_out.weight) + nn.init.zeros_(self.betas_out.bias) + + # poses_joint + self.D_alljoints_fc1 = nn.Linear(32*self.num_joints, 1024) + nn.init.xavier_uniform_(self.D_alljoints_fc1.weight) + nn.init.zeros_(self.D_alljoints_fc1.bias) + self.D_alljoints_fc2 = nn.Linear(1024, 1024) + nn.init.xavier_uniform_(self.D_alljoints_fc2.weight) + nn.init.zeros_(self.D_alljoints_fc2.bias) + self.D_alljoints_out = nn.Linear(1024, 1) + nn.init.xavier_uniform_(self.D_alljoints_out.weight) + nn.init.zeros_(self.D_alljoints_out.bias) + + + def forward(self, poses: torch.Tensor, betas: torch.Tensor) -> torch.Tensor: + """ + Forward pass of the discriminator. + Args: + poses (torch.Tensor): Tensor of shape (B, 23, 3, 3) containing a batch of SMPL body poses (excluding the global orientation). + betas (torch.Tensor): Tensor of shape (B, 10) containign a batch of SMPL beta coefficients. + Returns: + torch.Tensor: Discriminator output with shape (B, 25) + """ + #import ipdb; ipdb.set_trace() + #bn = poses.shape[0] + # poses B x 207 + #poses = poses.reshape(bn, -1) + # poses B x num_joints x 1 x 9 + poses = poses.reshape(-1, self.num_joints, 1, 9) + bn = poses.shape[0] + # poses B x 9 x num_joints x 1 + poses = poses.permute(0, 3, 1, 2).contiguous() + + # poses_alone + poses = self.D_conv1(poses) + poses = self.relu(poses) + poses = self.D_conv2(poses) + poses = self.relu(poses) + + poses_out = [] + for i in range(self.num_joints): + poses_out_ = self.pose_out[i](poses[:, :, i, 0]) + poses_out.append(poses_out_) + poses_out = torch.cat(poses_out, dim=1) + + # betas + betas = self.betas_fc1(betas) + betas = self.relu(betas) + betas = self.betas_fc2(betas) + betas = self.relu(betas) + betas_out = self.betas_out(betas) + + # poses_joint + poses = poses.reshape(bn,-1) + poses_all = self.D_alljoints_fc1(poses) + poses_all = self.relu(poses_all) + poses_all = self.D_alljoints_fc2(poses_all) + poses_all = self.relu(poses_all) + poses_all_out = self.D_alljoints_out(poses_all) + + disc_out = torch.cat((poses_out, betas_out, poses_all_out), 1) + return disc_out diff --git a/motiondiff_modules/hmr2/models/heads/__init__.py b/motiondiff_modules/hmr2/models/heads/__init__.py new file mode 100644 index 0000000..d993f8d --- /dev/null +++ b/motiondiff_modules/hmr2/models/heads/__init__.py @@ -0,0 +1 @@ +from .smpl_head import build_smpl_head diff --git a/motiondiff_modules/hmr2/models/heads/smpl_head.py b/motiondiff_modules/hmr2/models/heads/smpl_head.py new file mode 100644 index 0000000..06dd89f --- /dev/null +++ b/motiondiff_modules/hmr2/models/heads/smpl_head.py @@ -0,0 +1,111 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +import numpy as np +import einops + +from ...utils.geometry import rot6d_to_rotmat, aa_to_rotmat +from ..components.pose_transformer import TransformerDecoder + +def build_smpl_head(cfg): + smpl_head_type = cfg.MODEL.SMPL_HEAD.get('TYPE', 'hmr') + if smpl_head_type == 'transformer_decoder': + return SMPLTransformerDecoderHead(cfg) + else: + raise ValueError('Unknown SMPL head type: {}'.format(smpl_head_type)) + +class SMPLTransformerDecoderHead(nn.Module): + """ Cross-attention based SMPL Transformer decoder + """ + + def __init__(self, cfg): + super().__init__() + self.cfg = cfg + self.joint_rep_type = cfg.MODEL.SMPL_HEAD.get('JOINT_REP', '6d') + self.joint_rep_dim = {'6d': 6, 'aa': 3}[self.joint_rep_type] + npose = self.joint_rep_dim * (cfg.SMPL.NUM_BODY_JOINTS + 1) + self.npose = npose + self.input_is_mean_shape = cfg.MODEL.SMPL_HEAD.get('TRANSFORMER_INPUT', 'zero') == 'mean_shape' + transformer_args = dict( + num_tokens=1, + token_dim=(npose + 10 + 3) if self.input_is_mean_shape else 1, + dim=1024, + ) + transformer_args = (transformer_args | dict(cfg.MODEL.SMPL_HEAD.TRANSFORMER_DECODER)) + self.transformer = TransformerDecoder( + **transformer_args + ) + dim=transformer_args['dim'] + self.decpose = nn.Linear(dim, npose) + self.decshape = nn.Linear(dim, 10) + self.deccam = nn.Linear(dim, 3) + + if cfg.MODEL.SMPL_HEAD.get('INIT_DECODER_XAVIER', False): + # True by default in MLP. False by default in Transformer + nn.init.xavier_uniform_(self.decpose.weight, gain=0.01) + nn.init.xavier_uniform_(self.decshape.weight, gain=0.01) + nn.init.xavier_uniform_(self.deccam.weight, gain=0.01) + + mean_params = np.load(cfg.SMPL.MEAN_PARAMS) + init_body_pose = torch.from_numpy(mean_params['pose'].astype(np.float32)).unsqueeze(0) + init_betas = torch.from_numpy(mean_params['shape'].astype('float32')).unsqueeze(0) + init_cam = torch.from_numpy(mean_params['cam'].astype(np.float32)).unsqueeze(0) + self.register_buffer('init_body_pose', init_body_pose) + self.register_buffer('init_betas', init_betas) + self.register_buffer('init_cam', init_cam) + + def forward(self, x, **kwargs): + + batch_size = x.shape[0] + # vit pretrained backbone is channel-first. Change to token-first + x = einops.rearrange(x, 'b c h w -> b (h w) c') + + init_body_pose = self.init_body_pose.expand(batch_size, -1) + init_betas = self.init_betas.expand(batch_size, -1) + init_cam = self.init_cam.expand(batch_size, -1) + + # TODO: Convert init_body_pose to aa rep if needed + if self.joint_rep_type == 'aa': + raise NotImplementedError + + pred_body_pose = init_body_pose + pred_betas = init_betas + pred_cam = init_cam + pred_body_pose_list = [] + pred_betas_list = [] + pred_cam_list = [] + for i in range(self.cfg.MODEL.SMPL_HEAD.get('IEF_ITERS', 1)): + # Input token to transformer is zero token + if self.input_is_mean_shape: + token = torch.cat([pred_body_pose, pred_betas, pred_cam], dim=1)[:,None,:] + else: + token = torch.zeros(batch_size, 1, 1).to(x.device) + + # Pass through transformer + token_out = self.transformer(token, context=x) + token_out = token_out.squeeze(1) # (B, C) + + # Readout from token_out + pred_body_pose = self.decpose(token_out) + pred_body_pose + pred_betas = self.decshape(token_out) + pred_betas + pred_cam = self.deccam(token_out) + pred_cam + pred_body_pose_list.append(pred_body_pose) + pred_betas_list.append(pred_betas) + pred_cam_list.append(pred_cam) + + # Convert self.joint_rep_type -> rotmat + joint_conversion_fn = { + '6d': rot6d_to_rotmat, + 'aa': lambda x: aa_to_rotmat(x.view(-1, 3).contiguous()) + }[self.joint_rep_type] + + pred_smpl_params_list = {} + pred_smpl_params_list['body_pose'] = torch.cat([joint_conversion_fn(pbp).view(batch_size, -1, 3, 3)[:, 1:, :, :] for pbp in pred_body_pose_list], dim=0) + pred_smpl_params_list['betas'] = torch.cat(pred_betas_list, dim=0) + pred_smpl_params_list['cam'] = torch.cat(pred_cam_list, dim=0) + pred_body_pose = joint_conversion_fn(pred_body_pose).view(batch_size, self.cfg.SMPL.NUM_BODY_JOINTS+1, 3, 3) + + pred_smpl_params = {'global_orient': pred_body_pose[:, [0]], + 'body_pose': pred_body_pose[:, 1:], + 'betas': pred_betas} + return pred_smpl_params, pred_cam, pred_smpl_params_list diff --git a/motiondiff_modules/hmr2/models/hmr2_arch.py b/motiondiff_modules/hmr2/models/hmr2_arch.py new file mode 100644 index 0000000..b5d7b91 --- /dev/null +++ b/motiondiff_modules/hmr2/models/hmr2_arch.py @@ -0,0 +1,355 @@ +import torch +import pytorch_lightning as pl +from typing import Any, Dict, Mapping, Tuple + +from yacs.config import CfgNode + +from ..utils import SkeletonRenderer, MeshRenderer +from ..utils.geometry import aa_to_rotmat, perspective_projection +from ..utils.pylogger import get_pylogger +from .backbones import create_backbone +from .heads import build_smpl_head +from .discriminator import Discriminator +from .losses import Keypoint3DLoss, Keypoint2DLoss, ParameterLoss +from . import SMPL + +log = get_pylogger(__name__) + +class HMR2(pl.LightningModule): + + def __init__(self, cfg: CfgNode, init_renderer: bool = False): + """ + Setup HMR2 model + Args: + cfg (CfgNode): Config file as a yacs CfgNode + """ + super().__init__() + + # Save hyperparameters + self.save_hyperparameters(logger=False, ignore=['init_renderer']) + + self.cfg = cfg + # Create backbone feature extractor + self.backbone = create_backbone(cfg) + if cfg.MODEL.BACKBONE.get('PRETRAINED_WEIGHTS', None): + log.info(f'Loading backbone weights from {cfg.MODEL.BACKBONE.PRETRAINED_WEIGHTS}') + self.backbone.load_state_dict(torch.load(cfg.MODEL.BACKBONE.PRETRAINED_WEIGHTS, map_location='cpu')['state_dict']) + + # Create SMPL head + self.smpl_head = build_smpl_head(cfg) + + # Create discriminator + if self.cfg.LOSS_WEIGHTS.ADVERSARIAL > 0: + self.discriminator = Discriminator() + + # Define loss functions + self.keypoint_3d_loss = Keypoint3DLoss(loss_type='l1') + self.keypoint_2d_loss = Keypoint2DLoss(loss_type='l1') + self.smpl_parameter_loss = ParameterLoss() + + # Instantiate SMPL model + smpl_cfg = {k.lower(): v for k,v in dict(cfg.SMPL).items()} + self.smpl = SMPL(**smpl_cfg) + + # Buffer that shows whetheer we need to initialize ActNorm layers + self.register_buffer('initialized', torch.tensor(False)) + # Setup renderer for visualization + if init_renderer: + self.renderer = SkeletonRenderer(self.cfg) + self.mesh_renderer = MeshRenderer(self.cfg, faces=self.smpl.faces) + else: + self.renderer = None + self.mesh_renderer = None + + # Disable automatic optimization since we use adversarial training + self.automatic_optimization = False + + def get_parameters(self): + all_params = list(self.smpl_head.parameters()) + all_params += list(self.backbone.parameters()) + return all_params + + def configure_optimizers(self) -> Tuple[torch.optim.Optimizer, torch.optim.Optimizer]: + """ + Setup model and distriminator Optimizers + Returns: + Tuple[torch.optim.Optimizer, torch.optim.Optimizer]: Model and discriminator optimizers + """ + param_groups = [{'params': filter(lambda p: p.requires_grad, self.get_parameters()), 'lr': self.cfg.TRAIN.LR}] + + optimizer = torch.optim.AdamW(params=param_groups, + # lr=self.cfg.TRAIN.LR, + weight_decay=self.cfg.TRAIN.WEIGHT_DECAY) + optimizer_disc = torch.optim.AdamW(params=self.discriminator.parameters(), + lr=self.cfg.TRAIN.LR, + weight_decay=self.cfg.TRAIN.WEIGHT_DECAY) + + return optimizer, optimizer_disc + + def forward_step(self, batch: Dict, train: bool = False) -> Dict: + """ + Run a forward step of the network + Args: + batch (Dict): Dictionary containing batch data + train (bool): Flag indicating whether it is training or validation mode + Returns: + Dict: Dictionary containing the regression output + """ + + # Use RGB image as input + x = batch['img'] + batch_size = x.shape[0] + + # Compute conditioning features using the backbone + # if using ViT backbone, we need to use a different aspect ratio + conditioning_feats = self.backbone(x[:,:,:,32:-32]) + + pred_smpl_params, pred_cam, _ = self.smpl_head(conditioning_feats) + + # Store useful regression outputs to the output dict + output = {} + output['pred_cam'] = pred_cam + output['pred_smpl_params'] = {k: v.clone() for k,v in pred_smpl_params.items()} + + # Compute camera translation + device = pred_smpl_params['body_pose'].device + dtype = pred_smpl_params['body_pose'].dtype + focal_length = self.cfg.EXTRA.FOCAL_LENGTH * torch.ones(batch_size, 2, device=device, dtype=dtype) + pred_cam_t = torch.stack([pred_cam[:, 1], + pred_cam[:, 2], + 2*focal_length[:, 0]/(self.cfg.MODEL.IMAGE_SIZE * pred_cam[:, 0] +1e-9)],dim=-1) + output['pred_cam_t'] = pred_cam_t + output['focal_length'] = focal_length + + # Compute model vertices, joints and the projected joints + pred_smpl_params['global_orient'] = pred_smpl_params['global_orient'].reshape(batch_size, -1, 3, 3) + pred_smpl_params['body_pose'] = pred_smpl_params['body_pose'].reshape(batch_size, -1, 3, 3) + pred_smpl_params['betas'] = pred_smpl_params['betas'].reshape(batch_size, -1) + smpl_output = self.smpl(**{k: v.float() for k,v in pred_smpl_params.items()}, pose2rot=False) + pred_keypoints_3d = smpl_output.joints + pred_vertices = smpl_output.vertices + output['pred_keypoints_3d'] = pred_keypoints_3d.reshape(batch_size, -1, 3) + output['pred_vertices'] = pred_vertices.reshape(batch_size, -1, 3) + pred_cam_t = pred_cam_t.reshape(-1, 3) + focal_length = focal_length.reshape(-1, 2) + pred_keypoints_2d = perspective_projection(pred_keypoints_3d, + translation=pred_cam_t, + focal_length=focal_length / self.cfg.MODEL.IMAGE_SIZE) + + output['pred_keypoints_2d'] = pred_keypoints_2d.reshape(batch_size, -1, 2) + return output + + def compute_loss(self, batch: Dict, output: Dict, train: bool = True) -> torch.Tensor: + """ + Compute losses given the input batch and the regression output + Args: + batch (Dict): Dictionary containing batch data + output (Dict): Dictionary containing the regression output + train (bool): Flag indicating whether it is training or validation mode + Returns: + torch.Tensor : Total loss for current batch + """ + + pred_smpl_params = output['pred_smpl_params'] + pred_keypoints_2d = output['pred_keypoints_2d'] + pred_keypoints_3d = output['pred_keypoints_3d'] + + + batch_size = pred_smpl_params['body_pose'].shape[0] + device = pred_smpl_params['body_pose'].device + dtype = pred_smpl_params['body_pose'].dtype + + # Get annotations + gt_keypoints_2d = batch['keypoints_2d'] + gt_keypoints_3d = batch['keypoints_3d'] + gt_smpl_params = batch['smpl_params'] + has_smpl_params = batch['has_smpl_params'] + is_axis_angle = batch['smpl_params_is_axis_angle'] + + # Compute 3D keypoint loss + loss_keypoints_2d = self.keypoint_2d_loss(pred_keypoints_2d, gt_keypoints_2d) + loss_keypoints_3d = self.keypoint_3d_loss(pred_keypoints_3d, gt_keypoints_3d, pelvis_id=25+14) + + # Compute loss on SMPL parameters + loss_smpl_params = {} + for k, pred in pred_smpl_params.items(): + gt = gt_smpl_params[k].view(batch_size, -1) + if is_axis_angle[k].all(): + gt = aa_to_rotmat(gt.reshape(-1, 3)).view(batch_size, -1, 3, 3) + has_gt = has_smpl_params[k] + loss_smpl_params[k] = self.smpl_parameter_loss(pred.reshape(batch_size, -1), gt.reshape(batch_size, -1), has_gt) + + loss = self.cfg.LOSS_WEIGHTS['KEYPOINTS_3D'] * loss_keypoints_3d+\ + self.cfg.LOSS_WEIGHTS['KEYPOINTS_2D'] * loss_keypoints_2d+\ + sum([loss_smpl_params[k] * self.cfg.LOSS_WEIGHTS[k.upper()] for k in loss_smpl_params]) + + losses = dict(loss=loss.detach(), + loss_keypoints_2d=loss_keypoints_2d.detach(), + loss_keypoints_3d=loss_keypoints_3d.detach()) + + for k, v in loss_smpl_params.items(): + losses['loss_' + k] = v.detach() + + output['losses'] = losses + + return loss + + # Tensoroboard logging should run from first rank only + @pl.utilities.rank_zero.rank_zero_only + def tensorboard_logging(self, batch: Dict, output: Dict, step_count: int, train: bool = True, write_to_summary_writer: bool = True) -> None: + """ + Log results to Tensorboard + Args: + batch (Dict): Dictionary containing batch data + output (Dict): Dictionary containing the regression output + step_count (int): Global training step count + train (bool): Flag indicating whether it is training or validation mode + """ + + mode = 'train' if train else 'val' + batch_size = batch['keypoints_2d'].shape[0] + images = batch['img'] + images = images * torch.tensor([0.229, 0.224, 0.225], device=images.device).reshape(1,3,1,1) + images = images + torch.tensor([0.485, 0.456, 0.406], device=images.device).reshape(1,3,1,1) + #images = 255*images.permute(0, 2, 3, 1).cpu().numpy() + + pred_keypoints_3d = output['pred_keypoints_3d'].detach().reshape(batch_size, -1, 3) + pred_vertices = output['pred_vertices'].detach().reshape(batch_size, -1, 3) + focal_length = output['focal_length'].detach().reshape(batch_size, 2) + gt_keypoints_3d = batch['keypoints_3d'] + gt_keypoints_2d = batch['keypoints_2d'] + losses = output['losses'] + pred_cam_t = output['pred_cam_t'].detach().reshape(batch_size, 3) + pred_keypoints_2d = output['pred_keypoints_2d'].detach().reshape(batch_size, -1, 2) + + if write_to_summary_writer: + summary_writer = self.logger.experiment + for loss_name, val in losses.items(): + summary_writer.add_scalar(mode +'/' + loss_name, val.detach().item(), step_count) + num_images = min(batch_size, self.cfg.EXTRA.NUM_LOG_IMAGES) + + gt_keypoints_3d = batch['keypoints_3d'] + pred_keypoints_3d = output['pred_keypoints_3d'].detach().reshape(batch_size, -1, 3) + + # We render the skeletons instead of the full mesh because rendering a lot of meshes will make the training slow. + #predictions = self.renderer(pred_keypoints_3d[:num_images], + # gt_keypoints_3d[:num_images], + # 2 * gt_keypoints_2d[:num_images], + # images=images[:num_images], + # camera_translation=pred_cam_t[:num_images]) + predictions = self.mesh_renderer.visualize_tensorboard(pred_vertices[:num_images].cpu().numpy(), + pred_cam_t[:num_images].cpu().numpy(), + images[:num_images].cpu().numpy(), + pred_keypoints_2d[:num_images].cpu().numpy(), + gt_keypoints_2d[:num_images].cpu().numpy(), + focal_length=focal_length[:num_images].cpu().numpy()) + if write_to_summary_writer: + summary_writer.add_image('%s/predictions' % mode, predictions, step_count) + + return predictions + + def forward(self, batch: Dict) -> Dict: + """ + Run a forward step of the network in val mode + Args: + batch (Dict): Dictionary containing batch data + Returns: + Dict: Dictionary containing the regression output + """ + return self.forward_step(batch, train=False) + + def training_step_discriminator(self, batch: Dict, + body_pose: torch.Tensor, + betas: torch.Tensor, + optimizer: torch.optim.Optimizer) -> torch.Tensor: + """ + Run a discriminator training step + Args: + batch (Dict): Dictionary containing mocap batch data + body_pose (torch.Tensor): Regressed body pose from current step + betas (torch.Tensor): Regressed betas from current step + optimizer (torch.optim.Optimizer): Discriminator optimizer + Returns: + torch.Tensor: Discriminator loss + """ + batch_size = body_pose.shape[0] + gt_body_pose = batch['body_pose'] + gt_betas = batch['betas'] + gt_rotmat = aa_to_rotmat(gt_body_pose.view(-1,3)).view(batch_size, -1, 3, 3) + disc_fake_out = self.discriminator(body_pose.detach(), betas.detach()) + loss_fake = ((disc_fake_out - 0.0) ** 2).sum() / batch_size + disc_real_out = self.discriminator(gt_rotmat, gt_betas) + loss_real = ((disc_real_out - 1.0) ** 2).sum() / batch_size + loss_disc = loss_fake + loss_real + loss = self.cfg.LOSS_WEIGHTS.ADVERSARIAL * loss_disc + optimizer.zero_grad() + self.manual_backward(loss) + optimizer.step() + return loss_disc.detach() + + def training_step(self, joint_batch: Dict, batch_idx: int) -> Dict: + """ + Run a full training step + Args: + joint_batch (Dict): Dictionary containing image and mocap batch data + batch_idx (int): Unused. + batch_idx (torch.Tensor): Unused. + Returns: + Dict: Dictionary containing regression output. + """ + batch = joint_batch['img'] + mocap_batch = joint_batch['mocap'] + optimizer = self.optimizers(use_pl_optimizer=True) + if self.cfg.LOSS_WEIGHTS.ADVERSARIAL > 0: + optimizer, optimizer_disc = optimizer + + batch_size = batch['img'].shape[0] + output = self.forward_step(batch, train=True) + pred_smpl_params = output['pred_smpl_params'] + if self.cfg.get('UPDATE_GT_SPIN', False): + self.update_batch_gt_spin(batch, output) + loss = self.compute_loss(batch, output, train=True) + if self.cfg.LOSS_WEIGHTS.ADVERSARIAL > 0: + disc_out = self.discriminator(pred_smpl_params['body_pose'].reshape(batch_size, -1), pred_smpl_params['betas'].reshape(batch_size, -1)) + loss_adv = ((disc_out - 1.0) ** 2).sum() / batch_size + loss = loss + self.cfg.LOSS_WEIGHTS.ADVERSARIAL * loss_adv + + # Error if Nan + if torch.isnan(loss): + raise ValueError('Loss is NaN') + + optimizer.zero_grad() + self.manual_backward(loss) + # Clip gradient + if self.cfg.TRAIN.get('GRAD_CLIP_VAL', 0) > 0: + gn = torch.nn.utils.clip_grad_norm_(self.get_parameters(), self.cfg.TRAIN.GRAD_CLIP_VAL, error_if_nonfinite=True) + self.log('train/grad_norm', gn, on_step=True, on_epoch=True, prog_bar=True, logger=True) + optimizer.step() + if self.cfg.LOSS_WEIGHTS.ADVERSARIAL > 0: + loss_disc = self.training_step_discriminator(mocap_batch, pred_smpl_params['body_pose'].reshape(batch_size, -1), pred_smpl_params['betas'].reshape(batch_size, -1), optimizer_disc) + output['losses']['loss_gen'] = loss_adv + output['losses']['loss_disc'] = loss_disc + + if self.global_step > 0 and self.global_step % self.cfg.GENERAL.LOG_STEPS == 0: + self.tensorboard_logging(batch, output, self.global_step, train=True) + + self.log('train/loss', output['losses']['loss'], on_step=True, on_epoch=True, prog_bar=True, logger=False) + + return output + + def validation_step(self, batch: Dict, batch_idx: int, dataloader_idx=0) -> Dict: + """ + Run a validation step and log to Tensorboard + Args: + batch (Dict): Dictionary containing batch data + batch_idx (int): Unused. + Returns: + Dict: Dictionary containing regression output. + """ + # batch_size = batch['img'].shape[0] + output = self.forward_step(batch, train=False) + loss = self.compute_loss(batch, output, train=False) + output['loss'] = loss + self.tensorboard_logging(batch, output, self.global_step, train=False) + + return output diff --git a/motiondiff_modules/hmr2/models/losses.py b/motiondiff_modules/hmr2/models/losses.py new file mode 100644 index 0000000..0949d06 --- /dev/null +++ b/motiondiff_modules/hmr2/models/losses.py @@ -0,0 +1,92 @@ +import torch +import torch.nn as nn + +class Keypoint2DLoss(nn.Module): + + def __init__(self, loss_type: str = 'l1'): + """ + 2D keypoint loss module. + Args: + loss_type (str): Choose between l1 and l2 losses. + """ + super(Keypoint2DLoss, self).__init__() + if loss_type == 'l1': + self.loss_fn = nn.L1Loss(reduction='none') + elif loss_type == 'l2': + self.loss_fn = nn.MSELoss(reduction='none') + else: + raise NotImplementedError('Unsupported loss function') + + def forward(self, pred_keypoints_2d: torch.Tensor, gt_keypoints_2d: torch.Tensor) -> torch.Tensor: + """ + Compute 2D reprojection loss on the keypoints. + Args: + pred_keypoints_2d (torch.Tensor): Tensor of shape [B, S, N, 2] containing projected 2D keypoints (B: batch_size, S: num_samples, N: num_keypoints) + gt_keypoints_2d (torch.Tensor): Tensor of shape [B, S, N, 3] containing the ground truth 2D keypoints and confidence. + Returns: + torch.Tensor: 2D keypoint loss. + """ + conf = gt_keypoints_2d[:, :, -1].unsqueeze(-1).clone() + batch_size = conf.shape[0] + loss = (conf * self.loss_fn(pred_keypoints_2d, gt_keypoints_2d[:, :, :-1])).sum(dim=(1,2)) + return loss.sum() + + +class Keypoint3DLoss(nn.Module): + + def __init__(self, loss_type: str = 'l1'): + """ + 3D keypoint loss module. + Args: + loss_type (str): Choose between l1 and l2 losses. + """ + super(Keypoint3DLoss, self).__init__() + if loss_type == 'l1': + self.loss_fn = nn.L1Loss(reduction='none') + elif loss_type == 'l2': + self.loss_fn = nn.MSELoss(reduction='none') + else: + raise NotImplementedError('Unsupported loss function') + + def forward(self, pred_keypoints_3d: torch.Tensor, gt_keypoints_3d: torch.Tensor, pelvis_id: int = 39): + """ + Compute 3D keypoint loss. + Args: + pred_keypoints_3d (torch.Tensor): Tensor of shape [B, S, N, 3] containing the predicted 3D keypoints (B: batch_size, S: num_samples, N: num_keypoints) + gt_keypoints_3d (torch.Tensor): Tensor of shape [B, S, N, 4] containing the ground truth 3D keypoints and confidence. + Returns: + torch.Tensor: 3D keypoint loss. + """ + batch_size = pred_keypoints_3d.shape[0] + gt_keypoints_3d = gt_keypoints_3d.clone() + pred_keypoints_3d = pred_keypoints_3d - pred_keypoints_3d[:, pelvis_id, :].unsqueeze(dim=1) + gt_keypoints_3d[:, :, :-1] = gt_keypoints_3d[:, :, :-1] - gt_keypoints_3d[:, pelvis_id, :-1].unsqueeze(dim=1) + conf = gt_keypoints_3d[:, :, -1].unsqueeze(-1).clone() + gt_keypoints_3d = gt_keypoints_3d[:, :, :-1] + loss = (conf * self.loss_fn(pred_keypoints_3d, gt_keypoints_3d)).sum(dim=(1,2)) + return loss.sum() + +class ParameterLoss(nn.Module): + + def __init__(self): + """ + SMPL parameter loss module. + """ + super(ParameterLoss, self).__init__() + self.loss_fn = nn.MSELoss(reduction='none') + + def forward(self, pred_param: torch.Tensor, gt_param: torch.Tensor, has_param: torch.Tensor): + """ + Compute SMPL parameter loss. + Args: + pred_param (torch.Tensor): Tensor of shape [B, S, ...] containing the predicted parameters (body pose / global orientation / betas) + gt_param (torch.Tensor): Tensor of shape [B, S, ...] containing the ground truth SMPL parameters. + Returns: + torch.Tensor: L2 parameter loss loss. + """ + batch_size = pred_param.shape[0] + num_dims = len(pred_param.shape) + mask_dimension = [batch_size] + [1] * (num_dims-1) + has_param = has_param.type(pred_param.type()).view(*mask_dimension) + loss_param = (has_param * self.loss_fn(pred_param, gt_param)) + return loss_param.sum() diff --git a/motiondiff_modules/hmr2/models/smpl_wrapper.py b/motiondiff_modules/hmr2/models/smpl_wrapper.py new file mode 100644 index 0000000..4f98454 --- /dev/null +++ b/motiondiff_modules/hmr2/models/smpl_wrapper.py @@ -0,0 +1,41 @@ +import torch +import numpy as np +import pickle +from typing import Optional +import smplx +from smplx.lbs import vertices2joints +from smplx.utils import SMPLOutput + + +class SMPL(smplx.SMPLLayer): + def __init__(self, *args, joint_regressor_extra: Optional[str] = None, update_hips: bool = False, **kwargs): + """ + Extension of the official SMPL implementation to support more joints. + Args: + Same as SMPLLayer. + joint_regressor_extra (str): Path to extra joint regressor. + """ + super(SMPL, self).__init__(*args, **kwargs) + smpl_to_openpose = [24, 12, 17, 19, 21, 16, 18, 20, 0, 2, 5, 8, 1, 4, + 7, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34] + + if joint_regressor_extra is not None: + self.register_buffer('joint_regressor_extra', torch.tensor(pickle.load(open(joint_regressor_extra, 'rb'), encoding='latin1'), dtype=torch.float32)) + self.register_buffer('joint_map', torch.tensor(smpl_to_openpose, dtype=torch.long)) + self.update_hips = update_hips + + def forward(self, *args, **kwargs) -> SMPLOutput: + """ + Run forward pass. Same as SMPL and also append an extra set of joints if joint_regressor_extra is specified. + """ + smpl_output = super(SMPL, self).forward(*args, **kwargs) + joints = smpl_output.joints[:, self.joint_map, :] + if self.update_hips: + joints[:,[9,12]] = joints[:,[9,12]] + \ + 0.25*(joints[:,[9,12]]-joints[:,[12,9]]) + \ + 0.5*(joints[:,[8]] - 0.5*(joints[:,[9,12]] + joints[:,[12,9]])) + if hasattr(self, 'joint_regressor_extra'): + extra_joints = vertices2joints(self.joint_regressor_extra, smpl_output.vertices) + joints = torch.cat([joints, extra_joints], dim=1) + smpl_output.joints = joints + return smpl_output diff --git a/motiondiff_modules/hmr2/utils/__init__.py b/motiondiff_modules/hmr2/utils/__init__.py new file mode 100644 index 0000000..09e47cd --- /dev/null +++ b/motiondiff_modules/hmr2/utils/__init__.py @@ -0,0 +1,25 @@ +import torch +from typing import Any + +from .renderer import Renderer +from .mesh_renderer import MeshRenderer +from .skeleton_renderer import SkeletonRenderer +from .pose_utils import eval_pose, Evaluator + +def recursive_to(x: Any, target: torch.device): + """ + Recursively transfer a batch of data to the target device + Args: + x (Any): Batch of data. + target (torch.device): Target device. + Returns: + Batch of data where all tensors are transfered to the target device. + """ + if isinstance(x, dict): + return {k: recursive_to(v, target) for k, v in x.items()} + elif isinstance(x, torch.Tensor): + return x.to(target) + elif isinstance(x, list): + return [recursive_to(i, target) for i in x] + else: + return x diff --git a/motiondiff_modules/hmr2/utils/download.py b/motiondiff_modules/hmr2/utils/download.py new file mode 100644 index 0000000..5ff40c0 --- /dev/null +++ b/motiondiff_modules/hmr2/utils/download.py @@ -0,0 +1,67 @@ +import os +import re +import sys +from urllib import request as urlrequest + + +def _progress_bar(count, total): + """Report download progress. Credit: + https://stackoverflow.com/questions/3173320/text-progress-bar-in-the-console/27871113 + """ + bar_len = 60 + filled_len = int(round(bar_len * count / float(total))) + percents = round(100.0 * count / float(total), 1) + bar = "=" * filled_len + "-" * (bar_len - filled_len) + sys.stdout.write( + " [{}] {}% of {:.1f}MB file \r".format(bar, percents, total / 1024 / 1024) + ) + sys.stdout.flush() + if count >= total: + sys.stdout.write("\n") + + +def download_url(url, dst_file_path, chunk_size=8192, progress_hook=_progress_bar): + """Download url and write it to dst_file_path. Credit: + https://stackoverflow.com/questions/2028517/python-urllib2-progress-hook + """ + # url = url + "?dl=1" if "dropbox" in url else url + req = urlrequest.Request(url) + response = urlrequest.urlopen(req) + total_size = response.info().get("Content-Length") + if total_size is None: + raise ValueError("Cannot determine size of download from {}".format(url)) + total_size = int(total_size.strip()) + bytes_so_far = 0 + + with open(dst_file_path, "wb") as f: + while 1: + chunk = response.read(chunk_size) + bytes_so_far += len(chunk) + if not chunk: + break + + if progress_hook: + progress_hook(bytes_so_far, total_size) + + f.write(chunk) + return bytes_so_far + + +def cache_url(url_or_file, cache_file_path, download=True, log=True): + """Download the file specified by the URL to the cache_dir and return the path to + the cached file. If the argument is not a URL, simply return it as is. + """ + is_url = re.match(r"^(?:http)s?://", url_or_file, re.IGNORECASE) is not None + if not is_url: + return url_or_file + url = url_or_file + if os.path.exists(cache_file_path): + return cache_file_path + cache_file_dir = os.path.dirname(cache_file_path) + if not os.path.exists(cache_file_dir): + os.makedirs(cache_file_dir) + if download: + if log: + print("Downloading remote file {} to {}".format(url, cache_file_path)) + download_url(url, cache_file_path) + return cache_file_path diff --git a/motiondiff_modules/hmr2/utils/geometry.py b/motiondiff_modules/hmr2/utils/geometry.py new file mode 100644 index 0000000..7929ef5 --- /dev/null +++ b/motiondiff_modules/hmr2/utils/geometry.py @@ -0,0 +1,102 @@ +from typing import Optional +import torch +from torch.nn import functional as F + +def aa_to_rotmat(theta: torch.Tensor): + """ + Convert axis-angle representation to rotation matrix. + Works by first converting it to a quaternion. + Args: + theta (torch.Tensor): Tensor of shape (B, 3) containing axis-angle representations. + Returns: + torch.Tensor: Corresponding rotation matrices with shape (B, 3, 3). + """ + norm = torch.norm(theta + 1e-8, p = 2, dim = 1) + angle = torch.unsqueeze(norm, -1) + normalized = torch.div(theta, angle) + angle = angle * 0.5 + v_cos = torch.cos(angle) + v_sin = torch.sin(angle) + quat = torch.cat([v_cos, v_sin * normalized], dim = 1) + return quat_to_rotmat(quat) + +def quat_to_rotmat(quat: torch.Tensor) -> torch.Tensor: + """ + Convert quaternion representation to rotation matrix. + Args: + quat (torch.Tensor) of shape (B, 4); 4 <===> (w, x, y, z). + Returns: + torch.Tensor: Corresponding rotation matrices with shape (B, 3, 3). + """ + norm_quat = quat + norm_quat = norm_quat/norm_quat.norm(p=2, dim=1, keepdim=True) + w, x, y, z = norm_quat[:,0], norm_quat[:,1], norm_quat[:,2], norm_quat[:,3] + + B = quat.size(0) + + w2, x2, y2, z2 = w.pow(2), x.pow(2), y.pow(2), z.pow(2) + wx, wy, wz = w*x, w*y, w*z + xy, xz, yz = x*y, x*z, y*z + + rotMat = torch.stack([w2 + x2 - y2 - z2, 2*xy - 2*wz, 2*wy + 2*xz, + 2*wz + 2*xy, w2 - x2 + y2 - z2, 2*yz - 2*wx, + 2*xz - 2*wy, 2*wx + 2*yz, w2 - x2 - y2 + z2], dim=1).view(B, 3, 3) + return rotMat + + +def rot6d_to_rotmat(x: torch.Tensor) -> torch.Tensor: + """ + Convert 6D rotation representation to 3x3 rotation matrix. + Based on Zhou et al., "On the Continuity of Rotation Representations in Neural Networks", CVPR 2019 + Args: + x (torch.Tensor): (B,6) Batch of 6-D rotation representations. + Returns: + torch.Tensor: Batch of corresponding rotation matrices with shape (B,3,3). + """ + x = x.reshape(-1,2,3).permute(0, 2, 1).contiguous() + a1 = x[:, :, 0] + a2 = x[:, :, 1] + b1 = F.normalize(a1) + b2 = F.normalize(a2 - torch.einsum('bi,bi->b', b1, a2).unsqueeze(-1) * b1) + b3 = torch.cross(b1, b2) + return torch.stack((b1, b2, b3), dim=-1) + +def perspective_projection(points: torch.Tensor, + translation: torch.Tensor, + focal_length: torch.Tensor, + camera_center: Optional[torch.Tensor] = None, + rotation: Optional[torch.Tensor] = None) -> torch.Tensor: + """ + Computes the perspective projection of a set of 3D points. + Args: + points (torch.Tensor): Tensor of shape (B, N, 3) containing the input 3D points. + translation (torch.Tensor): Tensor of shape (B, 3) containing the 3D camera translation. + focal_length (torch.Tensor): Tensor of shape (B, 2) containing the focal length in pixels. + camera_center (torch.Tensor): Tensor of shape (B, 2) containing the camera center in pixels. + rotation (torch.Tensor): Tensor of shape (B, 3, 3) containing the camera rotation. + Returns: + torch.Tensor: Tensor of shape (B, N, 2) containing the projection of the input points. + """ + batch_size = points.shape[0] + if rotation is None: + rotation = torch.eye(3, device=points.device, dtype=points.dtype).unsqueeze(0).expand(batch_size, -1, -1) + if camera_center is None: + camera_center = torch.zeros(batch_size, 2, device=points.device, dtype=points.dtype) + # Populate intrinsic camera matrix K. + K = torch.zeros([batch_size, 3, 3], device=points.device, dtype=points.dtype) + K[:,0,0] = focal_length[:,0] + K[:,1,1] = focal_length[:,1] + K[:,2,2] = 1. + K[:,:-1, -1] = camera_center + + # Transform points + points = torch.einsum('bij,bkj->bki', rotation, points) + points = points + translation.unsqueeze(1) + + # Apply perspective distortion + projected_points = points / points[:,:,-1].unsqueeze(-1) + + # Apply camera intrinsics + projected_points = torch.einsum('bij,bkj->bki', K, projected_points) + + return projected_points[:, :, :-1] \ No newline at end of file diff --git a/motiondiff_modules/hmr2/utils/mesh_renderer.py b/motiondiff_modules/hmr2/utils/mesh_renderer.py new file mode 100644 index 0000000..ddcfab9 --- /dev/null +++ b/motiondiff_modules/hmr2/utils/mesh_renderer.py @@ -0,0 +1,149 @@ +import os +if os.name == 'posix' and "DISPLAY" not in os.environ: + os.environ['PYOPENGL_PLATFORM'] = 'egl' +import torch +from torchvision.utils import make_grid +import numpy as np +import pyrender +import trimesh +import cv2 +import torch.nn.functional as F + +from .render_openpose import render_openpose + +def create_raymond_lights(): + import pyrender + thetas = np.pi * np.array([1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0]) + phis = np.pi * np.array([0.0, 2.0 / 3.0, 4.0 / 3.0]) + + nodes = [] + + for phi, theta in zip(phis, thetas): + xp = np.sin(theta) * np.cos(phi) + yp = np.sin(theta) * np.sin(phi) + zp = np.cos(theta) + + z = np.array([xp, yp, zp]) + z = z / np.linalg.norm(z) + x = np.array([-z[1], z[0], 0.0]) + if np.linalg.norm(x) == 0: + x = np.array([1.0, 0.0, 0.0]) + x = x / np.linalg.norm(x) + y = np.cross(z, x) + + matrix = np.eye(4) + matrix[:3,:3] = np.c_[x,y,z] + nodes.append(pyrender.Node( + light=pyrender.DirectionalLight(color=np.ones(3), intensity=1.0), + matrix=matrix + )) + + return nodes + +class MeshRenderer: + + def __init__(self, cfg, faces=None): + self.cfg = cfg + self.focal_length = cfg.EXTRA.FOCAL_LENGTH + self.img_res = cfg.MODEL.IMAGE_SIZE + self.renderer = pyrender.OffscreenRenderer(viewport_width=self.img_res, + viewport_height=self.img_res, + point_size=1.0) + + self.camera_center = [self.img_res // 2, self.img_res // 2] + self.faces = faces + + def visualize(self, vertices, camera_translation, images, focal_length=None, nrow=3, padding=2): + images_np = np.transpose(images, (0,2,3,1)) + rend_imgs = [] + for i in range(vertices.shape[0]): + fl = self.focal_length + rend_img = torch.from_numpy(np.transpose(self.__call__(vertices[i], camera_translation[i], images_np[i], focal_length=fl, side_view=False), (2,0,1))).float() + rend_img_side = torch.from_numpy(np.transpose(self.__call__(vertices[i], camera_translation[i], images_np[i], focal_length=fl, side_view=True), (2,0,1))).float() + rend_imgs.append(torch.from_numpy(images[i])) + rend_imgs.append(rend_img) + rend_imgs.append(rend_img_side) + rend_imgs = make_grid(rend_imgs, nrow=nrow, padding=padding) + return rend_imgs + + def visualize_tensorboard(self, vertices, camera_translation, images, pred_keypoints, gt_keypoints, focal_length=None, nrow=5, padding=2): + images_np = np.transpose(images, (0,2,3,1)) + rend_imgs = [] + pred_keypoints = np.concatenate((pred_keypoints, np.ones_like(pred_keypoints)[:, :, [0]]), axis=-1) + pred_keypoints = self.img_res * (pred_keypoints + 0.5) + gt_keypoints[:, :, :-1] = self.img_res * (gt_keypoints[:, :, :-1] + 0.5) + keypoint_matches = [(1, 12), (2, 8), (3, 7), (4, 6), (5, 9), (6, 10), (7, 11), (8, 14), (9, 2), (10, 1), (11, 0), (12, 3), (13, 4), (14, 5)] + for i in range(vertices.shape[0]): + fl = self.focal_length + rend_img = torch.from_numpy(np.transpose(self.__call__(vertices[i], camera_translation[i], images_np[i], focal_length=fl, side_view=False), (2,0,1))).float() + rend_img_side = torch.from_numpy(np.transpose(self.__call__(vertices[i], camera_translation[i], images_np[i], focal_length=fl, side_view=True), (2,0,1))).float() + body_keypoints = pred_keypoints[i, :25] + extra_keypoints = pred_keypoints[i, -19:] + for pair in keypoint_matches: + body_keypoints[pair[0], :] = extra_keypoints[pair[1], :] + pred_keypoints_img = render_openpose(255 * images_np[i].copy(), body_keypoints) / 255 + body_keypoints = gt_keypoints[i, :25] + extra_keypoints = gt_keypoints[i, -19:] + for pair in keypoint_matches: + if extra_keypoints[pair[1], -1] > 0 and body_keypoints[pair[0], -1] == 0: + body_keypoints[pair[0], :] = extra_keypoints[pair[1], :] + gt_keypoints_img = render_openpose(255*images_np[i].copy(), body_keypoints) / 255 + rend_imgs.append(torch.from_numpy(images[i])) + rend_imgs.append(rend_img) + rend_imgs.append(rend_img_side) + rend_imgs.append(torch.from_numpy(pred_keypoints_img).permute(2,0,1)) + rend_imgs.append(torch.from_numpy(gt_keypoints_img).permute(2,0,1)) + rend_imgs = make_grid(rend_imgs, nrow=nrow, padding=padding) + return rend_imgs + + def __call__(self, vertices, camera_translation, image, focal_length=5000, text=None, resize=None, side_view=False, baseColorFactor=(1.0, 1.0, 0.9, 1.0), rot_angle=90): + renderer = pyrender.OffscreenRenderer(viewport_width=image.shape[1], + viewport_height=image.shape[0], + point_size=1.0) + material = pyrender.MetallicRoughnessMaterial( + metallicFactor=0.0, + alphaMode='OPAQUE', + baseColorFactor=baseColorFactor) + + camera_translation[0] *= -1. + + mesh = trimesh.Trimesh(vertices.copy(), self.faces.copy()) + if side_view: + rot = trimesh.transformations.rotation_matrix( + np.radians(rot_angle), [0, 1, 0]) + mesh.apply_transform(rot) + rot = trimesh.transformations.rotation_matrix( + np.radians(180), [1, 0, 0]) + mesh.apply_transform(rot) + mesh = pyrender.Mesh.from_trimesh(mesh, material=material) + + scene = pyrender.Scene(bg_color=[0.0, 0.0, 0.0, 0.0], + ambient_light=(0.3, 0.3, 0.3)) + scene.add(mesh, 'mesh') + + camera_pose = np.eye(4) + camera_pose[:3, 3] = camera_translation + camera_center = [image.shape[1] / 2., image.shape[0] / 2.] + camera = pyrender.IntrinsicsCamera(fx=focal_length, fy=focal_length, + cx=camera_center[0], cy=camera_center[1]) + scene.add(camera, pose=camera_pose) + + + light_nodes = create_raymond_lights() + for node in light_nodes: + scene.add_node(node) + + color, rend_depth = renderer.render(scene, flags=pyrender.RenderFlags.RGBA) + color = color.astype(np.float32) / 255.0 + valid_mask = (color[:, :, -1] > 0)[:, :, np.newaxis] + if not side_view: + output_img = (color[:, :, :3] * valid_mask + + (1 - valid_mask) * image) + else: + output_img = color[:, :, :3] + if resize is not None: + output_img = cv2.resize(output_img, resize) + + output_img = output_img.astype(np.float32) + renderer.delete() + return output_img diff --git a/motiondiff_modules/hmr2/utils/misc.py b/motiondiff_modules/hmr2/utils/misc.py new file mode 100644 index 0000000..ffcfe78 --- /dev/null +++ b/motiondiff_modules/hmr2/utils/misc.py @@ -0,0 +1,203 @@ +import time +import warnings +from importlib.util import find_spec +from pathlib import Path +from typing import Callable, List + +import hydra +from omegaconf import DictConfig, OmegaConf +from pytorch_lightning import Callback +from pytorch_lightning.loggers import Logger +from pytorch_lightning.utilities import rank_zero_only + +from . import pylogger, rich_utils + +log = pylogger.get_pylogger(__name__) + + +def task_wrapper(task_func: Callable) -> Callable: + """Optional decorator that wraps the task function in extra utilities. + + Makes multirun more resistant to failure. + + Utilities: + - Calling the `utils.extras()` before the task is started + - Calling the `utils.close_loggers()` after the task is finished + - Logging the exception if occurs + - Logging the task total execution time + - Logging the output dir + """ + + def wrap(cfg: DictConfig): + + # apply extra utilities + extras(cfg) + + # execute the task + try: + start_time = time.time() + ret = task_func(cfg=cfg) + except Exception as ex: + log.exception("") # save exception to `.log` file + raise ex + finally: + path = Path(cfg.paths.output_dir, "exec_time.log") + content = f"'{cfg.task_name}' execution time: {time.time() - start_time} (s)" + save_file(path, content) # save task execution time (even if exception occurs) + close_loggers() # close loggers (even if exception occurs so multirun won't fail) + + log.info(f"Output dir: {cfg.paths.output_dir}") + + return ret + + return wrap + + +def extras(cfg: DictConfig) -> None: + """Applies optional utilities before the task is started. + + Utilities: + - Ignoring python warnings + - Setting tags from command line + - Rich config printing + """ + + # return if no `extras` config + if not cfg.get("extras"): + log.warning("Extras config not found! ") + return + + # disable python warnings + if cfg.extras.get("ignore_warnings"): + log.info("Disabling python warnings! ") + warnings.filterwarnings("ignore") + + # prompt user to input tags from command line if none are provided in the config + if cfg.extras.get("enforce_tags"): + log.info("Enforcing tags! ") + rich_utils.enforce_tags(cfg, save_to_file=True) + + # pretty print config tree using Rich library + if cfg.extras.get("print_config"): + log.info("Printing config tree with Rich! ") + rich_utils.print_config_tree(cfg, resolve=True, save_to_file=True) + + +@rank_zero_only +def save_file(path: str, content: str) -> None: + """Save file in rank zero mode (only on one process in multi-GPU setup).""" + with open(path, "w+") as file: + file.write(content) + + +def instantiate_callbacks(callbacks_cfg: DictConfig) -> List[Callback]: + """Instantiates callbacks from config.""" + callbacks: List[Callback] = [] + + if not callbacks_cfg: + log.warning("Callbacks config is empty.") + return callbacks + + if not isinstance(callbacks_cfg, DictConfig): + raise TypeError("Callbacks config must be a DictConfig!") + + for _, cb_conf in callbacks_cfg.items(): + if isinstance(cb_conf, DictConfig) and "_target_" in cb_conf: + log.info(f"Instantiating callback <{cb_conf._target_}>") + callbacks.append(hydra.utils.instantiate(cb_conf)) + + return callbacks + + +def instantiate_loggers(logger_cfg: DictConfig) -> List[Logger]: + """Instantiates loggers from config.""" + logger: List[Logger] = [] + + if not logger_cfg: + log.warning("Logger config is empty.") + return logger + + if not isinstance(logger_cfg, DictConfig): + raise TypeError("Logger config must be a DictConfig!") + + for _, lg_conf in logger_cfg.items(): + if isinstance(lg_conf, DictConfig) and "_target_" in lg_conf: + log.info(f"Instantiating logger <{lg_conf._target_}>") + logger.append(hydra.utils.instantiate(lg_conf)) + + return logger + + +@rank_zero_only +def log_hyperparameters(object_dict: dict) -> None: + """Controls which config parts are saved by lightning loggers. + + Additionally saves: + - Number of model parameters + """ + + hparams = {} + + cfg = object_dict["cfg"] + model = object_dict["model"] + trainer = object_dict["trainer"] + + if not trainer.logger: + log.warning("Logger not found! Skipping hyperparameter logging...") + return + + # save number of model parameters + hparams["model/params/total"] = sum(p.numel() for p in model.parameters()) + hparams["model/params/trainable"] = sum( + p.numel() for p in model.parameters() if p.requires_grad + ) + hparams["model/params/non_trainable"] = sum( + p.numel() for p in model.parameters() if not p.requires_grad + ) + + for k in cfg.keys(): + hparams[k] = cfg.get(k) + + # Resolve all interpolations + def _resolve(_cfg): + if isinstance(_cfg, DictConfig): + _cfg = OmegaConf.to_container(_cfg, resolve=True) + return _cfg + + hparams = {k: _resolve(v) for k, v in hparams.items()} + + # send hparams to all loggers + trainer.logger.log_hyperparams(hparams) + + +def get_metric_value(metric_dict: dict, metric_name: str) -> float: + """Safely retrieves value of the metric logged in LightningModule.""" + + if not metric_name: + log.info("Metric name is None! Skipping metric value retrieval...") + return None + + if metric_name not in metric_dict: + raise Exception( + f"Metric value not found! \n" + "Make sure metric name logged in LightningModule is correct!\n" + "Make sure `optimized_metric` name in `hparams_search` config is correct!" + ) + + metric_value = metric_dict[metric_name].item() + log.info(f"Retrieved metric value! <{metric_name}={metric_value}>") + + return metric_value + + +def close_loggers() -> None: + """Makes sure all loggers closed properly (prevents logging failure during multirun).""" + + log.info("Closing loggers...") + + if find_spec("wandb"): # if wandb is installed + import wandb + + if wandb.run: + log.info("Closing wandb!") + wandb.finish() diff --git a/motiondiff_modules/hmr2/utils/pck_accuracy.py b/motiondiff_modules/hmr2/utils/pck_accuracy.py new file mode 100644 index 0000000..5fea6c3 --- /dev/null +++ b/motiondiff_modules/hmr2/utils/pck_accuracy.py @@ -0,0 +1,94 @@ +# Copyright (c) OpenMMLab. All rights reserved. + +import numpy as np + +def _calc_distances(preds, targets, mask, normalize): + """Calculate the normalized distances between preds and target. + + Note: + batch_size: N + num_keypoints: K + dimension of keypoints: D (normally, D=2 or D=3) + + Args: + preds (np.ndarray[N, K, D]): Predicted keypoint location. + targets (np.ndarray[N, K, D]): Groundtruth keypoint location. + mask (np.ndarray[N, K]): Visibility of the target. False for invisible + joints, and True for visible. Invisible joints will be ignored for + accuracy calculation. + normalize (np.ndarray[N, D]): Typical value is heatmap_size + + Returns: + np.ndarray[K, N]: The normalized distances. \ + If target keypoints are missing, the distance is -1. + """ + N, K, _ = preds.shape + # set mask=0 when normalize==0 + _mask = mask.copy() + _mask[np.where((normalize == 0).sum(1))[0], :] = False + distances = np.full((N, K), -1, dtype=np.float32) + # handle invalid values + normalize[np.where(normalize <= 0)] = 1e6 + distances[_mask] = np.linalg.norm( + ((preds - targets) / normalize[:, None, :])[_mask], axis=-1) + return distances.T + + +def _distance_acc(distances, thr=0.5): + """Return the percentage below the distance threshold, while ignoring + distances values with -1. + + Note: + batch_size: N + Args: + distances (np.ndarray[N, ]): The normalized distances. + thr (float): Threshold of the distances. + + Returns: + float: Percentage of distances below the threshold. \ + If all target keypoints are missing, return -1. + """ + distance_valid = distances != -1 + num_distance_valid = distance_valid.sum() + if num_distance_valid > 0: + return (distances[distance_valid] < thr).sum() / num_distance_valid + return -1 + + +def keypoint_pck_accuracy(pred, gt, mask, thr, normalize): + """Calculate the pose accuracy of PCK for each individual keypoint and the + averaged accuracy across all keypoints for coordinates. + + Note: + PCK metric measures accuracy of the localization of the body joints. + The distances between predicted positions and the ground-truth ones + are typically normalized by the bounding box size. + The threshold (thr) of the normalized distance is commonly set + as 0.05, 0.1 or 0.2 etc. + + - batch_size: N + - num_keypoints: K + + Args: + pred (np.ndarray[N, K, 2]): Predicted keypoint location. + gt (np.ndarray[N, K, 2]): Groundtruth keypoint location. + mask (np.ndarray[N, K]): Visibility of the target. False for invisible + joints, and True for visible. Invisible joints will be ignored for + accuracy calculation. + thr (float): Threshold of PCK calculation. + normalize (np.ndarray[N, 2]): Normalization factor for H&W. + + Returns: + tuple: A tuple containing keypoint accuracy. + + - acc (np.ndarray[K]): Accuracy of each keypoint. + - avg_acc (float): Averaged accuracy across all keypoints. + - cnt (int): Number of valid keypoints. + """ + distances = _calc_distances(pred, gt, mask, normalize) + + acc = np.array([_distance_acc(d, thr) for d in distances]) + valid_acc = acc[acc >= 0] + cnt = len(valid_acc) + avg_acc = valid_acc.mean() if cnt > 0 else 0 + return acc, avg_acc, cnt diff --git a/motiondiff_modules/hmr2/utils/pose_utils.py b/motiondiff_modules/hmr2/utils/pose_utils.py new file mode 100644 index 0000000..bcc731c --- /dev/null +++ b/motiondiff_modules/hmr2/utils/pose_utils.py @@ -0,0 +1,310 @@ +""" +Code adapted from: https://github.com/akanazawa/hmr/blob/master/src/benchmark/eval_util.py +""" + +import torch +import numpy as np +from typing import Optional, Dict, List, Tuple + +def compute_similarity_transform(S1: torch.Tensor, S2: torch.Tensor) -> torch.Tensor: + """ + Computes a similarity transform (sR, t) in a batched way that takes + a set of 3D points S1 (B, N, 3) closest to a set of 3D points S2 (B, N, 3), + where R is a 3x3 rotation matrix, t 3x1 translation, s scale. + i.e. solves the orthogonal Procrutes problem. + Args: + S1 (torch.Tensor): First set of points of shape (B, N, 3). + S2 (torch.Tensor): Second set of points of shape (B, N, 3). + Returns: + (torch.Tensor): The first set of points after applying the similarity transformation. + """ + + batch_size = S1.shape[0] + S1 = S1.permute(0, 2, 1) + S2 = S2.permute(0, 2, 1) + # 1. Remove mean. + mu1 = S1.mean(dim=2, keepdim=True) + mu2 = S2.mean(dim=2, keepdim=True) + X1 = S1 - mu1 + X2 = S2 - mu2 + + # 2. Compute variance of X1 used for scale. + var1 = (X1**2).sum(dim=(1,2)) + + # 3. The outer product of X1 and X2. + K = torch.matmul(X1, X2.permute(0, 2, 1)) + + # 4. Solution that Maximizes trace(R'K) is R=U*V', where U, V are singular vectors of K. + U, s, V = torch.svd(K) + Vh = V.permute(0, 2, 1) + + # Construct Z that fixes the orientation of R to get det(R)=1. + Z = torch.eye(U.shape[1], device=U.device).unsqueeze(0).repeat(batch_size, 1, 1) + Z[:, -1, -1] *= torch.sign(torch.linalg.det(torch.matmul(U, Vh))) + + # Construct R. + R = torch.matmul(torch.matmul(V, Z), U.permute(0, 2, 1)) + + # 5. Recover scale. + trace = torch.matmul(R, K).diagonal(offset=0, dim1=-1, dim2=-2).sum(dim=-1) + scale = (trace / var1).unsqueeze(dim=-1).unsqueeze(dim=-1) + + # 6. Recover translation. + t = mu2 - scale*torch.matmul(R, mu1) + + # 7. Error: + S1_hat = scale*torch.matmul(R, S1) + t + + return S1_hat.permute(0, 2, 1) + +def reconstruction_error(S1, S2) -> np.array: + """ + Computes the mean Euclidean distance of 2 set of points S1, S2 after performing Procrustes alignment. + Args: + S1 (torch.Tensor): First set of points of shape (B, N, 3). + S2 (torch.Tensor): Second set of points of shape (B, N, 3). + Returns: + (np.array): Reconstruction error. + """ + S1_hat = compute_similarity_transform(S1, S2) + re = torch.sqrt( ((S1_hat - S2)** 2).sum(dim=-1)).mean(dim=-1) + return re + +def eval_pose(pred_joints, gt_joints) -> Tuple[np.array, np.array]: + """ + Compute joint errors in mm before and after Procrustes alignment. + Args: + pred_joints (torch.Tensor): Predicted 3D joints of shape (B, N, 3). + gt_joints (torch.Tensor): Ground truth 3D joints of shape (B, N, 3). + Returns: + Tuple[np.array, np.array]: Joint errors in mm before and after alignment. + """ + # Absolute error (MPJPE) + mpjpe = torch.sqrt(((pred_joints - gt_joints) ** 2).sum(dim=-1)).mean(dim=-1).cpu().numpy() + + # Reconstruction_error + r_error = reconstruction_error(pred_joints, gt_joints).cpu().numpy() + return 1000 * mpjpe, 1000 * r_error + +class Evaluator: + + def __init__(self, + dataset_length: int, + keypoint_list: List, + pelvis_ind: int, + metrics: List = ['mode_mpjpe', 'mode_re', 'min_mpjpe', 'min_re'], + pck_thresholds: Optional[List] = None): + """ + Class used for evaluating trained models on different 3D pose datasets. + Args: + dataset_length (int): Total dataset length. + keypoint_list [List]: List of keypoints used for evaluation. + pelvis_ind (int): Index of pelvis keypoint; used for aligning the predictions and ground truth. + metrics [List]: List of evaluation metrics to record. + """ + self.dataset_length = dataset_length + self.keypoint_list = keypoint_list + self.pelvis_ind = pelvis_ind + self.metrics = metrics + for metric in self.metrics: + setattr(self, metric, np.zeros((dataset_length,))) + self.counter = 0 + if pck_thresholds is None: + self.pck_evaluator = None + else: + self.pck_evaluator = EvaluatorPCK(pck_thresholds) + + def log(self): + """ + Print current evaluation metrics + """ + if self.counter == 0: + print('Evaluation has not started') + return + print(f'{self.counter} / {self.dataset_length} samples') + if self.pck_evaluator is not None: + self.pck_evaluator.log() + for metric in self.metrics: + if metric in ['mode_mpjpe', 'mode_re', 'min_mpjpe', 'min_re']: + unit = 'mm' + else: + unit = '' + print(f'{metric}: {getattr(self, metric)[:self.counter].mean()} {unit}') + print('***') + + def get_metrics_dict(self) -> Dict: + """ + Returns: + Dict: Dictionary of evaluation metrics. + """ + d1 = {metric: getattr(self, metric)[:self.counter].mean() for metric in self.metrics} + if self.pck_evaluator is not None: + d2 = self.pck_evaluator.get_metrics_dict() + d1.update(d2) + return d1 + + def __call__(self, output: Dict, batch: Dict, opt_output: Optional[Dict] = None): + """ + Evaluate current batch. + Args: + output (Dict): Regression output. + batch (Dict): Dictionary containing images and their corresponding annotations. + opt_output (Dict): Optimization output. + """ + if self.pck_evaluator is not None: + self.pck_evaluator(output, batch, opt_output) + + pred_keypoints_3d = output['pred_keypoints_3d'].detach() + pred_keypoints_3d = pred_keypoints_3d[:,None,:,:] + batch_size = pred_keypoints_3d.shape[0] + num_samples = pred_keypoints_3d.shape[1] + gt_keypoints_3d = batch['keypoints_3d'][:, :, :-1].unsqueeze(1).repeat(1, num_samples, 1, 1) + + # Align predictions and ground truth such that the pelvis location is at the origin + pred_keypoints_3d -= pred_keypoints_3d[:, :, [self.pelvis_ind]] + gt_keypoints_3d -= gt_keypoints_3d[:, :, [self.pelvis_ind]] + + # Compute joint errors + mpjpe, re = eval_pose(pred_keypoints_3d.reshape(batch_size * num_samples, -1, 3)[:, self.keypoint_list], gt_keypoints_3d.reshape(batch_size * num_samples, -1 ,3)[:, self.keypoint_list]) + mpjpe = mpjpe.reshape(batch_size, num_samples) + re = re.reshape(batch_size, num_samples) + + # Compute 2d keypoint errors + pred_keypoints_2d = output['pred_keypoints_2d'].detach() + pred_keypoints_2d = pred_keypoints_2d[:,None,:,:] + gt_keypoints_2d = batch['keypoints_2d'][:,None,:,:].repeat(1, num_samples, 1, 1) + conf = gt_keypoints_2d[:, :, :, -1].clone() + kp_err = torch.nn.functional.mse_loss( + pred_keypoints_2d, + gt_keypoints_2d[:, :, :, :-1], + reduction='none' + ).sum(dim=3) + kp_l2_loss = (conf * kp_err).mean(dim=2) + kp_l2_loss = kp_l2_loss.detach().cpu().numpy() + + # Compute joint errors after optimization, if available. + if opt_output is not None: + opt_keypoints_3d = opt_output['model_joints'] + opt_keypoints_3d -= opt_keypoints_3d[:, [self.pelvis_ind]] + opt_mpjpe, opt_re = eval_pose(opt_keypoints_3d[:, self.keypoint_list], gt_keypoints_3d[:, 0, self.keypoint_list]) + + # The 0-th sample always corresponds to the mode + if hasattr(self, 'mode_mpjpe'): + mode_mpjpe = mpjpe[:, 0] + self.mode_mpjpe[self.counter:self.counter+batch_size] = mode_mpjpe + if hasattr(self, 'mode_re'): + mode_re = re[:, 0] + self.mode_re[self.counter:self.counter+batch_size] = mode_re + if hasattr(self, 'mode_kpl2'): + mode_kpl2 = kp_l2_loss[:, 0] + self.mode_kpl2[self.counter:self.counter+batch_size] = mode_kpl2 + if hasattr(self, 'min_mpjpe'): + min_mpjpe = mpjpe.min(axis=-1) + self.min_mpjpe[self.counter:self.counter+batch_size] = min_mpjpe + if hasattr(self, 'min_re'): + min_re = re.min(axis=-1) + self.min_re[self.counter:self.counter+batch_size] = min_re + if hasattr(self, 'min_kpl2'): + min_kpl2 = kp_l2_loss.min(axis=-1) + self.min_kpl2[self.counter:self.counter+batch_size] = min_kpl2 + if hasattr(self, 'opt_mpjpe'): + self.opt_mpjpe[self.counter:self.counter+batch_size] = opt_mpjpe + if hasattr(self, 'opt_re'): + self.opt_re[self.counter:self.counter+batch_size] = opt_re + + self.counter += batch_size + + if hasattr(self, 'mode_mpjpe') and hasattr(self, 'mode_re'): + return { + 'mode_mpjpe': mode_mpjpe, + 'mode_re': mode_re, + } + else: + return {} + + +class EvaluatorPCK: + + def __init__(self, thresholds: List = [0.05, 0.1, 0.2, 0.3, 0.4, 0.5],): + """ + Class used for evaluating trained models on different 3D pose datasets. + Args: + thresholds [List]: List of PCK thresholds to evaluate. + metrics [List]: List of evaluation metrics to record. + """ + self.thresholds = thresholds + self.pred_kp_2d = [] + self.gt_kp_2d = [] + self.gt_conf_2d = [] + self.counter = 0 + + def log(self): + """ + Print current evaluation metrics + """ + if self.counter == 0: + print('Evaluation has not started') + return + print(f'{self.counter} samples') + metrics_dict = self.get_metrics_dict() + for metric in metrics_dict: + print(f'{metric}: {metrics_dict[metric]}') + print('***') + + def get_metrics_dict(self) -> Dict: + """ + Returns: + Dict: Dictionary of evaluation metrics. + """ + pcks = self.compute_pcks() + metrics = {} + for thr, (acc,avg_acc,cnt) in zip(self.thresholds, pcks): + metrics.update({f'kp{i}_pck_{thr}': float(a) for i, a in enumerate(acc) if a>=0}) + metrics.update({f'kpAvg_pck_{thr}': float(avg_acc)}) + return metrics + + def compute_pcks(self): + pred_kp_2d = np.concatenate(self.pred_kp_2d, axis=0) + gt_kp_2d = np.concatenate(self.gt_kp_2d, axis=0) + gt_conf_2d = np.concatenate(self.gt_conf_2d, axis=0) + assert pred_kp_2d.shape == gt_kp_2d.shape + assert pred_kp_2d[..., 0].shape == gt_conf_2d.shape + assert pred_kp_2d.shape[1] == 1 # num_samples + + from .pck_accuracy import keypoint_pck_accuracy + pcks = [ + keypoint_pck_accuracy( + pred_kp_2d[:, 0, :, :], + gt_kp_2d[:, 0, :, :], + gt_conf_2d[:, 0, :]>0.5, + thr=thr, + normalize = np.ones((len(pred_kp_2d),2)) # Already in [-0.5,0.5] range. No need to normalize + ) + for thr in self.thresholds + ] + return pcks + + def __call__(self, output: Dict, batch: Dict, opt_output: Optional[Dict] = None): + """ + Evaluate current batch. + Args: + output (Dict): Regression output. + batch (Dict): Dictionary containing images and their corresponding annotations. + opt_output (Dict): Optimization output. + """ + pred_keypoints_2d = output['pred_keypoints_2d'].detach() + num_samples = 1 + batch_size = pred_keypoints_2d.shape[0] + + pred_keypoints_2d = pred_keypoints_2d[:,None,:,:] + gt_keypoints_2d = batch['keypoints_2d'][:,None,:,:].repeat(1, num_samples, 1, 1) + + gt_bbox_expand_factor = (batch['box_size']/(batch['_scale']*200).max(dim=-1).values) + gt_bbox_expand_factor = gt_bbox_expand_factor[:,None,None,None].repeat(1, num_samples, 1, 1) + gt_bbox_expand_factor = gt_bbox_expand_factor.detach().cpu().numpy() + + self.pred_kp_2d.append(pred_keypoints_2d[:, :, :, :2].detach().cpu().numpy() * gt_bbox_expand_factor) + self.gt_conf_2d.append(gt_keypoints_2d[:, :, :, -1].detach().cpu().numpy()) + self.gt_kp_2d.append(gt_keypoints_2d[:, :, :, :2].detach().cpu().numpy() * gt_bbox_expand_factor) + + self.counter += batch_size diff --git a/motiondiff_modules/hmr2/utils/pylogger.py b/motiondiff_modules/hmr2/utils/pylogger.py new file mode 100644 index 0000000..92ffa71 --- /dev/null +++ b/motiondiff_modules/hmr2/utils/pylogger.py @@ -0,0 +1,17 @@ +import logging + +from pytorch_lightning.utilities import rank_zero_only + + +def get_pylogger(name=__name__) -> logging.Logger: + """Initializes multi-GPU-friendly python command line logger.""" + + logger = logging.getLogger(name) + + # this ensures all logging levels get marked with the rank zero decorator + # otherwise logs would get multiplied for each GPU process in multi-GPU setup + logging_levels = ("debug", "info", "warning", "error", "exception", "fatal", "critical") + for level in logging_levels: + setattr(logger, level, rank_zero_only(getattr(logger, level))) + + return logger diff --git a/motiondiff_modules/hmr2/utils/render_openpose.py b/motiondiff_modules/hmr2/utils/render_openpose.py new file mode 100644 index 0000000..a4a26e3 --- /dev/null +++ b/motiondiff_modules/hmr2/utils/render_openpose.py @@ -0,0 +1,149 @@ +""" +Render OpenPose keypoints. +Code was ported to Python from the official C++ implementation https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/src/openpose/utilities/keypoint.cpp +""" +import cv2 +import math +import numpy as np +from typing import List, Tuple + +def get_keypoints_rectangle(keypoints: np.array, threshold: float) -> Tuple[float, float, float]: + """ + Compute rectangle enclosing keypoints above the threshold. + Args: + keypoints (np.array): Keypoint array of shape (N, 3). + threshold (float): Confidence visualization threshold. + Returns: + Tuple[float, float, float]: Rectangle width, height and area. + """ + valid_ind = keypoints[:, -1] > threshold + if valid_ind.sum() > 0: + valid_keypoints = keypoints[valid_ind][:, :-1] + max_x = valid_keypoints[:,0].max() + max_y = valid_keypoints[:,1].max() + min_x = valid_keypoints[:,0].min() + min_y = valid_keypoints[:,1].min() + width = max_x - min_x + height = max_y - min_y + area = width * height + return width, height, area + else: + return 0,0,0 + +def render_keypoints(img: np.array, + keypoints: np.array, + pairs: List, + colors: List, + thickness_circle_ratio: float, + thickness_line_ratio_wrt_circle: float, + pose_scales: List, + threshold: float = 0.1) -> np.array: + """ + Render keypoints on input image. + Args: + img (np.array): Input image of shape (H, W, 3) with pixel values in the [0,255] range. + keypoints (np.array): Keypoint array of shape (N, 3). + pairs (List): List of keypoint pairs per limb. + colors: (List): List of colors per keypoint. + thickness_circle_ratio (float): Circle thickness ratio. + thickness_line_ratio_wrt_circle (float): Line thickness ratio wrt the circle. + pose_scales (List): List of pose scales. + threshold (float): Only visualize keypoints with confidence above the threshold. + Returns: + (np.array): Image of shape (H, W, 3) with keypoints drawn on top of the original image. + """ + img_orig = img.copy() + width, height = img.shape[1], img.shape[2] + area = width * height + + lineType = 8 + shift = 0 + numberColors = len(colors) + thresholdRectangle = 0.1 + + person_width, person_height, person_area = get_keypoints_rectangle(keypoints, thresholdRectangle) + if person_area > 0: + ratioAreas = min(1, max(person_width / width, person_height / height)) + thicknessRatio = np.maximum(np.round(math.sqrt(area) * thickness_circle_ratio * ratioAreas), 2) + thicknessCircle = np.maximum(1, thicknessRatio if ratioAreas > 0.05 else -np.ones_like(thicknessRatio)) + thicknessLine = np.maximum(1, np.round(thicknessRatio * thickness_line_ratio_wrt_circle)) + radius = thicknessRatio / 2 + + img = np.ascontiguousarray(img.copy()) + for i, pair in enumerate(pairs): + index1, index2 = pair + if keypoints[index1, -1] > threshold and keypoints[index2, -1] > threshold: + thicknessLineScaled = int(round(min(thicknessLine[index1], thicknessLine[index2]) * pose_scales[0])) + colorIndex = index2 + color = colors[colorIndex % numberColors] + keypoint1 = keypoints[index1, :-1].astype(np.int) + keypoint2 = keypoints[index2, :-1].astype(np.int) + cv2.line(img, tuple(keypoint1.tolist()), tuple(keypoint2.tolist()), tuple(color.tolist()), thicknessLineScaled, lineType, shift) + for part in range(len(keypoints)): + faceIndex = part + if keypoints[faceIndex, -1] > threshold: + radiusScaled = int(round(radius[faceIndex] * pose_scales[0])) + thicknessCircleScaled = int(round(thicknessCircle[faceIndex] * pose_scales[0])) + colorIndex = part + color = colors[colorIndex % numberColors] + center = keypoints[faceIndex, :-1].astype(np.int) + cv2.circle(img, tuple(center.tolist()), radiusScaled, tuple(color.tolist()), thicknessCircleScaled, lineType, shift) + return img + +def render_body_keypoints(img: np.array, + body_keypoints: np.array) -> np.array: + """ + Render OpenPose body keypoints on input image. + Args: + img (np.array): Input image of shape (H, W, 3) with pixel values in the [0,255] range. + body_keypoints (np.array): Keypoint array of shape (N, 3); 3 <====> (x, y, confidence). + Returns: + (np.array): Image of shape (H, W, 3) with keypoints drawn on top of the original image. + """ + + thickness_circle_ratio = 1./75. * np.ones(body_keypoints.shape[0]) + thickness_line_ratio_wrt_circle = 0.75 + pairs = [] + pairs = [1,8,1,2,1,5,2,3,3,4,5,6,6,7,8,9,9,10,10,11,8,12,12,13,13,14,1,0,0,15,15,17,0,16,16,18,14,19,19,20,14,21,11,22,22,23,11,24] + pairs = np.array(pairs).reshape(-1,2) + colors = [255., 0., 85., + 255., 0., 0., + 255., 85., 0., + 255., 170., 0., + 255., 255., 0., + 170., 255., 0., + 85., 255., 0., + 0., 255., 0., + 255., 0., 0., + 0., 255., 85., + 0., 255., 170., + 0., 255., 255., + 0., 170., 255., + 0., 85., 255., + 0., 0., 255., + 255., 0., 170., + 170., 0., 255., + 255., 0., 255., + 85., 0., 255., + 0., 0., 255., + 0., 0., 255., + 0., 0., 255., + 0., 255., 255., + 0., 255., 255., + 0., 255., 255.] + colors = np.array(colors).reshape(-1,3) + pose_scales = [1] + return render_keypoints(img, body_keypoints, pairs, colors, thickness_circle_ratio, thickness_line_ratio_wrt_circle, pose_scales, 0.1) + +def render_openpose(img: np.array, + body_keypoints: np.array) -> np.array: + """ + Render keypoints in the OpenPose format on input image. + Args: + img (np.array): Input image of shape (H, W, 3) with pixel values in the [0,255] range. + body_keypoints (np.array): Keypoint array of shape (N, 3); 3 <====> (x, y, confidence). + Returns: + (np.array): Image of shape (H, W, 3) with keypoints drawn on top of the original image. + """ + img = render_body_keypoints(img, body_keypoints) + return img diff --git a/motiondiff_modules/hmr2/utils/renderer.py b/motiondiff_modules/hmr2/utils/renderer.py new file mode 100644 index 0000000..5454843 --- /dev/null +++ b/motiondiff_modules/hmr2/utils/renderer.py @@ -0,0 +1,399 @@ +import os +if os.name == 'posix' and "DISPLAY" not in os.environ: + os.environ['PYOPENGL_PLATFORM'] = 'egl' +import torch +import numpy as np +import pyrender +import trimesh +import cv2 +from yacs.config import CfgNode +from typing import List, Optional + +def cam_crop_to_full(cam_bbox, box_center, box_size, img_size, focal_length=5000.): + # Convert cam_bbox to full image + img_w, img_h = img_size[:, 0], img_size[:, 1] + cx, cy, b = box_center[:, 0], box_center[:, 1], box_size + w_2, h_2 = img_w / 2., img_h / 2. + bs = b * cam_bbox[:, 0] + 1e-9 + tz = 2 * focal_length / bs + tx = (2 * (cx - w_2) / bs) + cam_bbox[:, 1] + ty = (2 * (cy - h_2) / bs) + cam_bbox[:, 2] + full_cam = torch.stack([tx, ty, tz], dim=-1) + return full_cam + +def get_light_poses(n_lights=5, elevation=np.pi / 3, dist=12): + # get lights in a circle around origin at elevation + thetas = elevation * np.ones(n_lights) + phis = 2 * np.pi * np.arange(n_lights) / n_lights + poses = [] + trans = make_translation(torch.tensor([0, 0, dist])) + for phi, theta in zip(phis, thetas): + rot = make_rotation(rx=-theta, ry=phi, order="xyz") + poses.append((rot @ trans).numpy()) + return poses + +def make_translation(t): + return make_4x4_pose(torch.eye(3), t) + +def make_rotation(rx=0, ry=0, rz=0, order="xyz"): + Rx = rotx(rx) + Ry = roty(ry) + Rz = rotz(rz) + if order == "xyz": + R = Rz @ Ry @ Rx + elif order == "xzy": + R = Ry @ Rz @ Rx + elif order == "yxz": + R = Rz @ Rx @ Ry + elif order == "yzx": + R = Rx @ Rz @ Ry + elif order == "zyx": + R = Rx @ Ry @ Rz + elif order == "zxy": + R = Ry @ Rx @ Rz + return make_4x4_pose(R, torch.zeros(3)) + +def make_4x4_pose(R, t): + """ + :param R (*, 3, 3) + :param t (*, 3) + return (*, 4, 4) + """ + dims = R.shape[:-2] + pose_3x4 = torch.cat([R, t.view(*dims, 3, 1)], dim=-1) + bottom = ( + torch.tensor([0, 0, 0, 1], device=R.device) + .reshape(*(1,) * len(dims), 1, 4) + .expand(*dims, 1, 4) + ) + return torch.cat([pose_3x4, bottom], dim=-2) + + +def rotx(theta): + return torch.tensor( + [ + [1, 0, 0], + [0, np.cos(theta), -np.sin(theta)], + [0, np.sin(theta), np.cos(theta)], + ], + dtype=torch.float32, + ) + + +def roty(theta): + return torch.tensor( + [ + [np.cos(theta), 0, np.sin(theta)], + [0, 1, 0], + [-np.sin(theta), 0, np.cos(theta)], + ], + dtype=torch.float32, + ) + + +def rotz(theta): + return torch.tensor( + [ + [np.cos(theta), -np.sin(theta), 0], + [np.sin(theta), np.cos(theta), 0], + [0, 0, 1], + ], + dtype=torch.float32, + ) + + +def create_raymond_lights() -> List[pyrender.Node]: + """ + Return raymond light nodes for the scene. + """ + thetas = np.pi * np.array([1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0]) + phis = np.pi * np.array([0.0, 2.0 / 3.0, 4.0 / 3.0]) + + nodes = [] + + for phi, theta in zip(phis, thetas): + xp = np.sin(theta) * np.cos(phi) + yp = np.sin(theta) * np.sin(phi) + zp = np.cos(theta) + + z = np.array([xp, yp, zp]) + z = z / np.linalg.norm(z) + x = np.array([-z[1], z[0], 0.0]) + if np.linalg.norm(x) == 0: + x = np.array([1.0, 0.0, 0.0]) + x = x / np.linalg.norm(x) + y = np.cross(z, x) + + matrix = np.eye(4) + matrix[:3,:3] = np.c_[x,y,z] + nodes.append(pyrender.Node( + light=pyrender.DirectionalLight(color=np.ones(3), intensity=1.0), + matrix=matrix + )) + + return nodes + +class Renderer: + + def __init__(self, cfg: CfgNode, faces: np.array): + """ + Wrapper around the pyrender renderer to render SMPL meshes. + Args: + cfg (CfgNode): Model config file. + faces (np.array): Array of shape (F, 3) containing the mesh faces. + """ + self.cfg = cfg + self.focal_length = cfg.EXTRA.FOCAL_LENGTH + self.img_res = cfg.MODEL.IMAGE_SIZE + + self.camera_center = [self.img_res // 2, self.img_res // 2] + self.faces = faces + + def __call__(self, + vertices: np.array, + camera_translation: np.array, + image: torch.Tensor, + full_frame: bool = False, + imgname: Optional[str] = None, + side_view=False, top_view=False, + rot_angle=90, + mesh_base_color=(1.0, 1.0, 0.9), + scene_bg_color=(0,0,0), + return_rgba=False, + ) -> np.array: + """ + Render meshes on input image + Args: + vertices (np.array): Array of shape (V, 3) containing the mesh vertices. + camera_translation (np.array): Array of shape (3,) with the camera translation. + image (torch.Tensor): Tensor of shape (3, H, W) containing the image crop with normalized pixel values. + full_frame (bool): If True, then render on the full image. + imgname (Optional[str]): Contains the original image filenamee. Used only if full_frame == True. + """ + + if full_frame: + image = cv2.imread(imgname).astype(np.float32)[:, :, ::-1] / 255. + else: + image = image.clone() * torch.tensor(self.cfg.MODEL.IMAGE_STD, device=image.device).reshape(3,1,1) + image = image + torch.tensor(self.cfg.MODEL.IMAGE_MEAN, device=image.device).reshape(3,1,1) + image = image.permute(1, 2, 0).cpu().numpy() + + renderer = pyrender.OffscreenRenderer(viewport_width=image.shape[1], + viewport_height=image.shape[0], + point_size=1.0) + material = pyrender.MetallicRoughnessMaterial( + metallicFactor=0.0, + alphaMode='OPAQUE', + baseColorFactor=(*mesh_base_color, 1.0)) + + camera_translation[0] *= -1. + + mesh = trimesh.Trimesh(vertices.copy(), self.faces.copy()) + if side_view: + rot = trimesh.transformations.rotation_matrix( + np.radians(rot_angle), [0, 1, 0]) + mesh.apply_transform(rot) + elif top_view: + rot = trimesh.transformations.rotation_matrix( + np.radians(rot_angle), [1, 0, 0]) + mesh.apply_transform(rot) + rot = trimesh.transformations.rotation_matrix( + np.radians(180), [1, 0, 0]) + mesh.apply_transform(rot) + mesh = pyrender.Mesh.from_trimesh(mesh, material=material) + + scene = pyrender.Scene(bg_color=[*scene_bg_color, 0.0], + ambient_light=(0.3, 0.3, 0.3)) + scene.add(mesh, 'mesh') + + camera_pose = np.eye(4) + camera_pose[:3, 3] = camera_translation + camera_center = [image.shape[1] / 2., image.shape[0] / 2.] + camera = pyrender.IntrinsicsCamera(fx=self.focal_length, fy=self.focal_length, + cx=camera_center[0], cy=camera_center[1], zfar=1e12) + scene.add(camera, pose=camera_pose) + + + light_nodes = create_raymond_lights() + for node in light_nodes: + scene.add_node(node) + + color, rend_depth = renderer.render(scene, flags=pyrender.RenderFlags.RGBA) + color = color.astype(np.float32) / 255.0 + renderer.delete() + + if return_rgba: + return color + + valid_mask = (color[:, :, -1])[:, :, np.newaxis] + if not side_view and not top_view: + output_img = (color[:, :, :3] * valid_mask + (1 - valid_mask) * image) + else: + output_img = color[:, :, :3] + + output_img = output_img.astype(np.float32) + return output_img + + def vertices_to_trimesh(self, vertices, camera_translation, mesh_base_color=(1.0, 1.0, 0.9), + rot_axis=[1,0,0], rot_angle=0,): + # material = pyrender.MetallicRoughnessMaterial( + # metallicFactor=0.0, + # alphaMode='OPAQUE', + # baseColorFactor=(*mesh_base_color, 1.0)) + vertex_colors = np.array([(*mesh_base_color, 1.0)] * vertices.shape[0]) + mesh = trimesh.Trimesh(vertices.copy() + camera_translation, self.faces.copy(), vertex_colors=vertex_colors) + # mesh = trimesh.Trimesh(vertices.copy(), self.faces.copy()) + + rot = trimesh.transformations.rotation_matrix( + np.radians(rot_angle), rot_axis) + mesh.apply_transform(rot) + + rot = trimesh.transformations.rotation_matrix( + np.radians(180), [1, 0, 0]) + mesh.apply_transform(rot) + return mesh + + def render_rgba( + self, + vertices: np.array, + cam_t = None, + rot=None, + rot_axis=[1,0,0], + rot_angle=0, + camera_z=3, + # camera_translation: np.array, + mesh_base_color=(1.0, 1.0, 0.9), + scene_bg_color=(0,0,0), + render_res=[256, 256], + ): + + renderer = pyrender.OffscreenRenderer(viewport_width=render_res[0], + viewport_height=render_res[1], + point_size=1.0) + # material = pyrender.MetallicRoughnessMaterial( + # metallicFactor=0.0, + # alphaMode='OPAQUE', + # baseColorFactor=(*mesh_base_color, 1.0)) + + if cam_t is not None: + camera_translation = cam_t.copy() + # camera_translation[0] *= -1. + else: + camera_translation = np.array([0, 0, camera_z * self.focal_length/render_res[1]]) + + mesh = self.vertices_to_trimesh(vertices, camera_translation, mesh_base_color, rot_axis, rot_angle) + mesh = pyrender.Mesh.from_trimesh(mesh) + # mesh = pyrender.Mesh.from_trimesh(mesh, material=material) + + scene = pyrender.Scene(bg_color=[*scene_bg_color, 0.0], + ambient_light=(0.3, 0.3, 0.3)) + scene.add(mesh, 'mesh') + + camera_pose = np.eye(4) + # camera_pose[:3, 3] = camera_translation + camera_center = [render_res[0] / 2., render_res[1] / 2.] + camera = pyrender.IntrinsicsCamera(fx=self.focal_length, fy=self.focal_length, + cx=camera_center[0], cy=camera_center[1], zfar=1e12) + + # Create camera node and add it to pyRender scene + camera_node = pyrender.Node(camera=camera, matrix=camera_pose) + scene.add_node(camera_node) + self.add_point_lighting(scene, camera_node) + self.add_lighting(scene, camera_node) + + light_nodes = create_raymond_lights() + for node in light_nodes: + scene.add_node(node) + + color, rend_depth = renderer.render(scene, flags=pyrender.RenderFlags.RGBA) + color = color.astype(np.float32) / 255.0 + renderer.delete() + + return color + + def render_rgba_multiple( + self, + vertices: List[np.array], + cam_t: List[np.array], + rot_axis=[1,0,0], + rot_angle=0, + mesh_base_color=(1.0, 1.0, 0.9), + scene_bg_color=(0,0,0), + render_res=[256, 256], + focal_length=None, + ): + + renderer = pyrender.OffscreenRenderer(viewport_width=render_res[0], + viewport_height=render_res[1], + point_size=1.0) + # material = pyrender.MetallicRoughnessMaterial( + # metallicFactor=0.0, + # alphaMode='OPAQUE', + # baseColorFactor=(*mesh_base_color, 1.0)) + + mesh_list = [pyrender.Mesh.from_trimesh(self.vertices_to_trimesh(vvv, ttt.copy(), mesh_base_color, rot_axis, rot_angle)) for vvv,ttt in zip(vertices, cam_t)] + + scene = pyrender.Scene(bg_color=[*scene_bg_color, 0.0], + ambient_light=(0.3, 0.3, 0.3)) + for i,mesh in enumerate(mesh_list): + scene.add(mesh, f'mesh_{i}') + + camera_pose = np.eye(4) + # camera_pose[:3, 3] = camera_translation + camera_center = [render_res[0] / 2., render_res[1] / 2.] + focal_length = focal_length if focal_length is not None else self.focal_length + camera = pyrender.IntrinsicsCamera(fx=focal_length, fy=focal_length, + cx=camera_center[0], cy=camera_center[1], zfar=1e12) + + # Create camera node and add it to pyRender scene + camera_node = pyrender.Node(camera=camera, matrix=camera_pose) + scene.add_node(camera_node) + self.add_point_lighting(scene, camera_node) + self.add_lighting(scene, camera_node) + + light_nodes = create_raymond_lights() + for node in light_nodes: + scene.add_node(node) + + color, rend_depth = renderer.render(scene, flags=pyrender.RenderFlags.RGBA) + color = color.astype(np.float32) / 255.0 + renderer.delete() + + return color + + def add_lighting(self, scene, cam_node, color=np.ones(3), intensity=1.0): + # from phalp.visualize.py_renderer import get_light_poses + light_poses = get_light_poses() + light_poses.append(np.eye(4)) + cam_pose = scene.get_pose(cam_node) + for i, pose in enumerate(light_poses): + matrix = cam_pose @ pose + node = pyrender.Node( + name=f"light-{i:02d}", + light=pyrender.DirectionalLight(color=color, intensity=intensity), + matrix=matrix, + ) + if scene.has_node(node): + continue + scene.add_node(node) + + def add_point_lighting(self, scene, cam_node, color=np.ones(3), intensity=1.0): + # from phalp.visualize.py_renderer import get_light_poses + light_poses = get_light_poses(dist=0.5) + light_poses.append(np.eye(4)) + cam_pose = scene.get_pose(cam_node) + for i, pose in enumerate(light_poses): + matrix = cam_pose @ pose + # node = pyrender.Node( + # name=f"light-{i:02d}", + # light=pyrender.DirectionalLight(color=color, intensity=intensity), + # matrix=matrix, + # ) + node = pyrender.Node( + name=f"plight-{i:02d}", + light=pyrender.PointLight(color=color, intensity=intensity), + matrix=matrix, + ) + if scene.has_node(node): + continue + scene.add_node(node) diff --git a/motiondiff_modules/hmr2/utils/rich_utils.py b/motiondiff_modules/hmr2/utils/rich_utils.py new file mode 100644 index 0000000..19f9749 --- /dev/null +++ b/motiondiff_modules/hmr2/utils/rich_utils.py @@ -0,0 +1,105 @@ +from pathlib import Path +from typing import Sequence + +import rich +import rich.syntax +import rich.tree +from hydra.core.hydra_config import HydraConfig +from omegaconf import DictConfig, OmegaConf, open_dict +from pytorch_lightning.utilities import rank_zero_only +from rich.prompt import Prompt + +from . import pylogger + +log = pylogger.get_pylogger(__name__) + + +@rank_zero_only +def print_config_tree( + cfg: DictConfig, + print_order: Sequence[str] = ( + "datamodule", + "model", + "callbacks", + "logger", + "trainer", + "paths", + "extras", + ), + resolve: bool = False, + save_to_file: bool = False, +) -> None: + """Prints content of DictConfig using Rich library and its tree structure. + + Args: + cfg (DictConfig): Configuration composed by Hydra. + print_order (Sequence[str], optional): Determines in what order config components are printed. + resolve (bool, optional): Whether to resolve reference fields of DictConfig. + save_to_file (bool, optional): Whether to export config to the hydra output folder. + """ + + style = "dim" + tree = rich.tree.Tree("CONFIG", style=style, guide_style=style) + + queue = [] + + # add fields from `print_order` to queue + for field in print_order: + queue.append(field) if field in cfg else log.warning( + f"Field '{field}' not found in config. Skipping '{field}' config printing..." + ) + + # add all the other fields to queue (not specified in `print_order`) + for field in cfg: + if field not in queue: + queue.append(field) + + # generate config tree from queue + for field in queue: + branch = tree.add(field, style=style, guide_style=style) + + config_group = cfg[field] + if isinstance(config_group, DictConfig): + branch_content = OmegaConf.to_yaml(config_group, resolve=resolve) + else: + branch_content = str(config_group) + + branch.add(rich.syntax.Syntax(branch_content, "yaml")) + + # print config tree + rich.print(tree) + + # save config tree to file + if save_to_file: + with open(Path(cfg.paths.output_dir, "config_tree.log"), "w") as file: + rich.print(tree, file=file) + + +@rank_zero_only +def enforce_tags(cfg: DictConfig, save_to_file: bool = False) -> None: + """Prompts user to input tags from command line if no tags are provided in config.""" + + if not cfg.get("tags"): + if "id" in HydraConfig().cfg.hydra.job: + raise ValueError("Specify tags before launching a multirun!") + + log.warning("No tags provided in config. Prompting user to input tags...") + tags = Prompt.ask("Enter a list of comma separated tags", default="dev") + tags = [t.strip() for t in tags.split(",") if t != ""] + + with open_dict(cfg): + cfg.tags = tags + + log.info(f"Tags: {cfg.tags}") + + if save_to_file: + with open(Path(cfg.paths.output_dir, "tags.log"), "w") as file: + rich.print(cfg.tags, file=file) + + +if __name__ == "__main__": + from hydra import compose, initialize + + with initialize(version_base="1.2", config_path="../../configs"): + cfg = compose(config_name="train.yaml", return_hydra_config=False, overrides=[]) + print_config_tree(cfg, resolve=False, save_to_file=False) diff --git a/motiondiff_modules/hmr2/utils/skeleton_renderer.py b/motiondiff_modules/hmr2/utils/skeleton_renderer.py new file mode 100644 index 0000000..d2f3f5e --- /dev/null +++ b/motiondiff_modules/hmr2/utils/skeleton_renderer.py @@ -0,0 +1,122 @@ +import torch +import numpy as np +import trimesh +from typing import Optional +from yacs.config import CfgNode + +from .geometry import perspective_projection +from .render_openpose import render_openpose + +class SkeletonRenderer: + + def __init__(self, cfg: CfgNode): + """ + Object used to render 3D keypoints. Faster for use during training. + Args: + cfg (CfgNode): Model config file. + """ + self.cfg = cfg + + def __call__(self, + pred_keypoints_3d: torch.Tensor, + gt_keypoints_3d: torch.Tensor, + gt_keypoints_2d: torch.Tensor, + images: Optional[np.array] = None, + camera_translation: Optional[torch.Tensor] = None) -> np.array: + """ + Render batch of 3D keypoints. + Args: + pred_keypoints_3d (torch.Tensor): Tensor of shape (B, S, N, 3) containing a batch of predicted 3D keypoints, with S samples per image. + gt_keypoints_3d (torch.Tensor): Tensor of shape (B, N, 4) containing corresponding ground truth 3D keypoints; last value is the confidence. + gt_keypoints_2d (torch.Tensor): Tensor of shape (B, N, 3) containing corresponding ground truth 2D keypoints. + images (torch.Tensor): Tensor of shape (B, H, W, 3) containing images with values in the [0,255] range. + camera_translation (torch.Tensor): Tensor of shape (B, 3) containing the camera translation. + Returns: + np.array : Image with the following layout. Each row contains the a) input image, + b) image with gt 2D keypoints, + c) image with projected gt 3D keypoints, + d_1, ... , d_S) image with projected predicted 3D keypoints, + e) gt 3D keypoints rendered from a side view, + f_1, ... , f_S) predicted 3D keypoints frorm a side view + """ + batch_size = pred_keypoints_3d.shape[0] +# num_samples = pred_keypoints_3d.shape[1] + pred_keypoints_3d = pred_keypoints_3d.clone().cpu().float() + gt_keypoints_3d = gt_keypoints_3d.clone().cpu().float() + gt_keypoints_3d[:, :, :-1] = gt_keypoints_3d[:, :, :-1] - gt_keypoints_3d[:, [25+14], :-1] + pred_keypoints_3d[:, [25+14]] + gt_keypoints_2d = gt_keypoints_2d.clone().cpu().float().numpy() + gt_keypoints_2d[:, :, :-1] = self.cfg.MODEL.IMAGE_SIZE * (gt_keypoints_2d[:, :, :-1] + 1.0) / 2.0 + + openpose_indices = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + gt_indices = [12, 8, 7, 6, 9, 10, 11, 14, 2, 1, 0, 3, 4, 5] + gt_indices = [25 + i for i in gt_indices] + keypoints_to_render = torch.ones(batch_size, gt_keypoints_3d.shape[1], 1) + rotation = torch.eye(3).unsqueeze(0) + if camera_translation is None: + camera_translation = torch.tensor([0.0, 0.0, 2 * self.cfg.EXTRA.FOCAL_LENGTH / (0.8 * self.cfg.MODEL.IMAGE_SIZE)]).unsqueeze(0).repeat(batch_size, 1) + else: + camera_translation = camera_translation.cpu() + + if images is None: + images = np.zeros((batch_size, self.cfg.MODEL.IMAGE_SIZE, self.cfg.MODEL.IMAGE_SIZE, 3)) + focal_length = torch.tensor([self.cfg.EXTRA.FOCAL_LENGTH, self.cfg.EXTRA.FOCAL_LENGTH]).reshape(1, 2) + camera_center = torch.tensor([self.cfg.MODEL.IMAGE_SIZE, self.cfg.MODEL.IMAGE_SIZE], dtype=torch.float).reshape(1, 2) / 2. + gt_keypoints_3d_proj = perspective_projection(gt_keypoints_3d[:, :, :-1], rotation=rotation.repeat(batch_size, 1, 1), translation=camera_translation[:, :], focal_length=focal_length.repeat(batch_size, 1), camera_center=camera_center.repeat(batch_size, 1)) + pred_keypoints_3d_proj = perspective_projection(pred_keypoints_3d.reshape(batch_size, -1, 3), rotation=rotation.repeat(batch_size, 1, 1), translation=camera_translation.reshape(batch_size, -1), focal_length=focal_length.repeat(batch_size, 1), camera_center=camera_center.repeat(batch_size, 1)).reshape(batch_size, -1, 2) + gt_keypoints_3d_proj = torch.cat([gt_keypoints_3d_proj, gt_keypoints_3d[:, :, [-1]]], dim=-1).cpu().numpy() + pred_keypoints_3d_proj = torch.cat([pred_keypoints_3d_proj, keypoints_to_render.reshape(batch_size, -1, 1)], dim=-1).cpu().numpy() + rows = [] + # Rotate keypoints to visualize side view + R = torch.tensor(trimesh.transformations.rotation_matrix(np.radians(90), [0, 1, 0])[:3, :3]).float() + gt_keypoints_3d_side = gt_keypoints_3d.clone() + gt_keypoints_3d_side[:, :, :-1] = torch.einsum('bni,ij->bnj', gt_keypoints_3d_side[:, :, :-1], R) + pred_keypoints_3d_side = pred_keypoints_3d.clone() + pred_keypoints_3d_side = torch.einsum('bni,ij->bnj', pred_keypoints_3d_side, R) + gt_keypoints_3d_proj_side = perspective_projection(gt_keypoints_3d_side[:, :, :-1], rotation=rotation.repeat(batch_size, 1, 1), translation=camera_translation[:, :], focal_length=focal_length.repeat(batch_size, 1), camera_center=camera_center.repeat(batch_size, 1)) + pred_keypoints_3d_proj_side = perspective_projection(pred_keypoints_3d_side.reshape(batch_size, -1, 3), rotation=rotation.repeat(batch_size, 1, 1), translation=camera_translation.reshape(batch_size, -1), focal_length=focal_length.repeat(batch_size, 1), camera_center=camera_center.repeat(batch_size, 1)).reshape(batch_size, -1, 2) + gt_keypoints_3d_proj_side = torch.cat([gt_keypoints_3d_proj_side, gt_keypoints_3d_side[:, :, [-1]]], dim=-1).cpu().numpy() + pred_keypoints_3d_proj_side = torch.cat([pred_keypoints_3d_proj_side, keypoints_to_render.reshape(batch_size, -1, 1)], dim=-1).cpu().numpy() + for i in range(batch_size): + img = images[i] + side_img = np.zeros((self.cfg.MODEL.IMAGE_SIZE, self.cfg.MODEL.IMAGE_SIZE, 3)) + # gt 2D keypoints + body_keypoints_2d = gt_keypoints_2d[i, :25].copy() + for op, gt in zip(openpose_indices, gt_indices): + if gt_keypoints_2d[i, gt, -1] > body_keypoints_2d[op, -1]: + body_keypoints_2d[op] = gt_keypoints_2d[i, gt] + gt_keypoints_img = render_openpose(img, body_keypoints_2d) / 255. + # gt 3D keypoints + body_keypoints_3d_proj = gt_keypoints_3d_proj[i, :25].copy() + for op, gt in zip(openpose_indices, gt_indices): + if gt_keypoints_3d_proj[i, gt, -1] > body_keypoints_3d_proj[op, -1]: + body_keypoints_3d_proj[op] = gt_keypoints_3d_proj[i, gt] + gt_keypoints_3d_proj_img = render_openpose(img, body_keypoints_3d_proj) / 255. + # gt 3D keypoints from the side + body_keypoints_3d_proj = gt_keypoints_3d_proj_side[i, :25].copy() + for op, gt in zip(openpose_indices, gt_indices): + if gt_keypoints_3d_proj_side[i, gt, -1] > body_keypoints_3d_proj[op, -1]: + body_keypoints_3d_proj[op] = gt_keypoints_3d_proj_side[i, gt] + gt_keypoints_3d_proj_img_side = render_openpose(side_img, body_keypoints_3d_proj) / 255. + # pred 3D keypoints + pred_keypoints_3d_proj_imgs = [] + body_keypoints_3d_proj = pred_keypoints_3d_proj[i, :25].copy() + for op, gt in zip(openpose_indices, gt_indices): + if pred_keypoints_3d_proj[i, gt, -1] >= body_keypoints_3d_proj[op, -1]: + body_keypoints_3d_proj[op] = pred_keypoints_3d_proj[i, gt] + pred_keypoints_3d_proj_imgs.append(render_openpose(img, body_keypoints_3d_proj) / 255.) + pred_keypoints_3d_proj_img = np.concatenate(pred_keypoints_3d_proj_imgs, axis=1) + # gt 3D keypoints from the side + pred_keypoints_3d_proj_imgs_side = [] + body_keypoints_3d_proj = pred_keypoints_3d_proj_side[i, :25].copy() + for op, gt in zip(openpose_indices, gt_indices): + if pred_keypoints_3d_proj_side[i, gt, -1] >= body_keypoints_3d_proj[op, -1]: + body_keypoints_3d_proj[op] = pred_keypoints_3d_proj_side[i, gt] + pred_keypoints_3d_proj_imgs_side.append(render_openpose(side_img, body_keypoints_3d_proj) / 255.) + pred_keypoints_3d_proj_img_side = np.concatenate(pred_keypoints_3d_proj_imgs_side, axis=1) + rows.append(np.concatenate((gt_keypoints_img, gt_keypoints_3d_proj_img, pred_keypoints_3d_proj_img, gt_keypoints_3d_proj_img_side, pred_keypoints_3d_proj_img_side), axis=1)) + # Concatenate images + img = np.concatenate(rows, axis=0) + img[:, ::self.cfg.MODEL.IMAGE_SIZE, :] = 1.0 + img[::self.cfg.MODEL.IMAGE_SIZE, :, :] = 1.0 + img[:, (1+1+1)*self.cfg.MODEL.IMAGE_SIZE, :] = 0.5 + return img diff --git a/motiondiff_modules/hmr2/utils/texture_utils.py b/motiondiff_modules/hmr2/utils/texture_utils.py new file mode 100644 index 0000000..0d29d95 --- /dev/null +++ b/motiondiff_modules/hmr2/utils/texture_utils.py @@ -0,0 +1,85 @@ +import numpy as np +import torch +from torch.nn import functional as F +# from psbody.mesh.visibility import visibility_compute + +def uv_to_xyz_and_normals(verts, f, fmap, bmap, ftov): + vn = estimate_vertex_normals(verts, f, ftov) + pixels_to_set = torch.nonzero(fmap+1) + x_to_set = pixels_to_set[:,0] + y_to_set = pixels_to_set[:,1] + b_coords = bmap[x_to_set, y_to_set, :] + f_coords = fmap[x_to_set, y_to_set] + v_ids = f[f_coords] + points = (b_coords[:,0,None]*verts[:,v_ids[:,0]] + + b_coords[:,1,None]*verts[:,v_ids[:,1]] + + b_coords[:,2,None]*verts[:,v_ids[:,2]]) + normals = (b_coords[:,0,None]*vn[:,v_ids[:,0]] + + b_coords[:,1,None]*vn[:,v_ids[:,1]] + + b_coords[:,2,None]*vn[:,v_ids[:,2]]) + return points, normals, vn, f_coords + +def estimate_vertex_normals(v, f, ftov): + face_normals = TriNormalsScaled(v, f) + non_scaled_normals = torch.einsum('ij,bjk->bik', ftov, face_normals) + norms = torch.sum(non_scaled_normals ** 2.0, 2) ** 0.5 + norms[norms == 0] = 1.0 + return torch.div(non_scaled_normals, norms[:,:,None]) + +def TriNormalsScaled(v, f): + return torch.cross(_edges_for(v, f, 1, 0), _edges_for(v, f, 2, 0)) + +def _edges_for(v, f, cplus, cminus): + return v[:,f[:,cplus]] - v[:,f[:,cminus]] + +def psbody_get_face_visibility(v, n, f, cams, normal_threshold=0.5): + bn, nverts, _ = v.shape + nfaces, _ = f.shape + vis_f = np.zeros([bn, nfaces], dtype='float32') + for i in range(bn): + vis, n_dot_cam = visibility_compute(v=v[i], n=n[i], f=f, cams=cams) + vis_v = (vis == 1) & (n_dot_cam > normal_threshold) + vis_f[i] = np.all(vis_v[0,f],1) + return vis_f + +def compute_uvsampler(vt, ft, tex_size=6): + """ + For this mesh, pre-computes the UV coordinates for + F x T x T points. + Returns F x T x T x 2 + """ + uv = obj2nmr_uvmap(ft, vt, tex_size=tex_size) + uv = uv.reshape(-1, tex_size, tex_size, 2) + return uv + +def obj2nmr_uvmap(ft, vt, tex_size=6): + """ + Converts obj uv_map to NMR uv_map (F x T x T x 2), + where tex_size (T) is the sample rate on each face. + """ + # This is F x 3 x 2 + uv_map_for_verts = vt[ft] + + # obj's y coordinate is [1-0], but image is [0-1] + uv_map_for_verts[:, :, 1] = 1 - uv_map_for_verts[:, :, 1] + + # range [0, 1] -> [-1, 1] + uv_map_for_verts = (2 * uv_map_for_verts) - 1 + + alpha = np.arange(tex_size, dtype=float) / (tex_size - 1) + beta = np.arange(tex_size, dtype=float) / (tex_size - 1) + import itertools + # Barycentric coordinate values + coords = np.stack([p for p in itertools.product(*[alpha, beta])]) + + # Compute alpha, beta (this is the same order as NMR) + v2 = uv_map_for_verts[:, 2] + v0v2 = uv_map_for_verts[:, 0] - uv_map_for_verts[:, 2] + v1v2 = uv_map_for_verts[:, 1] - uv_map_for_verts[:, 2] + # Interpolate the vertex uv values: F x 2 x T*2 + uv_map = np.dstack([v0v2, v1v2]).dot(coords.T) + v2.reshape(-1, 2, 1) + + # F x T*2 x 2 -> F x T x T x 2 + uv_map = np.transpose(uv_map, (0, 2, 1)).reshape(-1, tex_size, tex_size, 2) + + return uv_map diff --git a/motiondiff_modules/hmr2/utils/utils_detectron2.py b/motiondiff_modules/hmr2/utils/utils_detectron2.py new file mode 100644 index 0000000..fe01e02 --- /dev/null +++ b/motiondiff_modules/hmr2/utils/utils_detectron2.py @@ -0,0 +1,93 @@ +import detectron2.data.transforms as T +import torch +from detectron2.checkpoint import DetectionCheckpointer +from detectron2.config import CfgNode, instantiate +from detectron2.data import MetadataCatalog +from omegaconf import OmegaConf + + +class DefaultPredictor_Lazy: + """Create a simple end-to-end predictor with the given config that runs on single device for a + single input image. + + Compared to using the model directly, this class does the following additions: + + 1. Load checkpoint from the weights specified in config (cfg.MODEL.WEIGHTS). + 2. Always take BGR image as the input and apply format conversion internally. + 3. Apply resizing defined by the config (`cfg.INPUT.{MIN,MAX}_SIZE_TEST`). + 4. Take one input image and produce a single output, instead of a batch. + + This is meant for simple demo purposes, so it does the above steps automatically. + This is not meant for benchmarks or running complicated inference logic. + If you'd like to do anything more complicated, please refer to its source code as + examples to build and use the model manually. + + Attributes: + metadata (Metadata): the metadata of the underlying dataset, obtained from + test dataset name in the config. + + + Examples: + :: + pred = DefaultPredictor(cfg) + inputs = cv2.imread("input.jpg") + outputs = pred(inputs) + """ + + def __init__(self, cfg): + """ + Args: + cfg: a yacs CfgNode or a omegaconf dict object. + """ + if isinstance(cfg, CfgNode): + self.cfg = cfg.clone() # cfg can be modified by model + self.model = build_model(self.cfg) # noqa: F821 + if len(cfg.DATASETS.TEST): + test_dataset = cfg.DATASETS.TEST[0] + + checkpointer = DetectionCheckpointer(self.model) + checkpointer.load(cfg.MODEL.WEIGHTS) + + self.aug = T.ResizeShortestEdge( + [cfg.INPUT.MIN_SIZE_TEST, cfg.INPUT.MIN_SIZE_TEST], cfg.INPUT.MAX_SIZE_TEST + ) + + self.input_format = cfg.INPUT.FORMAT + else: # new LazyConfig + self.cfg = cfg + self.model = instantiate(cfg.model) + test_dataset = OmegaConf.select(cfg, "dataloader.test.dataset.names", default=None) + if isinstance(test_dataset, (list, tuple)): + test_dataset = test_dataset[0] + + checkpointer = DetectionCheckpointer(self.model) + checkpointer.load(OmegaConf.select(cfg, "train.init_checkpoint", default="")) + + mapper = instantiate(cfg.dataloader.test.mapper) + self.aug = mapper.augmentations + self.input_format = mapper.image_format + + self.model.eval().cuda() + if test_dataset: + self.metadata = MetadataCatalog.get(test_dataset) + assert self.input_format in ["RGB", "BGR"], self.input_format + + def __call__(self, original_image): + """ + Args: + original_image (np.ndarray): an image of shape (H, W, C) (in BGR order). + + Returns: + predictions (dict): + the output of the model for one image only. + See :doc:`/tutorials/models` for details about the format. + """ + with torch.no_grad(): + if self.input_format == "RGB": + original_image = original_image[:, :, ::-1] + height, width = original_image.shape[:2] + image = self.aug(T.AugInput(original_image)).apply_image(original_image) + image = torch.as_tensor(image.astype("float32").transpose(2, 0, 1)) + inputs = {"image": image, "height": height, "width": width} + predictions = self.model([inputs])[0] + return predictions diff --git a/motiondiff_modules/mGPT/__init__.py b/motiondiff_modules/mGPT/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/motiondiff_modules/mGPT/archs/__init__.py b/motiondiff_modules/mGPT/archs/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/motiondiff_modules/mGPT/archs/mgpt_lm.py b/motiondiff_modules/mGPT/archs/mgpt_lm.py new file mode 100644 index 0000000..c30307a --- /dev/null +++ b/motiondiff_modules/mGPT/archs/mgpt_lm.py @@ -0,0 +1,592 @@ +import os +from typing import List, Union +import numpy as np +import math +import time +import heapq +import torch +from torch import Tensor, nn +from torch.distributions.distribution import Distribution +from transformers import AutoModelForSeq2SeqLM, T5ForConditionalGeneration, T5Tokenizer, AutoTokenizer, GPT2LMHeadModel, GPT2Tokenizer +import random +from typing import Optional +from .tools.token_emb import NewTokenEmb + + +class MLM(nn.Module): + + def __init__( + self, + model_path: str, + model_type: str = "t5", + stage: str = "lm_pretrain", + new_token_type: str = "insert", + motion_codebook_size: int = 512, + framerate: float = 20.0, + down_t: int = 4, + predict_ratio: float = 0.2, + inbetween_ratio: float = 0.25, + max_length: int = 256, + lora: bool = False, + quota_ratio: float = 0.5, + noise_density: float = 0.15, + mean_noise_span_length: int = 3, + **kwargs, + ) -> None: + + super().__init__() + + # Parameters + self.m_codebook_size = motion_codebook_size + self.max_length = max_length + self.framerate = framerate + self.down_t = down_t + self.predict_ratio = predict_ratio + self.inbetween_ratio = inbetween_ratio + self.noise_density = noise_density + self.mean_noise_span_length = mean_noise_span_length + self.quota_ratio = quota_ratio + self.stage = stage + + # Instantiate language model + self.tokenizer = AutoTokenizer.from_pretrained(model_path, legacy=True) + if model_type == "t5": + self.language_model = T5ForConditionalGeneration.from_pretrained( + model_path) + self.lm_type = 'encdec' + elif model_type == "gpt2": + self.language_model = GPT2LMHeadModel.from_pretrained(model_path) + self.lm_type = 'dec' + else: + raise ValueError("type must be either seq2seq or conditional") + + if self.lm_type == 'dec': + self.tokenizer.pad_token = self.tokenizer.eos_token + + # Add motion tokens + self.tokenizer.add_tokens( + [f'' for i in range(self.m_codebook_size + 3)]) + + if new_token_type == "insert": + self.language_model.resize_token_embeddings(len(self.tokenizer)) + elif new_token_type == "mlp": + shared = NewTokenEmb(self.language_model.shared, + self.m_codebook_size + 3) + # lm_head = NewTokenEmb(self.language_model.lm_head, + # self.m_codebook_size + 3) + self.language_model.resize_token_embeddings(len(self.tokenizer)) + self.language_model.shared = shared + # self.language_model.lm_head = lm_head + + # Lora + if lora: + from peft import LoraConfig, TaskType, get_peft_model, get_peft_model_state_dict + from peft.utils.other import fsdp_auto_wrap_policy + peft_config = LoraConfig( + bias="none", + task_type="CAUSAL_LM", + # inference_mode=False, + r=8, + lora_alpha=16, + lora_dropout=0.05) + self.language_model = get_peft_model(self.language_model, + peft_config) + + def forward(self, texts: List[str], motion_tokens: Tensor, + lengths: List[int], tasks: dict): + if self.lm_type == 'encdec': + return self.forward_encdec(texts, motion_tokens, lengths, tasks) + elif self.lm_type == 'dec': + return self.forward_dec(texts, motion_tokens, lengths, tasks) + else: + raise NotImplementedError("Only conditional_multitask supported") + + def forward_encdec( + self, + texts: List[str], + motion_tokens: Tensor, + lengths: List[int], + tasks: dict, + ): + + # Tensor to string + motion_strings = self.motion_token_to_string(motion_tokens, lengths) + + # Supervised or unsupervised + # condition = random.choice( + # ['text', 'motion', 'supervised', 'supervised', 'supervised']) + condition = random.choice(['supervised', 'supervised', 'supervised']) + + if condition == 'text': + inputs = texts + outputs = texts + elif condition == 'motion': + inputs = motion_strings + outputs = motion_strings + else: + inputs, outputs = self.template_fulfill(tasks, lengths, + motion_strings, texts) + + # Tokenize + source_encoding = self.tokenizer(inputs, + padding='max_length', + max_length=self.max_length, + truncation=True, + return_attention_mask=True, + add_special_tokens=True, + return_tensors="pt") + + source_attention_mask = source_encoding.attention_mask.to( + motion_tokens.device) + source_input_ids = source_encoding.input_ids.to(motion_tokens.device) + + if condition in ['text', 'motion']: + batch_size, expandend_input_length = source_input_ids.shape + mask_indices = np.asarray([ + self.random_spans_noise_mask(expandend_input_length) + for i in range(batch_size) + ]) + target_mask = ~mask_indices + input_ids_sentinel = self.create_sentinel_ids( + mask_indices.astype(np.int8)) + target_sentinel = self.create_sentinel_ids( + target_mask.astype(np.int8)) + + labels_input_ids = self.filter_input_ids(source_input_ids, + target_sentinel) + source_input_ids = self.filter_input_ids(source_input_ids, + input_ids_sentinel) + + else: + target_inputs = self.tokenizer(outputs, + padding='max_length', + max_length=self.max_length, + truncation=True, + return_attention_mask=True, + add_special_tokens=True, + return_tensors="pt") + + labels_input_ids = target_inputs.input_ids.to(motion_tokens.device) + lables_attention_mask = target_inputs.attention_mask.to( + motion_tokens.device) + + labels_input_ids[labels_input_ids == 0] = -100 + outputs = self.language_model( + input_ids=source_input_ids, + attention_mask=source_attention_mask + if condition == 'supervised' else None, + labels=labels_input_ids, + decoder_attention_mask=lables_attention_mask + if condition == 'supervised' else None, + ) + + return outputs + + def forward_dec( + self, + texts: List[str], + motion_tokens: Tensor, + lengths: List[int], + tasks: dict, + ): + self.tokenizer.padding_side = "right" + + # Tensor to string + motion_strings = self.motion_token_to_string(motion_tokens, lengths) + + # Supervised or unsupervised + condition = random.choice( + ['text', 'motion', 'supervised', 'supervised', 'supervised']) + + if condition == 'text': + labels = texts + elif condition == 'motion': + labels = motion_strings + else: + inputs, outputs = self.template_fulfill(tasks, lengths, + motion_strings, texts) + labels = [] + for i in range(len(inputs)): + labels.append(inputs[i] + ' \n ' + outputs[i] + + self.tokenizer.eos_token) + + # Tokenize + inputs = self.tokenizer(labels, + padding='max_length', + max_length=self.max_length, + truncation=True, + return_attention_mask=True, + return_tensors="pt") + + labels_input_ids = inputs.input_ids.to(motion_tokens.device) + lables_attention_mask = inputs.attention_mask.to(motion_tokens.device) + + # print(labels_input_ids[0:5]) + + outputs = self.language_model(input_ids=labels_input_ids, + attention_mask=lables_attention_mask, + labels=inputs["input_ids"]) + + return outputs + + def generate_direct(self, + texts: List[str], + max_length: int = 256, + num_beams: int = 1, + do_sample: bool = True, + bad_words_ids: List[int] = None): + + # Device + self.device = self.language_model.device + + # Tokenize + if self.lm_type == 'dec': + texts = [text + " \n " for text in texts] + + source_encoding = self.tokenizer(texts, + padding='max_length', + max_length=self.max_length, + truncation=True, + return_attention_mask=True, + add_special_tokens=True, + return_tensors="pt") + + source_input_ids = source_encoding.input_ids.to(self.device) + source_attention_mask = source_encoding.attention_mask.to(self.device) + + if self.lm_type == 'encdec': + outputs = self.language_model.generate( + source_input_ids, + max_length=max_length, + num_beams=num_beams, + do_sample=do_sample, + bad_words_ids=bad_words_ids, + ) + elif self.lm_type == 'dec': + outputs = self.language_model.generate( + input_ids=source_input_ids, + attention_mask=source_attention_mask, + pad_token_id=self.tokenizer.pad_token_id, + do_sample=do_sample, + max_new_tokens=max_length) + self.tokenizer.padding_side = 'left' + + outputs_string = self.tokenizer.batch_decode(outputs, + skip_special_tokens=True) + + print(texts[:2]) + print(outputs_string[:2]) + + outputs_tokens, cleaned_text = self.motion_string_to_token( + outputs_string) + + return outputs_tokens, cleaned_text + + def generate_conditional(self, + texts: Optional[List[str]] = None, + motion_tokens: Optional[Tensor] = None, + lengths: Optional[List[int]] = None, + task: str = "t2m", + with_len: bool = False, + stage: str = 'train', + tasks: dict = None): + + self.device = self.language_model.device + + if task in ["t2m", "m2m", "pred", "inbetween"]: + + if task == "t2m": + assert texts is not None + motion_strings = [''] * len(texts) + if not with_len: + if tasks is None: + tasks = [{ + 'input': + ['Generate motion: '], + 'output': [''] + }] * len(texts) + + lengths = [0] * len(texts) + else: + tasks = [{ + 'input': [ + 'Generate motion with frames: ' + ], + 'output': [''] + }] * len(texts) + + elif task == "pred": + assert motion_tokens is not None and lengths is not None + texts = [''] * len(lengths) + tasks = [{ + 'input': ['Predict motion: '], + 'output': [''] + }] * len(lengths) + + motion_strings_old = self.motion_token_to_string( + motion_tokens, lengths) + motion_strings = [] + for i, length in enumerate(lengths): + split = length // 5 + motion_strings.append( + '>'.join(motion_strings_old[i].split('>')[:split]) + + '>') + + elif task == "inbetween": + assert motion_tokens is not None and lengths is not None + texts = [''] * len(lengths) + tasks = [{ + 'input': [ + "Complete the masked motion: " + ], + 'output': [''] + }] * len(lengths) + motion_strings = self.motion_token_to_string( + motion_tokens, lengths) + + inputs, outputs = self.template_fulfill(tasks, lengths, + motion_strings, texts, + stage) + + outputs_tokens, cleaned_text = self.generate_direct(inputs, + max_length=128, + num_beams=1, + do_sample=True) + + return outputs_tokens + + elif task == "m2t": + assert motion_tokens is not None and lengths is not None + + motion_strings = self.motion_token_to_string( + motion_tokens, lengths) + + if not with_len: + tasks = [{ + 'input': ['Generate text: '], + 'output': [''] + }] * len(lengths) + else: + tasks = [{ + 'input': [ + 'Generate text with frames: ' + ], + 'output': [''] + }] * len(lengths) + + texts = [''] * len(lengths) + + inputs, outputs = self.template_fulfill(tasks, lengths, + motion_strings, texts) + outputs_tokens, cleaned_text = self.generate_direct( + inputs, + max_length=40, + num_beams=1, + do_sample=False, + # bad_words_ids=self.bad_words_ids + ) + return cleaned_text + + def motion_token_to_string(self, motion_token: Tensor, lengths: List[int]): + motion_string = [] + for i in range(len(motion_token)): + motion_i = motion_token[i].cpu( + ) if motion_token[i].device.type == 'cuda' else motion_token[i] + motion_list = motion_i.tolist()[:lengths[i]] + motion_string.append( + (f'' + + ''.join([f'' for i in motion_list]) + + f'')) + return motion_string + + def motion_token_list_to_string(self, motion_token: Tensor): + motion_string = [] + for i in range(len(motion_token)): + motion_i = motion_token[i].cpu( + ) if motion_token[i].device.type == 'cuda' else motion_token[i] + motion_list = motion_i.tolist() + motion_string.append( + (f'' + + ''.join([f'' for i in motion_list]) + + f'')) + return motion_string + + def motion_string_to_token(self, motion_string: List[str]): + motion_tokens = [] + output_string = [] + for i in range(len(motion_string)): + string = self.get_middle_str( + motion_string[i], f'', + f'') + string_list = string.split('><') + token_list = [ + int(i.split('_')[-1].replace('>', '')) + for i in string_list[1:-1] + ] + if len(token_list) == 0: + token_list = [0] + token_list_padded = torch.tensor(token_list, + dtype=int).to(self.device) + motion_tokens.append(token_list_padded) + output_string.append(motion_string[i].replace( + string, '')) + + return motion_tokens, output_string + + def placeholder_fulfill(self, prompt: str, length: int, motion_string: str, + text: str): + + seconds = math.floor(length / self.framerate) + motion_splited = motion_string.split('>') + token_length = length / self.down_t + predict_head = int(token_length * self.predict_ratio + 1) + masked_head = int(token_length * self.inbetween_ratio + 1) + masked_tail = int(token_length * (1 - self.inbetween_ratio) + 1) + + motion_predict_head = '>'.join( + motion_splited[:predict_head] + ) + f'>' + motion_predict_last = f'' + '>'.join( + motion_splited[predict_head:]) + + motion_masked = '>'.join( + motion_splited[:masked_head] + ) + '>' + f'' * ( + masked_tail - masked_head) + '>'.join(motion_splited[masked_tail:]) + + if random.random() < self.quota_ratio: + text = f'\"{text}\"' + + prompt = prompt.replace('', text).replace( + '', + motion_string).replace('', f'{length}').replace( + '', '%.1f' % seconds).replace( + '', motion_predict_head).replace( + '', + motion_predict_last).replace( + '', motion_masked) + + return prompt + + def template_fulfill(self, + tasks, + lengths, + motion_strings, + texts, + stage='test'): + inputs = [] + outputs = [] + for i in range(len(lengths)): + input_template = random.choice(tasks[i]['input']) + output_template = random.choice(tasks[i]['output']) + length = lengths[i] + inputs.append( + self.placeholder_fulfill(input_template, length, + motion_strings[i], texts[i])) + outputs.append( + self.placeholder_fulfill(output_template, length, + motion_strings[i], texts[i])) + + return inputs, outputs + + def get_middle_str(self, content, startStr, endStr): + try: + startIndex = content.index(startStr) + if startIndex >= 0: + startIndex += len(startStr) + endIndex = content.index(endStr) + except: + return f'' + + return f'' + content[ + startIndex:endIndex] + f'' + + def random_spans_noise_mask(self, length): + # From https://github.com/google-research/text-to-text-transfer-transformer/blob/84f8bcc14b5f2c03de51bd3587609ba8f6bbd1cd/t5/data/preprocessors.py + + orig_length = length + + num_noise_tokens = int(np.round(length * self.noise_density)) + # avoid degeneracy by ensuring positive numbers of noise and nonnoise tokens. + num_noise_tokens = min(max(num_noise_tokens, 1), length - 1) + num_noise_spans = int( + np.round(num_noise_tokens / self.mean_noise_span_length)) + + # avoid degeneracy by ensuring positive number of noise spans + num_noise_spans = max(num_noise_spans, 1) + num_nonnoise_tokens = length - num_noise_tokens + + # pick the lengths of the noise spans and the non-noise spans + def _random_segmentation(num_items, num_segments): + """Partition a sequence of items randomly into non-empty segments. + Args: + num_items: an integer scalar > 0 + num_segments: an integer scalar in [1, num_items] + Returns: + a Tensor with shape [num_segments] containing positive integers that add + up to num_items + """ + mask_indices = np.arange(num_items - 1) < (num_segments - 1) + np.random.shuffle(mask_indices) + first_in_segment = np.pad(mask_indices, [[1, 0]]) + segment_id = np.cumsum(first_in_segment) + # count length of sub segments assuming that list is sorted + _, segment_length = np.unique(segment_id, return_counts=True) + return segment_length + + noise_span_lengths = _random_segmentation(num_noise_tokens, + num_noise_spans) + nonnoise_span_lengths = _random_segmentation(num_nonnoise_tokens, + num_noise_spans) + + interleaved_span_lengths = np.reshape( + np.stack([nonnoise_span_lengths, noise_span_lengths], axis=1), + [num_noise_spans * 2], + ) + span_starts = np.cumsum(interleaved_span_lengths)[:-1] + span_start_indicator = np.zeros((length, ), dtype=np.int8) + span_start_indicator[span_starts] = True + span_num = np.cumsum(span_start_indicator) + is_noise = np.equal(span_num % 2, 1) + + return is_noise[:orig_length] + + def create_sentinel_ids(self, mask_indices): + # From https://github.com/huggingface/transformers/blob/main/examples/flax/language-modeling/run_t5_mlm_flax.py + start_indices = mask_indices - np.roll(mask_indices, 1, + axis=-1) * mask_indices + start_indices[:, 0] = mask_indices[:, 0] + + sentinel_ids = np.where(start_indices != 0, + np.cumsum(start_indices, axis=-1), + start_indices) + sentinel_ids = np.where(sentinel_ids != 0, + (len(self.tokenizer) - sentinel_ids), 0) + sentinel_ids -= mask_indices - start_indices + + return sentinel_ids + + def filter_input_ids(self, input_ids, sentinel_ids): + # From https://github.com/huggingface/transformers/blob/main/examples/flax/language-modeling/run_t5_mlm_flax.py + batch_size = input_ids.shape[0] + + input_ids_full = np.where(sentinel_ids != 0, sentinel_ids, + input_ids.to('cpu')) + + # input_ids tokens and sentinel tokens are >= 0, tokens < 0 are + # masked tokens coming after sentinel tokens and should be removed + input_ids = input_ids_full[input_ids_full >= 0].reshape( + (batch_size, -1)) + input_ids = np.concatenate( + [ + input_ids, + np.full((batch_size, 1), + self.tokenizer.eos_token_id, + dtype=np.int32), + ], + axis=-1, + ) + + input_ids = torch.tensor(input_ids, device=self.device) + + return input_ids diff --git a/motiondiff_modules/mGPT/archs/mgpt_vq.py b/motiondiff_modules/mGPT/archs/mgpt_vq.py new file mode 100644 index 0000000..077dc48 --- /dev/null +++ b/motiondiff_modules/mGPT/archs/mgpt_vq.py @@ -0,0 +1,190 @@ +# Partially from https://github.com/Mael-zys/T2M-GPT + +from typing import List, Optional, Union +import torch +import torch.nn as nn +from torch import Tensor, nn +from torch.distributions.distribution import Distribution +from .tools.resnet import Resnet1D +from .tools.quantize_cnn import QuantizeEMAReset, Quantizer, QuantizeEMA, QuantizeReset +from collections import OrderedDict + + +class VQVae(nn.Module): + + def __init__(self, + nfeats: int, + quantizer: str = "ema_reset", + code_num=512, + code_dim=512, + output_emb_width=512, + down_t=3, + stride_t=2, + width=512, + depth=3, + dilation_growth_rate=3, + norm=None, + activation: str = "relu", + **kwargs) -> None: + + super().__init__() + + self.code_dim = code_dim + + self.encoder = Encoder(nfeats, + output_emb_width, + down_t, + stride_t, + width, + depth, + dilation_growth_rate, + activation=activation, + norm=norm) + + self.decoder = Decoder(nfeats, + output_emb_width, + down_t, + stride_t, + width, + depth, + dilation_growth_rate, + activation=activation, + norm=norm) + + if quantizer == "ema_reset": + self.quantizer = QuantizeEMAReset(code_num, code_dim, mu=0.99) + elif quantizer == "orig": + self.quantizer = Quantizer(code_num, code_dim, beta=1.0) + elif quantizer == "ema": + self.quantizer = QuantizeEMA(code_num, code_dim, mu=0.99) + elif quantizer == "reset": + self.quantizer = QuantizeReset(code_num, code_dim) + + def preprocess(self, x): + # (bs, T, Jx3) -> (bs, Jx3, T) + x = x.permute(0, 2, 1) + return x + + def postprocess(self, x): + # (bs, Jx3, T) -> (bs, T, Jx3) + x = x.permute(0, 2, 1) + return x + + def forward(self, features: Tensor): + # Preprocess + x_in = self.preprocess(features) + + # Encode + x_encoder = self.encoder(x_in) + + # quantization + x_quantized, loss, perplexity = self.quantizer(x_encoder) + + # decoder + x_decoder = self.decoder(x_quantized) + x_out = self.postprocess(x_decoder) + + return x_out, loss, perplexity + + def encode( + self, + features: Tensor, + ) -> Union[Tensor, Distribution]: + + N, T, _ = features.shape + x_in = self.preprocess(features) + x_encoder = self.encoder(x_in) + x_encoder = self.postprocess(x_encoder) + x_encoder = x_encoder.contiguous().view(-1, + x_encoder.shape[-1]) # (NT, C) + code_idx = self.quantizer.quantize(x_encoder) + code_idx = code_idx.view(N, -1) + + # latent, dist + return code_idx, None + + def decode(self, z: Tensor): + + x_d = self.quantizer.dequantize(z) + x_d = x_d.view(1, -1, self.code_dim).permute(0, 2, 1).contiguous() + + # decoder + x_decoder = self.decoder(x_d) + x_out = self.postprocess(x_decoder) + return x_out + + +class Encoder(nn.Module): + + def __init__(self, + input_emb_width=3, + output_emb_width=512, + down_t=3, + stride_t=2, + width=512, + depth=3, + dilation_growth_rate=3, + activation='relu', + norm=None): + super().__init__() + + blocks = [] + filter_t, pad_t = stride_t * 2, stride_t // 2 + blocks.append(nn.Conv1d(input_emb_width, width, 3, 1, 1)) + blocks.append(nn.ReLU()) + + for i in range(down_t): + input_dim = width + block = nn.Sequential( + nn.Conv1d(input_dim, width, filter_t, stride_t, pad_t), + Resnet1D(width, + depth, + dilation_growth_rate, + activation=activation, + norm=norm), + ) + blocks.append(block) + blocks.append(nn.Conv1d(width, output_emb_width, 3, 1, 1)) + self.model = nn.Sequential(*blocks) + + def forward(self, x): + return self.model(x) + + +class Decoder(nn.Module): + + def __init__(self, + input_emb_width=3, + output_emb_width=512, + down_t=3, + stride_t=2, + width=512, + depth=3, + dilation_growth_rate=3, + activation='relu', + norm=None): + super().__init__() + blocks = [] + + filter_t, pad_t = stride_t * 2, stride_t // 2 + blocks.append(nn.Conv1d(output_emb_width, width, 3, 1, 1)) + blocks.append(nn.ReLU()) + for i in range(down_t): + out_dim = width + block = nn.Sequential( + Resnet1D(width, + depth, + dilation_growth_rate, + reverse_dilation=True, + activation=activation, + norm=norm), nn.Upsample(scale_factor=2, + mode='nearest'), + nn.Conv1d(width, out_dim, 3, 1, 1)) + blocks.append(block) + blocks.append(nn.Conv1d(width, width, 3, 1, 1)) + blocks.append(nn.ReLU()) + blocks.append(nn.Conv1d(width, input_emb_width, 3, 1, 1)) + self.model = nn.Sequential(*blocks) + + def forward(self, x): + return self.model(x) diff --git a/motiondiff_modules/mGPT/archs/tm2t_evaluator.py b/motiondiff_modules/mGPT/archs/tm2t_evaluator.py new file mode 100644 index 0000000..4654440 --- /dev/null +++ b/motiondiff_modules/mGPT/archs/tm2t_evaluator.py @@ -0,0 +1,111 @@ +import torch +import torch.nn as nn +from torch.nn.utils.rnn import pack_padded_sequence + + +class MovementConvEncoder(nn.Module): + def __init__(self, input_size, hidden_size, output_size): + super(MovementConvEncoder, self).__init__() + self.main = nn.Sequential( + nn.Conv1d(input_size, hidden_size, 4, 2, 1), + nn.Dropout(0.2, inplace=True), + nn.LeakyReLU(0.2, inplace=True), + nn.Conv1d(hidden_size, output_size, 4, 2, 1), + nn.Dropout(0.2, inplace=True), + nn.LeakyReLU(0.2, inplace=True), + ) + self.out_net = nn.Linear(output_size, output_size) + # self.main.apply(init_weight) + # self.out_net.apply(init_weight) + + def forward(self, inputs): + inputs = inputs.permute(0, 2, 1) + outputs = self.main(inputs).permute(0, 2, 1) + # print(outputs.shape) + return self.out_net(outputs) + + +class MotionEncoderBiGRUCo(nn.Module): + def __init__(self, input_size, hidden_size, output_size): + super(MotionEncoderBiGRUCo, self).__init__() + + self.input_emb = nn.Linear(input_size, hidden_size) + self.gru = nn.GRU( + hidden_size, hidden_size, batch_first=True, bidirectional=True + ) + self.output_net = nn.Sequential( + nn.Linear(hidden_size * 2, hidden_size), + nn.LayerNorm(hidden_size), + nn.LeakyReLU(0.2, inplace=True), + nn.Linear(hidden_size, output_size), + ) + + # self.input_emb.apply(init_weight) + # self.output_net.apply(init_weight) + self.hidden_size = hidden_size + self.hidden = nn.Parameter( + torch.randn((2, 1, self.hidden_size), requires_grad=True) + ) + + # input(batch_size, seq_len, dim) + def forward(self, inputs, m_lens): + num_samples = inputs.shape[0] + + input_embs = self.input_emb(inputs) + hidden = self.hidden.repeat(1, num_samples, 1) + + cap_lens = m_lens.data.tolist() + + # emb = pack_padded_sequence(input=input_embs, lengths=cap_lens, batch_first=True) + emb = input_embs + + gru_seq, gru_last = self.gru(emb, hidden) + + gru_last = torch.cat([gru_last[0], gru_last[1]], dim=-1) + + return self.output_net(gru_last) + + +class TextEncoderBiGRUCo(nn.Module): + def __init__(self, word_size, pos_size, hidden_size, output_size): + super(TextEncoderBiGRUCo, self).__init__() + + self.pos_emb = nn.Linear(pos_size, word_size) + self.input_emb = nn.Linear(word_size, hidden_size) + self.gru = nn.GRU( + hidden_size, hidden_size, batch_first=True, bidirectional=True + ) + self.output_net = nn.Sequential( + nn.Linear(hidden_size * 2, hidden_size), + nn.LayerNorm(hidden_size), + nn.LeakyReLU(0.2, inplace=True), + nn.Linear(hidden_size, output_size), + ) + + # self.input_emb.apply(init_weight) + # self.pos_emb.apply(init_weight) + # self.output_net.apply(init_weight) + # self.linear2.apply(init_weight) + # self.batch_size = batch_size + self.hidden_size = hidden_size + self.hidden = nn.Parameter( + torch.randn((2, 1, self.hidden_size), requires_grad=True) + ) + + # input(batch_size, seq_len, dim) + def forward(self, word_embs, pos_onehot, cap_lens): + num_samples = word_embs.shape[0] + + pos_embs = self.pos_emb(pos_onehot) + inputs = word_embs + pos_embs + input_embs = self.input_emb(inputs) + hidden = self.hidden.repeat(1, num_samples, 1) + + cap_lens = cap_lens.data.tolist() + emb = pack_padded_sequence(input=input_embs, lengths=cap_lens, batch_first=True) + + gru_seq, gru_last = self.gru(emb, hidden) + + gru_last = torch.cat([gru_last[0], gru_last[1]], dim=-1) + + return self.output_net(gru_last) diff --git a/motiondiff_modules/mGPT/archs/tools/embeddings.py b/motiondiff_modules/mGPT/archs/tools/embeddings.py new file mode 100644 index 0000000..b53470c --- /dev/null +++ b/motiondiff_modules/mGPT/archs/tools/embeddings.py @@ -0,0 +1,322 @@ +# This file is taken from signjoey repository +import math + +import torch +from torch import Tensor, nn + + +def get_activation(activation_type): + if activation_type == "relu": + return nn.ReLU() + elif activation_type == "relu6": + return nn.ReLU6() + elif activation_type == "prelu": + return nn.PReLU() + elif activation_type == "selu": + return nn.SELU() + elif activation_type == "celu": + return nn.CELU() + elif activation_type == "gelu": + return nn.GELU() + elif activation_type == "sigmoid": + return nn.Sigmoid() + elif activation_type == "softplus": + return nn.Softplus() + elif activation_type == "softshrink": + return nn.Softshrink() + elif activation_type == "softsign": + return nn.Softsign() + elif activation_type == "tanh": + return nn.Tanh() + elif activation_type == "tanhshrink": + return nn.Tanhshrink() + else: + raise ValueError("Unknown activation type {}".format(activation_type)) + + +class MaskedNorm(nn.Module): + """ + Original Code from: + https://discuss.pytorch.org/t/batchnorm-for-different-sized-samples-in-batch/44251/8 + """ + + def __init__(self, norm_type, num_groups, num_features): + super().__init__() + self.norm_type = norm_type + if self.norm_type == "batch": + self.norm = nn.BatchNorm1d(num_features=num_features) + elif self.norm_type == "group": + self.norm = nn.GroupNorm(num_groups=num_groups, num_channels=num_features) + elif self.norm_type == "layer": + self.norm = nn.LayerNorm(normalized_shape=num_features) + else: + raise ValueError("Unsupported Normalization Layer") + + self.num_features = num_features + + def forward(self, x: Tensor, mask: Tensor): + if self.training: + reshaped = x.reshape([-1, self.num_features]) + reshaped_mask = mask.reshape([-1, 1]) > 0 + selected = torch.masked_select(reshaped, reshaped_mask).reshape( + [-1, self.num_features] + ) + batch_normed = self.norm(selected) + scattered = reshaped.masked_scatter(reshaped_mask, batch_normed) + return scattered.reshape([x.shape[0], -1, self.num_features]) + else: + reshaped = x.reshape([-1, self.num_features]) + batched_normed = self.norm(reshaped) + return batched_normed.reshape([x.shape[0], -1, self.num_features]) + + +# TODO (Cihan): Spatial and Word Embeddings are pretty much the same +# We might as well convert them into a single module class. +# Only difference is the lut vs linear layers. +class Embeddings(nn.Module): + + """ + Simple embeddings class + """ + + # pylint: disable=unused-argument + def __init__( + self, + embedding_dim: int = 64, + num_heads: int = 8, + scale: bool = False, + scale_factor: float = None, + norm_type: str = None, + activation_type: str = None, + vocab_size: int = 0, + padding_idx: int = 1, + freeze: bool = False, + **kwargs + ): + """ + Create new embeddings for the vocabulary. + Use scaling for the Transformer. + + :param embedding_dim: + :param scale: + :param vocab_size: + :param padding_idx: + :param freeze: freeze the embeddings during training + """ + super().__init__() + + self.embedding_dim = embedding_dim + self.vocab_size = vocab_size + self.lut = nn.Embedding(vocab_size, self.embedding_dim, padding_idx=padding_idx) + + self.norm_type = norm_type + if self.norm_type: + self.norm = MaskedNorm( + norm_type=norm_type, num_groups=num_heads, num_features=embedding_dim + ) + + self.activation_type = activation_type + if self.activation_type: + self.activation = get_activation(activation_type) + + self.scale = scale + if self.scale: + if scale_factor: + self.scale_factor = scale_factor + else: + self.scale_factor = math.sqrt(self.embedding_dim) + + if freeze: + freeze_params(self) + + # pylint: disable=arguments-differ + def forward(self, x: Tensor, mask: Tensor = None) -> Tensor: + """ + Perform lookup for input `x` in the embedding table. + + :param mask: token masks + :param x: index in the vocabulary + :return: embedded representation for `x` + """ + + x = self.lut(x) + + if self.norm_type: + x = self.norm(x, mask) + + if self.activation_type: + x = self.activation(x) + + if self.scale: + return x * self.scale_factor + else: + return x + + def __repr__(self): + return "%s(embedding_dim=%d, vocab_size=%d)" % ( + self.__class__.__name__, + self.embedding_dim, + self.vocab_size, + ) + + +class SpatialEmbeddings(nn.Module): + + """ + Simple Linear Projection Layer + (For encoder outputs to predict glosses) + """ + + # pylint: disable=unused-argument + def __init__( + self, + embedding_dim: int, + input_size: int, + num_heads: int, + freeze: bool = False, + norm_type: str = "batch", + activation_type: str = "softsign", + scale: bool = False, + scale_factor: float = None, + **kwargs + ): + """ + Create new embeddings for the vocabulary. + Use scaling for the Transformer. + + :param embedding_dim: + :param input_size: + :param freeze: freeze the embeddings during training + """ + super().__init__() + + self.embedding_dim = embedding_dim + self.input_size = input_size + self.ln = nn.Linear(self.input_size, self.embedding_dim) + + self.norm_type = norm_type + if self.norm_type: + self.norm = MaskedNorm( + norm_type=norm_type, num_groups=num_heads, num_features=embedding_dim + ) + + self.activation_type = activation_type + if self.activation_type: + self.activation = get_activation(activation_type) + + self.scale = scale + if self.scale: + if scale_factor: + self.scale_factor = scale_factor + else: + self.scale_factor = math.sqrt(self.embedding_dim) + + if freeze: + freeze_params(self) + + # pylint: disable=arguments-differ + def forward(self, x: Tensor, mask: Tensor) -> Tensor: + """ + :param mask: frame masks + :param x: input frame features + :return: embedded representation for `x` + """ + + x = self.ln(x) + + if self.norm_type: + x = self.norm(x, mask) + + if self.activation_type: + x = self.activation(x) + + if self.scale: + return x * self.scale_factor + else: + return x + + def __repr__(self): + return "%s(embedding_dim=%d, input_size=%d)" % ( + self.__class__.__name__, + self.embedding_dim, + self.input_size, + ) + +def get_timestep_embedding( + timesteps: torch.Tensor, + embedding_dim: int, + flip_sin_to_cos: bool = False, + downscale_freq_shift: float = 1, + scale: float = 1, + max_period: int = 10000, +): + """ + This matches the implementation in Denoising Diffusion Probabilistic Models: Create sinusoidal timestep embeddings. + + :param timesteps: a 1-D Tensor of N indices, one per batch element. + These may be fractional. + :param embedding_dim: the dimension of the output. :param max_period: controls the minimum frequency of the + embeddings. :return: an [N x dim] Tensor of positional embeddings. + """ + assert len(timesteps.shape) == 1, "Timesteps should be a 1d-array" + + half_dim = embedding_dim // 2 + exponent = -math.log(max_period) * torch.arange( + start=0, end=half_dim, dtype=torch.float32, device=timesteps.device + ) + exponent = exponent / (half_dim - downscale_freq_shift) + + emb = torch.exp(exponent) + emb = timesteps[:, None].float() * emb[None, :] + + # scale embeddings + emb = scale * emb + + # concat sine and cosine embeddings + emb = torch.cat([torch.sin(emb), torch.cos(emb)], dim=-1) + + # flip sine and cosine embeddings + if flip_sin_to_cos: + emb = torch.cat([emb[:, half_dim:], emb[:, :half_dim]], dim=-1) + + # zero pad + if embedding_dim % 2 == 1: + emb = torch.nn.functional.pad(emb, (0, 1, 0, 0)) + return emb + + +class TimestepEmbedding(nn.Module): + def __init__(self, channel: int, time_embed_dim: int, act_fn: str = "silu"): + super().__init__() + + self.linear_1 = nn.Linear(channel, time_embed_dim) + self.act = None + if act_fn == "silu": + self.act = nn.SiLU() + self.linear_2 = nn.Linear(time_embed_dim, time_embed_dim) + + def forward(self, sample): + sample = self.linear_1(sample) + + if self.act is not None: + sample = self.act(sample) + + sample = self.linear_2(sample) + return sample + + +class Timesteps(nn.Module): + def __init__(self, num_channels: int, flip_sin_to_cos: bool, downscale_freq_shift: float): + super().__init__() + self.num_channels = num_channels + self.flip_sin_to_cos = flip_sin_to_cos + self.downscale_freq_shift = downscale_freq_shift + + def forward(self, timesteps): + t_emb = get_timestep_embedding( + timesteps, + self.num_channels, + flip_sin_to_cos=self.flip_sin_to_cos, + downscale_freq_shift=self.downscale_freq_shift, + ) + return t_emb diff --git a/motiondiff_modules/mGPT/archs/tools/quantize_cnn.py b/motiondiff_modules/mGPT/archs/tools/quantize_cnn.py new file mode 100644 index 0000000..98ca858 --- /dev/null +++ b/motiondiff_modules/mGPT/archs/tools/quantize_cnn.py @@ -0,0 +1,414 @@ +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F + +class QuantizeEMAReset(nn.Module): + def __init__(self, nb_code, code_dim, mu): + super().__init__() + self.nb_code = nb_code + self.code_dim = code_dim + self.mu = mu + self.reset_codebook() + + def reset_codebook(self): + self.init = False + self.code_sum = None + self.code_count = None + device = "cuda" if torch.cuda.is_available() else "cpu" + self.register_buffer('codebook', torch.zeros(self.nb_code, self.code_dim).to(device)) + + def _tile(self, x): + nb_code_x, code_dim = x.shape + if nb_code_x < self.nb_code: + n_repeats = (self.nb_code + nb_code_x - 1) // nb_code_x + std = 0.01 / np.sqrt(code_dim) + out = x.repeat(n_repeats, 1) + out = out + torch.randn_like(out) * std + else : + out = x + return out + + def init_codebook(self, x): + out = self._tile(x) + self.codebook = out[:self.nb_code] + self.code_sum = self.codebook.clone() + self.code_count = torch.ones(self.nb_code, device=self.codebook.device) + self.init = True + + @torch.no_grad() + def compute_perplexity(self, code_idx) : + # Calculate new centres + code_onehot = torch.zeros(self.nb_code, code_idx.shape[0], device=code_idx.device) # nb_code, N * L + code_onehot.scatter_(0, code_idx.view(1, code_idx.shape[0]), 1) + + code_count = code_onehot.sum(dim=-1) # nb_code + prob = code_count / torch.sum(code_count) + perplexity = torch.exp(-torch.sum(prob * torch.log(prob + 1e-7))) + return perplexity + + @torch.no_grad() + def update_codebook(self, x, code_idx): + + code_onehot = torch.zeros(self.nb_code, x.shape[0], device=x.device) # nb_code, N * L + code_onehot.scatter_(0, code_idx.view(1, x.shape[0]), 1) + + code_sum = torch.matmul(code_onehot, x) # nb_code, w + code_count = code_onehot.sum(dim=-1) # nb_code + + out = self._tile(x) + code_rand = out[:self.nb_code] + + # Update centres + self.code_sum = self.mu * self.code_sum + (1. - self.mu) * code_sum # w, nb_code + self.code_count = self.mu * self.code_count + (1. - self.mu) * code_count # nb_code + + usage = (self.code_count.view(self.nb_code, 1) >= 1.0).float() + code_update = self.code_sum.view(self.nb_code, self.code_dim) / self.code_count.view(self.nb_code, 1) + + self.codebook = usage * code_update + (1 - usage) * code_rand + prob = code_count / torch.sum(code_count) + perplexity = torch.exp(-torch.sum(prob * torch.log(prob + 1e-7))) + + + return perplexity + + def preprocess(self, x): + # NCT -> NTC -> [NT, C] + x = x.permute(0, 2, 1).contiguous() + x = x.view(-1, x.shape[-1]) + return x + + def quantize(self, x): + # Calculate latent code x_l + k_w = self.codebook.t() + distance = torch.sum(x ** 2, dim=-1, keepdim=True) - 2 * torch.matmul(x, k_w) + torch.sum(k_w ** 2, dim=0, + keepdim=True) # (N * L, b) + _, code_idx = torch.min(distance, dim=-1) + return code_idx + + def dequantize(self, code_idx): + x = F.embedding(code_idx, self.codebook) + return x + + + def forward(self, x): + N, width, T = x.shape + + # Preprocess + x = self.preprocess(x) + + # Init codebook if not inited + if self.training and not self.init: + self.init_codebook(x) + + # quantize and dequantize through bottleneck + code_idx = self.quantize(x) + x_d = self.dequantize(code_idx) + + # Update embeddings + if self.training: + perplexity = self.update_codebook(x, code_idx) + else : + perplexity = self.compute_perplexity(code_idx) + + # Loss + commit_loss = F.mse_loss(x, x_d.detach()) + + # Passthrough + x_d = x + (x_d - x).detach() + + # Postprocess + x_d = x_d.view(N, T, -1).permute(0, 2, 1).contiguous() #(N, DIM, T) + + return x_d, commit_loss, perplexity + + + +class Quantizer(nn.Module): + def __init__(self, n_e, e_dim, beta): + super(Quantizer, self).__init__() + + self.e_dim = e_dim + self.n_e = n_e + self.beta = beta + + self.embedding = nn.Embedding(self.n_e, self.e_dim) + self.embedding.weight.data.uniform_(-1.0 / self.n_e, 1.0 / self.n_e) + + def forward(self, z): + + N, width, T = z.shape + z = self.preprocess(z) + assert z.shape[-1] == self.e_dim + z_flattened = z.contiguous().view(-1, self.e_dim) + + # B x V + d = torch.sum(z_flattened ** 2, dim=1, keepdim=True) + \ + torch.sum(self.embedding.weight**2, dim=1) - 2 * \ + torch.matmul(z_flattened, self.embedding.weight.t()) + # B x 1 + min_encoding_indices = torch.argmin(d, dim=1) + z_q = self.embedding(min_encoding_indices).view(z.shape) + + # compute loss for embedding + loss = torch.mean((z_q - z.detach())**2) + self.beta * \ + torch.mean((z_q.detach() - z)**2) + + # preserve gradients + z_q = z + (z_q - z).detach() + z_q = z_q.view(N, T, -1).permute(0, 2, 1).contiguous() #(N, DIM, T) + + min_encodings = F.one_hot(min_encoding_indices, self.n_e).type(z.dtype) + e_mean = torch.mean(min_encodings, dim=0) + perplexity = torch.exp(-torch.sum(e_mean*torch.log(e_mean + 1e-10))) + return z_q, loss, perplexity + + def quantize(self, z): + + assert z.shape[-1] == self.e_dim + + # B x V + d = torch.sum(z ** 2, dim=1, keepdim=True) + \ + torch.sum(self.embedding.weight ** 2, dim=1) - 2 * \ + torch.matmul(z, self.embedding.weight.t()) + # B x 1 + min_encoding_indices = torch.argmin(d, dim=1) + return min_encoding_indices + + def dequantize(self, indices): + + index_flattened = indices.view(-1) + z_q = self.embedding(index_flattened) + z_q = z_q.view(indices.shape + (self.e_dim, )).contiguous() + return z_q + + def preprocess(self, x): + # NCT -> NTC -> [NT, C] + x = x.permute(0, 2, 1).contiguous() + x = x.view(-1, x.shape[-1]) + return x + + + +class QuantizeReset(nn.Module): + def __init__(self, nb_code, code_dim): + super().__init__() + self.nb_code = nb_code + self.code_dim = code_dim + self.reset_codebook() + self.codebook = nn.Parameter(torch.randn(nb_code, code_dim)) + + def reset_codebook(self): + self.init = False + self.code_count = None + + def _tile(self, x): + nb_code_x, code_dim = x.shape + if nb_code_x < self.nb_code: + n_repeats = (self.nb_code + nb_code_x - 1) // nb_code_x + std = 0.01 / np.sqrt(code_dim) + out = x.repeat(n_repeats, 1) + out = out + torch.randn_like(out) * std + else : + out = x + return out + + def init_codebook(self, x): + out = self._tile(x) + self.codebook = nn.Parameter(out[:self.nb_code]) + self.code_count = torch.ones(self.nb_code, device=self.codebook.device) + self.init = True + + @torch.no_grad() + def compute_perplexity(self, code_idx) : + # Calculate new centres + code_onehot = torch.zeros(self.nb_code, code_idx.shape[0], device=code_idx.device) # nb_code, N * L + code_onehot.scatter_(0, code_idx.view(1, code_idx.shape[0]), 1) + + code_count = code_onehot.sum(dim=-1) # nb_code + prob = code_count / torch.sum(code_count) + perplexity = torch.exp(-torch.sum(prob * torch.log(prob + 1e-7))) + return perplexity + + def update_codebook(self, x, code_idx): + + code_onehot = torch.zeros(self.nb_code, x.shape[0], device=x.device) # nb_code, N * L + code_onehot.scatter_(0, code_idx.view(1, x.shape[0]), 1) + + code_count = code_onehot.sum(dim=-1) # nb_code + + out = self._tile(x) + code_rand = out[:self.nb_code] + + # Update centres + self.code_count = code_count # nb_code + usage = (self.code_count.view(self.nb_code, 1) >= 1.0).float() + + self.codebook.data = usage * self.codebook.data + (1 - usage) * code_rand + prob = code_count / torch.sum(code_count) + perplexity = torch.exp(-torch.sum(prob * torch.log(prob + 1e-7))) + + + return perplexity + + def preprocess(self, x): + # NCT -> NTC -> [NT, C] + x = x.permute(0, 2, 1).contiguous() + x = x.view(-1, x.shape[-1]) + return x + + def quantize(self, x): + # Calculate latent code x_l + k_w = self.codebook.t() + distance = torch.sum(x ** 2, dim=-1, keepdim=True) - 2 * torch.matmul(x, k_w) + torch.sum(k_w ** 2, dim=0, + keepdim=True) # (N * L, b) + _, code_idx = torch.min(distance, dim=-1) + return code_idx + + def dequantize(self, code_idx): + x = F.embedding(code_idx, self.codebook) + return x + + + def forward(self, x): + N, width, T = x.shape + # Preprocess + x = self.preprocess(x) + # Init codebook if not inited + if self.training and not self.init: + self.init_codebook(x) + # quantize and dequantize through bottleneck + code_idx = self.quantize(x) + x_d = self.dequantize(code_idx) + # Update embeddings + if self.training: + perplexity = self.update_codebook(x, code_idx) + else : + perplexity = self.compute_perplexity(code_idx) + + # Loss + commit_loss = F.mse_loss(x, x_d.detach()) + + # Passthrough + x_d = x + (x_d - x).detach() + + # Postprocess + x_d = x_d.view(N, T, -1).permute(0, 2, 1).contiguous() #(N, DIM, T) + + return x_d, commit_loss, perplexity + + +class QuantizeEMA(nn.Module): + def __init__(self, nb_code, code_dim, mu): + super().__init__() + self.nb_code = nb_code + self.code_dim = code_dim + self.mu = mu + self.reset_codebook() + + def reset_codebook(self): + self.init = False + self.code_sum = None + self.code_count = None + self.register_buffer('codebook', torch.zeros(self.nb_code, self.code_dim).cuda()) + + def _tile(self, x): + nb_code_x, code_dim = x.shape + if nb_code_x < self.nb_code: + n_repeats = (self.nb_code + nb_code_x - 1) // nb_code_x + std = 0.01 / np.sqrt(code_dim) + out = x.repeat(n_repeats, 1) + out = out + torch.randn_like(out) * std + else : + out = x + return out + + def init_codebook(self, x): + out = self._tile(x) + self.codebook = out[:self.nb_code] + self.code_sum = self.codebook.clone() + self.code_count = torch.ones(self.nb_code, device=self.codebook.device) + self.init = True + + @torch.no_grad() + def compute_perplexity(self, code_idx) : + # Calculate new centres + code_onehot = torch.zeros(self.nb_code, code_idx.shape[0], device=code_idx.device) # nb_code, N * L + code_onehot.scatter_(0, code_idx.view(1, code_idx.shape[0]), 1) + + code_count = code_onehot.sum(dim=-1) # nb_code + prob = code_count / torch.sum(code_count) + perplexity = torch.exp(-torch.sum(prob * torch.log(prob + 1e-7))) + return perplexity + + @torch.no_grad() + def update_codebook(self, x, code_idx): + + code_onehot = torch.zeros(self.nb_code, x.shape[0], device=x.device) # nb_code, N * L + code_onehot.scatter_(0, code_idx.view(1, x.shape[0]), 1) + + code_sum = torch.matmul(code_onehot, x) # nb_code, w + code_count = code_onehot.sum(dim=-1) # nb_code + + # Update centres + self.code_sum = self.mu * self.code_sum + (1. - self.mu) * code_sum # w, nb_code + self.code_count = self.mu * self.code_count + (1. - self.mu) * code_count # nb_code + + code_update = self.code_sum.view(self.nb_code, self.code_dim) / self.code_count.view(self.nb_code, 1) + + self.codebook = code_update + prob = code_count / torch.sum(code_count) + perplexity = torch.exp(-torch.sum(prob * torch.log(prob + 1e-7))) + + return perplexity + + def preprocess(self, x): + # NCT -> NTC -> [NT, C] + x = x.permute(0, 2, 1).contiguous() + x = x.view(-1, x.shape[-1]) + return x + + def quantize(self, x): + # Calculate latent code x_l + k_w = self.codebook.t() + distance = torch.sum(x ** 2, dim=-1, keepdim=True) - 2 * torch.matmul(x, k_w) + torch.sum(k_w ** 2, dim=0, + keepdim=True) # (N * L, b) + _, code_idx = torch.min(distance, dim=-1) + return code_idx + + def dequantize(self, code_idx): + x = F.embedding(code_idx, self.codebook) + return x + + + def forward(self, x): + N, width, T = x.shape + + # Preprocess + x = self.preprocess(x) + + # Init codebook if not inited + if self.training and not self.init: + self.init_codebook(x) + + # quantize and dequantize through bottleneck + code_idx = self.quantize(x) + x_d = self.dequantize(code_idx) + + # Update embeddings + if self.training: + perplexity = self.update_codebook(x, code_idx) + else : + perplexity = self.compute_perplexity(code_idx) + + # Loss + commit_loss = F.mse_loss(x, x_d.detach()) + + # Passthrough + x_d = x + (x_d - x).detach() + + # Postprocess + x_d = x_d.view(N, T, -1).permute(0, 2, 1).contiguous() #(N, DIM, T) + + return x_d, commit_loss, perplexity diff --git a/motiondiff_modules/mGPT/archs/tools/resnet.py b/motiondiff_modules/mGPT/archs/tools/resnet.py new file mode 100644 index 0000000..062346e --- /dev/null +++ b/motiondiff_modules/mGPT/archs/tools/resnet.py @@ -0,0 +1,82 @@ +import torch.nn as nn +import torch + +class nonlinearity(nn.Module): + def __init__(self): + super().__init__() + + def forward(self, x): + # swish + return x * torch.sigmoid(x) + +class ResConv1DBlock(nn.Module): + def __init__(self, n_in, n_state, dilation=1, activation='silu', norm=None, dropout=None): + super().__init__() + padding = dilation + self.norm = norm + if norm == "LN": + self.norm1 = nn.LayerNorm(n_in) + self.norm2 = nn.LayerNorm(n_in) + elif norm == "GN": + self.norm1 = nn.GroupNorm(num_groups=32, num_channels=n_in, eps=1e-6, affine=True) + self.norm2 = nn.GroupNorm(num_groups=32, num_channels=n_in, eps=1e-6, affine=True) + elif norm == "BN": + self.norm1 = nn.BatchNorm1d(num_features=n_in, eps=1e-6, affine=True) + self.norm2 = nn.BatchNorm1d(num_features=n_in, eps=1e-6, affine=True) + + else: + self.norm1 = nn.Identity() + self.norm2 = nn.Identity() + + if activation == "relu": + self.activation1 = nn.ReLU() + self.activation2 = nn.ReLU() + + elif activation == "silu": + self.activation1 = nonlinearity() + self.activation2 = nonlinearity() + + elif activation == "gelu": + self.activation1 = nn.GELU() + self.activation2 = nn.GELU() + + + + self.conv1 = nn.Conv1d(n_in, n_state, 3, 1, padding, dilation) + self.conv2 = nn.Conv1d(n_state, n_in, 1, 1, 0,) + + + def forward(self, x): + x_orig = x + if self.norm == "LN": + x = self.norm1(x.transpose(-2, -1)) + x = self.activation1(x.transpose(-2, -1)) + else: + x = self.norm1(x) + x = self.activation1(x) + + x = self.conv1(x) + + if self.norm == "LN": + x = self.norm2(x.transpose(-2, -1)) + x = self.activation2(x.transpose(-2, -1)) + else: + x = self.norm2(x) + x = self.activation2(x) + + x = self.conv2(x) + x = x + x_orig + return x + +class Resnet1D(nn.Module): + def __init__(self, n_in, n_depth, dilation_growth_rate=1, reverse_dilation=True, activation='relu', norm=None): + super().__init__() + + blocks = [ResConv1DBlock(n_in, n_in, dilation=dilation_growth_rate ** depth, activation=activation, norm=norm) for depth in range(n_depth)] + if reverse_dilation: + blocks = blocks[::-1] + + self.model = nn.Sequential(*blocks) + + def forward(self, x): + return self.model(x) \ No newline at end of file diff --git a/motiondiff_modules/mGPT/archs/tools/token_emb.py b/motiondiff_modules/mGPT/archs/tools/token_emb.py new file mode 100644 index 0000000..9bfa610 --- /dev/null +++ b/motiondiff_modules/mGPT/archs/tools/token_emb.py @@ -0,0 +1,73 @@ + +from torch import Tensor, nn + +class NewTokenEmb(nn.Module): + """ + For adding new tokens to a pretrained model + """ + + def __init__(self, + old_embeddings: nn.Embedding, + new_num_tokens: int = None) -> None: + + super().__init__() + + self.num_tokens = old_embeddings.num_embeddings + new_num_tokens + self.old_num_tokens = old_embeddings.num_embeddings + self.new_num_tokens = new_num_tokens + self.embedding_dim = old_embeddings.embedding_dim + + # For text embeddings + self.text_embeddings = nn.Embedding( + self.num_tokens, + self.embedding_dim, + device=old_embeddings.weight.device, + dtype=old_embeddings.weight.dtype) + with torch.no_grad(): + self.text_embeddings.weight.data[:old_embeddings. + num_embeddings] = old_embeddings.weight.data + self.text_embeddings.weight.data[ + self.old_num_tokens:] = torch.zeros( + self.new_num_tokens, + self.embedding_dim, + dtype=old_embeddings.weight.dtype, + device=old_embeddings.weight.device) + self.text_embeddings.weight.requires_grad_(False) + + # For motion embeddings + self.motion_embeddings = nn.Embedding( + new_num_tokens, + self.embedding_dim, + device=old_embeddings.weight.device, + dtype=old_embeddings.weight.dtype) + with torch.no_grad(): + self.motion_embeddings.weight.data[:self. + old_num_tokens] = torch.zeros( + new_num_tokens, + self.embedding_dim, + dtype=old_embeddings.weight. + dtype, + device=old_embeddings. + weight.device) + self.word2motionProj = nn.Linear(self.old_num_tokens, new_num_tokens) + + def forward(self, input: Tensor) -> Tensor: + + with torch.no_grad(): + self.motion_embeddings.weight.data[:self. + old_num_tokens] = torch.zeros( + self.new_num_tokens, + self.embedding_dim, + dtype=self.motion_embeddings + .weight.dtype, + device=self. + motion_embeddings.weight. + device) + + self.motion_embeddings.weight.data[ + self.old_num_tokens:] = self.word2motionProj( + self.text_embeddings.weight.data[:self.old_num_tokens].permute( + 1, 0)).permute(1, 0) + + return self.text_embeddings(input) + self.motion_embeddings(input) + diff --git a/motiondiff_modules/mGPT/archs/tools/transformer_layers.py b/motiondiff_modules/mGPT/archs/tools/transformer_layers.py new file mode 100644 index 0000000..7b53429 --- /dev/null +++ b/motiondiff_modules/mGPT/archs/tools/transformer_layers.py @@ -0,0 +1,285 @@ +# -*- coding: utf-8 -*- +import math +import torch +import torch.nn as nn +from torch import Tensor + +# Took from https://github.com/joeynmt/joeynmt/blob/fb66afcbe1beef9acd59283bcc084c4d4c1e6343/joeynmt/transformer_layers.py + + +# pylint: disable=arguments-differ +class MultiHeadedAttention(nn.Module): + """ + Multi-Head Attention module from "Attention is All You Need" + + Implementation modified from OpenNMT-py. + https://github.com/OpenNMT/OpenNMT-py + """ + + def __init__(self, num_heads: int, size: int, dropout: float = 0.1): + """ + Create a multi-headed attention layer. + :param num_heads: the number of heads + :param size: model size (must be divisible by num_heads) + :param dropout: probability of dropping a unit + """ + super().__init__() + + assert size % num_heads == 0 + + self.head_size = head_size = size // num_heads + self.model_size = size + self.num_heads = num_heads + + self.k_layer = nn.Linear(size, num_heads * head_size) + self.v_layer = nn.Linear(size, num_heads * head_size) + self.q_layer = nn.Linear(size, num_heads * head_size) + + self.output_layer = nn.Linear(size, size) + self.softmax = nn.Softmax(dim=-1) + self.dropout = nn.Dropout(dropout) + + def forward(self, k: Tensor, v: Tensor, q: Tensor, mask: Tensor = None): + """ + Computes multi-headed attention. + + :param k: keys [B, M, D] with M being the sentence length. + :param v: values [B, M, D] + :param q: query [B, M, D] + :param mask: optional mask [B, 1, M] or [B, M, M] + :return: + """ + batch_size = k.size(0) + num_heads = self.num_heads + + # project the queries (q), keys (k), and values (v) + k = self.k_layer(k) + v = self.v_layer(v) + q = self.q_layer(q) + + # reshape q, k, v for our computation to [batch_size, num_heads, ..] + k = k.view(batch_size, -1, num_heads, self.head_size).transpose(1, 2) + v = v.view(batch_size, -1, num_heads, self.head_size).transpose(1, 2) + q = q.view(batch_size, -1, num_heads, self.head_size).transpose(1, 2) + + # compute scores + q = q / math.sqrt(self.head_size) + + # batch x num_heads x query_len x key_len + scores = torch.matmul(q, k.transpose(2, 3)) + # torch.Size([48, 8, 183, 183]) + + # apply the mask (if we have one) + # we add a dimension for the heads to it below: [B, 1, 1, M] + if mask is not None: + scores = scores.masked_fill(~mask.unsqueeze(1), float('-inf')) + + # apply attention dropout and compute context vectors. + attention = self.softmax(scores) + attention = self.dropout(attention) + # torch.Size([48, 8, 183, 183]) [bs, nheads, time, time] (for decoding) + + # v: torch.Size([48, 8, 183, 32]) (32 is 256/8) + # get context vector (select values with attention) and reshape + # back to [B, M, D] + context = torch.matmul(attention, v) # torch.Size([48, 8, 183, 32]) + context = context.transpose(1, 2).contiguous().view( + batch_size, -1, num_heads * self.head_size) + # torch.Size([48, 183, 256]) put back to 256 (combine the heads) + + output = self.output_layer(context) + # torch.Size([48, 183, 256]): 1 output per time step + + return output + + +# pylint: disable=arguments-differ +class PositionwiseFeedForward(nn.Module): + """ + Position-wise Feed-forward layer + Projects to ff_size and then back down to input_size. + """ + + def __init__(self, input_size, ff_size, dropout=0.1): + """ + Initializes position-wise feed-forward layer. + :param input_size: dimensionality of the input. + :param ff_size: dimensionality of intermediate representation + :param dropout: + """ + super().__init__() + self.layer_norm = nn.LayerNorm(input_size, eps=1e-6) + self.pwff_layer = nn.Sequential( + nn.Linear(input_size, ff_size), + nn.ReLU(), + nn.Dropout(dropout), + nn.Linear(ff_size, input_size), + nn.Dropout(dropout), + ) + + def forward(self, x): + x_norm = self.layer_norm(x) + return self.pwff_layer(x_norm) + x + + +# pylint: disable=arguments-differ +class PositionalEncoding(nn.Module): + """ + Pre-compute position encodings (PE). + In forward pass, this adds the position-encodings to the + input for as many time steps as necessary. + + Implementation based on OpenNMT-py. + https://github.com/OpenNMT/OpenNMT-py + """ + + def __init__(self, size: int = 0, max_len: int = 5000): + """ + Positional Encoding with maximum length max_len + :param size: + :param max_len: + :param dropout: + """ + if size % 2 != 0: + raise ValueError("Cannot use sin/cos positional encoding with " + "odd dim (got dim={:d})".format(size)) + pe = torch.zeros(max_len, size) + position = torch.arange(0, max_len).unsqueeze(1) + div_term = torch.exp((torch.arange(0, size, 2, dtype=torch.float) * + -(math.log(10000.0) / size))) + pe[:, 0::2] = torch.sin(position.float() * div_term) + pe[:, 1::2] = torch.cos(position.float() * div_term) + pe = pe.unsqueeze(0) # shape: [1, size, max_len] + super().__init__() + self.register_buffer('pe', pe) + self.dim = size + + def forward(self, emb): + """Embed inputs. + Args: + emb (FloatTensor): Sequence of word vectors + ``(seq_len, batch_size, self.dim)`` + """ + # Add position encodings + return emb + self.pe[:, :emb.size(1)] + + +class TransformerEncoderLayer(nn.Module): + """ + One Transformer encoder layer has a Multi-head attention layer plus + a position-wise feed-forward layer. + """ + + def __init__(self, + size: int = 0, + ff_size: int = 0, + num_heads: int = 0, + dropout: float = 0.1): + """ + A single Transformer layer. + :param size: + :param ff_size: + :param num_heads: + :param dropout: + """ + super().__init__() + + self.layer_norm = nn.LayerNorm(size, eps=1e-6) + self.src_src_att = MultiHeadedAttention(num_heads, + size, + dropout=dropout) + self.feed_forward = PositionwiseFeedForward(size, + ff_size=ff_size, + dropout=dropout) + self.dropout = nn.Dropout(dropout) + self.size = size + + # pylint: disable=arguments-differ + def forward(self, x: Tensor, mask: Tensor) -> Tensor: + """ + Forward pass for a single transformer encoder layer. + First applies layer norm, then self attention, + then dropout with residual connection (adding the input to the result), + and then a position-wise feed-forward layer. + + :param x: layer input + :param mask: input mask + :return: output tensor + """ + x_norm = self.layer_norm(x) + h = self.src_src_att(x_norm, x_norm, x_norm, mask) + h = self.dropout(h) + x + o = self.feed_forward(h) + return o + + +class TransformerDecoderLayer(nn.Module): + """ + Transformer decoder layer. + + Consists of self-attention, source-attention, and feed-forward. + """ + + def __init__(self, + size: int = 0, + ff_size: int = 0, + num_heads: int = 0, + dropout: float = 0.1): + """ + Represents a single Transformer decoder layer. + + It attends to the source representation and the previous decoder states. + + :param size: model dimensionality + :param ff_size: size of the feed-forward intermediate layer + :param num_heads: number of heads + :param dropout: dropout to apply to input + """ + super().__init__() + self.size = size + + self.trg_trg_att = MultiHeadedAttention(num_heads, + size, + dropout=dropout) + self.src_trg_att = MultiHeadedAttention(num_heads, + size, + dropout=dropout) + + self.feed_forward = PositionwiseFeedForward(size, + ff_size=ff_size, + dropout=dropout) + + self.x_layer_norm = nn.LayerNorm(size, eps=1e-6) + self.dec_layer_norm = nn.LayerNorm(size, eps=1e-6) + + self.dropout = nn.Dropout(dropout) + + # pylint: disable=arguments-differ + def forward(self, + x: Tensor = None, + memory: Tensor = None, + src_mask: Tensor = None, + trg_mask: Tensor = None) -> Tensor: + """ + Forward pass of a single Transformer decoder layer. + + :param x: inputs + :param memory: source representations + :param src_mask: source mask + :param trg_mask: target mask (so as to not condition on future steps) + :return: output tensor + """ + # decoder/target self-attention + x_norm = self.x_layer_norm(x) # torch.Size([48, 183, 256]) + h1 = self.trg_trg_att(x_norm, x_norm, x_norm, mask=trg_mask) + h1 = self.dropout(h1) + x + + # source-target attention + h1_norm = self.dec_layer_norm( + h1) # torch.Size([48, 183, 256]) (same for memory) + h2 = self.src_trg_att(memory, memory, h1_norm, mask=src_mask) + + # final position-wise feed-forward layer + o = self.feed_forward(self.dropout(h2) + h1) + + return o diff --git a/motiondiff_modules/mGPT/callback.py b/motiondiff_modules/mGPT/callback.py new file mode 100644 index 0000000..19d6421 --- /dev/null +++ b/motiondiff_modules/mGPT/callback.py @@ -0,0 +1,200 @@ +import os +from pytorch_lightning import LightningModule, Trainer +from pytorch_lightning.callbacks import Callback, RichProgressBar, ModelCheckpoint + + +def build_callbacks(cfg, logger=None, phase='test', **kwargs): + callbacks = [] + logger = logger + + # Rich Progress Bar + callbacks.append(progressBar()) + + # Checkpoint Callback + if phase == 'train': + callbacks.extend(getCheckpointCallback(cfg, logger=logger, **kwargs)) + + return callbacks + +def getCheckpointCallback(cfg, logger=None, **kwargs): + callbacks = [] + # Logging + metric_monitor = { + "loss_total": "total/train", + "Train_jf": "recons/text2jfeats/train", + "Val_jf": "recons/text2jfeats/val", + "Train_rf": "recons/text2rfeats/train", + "Val_rf": "recons/text2rfeats/val", + "APE root": "Metrics/APE_root", + "APE mean pose": "Metrics/APE_mean_pose", + "AVE root": "Metrics/AVE_root", + "AVE mean pose": "Metrics/AVE_mean_pose", + "R_TOP_1": "Metrics/R_precision_top_1", + "R_TOP_2": "Metrics/R_precision_top_2", + "R_TOP_3": "Metrics/R_precision_top_3", + "gt_R_TOP_3": "Metrics/gt_R_precision_top_3", + "FID": "Metrics/FID", + "gt_FID": "Metrics/gt_FID", + "Diversity": "Metrics/Diversity", + "MM dist": "Metrics/Matching_score", + "Accuracy": "Metrics/accuracy", + } + callbacks.append( + progressLogger(logger,metric_monitor=metric_monitor,log_every_n_steps=1)) + + # Save 10 latest checkpoints + checkpointParams = { + 'dirpath': os.path.join(cfg.FOLDER_EXP, "checkpoints"), + 'filename': "{epoch}", + 'monitor': "step", + 'mode': "max", + 'every_n_epochs': cfg.LOGGER.VAL_EVERY_STEPS, + 'save_top_k': 8, + 'save_last': True, + 'save_on_train_epoch_end': True + } + callbacks.append(ModelCheckpoint(**checkpointParams)) + + # Save checkpoint every n*10 epochs + checkpointParams.update({ + 'every_n_epochs': + cfg.LOGGER.VAL_EVERY_STEPS * 10, + 'save_top_k': + -1, + 'save_last': + False + }) + callbacks.append(ModelCheckpoint(**checkpointParams)) + + metrics = cfg.METRIC.TYPE + metric_monitor_map = { + 'TemosMetric': { + 'Metrics/APE_root': { + 'abbr': 'APEroot', + 'mode': 'min' + }, + }, + 'TM2TMetrics': { + 'Metrics/FID': { + 'abbr': 'FID', + 'mode': 'min' + }, + 'Metrics/R_precision_top_3': { + 'abbr': 'R3', + 'mode': 'max' + } + }, + 'MRMetrics': { + 'Metrics/MPJPE': { + 'abbr': 'MPJPE', + 'mode': 'min' + } + }, + 'HUMANACTMetrics': { + 'Metrics/Accuracy': { + 'abbr': 'Accuracy', + 'mode': 'max' + } + }, + 'UESTCMetrics': { + 'Metrics/Accuracy': { + 'abbr': 'Accuracy', + 'mode': 'max' + } + }, + 'UncondMetrics': { + 'Metrics/FID': { + 'abbr': 'FID', + 'mode': 'min' + } + } + } + + checkpointParams.update({ + 'every_n_epochs': cfg.LOGGER.VAL_EVERY_STEPS, + 'save_top_k': 1, + }) + + for metric in metrics: + if metric in metric_monitor_map.keys(): + metric_monitors = metric_monitor_map[metric] + + # Delete R3 if training VAE + if cfg.TRAIN.STAGE == 'vae' and metric == 'TM2TMetrics': + del metric_monitors['Metrics/R_precision_top_3'] + + for metric_monitor in metric_monitors: + checkpointParams.update({ + 'filename': + metric_monitor_map[metric][metric_monitor]['mode'] + + "-" + + metric_monitor_map[metric][metric_monitor]['abbr'] + + "{ep}", + 'monitor': + metric_monitor, + 'mode': + metric_monitor_map[metric][metric_monitor]['mode'], + }) + callbacks.append( + ModelCheckpoint(**checkpointParams)) + return callbacks + +class progressBar(RichProgressBar): + def __init__(self, ): + super().__init__() + + def get_metrics(self, trainer, model): + # Don't show the version number + items = super().get_metrics(trainer, model) + items.pop("v_num", None) + return items + +class progressLogger(Callback): + def __init__(self, + logger, + metric_monitor: dict, + precision: int = 3, + log_every_n_steps: int = 1): + # Metric to monitor + self.logger = logger + self.metric_monitor = metric_monitor + self.precision = precision + self.log_every_n_steps = log_every_n_steps + + def on_train_start(self, trainer: Trainer, pl_module: LightningModule, + **kwargs) -> None: + self.logger.info("Training started") + + def on_train_end(self, trainer: Trainer, pl_module: LightningModule, + **kwargs) -> None: + self.logger.info("Training done") + + def on_validation_epoch_end(self, trainer: Trainer, + pl_module: LightningModule, **kwargs) -> None: + if trainer.sanity_checking: + self.logger.info("Sanity checking ok.") + + def on_train_epoch_end(self, + trainer: Trainer, + pl_module: LightningModule, + padding=False, + **kwargs) -> None: + metric_format = f"{{:.{self.precision}e}}" + line = f"Epoch {trainer.current_epoch}" + if padding: + line = f"{line:>{len('Epoch xxxx')}}" # Right padding + + if trainer.current_epoch % self.log_every_n_steps == 0: + metrics_str = [] + + losses_dict = trainer.callback_metrics + for metric_name, dico_name in self.metric_monitor.items(): + if dico_name in losses_dict: + metric = losses_dict[dico_name].item() + metric = metric_format.format(metric) + metric = f"{metric_name} {metric}" + metrics_str.append(metric) + + line = line + ": " + " ".join(metrics_str) + + self.logger.info(line) diff --git a/motiondiff_modules/mGPT/config.py b/motiondiff_modules/mGPT/config.py new file mode 100644 index 0000000..dfa2b4a --- /dev/null +++ b/motiondiff_modules/mGPT/config.py @@ -0,0 +1,217 @@ +import importlib +from argparse import ArgumentParser +from omegaconf import OmegaConf +from os.path import join as pjoin +import os +import glob + + +def get_module_config(cfg, filepath="./configs"): + """ + Load yaml config files from subfolders + """ + + yamls = glob.glob(pjoin(filepath, '*', '*.yaml')) + yamls = [y.replace(filepath, '') for y in yamls] + for yaml in yamls: + nodes = yaml.replace('.yaml', '').replace('/', '.') + nodes = nodes[1:] if nodes[0] == '.' else nodes + OmegaConf.update(cfg, nodes, OmegaConf.load('./configs' + yaml)) + + return cfg + + +def get_obj_from_str(string, reload=False): + """ + Get object from string + """ + package_directory_name = os.path.basename(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + module, cls = string.rsplit(".", 1) + if reload: + module_imp = importlib.import_module(module) + importlib.reload(module_imp) + return getattr(importlib.import_module(module, package=package_directory_name), cls) + + +def instantiate_from_config(config): + """ + Instantiate object from config + """ + if not "target" in config: + raise KeyError("Expected key `target` to instantiate.") + return get_obj_from_str(config["target"])(**config.get("params", dict())) + + +def resume_config(cfg: OmegaConf): + """ + Resume model and wandb + """ + + if cfg.TRAIN.RESUME: + resume = cfg.TRAIN.RESUME + if os.path.exists(resume): + # Checkpoints + cfg.TRAIN.PRETRAINED = pjoin(resume, "checkpoints", "last.ckpt") + # Wandb + wandb_files = os.listdir(pjoin(resume, "wandb", "latest-run")) + wandb_run = [item for item in wandb_files if "run-" in item][0] + cfg.LOGGER.WANDB.params.id = wandb_run.replace("run-","").replace(".wandb", "") + else: + raise ValueError("Resume path is not right.") + + return cfg + +def parse_args(phase="train"): + """ + Parse arguments and load config files + """ + + parser = ArgumentParser() + group = parser.add_argument_group("Training options") + + # Assets + group.add_argument( + "--cfg_assets", + type=str, + required=False, + default="./configs/assets.yaml", + help="config file for asset paths", + ) + + # Default config + if phase in ["train", "test"]: + cfg_defualt = "./configs/default.yaml" + elif phase == "render": + cfg_defualt = "./configs/render.yaml" + elif phase == "webui": + cfg_defualt = "./configs/webui.yaml" + + group.add_argument( + "--cfg", + type=str, + required=False, + default=cfg_defualt, + help="config file", + ) + + # Parse for each phase + if phase in ["train", "test"]: + group.add_argument("--batch_size", + type=int, + required=False, + help="training batch size") + group.add_argument("--num_nodes", + type=int, + required=False, + help="number of nodes") + group.add_argument("--device", + type=int, + nargs="+", + required=False, + help="training device") + group.add_argument("--task", + type=str, + required=False, + help="evaluation task type") + group.add_argument("--nodebug", + action="store_true", + required=False, + help="debug or not") + + + if phase == "demo": + group.add_argument( + "--example", + type=str, + required=False, + help="input text and lengths with txt format", + ) + group.add_argument( + "--out_dir", + type=str, + required=False, + help="output dir", + ) + group.add_argument("--task", + type=str, + required=False, + help="evaluation task type") + + if phase == "render": + group.add_argument("--npy", + type=str, + required=False, + default=None, + help="npy motion files") + group.add_argument("--dir", + type=str, + required=False, + default=None, + help="npy motion folder") + group.add_argument("--fps", + type=int, + required=False, + default=30, + help="render fps") + group.add_argument( + "--mode", + type=str, + required=False, + default="sequence", + help="render target: video, sequence, frame", + ) + + params = parser.parse_args() + + # Load yaml config files + OmegaConf.register_new_resolver("eval", eval) + cfg_assets = OmegaConf.load(params.cfg_assets) + cfg_base = OmegaConf.load(pjoin(cfg_assets.CONFIG_FOLDER, 'default.yaml')) + cfg_exp = OmegaConf.merge(cfg_base, OmegaConf.load(params.cfg)) + if not cfg_exp.FULL_CONFIG: + cfg_exp = get_module_config(cfg_exp, cfg_assets.CONFIG_FOLDER) + cfg = OmegaConf.merge(cfg_exp, cfg_assets) + + # Update config with arguments + if phase in ["train", "test"]: + cfg.TRAIN.BATCH_SIZE = params.batch_size if params.batch_size else cfg.TRAIN.BATCH_SIZE + cfg.DEVICE = params.device if params.device else cfg.DEVICE + cfg.NUM_NODES = params.num_nodes if params.num_nodes else cfg.NUM_NODES + cfg.model.params.task = params.task if params.task else cfg.model.params.task + cfg.DEBUG = not params.nodebug if params.nodebug is not None else cfg.DEBUG + + # Force no debug in test + if phase == "test": + cfg.DEBUG = False + cfg.DEVICE = [0] + print("Force no debugging and one gpu when testing") + + if phase == "demo": + cfg.DEMO.RENDER = params.render + cfg.DEMO.FRAME_RATE = params.frame_rate + cfg.DEMO.EXAMPLE = params.example + cfg.DEMO.TASK = params.task + cfg.TEST.FOLDER = params.out_dir if params.out_dir else cfg.TEST.FOLDER + os.makedirs(cfg.TEST.FOLDER, exist_ok=True) + + if phase == "render": + if params.npy: + cfg.RENDER.NPY = params.npy + cfg.RENDER.INPUT_MODE = "npy" + if params.dir: + cfg.RENDER.DIR = params.dir + cfg.RENDER.INPUT_MODE = "dir" + if params.fps: + cfg.RENDER.FPS = float(params.fps) + cfg.RENDER.MODE = params.mode + + # Debug mode + if cfg.DEBUG: + cfg.NAME = "debug--" + cfg.NAME + cfg.LOGGER.WANDB.params.offline = True + cfg.LOGGER.VAL_EVERY_STEPS = 1 + + # Resume config + cfg = resume_config(cfg) + + return cfg diff --git a/motiondiff_modules/mGPT/configs/inference.yaml b/motiondiff_modules/mGPT/configs/inference.yaml new file mode 100644 index 0000000..ba3269b --- /dev/null +++ b/motiondiff_modules/mGPT/configs/inference.yaml @@ -0,0 +1,175 @@ +NAME: Webui # Experiment name +DEBUG: False # Debug mode +ACCELERATOR: 'cpu' # Devices optioncal: “cpu”, “gpu”, “tpu”, “ipu”, “hpu”, “mps, “auto” +DEVICE: [0] # Index of gpus eg. [0] or [0,1,2,3] + +# Training configuration +TRAIN: + #--------------------------------- + STAGE: lm_instruct + DATASETS: ['humanml3d'] # Training datasets + SPLIT: 'train' # Training split name + NUM_WORKERS: 32 # Number of workers + BATCH_SIZE: 16 # Size of batches + START_EPOCH: 0 # Start epochMMOTIONENCODER + END_EPOCH: 99999 # End epoch + ABLATION: + pkeep: 0.5 + OPTIM: + TYPE: AdamW # Optimizer type + LR: 2e-4 # Learning rate + WEIGHT_DECAY: 0.0 + LR_SCHEDULER: [100, 200, 300, 400] + GAMMA: 0.8 + + LR_SCHEDULER: + target: CosineAnnealingLR + params: + T_max: ${eval:${LOGGER.VAL_EVERY_STEPS} * 100} + eta_min: 1e-6 + +# Evaluating Configuration +EVAL: + DATASETS: ['humanml3d'] # Evaluating datasets + BATCH_SIZE: 32 # Evaluating Batch size + NUM_WORKERS: 8 # Validation Batch size + SPLIT: test + +# Test Configuration +TEST: + CHECKPOINTS: checkpoints/MotionGPT-base/motiongpt_s3_h3d.ckpt + DATASETS: ['humanml3d'] # training datasets + SPLIT: test + BATCH_SIZE: 32 # training Batch size + MEAN: False + NUM_SAMPLES: 1 + FACT: 1 + +# Datasets Configuration +DATASET: + target: .mGPT.data.HumanML3D.HumanML3DDataModule + JOINT_TYPE: 'humanml3d' # join type + CODE_PATH: 'VQBEST' + TASK_ROOT: .deps/mGPT_instructions + TASK_PATH: '' + SMPL_PATH: .deps/smpl + TRANSFORM_PATH: .deps/transforms/ + WORD_VERTILIZER_PATH: .deps/glove/ + NFEATS: 263 + KIT: + ROOT: .datasets/kit-ml # KIT directory + SPLIT_ROOT: .datasets/kit-ml # KIT splits directory + MEAN_STD_PATH: .deps/t2m/ + MAX_MOTION_LEN: 196 + MIN_MOTION_LEN: 24 + MAX_TEXT_LEN: 20 + PICK_ONE_TEXT: true + FRAME_RATE: 12.5 + UNIT_LEN: 4 + HUMANML3D: + ROOT: .datasets/humanml3d # HumanML3D directory + SPLIT_ROOT: .datasets/humanml3d # HumanML3D splits directory + ASSETS_ROOT: .assets/meta/ + MEAN_STD_PATH: .deps/t2m/ + MAX_MOTION_LEN: 196 + MIN_MOTION_LEN: 40 + MAX_TEXT_LEN: 20 + PICK_ONE_TEXT: true + FRAME_RATE: 20.0 + UNIT_LEN: 4 + STD_TEXT: False + +ABLATION: + # For MotionGPT + use_length: False + predict_ratio: 0.2 + inbetween_ratio: 0.25 + image_size: 256 + # For Motion-latent-diffusion + VAE_TYPE: 'actor' # vae ablation: actor or mcross + VAE_ARCH: 'encoder_decoder' # mdiffusion vae architecture + PE_TYPE: 'actor' # mdiffusion mld or actor + DIFF_PE_TYPE: 'actor' # mdiffusion mld or actor + SKIP_CONNECT: False # skip connection for denoiser va + MLP_DIST: False # use linear to expand mean and std rather expand token nums + IS_DIST: False # Mcross distribution kl + PREDICT_EPSILON: True # noise or motion + +METRIC: + TYPE: ['TM2TMetrics'] + TM2T: + t2m_path: .deps/t2m/ # path for tm2t evaluator + TASK: 't2m' + FORCE_IN_METER: True + DIST_SYNC_ON_STEP: True + MM_NUM_SAMPLES: 100 # Number of samples for multimodal test + MM_NUM_REPEATS: 30 # Number of repeats for multimodal test + MM_NUM_TIMES: 10 # Number of times to repeat the multimodal test + DIVERSITY_TIMES: 300 # Number of times to repeat the diversity test + +# Losses Configuration +LOSS: + TYPE: t2mgpt # Losses type + LAMBDA_FEATURE: 1.0 + LAMBDA_VELOCITY: 0.5 + LAMBDA_COMMIT: 0.02 + LAMBDA_CLS: 1.0 + LAMBDA_M2T2M: 1.0 + LAMBDA_T2M2T: 10.0 + ABLATION: + RECONS_LOSS: 'l1_smooth' + LAMBDA_REC: 1.0 # Lambda for reconstruction losses + LAMBDA_JOINT: 1.0 # Lambda for joint losses + + LAMBDA_LATENT: 1e-5 # Lambda for latent losses + LAMBDA_KL: 1e-5 # Lambda for kl losses + LAMBDA_GEN: 1.0 # Lambda for text-motion generation losses + LAMBDA_CROSS: 1.0 # Lambda for cross-reconstruction losses + LAMBDA_CYCLE: 1.0 # Lambda for cycle losses + LAMBDA_PRIOR: 0.0 # Lambda for diffusion prior losses + +# Model Configuration +model: + target: .mGPT.models.mgpt.MotionGPT + params: + condition: 'text' + task: 't2m' + lm: + target: .mGPT.archs.mgpt_lm.MLM + params: + model_type: t5 + model_path: google/flan-t5-base + stage: ${TRAIN.STAGE} + motion_codebook_size: 512 + ablation: ${ABLATION} + motion_vae: + target: .mGPT.archs.mgpt_vq.VQVae + params: + quantizer: 'ema_reset' + code_num: 512 + code_dim: 512 + output_emb_width: 512 + down_t: 2 + stride_t: 2 + width: 512 + depth: 3 + dilation_growth_rate: 3 + norm: None + activation: 'relu' + nfeats: ${DATASET.NFEATS} + ablation: ${ABLATION} + + # Related parameters + stage: ${TRAIN.STAGE} + debug: ${DEBUG} + codebook_size: 512 + metrics_dict: ${METRIC.TYPE} + +# Logger configuration +LOGGER: + LOG_EVERY_STEPS: 5 + VAL_EVERY_STEPS: 10 + TENSORBOARD: True + wandb: + params: + project: null diff --git a/motiondiff_modules/mGPT/data/HumanML3D.py b/motiondiff_modules/mGPT/data/HumanML3D.py new file mode 100644 index 0000000..5213627 --- /dev/null +++ b/motiondiff_modules/mGPT/data/HumanML3D.py @@ -0,0 +1,118 @@ +import numpy as np +import torch +from os.path import join as pjoin +import os +from .humanml.utils.word_vectorizer import WordVectorizer +from .humanml.scripts.motion_process import (process_file, recover_from_ric) +from . import BASEDataModule +from .humanml import Text2MotionDatasetEval, Text2MotionDataset, Text2MotionDatasetCB, MotionDataset, MotionDatasetVQ, Text2MotionDatasetToken, Text2MotionDatasetM2T +from .utils import humanml3d_collate +script_directory = os.path.dirname(os.path.abspath(__file__)) +class HumanML3DDataModule(BASEDataModule): + def __init__(self, cfg, **kwargs): + + super().__init__(collate_fn=humanml3d_collate) + self.cfg = cfg + self.save_hyperparameters(logger=False) + + # Basic info of the dataset + cfg.DATASET.JOINT_TYPE = 'humanml3d' + self.name = "humanml3d" + self.njoints = 22 + + # Path to the dataset + data_root = cfg.DATASET.HUMANML3D.ROOT + assets_root = cfg.DATASET.HUMANML3D.ASSETS_ROOT + self.hparams.data_root = data_root + self.hparams.text_dir = pjoin(data_root, "texts") + self.hparams.motion_dir = pjoin(data_root, 'new_joint_vecs') + + # Mean and std of the dataset + self.hparams.mean = np.load(pjoin(script_directory, "mean.npy")) + self.hparams.std = np.load(pjoin(script_directory, "std.npy")) + + # Mean and std for fair evaluation + self.hparams.mean_eval = np.load(pjoin(script_directory, "mean_eval.npy")) + self.hparams.std_eval = np.load(pjoin(script_directory, "std_eval.npy")) + + # Length of the dataset + self.hparams.max_motion_length = cfg.DATASET.HUMANML3D.MAX_MOTION_LEN + self.hparams.min_motion_length = cfg.DATASET.HUMANML3D.MIN_MOTION_LEN + self.hparams.max_text_len = cfg.DATASET.HUMANML3D.MAX_TEXT_LEN + self.hparams.unit_length = cfg.DATASET.HUMANML3D.UNIT_LEN + + # Additional parameters + self.hparams.debug = cfg.DEBUG + self.hparams.stage = cfg.TRAIN.STAGE + + # Dataset switch + self.DatasetEval = Text2MotionDatasetEval + + if cfg.TRAIN.STAGE == "vae": + if cfg.model.params.motion_vae.target.split('.')[-1].lower() == "vqvae": + self.hparams.win_size = 64 + self.Dataset = MotionDatasetVQ + else: + self.Dataset = MotionDataset + elif 'lm' in cfg.TRAIN.STAGE: + self.hparams.code_path = cfg.DATASET.CODE_PATH + self.hparams.task_path = cfg.DATASET.TASK_PATH + self.hparams.std_text = cfg.DATASET.HUMANML3D.STD_TEXT + self.Dataset = Text2MotionDatasetCB + elif cfg.TRAIN.STAGE == "token": + self.Dataset = Text2MotionDatasetToken + self.DatasetEval = Text2MotionDatasetToken + elif cfg.TRAIN.STAGE == "m2t": + self.Dataset = Text2MotionDatasetM2T + self.DatasetEval = Text2MotionDatasetM2T + else: + self.Dataset = Text2MotionDataset + + # Get additional info of the dataset + self.nfeats = 263 + cfg.DATASET.NFEATS = self.nfeats + + + def feats2joints(self, features): + mean = torch.tensor(self.hparams.mean).to(features) + std = torch.tensor(self.hparams.std).to(features) + features = features * std + mean + return recover_from_ric(features, self.njoints) + + def joints2feats(self, features): + features = process_file(features, self.njoints)[0] + return features + + def normalize(self, features): + mean = torch.tensor(self.hparams.mean).to(features) + std = torch.tensor(self.hparams.std).to(features) + features = (features - mean) / std + return features + + def denormalize(self, features): + mean = torch.tensor(self.hparams.mean).to(features) + std = torch.tensor(self.hparams.std).to(features) + features = features * std + mean + return features + + def renorm4t2m(self, features): + # renorm to t2m norms for using t2m evaluators + ori_mean = torch.tensor(self.hparams.mean).to(features) + ori_std = torch.tensor(self.hparams.std).to(features) + eval_mean = torch.tensor(self.hparams.mean_eval).to(features) + eval_std = torch.tensor(self.hparams.std_eval).to(features) + features = features * ori_std + ori_mean + features = (features - eval_mean) / eval_std + return features + + def mm_mode(self, mm_on=True): + if mm_on: + self.is_mm = True + self.name_list = self.test_dataset.name_list + self.mm_list = np.random.choice(self.name_list, + self.cfg.METRIC.MM_NUM_SAMPLES, + replace=False) + self.test_dataset.name_list = self.mm_list + else: + self.is_mm = False + self.test_dataset.name_list = self.name_list diff --git a/motiondiff_modules/mGPT/data/Kit.py b/motiondiff_modules/mGPT/data/Kit.py new file mode 100644 index 0000000..1eecaa1 --- /dev/null +++ b/motiondiff_modules/mGPT/data/Kit.py @@ -0,0 +1,88 @@ +import numpy as np +import torch +from os.path import join as pjoin +from .humanml.utils.word_vectorizer import WordVectorizer +from .humanml.scripts.motion_process import (process_file, recover_from_ric) +from .HumanML3D import HumanML3DDataModule +from .humanml import Text2MotionDatasetEval, Text2MotionDataset, Text2MotionDatasetCB, MotionDataset, MotionDatasetVQ, Text2MotionDatasetToken + + +class KitDataModule(HumanML3DDataModule): + def __init__(self, cfg, **kwargs): + + super().__init__(cfg, **kwargs) + + # Basic info of the dataset + self.name = "kit" + self.njoints = 21 + + # Path to the dataset + data_root = cfg.DATASET.KIT.ROOT + self.hparams.data_root = data_root + self.hparams.text_dir = pjoin(data_root, "texts") + self.hparams.motion_dir = pjoin(data_root, 'new_joint_vecs') + + # Mean and std of the dataset + dis_data_root = pjoin(cfg.DATASET.KIT.MEAN_STD_PATH, 'kit', + "VQVAEV3_CB1024_CMT_H1024_NRES3", "meta") + self.hparams.mean = np.load(pjoin(dis_data_root, "mean.npy")) + self.hparams.std = np.load(pjoin(dis_data_root, "std.npy")) + + # Mean and std for fair evaluation + dis_data_root_eval = pjoin(cfg.DATASET.KIT.MEAN_STD_PATH, 't2m', + "Comp_v6_KLD005", "meta") + self.hparams.mean_eval = np.load(pjoin(dis_data_root_eval, "mean.npy")) + self.hparams.std_eval = np.load(pjoin(dis_data_root_eval, "std.npy")) + + # Length of the dataset + self.hparams.max_motion_length = cfg.DATASET.KIT.MAX_MOTION_LEN + self.hparams.min_motion_length = cfg.DATASET.KIT.MIN_MOTION_LEN + self.hparams.max_text_len = cfg.DATASET.KIT.MAX_TEXT_LEN + self.hparams.unit_length = cfg.DATASET.KIT.UNIT_LEN + + # Get additional info of the dataset + self._sample_set = self.get_sample_set(overrides={"split": "test", "tiny": True}) + self.nfeats = self._sample_set.nfeats + cfg.DATASET.NFEATS = self.nfeats + + def feats2joints(self, features): + mean = torch.tensor(self.hparams.mean).to(features) + std = torch.tensor(self.hparams.std).to(features) + features = features * std + mean + return recover_from_ric(features, self.njoints) + + def joints2feats(self, features): + features = process_file(features, self.njoints)[0] + # mean = torch.tensor(self.hparams.mean).to(features) + # std = torch.tensor(self.hparams.std).to(features) + # features = (features - mean) / std + return features + + def normalize(self, features): + mean = torch.tensor(self.hparams.mean).to(features) + std = torch.tensor(self.hparams.std).to(features) + features = (features - mean) / std + return features + + def renorm4t2m(self, features): + # renorm to t2m norms for using t2m evaluators + ori_mean = torch.tensor(self.hparams.mean).to(features) + ori_std = torch.tensor(self.hparams.std).to(features) + eval_mean = torch.tensor(self.hparams.mean_eval).to(features) + eval_std = torch.tensor(self.hparams.std_eval).to(features) + features = features * ori_std + ori_mean + features = (features - eval_mean) / eval_std + return features + + def mm_mode(self, mm_on=True): + # random select samples for mm + if mm_on: + self.is_mm = True + self.name_list = self.test_dataset.name_list + self.mm_list = np.random.choice(self.name_list, + self.cfg.METRIC.MM_NUM_SAMPLES, + replace=False) + self.test_dataset.name_list = self.mm_list + else: + self.is_mm = False + self.test_dataset.name_list = self.name_list diff --git a/motiondiff_modules/mGPT/data/__init__.py b/motiondiff_modules/mGPT/data/__init__.py new file mode 100644 index 0000000..948f49c --- /dev/null +++ b/motiondiff_modules/mGPT/data/__init__.py @@ -0,0 +1,103 @@ +import pytorch_lightning as pl +from torch.utils.data import DataLoader + + +class BASEDataModule(pl.LightningDataModule): + def __init__(self, collate_fn): + super().__init__() + + self.dataloader_options = {"collate_fn": collate_fn} + self.persistent_workers = True + self.is_mm = False + + self._train_dataset = None + self._val_dataset = None + self._test_dataset = None + + def get_sample_set(self, overrides={}): + sample_params = self.hparams.copy() + sample_params.update(overrides) + return self.DatasetEval(**sample_params) + + @property + def train_dataset(self): + if self._train_dataset is None: + self._train_dataset = self.Dataset(split=self.cfg.TRAIN.SPLIT, + **self.hparams) + return self._train_dataset + + @property + def val_dataset(self): + if self._val_dataset is None: + params = self.hparams.copy() + params['code_path'] = None + params['split'] = self.cfg.EVAL.SPLIT + self._val_dataset = self.DatasetEval(**params) + return self._val_dataset + + @property + def test_dataset(self): + if self._test_dataset is None: + # self._test_dataset = self.DatasetEval(split=self.cfg.TEST.SPLIT, + # **self.hparams) + params = self.hparams.copy() + params['code_path'] = None + params['split'] = self.cfg.TEST.SPLIT + self._test_dataset = self.DatasetEval( **params) + return self._test_dataset + + def setup(self, stage=None): + # Use the getter the first time to load the data + if stage in (None, "fit"): + _ = self.train_dataset + _ = self.val_dataset + if stage in (None, "test"): + _ = self.test_dataset + + def train_dataloader(self): + dataloader_options = self.dataloader_options.copy() + dataloader_options["batch_size"] = self.cfg.TRAIN.BATCH_SIZE + dataloader_options["num_workers"] = self.cfg.TRAIN.NUM_WORKERS + return DataLoader( + self.train_dataset, + shuffle=False, + persistent_workers=True, + **dataloader_options, + ) + + def predict_dataloader(self): + dataloader_options = self.dataloader_options.copy() + dataloader_options[ + "batch_size"] = 1 if self.is_mm else self.cfg.TEST.BATCH_SIZE + dataloader_options["num_workers"] = self.cfg.TEST.NUM_WORKERS + dataloader_options["shuffle"] = False + return DataLoader( + self.test_dataset, + persistent_workers=True, + **dataloader_options, + ) + + def val_dataloader(self): + # overrides batch_size and num_workers + dataloader_options = self.dataloader_options.copy() + dataloader_options["batch_size"] = self.cfg.EVAL.BATCH_SIZE + dataloader_options["num_workers"] = self.cfg.EVAL.NUM_WORKERS + dataloader_options["shuffle"] = False + return DataLoader( + self.val_dataset, + persistent_workers=True, + **dataloader_options, + ) + + def test_dataloader(self): + # overrides batch_size and num_workers + dataloader_options = self.dataloader_options.copy() + dataloader_options[ + "batch_size"] = 1 if self.is_mm else self.cfg.TEST.BATCH_SIZE + dataloader_options["num_workers"] = self.cfg.TEST.NUM_WORKERS + dataloader_options["shuffle"] = False + return DataLoader( + self.test_dataset, + persistent_workers=True, + **dataloader_options, + ) diff --git a/motiondiff_modules/mGPT/data/build_data.py b/motiondiff_modules/mGPT/data/build_data.py new file mode 100644 index 0000000..88b493e --- /dev/null +++ b/motiondiff_modules/mGPT/data/build_data.py @@ -0,0 +1,15 @@ +from omegaconf import OmegaConf +from os.path import join as pjoin +from ..config import instantiate_from_config + + +def build_data(cfg, phase="train"): + data_config = OmegaConf.to_container(cfg.DATASET, resolve=True) + data_config['params'] = {'cfg': cfg, 'phase': phase} + if isinstance(data_config['target'], str): + return instantiate_from_config(data_config) + elif isinstance(data_config['target'], list): + data_config_tmp = data_config.copy() + data_config_tmp['params']['dataModules'] = data_config['target'] + data_config_tmp['target'] = 'mGPT.data.Concat.ConcatDataModule' + return instantiate_from_config(data_config) diff --git a/motiondiff_modules/mGPT/data/humanml/README.md b/motiondiff_modules/mGPT/data/humanml/README.md new file mode 100644 index 0000000..4bf224f --- /dev/null +++ b/motiondiff_modules/mGPT/data/humanml/README.md @@ -0,0 +1 @@ +This code is based on https://github.com/EricGuo5513/text-to-motion.git \ No newline at end of file diff --git a/motiondiff_modules/mGPT/data/humanml/__init__.py b/motiondiff_modules/mGPT/data/humanml/__init__.py new file mode 100644 index 0000000..8e75358 --- /dev/null +++ b/motiondiff_modules/mGPT/data/humanml/__init__.py @@ -0,0 +1,7 @@ +from .dataset_t2m import Text2MotionDataset +from .dataset_t2m_eval import Text2MotionDatasetEval +from .dataset_t2m_cb import Text2MotionDatasetCB +from .dataset_t2m_token import Text2MotionDatasetToken +from .dataset_t2m_m2t import Text2MotionDatasetM2T +from .dataset_m import MotionDataset +from .dataset_m_vq import MotionDatasetVQ diff --git a/motiondiff_modules/mGPT/data/humanml/common/quaternion.py b/motiondiff_modules/mGPT/data/humanml/common/quaternion.py new file mode 100644 index 0000000..dca3d89 --- /dev/null +++ b/motiondiff_modules/mGPT/data/humanml/common/quaternion.py @@ -0,0 +1,423 @@ +# Copyright (c) 2018-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. +# + +import torch +import numpy as np + +_EPS4 = np.finfo(float).eps * 4.0 + +_FLOAT_EPS = np.finfo(np.float64).eps + +# PyTorch-backed implementations +def qinv(q): + assert q.shape[-1] == 4, 'q must be a tensor of shape (*, 4)' + mask = torch.ones_like(q) + mask[..., 1:] = -mask[..., 1:] + return q * mask + + +def qinv_np(q): + assert q.shape[-1] == 4, 'q must be a tensor of shape (*, 4)' + return qinv(torch.from_numpy(q).float()).numpy() + + +def qnormalize(q): + assert q.shape[-1] == 4, 'q must be a tensor of shape (*, 4)' + return q / torch.norm(q, dim=-1, keepdim=True) + + +def qmul(q, r): + """ + Multiply quaternion(s) q with quaternion(s) r. + Expects two equally-sized tensors of shape (*, 4), where * denotes any number of dimensions. + Returns q*r as a tensor of shape (*, 4). + """ + assert q.shape[-1] == 4 + assert r.shape[-1] == 4 + + original_shape = q.shape + + # Compute outer product + terms = torch.bmm(r.view(-1, 4, 1), q.view(-1, 1, 4)) + + w = terms[:, 0, 0] - terms[:, 1, 1] - terms[:, 2, 2] - terms[:, 3, 3] + x = terms[:, 0, 1] + terms[:, 1, 0] - terms[:, 2, 3] + terms[:, 3, 2] + y = terms[:, 0, 2] + terms[:, 1, 3] + terms[:, 2, 0] - terms[:, 3, 1] + z = terms[:, 0, 3] - terms[:, 1, 2] + terms[:, 2, 1] + terms[:, 3, 0] + return torch.stack((w, x, y, z), dim=1).view(original_shape) + + +def qrot(q, v): + """ + Rotate vector(s) v about the rotation described by quaternion(s) q. + Expects a tensor of shape (*, 4) for q and a tensor of shape (*, 3) for v, + where * denotes any number of dimensions. + Returns a tensor of shape (*, 3). + """ + assert q.shape[-1] == 4 + assert v.shape[-1] == 3 + assert q.shape[:-1] == v.shape[:-1] + + original_shape = list(v.shape) + # print(q.shape) + q = q.contiguous().view(-1, 4) + v = v.contiguous().view(-1, 3) + + qvec = q[:, 1:] + uv = torch.cross(qvec, v, dim=1) + uuv = torch.cross(qvec, uv, dim=1) + return (v + 2 * (q[:, :1] * uv + uuv)).view(original_shape) + + +def qeuler(q, order, epsilon=0, deg=True): + """ + Convert quaternion(s) q to Euler angles. + Expects a tensor of shape (*, 4), where * denotes any number of dimensions. + Returns a tensor of shape (*, 3). + """ + assert q.shape[-1] == 4 + + original_shape = list(q.shape) + original_shape[-1] = 3 + q = q.view(-1, 4) + + q0 = q[:, 0] + q1 = q[:, 1] + q2 = q[:, 2] + q3 = q[:, 3] + + if order == 'xyz': + x = torch.atan2(2 * (q0 * q1 - q2 * q3), 1 - 2 * (q1 * q1 + q2 * q2)) + y = torch.asin(torch.clamp(2 * (q1 * q3 + q0 * q2), -1 + epsilon, 1 - epsilon)) + z = torch.atan2(2 * (q0 * q3 - q1 * q2), 1 - 2 * (q2 * q2 + q3 * q3)) + elif order == 'yzx': + x = torch.atan2(2 * (q0 * q1 - q2 * q3), 1 - 2 * (q1 * q1 + q3 * q3)) + y = torch.atan2(2 * (q0 * q2 - q1 * q3), 1 - 2 * (q2 * q2 + q3 * q3)) + z = torch.asin(torch.clamp(2 * (q1 * q2 + q0 * q3), -1 + epsilon, 1 - epsilon)) + elif order == 'zxy': + x = torch.asin(torch.clamp(2 * (q0 * q1 + q2 * q3), -1 + epsilon, 1 - epsilon)) + y = torch.atan2(2 * (q0 * q2 - q1 * q3), 1 - 2 * (q1 * q1 + q2 * q2)) + z = torch.atan2(2 * (q0 * q3 - q1 * q2), 1 - 2 * (q1 * q1 + q3 * q3)) + elif order == 'xzy': + x = torch.atan2(2 * (q0 * q1 + q2 * q3), 1 - 2 * (q1 * q1 + q3 * q3)) + y = torch.atan2(2 * (q0 * q2 + q1 * q3), 1 - 2 * (q2 * q2 + q3 * q3)) + z = torch.asin(torch.clamp(2 * (q0 * q3 - q1 * q2), -1 + epsilon, 1 - epsilon)) + elif order == 'yxz': + x = torch.asin(torch.clamp(2 * (q0 * q1 - q2 * q3), -1 + epsilon, 1 - epsilon)) + y = torch.atan2(2 * (q1 * q3 + q0 * q2), 1 - 2 * (q1 * q1 + q2 * q2)) + z = torch.atan2(2 * (q1 * q2 + q0 * q3), 1 - 2 * (q1 * q1 + q3 * q3)) + elif order == 'zyx': + x = torch.atan2(2 * (q0 * q1 + q2 * q3), 1 - 2 * (q1 * q1 + q2 * q2)) + y = torch.asin(torch.clamp(2 * (q0 * q2 - q1 * q3), -1 + epsilon, 1 - epsilon)) + z = torch.atan2(2 * (q0 * q3 + q1 * q2), 1 - 2 * (q2 * q2 + q3 * q3)) + else: + raise + + if deg: + return torch.stack((x, y, z), dim=1).view(original_shape) * 180 / np.pi + else: + return torch.stack((x, y, z), dim=1).view(original_shape) + + +# Numpy-backed implementations + +def qmul_np(q, r): + q = torch.from_numpy(q).contiguous().float() + r = torch.from_numpy(r).contiguous().float() + return qmul(q, r).numpy() + + +def qrot_np(q, v): + q = torch.from_numpy(q).contiguous().float() + v = torch.from_numpy(v).contiguous().float() + return qrot(q, v).numpy() + + +def qeuler_np(q, order, epsilon=0, use_gpu=False): + if use_gpu: + q = torch.from_numpy(q).cuda().float() + return qeuler(q, order, epsilon).cpu().numpy() + else: + q = torch.from_numpy(q).contiguous().float() + return qeuler(q, order, epsilon).numpy() + + +def qfix(q): + """ + Enforce quaternion continuity across the time dimension by selecting + the representation (q or -q) with minimal distance (or, equivalently, maximal dot product) + between two consecutive frames. + + Expects a tensor of shape (L, J, 4), where L is the sequence length and J is the number of joints. + Returns a tensor of the same shape. + """ + assert len(q.shape) == 3 + assert q.shape[-1] == 4 + + result = q.copy() + dot_products = np.sum(q[1:] * q[:-1], axis=2) + mask = dot_products < 0 + mask = (np.cumsum(mask, axis=0) % 2).astype(bool) + result[1:][mask] *= -1 + return result + + +def euler2quat(e, order, deg=True): + """ + Convert Euler angles to quaternions. + """ + assert e.shape[-1] == 3 + + original_shape = list(e.shape) + original_shape[-1] = 4 + + e = e.view(-1, 3) + + ## if euler angles in degrees + if deg: + e = e * np.pi / 180. + + x = e[:, 0] + y = e[:, 1] + z = e[:, 2] + + rx = torch.stack((torch.cos(x / 2), torch.sin(x / 2), torch.zeros_like(x), torch.zeros_like(x)), dim=1) + ry = torch.stack((torch.cos(y / 2), torch.zeros_like(y), torch.sin(y / 2), torch.zeros_like(y)), dim=1) + rz = torch.stack((torch.cos(z / 2), torch.zeros_like(z), torch.zeros_like(z), torch.sin(z / 2)), dim=1) + + result = None + for coord in order: + if coord == 'x': + r = rx + elif coord == 'y': + r = ry + elif coord == 'z': + r = rz + else: + raise + if result is None: + result = r + else: + result = qmul(result, r) + + # Reverse antipodal representation to have a non-negative "w" + if order in ['xyz', 'yzx', 'zxy']: + result *= -1 + + return result.view(original_shape) + + +def expmap_to_quaternion(e): + """ + Convert axis-angle rotations (aka exponential maps) to quaternions. + Stable formula from "Practical Parameterization of Rotations Using the Exponential Map". + Expects a tensor of shape (*, 3), where * denotes any number of dimensions. + Returns a tensor of shape (*, 4). + """ + assert e.shape[-1] == 3 + + original_shape = list(e.shape) + original_shape[-1] = 4 + e = e.reshape(-1, 3) + + theta = np.linalg.norm(e, axis=1).reshape(-1, 1) + w = np.cos(0.5 * theta).reshape(-1, 1) + xyz = 0.5 * np.sinc(0.5 * theta / np.pi) * e + return np.concatenate((w, xyz), axis=1).reshape(original_shape) + + +def euler_to_quaternion(e, order): + """ + Convert Euler angles to quaternions. + """ + assert e.shape[-1] == 3 + + original_shape = list(e.shape) + original_shape[-1] = 4 + + e = e.reshape(-1, 3) + + x = e[:, 0] + y = e[:, 1] + z = e[:, 2] + + rx = np.stack((np.cos(x / 2), np.sin(x / 2), np.zeros_like(x), np.zeros_like(x)), axis=1) + ry = np.stack((np.cos(y / 2), np.zeros_like(y), np.sin(y / 2), np.zeros_like(y)), axis=1) + rz = np.stack((np.cos(z / 2), np.zeros_like(z), np.zeros_like(z), np.sin(z / 2)), axis=1) + + result = None + for coord in order: + if coord == 'x': + r = rx + elif coord == 'y': + r = ry + elif coord == 'z': + r = rz + else: + raise + if result is None: + result = r + else: + result = qmul_np(result, r) + + # Reverse antipodal representation to have a non-negative "w" + if order in ['xyz', 'yzx', 'zxy']: + result *= -1 + + return result.reshape(original_shape) + + +def quaternion_to_matrix(quaternions): + """ + Convert rotations given as quaternions to rotation matrices. + Args: + quaternions: quaternions with real part first, + as tensor of shape (..., 4). + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + r, i, j, k = torch.unbind(quaternions, -1) + two_s = 2.0 / (quaternions * quaternions).sum(-1) + + o = torch.stack( + ( + 1 - two_s * (j * j + k * k), + two_s * (i * j - k * r), + two_s * (i * k + j * r), + two_s * (i * j + k * r), + 1 - two_s * (i * i + k * k), + two_s * (j * k - i * r), + two_s * (i * k - j * r), + two_s * (j * k + i * r), + 1 - two_s * (i * i + j * j), + ), + -1, + ) + return o.reshape(quaternions.shape[:-1] + (3, 3)) + + +def quaternion_to_matrix_np(quaternions): + q = torch.from_numpy(quaternions).contiguous().float() + return quaternion_to_matrix(q).numpy() + + +def quaternion_to_cont6d_np(quaternions): + rotation_mat = quaternion_to_matrix_np(quaternions) + cont_6d = np.concatenate([rotation_mat[..., 0], rotation_mat[..., 1]], axis=-1) + return cont_6d + + +def quaternion_to_cont6d(quaternions): + rotation_mat = quaternion_to_matrix(quaternions) + cont_6d = torch.cat([rotation_mat[..., 0], rotation_mat[..., 1]], dim=-1) + return cont_6d + + +def cont6d_to_matrix(cont6d): + assert cont6d.shape[-1] == 6, "The last dimension must be 6" + x_raw = cont6d[..., 0:3] + y_raw = cont6d[..., 3:6] + + x = x_raw / torch.norm(x_raw, dim=-1, keepdim=True) + z = torch.cross(x, y_raw, dim=-1) + z = z / torch.norm(z, dim=-1, keepdim=True) + + y = torch.cross(z, x, dim=-1) + + x = x[..., None] + y = y[..., None] + z = z[..., None] + + mat = torch.cat([x, y, z], dim=-1) + return mat + + +def cont6d_to_matrix_np(cont6d): + q = torch.from_numpy(cont6d).contiguous().float() + return cont6d_to_matrix(q).numpy() + + +def qpow(q0, t, dtype=torch.float): + ''' q0 : tensor of quaternions + t: tensor of powers + ''' + q0 = qnormalize(q0) + theta0 = torch.acos(q0[..., 0]) + + ## if theta0 is close to zero, add epsilon to avoid NaNs + mask = (theta0 <= 10e-10) * (theta0 >= -10e-10) + theta0 = (1 - mask) * theta0 + mask * 10e-10 + v0 = q0[..., 1:] / torch.sin(theta0).view(-1, 1) + + if isinstance(t, torch.Tensor): + q = torch.zeros(t.shape + q0.shape) + theta = t.view(-1, 1) * theta0.view(1, -1) + else: ## if t is a number + q = torch.zeros(q0.shape) + theta = t * theta0 + + q[..., 0] = torch.cos(theta) + q[..., 1:] = v0 * torch.sin(theta).unsqueeze(-1) + + return q.to(dtype) + + +def qslerp(q0, q1, t): + ''' + q0: starting quaternion + q1: ending quaternion + t: array of points along the way + + Returns: + Tensor of Slerps: t.shape + q0.shape + ''' + + q0 = qnormalize(q0) + q1 = qnormalize(q1) + q_ = qpow(qmul(q1, qinv(q0)), t) + + return qmul(q_, + q0.contiguous().view(torch.Size([1] * len(t.shape)) + q0.shape).expand(t.shape + q0.shape).contiguous()) + + +def qbetween(v0, v1): + ''' + find the quaternion used to rotate v0 to v1 + ''' + assert v0.shape[-1] == 3, 'v0 must be of the shape (*, 3)' + assert v1.shape[-1] == 3, 'v1 must be of the shape (*, 3)' + + v = torch.cross(v0, v1) + w = torch.sqrt((v0 ** 2).sum(dim=-1, keepdim=True) * (v1 ** 2).sum(dim=-1, keepdim=True)) + (v0 * v1).sum(dim=-1, + keepdim=True) + return qnormalize(torch.cat([w, v], dim=-1)) + + +def qbetween_np(v0, v1): + ''' + find the quaternion used to rotate v0 to v1 + ''' + assert v0.shape[-1] == 3, 'v0 must be of the shape (*, 3)' + assert v1.shape[-1] == 3, 'v1 must be of the shape (*, 3)' + + v0 = torch.from_numpy(v0).float() + v1 = torch.from_numpy(v1).float() + return qbetween(v0, v1).numpy() + + +def lerp(p0, p1, t): + if not isinstance(t, torch.Tensor): + t = torch.Tensor([t]) + + new_shape = t.shape + p0.shape + new_view_t = t.shape + torch.Size([1] * len(p0.shape)) + new_view_p = torch.Size([1] * len(t.shape)) + p0.shape + p0 = p0.view(new_view_p).expand(new_shape) + p1 = p1.view(new_view_p).expand(new_shape) + t = t.view(new_view_t).expand(new_shape) + + return p0 + t * (p1 - p0) diff --git a/motiondiff_modules/mGPT/data/humanml/common/skeleton.py b/motiondiff_modules/mGPT/data/humanml/common/skeleton.py new file mode 100644 index 0000000..b2ae85a --- /dev/null +++ b/motiondiff_modules/mGPT/data/humanml/common/skeleton.py @@ -0,0 +1,199 @@ +from .quaternion import * +import scipy.ndimage.filters as filters + +class Skeleton(object): + def __init__(self, offset, kinematic_tree, device): + self.device = device + self._raw_offset_np = offset.numpy() + self._raw_offset = offset.clone().detach().to(device).float() + self._kinematic_tree = kinematic_tree + self._offset = None + self._parents = [0] * len(self._raw_offset) + self._parents[0] = -1 + for chain in self._kinematic_tree: + for j in range(1, len(chain)): + self._parents[chain[j]] = chain[j-1] + + def njoints(self): + return len(self._raw_offset) + + def offset(self): + return self._offset + + def set_offset(self, offsets): + self._offset = offsets.clone().detach().to(self.device).float() + + def kinematic_tree(self): + return self._kinematic_tree + + def parents(self): + return self._parents + + # joints (batch_size, joints_num, 3) + def get_offsets_joints_batch(self, joints): + assert len(joints.shape) == 3 + _offsets = self._raw_offset.expand(joints.shape[0], -1, -1).clone() + for i in range(1, self._raw_offset.shape[0]): + _offsets[:, i] = torch.norm(joints[:, i] - joints[:, self._parents[i]], p=2, dim=1)[:, None] * _offsets[:, i] + + self._offset = _offsets.detach() + return _offsets + + # joints (joints_num, 3) + def get_offsets_joints(self, joints): + assert len(joints.shape) == 2 + _offsets = self._raw_offset.clone() + for i in range(1, self._raw_offset.shape[0]): + # print(joints.shape) + _offsets[i] = torch.norm(joints[i] - joints[self._parents[i]], p=2, dim=0) * _offsets[i] + + self._offset = _offsets.detach() + return _offsets + + # face_joint_idx should follow the order of right hip, left hip, right shoulder, left shoulder + # joints (batch_size, joints_num, 3) + def inverse_kinematics_np(self, joints, face_joint_idx, smooth_forward=False): + assert len(face_joint_idx) == 4 + '''Get Forward Direction''' + l_hip, r_hip, sdr_r, sdr_l = face_joint_idx + across1 = joints[:, r_hip] - joints[:, l_hip] + across2 = joints[:, sdr_r] - joints[:, sdr_l] + across = across1 + across2 + across = across / np.sqrt((across**2).sum(axis=-1))[:, np.newaxis] + # print(across1.shape, across2.shape) + + # forward (batch_size, 3) + forward = np.cross(np.array([[0, 1, 0]]), across, axis=-1) + if smooth_forward: + forward = filters.gaussian_filter1d(forward, 20, axis=0, mode='nearest') + # forward (batch_size, 3) + forward = forward / np.sqrt((forward**2).sum(axis=-1))[..., np.newaxis] + + '''Get Root Rotation''' + target = np.array([[0,0,1]]).repeat(len(forward), axis=0) + root_quat = qbetween_np(forward, target) + + '''Inverse Kinematics''' + # quat_params (batch_size, joints_num, 4) + # print(joints.shape[:-1]) + quat_params = np.zeros(joints.shape[:-1] + (4,)) + # print(quat_params.shape) + root_quat[0] = np.array([[1.0, 0.0, 0.0, 0.0]]) + quat_params[:, 0] = root_quat + # quat_params[0, 0] = np.array([[1.0, 0.0, 0.0, 0.0]]) + for chain in self._kinematic_tree: + R = root_quat + for j in range(len(chain) - 1): + # (batch, 3) + u = self._raw_offset_np[chain[j+1]][np.newaxis,...].repeat(len(joints), axis=0) + # print(u.shape) + # (batch, 3) + v = joints[:, chain[j+1]] - joints[:, chain[j]] + v = v / np.sqrt((v**2).sum(axis=-1))[:, np.newaxis] + # print(u.shape, v.shape) + rot_u_v = qbetween_np(u, v) + + R_loc = qmul_np(qinv_np(R), rot_u_v) + + quat_params[:,chain[j + 1], :] = R_loc + R = qmul_np(R, R_loc) + + return quat_params + + # Be sure root joint is at the beginning of kinematic chains + def forward_kinematics(self, quat_params, root_pos, skel_joints=None, do_root_R=True): + # quat_params (batch_size, joints_num, 4) + # joints (batch_size, joints_num, 3) + # root_pos (batch_size, 3) + if skel_joints is not None: + offsets = self.get_offsets_joints_batch(skel_joints) + if len(self._offset.shape) == 2: + offsets = self._offset.expand(quat_params.shape[0], -1, -1) + joints = torch.zeros(quat_params.shape[:-1] + (3,)).to(self.device) + joints[:, 0] = root_pos + for chain in self._kinematic_tree: + if do_root_R: + R = quat_params[:, 0] + else: + R = torch.tensor([[1.0, 0.0, 0.0, 0.0]]).expand(len(quat_params), -1).detach().to(self.device) + for i in range(1, len(chain)): + R = qmul(R, quat_params[:, chain[i]]) + offset_vec = offsets[:, chain[i]] + joints[:, chain[i]] = qrot(R, offset_vec) + joints[:, chain[i-1]] + return joints + + # Be sure root joint is at the beginning of kinematic chains + def forward_kinematics_np(self, quat_params, root_pos, skel_joints=None, do_root_R=True): + # quat_params (batch_size, joints_num, 4) + # joints (batch_size, joints_num, 3) + # root_pos (batch_size, 3) + if skel_joints is not None: + skel_joints = torch.from_numpy(skel_joints) + offsets = self.get_offsets_joints_batch(skel_joints) + if len(self._offset.shape) == 2: + offsets = self._offset.expand(quat_params.shape[0], -1, -1) + offsets = offsets.numpy() + joints = np.zeros(quat_params.shape[:-1] + (3,)) + joints[:, 0] = root_pos + for chain in self._kinematic_tree: + if do_root_R: + R = quat_params[:, 0] + else: + R = np.array([[1.0, 0.0, 0.0, 0.0]]).repeat(len(quat_params), axis=0) + for i in range(1, len(chain)): + R = qmul_np(R, quat_params[:, chain[i]]) + offset_vec = offsets[:, chain[i]] + joints[:, chain[i]] = qrot_np(R, offset_vec) + joints[:, chain[i - 1]] + return joints + + def forward_kinematics_cont6d_np(self, cont6d_params, root_pos, skel_joints=None, do_root_R=True): + # cont6d_params (batch_size, joints_num, 6) + # joints (batch_size, joints_num, 3) + # root_pos (batch_size, 3) + if skel_joints is not None: + skel_joints = torch.from_numpy(skel_joints) + offsets = self.get_offsets_joints_batch(skel_joints) + if len(self._offset.shape) == 2: + offsets = self._offset.expand(cont6d_params.shape[0], -1, -1) + offsets = offsets.numpy() + joints = np.zeros(cont6d_params.shape[:-1] + (3,)) + joints[:, 0] = root_pos + for chain in self._kinematic_tree: + if do_root_R: + matR = cont6d_to_matrix_np(cont6d_params[:, 0]) + else: + matR = np.eye(3)[np.newaxis, :].repeat(len(cont6d_params), axis=0) + for i in range(1, len(chain)): + matR = np.matmul(matR, cont6d_to_matrix_np(cont6d_params[:, chain[i]])) + offset_vec = offsets[:, chain[i]][..., np.newaxis] + # print(matR.shape, offset_vec.shape) + joints[:, chain[i]] = np.matmul(matR, offset_vec).squeeze(-1) + joints[:, chain[i-1]] + return joints + + def forward_kinematics_cont6d(self, cont6d_params, root_pos, skel_joints=None, do_root_R=True): + # cont6d_params (batch_size, joints_num, 6) + # joints (batch_size, joints_num, 3) + # root_pos (batch_size, 3) + if skel_joints is not None: + # skel_joints = torch.from_numpy(skel_joints) + offsets = self.get_offsets_joints_batch(skel_joints) + if len(self._offset.shape) == 2: + offsets = self._offset.expand(cont6d_params.shape[0], -1, -1) + joints = torch.zeros(cont6d_params.shape[:-1] + (3,)).to(cont6d_params.device) + joints[..., 0, :] = root_pos + for chain in self._kinematic_tree: + if do_root_R: + matR = cont6d_to_matrix(cont6d_params[:, 0]) + else: + matR = torch.eye(3).expand((len(cont6d_params), -1, -1)).detach().to(cont6d_params.device) + for i in range(1, len(chain)): + matR = torch.matmul(matR, cont6d_to_matrix(cont6d_params[:, chain[i]])) + offset_vec = offsets[:, chain[i]].unsqueeze(-1) + # print(matR.shape, offset_vec.shape) + joints[:, chain[i]] = torch.matmul(matR, offset_vec).squeeze(-1) + joints[:, chain[i-1]] + return joints + + + + + diff --git a/motiondiff_modules/mGPT/data/humanml/dataset_m.py b/motiondiff_modules/mGPT/data/humanml/dataset_m.py new file mode 100644 index 0000000..241cabc --- /dev/null +++ b/motiondiff_modules/mGPT/data/humanml/dataset_m.py @@ -0,0 +1,156 @@ +import os +import rich +import random +import pickle +import codecs as cs +import numpy as np +from torch.utils import data +from rich.progress import track +from os.path import join as pjoin + + +class MotionDataset(data.Dataset): + def __init__( + self, + data_root, + split, + mean, + std, + max_motion_length=196, + min_motion_length=20, + unit_length=4, + fps=20, + tmpFile=True, + tiny=False, + debug=False, + **kwargs, + ): + + # restrian the length of motion and text + self.max_motion_length = max_motion_length + self.min_motion_length = min_motion_length + self.unit_length = unit_length + + # Data mean and std + self.mean = mean + self.std = std + + # Data path + split_file = pjoin(data_root, split + '.txt') + motion_dir = pjoin(data_root, 'new_joint_vecs') + text_dir = pjoin(data_root, 'texts') + + # Data id list + self.id_list = [] + with cs.open(split_file, "r") as f: + for line in f.readlines(): + self.id_list.append(line.strip()) + + # Debug mode + if tiny or debug: + enumerator = enumerate( + track( + self.id_list, + f"Loading HumanML3D {split}", + )) + maxdata = 100 + subset = '_tiny' + else: + enumerator = enumerate(self.id_list) + maxdata = 1e10 + subset = '' + + new_name_list = [] + motion_dict = {} + + # Fast loading + if os.path.exists(pjoin(data_root, f'tmp/{split}{subset}_motion.pkl')): + with rich.progress.open(pjoin(data_root, f'tmp/{split}{subset}_motion.pkl'), + 'rb', description=f"Loading HumanML3D {split}") as file: + motion_dict = pickle.load(file) + with open(pjoin(data_root, f'tmp/{split}{subset}_index.pkl'), 'rb') as file: + new_name_list = pickle.load(file) + else: + for idx, name in enumerator: + if len(new_name_list) > maxdata: + break + try: + motion = [np.load(pjoin(motion_dir, name + ".npy"))] + + # Read text + with cs.open(pjoin(text_dir, name + '.txt')) as f: + text_data = [] + flag = False + lines = f.readlines() + + for line in lines: + try: + line_split = line.strip().split('#') + f_tag = float(line_split[2]) + to_tag = float(line_split[3]) + f_tag = 0.0 if np.isnan(f_tag) else f_tag + to_tag = 0.0 if np.isnan(to_tag) else to_tag + + if f_tag == 0.0 and to_tag == 0.0: + flag = True + else: + motion_new = [tokens[int(f_tag*fps/unit_length) : int(to_tag*fps/unit_length)] for tokens in motion if int(f_tag*fps/unit_length) < int(to_tag*fps/unit_length)] + + if len(motion_new) == 0: + continue + new_name = '%s_%f_%f'%(name, f_tag, to_tag) + + motion_dict[new_name] = { + 'motion': motion_new, + "length": [len(m[0]) for m in motion_new]} + new_name_list.append(new_name) + except: + pass + + if flag: + motion_dict[name] = { + 'motion': motion, + "length": [len(m[0]) for m in motion]} + new_name_list.append(name) + except: + pass + + if tmpFile: + os.makedirs(pjoin(data_root, 'tmp'), exist_ok=True) + + with open(pjoin(data_root, f'tmp/{split}{subset}_motion.pkl'),'wb') as file: + pickle.dump(motion_dict, file) + with open(pjoin(data_root, f'tmp/{split}{subset}_index.pkl'), 'wb') as file: + pickle.dump(new_name_list, file) + + self.motion_dict = motion_dict + self.name_list = new_name_list + self.nfeats = motion_dict[new_name_list[0]]['motion'][0].shape[1] + + def __len__(self): + return len(self.name_list) + + def __getitem__(self, item): + data = self.motion_dict[self.name_list[item]] + motion_list, m_length = data["motion"], data["length"] + + # Randomly select a motion + motion = random.choice(motion_list) + + # Crop the motions in to times of 4, and introduce small variations + if self.unit_length < 10: + coin2 = np.random.choice(["single", "single", "double"]) + else: + coin2 = "single" + + if coin2 == "double": + m_length = (m_length // self.unit_length - 1) * self.unit_length + elif coin2 == "single": + m_length = (m_length // self.unit_length) * self.unit_length + idx = random.randint(0, len(motion) - m_length) + motion = motion[idx:idx + m_length] + + # Z Normalization + motion = (motion - self.mean) / self.std + + return None, motion, m_length, None, None, None, None, diff --git a/motiondiff_modules/mGPT/data/humanml/dataset_m_vq.py b/motiondiff_modules/mGPT/data/humanml/dataset_m_vq.py new file mode 100644 index 0000000..dfa3ae5 --- /dev/null +++ b/motiondiff_modules/mGPT/data/humanml/dataset_m_vq.py @@ -0,0 +1,54 @@ +import random +import codecs as cs +import numpy as np +from torch.utils import data +from rich.progress import track +from os.path import join as pjoin +from .dataset_m import MotionDataset +from .dataset_t2m import Text2MotionDataset + + +class MotionDatasetVQ(Text2MotionDataset): + def __init__( + self, + data_root, + split, + mean, + std, + max_motion_length, + min_motion_length, + win_size, + unit_length=4, + fps=20, + tmpFile=True, + tiny=False, + debug=False, + **kwargs, + ): + super().__init__(data_root, split, mean, std, max_motion_length, + min_motion_length, unit_length, fps, tmpFile, tiny, + debug, **kwargs) + + # Filter out the motions that are too short + self.window_size = win_size + name_list = list(self.name_list) + for name in self.name_list: + motion = self.data_dict[name]["motion"] + if motion.shape[0] < self.window_size: + name_list.remove(name) + self.data_dict.pop(name) + self.name_list = name_list + + def __len__(self): + return len(self.name_list) + + def __getitem__(self, item): + idx = self.pointer + item + data = self.data_dict[self.name_list[idx]] + motion, length = data["motion"], data["length"] + + idx = random.randint(0, motion.shape[0] - self.window_size) + motion = motion[idx:idx + self.window_size] + motion = (motion - self.mean) / self.std + + return None, motion, length, None, None, None, None, diff --git a/motiondiff_modules/mGPT/data/humanml/dataset_t2m.py b/motiondiff_modules/mGPT/data/humanml/dataset_t2m.py new file mode 100644 index 0000000..3460681 --- /dev/null +++ b/motiondiff_modules/mGPT/data/humanml/dataset_t2m.py @@ -0,0 +1,211 @@ +import os +import rich +import random +import pickle +import codecs as cs +import numpy as np +from torch.utils import data +from rich.progress import track +from os.path import join as pjoin + + +class Text2MotionDataset(data.Dataset): + + def __init__( + self, + data_root, + split, + mean, + std, + max_motion_length=196, + min_motion_length=40, + unit_length=4, + fps=20, + tmpFile=True, + tiny=False, + debug=False, + **kwargs, + ): + + # restrian the length of motion and text + self.max_length = 20 + self.max_motion_length = max_motion_length + self.min_motion_length = min_motion_length + self.unit_length = unit_length + + # Data mean and std + self.mean = mean + self.std = std + + # Data path + split_file = pjoin(data_root, split + '.txt') + motion_dir = pjoin(data_root, 'new_joint_vecs') + text_dir = pjoin(data_root, 'texts') + + # Data id list + self.id_list = [] + with cs.open(split_file, "r") as f: + for line in f.readlines(): + self.id_list.append(line.strip()) + + # Debug mode + if tiny or debug: + enumerator = enumerate(self.id_list) + maxdata = 100 + subset = '_tiny' + else: + enumerator = enumerate( + track( + self.id_list, + f"Loading HumanML3D {split}", + )) + maxdata = 1e10 + subset = '' + + new_name_list = [] + length_list = [] + data_dict = {} + + # Fast loading + if os.path.exists(pjoin(data_root, f'tmp/{split}{subset}_data.pkl')): + if tiny or debug: + with open(pjoin(data_root, f'tmp/{split}{subset}_data.pkl'), + 'rb') as file: + data_dict = pickle.load(file) + else: + with rich.progress.open( + pjoin(data_root, f'tmp/{split}{subset}_data.pkl'), + 'rb', + description=f"Loading HumanML3D {split}") as file: + data_dict = pickle.load(file) + with open(pjoin(data_root, f'tmp/{split}{subset}_index.pkl'), + 'rb') as file: + name_list = pickle.load(file) + for name in new_name_list: + length_list.append(data_dict[name]['length']) + + else: + for idx, name in enumerator: + if len(new_name_list) > maxdata: + break + try: + motion = np.load(pjoin(motion_dir, name + ".npy")) + if (len(motion)) < self.min_motion_length or (len(motion) + >= 200): + continue + + # Read text + text_data = [] + flag = False + with cs.open(pjoin(text_dir, name + '.txt')) as f: + lines = f.readlines() + for line in lines: + text_dict = {} + line_split = line.strip().split('#') + caption = line_split[0] + t_tokens = line_split[1].split(' ') + f_tag = float(line_split[2]) + to_tag = float(line_split[3]) + f_tag = 0.0 if np.isnan(f_tag) else f_tag + to_tag = 0.0 if np.isnan(to_tag) else to_tag + + text_dict['caption'] = caption + text_dict['tokens'] = t_tokens + if f_tag == 0.0 and to_tag == 0.0: + flag = True + text_data.append(text_dict) + else: + motion_new = motion[int(f_tag * + fps):int(to_tag * fps)] + if (len(motion_new) + ) < self.min_motion_length or ( + len(motion_new) >= 200): + continue + new_name = random.choice( + 'ABCDEFGHIJKLMNOPQRSTUVW') + '_' + name + while new_name in new_name_list: + new_name = random.choice( + 'ABCDEFGHIJKLMNOPQRSTUVW') + '_' + name + name_count = 1 + while new_name in data_dict: + new_name += '_' + name_count + name_count += 1 + data_dict[new_name] = { + 'motion': motion_new, + "length": len(motion_new), + 'text': [text_dict] + } + new_name_list.append(new_name) + length_list.append(len(motion_new)) + + if flag: + data_dict[name] = { + 'motion': motion, + "length": len(motion), + 'text': text_data + } + new_name_list.append(name) + length_list.append(len(motion)) + except: + pass + + name_list, length_list = zip( + *sorted(zip(new_name_list, length_list), key=lambda x: x[1])) + + if tmpFile: + os.makedirs(pjoin(data_root, 'tmp'), exist_ok=True) + with open(pjoin(data_root, f'tmp/{split}{subset}_data.pkl'), + 'wb') as file: + pickle.dump(data_dict, file) + with open(pjoin(data_root, f'tmp/{split}{subset}_index.pkl'), + 'wb') as file: + pickle.dump(name_list, file) + + self.length_arr = np.array(length_list) + self.data_dict = data_dict + self.name_list = name_list + self.nfeats = data_dict[name_list[0]]['motion'].shape[1] + self.reset_max_len(self.max_length) + + def reset_max_len(self, length): + assert length <= self.max_motion_length + self.pointer = np.searchsorted(self.length_arr, length) + print("Pointer Pointing at %d" % self.pointer) + self.max_length = length + + def __len__(self): + return len(self.name_list) - self.pointer + + def __getitem__(self, item): + idx = self.pointer + item + data = self.data_dict[self.name_list[idx]] + motion, m_length, text_list = data["motion"], data["length"], data[ + "text"] + + # Randomly select a caption + text_data = random.choice(text_list) + caption = text_data["caption"] + + all_captions = [ + ' '.join([token.split('/')[0] for token in text_dic['tokens']]) + for text_dic in text_list + ] + + # Crop the motions in to times of 4, and introduce small variations + if self.unit_length < 10: + coin2 = np.random.choice(["single", "single", "double"]) + else: + coin2 = "single" + + if coin2 == "double": + m_length = (m_length // self.unit_length - 1) * self.unit_length + elif coin2 == "single": + m_length = (m_length // self.unit_length) * self.unit_length + + idx = random.randint(0, len(motion) - m_length) + motion = motion[idx:idx + m_length] + + # Z Normalization + motion = (motion - self.mean) / self.std + + return caption, motion, m_length, None, None, None, None, all_captions diff --git a/motiondiff_modules/mGPT/data/humanml/dataset_t2m_cb.py b/motiondiff_modules/mGPT/data/humanml/dataset_t2m_cb.py new file mode 100644 index 0000000..6f7e1fe --- /dev/null +++ b/motiondiff_modules/mGPT/data/humanml/dataset_t2m_cb.py @@ -0,0 +1,211 @@ +import rich +import random +import pickle +import os +import numpy as np +import codecs as cs +from torch.utils import data +from os.path import join as pjoin +from rich.progress import track +import json +import spacy + +class Text2MotionDatasetCB(data.Dataset): + def __init__( + self, + data_root, + split, + mean, + std, + max_motion_length=196, + min_motion_length=20, + unit_length=4, + fps=20, + tmpFile=True, + tiny=False, + debug=False, + stage='lm_pretrain', + code_path='VQVAE', + task_path=None, + std_text=False, + **kwargs, + ): + self.tiny = tiny + self.unit_length = unit_length + + # Data mean and std + self.mean = mean + self.std = std + + # Data path + split = 'train' + split_file = pjoin(data_root, split + '.txt') + motion_dir = pjoin(data_root, code_path) + text_dir = pjoin(data_root, 'texts') + + if task_path: + instructions = task_path + elif stage == 'lm_pretrain': + instructions = pjoin(data_root, 'template_pretrain.json') + elif stage in ['lm_instruct', "lm_rl"]: + instructions = pjoin(data_root, 'template_instructions.json') + else: + raise NotImplementedError(f"stage {stage} not implemented") + + # Data id list + self.id_list = [] + with cs.open(split_file, "r") as f: + for line in f.readlines(): + self.id_list.append(line.strip()) + + # Debug mode + if tiny or debug: + enumerator = enumerate(self.id_list) + maxdata = 100 + subset = '_tiny' + else: + enumerator = enumerate( + track( + self.id_list, + f"Loading HumanML3D {split}", + )) + maxdata = 1e10 + subset = '' + + new_name_list = [] + data_dict = {} + + # Fast loading + for i, name in enumerator: + if len(new_name_list) > maxdata: + break + try: + # Load motion tokens + m_token_list = np.load(pjoin(motion_dir, f'{name}.npy')) + # Read text + with cs.open(pjoin(text_dir, name + '.txt')) as f: + text_data = [] + flag = False + lines = f.readlines() + + for line in lines: + try: + text_dict = {} + line_split = line.strip().split('#') + caption = line_split[0] + t_tokens = line_split[1].split(' ') + f_tag = float(line_split[2]) + to_tag = float(line_split[3]) + f_tag = 0.0 if np.isnan(f_tag) else f_tag + to_tag = 0.0 if np.isnan(to_tag) else to_tag + + text_dict['caption'] = caption + text_dict['tokens'] = t_tokens + if f_tag == 0.0 and to_tag == 0.0: + flag = True + text_data.append(text_dict) + else: + m_token_list_new = [ + tokens[int(f_tag * fps / unit_length + ):int(to_tag * fps / + unit_length)] + for tokens in m_token_list + if int(f_tag * fps / unit_length) < + int(to_tag * fps / unit_length) + ] + + if len(m_token_list_new) == 0: + continue + new_name = '%s_%f_%f' % (name, f_tag, + to_tag) + + data_dict[new_name] = { + 'm_token_list': m_token_list_new, + 'text': [text_dict] + } + new_name_list.append(new_name) + except: + pass + + if flag: + data_dict[name] = { + 'm_token_list': m_token_list, + 'text': text_data + } + new_name_list.append(name) + except: + pass + + if tmpFile: + os.makedirs(pjoin(data_root, 'tmp'), exist_ok=True) + with open( + pjoin(data_root, + f'tmp/{split}{subset}_tokens_data.pkl'), + 'wb') as file: + pickle.dump(data_dict, file) + with open( + pjoin(data_root, + f'tmp/{split}{subset}_tokens_index.pkl'), + 'wb') as file: + pickle.dump(new_name_list, file) + + self.data_dict = data_dict + self.name_list = new_name_list + self.nlp = spacy.load('en_core_web_sm') + self.std_text = std_text + self.instructions = json.load(open(instructions, 'r')) + self.tasks = [] + for task in self.instructions.keys(): + for subtask in self.instructions[task].keys(): + self.tasks.append(self.instructions[task][subtask]) + + def __len__(self): + return len(self.name_list) * len(self.tasks) + + def __getitem__(self, item): + data_idx = item % len(self.name_list) + task_idx = item // len(self.name_list) + + data = self.data_dict[self.name_list[data_idx]] + m_token_list, text_list = data['m_token_list'], data['text'] + + m_tokens = random.choice(m_token_list) + text_data = random.choice(text_list) + caption = text_data['caption'] + if self.std_text: + doc = self.nlp(caption) + word_list = [] + pos_list = [] + for token in doc: + word = token.text + if not word.isalpha(): + continue + if (token.pos_ == 'NOUN' + or token.pos_ == 'VERB') and (word != 'left'): + word_list.append(token.lemma_) + else: + word_list.append(word) + pos_list.append(token.pos_) + + caption = ' '.join(word_list) + + all_captions = [ + ' '.join([token.split('/')[0] for token in text_dic['tokens']]) + for text_dic in text_list + ] + + coin = np.random.choice([False, False, True]) + + if coin: + # drop one token at the head or tail + coin2 = np.random.choice([True, False]) + if coin2: + m_tokens = m_tokens[:-1] + else: + m_tokens = m_tokens[1:] + + m_tokens_len = m_tokens.shape[0] + + tasks = self.tasks[task_idx] + + return caption, m_tokens, m_tokens_len, None, None, None, None, all_captions, tasks diff --git a/motiondiff_modules/mGPT/data/humanml/dataset_t2m_eval.py b/motiondiff_modules/mGPT/data/humanml/dataset_t2m_eval.py new file mode 100644 index 0000000..4162981 --- /dev/null +++ b/motiondiff_modules/mGPT/data/humanml/dataset_t2m_eval.py @@ -0,0 +1,92 @@ +import random +import numpy as np +from .dataset_t2m import Text2MotionDataset + + +class Text2MotionDatasetEval(Text2MotionDataset): + + def __init__( + self, + data_root, + split, + mean, + std, + w_vectorizer, + max_motion_length=196, + min_motion_length=40, + unit_length=4, + fps=20, + tmpFile=True, + tiny=False, + debug=False, + **kwargs, + ): + super().__init__(data_root, split, mean, std, max_motion_length, + min_motion_length, unit_length, fps, tmpFile, tiny, + debug, **kwargs) + + self.w_vectorizer = w_vectorizer + + + def __getitem__(self, item): + # Get text data + idx = self.pointer + item + data = self.data_dict[self.name_list[idx]] + motion, m_length, text_list = data["motion"], data["length"], data["text"] + + all_captions = [ + ' '.join([token.split('/')[0] for token in text_dic['tokens']]) + for text_dic in text_list + ] + + if len(all_captions) > 3: + all_captions = all_captions[:3] + elif len(all_captions) == 2: + all_captions = all_captions + all_captions[0:1] + elif len(all_captions) == 1: + all_captions = all_captions * 3 + + # Randomly select a caption + text_data = random.choice(text_list) + caption, tokens = text_data["caption"], text_data["tokens"] + + # Text + max_text_len = 20 + if len(tokens) < max_text_len: + # pad with "unk" + tokens = ["sos/OTHER"] + tokens + ["eos/OTHER"] + sent_len = len(tokens) + tokens = tokens + ["unk/OTHER"] * (max_text_len + 2 - sent_len) + else: + # crop + tokens = tokens[:max_text_len] + tokens = ["sos/OTHER"] + tokens + ["eos/OTHER"] + sent_len = len(tokens) + pos_one_hots = [] + word_embeddings = [] + for token in tokens: + word_emb, pos_oh = self.w_vectorizer[token] + pos_one_hots.append(pos_oh[None, :]) + word_embeddings.append(word_emb[None, :]) + pos_one_hots = np.concatenate(pos_one_hots, axis=0) + word_embeddings = np.concatenate(word_embeddings, axis=0) + + # Random crop + if self.unit_length < 10: + coin2 = np.random.choice(["single", "single", "double"]) + else: + coin2 = "single" + + if coin2 == "double": + m_length = (m_length // self.unit_length - 1) * self.unit_length + elif coin2 == "single": + m_length = (m_length // self.unit_length) * self.unit_length + + idx = random.randint(0, len(motion) - m_length) + motion = motion[idx:idx + m_length] + + # Z Normalization + motion = (motion - self.mean) / self.std + + return caption, motion, m_length, word_embeddings, pos_one_hots, sent_len, "_".join( + tokens), all_captions diff --git a/motiondiff_modules/mGPT/data/humanml/dataset_t2m_m2t.py b/motiondiff_modules/mGPT/data/humanml/dataset_t2m_m2t.py new file mode 100644 index 0000000..259078c --- /dev/null +++ b/motiondiff_modules/mGPT/data/humanml/dataset_t2m_m2t.py @@ -0,0 +1,119 @@ +import random +import numpy as np +from torch.utils import data +from .dataset_t2m import Text2MotionDataset +import codecs as cs +from os.path import join as pjoin + + +class Text2MotionDatasetM2T(data.Dataset): + + def __init__( + self, + data_root, + split, + mean, + std, + max_motion_length=196, + min_motion_length=40, + unit_length=4, + fps=20, + tmpFile=True, + tiny=False, + debug=False, + **kwargs, + ): + + self.max_motion_length = max_motion_length + self.min_motion_length = min_motion_length + self.unit_length = unit_length + + # Data mean and std + self.mean = mean + self.std = std + + # Data path + split_file = pjoin(data_root, split + '.txt') + motion_dir = pjoin(data_root, 'new_joint_vecs') + text_dir = pjoin(data_root, 'texts') + + # Data id list + self.id_list = [] + with cs.open(split_file, "r") as f: + for line in f.readlines(): + self.id_list.append(line.strip()) + + new_name_list = [] + length_list = [] + data_dict = {} + for name in self.id_list: + # try: + motion = np.load(pjoin(motion_dir, name + '.npy')) + if (len(motion)) < self.min_motion_length or (len(motion) >= 200): + continue + + + text_data = [] + flag = False + + with cs.open(pjoin(text_dir, name + '.txt')) as f: + for line in f.readlines(): + text_dict = {} + line_split = line.strip().split('#') + caption = line_split[0] + tokens = line_split[1].split(' ') + f_tag = float(line_split[2]) + to_tag = float(line_split[3]) + f_tag = 0.0 if np.isnan(f_tag) else f_tag + to_tag = 0.0 if np.isnan(to_tag) else to_tag + + text_dict['caption'] = caption + text_dict['tokens'] = tokens + if f_tag == 0.0 and to_tag == 0.0: + flag = True + text_data.append(text_dict) + else: + try: + n_motion = motion[int(f_tag*20) : int(to_tag*20)] + + if (len(n_motion)) < min_motion_length or (len(n_motion) >= 200): + continue + + new_name = "%s_%f_%f"%(name, f_tag, to_tag) + data_dict[new_name] = {'motion': n_motion, + 'length': len(n_motion), + 'text':[text_dict]} + new_name_list.append(new_name) + except: + print(line_split) + print(line_split[2], line_split[3], f_tag, to_tag, name) + if flag: + data_dict[name] = {'motion': motion, + 'length': len(motion), + 'name': name, + 'text': text_data} + + new_name_list.append(name) + length_list.append(len(motion)) + # except: + # # Some motion may not exist in KIT dataset + # pass + + self.length_arr = np.array(length_list) + self.data_dict = data_dict + self.name_list = new_name_list + self.nfeats = motion.shape[-1] + + + def __len__(self): + return len(self.data_dict) + + def __getitem__(self, item): + name = self.name_list[item] + data = self.data_dict[name] + motion, m_length = data['motion'], data['length'] + + "Z Normalization" + motion = (motion - self.mean) / self.std + + return name, motion, m_length, True, True, True, True, True, True diff --git a/motiondiff_modules/mGPT/data/humanml/dataset_t2m_token.py b/motiondiff_modules/mGPT/data/humanml/dataset_t2m_token.py new file mode 100644 index 0000000..d9f1e54 --- /dev/null +++ b/motiondiff_modules/mGPT/data/humanml/dataset_t2m_token.py @@ -0,0 +1,86 @@ +import random +import numpy as np +from torch.utils import data +from .dataset_t2m import Text2MotionDataset +import codecs as cs +from os.path import join as pjoin + + +class Text2MotionDatasetToken(data.Dataset): + + def __init__( + self, + data_root, + split, + mean, + std, + max_motion_length=196, + min_motion_length=40, + unit_length=4, + fps=20, + tmpFile=True, + tiny=False, + debug=False, + **kwargs, + ): + + self.max_motion_length = max_motion_length + self.min_motion_length = min_motion_length + self.unit_length = unit_length + + # Data mean and std + self.mean = mean + self.std = std + + # Data path + split_file = pjoin(data_root, split + '.txt') + motion_dir = pjoin(data_root, 'new_joint_vecs') + text_dir = pjoin(data_root, 'texts') + + # Data id list + self.id_list = [] + with cs.open(split_file, "r") as f: + for line in f.readlines(): + self.id_list.append(line.strip()) + + new_name_list = [] + length_list = [] + data_dict = {} + for name in self.id_list: + try: + motion = np.load(pjoin(motion_dir, name + '.npy')) + if (len(motion)) < self.min_motion_length or (len(motion) >= 200): + continue + + data_dict[name] = {'motion': motion, + 'length': len(motion), + 'name': name} + new_name_list.append(name) + length_list.append(len(motion)) + except: + # Some motion may not exist in KIT dataset + pass + + self.length_arr = np.array(length_list) + self.data_dict = data_dict + self.name_list = new_name_list + self.nfeats = motion.shape[-1] + + + def __len__(self): + return len(self.data_dict) + + def __getitem__(self, item): + name = self.name_list[item] + data = self.data_dict[name] + motion, m_length = data['motion'], data['length'] + + m_length = (m_length // self.unit_length) * self.unit_length + + idx = random.randint(0, len(motion) - m_length) + motion = motion[idx:idx+m_length] + + "Z Normalization" + motion = (motion - self.mean) / self.std + + return name, motion, m_length, True, True, True, True, True, True diff --git a/motiondiff_modules/mGPT/data/humanml/scripts/motion_process.py b/motiondiff_modules/mGPT/data/humanml/scripts/motion_process.py new file mode 100644 index 0000000..8b3395c --- /dev/null +++ b/motiondiff_modules/mGPT/data/humanml/scripts/motion_process.py @@ -0,0 +1,529 @@ +from os.path import join as pjoin + +from ..common.skeleton import Skeleton +import numpy as np +import os +from ..common.quaternion import * +from ..utils.paramUtil import * + +import torch +from tqdm import tqdm + +# positions (batch, joint_num, 3) +def uniform_skeleton(positions, target_offset): + src_skel = Skeleton(n_raw_offsets, kinematic_chain, 'cpu') + src_offset = src_skel.get_offsets_joints(torch.from_numpy(positions[0])) + src_offset = src_offset.numpy() + tgt_offset = target_offset.numpy() + # print(src_offset) + # print(tgt_offset) + '''Calculate Scale Ratio as the ratio of legs''' + src_leg_len = np.abs(src_offset[l_idx1]).max() + np.abs(src_offset[l_idx2]).max() + tgt_leg_len = np.abs(tgt_offset[l_idx1]).max() + np.abs(tgt_offset[l_idx2]).max() + + scale_rt = tgt_leg_len / src_leg_len + # print(scale_rt) + src_root_pos = positions[:, 0] + tgt_root_pos = src_root_pos * scale_rt + + '''Inverse Kinematics''' + quat_params = src_skel.inverse_kinematics_np(positions, face_joint_indx) + # print(quat_params.shape) + + '''Forward Kinematics''' + src_skel.set_offset(target_offset) + new_joints = src_skel.forward_kinematics_np(quat_params, tgt_root_pos) + return new_joints + + +def extract_features(positions, feet_thre, n_raw_offsets, kinematic_chain, face_joint_indx, fid_r, fid_l): + global_positions = positions.copy() + """ Get Foot Contacts """ + + def foot_detect(positions, thres): + velfactor, heightfactor = np.array([thres, thres]), np.array([3.0, 2.0]) + + feet_l_x = (positions[1:, fid_l, 0] - positions[:-1, fid_l, 0]) ** 2 + feet_l_y = (positions[1:, fid_l, 1] - positions[:-1, fid_l, 1]) ** 2 + feet_l_z = (positions[1:, fid_l, 2] - positions[:-1, fid_l, 2]) ** 2 + # feet_l_h = positions[:-1,fid_l,1] + # feet_l = (((feet_l_x + feet_l_y + feet_l_z) < velfactor) & (feet_l_h < heightfactor)).astype(np.float64) + feet_l = ((feet_l_x + feet_l_y + feet_l_z) < velfactor).astype(np.float64) + + feet_r_x = (positions[1:, fid_r, 0] - positions[:-1, fid_r, 0]) ** 2 + feet_r_y = (positions[1:, fid_r, 1] - positions[:-1, fid_r, 1]) ** 2 + feet_r_z = (positions[1:, fid_r, 2] - positions[:-1, fid_r, 2]) ** 2 + # feet_r_h = positions[:-1,fid_r,1] + # feet_r = (((feet_r_x + feet_r_y + feet_r_z) < velfactor) & (feet_r_h < heightfactor)).astype(np.float64) + feet_r = (((feet_r_x + feet_r_y + feet_r_z) < velfactor)).astype(np.float64) + return feet_l, feet_r + + # + feet_l, feet_r = foot_detect(positions, feet_thre) + # feet_l, feet_r = foot_detect(positions, 0.002) + + '''Quaternion and Cartesian representation''' + r_rot = None + + def get_rifke(positions): + '''Local pose''' + positions[..., 0] -= positions[:, 0:1, 0] + positions[..., 2] -= positions[:, 0:1, 2] + '''All pose face Z+''' + positions = qrot_np(np.repeat(r_rot[:, None], positions.shape[1], axis=1), positions) + return positions + + def get_quaternion(positions): + skel = Skeleton(n_raw_offsets, kinematic_chain, "cpu") + # (seq_len, joints_num, 4) + quat_params = skel.inverse_kinematics_np(positions, face_joint_indx, smooth_forward=False) + + '''Fix Quaternion Discontinuity''' + quat_params = qfix(quat_params) + # (seq_len, 4) + r_rot = quat_params[:, 0].copy() + # print(r_rot[0]) + '''Root Linear Velocity''' + # (seq_len - 1, 3) + velocity = (positions[1:, 0] - positions[:-1, 0]).copy() + # print(r_rot.shape, velocity.shape) + velocity = qrot_np(r_rot[1:], velocity) + '''Root Angular Velocity''' + # (seq_len - 1, 4) + r_velocity = qmul_np(r_rot[1:], qinv_np(r_rot[:-1])) + quat_params[1:, 0] = r_velocity + # (seq_len, joints_num, 4) + return quat_params, r_velocity, velocity, r_rot + + def get_cont6d_params(positions): + skel = Skeleton(n_raw_offsets, kinematic_chain, "cpu") + # (seq_len, joints_num, 4) + quat_params = skel.inverse_kinematics_np(positions, face_joint_indx, smooth_forward=True) + + '''Quaternion to continuous 6D''' + cont_6d_params = quaternion_to_cont6d_np(quat_params) + # (seq_len, 4) + r_rot = quat_params[:, 0].copy() + # print(r_rot[0]) + '''Root Linear Velocity''' + # (seq_len - 1, 3) + velocity = (positions[1:, 0] - positions[:-1, 0]).copy() + # print(r_rot.shape, velocity.shape) + velocity = qrot_np(r_rot[1:], velocity) + '''Root Angular Velocity''' + # (seq_len - 1, 4) + r_velocity = qmul_np(r_rot[1:], qinv_np(r_rot[:-1])) + # (seq_len, joints_num, 4) + return cont_6d_params, r_velocity, velocity, r_rot + + cont_6d_params, r_velocity, velocity, r_rot = get_cont6d_params(positions) + positions = get_rifke(positions) + + # trejec = np.cumsum(np.concatenate([np.array([[0, 0, 0]]), velocity], axis=0), axis=0) + # r_rotations, r_pos = recover_ric_glo_np(r_velocity, velocity[:, [0, 2]]) + + # plt.plot(positions_b[:, 0, 0], positions_b[:, 0, 2], marker='*') + # plt.plot(ground_positions[:, 0, 0], ground_positions[:, 0, 2], marker='o', color='r') + # plt.plot(trejec[:, 0], trejec[:, 2], marker='^', color='g') + # plt.plot(r_pos[:, 0], r_pos[:, 2], marker='s', color='y') + # plt.xlabel('x') + # plt.ylabel('z') + # plt.axis('equal') + # plt.show() + + '''Root height''' + root_y = positions[:, 0, 1:2] + + '''Root rotation and linear velocity''' + # (seq_len-1, 1) rotation velocity along y-axis + # (seq_len-1, 2) linear velovity on xz plane + r_velocity = np.arcsin(r_velocity[:, 2:3]) + l_velocity = velocity[:, [0, 2]] + # print(r_velocity.shape, l_velocity.shape, root_y.shape) + root_data = np.concatenate([r_velocity, l_velocity, root_y[:-1]], axis=-1) + + '''Get Joint Rotation Representation''' + # (seq_len, (joints_num-1) *6) quaternion for skeleton joints + rot_data = cont_6d_params[:, 1:].reshape(len(cont_6d_params), -1) + + '''Get Joint Rotation Invariant Position Represention''' + # (seq_len, (joints_num-1)*3) local joint position + ric_data = positions[:, 1:].reshape(len(positions), -1) + + '''Get Joint Velocity Representation''' + # (seq_len-1, joints_num*3) + local_vel = qrot_np(np.repeat(r_rot[:-1, None], global_positions.shape[1], axis=1), + global_positions[1:] - global_positions[:-1]) + local_vel = local_vel.reshape(len(local_vel), -1) + + data = root_data + data = np.concatenate([data, ric_data[:-1]], axis=-1) + data = np.concatenate([data, rot_data[:-1]], axis=-1) + # print(dataset.shape, local_vel.shape) + data = np.concatenate([data, local_vel], axis=-1) + data = np.concatenate([data, feet_l, feet_r], axis=-1) + + return data + + +def process_file(positions, feet_thre): + # (seq_len, joints_num, 3) + # '''Down Sample''' + # positions = positions[::ds_num] + + '''Uniform Skeleton''' + positions = uniform_skeleton(positions, tgt_offsets) + + '''Put on Floor''' + floor_height = positions.min(axis=0).min(axis=0)[1] + positions[:, :, 1] -= floor_height + # print(floor_height) + + # plot_3d_motion("./positions_1.mp4", kinematic_chain, positions, 'title', fps=20) + + '''XZ at origin''' + root_pos_init = positions[0] + root_pose_init_xz = root_pos_init[0] * np.array([1, 0, 1]) + positions = positions - root_pose_init_xz + + # '''Move the first pose to origin ''' + # root_pos_init = positions[0] + # positions = positions - root_pos_init[0] + + '''All initially face Z+''' + r_hip, l_hip, sdr_r, sdr_l = face_joint_indx + across1 = root_pos_init[r_hip] - root_pos_init[l_hip] + across2 = root_pos_init[sdr_r] - root_pos_init[sdr_l] + across = across1 + across2 + across = across / np.sqrt((across ** 2).sum(axis=-1))[..., np.newaxis] + + # forward (3,), rotate around y-axis + forward_init = np.cross(np.array([[0, 1, 0]]), across, axis=-1) + # forward (3,) + forward_init = forward_init / np.sqrt((forward_init ** 2).sum(axis=-1))[..., np.newaxis] + + # print(forward_init) + + target = np.array([[0, 0, 1]]) + root_quat_init = qbetween_np(forward_init, target) + root_quat_init = np.ones(positions.shape[:-1] + (4,)) * root_quat_init + + positions_b = positions.copy() + + positions = qrot_np(root_quat_init, positions) + + # plot_3d_motion("./positions_2.mp4", kinematic_chain, positions, 'title', fps=20) + + '''New ground truth positions''' + global_positions = positions.copy() + + # plt.plot(positions_b[:, 0, 0], positions_b[:, 0, 2], marker='*') + # plt.plot(positions[:, 0, 0], positions[:, 0, 2], marker='o', color='r') + # plt.xlabel('x') + # plt.ylabel('z') + # plt.axis('equal') + # plt.show() + + """ Get Foot Contacts """ + + def foot_detect(positions, thres): + velfactor, heightfactor = np.array([thres, thres]), np.array([3.0, 2.0]) + + feet_l_x = (positions[1:, fid_l, 0] - positions[:-1, fid_l, 0]) ** 2 + feet_l_y = (positions[1:, fid_l, 1] - positions[:-1, fid_l, 1]) ** 2 + feet_l_z = (positions[1:, fid_l, 2] - positions[:-1, fid_l, 2]) ** 2 + # feet_l_h = positions[:-1,fid_l,1] + # feet_l = (((feet_l_x + feet_l_y + feet_l_z) < velfactor) & (feet_l_h < heightfactor)).astype(np.float64) + feet_l = ((feet_l_x + feet_l_y + feet_l_z) < velfactor).astype(np.float64) + + feet_r_x = (positions[1:, fid_r, 0] - positions[:-1, fid_r, 0]) ** 2 + feet_r_y = (positions[1:, fid_r, 1] - positions[:-1, fid_r, 1]) ** 2 + feet_r_z = (positions[1:, fid_r, 2] - positions[:-1, fid_r, 2]) ** 2 + # feet_r_h = positions[:-1,fid_r,1] + # feet_r = (((feet_r_x + feet_r_y + feet_r_z) < velfactor) & (feet_r_h < heightfactor)).astype(np.float64) + feet_r = (((feet_r_x + feet_r_y + feet_r_z) < velfactor)).astype(np.float64) + return feet_l, feet_r + # + feet_l, feet_r = foot_detect(positions, feet_thre) + # feet_l, feet_r = foot_detect(positions, 0.002) + + '''Quaternion and Cartesian representation''' + r_rot = None + + def get_rifke(positions): + '''Local pose''' + positions[..., 0] -= positions[:, 0:1, 0] + positions[..., 2] -= positions[:, 0:1, 2] + '''All pose face Z+''' + positions = qrot_np(np.repeat(r_rot[:, None], positions.shape[1], axis=1), positions) + return positions + + def get_quaternion(positions): + skel = Skeleton(n_raw_offsets, kinematic_chain, "cpu") + # (seq_len, joints_num, 4) + quat_params = skel.inverse_kinematics_np(positions, face_joint_indx, smooth_forward=False) + + '''Fix Quaternion Discontinuity''' + quat_params = qfix(quat_params) + # (seq_len, 4) + r_rot = quat_params[:, 0].copy() + # print(r_rot[0]) + '''Root Linear Velocity''' + # (seq_len - 1, 3) + velocity = (positions[1:, 0] - positions[:-1, 0]).copy() + # print(r_rot.shape, velocity.shape) + velocity = qrot_np(r_rot[1:], velocity) + '''Root Angular Velocity''' + # (seq_len - 1, 4) + r_velocity = qmul_np(r_rot[1:], qinv_np(r_rot[:-1])) + quat_params[1:, 0] = r_velocity + # (seq_len, joints_num, 4) + return quat_params, r_velocity, velocity, r_rot + + def get_cont6d_params(positions): + skel = Skeleton(n_raw_offsets, kinematic_chain, "cpu") + # (seq_len, joints_num, 4) + quat_params = skel.inverse_kinematics_np(positions, face_joint_indx, smooth_forward=True) + + '''Quaternion to continuous 6D''' + cont_6d_params = quaternion_to_cont6d_np(quat_params) + # (seq_len, 4) + r_rot = quat_params[:, 0].copy() + # print(r_rot[0]) + '''Root Linear Velocity''' + # (seq_len - 1, 3) + velocity = (positions[1:, 0] - positions[:-1, 0]).copy() + # print(r_rot.shape, velocity.shape) + velocity = qrot_np(r_rot[1:], velocity) + '''Root Angular Velocity''' + # (seq_len - 1, 4) + r_velocity = qmul_np(r_rot[1:], qinv_np(r_rot[:-1])) + # (seq_len, joints_num, 4) + return cont_6d_params, r_velocity, velocity, r_rot + + cont_6d_params, r_velocity, velocity, r_rot = get_cont6d_params(positions) + positions = get_rifke(positions) + + # trejec = np.cumsum(np.concatenate([np.array([[0, 0, 0]]), velocity], axis=0), axis=0) + # r_rotations, r_pos = recover_ric_glo_np(r_velocity, velocity[:, [0, 2]]) + + # plt.plot(positions_b[:, 0, 0], positions_b[:, 0, 2], marker='*') + # plt.plot(ground_positions[:, 0, 0], ground_positions[:, 0, 2], marker='o', color='r') + # plt.plot(trejec[:, 0], trejec[:, 2], marker='^', color='g') + # plt.plot(r_pos[:, 0], r_pos[:, 2], marker='s', color='y') + # plt.xlabel('x') + # plt.ylabel('z') + # plt.axis('equal') + # plt.show() + + '''Root height''' + root_y = positions[:, 0, 1:2] + + '''Root rotation and linear velocity''' + # (seq_len-1, 1) rotation velocity along y-axis + # (seq_len-1, 2) linear velovity on xz plane + r_velocity = np.arcsin(r_velocity[:, 2:3]) + l_velocity = velocity[:, [0, 2]] + # print(r_velocity.shape, l_velocity.shape, root_y.shape) + root_data = np.concatenate([r_velocity, l_velocity, root_y[:-1]], axis=-1) + + '''Get Joint Rotation Representation''' + # (seq_len, (joints_num-1) *6) quaternion for skeleton joints + rot_data = cont_6d_params[:, 1:].reshape(len(cont_6d_params), -1) + + '''Get Joint Rotation Invariant Position Represention''' + # (seq_len, (joints_num-1)*3) local joint position + ric_data = positions[:, 1:].reshape(len(positions), -1) + + '''Get Joint Velocity Representation''' + # (seq_len-1, joints_num*3) + local_vel = qrot_np(np.repeat(r_rot[:-1, None], global_positions.shape[1], axis=1), + global_positions[1:] - global_positions[:-1]) + local_vel = local_vel.reshape(len(local_vel), -1) + + data = root_data + data = np.concatenate([data, ric_data[:-1]], axis=-1) + data = np.concatenate([data, rot_data[:-1]], axis=-1) + # print(dataset.shape, local_vel.shape) + data = np.concatenate([data, local_vel], axis=-1) + data = np.concatenate([data, feet_l, feet_r], axis=-1) + + return data, global_positions, positions, l_velocity + + +# Recover global angle and positions for rotation dataset +# root_rot_velocity (B, seq_len, 1) +# root_linear_velocity (B, seq_len, 2) +# root_y (B, seq_len, 1) +# ric_data (B, seq_len, (joint_num - 1)*3) +# rot_data (B, seq_len, (joint_num - 1)*6) +# local_velocity (B, seq_len, joint_num*3) +# foot contact (B, seq_len, 4) +def recover_root_rot_pos(data): + rot_vel = data[..., 0] + r_rot_ang = torch.zeros_like(rot_vel).to(data.device) + '''Get Y-axis rotation from rotation velocity''' + r_rot_ang[..., 1:] = rot_vel[..., :-1] + r_rot_ang = torch.cumsum(r_rot_ang, dim=-1) + + r_rot_quat = torch.zeros(data.shape[:-1] + (4,)).to(data.device) + r_rot_quat[..., 0] = torch.cos(r_rot_ang) + r_rot_quat[..., 2] = torch.sin(r_rot_ang) + + r_pos = torch.zeros(data.shape[:-1] + (3,)).to(data.device) + r_pos[..., 1:, [0, 2]] = data[..., :-1, 1:3] + '''Add Y-axis rotation to root position''' + r_pos = qrot(qinv(r_rot_quat), r_pos) + + r_pos = torch.cumsum(r_pos, dim=-2) + + r_pos[..., 1] = data[..., 3] + return r_rot_quat, r_pos + + +def recover_from_rot(data, joints_num, skeleton): + r_rot_quat, r_pos = recover_root_rot_pos(data) + + r_rot_cont6d = quaternion_to_cont6d(r_rot_quat) + + start_indx = 1 + 2 + 1 + (joints_num - 1) * 3 + end_indx = start_indx + (joints_num - 1) * 6 + cont6d_params = data[..., start_indx:end_indx] + # print(r_rot_cont6d.shape, cont6d_params.shape, r_pos.shape) + cont6d_params = torch.cat([r_rot_cont6d, cont6d_params], dim=-1) + cont6d_params = cont6d_params.view(-1, joints_num, 6) + + positions = skeleton.forward_kinematics_cont6d(cont6d_params, r_pos) + + return positions + +def recover_rot(data): + # dataset [bs, seqlen, 263/251] HumanML/KIT + joints_num = 22 if data.shape[-1] == 263 else 21 + r_rot_quat, r_pos = recover_root_rot_pos(data) + r_pos_pad = torch.cat([r_pos, torch.zeros_like(r_pos)], dim=-1).unsqueeze(-2) + r_rot_cont6d = quaternion_to_cont6d(r_rot_quat) + start_indx = 1 + 2 + 1 + (joints_num - 1) * 3 + end_indx = start_indx + (joints_num - 1) * 6 + cont6d_params = data[..., start_indx:end_indx] + cont6d_params = torch.cat([r_rot_cont6d, cont6d_params], dim=-1) + cont6d_params = cont6d_params.view(-1, joints_num, 6) + cont6d_params = torch.cat([cont6d_params, r_pos_pad], dim=-2) + return cont6d_params + + +def recover_from_ric(data, joints_num): + r_rot_quat, r_pos = recover_root_rot_pos(data) + positions = data[..., 4:(joints_num - 1) * 3 + 4] + positions = positions.view(positions.shape[:-1] + (-1, 3)) + + '''Add Y-axis rotation to local joints''' + positions = qrot(qinv(r_rot_quat[..., None, :]).expand(positions.shape[:-1] + (4,)), positions) + + '''Add root XZ to joints''' + positions[..., 0] += r_pos[..., 0:1] + positions[..., 2] += r_pos[..., 2:3] + + '''Concate root and joints''' + positions = torch.cat([r_pos.unsqueeze(-2), positions], dim=-2) + + return positions +''' +For Text2Motion Dataset +''' +''' +if __name__ == "__main__": + example_id = "000021" + # Lower legs + l_idx1, l_idx2 = 5, 8 + # Right/Left foot + fid_r, fid_l = [8, 11], [7, 10] + # Face direction, r_hip, l_hip, sdr_r, sdr_l + face_joint_indx = [2, 1, 17, 16] + # l_hip, r_hip + r_hip, l_hip = 2, 1 + joints_num = 22 + # ds_num = 8 + data_dir = '../dataset/pose_data_raw/joints/' + save_dir1 = '../dataset/pose_data_raw/new_joints/' + save_dir2 = '../dataset/pose_data_raw/new_joint_vecs/' + + n_raw_offsets = torch.from_numpy(t2m_raw_offsets) + kinematic_chain = t2m_kinematic_chain + + # Get offsets of target skeleton + example_data = np.load(os.path.join(data_dir, example_id + '.npy')) + example_data = example_data.reshape(len(example_data), -1, 3) + example_data = torch.from_numpy(example_data) + tgt_skel = Skeleton(n_raw_offsets, kinematic_chain, 'cpu') + # (joints_num, 3) + tgt_offsets = tgt_skel.get_offsets_joints(example_data[0]) + # print(tgt_offsets) + + source_list = os.listdir(data_dir) + frame_num = 0 + for source_file in tqdm(source_list): + source_data = np.load(os.path.join(data_dir, source_file))[:, :joints_num] + try: + dataset, ground_positions, positions, l_velocity = process_file(source_data, 0.002) + rec_ric_data = recover_from_ric(torch.from_numpy(dataset).unsqueeze(0).float(), joints_num) + np.save(pjoin(save_dir1, source_file), rec_ric_data.squeeze().numpy()) + np.save(pjoin(save_dir2, source_file), dataset) + frame_num += dataset.shape[0] + except Exception as e: + print(source_file) + print(e) + + print('Total clips: %d, Frames: %d, Duration: %fm' % + (len(source_list), frame_num, frame_num / 20 / 60)) +''' + +if __name__ == "__main__": + example_id = "03950_gt" + # Lower legs + l_idx1, l_idx2 = 17, 18 + # Right/Left foot + fid_r, fid_l = [14, 15], [19, 20] + # Face direction, r_hip, l_hip, sdr_r, sdr_l + face_joint_indx = [11, 16, 5, 8] + # l_hip, r_hip + r_hip, l_hip = 11, 16 + joints_num = 21 + # ds_num = 8 + data_dir = '../dataset/kit_mocap_dataset/joints/' + save_dir1 = '../dataset/kit_mocap_dataset/new_joints/' + save_dir2 = '../dataset/kit_mocap_dataset/new_joint_vecs/' + + n_raw_offsets = torch.from_numpy(kit_raw_offsets) + kinematic_chain = kit_kinematic_chain + + '''Get offsets of target skeleton''' + example_data = np.load(os.path.join(data_dir, example_id + '.npy')) + example_data = example_data.reshape(len(example_data), -1, 3) + example_data = torch.from_numpy(example_data) + tgt_skel = Skeleton(n_raw_offsets, kinematic_chain, 'cpu') + # (joints_num, 3) + tgt_offsets = tgt_skel.get_offsets_joints(example_data[0]) + # print(tgt_offsets) + + source_list = os.listdir(data_dir) + frame_num = 0 + '''Read source dataset''' + for source_file in tqdm(source_list): + source_data = np.load(os.path.join(data_dir, source_file))[:, :joints_num] + try: + name = ''.join(source_file[:-7].split('_')) + '.npy' + data, ground_positions, positions, l_velocity = process_file(source_data, 0.05) + rec_ric_data = recover_from_ric(torch.from_numpy(data).unsqueeze(0).float(), joints_num) + if np.isnan(rec_ric_data.numpy()).any(): + print(source_file) + continue + np.save(pjoin(save_dir1, name), rec_ric_data.squeeze().numpy()) + np.save(pjoin(save_dir2, name), data) + frame_num += data.shape[0] + except Exception as e: + print(source_file) + print(e) + + print('Total clips: %d, Frames: %d, Duration: %fm' % + (len(source_list), frame_num, frame_num / 12.5 / 60)) diff --git a/motiondiff_modules/mGPT/data/humanml/utils/paramUtil.py b/motiondiff_modules/mGPT/data/humanml/utils/paramUtil.py new file mode 100644 index 0000000..a9f1708 --- /dev/null +++ b/motiondiff_modules/mGPT/data/humanml/utils/paramUtil.py @@ -0,0 +1,63 @@ +import numpy as np + +# Define a kinematic tree for the skeletal struture +kit_kinematic_chain = [[0, 11, 12, 13, 14, 15], [0, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4], [3, 5, 6, 7], [3, 8, 9, 10]] + +kit_raw_offsets = np.array( + [ + [0, 0, 0], + [0, 1, 0], + [0, 1, 0], + [0, 1, 0], + [0, 1, 0], + [1, 0, 0], + [0, -1, 0], + [0, -1, 0], + [-1, 0, 0], + [0, -1, 0], + [0, -1, 0], + [1, 0, 0], + [0, -1, 0], + [0, -1, 0], + [0, 0, 1], + [0, 0, 1], + [-1, 0, 0], + [0, -1, 0], + [0, -1, 0], + [0, 0, 1], + [0, 0, 1] + ] +) + +t2m_raw_offsets = np.array([[0,0,0], + [1,0,0], + [-1,0,0], + [0,1,0], + [0,-1,0], + [0,-1,0], + [0,1,0], + [0,-1,0], + [0,-1,0], + [0,1,0], + [0,0,1], + [0,0,1], + [0,1,0], + [1,0,0], + [-1,0,0], + [0,0,1], + [0,-1,0], + [0,-1,0], + [0,-1,0], + [0,-1,0], + [0,-1,0], + [0,-1,0]]) + +t2m_kinematic_chain = [[0, 2, 5, 8, 11], [0, 1, 4, 7, 10], [0, 3, 6, 9, 12, 15], [9, 14, 17, 19, 21], [9, 13, 16, 18, 20]] +t2m_left_hand_chain = [[20, 22, 23, 24], [20, 34, 35, 36], [20, 25, 26, 27], [20, 31, 32, 33], [20, 28, 29, 30]] +t2m_right_hand_chain = [[21, 43, 44, 45], [21, 46, 47, 48], [21, 40, 41, 42], [21, 37, 38, 39], [21, 49, 50, 51]] + + +kit_tgt_skel_id = '03950' + +t2m_tgt_skel_id = '000021' + diff --git a/motiondiff_modules/mGPT/data/humanml/utils/word_vectorizer.py b/motiondiff_modules/mGPT/data/humanml/utils/word_vectorizer.py new file mode 100644 index 0000000..d272058 --- /dev/null +++ b/motiondiff_modules/mGPT/data/humanml/utils/word_vectorizer.py @@ -0,0 +1,79 @@ +import numpy as np +import pickle +from os.path import join as pjoin + +POS_enumerator = { + 'VERB': 0, + 'NOUN': 1, + 'DET': 2, + 'ADP': 3, + 'NUM': 4, + 'AUX': 5, + 'PRON': 6, + 'ADJ': 7, + 'ADV': 8, + 'Loc_VIP': 9, + 'Body_VIP': 10, + 'Obj_VIP': 11, + 'Act_VIP': 12, + 'Desc_VIP': 13, + 'OTHER': 14, +} + +Loc_list = ('left', 'right', 'clockwise', 'counterclockwise', 'anticlockwise', 'forward', 'back', 'backward', + 'up', 'down', 'straight', 'curve') + +Body_list = ('arm', 'chin', 'foot', 'feet', 'face', 'hand', 'mouth', 'leg', 'waist', 'eye', 'knee', 'shoulder', 'thigh') + +Obj_List = ('stair', 'dumbbell', 'chair', 'window', 'floor', 'car', 'ball', 'handrail', 'baseball', 'basketball') + +Act_list = ('walk', 'run', 'swing', 'pick', 'bring', 'kick', 'put', 'squat', 'throw', 'hop', 'dance', 'jump', 'turn', + 'stumble', 'dance', 'stop', 'sit', 'lift', 'lower', 'raise', 'wash', 'stand', 'kneel', 'stroll', + 'rub', 'bend', 'balance', 'flap', 'jog', 'shuffle', 'lean', 'rotate', 'spin', 'spread', 'climb') + +Desc_list = ('slowly', 'carefully', 'fast', 'careful', 'slow', 'quickly', 'happy', 'angry', 'sad', 'happily', 'angrily', 'sadly') + +VIP_dict = { + 'Loc_VIP': Loc_list, + 'Body_VIP': Body_list, + 'Obj_VIP': Obj_List, + 'Act_VIP': Act_list, + 'Desc_VIP': Desc_list, +} + + +class WordVectorizer(object): + def __init__(self, meta_root, prefix): + vectors = np.load(pjoin(meta_root, '%s_data.npy'%prefix)) + words = pickle.load(open(pjoin(meta_root, '%s_words.pkl'%prefix), 'rb')) + word2idx = pickle.load(open(pjoin(meta_root, '%s_idx.pkl'%prefix), 'rb')) + self.word2vec = {w: vectors[word2idx[w]] for w in words} + + def _get_pos_ohot(self, pos): + pos_vec = np.zeros(len(POS_enumerator)) + if pos in POS_enumerator: + pos_vec[POS_enumerator[pos]] = 1 + else: + pos_vec[POS_enumerator['OTHER']] = 1 + return pos_vec + + def __len__(self): + return len(self.word2vec) + + def __getitem__(self, item): + word, pos = item.split('/') + if word in self.word2vec: + word_vec = self.word2vec[word] + vip_pos = None + for key, values in VIP_dict.items(): + if word in values: + vip_pos = key + break + if vip_pos is not None: + pos_vec = self._get_pos_ohot(vip_pos) + else: + pos_vec = self._get_pos_ohot(pos) + else: + word_vec = self.word2vec['unk'] + pos_vec = self._get_pos_ohot('OTHER') + return word_vec, pos_vec diff --git a/motiondiff_modules/mGPT/data/mean.npy b/motiondiff_modules/mGPT/data/mean.npy new file mode 100644 index 0000000000000000000000000000000000000000..e754cba2fee3e20e6b0b11fe8d3ac24ae7b0214c GIT binary patch literal 2232 zcmbW!`9IYA7r=4S$Xbe9k)npCkjhSRNV!>(EXi7AmuQ3{%b<`{8iS-l))Bh+R)#+B zP*M$M$dY|B*~StQ6Y1*y3E%VEc|D##okKRaIbmVP%M;8KMsRZvJWnL($Px~FXc3fT z2_F8$%S4xpXZ?w8?ti+G%Y{Jq)gI{O65zhN?@`fERobg08!r2QkC21jC^lNziETRI zlwFeRCjC@yEQ++AA zVlc1KMHvU_+f!jH;ZbPFu6vskbqg|n5S4f+>l>tRYwc zZm_;Lq44vEDzFH8mA~Xj1H9$$K9li$q)+8E+&xc27*l~FWLXUhYbGqdy~;=4OZ&2q zwW^`D{W^lDFV2Cm@~2qFlT@g($})Z1RR)(T%Bx3G^C1YND(`DFCNEJy&*R_yg_vO=a?;MO!x;R653u6Hm#b~6;_s=0V zslVbzd?Vbj@rhE#&qItvH-m4H04l<-1|OV^kO1MP{}Rv!v%t;vY#)@A@( zGe^pcH3MR=^iFC$IR`y2{dE`l7^pJu5t}wR1L6L23l3k*Au}JhMM#bb)I76-L)WK) zV>7UDt(FE)51N)teq*4IJCjGYU7m(2H_4UF?`U8Wu`EF(eunm+8_lm6jG=yiub!HR5jvg-yx+@~bW{#zFEvv?)=M})IXGBqImp$4*lT9X=%0nb;Wj2mH z33#83zO=jVPOB-ZrJX>$# zT8~D_LY#ouHhA^V*b4(44q7n%-M`x*1to^g{_)_~b&DX-)&`gMDQHew)FY{HeJ)Y? zQ&5rJu}Rw65D5?+O>{0uBLm}H{+=L1sI9HCQhhxNqNHI1%7IQurqOAYWs_iQKGd7~ zrXDqD-`p4EK|$fy56H#W)qzV%-JnVED6lfrHDyHT@GPf*weV~bR;>NsJC@XgI8Gav zX-$EpJ+X~hMRn-$TIzqEe7pHejU*k$k|Sg;g-wG*dNWlwMinXb;O&m?l|Vcq)N2p> zRUtQ_(XVfL65@U3I45n(!B(2oG(jB!-Uj9AG@bikT=$^hm@*Sp6DXZzg*-@5QVIA% z7zZ4Ueo=Dn0|;u0c34!5fS0PL&s(o_bYETd6~7P@?9^rj{yCV3sK+E!F!^zC)4BWl z+0+LhehoTIvz>-;lH2>YQwTx!~mX&N~6>$_0-+trX*0Y_^ ztaJH~N9LrIUoR>$;L&nyZ*%|)wx&5bCHt8NTZ(MyKaRS%_4m*}3bd8yc`U>y9Nxqsy&pH?DeE z&?Q)zd$Qp>qb0u2_X(N~7%GmScEeE>dbwaC8;v?W?VSsbhwLW;Un8}LfTus+NKLsN z{`avzAxnn}_FnoTkIK5if644`ERGF4Jb(F~IeP=`sL3?V&>TXfYdGUSKJIwVkw!u> z=q45Nr&y0dn^!uqC9(?ji(X(((2LLp=U)5Q57I%J5&qI@0}Etse(E``)`i}LMvw5F z8igSC$(v?xs$lVEW(wzB5r}2~kg3+pKuu#;|MRZ5lXg1q??R4t{&Mh>5x#!iyQsU}VPC48tK3u;%_MFAe#L6)5pB7d2tz;i_E)Q6>pfoD7pblq4MGc8 z<%2t$P->vny|P6-Mf(&nI!mJwk}4_QVb5( zoF7!lSOtc- z7~b7b)wG2KA~9AvPj5?rrztyMtbi8^-HIjM?W3Wo;<-AzPZnwPD5_ETcwt9-j?nJa zUNf2#oOX|kH5OY*EHv|?s1VgaMLG$R?icol$FD&SCSVoe&4X-DtLJZOCIR0Zy2V_> z!8#scQDs+o(018CEt%EcOerb})#PHX__)J|)7BvG?v3Lo@=5Ta-i=yH6+_|;(sIJj zeqlUse=h~LlHh>c25HaZ6M8;F$MNF06|8o8tGE4XxAq-*EM+W>T%_+0uf4jAotj!q z4V@xES*U1&@$`E5+Kw9zZCJ+a-sc_`pC*CcYYUCF2|JNzWM=aI?JO)>T`^>8kp%n^ zmO&?sH^XZwE%qXwg$czd&>373%sRYmID+RuWV=Y9d?E*gzh|0u5jeni)^K}Q5(oYT DDM3hl literal 0 HcmV?d00001 diff --git a/motiondiff_modules/mGPT/data/mean_eval.npy b/motiondiff_modules/mGPT/data/mean_eval.npy new file mode 100644 index 0000000000000000000000000000000000000000..e754cba2fee3e20e6b0b11fe8d3ac24ae7b0214c GIT binary patch literal 2232 zcmbW!`9IYA7r=4S$Xbe9k)npCkjhSRNV!>(EXi7AmuQ3{%b<`{8iS-l))Bh+R)#+B zP*M$M$dY|B*~StQ6Y1*y3E%VEc|D##okKRaIbmVP%M;8KMsRZvJWnL($Px~FXc3fT z2_F8$%S4xpXZ?w8?ti+G%Y{Jq)gI{O65zhN?@`fERobg08!r2QkC21jC^lNziETRI zlwFeRCjC@yEQ++AA zVlc1KMHvU_+f!jH;ZbPFu6vskbqg|n5S4f+>l>tRYwc zZm_;Lq44vEDzFH8mA~Xj1H9$$K9li$q)+8E+&xc27*l~FWLXUhYbGqdy~;=4OZ&2q zwW^`D{W^lDFV2Cm@~2qFlT@g($})Z1RR)(T%Bx3G^C1YND(`DFCNEJy&*R_yg_vO=a?;MO!x;R653u6Hm#b~6;_s=0V zslVbzd?Vbj@rhE#&qItvH-m4H04l<-1|OV^kO1MP{}Rv!v%t;vY#)@A@( zGe^pcH3MR=^iFC$IR`y2{dE`l7^pJu5t}wR1L6L23l3k*Au}JhMM#bb)I76-L)WK) zV>7UDt(FE)51N)teq*4IJCjGYU7m(2H_4UF?`U8Wu`EF(eunm+8_lm6jG=yiub!HR5jvg-yx+@~bW{#zFEvv?)=M})IXGBqImp$4*lT9X=%0nb;Wj2mH z33#83zO=jVPOB-ZrJX>$# zT8~D_LY#ouHhA^V*b4(44q7n%-M`x*1to^g{_)_~b&DX-)&`gMDQHew)FY{HeJ)Y? zQ&5rJu}Rw65D5?+O>{0uBLm}H{+=L1sI9HCQhhxNqNHI1%7IQurqOAYWs_iQKGd7~ zrXDqD-`p4EK|$fy56H#W)qzV%-JnVED6lfrHDyHT@GPf*weV~bR;>NsJC@XgI8Gav zX-$EpJ+X~hMRn-$TIzqEe7pHejU*k$k|Sg;g-wG*dNWlwMinXb;O&m?l|Vcq)N2p> zRUtQ_(XVfL65@U3I45n(!B(2oG(jB!-Uj9AG@bikT=$^hm@*Sp6DXZzg*-@5QVIA% z7zZ4Ueo=Dn0|;u0c34!5fS0PL&s(o_bYETd6~7P@?9^rj{yCV3sK+E!F!^zC)4BWl z+0+LhehoTIvz>-;lH2>YQwTx!~mX&N~6>$_0-+trX*0Y_^ ztaJH~N9LrIUoR>$;L&nyZ*%|)wx&5bCHt8NTZ(MyKaRS%_4m*}3bd8yc`U>y9Nxqsy&pH?DeE z&?Q)zd$Qp>qb0u2_X(N~7%GmScEeE>dbwaC8;v?W?VSsbhwLW;Un8}LfTus+NKLsN z{`avzAxnn}_FnoTkIK5if644`ERGF4Jb(F~IeP=`sL3?V&>TXfYdGUSKJIwVkw!u> z=q45Nr&y0dn^!uqC9(?ji(X(((2LLp=U)5Q57I%J5&qI@0}Etse(E``)`i}LMvw5F z8igSC$(v?xs$lVEW(wzB5r}2~kg3+pKuu#;|MRZ5lXg1q??R4t{&Mh>5x#!iyQsU}VPC48tK3u;%_MFAe#L6)5pB7d2tz;i_E)Q6>pfoD7pblq4MGc8 z<%2t$P->vny|P6-Mf(&nI!mJwk}4_QVb5( zoF7!lSOtc- z7~b7b)wG2KA~9AvPj5?rrztyMtbi8^-HIjM?W3Wo;<-AzPZnwPD5_ETcwt9-j?nJa zUNf2#oOX|kH5OY*EHv|?s1VgaMLG$R?icol$FD&SCSVoe&4X-DtLJZOCIR0Zy2V_> z!8#scQDs+o(018CEt%EcOerb})#PHX__)J|)7BvG?v3Lo@=5Ta-i=yH6+_|;(sIJj zeqlUse=h~LlHh>c25HaZ6M8;F$MNF06|8o8tGE4XxAq-*EM+W>T%_+0uf4jAotj!q z4V@xES*U1&@$`E5+Kw9zZCJ+a-sc_`pC*CcYYUCF2|JNzWM=aI?JO)>T`^>8kp%n^ zmO&?sH^XZwE%qXwg$czd&>373%sRYmID+RuWV=Y9d?E*gzh|0u5jeni)^K}Q5(oYT DDM3hl literal 0 HcmV?d00001 diff --git a/motiondiff_modules/mGPT/data/std.npy b/motiondiff_modules/mGPT/data/std.npy new file mode 100644 index 0000000000000000000000000000000000000000..c0ae831306536a16da5c499325588eb521fd3255 GIT binary patch literal 2232 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I$7X2v?2ItsN4WCJdt@VQ%3?mF1JEOYOy(Q|{-nFfagRfH<-{YqQ4PQ~vZ zrAJsel-HfL@36dVKT3~=!)Q7f{`r6*)~K?OX^Q Tensor: + dims = batch[0].dim() + max_size = [max([b.size(i) for b in batch]) for i in range(dims)] + size = (len(batch),) + tuple(max_size) + canvas = batch[0].new_zeros(size=size) + for i, b in enumerate(batch): + sub_tensor = canvas[i] + for d in range(dims): + sub_tensor = sub_tensor.narrow(d, 0, b.size(d)) + sub_tensor.add_(b) + return canvas + + +def collate_datastruct_and_text(lst_elements: List) -> Dict: + collate_datastruct = lst_elements[0]["datastruct"].transforms.collate + + batch = { + # Collate with padding for the datastruct + "datastruct": collate_datastruct([x["datastruct"] for x in lst_elements]), + # Collate normally for the length + "length": [x["length"] for x in lst_elements], + # Collate the text + "text": [x["text"] for x in lst_elements]} + + # add keyid for example + otherkeys = [x for x in lst_elements[0].keys() if x not in batch] + for key in otherkeys: + batch[key] = [x[key] for x in lst_elements] + + return batch + +def collate_length_and_text(lst_elements: List) -> Dict: + + batch = { + "length_0": [x["length_0"] for x in lst_elements], + "length_1": [x["length_1"] for x in lst_elements], + "length_transition": [x["length_transition"] for x in lst_elements], + "length_1_with_transition": [x["length_1_with_transition"] for x in lst_elements], + "text_0": [x["text_0"] for x in lst_elements], + "text_1": [x["text_1"] for x in lst_elements] + } + + return batch + +def collate_pairs_and_text(lst_elements: List, ) -> Dict: + if 'features_0' not in lst_elements[0]: # test set + collate_datastruct = lst_elements[0]["datastruct"].transforms.collate + batch = {"datastruct": collate_datastruct([x["datastruct"] for x in lst_elements]), + "length_0": [x["length_0"] for x in lst_elements], + "length_1": [x["length_1"] for x in lst_elements], + "length_transition": [x["length_transition"] for x in lst_elements], + "length_1_with_transition": [x["length_1_with_transition"] for x in lst_elements], + "text_0": [x["text_0"] for x in lst_elements], + "text_1": [x["text_1"] for x in lst_elements] + } + + else: + batch = {"motion_feats_0": collate_tensor_with_padding([el["features_0"] for el in lst_elements]), + "motion_feats_1": collate_tensor_with_padding([el["features_1"] for el in lst_elements]), + "motion_feats_1_with_transition": collate_tensor_with_padding([el["features_1_with_transition"] for el in lst_elements]), + "length_0": [x["length_0"] for x in lst_elements], + "length_1": [x["length_1"] for x in lst_elements], + "length_transition": [x["length_transition"] for x in lst_elements], + "length_1_with_transition": [x["length_1_with_transition"] for x in lst_elements], + "text_0": [x["text_0"] for x in lst_elements], + "text_1": [x["text_1"] for x in lst_elements] + } + return batch + + +def collate_text_and_length(lst_elements: Dict) -> Dict: + batch = {"length": [x["length"] for x in lst_elements], + "text": [x["text"] for x in lst_elements]} + + # add keyid for example + otherkeys = [x for x in lst_elements[0].keys() if x not in batch and x != "datastruct"] + for key in otherkeys: + batch[key] = [x[key] for x in lst_elements] + return batch diff --git a/motiondiff_modules/mGPT/data/tools/easyconvert.py b/motiondiff_modules/mGPT/data/tools/easyconvert.py new file mode 100644 index 0000000..3649a93 --- /dev/null +++ b/motiondiff_modules/mGPT/data/tools/easyconvert.py @@ -0,0 +1,72 @@ +from .geometry import * + +def nfeats_of(rottype): + if rottype in ["rotvec", "axisangle"]: + return 3 + elif rottype in ["rotquat", "quaternion"]: + return 4 + elif rottype in ["rot6d", "6drot", "rotation6d"]: + return 6 + elif rottype in ["rotmat"]: + return 9 + else: + return TypeError("This rotation type doesn't have features.") + + +def axis_angle_to(newtype, rotations): + if newtype in ["matrix"]: + rotations = axis_angle_to_matrix(rotations) + return rotations + elif newtype in ["rotmat"]: + rotations = axis_angle_to_matrix(rotations) + rotations = matrix_to("rotmat", rotations) + return rotations + elif newtype in ["rot6d", "6drot", "rotation6d"]: + rotations = axis_angle_to_matrix(rotations) + rotations = matrix_to("rot6d", rotations) + return rotations + elif newtype in ["rotquat", "quaternion"]: + rotations = axis_angle_to_quaternion(rotations) + return rotations + elif newtype in ["rotvec", "axisangle"]: + return rotations + else: + raise NotImplementedError + + +def matrix_to(newtype, rotations): + if newtype in ["matrix"]: + return rotations + if newtype in ["rotmat"]: + rotations = rotations.reshape((*rotations.shape[:-2], 9)) + return rotations + elif newtype in ["rot6d", "6drot", "rotation6d"]: + rotations = matrix_to_rotation_6d(rotations) + return rotations + elif newtype in ["rotquat", "quaternion"]: + rotations = matrix_to_quaternion(rotations) + return rotations + elif newtype in ["rotvec", "axisangle"]: + rotations = matrix_to_axis_angle(rotations) + return rotations + else: + raise NotImplementedError + + +def to_matrix(oldtype, rotations): + if oldtype in ["matrix"]: + return rotations + if oldtype in ["rotmat"]: + rotations = rotations.reshape((*rotations.shape[:-2], 3, 3)) + return rotations + elif oldtype in ["rot6d", "6drot", "rotation6d"]: + rotations = rotation_6d_to_matrix(rotations) + return rotations + elif oldtype in ["rotquat", "quaternion"]: + rotations = quaternion_to_matrix(rotations) + return rotations + elif oldtype in ["rotvec", "axisangle"]: + rotations = axis_angle_to_matrix(rotations) + return rotations + else: + raise NotImplementedError diff --git a/motiondiff_modules/mGPT/data/tools/geometry.py b/motiondiff_modules/mGPT/data/tools/geometry.py new file mode 100644 index 0000000..e6eafa2 --- /dev/null +++ b/motiondiff_modules/mGPT/data/tools/geometry.py @@ -0,0 +1,566 @@ +# Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. +# Check PYTORCH3D_LICENCE before use + +import functools +from typing import Optional + +import torch +import torch.nn.functional as F + + +""" +The transformation matrices returned from the functions in this file assume +the points on which the transformation will be applied are column vectors. +i.e. the R matrix is structured as + + R = [ + [Rxx, Rxy, Rxz], + [Ryx, Ryy, Ryz], + [Rzx, Rzy, Rzz], + ] # (3, 3) + +This matrix can be applied to column vectors by post multiplication +by the points e.g. + + points = [[0], [1], [2]] # (3 x 1) xyz coordinates of a point + transformed_points = R * points + +To apply the same matrix to points which are row vectors, the R matrix +can be transposed and pre multiplied by the points: + +e.g. + points = [[0, 1, 2]] # (1 x 3) xyz coordinates of a point + transformed_points = points * R.transpose(1, 0) +""" + + +# Added +def matrix_of_angles(cos, sin, inv=False, dim=2): + assert dim in [2, 3] + sin = -sin if inv else sin + if dim == 2: + row1 = torch.stack((cos, -sin), axis=-1) + row2 = torch.stack((sin, cos), axis=-1) + return torch.stack((row1, row2), axis=-2) + elif dim == 3: + row1 = torch.stack((cos, -sin, 0*cos), axis=-1) + row2 = torch.stack((sin, cos, 0*cos), axis=-1) + row3 = torch.stack((0*sin, 0*cos, 1+0*cos), axis=-1) + return torch.stack((row1, row2, row3),axis=-2) + + +def quaternion_to_matrix(quaternions): + """ + Convert rotations given as quaternions to rotation matrices. + + Args: + quaternions: quaternions with real part first, + as tensor of shape (..., 4). + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + r, i, j, k = torch.unbind(quaternions, -1) + two_s = 2.0 / (quaternions * quaternions).sum(-1) + + o = torch.stack( + ( + 1 - two_s * (j * j + k * k), + two_s * (i * j - k * r), + two_s * (i * k + j * r), + two_s * (i * j + k * r), + 1 - two_s * (i * i + k * k), + two_s * (j * k - i * r), + two_s * (i * k - j * r), + two_s * (j * k + i * r), + 1 - two_s * (i * i + j * j), + ), + -1, + ) + return o.reshape(quaternions.shape[:-1] + (3, 3)) + + +def _copysign(a, b): + """ + Return a tensor where each element has the absolute value taken from the, + corresponding element of a, with sign taken from the corresponding + element of b. This is like the standard copysign floating-point operation, + but is not careful about negative 0 and NaN. + + Args: + a: source tensor. + b: tensor whose signs will be used, of the same shape as a. + + Returns: + Tensor of the same shape as a with the signs of b. + """ + signs_differ = (a < 0) != (b < 0) + return torch.where(signs_differ, -a, a) + + +def _sqrt_positive_part(x): + """ + Returns torch.sqrt(torch.max(0, x)) + but with a zero subgradient where x is 0. + """ + ret = torch.zeros_like(x) + positive_mask = x > 0 + ret[positive_mask] = torch.sqrt(x[positive_mask]) + return ret + + +def matrix_to_quaternion(matrix): + """ + Convert rotations given as rotation matrices to quaternions. + + Args: + matrix: Rotation matrices as tensor of shape (..., 3, 3). + + Returns: + quaternions with real part first, as tensor of shape (..., 4). + """ + if matrix.size(-1) != 3 or matrix.size(-2) != 3: + raise ValueError(f"Invalid rotation matrix shape f{matrix.shape}.") + m00 = matrix[..., 0, 0] + m11 = matrix[..., 1, 1] + m22 = matrix[..., 2, 2] + o0 = 0.5 * _sqrt_positive_part(1 + m00 + m11 + m22) + x = 0.5 * _sqrt_positive_part(1 + m00 - m11 - m22) + y = 0.5 * _sqrt_positive_part(1 - m00 + m11 - m22) + z = 0.5 * _sqrt_positive_part(1 - m00 - m11 + m22) + o1 = _copysign(x, matrix[..., 2, 1] - matrix[..., 1, 2]) + o2 = _copysign(y, matrix[..., 0, 2] - matrix[..., 2, 0]) + o3 = _copysign(z, matrix[..., 1, 0] - matrix[..., 0, 1]) + return torch.stack((o0, o1, o2, o3), -1) + + +def _axis_angle_rotation(axis: str, angle): + """ + Return the rotation matrices for one of the rotations about an axis + of which Euler angles describe, for each value of the angle given. + + Args: + axis: Axis label "X" or "Y or "Z". + angle: any shape tensor of Euler angles in radians + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + + cos = torch.cos(angle) + sin = torch.sin(angle) + one = torch.ones_like(angle) + zero = torch.zeros_like(angle) + + if axis == "X": + R_flat = (one, zero, zero, zero, cos, -sin, zero, sin, cos) + if axis == "Y": + R_flat = (cos, zero, sin, zero, one, zero, -sin, zero, cos) + if axis == "Z": + R_flat = (cos, -sin, zero, sin, cos, zero, zero, zero, one) + + return torch.stack(R_flat, -1).reshape(angle.shape + (3, 3)) + + +def euler_angles_to_matrix(euler_angles, convention: str): + """ + Convert rotations given as Euler angles in radians to rotation matrices. + + Args: + euler_angles: Euler angles in radians as tensor of shape (..., 3). + convention: Convention string of three uppercase letters from + {"X", "Y", and "Z"}. + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + if euler_angles.dim() == 0 or euler_angles.shape[-1] != 3: + raise ValueError("Invalid input euler angles.") + if len(convention) != 3: + raise ValueError("Convention must have 3 letters.") + if convention[1] in (convention[0], convention[2]): + raise ValueError(f"Invalid convention {convention}.") + for letter in convention: + if letter not in ("X", "Y", "Z"): + raise ValueError(f"Invalid letter {letter} in convention string.") + matrices = map(_axis_angle_rotation, convention, torch.unbind(euler_angles, -1)) + return functools.reduce(torch.matmul, matrices) + + +def _angle_from_tan( + axis: str, other_axis: str, data, horizontal: bool, tait_bryan: bool +): + """ + Extract the first or third Euler angle from the two members of + the matrix which are positive constant times its sine and cosine. + + Args: + axis: Axis label "X" or "Y or "Z" for the angle we are finding. + other_axis: Axis label "X" or "Y or "Z" for the middle axis in the + convention. + data: Rotation matrices as tensor of shape (..., 3, 3). + horizontal: Whether we are looking for the angle for the third axis, + which means the relevant entries are in the same row of the + rotation matrix. If not, they are in the same column. + tait_bryan: Whether the first and third axes in the convention differ. + + Returns: + Euler Angles in radians for each matrix in data as a tensor + of shape (...). + """ + + i1, i2 = {"X": (2, 1), "Y": (0, 2), "Z": (1, 0)}[axis] + if horizontal: + i2, i1 = i1, i2 + even = (axis + other_axis) in ["XY", "YZ", "ZX"] + if horizontal == even: + return torch.atan2(data[..., i1], data[..., i2]) + if tait_bryan: + return torch.atan2(-data[..., i2], data[..., i1]) + return torch.atan2(data[..., i2], -data[..., i1]) + + +def _index_from_letter(letter: str): + if letter == "X": + return 0 + if letter == "Y": + return 1 + if letter == "Z": + return 2 + + +def matrix_to_euler_angles(matrix, convention: str): + """ + Convert rotations given as rotation matrices to Euler angles in radians. + + Args: + matrix: Rotation matrices as tensor of shape (..., 3, 3). + convention: Convention string of three uppercase letters. + + Returns: + Euler angles in radians as tensor of shape (..., 3). + """ + if len(convention) != 3: + raise ValueError("Convention must have 3 letters.") + if convention[1] in (convention[0], convention[2]): + raise ValueError(f"Invalid convention {convention}.") + for letter in convention: + if letter not in ("X", "Y", "Z"): + raise ValueError(f"Invalid letter {letter} in convention string.") + if matrix.size(-1) != 3 or matrix.size(-2) != 3: + raise ValueError(f"Invalid rotation matrix shape f{matrix.shape}.") + i0 = _index_from_letter(convention[0]) + i2 = _index_from_letter(convention[2]) + tait_bryan = i0 != i2 + if tait_bryan: + central_angle = torch.asin( + matrix[..., i0, i2] * (-1.0 if i0 - i2 in [-1, 2] else 1.0) + ) + else: + central_angle = torch.acos(matrix[..., i0, i0]) + + o = ( + _angle_from_tan( + convention[0], convention[1], matrix[..., i2], False, tait_bryan + ), + central_angle, + _angle_from_tan( + convention[2], convention[1], matrix[..., i0, :], True, tait_bryan + ), + ) + return torch.stack(o, -1) + + +def random_quaternions( + n: int, dtype: Optional[torch.dtype] = None, device=None, requires_grad=False +): + """ + Generate random quaternions representing rotations, + i.e. versors with nonnegative real part. + + Args: + n: Number of quaternions in a batch to return. + dtype: Type to return. + device: Desired device of returned tensor. Default: + uses the current device for the default tensor type. + requires_grad: Whether the resulting tensor should have the gradient + flag set. + + Returns: + Quaternions as tensor of shape (N, 4). + """ + o = torch.randn((n, 4), dtype=dtype, device=device, requires_grad=requires_grad) + s = (o * o).sum(1) + o = o / _copysign(torch.sqrt(s), o[:, 0])[:, None] + return o + + +def random_rotations( + n: int, dtype: Optional[torch.dtype] = None, device=None, requires_grad=False +): + """ + Generate random rotations as 3x3 rotation matrices. + + Args: + n: Number of rotation matrices in a batch to return. + dtype: Type to return. + device: Device of returned tensor. Default: if None, + uses the current device for the default tensor type. + requires_grad: Whether the resulting tensor should have the gradient + flag set. + + Returns: + Rotation matrices as tensor of shape (n, 3, 3). + """ + quaternions = random_quaternions( + n, dtype=dtype, device=device, requires_grad=requires_grad + ) + return quaternion_to_matrix(quaternions) + + +def random_rotation( + dtype: Optional[torch.dtype] = None, device=None, requires_grad=False +): + """ + Generate a single random 3x3 rotation matrix. + + Args: + dtype: Type to return + device: Device of returned tensor. Default: if None, + uses the current device for the default tensor type + requires_grad: Whether the resulting tensor should have the gradient + flag set + + Returns: + Rotation matrix as tensor of shape (3, 3). + """ + return random_rotations(1, dtype, device, requires_grad)[0] + + +def standardize_quaternion(quaternions): + """ + Convert a unit quaternion to a standard form: one in which the real + part is non negative. + + Args: + quaternions: Quaternions with real part first, + as tensor of shape (..., 4). + + Returns: + Standardized quaternions as tensor of shape (..., 4). + """ + return torch.where(quaternions[..., 0:1] < 0, -quaternions, quaternions) + + +def quaternion_raw_multiply(a, b): + """ + Multiply two quaternions. + Usual torch rules for broadcasting apply. + + Args: + a: Quaternions as tensor of shape (..., 4), real part first. + b: Quaternions as tensor of shape (..., 4), real part first. + + Returns: + The product of a and b, a tensor of quaternions shape (..., 4). + """ + aw, ax, ay, az = torch.unbind(a, -1) + bw, bx, by, bz = torch.unbind(b, -1) + ow = aw * bw - ax * bx - ay * by - az * bz + ox = aw * bx + ax * bw + ay * bz - az * by + oy = aw * by - ax * bz + ay * bw + az * bx + oz = aw * bz + ax * by - ay * bx + az * bw + return torch.stack((ow, ox, oy, oz), -1) + + +def quaternion_multiply(a, b): + """ + Multiply two quaternions representing rotations, returning the quaternion + representing their composition, i.e. the versor with nonnegative real part. + Usual torch rules for broadcasting apply. + + Args: + a: Quaternions as tensor of shape (..., 4), real part first. + b: Quaternions as tensor of shape (..., 4), real part first. + + Returns: + The product of a and b, a tensor of quaternions of shape (..., 4). + """ + ab = quaternion_raw_multiply(a, b) + return standardize_quaternion(ab) + + +def quaternion_invert(quaternion): + """ + Given a quaternion representing rotation, get the quaternion representing + its inverse. + + Args: + quaternion: Quaternions as tensor of shape (..., 4), with real part + first, which must be versors (unit quaternions). + + Returns: + The inverse, a tensor of quaternions of shape (..., 4). + """ + + return quaternion * quaternion.new_tensor([1, -1, -1, -1]) + + +def quaternion_apply(quaternion, point): + """ + Apply the rotation given by a quaternion to a 3D point. + Usual torch rules for broadcasting apply. + + Args: + quaternion: Tensor of quaternions, real part first, of shape (..., 4). + point: Tensor of 3D points of shape (..., 3). + + Returns: + Tensor of rotated points of shape (..., 3). + """ + if point.size(-1) != 3: + raise ValueError(f"Points are not in 3D, f{point.shape}.") + real_parts = point.new_zeros(point.shape[:-1] + (1,)) + point_as_quaternion = torch.cat((real_parts, point), -1) + out = quaternion_raw_multiply( + quaternion_raw_multiply(quaternion, point_as_quaternion), + quaternion_invert(quaternion), + ) + return out[..., 1:] + + +def axis_angle_to_matrix(axis_angle): + """ + Convert rotations given as axis/angle to rotation matrices. + + Args: + axis_angle: Rotations given as a vector in axis angle form, + as a tensor of shape (..., 3), where the magnitude is + the angle turned anticlockwise in radians around the + vector's direction. + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + return quaternion_to_matrix(axis_angle_to_quaternion(axis_angle)) + + +def matrix_to_axis_angle(matrix): + """ + Convert rotations given as rotation matrices to axis/angle. + + Args: + matrix: Rotation matrices as tensor of shape (..., 3, 3). + + Returns: + Rotations given as a vector in axis angle form, as a tensor + of shape (..., 3), where the magnitude is the angle + turned anticlockwise in radians around the vector's + direction. + """ + return quaternion_to_axis_angle(matrix_to_quaternion(matrix)) + + +def axis_angle_to_quaternion(axis_angle): + """ + Convert rotations given as axis/angle to quaternions. + + Args: + axis_angle: Rotations given as a vector in axis angle form, + as a tensor of shape (..., 3), where the magnitude is + the angle turned anticlockwise in radians around the + vector's direction. + + Returns: + quaternions with real part first, as tensor of shape (..., 4). + """ + angles = torch.norm(axis_angle, p=2, dim=-1, keepdim=True) + half_angles = 0.5 * angles + eps = 1e-6 + small_angles = angles.abs() < eps + sin_half_angles_over_angles = torch.empty_like(angles) + sin_half_angles_over_angles[~small_angles] = ( + torch.sin(half_angles[~small_angles]) / angles[~small_angles] + ) + # for x small, sin(x/2) is about x/2 - (x/2)^3/6 + # so sin(x/2)/x is about 1/2 - (x*x)/48 + sin_half_angles_over_angles[small_angles] = ( + 0.5 - (angles[small_angles] * angles[small_angles]) / 48 + ) + quaternions = torch.cat( + [torch.cos(half_angles), axis_angle * sin_half_angles_over_angles], dim=-1 + ) + return quaternions + + +def quaternion_to_axis_angle(quaternions): + """ + Convert rotations given as quaternions to axis/angle. + + Args: + quaternions: quaternions with real part first, + as tensor of shape (..., 4). + + Returns: + Rotations given as a vector in axis angle form, as a tensor + of shape (..., 3), where the magnitude is the angle + turned anticlockwise in radians around the vector's + direction. + """ + norms = torch.norm(quaternions[..., 1:], p=2, dim=-1, keepdim=True) + half_angles = torch.atan2(norms, quaternions[..., :1]) + angles = 2 * half_angles + eps = 1e-6 + small_angles = angles.abs() < eps + sin_half_angles_over_angles = torch.empty_like(angles) + sin_half_angles_over_angles[~small_angles] = ( + torch.sin(half_angles[~small_angles]) / angles[~small_angles] + ) + # for x small, sin(x/2) is about x/2 - (x/2)^3/6 + # so sin(x/2)/x is about 1/2 - (x*x)/48 + sin_half_angles_over_angles[small_angles] = ( + 0.5 - (angles[small_angles] * angles[small_angles]) / 48 + ) + return quaternions[..., 1:] / sin_half_angles_over_angles + + +def rotation_6d_to_matrix(d6: torch.Tensor) -> torch.Tensor: + """ + Converts 6D rotation representation by Zhou et al. [1] to rotation matrix + using Gram--Schmidt orthogonalisation per Section B of [1]. + Args: + d6: 6D rotation representation, of size (*, 6) + + Returns: + batch of rotation matrices of size (*, 3, 3) + + [1] Zhou, Y., Barnes, C., Lu, J., Yang, J., & Li, H. + On the Continuity of Rotation Representations in Neural Networks. + IEEE Conference on Computer Vision and Pattern Recognition, 2019. + Retrieved from http://arxiv.org/abs/1812.07035 + """ + + a1, a2 = d6[..., :3], d6[..., 3:] + b1 = F.normalize(a1, dim=-1) + b2 = a2 - (b1 * a2).sum(-1, keepdim=True) * b1 + b2 = F.normalize(b2, dim=-1) + b3 = torch.cross(b1, b2, dim=-1) + return torch.stack((b1, b2, b3), dim=-2) + + +def matrix_to_rotation_6d(matrix: torch.Tensor) -> torch.Tensor: + """ + Converts rotation matrices to 6D rotation representation by Zhou et al. [1] + by dropping the last row. Note that 6D representation is not unique. + Args: + matrix: batch of rotation matrices of size (*, 3, 3) + + Returns: + 6D rotation representation, of size (*, 6) + + [1] Zhou, Y., Barnes, C., Lu, J., Yang, J., & Li, H. + On the Continuity of Rotation Representations in Neural Networks. + IEEE Conference on Computer Vision and Pattern Recognition, 2019. + Retrieved from http://arxiv.org/abs/1812.07035 + """ + return matrix[..., :2, :].clone().reshape(*matrix.size()[:-2], 6) diff --git a/motiondiff_modules/mGPT/data/tools/tensors.py b/motiondiff_modules/mGPT/data/tools/tensors.py new file mode 100644 index 0000000..6bcc051 --- /dev/null +++ b/motiondiff_modules/mGPT/data/tools/tensors.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +# Max-Planck-Gesellschaft zur Förderung der Wissenschaften e.V. (MPG) is +# holder of all proprietary rights on this computer program. +# You can only use this computer program if you have closed +# a license agreement with MPG or you get the right to use the computer +# program from someone who is authorized to grant you that right. +# Any use of the computer program without a valid license is prohibited and +# liable to prosecution. +# +# Copyright©2020 Max-Planck-Gesellschaft zur Förderung +# der Wissenschaften e.V. (MPG). acting on behalf of its Max Planck Institute +# for Intelligent Systems. All rights reserved. +# +# Contact: ps-license@tuebingen.mpg.de + +from typing import List, Dict +import torch +from torch import Tensor + + +def lengths_to_mask(lengths: List[int], device: torch.device) -> Tensor: + lengths = torch.tensor(lengths, device=device) + max_len = max(lengths) + mask = torch.arange(max_len, device=device).expand(len(lengths), max_len) < lengths.unsqueeze(1) + return mask diff --git a/motiondiff_modules/mGPT/data/transforms/__init__.py b/motiondiff_modules/mGPT/data/transforms/__init__.py new file mode 100644 index 0000000..394dfc5 --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/__init__.py @@ -0,0 +1,15 @@ +from .base import Transform +from .smpl import SMPLTransform +from .xyz import XYZTransform + +# rots2rfeats +from .rots2rfeats import Rots2Rfeats +from .rots2rfeats import Globalvelandy + +# rots2joints +from .rots2joints import Rots2Joints +from .rots2joints import SMPLH, SMPLX + +# joints2jfeats +from .joints2jfeats import Joints2Jfeats +from .joints2jfeats import Rifke diff --git a/motiondiff_modules/mGPT/data/transforms/base.py b/motiondiff_modules/mGPT/data/transforms/base.py new file mode 100644 index 0000000..1c60a60 --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/base.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- + +# Max-Planck-Gesellschaft zur Förderung der Wissenschaften e.V. (MPG) is +# holder of all proprietary rights on this computer program. +# You can only use this computer program if you have closed +# a license agreement with MPG or you get the right to use the computer +# program from someone who is authorized to grant you that right. +# Any use of the computer program without a valid license is prohibited and +# liable to prosecution. +# +# Copyright©2020 Max-Planck-Gesellschaft zur Förderung +# der Wissenschaften e.V. (MPG). acting on behalf of its Max Planck Institute +# for Intelligent Systems. All rights reserved. +# +# Contact: ps-license@tuebingen.mpg.de + +from dataclasses import dataclass, fields + + +class Transform: + + def collate(self, lst_datastruct): + from ..tools import collate_tensor_with_padding + example = lst_datastruct[0] + + def collate_or_none(key): + if example[key] is None: + return None + key_lst = [x[key] for x in lst_datastruct] + return collate_tensor_with_padding(key_lst) + + kwargs = {key: collate_or_none(key) for key in example.datakeys} + + return self.Datastruct(**kwargs) + + +# Inspired from SMPLX library +# need to define "datakeys" and transforms +@dataclass +class Datastruct: + + def __getitem__(self, key): + return getattr(self, key) + + def __setitem__(self, key, value): + self.__dict__[key] = value + + def get(self, key, default=None): + return getattr(self, key, default) + + def __iter__(self): + return self.keys() + + def keys(self): + keys = [t.name for t in fields(self)] + return iter(keys) + + def values(self): + values = [getattr(self, t.name) for t in fields(self)] + return iter(values) + + def items(self): + data = [(t.name, getattr(self, t.name)) for t in fields(self)] + return iter(data) + + def to(self, *args, **kwargs): + for key in self.datakeys: + if self[key] is not None: + self[key] = self[key].to(*args, **kwargs) + return self + + @property + def device(self): + return self[self.datakeys[0]].device + + def detach(self): + + def detach_or_none(tensor): + if tensor is not None: + return tensor.detach() + return None + + kwargs = {key: detach_or_none(self[key]) for key in self.datakeys} + return self.transforms.Datastruct(**kwargs) diff --git a/motiondiff_modules/mGPT/data/transforms/identity.py b/motiondiff_modules/mGPT/data/transforms/identity.py new file mode 100644 index 0000000..ec12e7f --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/identity.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- + +# Max-Planck-Gesellschaft zur Förderung der Wissenschaften e.V. (MPG) is +# holder of all proprietary rights on this computer program. +# You can only use this computer program if you have closed +# a license agreement with MPG or you get the right to use the computer +# program from someone who is authorized to grant you that right. +# Any use of the computer program without a valid license is prohibited and +# liable to prosecution. +# +# Copyright©2020 Max-Planck-Gesellschaft zur Förderung +# der Wissenschaften e.V. (MPG). acting on behalf of its Max Planck Institute +# for Intelligent Systems. All rights reserved. +# +# Contact: ps-license@tuebingen.mpg.de + +from typing import Optional +from torch import Tensor + +from .base import Datastruct, dataclass, Transform + + +class IdentityTransform(Transform): + def __init__(self, **kwargs): + return + + def Datastruct(self, **kwargs): + return IdentityDatastruct(**kwargs) + + def __repr__(self): + return "IdentityTransform()" + + +@dataclass +class IdentityDatastruct(Datastruct): + transforms: IdentityTransform + + features: Optional[Tensor] = None + + def __post_init__(self): + self.datakeys = ["features"] + + def __len__(self): + return len(self.rfeats) diff --git a/motiondiff_modules/mGPT/data/transforms/joints2jfeats/__init__.py b/motiondiff_modules/mGPT/data/transforms/joints2jfeats/__init__.py new file mode 100644 index 0000000..0a924e8 --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/joints2jfeats/__init__.py @@ -0,0 +1,2 @@ +from .base import Joints2Jfeats +from .rifke import Rifke diff --git a/motiondiff_modules/mGPT/data/transforms/joints2jfeats/base.py b/motiondiff_modules/mGPT/data/transforms/joints2jfeats/base.py new file mode 100644 index 0000000..03d6f5f --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/joints2jfeats/base.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- + +# Max-Planck-Gesellschaft zur Förderung der Wissenschaften e.V. (MPG) is +# holder of all proprietary rights on this computer program. +# You can only use this computer program if you have closed +# a license agreement with MPG or you get the right to use the computer +# program from someone who is authorized to grant you that right. +# Any use of the computer program without a valid license is prohibited and +# liable to prosecution. +# +# Copyright©2020 Max-Planck-Gesellschaft zur Förderung +# der Wissenschaften e.V. (MPG). acting on behalf of its Max Planck Institute +# for Intelligent Systems. All rights reserved. +# +# Contact: ps-license@tuebingen.mpg.de + +from typing import Optional + +import torch +from torch import Tensor, nn +from pathlib import Path +import os + + +class Joints2Jfeats(nn.Module): + + def __init__(self, + path: Optional[str] = None, + normalization: bool = False, + eps: float = 1e-12, + **kwargs) -> None: + if normalization and path is None: + raise TypeError( + "You should provide a path if normalization is on.") + + super().__init__() + self.normalization = normalization + self.eps = eps + # workaround for cluster local/sync + if path is not None: + # rel_p = path.split('/') + # rel_p = rel_p[rel_p.index('deps'):] + # rel_p = '/'.join(rel_p) + pass + if normalization: + mean_path = Path(path) / "jfeats_mean.pt" + std_path = Path(path) / "jfeats_std.pt" + self.register_buffer('mean', torch.load(mean_path)) + self.register_buffer('std', torch.load(std_path)) + + def normalize(self, features: Tensor) -> Tensor: + if self.normalization: + features = (features - self.mean) / (self.std + self.eps) + return features + + def unnormalize(self, features: Tensor) -> Tensor: + if self.normalization: + features = features * self.std + self.mean + return features diff --git a/motiondiff_modules/mGPT/data/transforms/joints2jfeats/rifke.py b/motiondiff_modules/mGPT/data/transforms/joints2jfeats/rifke.py new file mode 100644 index 0000000..e6528f3 --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/joints2jfeats/rifke.py @@ -0,0 +1,159 @@ +# -*- coding: utf-8 -*- + +# Max-Planck-Gesellschaft zur Förderung der Wissenschaften e.V. (MPG) is +# holder of all proprietary rights on this computer program. +# You can only use this computer program if you have closed +# a license agreement with MPG or you get the right to use the computer +# program from someone who is authorized to grant you that right. +# Any use of the computer program without a valid license is prohibited and +# liable to prosecution. +# +# Copyright©2020 Max-Planck-Gesellschaft zur Förderung +# der Wissenschaften e.V. (MPG). acting on behalf of its Max Planck Institute +# for Intelligent Systems. All rights reserved. +# +# Contact: ps-license@tuebingen.mpg.de + +from typing import Optional + +import torch +from einops import rearrange +from torch import Tensor +from .tools import get_forward_direction, get_floor, gaussian_filter1d # noqa +from motiondiff_modules.mGPT.utils.geometry_tools import matrix_of_angles +from .base import Joints2Jfeats + + +class Rifke(Joints2Jfeats): + + def __init__(self, + jointstype: str = "mmm", + path: Optional[str] = None, + normalization: bool = False, + forward_filter: bool = False, + **kwargs) -> None: + # + # if jointstype != "mmm": + # print("This function assume that the root is the first index") + # raise NotImplementedError("This jointstype is not implemented.") + + super().__init__(path=path, normalization=normalization) + self.jointstype = jointstype + self.forward_filter = forward_filter + + def forward(self, joints: Tensor) -> Tensor: + # Joints to rotation invariant poses (Holden et. al.) + # Similar function than fke2rifke in Language2Pose repository + # Adapted to pytorch + # Put the origin center of the root joint instead of the ground projection + poses = joints.clone() + poses[..., 1] -= get_floor(poses, jointstype=self.jointstype) + + translation = poses[..., 0, :].clone() + # Let the root have the Y translation --> gravity axis + root_y = translation[..., 1] + + # Trajectory => Translation without gravity axis (Y) + trajectory = translation[..., [0, 2]] + + # Delete the root joints of the poses + poses = poses[..., 1:, :] + + # Remove the trajectory of the poses + poses[..., [0, 2]] -= trajectory[..., None, :] + + # Compute the trajectory + vel_trajectory = torch.diff(trajectory, dim=-2) + # 0 for the first one => keep the dimentionality + vel_trajectory = torch.cat( + (0 * vel_trajectory[..., [0], :], vel_trajectory), dim=-2) + + # Compute the forward direction + forward = get_forward_direction(poses, jointstype=self.jointstype) + if self.forward_filter: + # Smoothing to remove high frequencies + forward = gaussian_filter1d(forward, 2) + # normalize again to get real directions + forward = torch.nn.functional.normalize(forward, dim=-1) + # changed this also for New pytorch + angles = torch.atan2(*(forward.transpose(0, -1))).transpose(0, -1) + vel_angles = torch.diff(angles, dim=-1) + # 0 for the first one => keep the dimentionality + vel_angles = torch.cat((0 * vel_angles[..., [0]], vel_angles), dim=-1) + + # Construct the inverse rotation matrix + sin, cos = forward[..., 0], forward[..., 1] + rotations_inv = matrix_of_angles(cos, sin, inv=True) + + # Rotate the poses + poses_local = torch.einsum("...lj,...jk->...lk", poses[..., [0, 2]], + rotations_inv) + poses_local = torch.stack( + (poses_local[..., 0], poses[..., 1], poses_local[..., 1]), axis=-1) + + # stack the xyz joints into feature vectors + poses_features = rearrange(poses_local, + "... joints xyz -> ... (joints xyz)") + + # Rotate the vel_trajectory + vel_trajectory_local = torch.einsum("...j,...jk->...k", vel_trajectory, + rotations_inv) + + # Stack things together + features = torch.cat((root_y[..., None], poses_features, + vel_angles[..., None], vel_trajectory_local), -1) + + # Normalize if needed + features = self.normalize(features) + return features + + def inverse(self, features: Tensor) -> Tensor: + features = self.unnormalize(features) + root_y, poses_features, vel_angles, vel_trajectory_local = self.extract( + features) + + # already have the good dimensionality + angles = torch.cumsum(vel_angles, dim=-1) + # First frame should be 0, but if infered it is better to ensure it + angles = angles - angles[..., [0]] + + cos, sin = torch.cos(angles), torch.sin(angles) + rotations = matrix_of_angles(cos, sin, inv=False) + + # Get back the poses + poses_local = rearrange(poses_features, + "... (joints xyz) -> ... joints xyz", + xyz=3) + + # Rotate the poses + poses = torch.einsum("...lj,...jk->...lk", poses_local[..., [0, 2]], + rotations) + poses = torch.stack( + (poses[..., 0], poses_local[..., 1], poses[..., 1]), axis=-1) + + # Rotate the vel_trajectory + vel_trajectory = torch.einsum("...j,...jk->...k", vel_trajectory_local, + rotations) + # Integrate the trajectory + # Already have the good dimensionality + trajectory = torch.cumsum(vel_trajectory, dim=-2) + # First frame should be 0, but if infered it is better to ensure it + trajectory = trajectory - trajectory[..., [0], :] + + # Add the root joints (which is still zero) + poses = torch.cat((0 * poses[..., [0], :], poses), -2) + + # put back the root joint y + poses[..., 0, 1] = root_y + + # Add the trajectory globally + poses[..., [0, 2]] += trajectory[..., None, :] + return poses + + def extract(self, features: Tensor): + root_y = features[..., 0] + poses_features = features[..., 1:-3] + vel_angles = features[..., -3] + vel_trajectory_local = features[..., -2:] + + return root_y, poses_features, vel_angles, vel_trajectory_local diff --git a/motiondiff_modules/mGPT/data/transforms/joints2jfeats/tools.py b/motiondiff_modules/mGPT/data/transforms/joints2jfeats/tools.py new file mode 100644 index 0000000..74f3b0b --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/joints2jfeats/tools.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- + +# Max-Planck-Gesellschaft zur Förderung der Wissenschaften e.V. (MPG) is +# holder of all proprietary rights on this computer program. +# You can only use this computer program if you have closed +# a license agreement with MPG or you get the right to use the computer +# program from someone who is authorized to grant you that right. +# Any use of the computer program without a valid license is prohibited and +# liable to prosecution. +# +# Copyright©2020 Max-Planck-Gesellschaft zur Förderung +# der Wissenschaften e.V. (MPG). acting on behalf of its Max Planck Institute +# for Intelligent Systems. All rights reserved. +# +# Contact: ps-license@tuebingen.mpg.de + +import torch +import torch.nn.functional as F + +from motiondiff_modules.mGPT.utils.joints import mmm_joints + +# Get the indexes of particular body part SMPLH case +# Feet +# LM, RM = smplh_joints.index("left_ankle"), smplh_joints.index("right_ankle") +# LF, RF = smplh_joints.index("left_foot"), smplh_joints.index("right_foot") +# # Shoulders +# LS, RS = smplh_joints.index("left_shoulder"), smplh_joints.index("right_shoulder") +# # Hips +# LH, RH = smplh_joints.index("left_hip"), smplh_joints.index("right_hip") + +# Get the indexes of particular body part +# Feet +LM, RM = mmm_joints.index("LMrot"), mmm_joints.index("RMrot") +LF, RF = mmm_joints.index("LF"), mmm_joints.index("RF") +# Shoulders +LS, RS = mmm_joints.index("LS"), mmm_joints.index("RS") +# Hips +LH, RH = mmm_joints.index("LH"), mmm_joints.index("RH") + + +def get_forward_direction(poses, jointstype="mmm"): + # assert jointstype == 'mmm' + across = poses[..., RH, :] - poses[..., LH, :] + poses[..., RS, :] - poses[ + ..., LS, :] + forward = torch.stack((-across[..., 2], across[..., 0]), axis=-1) + forward = torch.nn.functional.normalize(forward, dim=-1) + return forward + + +def get_floor(poses, jointstype="mmm"): + # assert jointstype == 'mmm' + ndim = len(poses.shape) + foot_heights = poses[..., (LM, LF, RM, RF), 1].min(-1).values + floor_height = softmin(foot_heights, softness=0.5, dim=-1) + # changed this thing Mathis version 1.11 pytorch + return floor_height[(ndim - 2) * [None]].transpose(0, -1) + + +def softmax(x, softness=1.0, dim=None): + maxi, mini = x.max(dim=dim).values, x.min(dim=dim).values + return maxi + torch.log(softness + torch.exp(mini - maxi)) + + +def softmin(x, softness=1.0, dim=0): + return -softmax(-x, softness=softness, dim=dim) + + +def gaussian_filter1d(_inputs, sigma, truncate=4.0): + # Code adapted/mixed from scipy library into pytorch + # https://github.com/scipy/scipy/blob/47bb6febaa10658c72962b9615d5d5aa2513fa3a/scipy/ndimage/filters.py#L211 + # and gaussian kernel + # https://github.com/scipy/scipy/blob/47bb6febaa10658c72962b9615d5d5aa2513fa3a/scipy/ndimage/filters.py#L179 + # Correspond to mode="nearest" and order = 0 + # But works batched + if len(_inputs.shape) == 2: + inputs = _inputs[None] + else: + inputs = _inputs + + sd = float(sigma) + radius = int(truncate * sd + 0.5) + sigma2 = sigma * sigma + x = torch.arange(-radius, + radius + 1, + device=inputs.device, + dtype=inputs.dtype) + phi_x = torch.exp(-0.5 / sigma2 * x**2) + phi_x = phi_x / phi_x.sum() + + # Conv1d weights + groups = inputs.shape[-1] + weights = torch.tile(phi_x, (groups, 1, 1)) + inputs = inputs.transpose(-1, -2) + outputs = F.conv1d(inputs, weights, padding="same", + groups=groups).transpose(-1, -2) + + return outputs.reshape(_inputs.shape) diff --git a/motiondiff_modules/mGPT/data/transforms/joints2rots/config.py b/motiondiff_modules/mGPT/data/transforms/joints2rots/config.py new file mode 100644 index 0000000..8670212 --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/joints2rots/config.py @@ -0,0 +1,119 @@ +import numpy as np +from motiondiff_modules.mGPT.utils.joints import mmm_joints, smplh2mmm_indexes + +# Map joints Name to SMPL joints idx +JOINT_MAP = { + 'MidHip': 0, + 'LHip': 1, + 'LKnee': 4, + 'LAnkle': 7, + 'LFoot': 10, + 'RHip': 2, + 'RKnee': 5, + 'RAnkle': 8, + 'RFoot': 11, + 'LShoulder': 16, + 'LElbow': 18, + 'LWrist': 20, + 'LHand': 22, + 'RShoulder': 17, + 'RElbow': 19, + 'RWrist': 21, + 'RHand': 23, + 'spine1': 3, + 'spine2': 6, + 'spine3': 9, + 'Neck': 12, + 'Head': 15, + 'LCollar': 13, + 'Rcollar': 14, + 'Nose': 24, + 'REye': 26, + 'LEye': 26, + 'REar': 27, + 'LEar': 28, + 'LHeel': 31, + 'RHeel': 34, + 'OP RShoulder': 17, + 'OP LShoulder': 16, + 'OP RHip': 2, + 'OP LHip': 1, + 'OP Neck': 12, +} + +mmm2smpl_correspondence = { + "root": "MidHip", + "BP": "spine1", + "BT": "spine3", + "BLN": "Neck", + "BUN": "Head", + "LS": "LShoulder", + "LE": "LElbow", + "LW": "LWrist", + "RS": "RShoulder", + "RE": "RElbow", + "RW": "RWrist", + "LH": "LHip", + "LK": "LKnee", + "LA": "LAnkle", + "LMrot": "LHeel", + "LF": "LFoot", + "RH": "RHip", + "RK": "RKnee", + "RA": "RAnkle", + "RMrot": "RHeel", + "RF": "RFoot" +} + +full_smpl_idx = range(24) +key_smpl_idx = [0, 1, 4, 7, 2, 5, 8, 17, 19, 21, 16, 18, 20] + +AMASS_JOINT_MAP = { + 'MidHip': 0, + 'LHip': 1, + 'LKnee': 4, + 'LAnkle': 7, + 'LFoot': 10, + 'RHip': 2, + 'RKnee': 5, + 'RAnkle': 8, + 'RFoot': 11, + 'LShoulder': 16, + 'LElbow': 18, + 'LWrist': 20, + 'RShoulder': 17, + 'RElbow': 19, + 'RWrist': 21, + 'spine1': 3, + 'spine2': 6, + 'spine3': 9, + 'Neck': 12, + 'Head': 15, + 'LCollar': 13, + 'Rcollar': 14, +} +amass_idx = range(22) +amass_smpl_idx = range(22) + +# cal mmm in smpl index +smpl2mmm_correspondence = { + val: key + for key, val in mmm2smpl_correspondence.items() +} +smpl2mmm_indexes = [JOINT_MAP[mmm2smpl_correspondence[x]] for x in mmm_joints] + +# cal mmm joints map +MMM_JOINT_MAP = { + val: JOINT_MAP[val] + for key, val in mmm2smpl_correspondence.items() +} + +# mmm_idx = range(21) +# mmm_smpl_dix = smpl2mmm_indexes +# mmm_smpl_dix = smplh2mmm_indexes +# todo - configable +SMPL_MODEL_DIR = "/apdcephfs/share_1227775/shingxchen/AIMotion/TMOSTData/deps/smpl_models/" +GMM_MODEL_DIR = "/apdcephfs/share_1227775/shingxchen/AIMotion/TMOSTData/deps/smpl_models/" +SMPL_MEAN_FILE = "/apdcephfs/share_1227775/shingxchen/AIMotion/TMOSTData/deps/smpl_models/neutral_smpl_mean_params.h5" +# for collsion +Part_Seg_DIR = "/apdcephfs/share_1227775/shingxchen/AIMotion/TMOSTData/deps/smpl_models/smplx_parts_segm.pkl" diff --git a/motiondiff_modules/mGPT/data/transforms/joints2rots/customloss.py b/motiondiff_modules/mGPT/data/transforms/joints2rots/customloss.py new file mode 100644 index 0000000..2c3c3a5 --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/joints2rots/customloss.py @@ -0,0 +1,217 @@ +import torch +import torch.nn.functional as F +import config + +# Guassian +def gmof(x, sigma): + """ + Geman-McClure error function + """ + x_squared = x ** 2 + sigma_squared = sigma ** 2 + return (sigma_squared * x_squared) / (sigma_squared + x_squared) + +# angle prior +def angle_prior(pose): + """ + Angle prior that penalizes unnatural bending of the knees and elbows + """ + # We subtract 3 because pose does not include the global rotation of the model + return torch.exp( + pose[:, [55 - 3, 58 - 3, 12 - 3, 15 - 3]] * torch.tensor([1., -1., -1, -1.], device=pose.device)) ** 2 + + +def perspective_projection(points, rotation, translation, + focal_length, camera_center): + """ + This function computes the perspective projection of a set of points. + Input: + points (bs, N, 3): 3D points + rotation (bs, 3, 3): Camera rotation + translation (bs, 3): Camera translation + focal_length (bs,) or scalar: Focal length + camera_center (bs, 2): Camera center + """ + batch_size = points.shape[0] + K = torch.zeros([batch_size, 3, 3], device=points.device) + K[:, 0, 0] = focal_length + K[:, 1, 1] = focal_length + K[:, 2, 2] = 1. + K[:, :-1, -1] = camera_center + + # Transform points + points = torch.einsum('bij,bkj->bki', rotation, points) + points = points + translation.unsqueeze(1) + + # Apply perspective distortion + projected_points = points / points[:, :, -1].unsqueeze(-1) + + # Apply camera intrinsics + projected_points = torch.einsum('bij,bkj->bki', K, projected_points) + + return projected_points[:, :, :-1] + + +def body_fitting_loss(body_pose, betas, model_joints, camera_t, camera_center, + joints_2d, joints_conf, pose_prior, + focal_length=5000, sigma=100, pose_prior_weight=4.78, + shape_prior_weight=5, angle_prior_weight=15.2, + output='sum'): + """ + Loss function for body fitting + """ + batch_size = body_pose.shape[0] + rotation = torch.eye(3, device=body_pose.device).unsqueeze(0).expand(batch_size, -1, -1) + + projected_joints = perspective_projection(model_joints, rotation, camera_t, + focal_length, camera_center) + + # Weighted robust reprojection error + reprojection_error = gmof(projected_joints - joints_2d, sigma) + reprojection_loss = (joints_conf ** 2) * reprojection_error.sum(dim=-1) + + # Pose prior loss + pose_prior_loss = (pose_prior_weight ** 2) * pose_prior(body_pose, betas) + + # Angle prior for knees and elbows + angle_prior_loss = (angle_prior_weight ** 2) * angle_prior(body_pose).sum(dim=-1) + + # Regularizer to prevent betas from taking large values + shape_prior_loss = (shape_prior_weight ** 2) * (betas ** 2).sum(dim=-1) + + total_loss = reprojection_loss.sum(dim=-1) + pose_prior_loss + angle_prior_loss + shape_prior_loss + + if output == 'sum': + return total_loss.sum() + elif output == 'reprojection': + return reprojection_loss + + +# --- get camera fitting loss ----- +def camera_fitting_loss(model_joints, camera_t, camera_t_est, camera_center, + joints_2d, joints_conf, + focal_length=5000, depth_loss_weight=100): + """ + Loss function for camera optimization. + """ + # Project model joints + batch_size = model_joints.shape[0] + rotation = torch.eye(3, device=model_joints.device).unsqueeze(0).expand(batch_size, -1, -1) + projected_joints = perspective_projection(model_joints, rotation, camera_t, + focal_length, camera_center) + + # get the indexed four + op_joints = ['OP RHip', 'OP LHip', 'OP RShoulder', 'OP LShoulder'] + op_joints_ind = [config.JOINT_MAP[joint] for joint in op_joints] + gt_joints = ['RHip', 'LHip', 'RShoulder', 'LShoulder'] + gt_joints_ind = [config.JOINT_MAP[joint] for joint in gt_joints] + + reprojection_error_op = (joints_2d[:, op_joints_ind] - + projected_joints[:, op_joints_ind]) ** 2 + reprojection_error_gt = (joints_2d[:, gt_joints_ind] - + projected_joints[:, gt_joints_ind]) ** 2 + + # Check if for each example in the batch all 4 OpenPose detections are valid, otherwise use the GT detections + # OpenPose joints are more reliable for this task, so we prefer to use them if possible + is_valid = (joints_conf[:, op_joints_ind].min(dim=-1)[0][:, None, None] > 0).float() + reprojection_loss = (is_valid * reprojection_error_op + (1 - is_valid) * reprojection_error_gt).sum(dim=(1, 2)) + + # Loss that penalizes deviation from depth estimate + depth_loss = (depth_loss_weight ** 2) * (camera_t[:, 2] - camera_t_est[:, 2]) ** 2 + + total_loss = reprojection_loss + depth_loss + return total_loss.sum() + + + + # #####--- body fitiing loss ----- +def body_fitting_loss_3d(body_pose, preserve_pose, + betas, model_joints, camera_translation, + j3d, pose_prior, + joints3d_conf, + sigma=100, pose_prior_weight=4.78*1.5, + shape_prior_weight=5.0, angle_prior_weight=15.2, + joint_loss_weight=500.0, + pose_preserve_weight=0.0, + use_collision=False, + model_vertices=None, model_faces=None, + search_tree=None, pen_distance=None, filter_faces=None, + collision_loss_weight=1000 + ): + """ + Loss function for body fitting + """ + batch_size = body_pose.shape[0] + + #joint3d_loss = (joint_loss_weight ** 2) * gmof((model_joints + camera_translation) - j3d, sigma).sum(dim=-1) + + joint3d_error = gmof((model_joints + camera_translation) - j3d, sigma) + + joint3d_loss_part = (joints3d_conf ** 2) * joint3d_error.sum(dim=-1) + joint3d_loss = (joint_loss_weight ** 2) * joint3d_loss_part + + # Pose prior loss + pose_prior_loss = (pose_prior_weight ** 2) * pose_prior(body_pose, betas) + # Angle prior for knees and elbows + angle_prior_loss = (angle_prior_weight ** 2) * angle_prior(body_pose).sum(dim=-1) + # Regularizer to prevent betas from taking large values + shape_prior_loss = (shape_prior_weight ** 2) * (betas ** 2).sum(dim=-1) + + collision_loss = 0.0 + # Calculate the loss due to interpenetration + if use_collision: + triangles = torch.index_select( + model_vertices, 1, + model_faces).view(batch_size, -1, 3, 3) + + with torch.no_grad(): + collision_idxs = search_tree(triangles) + + # Remove unwanted collisions + if filter_faces is not None: + collision_idxs = filter_faces(collision_idxs) + + if collision_idxs.ge(0).sum().item() > 0: + collision_loss = torch.sum(collision_loss_weight * pen_distance(triangles, collision_idxs)) + + pose_preserve_loss = (pose_preserve_weight ** 2) * ((body_pose - preserve_pose) ** 2).sum(dim=-1) + + total_loss = joint3d_loss + pose_prior_loss + angle_prior_loss + shape_prior_loss + collision_loss + pose_preserve_loss + + return total_loss.sum() + + +# #####--- get camera fitting loss ----- +def camera_fitting_loss_3d(model_joints, camera_t, camera_t_est, + j3d, joints_category="orig", depth_loss_weight=100.0): + """ + Loss function for camera optimization. + """ + model_joints = model_joints + camera_t + # # get the indexed four + # op_joints = ['OP RHip', 'OP LHip', 'OP RShoulder', 'OP LShoulder'] + # op_joints_ind = [config.JOINT_MAP[joint] for joint in op_joints] + # + # j3d_error_loss = (j3d[:, op_joints_ind] - + # model_joints[:, op_joints_ind]) ** 2 + + gt_joints = ['RHip', 'LHip', 'RShoulder', 'LShoulder'] + gt_joints_ind = [config.JOINT_MAP[joint] for joint in gt_joints] + + if joints_category=="orig": + select_joints_ind = [config.JOINT_MAP[joint] for joint in gt_joints] + elif joints_category=="AMASS": + select_joints_ind = [config.AMASS_JOINT_MAP[joint] for joint in gt_joints] + elif joints_category=="MMM": + select_joints_ind = [config.MMM_JOINT_MAP[joint] for joint in gt_joints] + else: + print("NO SUCH JOINTS CATEGORY!") + + j3d_error_loss = (j3d[:, select_joints_ind] - + model_joints[:, gt_joints_ind]) ** 2 + + # Loss that penalizes deviation from depth estimate + depth_loss = (depth_loss_weight**2) * (camera_t - camera_t_est)**2 + + total_loss = j3d_error_loss + depth_loss + return total_loss.sum() \ No newline at end of file diff --git a/motiondiff_modules/mGPT/data/transforms/joints2rots/prior.py b/motiondiff_modules/mGPT/data/transforms/joints2rots/prior.py new file mode 100644 index 0000000..d85debd --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/joints2rots/prior.py @@ -0,0 +1,229 @@ +# -*- coding: utf-8 -*- + +# Max-Planck-Gesellschaft zur Förderung der Wissenschaften e.V. (MPG) is +# holder of all proprietary rights on this computer program. +# You can only use this computer program if you have closed +# a license agreement with MPG or you get the right to use the computer +# program from someone who is authorized to grant you that right. +# Any use of the computer program without a valid license is prohibited and +# liable to prosecution. +# +# Copyright©2019 Max-Planck-Gesellschaft zur Förderung +# der Wissenschaften e.V. (MPG). acting on behalf of its Max Planck Institute +# for Intelligent Systems. All rights reserved. +# +# Contact: ps-license@tuebingen.mpg.de + +from __future__ import absolute_import +from __future__ import print_function +from __future__ import division + +import sys +import os + +import time +import pickle + +import numpy as np + +import torch +import torch.nn as nn + +DEFAULT_DTYPE = torch.float32 + + +def create_prior(prior_type, **kwargs): + if prior_type == 'gmm': + prior = MaxMixturePrior(**kwargs) + elif prior_type == 'l2': + return L2Prior(**kwargs) + elif prior_type == 'angle': + return SMPLifyAnglePrior(**kwargs) + elif prior_type == 'none' or prior_type is None: + # Don't use any pose prior + def no_prior(*args, **kwargs): + return 0.0 + prior = no_prior + else: + raise ValueError('Prior {}'.format(prior_type) + ' is not implemented') + return prior + + +class SMPLifyAnglePrior(nn.Module): + def __init__(self, dtype=torch.float32, **kwargs): + super(SMPLifyAnglePrior, self).__init__() + + # Indices for the roration angle of + # 55: left elbow, 90deg bend at -np.pi/2 + # 58: right elbow, 90deg bend at np.pi/2 + # 12: left knee, 90deg bend at np.pi/2 + # 15: right knee, 90deg bend at np.pi/2 + angle_prior_idxs = np.array([55, 58, 12, 15], dtype=np.int64) + angle_prior_idxs = torch.tensor(angle_prior_idxs, dtype=torch.long) + self.register_buffer('angle_prior_idxs', angle_prior_idxs) + + angle_prior_signs = np.array([1, -1, -1, -1], + dtype=np.float6432 if dtype == torch.float32 + else np.float6464) + angle_prior_signs = torch.tensor(angle_prior_signs, + dtype=dtype) + self.register_buffer('angle_prior_signs', angle_prior_signs) + + def forward(self, pose, with_global_pose=False): + ''' Returns the angle prior loss for the given pose + Args: + pose: (Bx[23 + 1] * 3) torch tensor with the axis-angle + representation of the rotations of the joints of the SMPL model. + Kwargs: + with_global_pose: Whether the pose vector also contains the global + orientation of the SMPL model. If not then the indices must be + corrected. + Returns: + A sze (B) tensor containing the angle prior loss for each element + in the batch. + ''' + angle_prior_idxs = self.angle_prior_idxs - (not with_global_pose) * 3 + return torch.exp(pose[:, angle_prior_idxs] * + self.angle_prior_signs).pow(2) + + +class L2Prior(nn.Module): + def __init__(self, dtype=DEFAULT_DTYPE, reduction='sum', **kwargs): + super(L2Prior, self).__init__() + + def forward(self, module_input, *args): + return torch.sum(module_input.pow(2)) + + +class MaxMixturePrior(nn.Module): + + def __init__(self, prior_folder='prior', + num_gaussians=6, dtype=DEFAULT_DTYPE, epsilon=1e-16, + use_merged=True, + **kwargs): + super(MaxMixturePrior, self).__init__() + + if dtype == DEFAULT_DTYPE: + np_dtype = np.float6432 + elif dtype == torch.float64: + np_dtype = np.float6464 + else: + print('Unknown float type {}, exiting!'.format(dtype)) + sys.exit(-1) + + self.num_gaussians = num_gaussians + self.epsilon = epsilon + self.use_merged = use_merged + gmm_fn = 'gmm_{:02d}.pkl'.format(num_gaussians) + + full_gmm_fn = os.path.join(prior_folder, gmm_fn) + if not os.path.exists(full_gmm_fn): + print('The path to the mixture prior "{}"'.format(full_gmm_fn) + + ' does not exist, exiting!') + sys.exit(-1) + + with open(full_gmm_fn, 'rb') as f: + gmm = pickle.load(f, encoding='latin1') + + if type(gmm) == dict: + means = gmm['means'].astype(np_dtype) + covs = gmm['covars'].astype(np_dtype) + weights = gmm['weights'].astype(np_dtype) + elif 'sklearn.mixture.gmm.GMM' in str(type(gmm)): + means = gmm.means_.astype(np_dtype) + covs = gmm.covars_.astype(np_dtype) + weights = gmm.weights_.astype(np_dtype) + else: + print('Unknown type for the prior: {}, exiting!'.format(type(gmm))) + sys.exit(-1) + + self.register_buffer('means', torch.tensor(means, dtype=dtype)) + + self.register_buffer('covs', torch.tensor(covs, dtype=dtype)) + + precisions = [np.linalg.inv(cov) for cov in covs] + precisions = np.stack(precisions).astype(np_dtype) + + self.register_buffer('precisions', + torch.tensor(precisions, dtype=dtype)) + + # The constant term: + sqrdets = np.array([(np.sqrt(np.linalg.det(c))) + for c in gmm['covars']]) + const = (2 * np.pi)**(69 / 2.) + + nll_weights = np.asarray(gmm['weights'] / (const * + (sqrdets / sqrdets.min()))) + nll_weights = torch.tensor(nll_weights, dtype=dtype).unsqueeze(dim=0) + self.register_buffer('nll_weights', nll_weights) + + weights = torch.tensor(gmm['weights'], dtype=dtype).unsqueeze(dim=0) + self.register_buffer('weights', weights) + + self.register_buffer('pi_term', + torch.log(torch.tensor(2 * np.pi, dtype=dtype))) + + cov_dets = [np.log(np.linalg.det(cov.astype(np_dtype)) + epsilon) + for cov in covs] + self.register_buffer('cov_dets', + torch.tensor(cov_dets, dtype=dtype)) + + # The dimensionality of the random variable + self.random_var_dim = self.means.shape[1] + + def get_mean(self): + ''' Returns the mean of the mixture ''' + mean_pose = torch.matmul(self.weights, self.means) + return mean_pose + + def merged_log_likelihood(self, pose, betas): + diff_from_mean = pose.unsqueeze(dim=1) - self.means + + prec_diff_prod = torch.einsum('mij,bmj->bmi', + [self.precisions, diff_from_mean]) + diff_prec_quadratic = (prec_diff_prod * diff_from_mean).sum(dim=-1) + + curr_loglikelihood = 0.5 * diff_prec_quadratic - \ + torch.log(self.nll_weights) + # curr_loglikelihood = 0.5 * (self.cov_dets.unsqueeze(dim=0) + + # self.random_var_dim * self.pi_term + + # diff_prec_quadratic + # ) - torch.log(self.weights) + + min_likelihood, _ = torch.min(curr_loglikelihood, dim=1) + return min_likelihood + + def log_likelihood(self, pose, betas, *args, **kwargs): + ''' Create graph operation for negative log-likelihood calculation + ''' + likelihoods = [] + + for idx in range(self.num_gaussians): + mean = self.means[idx] + prec = self.precisions[idx] + cov = self.covs[idx] + diff_from_mean = pose - mean + + curr_loglikelihood = torch.einsum('bj,ji->bi', + [diff_from_mean, prec]) + curr_loglikelihood = torch.einsum('bi,bi->b', + [curr_loglikelihood, + diff_from_mean]) + cov_term = torch.log(torch.det(cov) + self.epsilon) + curr_loglikelihood += 0.5 * (cov_term + + self.random_var_dim * + self.pi_term) + likelihoods.append(curr_loglikelihood) + + log_likelihoods = torch.stack(likelihoods, dim=1) + min_idx = torch.argmin(log_likelihoods, dim=1) + weight_component = self.nll_weights[:, min_idx] + weight_component = -torch.log(weight_component) + + return weight_component + log_likelihoods[:, min_idx] + + def forward(self, pose, betas): + if self.use_merged: + return self.merged_log_likelihood(pose, betas) + else: + return self.log_likelihood(pose, betas) diff --git a/motiondiff_modules/mGPT/data/transforms/joints2rots/smplify.py b/motiondiff_modules/mGPT/data/transforms/joints2rots/smplify.py new file mode 100644 index 0000000..7df5150 --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/joints2rots/smplify.py @@ -0,0 +1,284 @@ +import torch +import os, sys +import pickle +import smplx +import numpy as np +from tqdm import tqdm + +sys.path.append(os.path.dirname(__file__)) +from customloss import (camera_fitting_loss, + body_fitting_loss, + camera_fitting_loss_3d, + body_fitting_loss_3d, + ) +from prior import MaxMixturePrior +import config + + + +@torch.no_grad() +def guess_init_3d(model_joints, + j3d, + joints_category="orig"): + """Initialize the camera translation via triangle similarity, by using the torso joints . + :param model_joints: SMPL model with pre joints + :param j3d: 25x3 array of Kinect Joints + :returns: 3D vector corresponding to the estimated camera translation + """ + # get the indexed four + gt_joints = ['RHip', 'LHip', 'RShoulder', 'LShoulder'] + gt_joints_ind = [config.JOINT_MAP[joint] for joint in gt_joints] + + if joints_category=="orig": + joints_ind_category = [config.JOINT_MAP[joint] for joint in gt_joints] + elif joints_category=="AMASS": + joints_ind_category = [config.AMASS_JOINT_MAP[joint] for joint in gt_joints] + elif joints_category=="MMM": + joints_ind_category = [config.MMM_JOINT_MAP[joint] for joint in gt_joints] + else: + print("NO SUCH JOINTS CATEGORY!") + + sum_init_t = (j3d[:, joints_ind_category] - model_joints[:, gt_joints_ind]).sum(dim=1) + init_t = sum_init_t / 4.0 + return init_t + + +# SMPLIfy 3D +class SMPLify3D(): + """Implementation of SMPLify, use 3D joints.""" + + def __init__(self, + smplxmodel, + step_size=1e-2, + batch_size=1, + num_iters=100, + use_collision=False, + use_lbfgs=True, + joints_category="orig", + device=torch.device('cuda:0'), + ): + + # Store options + self.batch_size = batch_size + self.device = device + self.step_size = step_size + + self.num_iters = num_iters + # --- choose optimizer + self.use_lbfgs = use_lbfgs + # GMM pose prior + self.pose_prior = MaxMixturePrior(prior_folder=config.GMM_MODEL_DIR, + num_gaussians=8, + dtype=torch.float32).to(device) + # collision part + self.use_collision = use_collision + if self.use_collision: + self.part_segm_fn = config.Part_Seg_DIR + + # reLoad SMPL-X model + self.smpl = smplxmodel + + self.model_faces = smplxmodel.faces_tensor.view(-1) + + # select joint joint_category + self.joints_category = joints_category + + if joints_category=="orig": + self.smpl_index = config.full_smpl_idx + self.corr_index = config.full_smpl_idx + elif joints_category=="AMASS": + self.smpl_index = config.amass_smpl_idx + self.corr_index = config.amass_idx + # elif joints_category=="MMM": + # self.smpl_index = config.mmm_smpl_dix + # self.corr_index = config.mmm_idx + else: + self.smpl_index = None + self.corr_index = None + print("NO SUCH JOINTS CATEGORY!") + + # ---- get the man function here ------ + def __call__(self, init_pose, init_betas, init_cam_t, j3d, conf_3d=1.0, seq_ind=0): + """Perform body fitting. + Input: + init_pose: SMPL pose estimate + init_betas: SMPL betas estimate + init_cam_t: Camera translation estimate + j3d: joints 3d aka keypoints + conf_3d: confidence for 3d joints + seq_ind: index of the sequence + Returns: + vertices: Vertices of optimized shape + joints: 3D joints of optimized shape + pose: SMPL pose parameters of optimized shape + betas: SMPL beta parameters of optimized shape + camera_translation: Camera translation + """ + + # # # add the mesh inter-section to avoid + search_tree = None + pen_distance = None + filter_faces = None + + if self.use_collision: + from mesh_intersection.bvh_search_tree import BVH + import mesh_intersection.loss as collisions_loss + from mesh_intersection.filter_faces import FilterFaces + + search_tree = BVH(max_collisions=8) + + pen_distance = collisions_loss.DistanceFieldPenetrationLoss( + sigma=0.5, point2plane=False, vectorized=True, penalize_outside=True) + + if self.part_segm_fn: + # Read the part segmentation + part_segm_fn = os.path.expandvars(self.part_segm_fn) + with open(part_segm_fn, 'rb') as faces_parents_file: + face_segm_data = pickle.load(faces_parents_file, encoding='latin1') + faces_segm = face_segm_data['segm'] + faces_parents = face_segm_data['parents'] + # Create the module used to filter invalid collision pairs + filter_faces = FilterFaces( + faces_segm=faces_segm, faces_parents=faces_parents, + ign_part_pairs=None).to(device=self.device) + + + # Split SMPL pose to body pose and global orientation + body_pose = init_pose[:, 3:].detach().clone() + global_orient = init_pose[:, :3].detach().clone() + betas = init_betas.detach().clone() + + # use guess 3d to get the initial + smpl_output = self.smpl(global_orient=global_orient, + body_pose=body_pose, + betas=betas) + model_joints = smpl_output.joints + + init_cam_t = guess_init_3d(model_joints, j3d, self.joints_category).detach() + camera_translation = init_cam_t.clone() + + preserve_pose = init_pose[:, 3:].detach().clone() + # -------------Step 1: Optimize camera translation and body orientation-------- + # Optimize only camera translation and body orientation + body_pose.requires_grad = False + betas.requires_grad = False + global_orient.requires_grad = True + camera_translation.requires_grad = True + + camera_opt_params = [global_orient, camera_translation] + + if self.use_lbfgs: + camera_optimizer = torch.optim.LBFGS(camera_opt_params, max_iter=self.num_iters, + lr=self.step_size, line_search_fn='strong_wolfe') + for i in range(10): + def closure(): + camera_optimizer.zero_grad() + smpl_output = self.smpl(global_orient=global_orient, + body_pose=body_pose, + betas=betas) + model_joints = smpl_output.joints + + loss = camera_fitting_loss_3d(model_joints, camera_translation, + init_cam_t, j3d, self.joints_category) + loss.backward() + return loss + + camera_optimizer.step(closure) + else: + camera_optimizer = torch.optim.Adam(camera_opt_params, lr=self.step_size, betas=(0.9, 0.999)) + + for i in range(20): + smpl_output = self.smpl(global_orient=global_orient, + body_pose=body_pose, + betas=betas) + model_joints = smpl_output.joints + + loss = camera_fitting_loss_3d(model_joints[:, self.smpl_index], camera_translation, + init_cam_t, j3d[:, self.corr_index], self.joints_category) + camera_optimizer.zero_grad() + loss.backward() + camera_optimizer.step() + + # Fix camera translation after optimizing camera + # --------Step 2: Optimize body joints -------------------------- + # Optimize only the body pose and global orientation of the body + body_pose.requires_grad = True + global_orient.requires_grad = True + camera_translation.requires_grad = True + + # --- if we use the sequence, fix the shape + if seq_ind == 0: + betas.requires_grad = True + body_opt_params = [body_pose, betas, global_orient, camera_translation] + else: + betas.requires_grad = False + body_opt_params = [body_pose, global_orient, camera_translation] + + if self.use_lbfgs: + body_optimizer = torch.optim.LBFGS(body_opt_params, max_iter=self.num_iters, + lr=self.step_size, line_search_fn='strong_wolfe') + + for i in tqdm(range(self.num_iters), desc=f"LBFGS iter: "): + # for i in range(self.num_iters): + def closure(): + body_optimizer.zero_grad() + smpl_output = self.smpl(global_orient=global_orient, + body_pose=body_pose, + betas=betas) + model_joints = smpl_output.joints + model_vertices = smpl_output.vertices + + loss = body_fitting_loss_3d(body_pose, preserve_pose, betas, model_joints[:, self.smpl_index], camera_translation, + j3d[:, self.corr_index], self.pose_prior, + joints3d_conf=conf_3d, + joint_loss_weight=600.0, + pose_preserve_weight=5.0, + use_collision=self.use_collision, + model_vertices=model_vertices, model_faces=self.model_faces, + search_tree=search_tree, pen_distance=pen_distance, filter_faces=filter_faces) + loss.backward() + return loss + + body_optimizer.step(closure) + else: + body_optimizer = torch.optim.Adam(body_opt_params, lr=self.step_size, betas=(0.9, 0.999)) + + for i in range(self.num_iters): + smpl_output = self.smpl(global_orient=global_orient, + body_pose=body_pose, + betas=betas) + model_joints = smpl_output.joints + model_vertices = smpl_output.vertices + + loss = body_fitting_loss_3d(body_pose, preserve_pose, betas, model_joints[:, self.smpl_index], camera_translation, + j3d[:, self.corr_index], self.pose_prior, + joints3d_conf=conf_3d, + joint_loss_weight=600.0, + use_collision=self.use_collision, + model_vertices=model_vertices, model_faces=self.model_faces, + search_tree=search_tree, pen_distance=pen_distance, filter_faces=filter_faces) + body_optimizer.zero_grad() + loss.backward() + body_optimizer.step() + + # Get final loss value + with torch.no_grad(): + smpl_output = self.smpl(global_orient=global_orient, + body_pose=body_pose, + betas=betas, return_full_pose=True) + model_joints = smpl_output.joints + model_vertices = smpl_output.vertices + + final_loss = body_fitting_loss_3d(body_pose, preserve_pose, betas, model_joints[:, self.smpl_index], camera_translation, + j3d[:, self.corr_index], self.pose_prior, + joints3d_conf=conf_3d, + joint_loss_weight=600.0, + use_collision=self.use_collision, model_vertices=model_vertices, model_faces=self.model_faces, + search_tree=search_tree, pen_distance=pen_distance, filter_faces=filter_faces) + + vertices = smpl_output.vertices.detach() + joints = smpl_output.joints.detach() + pose = torch.cat([global_orient, body_pose], dim=-1).detach() + betas = betas.detach() + + return vertices, joints, pose, betas, camera_translation, final_loss \ No newline at end of file diff --git a/motiondiff_modules/mGPT/data/transforms/rots2joints/__init__.py b/motiondiff_modules/mGPT/data/transforms/rots2joints/__init__.py new file mode 100644 index 0000000..7719c70 --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/rots2joints/__init__.py @@ -0,0 +1,3 @@ +from .base import Rots2Joints +from .smplh import SMPLH +from .smplx import SMPLX diff --git a/motiondiff_modules/mGPT/data/transforms/rots2joints/base.py b/motiondiff_modules/mGPT/data/transforms/rots2joints/base.py new file mode 100644 index 0000000..524f830 --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/rots2joints/base.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- + +# Max-Planck-Gesellschaft zur Förderung der Wissenschaften e.V. (MPG) is +# holder of all proprietary rights on this computer program. +# You can only use this computer program if you have closed +# a license agreement with MPG or you get the right to use the computer +# program from someone who is authorized to grant you that right. +# Any use of the computer program without a valid license is prohibited and +# liable to prosecution. +# +# Copyright©2020 Max-Planck-Gesellschaft zur Förderung +# der Wissenschaften e.V. (MPG). acting on behalf of its Max Planck Institute +# for Intelligent Systems. All rights reserved. +# +# Contact: ps-license@tuebingen.mpg.de + +from typing import Optional + +import torch +from torch import Tensor, nn +from pathlib import Path +import os +# import hydra + +class Rots2Joints(nn.Module): + def __init__(self, path: Optional[str] = None, + normalization: bool = False, + eps: float = 1e-12, + **kwargs) -> None: + if normalization and path is None: + raise TypeError("You should provide a path if normalization is on.") + + super().__init__() + self.normalization = normalization + self.eps = eps + # workaround for cluster local/sync + if path is not None: + rel_p = path.split('/') + rel_p = rel_p[rel_p.index('deps'):] + rel_p = '/'.join(rel_p) + # path = hydra.utils.get_original_cwd() + '/' + rel_p + if normalization: + mean_path = Path(path) / "mean.pt" + std_path = Path(path) / "std.pt" + self.register_buffer('mean', torch.load(mean_path)) + self.register_buffer('std', torch.load(std_path)) + + def normalize(self, features: Tensor) -> Tensor: + if self.normalization: + features = (features - self.mean)/(self.std + self.eps) + return features + + def unnormalize(self, features: Tensor) -> Tensor: + if self.normalization: + features = features * self.std + self.mean + return features diff --git a/motiondiff_modules/mGPT/data/transforms/rots2joints/smplh.py b/motiondiff_modules/mGPT/data/transforms/rots2joints/smplh.py new file mode 100644 index 0000000..f3bd0c8 --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/rots2joints/smplh.py @@ -0,0 +1,192 @@ +# -*- coding: utf-8 -*- + +# Max-Planck-Gesellschaft zur Förderung der Wissenschaften e.V. (MPG) is +# holder of all proprietary rights on this computer program. +# You can only use this computer program if you have closed +# a license agreement with MPG or you get the right to use the computer +# program from someone who is authorized to grant you that right. +# Any use of the computer program without a valid license is prohibited and +# liable to prosecution. +# +# Copyright©2020 Max-Planck-Gesellschaft zur Förderung +# der Wissenschaften e.V. (MPG). acting on behalf of its Max Planck Institute +# for Intelligent Systems. All rights reserved. +# +# Contact: ps-license@tuebingen.mpg.de + +import contextlib +from typing import Optional + +import torch +from einops import rearrange +from torch import Tensor +from motiondiff_modules.mGPT.utils.joints import smplh_to_mmm_scaling_factor +from motiondiff_modules.mGPT.utils.joints import smplh2mmm_indexes +from .base import Rots2Joints + + +def slice_or_none(data, cslice): + if data is None: + return data + else: + return data[cslice] + + +class SMPLH(Rots2Joints): + + def __init__(self, + path: str, + jointstype: str = "mmm", + input_pose_rep: str = "matrix", + batch_size: int = 512, + gender="neutral", + **kwargs) -> None: + super().__init__(path=None, normalization=False) + self.batch_size = batch_size + self.input_pose_rep = input_pose_rep + self.jointstype = jointstype + self.training = False + + from smplx.body_models import SMPLHLayer + import os + # rel_p = path.split('/') + # rel_p = rel_p[rel_p.index('data'):] + # rel_p = '/'.join(rel_p) + + # Remove annoying print + with contextlib.redirect_stdout(None): + self.smplh = SMPLHLayer(path, ext="pkl", gender=gender).eval() + + self.faces = self.smplh.faces + for p in self.parameters(): + p.requires_grad = False + + def train(self, *args, **kwargs): + return self + + def forward(self, + smpl_data: dict, + jointstype: Optional[str] = None, + input_pose_rep: Optional[str] = None, + batch_size: Optional[int] = None) -> Tensor: + + # Take values from init if not specified there + jointstype = self.jointstype if jointstype is None else jointstype + batch_size = self.batch_size if batch_size is None else batch_size + input_pose_rep = self.input_pose_rep if input_pose_rep is None else input_pose_rep + + if input_pose_rep == "xyz": + raise NotImplementedError( + "You should use identity pose2joints instead") + + poses = smpl_data.rots + trans = smpl_data.trans + + from functools import reduce + import operator + save_shape_bs_len = poses.shape[:-3] + nposes = reduce(operator.mul, save_shape_bs_len, 1) + + if poses.shape[-3] == 52: + nohands = False + elif poses.shape[-3] == 22: + nohands = True + else: + raise NotImplementedError("Could not parse the poses.") + + # Convert any rotations to matrix + # from temos.tools.easyconvert import to_matrix + # matrix_poses = to_matrix(input_pose_rep, poses) + matrix_poses = poses + + # Reshaping + matrix_poses = matrix_poses.reshape((nposes, *matrix_poses.shape[-3:])) + global_orient = matrix_poses[:, 0] + + if trans is None: + trans = torch.zeros((*save_shape_bs_len, 3), + dtype=poses.dtype, + device=poses.device) + + trans_all = trans.reshape((nposes, *trans.shape[-1:])) + + body_pose = matrix_poses[:, 1:22] + if nohands: + left_hand_pose = None + right_hand_pose = None + else: + hand_pose = matrix_poses[:, 22:] + left_hand_pose = hand_pose[:, :15] + right_hand_pose = hand_pose[:, 15:] + + n = len(body_pose) + outputs = [] + for chunk in range(int((n - 1) / batch_size) + 1): + chunk_slice = slice(chunk * batch_size, (chunk + 1) * batch_size) + smpl_output = self.smplh( + global_orient=slice_or_none(global_orient, chunk_slice), + body_pose=slice_or_none(body_pose, chunk_slice), + left_hand_pose=slice_or_none(left_hand_pose, chunk_slice), + right_hand_pose=slice_or_none(right_hand_pose, chunk_slice), + transl=slice_or_none(trans_all, chunk_slice)) + + if jointstype == "vertices": + output_chunk = smpl_output.vertices + else: + joints = smpl_output.joints + output_chunk = joints + + outputs.append(output_chunk) + + outputs = torch.cat(outputs) + outputs = outputs.reshape((*save_shape_bs_len, *outputs.shape[1:])) + + # Change topology if needed + outputs = smplh_to(jointstype, outputs, trans) + + return outputs + + def inverse(self, joints: Tensor) -> Tensor: + raise NotImplementedError("Cannot inverse SMPLH layer.") + + +def smplh_to(jointstype, data, trans): + from motiondiff_modules.mGPT.utils.joints import get_root_idx + + if "mmm" in jointstype: + from motiondiff_modules.mGPT.utils.joints import smplh2mmm_indexes + indexes = smplh2mmm_indexes + data = data[..., indexes, :] + + # make it compatible with mmm + if jointstype == "mmm": + from motiondiff_modules.mGPT.utils.joints import smplh_to_mmm_scaling_factor + data *= smplh_to_mmm_scaling_factor + + if jointstype == "smplmmm": + pass + elif jointstype in ["mmm", "mmmns"]: + # swap axis + data = data[..., [1, 2, 0]] + # revert left and right + data[..., 2] = -data[..., 2] + + elif jointstype == "smplnh": + from motiondiff_modules.mGPT.utils.joints import smplh2smplnh_indexes + indexes = smplh2smplnh_indexes + data = data[..., indexes, :] + elif jointstype == "smplh": + pass + elif jointstype == "vertices": + pass + else: + raise NotImplementedError(f"SMPLH to {jointstype} is not implemented.") + + if jointstype != "vertices": + # shift the output in each batch + # such that it is centered on the pelvis/root on the first frame + root_joint_idx = get_root_idx(jointstype) + shift = trans[..., 0, :] - data[..., 0, root_joint_idx, :] + data += shift[..., None, None, :] + + return data diff --git a/motiondiff_modules/mGPT/data/transforms/rots2joints/smplx.py b/motiondiff_modules/mGPT/data/transforms/rots2joints/smplx.py new file mode 100644 index 0000000..37cf776 --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/rots2joints/smplx.py @@ -0,0 +1,201 @@ +# -*- coding: utf-8 -*- + +# Max-Planck-Gesellschaft zur Förderung der Wissenschaften e.V. (MPG) is +# holder of all proprietary rights on this computer program. +# You can only use this computer program if you have closed +# a license agreement with MPG or you get the right to use the computer +# program from someone who is authorized to grant you that right. +# Any use of the computer program without a valid license is prohibited and +# liable to prosecution. +# +# Copyright©2020 Max-Planck-Gesellschaft zur Förderung +# der Wissenschaften e.V. (MPG). acting on behalf of its Max Planck Institute +# for Intelligent Systems. All rights reserved. +# +# Contact: ps-license@tuebingen.mpg.de + +import contextlib +from typing import Optional +import torch +from torch import Tensor +from motiondiff_modules.mGPT.utils.joints import smplh_to_mmm_scaling_factor, smplh2mmm_indexes, get_root_idx +from motiondiff_modules.mGPT.utils.easyconvert import rep_to_rep +from .base import Rots2Joints + + +def slice_or_none(data, cslice): + if data is None: + return data + else: + return data[cslice] + + +class SMPLX(Rots2Joints): + def __init__(self, + path: str, + jointstype: str = "mmm", + input_pose_rep: str = "matrix", + batch_size: int = 512, + gender="neutral", + **kwargs) -> None: + super().__init__(path=None, normalization=False) + self.batch_size = batch_size + self.input_pose_rep = input_pose_rep + self.jointstype = jointstype + self.training = False + + from smplx.body_models import SMPLXLayer + import os + # rel_p = path.split('/') + # rel_p = rel_p[rel_p.index('data'):] + # rel_p = '/'.join(rel_p) + + # Remove annoying print + with contextlib.redirect_stdout(None): + self.smplx = SMPLXLayer(path, + ext="npz", + gender=gender, + batch_size=batch_size).eval() + + self.faces = self.smplx.faces + for p in self.parameters(): + p.requires_grad = False + + def train(self, *args, **kwargs): + return self + + def forward(self, + smpl_data: dict, + jointstype: Optional[str] = None, + input_pose_rep: Optional[str] = None, + batch_size: Optional[int] = None) -> Tensor: + + # Take values from init if not specified there + jointstype = self.jointstype if jointstype is None else jointstype + batch_size = self.batch_size if batch_size is None else batch_size + input_pose_rep = self.input_pose_rep if input_pose_rep is None else input_pose_rep + + poses = smpl_data.rots + trans = smpl_data.trans + + from functools import reduce + import operator + save_shape_bs_len = poses.shape[:-3] + nposes = reduce(operator.mul, save_shape_bs_len, 1) + + + matrix_poses = rep_to_rep(self.input_pose_rep, input_pose_rep, poses) + + # Reshaping + matrix_poses = matrix_poses.reshape((nposes, *matrix_poses.shape[-3:])) + + global_orient = matrix_poses[:, 0] + + if trans is None: + trans = torch.zeros((*save_shape_bs_len, 3), + dtype=poses.dtype, + device=poses.device) + + trans_all = trans.reshape((nposes, *trans.shape[-1:])) + + body_pose = matrix_poses[:, 1:22] + + if poses.shape[-3] == 55: + nohands = False + nofaces = False + elif poses.shape[-3] == 52: + nohands = False + nofaces = True + elif poses.shape[-3] == 22: + nohands = True + nofaces = True + else: + raise NotImplementedError("Could not parse the poses.") + + if nohands: + left_hand_pose = None + right_hand_pose = None + else: + left_hand_pose = matrix_poses[:, 25:40] + right_hand_pose = matrix_poses[:, 40:55] + + if nofaces: + jaw_pose = None + leye_pose = None + reye_pose = None + else: + jaw_pose = matrix_poses[:, 22:23] + leye_pose = matrix_poses[:, 23:24] + reye_pose = matrix_poses[:, 24:25] + + n = len(body_pose) + outputs = [] + for chunk in range(int((n - 1) / batch_size) + 1): + chunk_slice = slice(chunk * batch_size, (chunk + 1) * batch_size) + smpl_output = self.smplx( + global_orient=slice_or_none(global_orient, chunk_slice), + body_pose=slice_or_none(body_pose, chunk_slice), + left_hand_pose=slice_or_none(left_hand_pose, chunk_slice), + right_hand_pose=slice_or_none(right_hand_pose, chunk_slice), + jaw_pose=slice_or_none(jaw_pose, chunk_slice), + leye_pose=slice_or_none(leye_pose, chunk_slice), + reye_pose=slice_or_none(reye_pose, chunk_slice), + transl=slice_or_none(trans_all, chunk_slice)) + + if jointstype == "vertices": + output_chunk = smpl_output.vertices + else: + joints = smpl_output.joints + output_chunk = joints + + outputs.append(output_chunk) + + outputs = torch.cat(outputs) + outputs = outputs.reshape((*save_shape_bs_len, *outputs.shape[1:])) + + # Change topology if needed + outputs = smplx_to(jointstype, outputs, trans) + + return outputs + + def inverse(self, joints: Tensor) -> Tensor: + raise NotImplementedError("Cannot inverse SMPLX layer.") + + +def smplx_to(jointstype, data, trans): + + if "mmm" in jointstype: + indexes = smplh2mmm_indexes + data = data[..., indexes, :] + + # make it compatible with mmm + if jointstype == "mmm": + data *= smplh_to_mmm_scaling_factor + + if jointstype == "smplmmm": + pass + elif jointstype in ["mmm", "mmmns"]: + # swap axis + data = data[..., [1, 2, 0]] + # revert left and right + data[..., 2] = -data[..., 2] + + elif jointstype == "smplnh": + from motiondiff_modules.mGPT.utils.joints import smplh2smplnh_indexes + indexes = smplh2smplnh_indexes + data = data[..., indexes, :] + elif jointstype == "smplh": + pass + elif jointstype == "vertices": + pass + else: + raise NotImplementedError(f"SMPLX to {jointstype} is not implemented.") + + if jointstype != "vertices": + # shift the output in each batch + # such that it is centered on the pelvis/root on the first frame + root_joint_idx = get_root_idx(jointstype) + shift = trans[..., 0, :] - data[..., 0, root_joint_idx, :] + data += shift[..., None, None, :] + + return data diff --git a/motiondiff_modules/mGPT/data/transforms/rots2rfeats/__init__.py b/motiondiff_modules/mGPT/data/transforms/rots2rfeats/__init__.py new file mode 100644 index 0000000..29b206c --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/rots2rfeats/__init__.py @@ -0,0 +1,5 @@ +from .base import Rots2Rfeats +# from .globvel import Globalvel + +from .globvelandy import Globalvelandy +# from .rifeats import Rifeats diff --git a/motiondiff_modules/mGPT/data/transforms/rots2rfeats/base.py b/motiondiff_modules/mGPT/data/transforms/rots2rfeats/base.py new file mode 100644 index 0000000..98c33bd --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/rots2rfeats/base.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- + +# Max-Planck-Gesellschaft zur Förderung der Wissenschaften e.V. (MPG) is +# holder of all proprietary rights on this computer program. +# You can only use this computer program if you have closed +# a license agreement with MPG or you get the right to use the computer +# program from someone who is authorized to grant you that right. +# Any use of the computer program without a valid license is prohibited and +# liable to prosecution. +# +# Copyright©2020 Max-Planck-Gesellschaft zur Förderung +# der Wissenschaften e.V. (MPG). acting on behalf of its Max Planck Institute +# for Intelligent Systems. All rights reserved. +# +# Contact: ps-license@tuebingen.mpg.de + +from typing import Optional + +import torch +from torch import Tensor, nn +from pathlib import Path +import os + +class Rots2Rfeats(nn.Module): + def __init__(self, path: Optional[str] = None, + normalization: bool = True, + eps: float = 1e-12, + **kwargs) -> None: + if normalization and path is None: + raise TypeError("You should provide a path if normalization is on.") + + super().__init__() + self.normalization = normalization + self.eps = eps + if normalization: + # workaround for cluster local/sync + rel_p = path.split('/') + # superhacky it is for the datatype ugly stuff change it, copy the main stuff to seperate_pairs dict + if rel_p[-1] == 'separate_pairs': + rel_p.remove('separate_pairs') + ######################################################## + # rel_p = rel_p[rel_p.index('deps'):] + rel_p = '/'.join(rel_p) + # path = hydra.utils.get_original_cwd() + '/' + rel_p + path = rel_p + mean_path = Path(path) / "rfeats_mean.pt" + std_path = Path(path) / "rfeats_std.pt" + + self.register_buffer('mean', torch.load(mean_path)) + self.register_buffer('std', torch.load(std_path)) + + def normalize(self, features: Tensor) -> Tensor: + if self.normalization: + features = (features - self.mean)/(self.std + self.eps) + return features + + def unnormalize(self, features: Tensor) -> Tensor: + if self.normalization: + features = features * self.std + self.mean + return features diff --git a/motiondiff_modules/mGPT/data/transforms/rots2rfeats/globvelandy.py b/motiondiff_modules/mGPT/data/transforms/rots2rfeats/globvelandy.py new file mode 100644 index 0000000..5189e51 --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/rots2rfeats/globvelandy.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- + +# Max-Planck-Gesellschaft zur Förderung der Wissenschaften e.V. (MPG) is +# holder of all proprietary rights on this computer program. +# You can only use this computer program if you have closed +# a license agreement with MPG or you get the right to use the computer +# program from someone who is authorized to grant you that right. +# Any use of the computer program without a valid license is prohibited and +# liable to prosecution. +# +# Copyright©2020 Max-Planck-Gesellschaft zur Förderung +# der Wissenschaften e.V. (MPG). acting on behalf of its Max Planck Institute +# for Intelligent Systems. All rights reserved. +# +# Contact: ps-license@tuebingen.mpg.de + +from typing import Optional + +import torch +from torch import Tensor +from einops import rearrange + +from motiondiff_modules.mGPT.utils.easyconvert import rep_to_rep, nfeats_of, to_matrix +import mGPT.utils.geometry_tools as geometry_tools + +from .base import Rots2Rfeats + + +class Globalvelandy(Rots2Rfeats): + def __init__(self, + path: Optional[str] = None, + normalization: bool = False, + pose_rep: str = "rot6d", + canonicalize: bool = False, + offset: bool = True, + **kwargs) -> None: + super().__init__(path=path, normalization=normalization) + + self.canonicalize = canonicalize + self.pose_rep = pose_rep + self.nfeats = nfeats_of(pose_rep) + self.offset = offset + + def forward(self, data, data_rep='matrix', first_frame=None) -> Tensor: + + poses, trans = data.rots, data.trans + + # extract the root gravity axis + # for smpl it is the last coordinate + root_y = trans[..., 2] + trajectory = trans[..., [0, 1]] + + # Compute the difference of trajectory + vel_trajectory = torch.diff(trajectory, dim=-2) + + # 0 for the first one => keep the dimentionality + if first_frame is None: + first_frame = 0 * vel_trajectory[..., [0], :] + + vel_trajectory = torch.cat((first_frame, vel_trajectory), dim=-2) + + # first normalize the data + if self.canonicalize: + + matrix_poses = rep_to_rep(data_rep, 'matrix', poses) + global_orient = matrix_poses[..., 0, :, :] + + # remove the rotation + rot2d = rep_to_rep(data_rep, 'rotvec', poses[0, 0, ...]) + + # Remove the fist rotation along the vertical axis + rot2d[..., :2] = 0 + + if self.offset: + # add a bit more rotation + rot2d[..., 2] += torch.pi / 2 + + rot2d = rep_to_rep('rotvec', 'matrix', rot2d) + + # turn with the same amount all the rotations + global_orient = torch.einsum("...kj,...kl->...jl", rot2d, + global_orient) + + matrix_poses = torch.cat( + (global_orient[..., None, :, :], matrix_poses[..., 1:, :, :]), + dim=-3) + + poses = rep_to_rep('matrix', data_rep, matrix_poses) + + # Turn the trajectory as well + vel_trajectory = torch.einsum("...kj,...lk->...lj", + rot2d[..., :2, :2], vel_trajectory) + + poses = rep_to_rep(data_rep, self.pose_rep, poses) + features = torch.cat( + (root_y[..., None], vel_trajectory, + rearrange(poses, "... joints rot -> ... (joints rot)")), + dim=-1) + features = self.normalize(features) + + return features + + def extract(self, features): + root_y = features[..., 0] + vel_trajectory = features[..., 1:3] + poses_features = features[..., 3:] + poses = rearrange(poses_features, + "... (joints rot) -> ... joints rot", + rot=self.nfeats) + return root_y, vel_trajectory, poses + + def inverse(self, features, last_frame=None): + features = self.unnormalize(features) + root_y, vel_trajectory, poses = self.extract(features) + + # integrate the trajectory + trajectory = torch.cumsum(vel_trajectory, dim=-2) + if last_frame is None: + pass + # First frame should be 0, but if infered it is better to ensure it + trajectory = trajectory - trajectory[..., [0], :] + + # Get back the translation + trans = torch.cat([trajectory, root_y[..., None]], dim=-1) + matrix_poses = rep_to_rep(self.pose_rep, 'matrix', poses) + + from ..smpl import RotTransDatastruct + return RotTransDatastruct(rots=matrix_poses, trans=trans) diff --git a/motiondiff_modules/mGPT/data/transforms/smpl.py b/motiondiff_modules/mGPT/data/transforms/smpl.py new file mode 100644 index 0000000..fc46b11 --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/smpl.py @@ -0,0 +1,191 @@ +# -*- coding: utf-8 -*- + +# Max-Planck-Gesellschaft zur Förderung der Wissenschaften e.V. (MPG) is +# holder of all proprietary rights on this computer program. +# You can only use this computer program if you have closed +# a license agreement with MPG or you get the right to use the computer +# program from someone who is authorized to grant you that right. +# Any use of the computer program without a valid license is prohibited and +# liable to prosecution. +# +# Copyright©2020 Max-Planck-Gesellschaft zur Förderung +# der Wissenschaften e.V. (MPG). acting on behalf of its Max Planck Institute +# for Intelligent Systems. All rights reserved. +# +# Contact: ps-license@tuebingen.mpg.de + +from typing import Optional +from torch import Tensor +import smplx + +from .base import Datastruct, dataclass, Transform + +from .rots2rfeats import Rots2Rfeats +from .rots2joints import Rots2Joints +from .joints2jfeats import Joints2Jfeats + + +class SMPLTransform(Transform): + def __init__(self, rots2rfeats: Rots2Rfeats, + rots2joints: Rots2Joints, + joints2jfeats: Joints2Jfeats, + **kwargs): + self.rots2rfeats = rots2rfeats + self.rots2joints = rots2joints + self.joints2jfeats = joints2jfeats + + def Datastruct(self, **kwargs): + return SMPLDatastruct(_rots2rfeats=self.rots2rfeats, + _rots2joints=self.rots2joints, + _joints2jfeats=self.joints2jfeats, + transforms=self, + **kwargs) + + def __repr__(self): + return "SMPLTransform()" + + +class RotIdentityTransform(Transform): + def __init__(self, **kwargs): + return + + def Datastruct(self, **kwargs): + return RotTransDatastruct(**kwargs) + + def __repr__(self): + return "RotIdentityTransform()" + + +@dataclass +class RotTransDatastruct(Datastruct): + rots: Tensor + trans: Tensor + + transforms: RotIdentityTransform = RotIdentityTransform() + + def __post_init__(self): + self.datakeys = ["rots", "trans"] + + def __len__(self): + return len(self.rots) + + +@dataclass +class SMPLDatastruct(Datastruct): + transforms: SMPLTransform + _rots2rfeats: Rots2Rfeats + _rots2joints: Rots2Joints + _joints2jfeats: Joints2Jfeats + + features: Optional[Tensor] = None + rots_: Optional[RotTransDatastruct] = None + rfeats_: Optional[Tensor] = None + joints_: Optional[Tensor] = None + jfeats_: Optional[Tensor] = None + vertices_: Optional[Tensor] = None + + def __post_init__(self): + self.datakeys = ['features', 'rots_', 'rfeats_', + 'joints_', 'jfeats_', 'vertices_'] + # starting point + if self.features is not None and self.rfeats_ is None: + self.rfeats_ = self.features + + @property + def rots(self): + # Cached value + if self.rots_ is not None: + return self.rots_ + + # self.rfeats_ should be defined + assert self.rfeats_ is not None + + self._rots2rfeats.to(self.rfeats.device) + self.rots_ = self._rots2rfeats.inverse(self.rfeats) + return self.rots_ + + @property + def rfeats(self): + # Cached value + if self.rfeats_ is not None: + return self.rfeats_ + + # self.rots_ should be defined + assert self.rots_ is not None + + self._rots2rfeats.to(self.rots.device) + self.rfeats_ = self._rots2rfeats(self.rots) + return self.rfeats_ + + @property + def joints(self): + # Cached value + if self.joints_ is not None: + return self.joints_ + + self._rots2joints.to(self.rots.device) + self.joints_ = self._rots2joints(self.rots) + return self.joints_ + + @property + def jfeats(self): + # Cached value + if self.jfeats_ is not None: + return self.jfeats_ + + self._joints2jfeats.to(self.joints.device) + self.jfeats_ = self._joints2jfeats(self.joints) + return self.jfeats_ + + @property + def vertices(self): + # Cached value + if self.vertices_ is not None: + return self.vertices_ + + self._rots2joints.to(self.rots.device) + self.vertices_ = self._rots2joints(self.rots, jointstype="vertices") + return self.vertices_ + + def __len__(self): + return len(self.rfeats) + + +def get_body_model(model_type, gender, batch_size, device='cpu', ext='pkl'): + ''' + type: smpl, smplx smplh and others. Refer to smplx tutorial + gender: male, female, neutral + batch_size: an positive integar + ''' + mtype = model_type.upper() + if gender != 'neutral': + if not isinstance(gender, str): + gender = str(gender.astype(str)).upper() + else: + gender = gender.upper() + else: + gender = gender.upper() + ext = 'npz' + body_model_path = f'data/smpl_models/{model_type}/{mtype}_{gender}.{ext}' + + body_model = smplx.create(body_model_path, model_type=type, + gender=gender, ext=ext, + use_pca=False, + num_pca_comps=12, + create_global_orient=True, + create_body_pose=True, + create_betas=True, + create_left_hand_pose=True, + create_right_hand_pose=True, + create_expression=True, + create_jaw_pose=True, + create_leye_pose=True, + create_reye_pose=True, + create_transl=True, + batch_size=batch_size) + + if device == 'cuda': + return body_model.cuda() + else: + return body_model + diff --git a/motiondiff_modules/mGPT/data/transforms/xyz.py b/motiondiff_modules/mGPT/data/transforms/xyz.py new file mode 100644 index 0000000..7add165 --- /dev/null +++ b/motiondiff_modules/mGPT/data/transforms/xyz.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- + +# Max-Planck-Gesellschaft zur Förderung der Wissenschaften e.V. (MPG) is +# holder of all proprietary rights on this computer program. +# You can only use this computer program if you have closed +# a license agreement with MPG or you get the right to use the computer +# program from someone who is authorized to grant you that right. +# Any use of the computer program without a valid license is prohibited and +# liable to prosecution. +# +# Copyright©2020 Max-Planck-Gesellschaft zur Förderung +# der Wissenschaften e.V. (MPG). acting on behalf of its Max Planck Institute +# for Intelligent Systems. All rights reserved. +# +# Contact: ps-license@tuebingen.mpg.de + +from typing import Optional +from torch import Tensor + +from .base import Datastruct, dataclass, Transform +from ..tools import collate_tensor_with_padding + +from .joints2jfeats import Joints2Jfeats + + +class XYZTransform(Transform): + def __init__(self, joints2jfeats: Joints2Jfeats, **kwargs): + self.joints2jfeats = joints2jfeats + + def Datastruct(self, **kwargs): + return XYZDatastruct(_joints2jfeats=self.joints2jfeats, + transforms=self, + **kwargs) + + def __repr__(self): + return "XYZTransform()" + + +@dataclass +class XYZDatastruct(Datastruct): + transforms: XYZTransform + _joints2jfeats: Joints2Jfeats + + features: Optional[Tensor] = None + joints_: Optional[Tensor] = None + jfeats_: Optional[Tensor] = None + + def __post_init__(self): + self.datakeys = ["features", "joints_", "jfeats_"] + # starting point + if self.features is not None and self.jfeats_ is None: + self.jfeats_ = self.features + + @property + def joints(self): + # Cached value + if self.joints_ is not None: + return self.joints_ + + # self.jfeats_ should be defined + assert self.jfeats_ is not None + + self._joints2jfeats.to(self.jfeats.device) + self.joints_ = self._joints2jfeats.inverse(self.jfeats) + return self.joints_ + + @property + def jfeats(self): + # Cached value + if self.jfeats_ is not None: + return self.jfeats_ + + # self.joints_ should be defined + assert self.joints_ is not None + + self._joints2jfeats.to(self.joints.device) + self.jfeats_ = self._joints2jfeats(self.joints) + return self.jfeats_ + + def __len__(self): + return len(self.jfeats) diff --git a/motiondiff_modules/mGPT/data/utils.py b/motiondiff_modules/mGPT/data/utils.py new file mode 100644 index 0000000..30714ff --- /dev/null +++ b/motiondiff_modules/mGPT/data/utils.py @@ -0,0 +1,81 @@ +import torch +import rich +import pickle +import numpy as np + + +def lengths_to_mask(lengths): + max_len = max(lengths) + mask = torch.arange(max_len, device=lengths.device).expand( + len(lengths), max_len) < lengths.unsqueeze(1) + return mask + + +# padding to max length in one batch +def collate_tensors(batch): + if isinstance(batch[0], np.ndarray): + batch = [torch.tensor(b).float() for b in batch] + + dims = batch[0].dim() + max_size = [max([b.size(i) for b in batch]) for i in range(dims)] + size = (len(batch), ) + tuple(max_size) + canvas = batch[0].new_zeros(size=size) + for i, b in enumerate(batch): + sub_tensor = canvas[i] + for d in range(dims): + sub_tensor = sub_tensor.narrow(d, 0, b.size(d)) + sub_tensor.add_(b) + return canvas + +def humanml3d_collate(batch): + notnone_batches = [b for b in batch if b is not None] + EvalFlag = False if notnone_batches[0][5] is None else True + + # Sort by text length + if EvalFlag: + notnone_batches.sort(key=lambda x: x[5], reverse=True) + + # Motion only + adapted_batch = { + "motion": + collate_tensors([torch.tensor(b[1]).float() for b in notnone_batches]), + "length": [b[2] for b in notnone_batches], + } + + # Text and motion + if notnone_batches[0][0] is not None: + adapted_batch.update({ + "text": [b[0] for b in notnone_batches], + "all_captions": [b[7] for b in notnone_batches], + }) + + # Evaluation related + if EvalFlag: + adapted_batch.update({ + "text": [b[0] for b in notnone_batches], + "word_embs": + collate_tensors( + [torch.tensor(b[3]).float() for b in notnone_batches]), + "pos_ohot": + collate_tensors( + [torch.tensor(b[4]).float() for b in notnone_batches]), + "text_len": + collate_tensors([torch.tensor(b[5]) for b in notnone_batches]), + "tokens": [b[6] for b in notnone_batches], + }) + + # Tasks + if len(notnone_batches[0]) == 9: + adapted_batch.update({"tasks": [b[8] for b in notnone_batches]}) + + return adapted_batch + + +def load_pkl(path, description=None, progressBar=False): + if progressBar: + with rich.progress.open(path, 'rb', description=description) as file: + data = pickle.load(file) + else: + with open(path, 'rb') as file: + data = pickle.load(file) + return data diff --git a/motiondiff_modules/mGPT/losses/__init__.py b/motiondiff_modules/mGPT/losses/__init__.py new file mode 100644 index 0000000..2fe3b35 --- /dev/null +++ b/motiondiff_modules/mGPT/losses/__init__.py @@ -0,0 +1 @@ +from .base import BaseLosses diff --git a/motiondiff_modules/mGPT/losses/base.py b/motiondiff_modules/mGPT/losses/base.py new file mode 100644 index 0000000..d310311 --- /dev/null +++ b/motiondiff_modules/mGPT/losses/base.py @@ -0,0 +1,61 @@ +import torch +import torch.nn as nn + +class BaseLosses(nn.Module): + def __init__(self, cfg, losses, params, losses_func, num_joints, **kwargs): + super().__init__() + + # Save parameters + self.num_joints = num_joints + self._params = params + + # Add total indicator + losses.append("total") if "total" not in losses else None + + # Register losses + for loss in losses: + self.register_buffer(loss, torch.tensor(0.0)) + self.register_buffer("count", torch.tensor(0.0)) + self.losses = losses + + # Instantiate loss functions + self._losses_func = {} + for loss in losses[:-1]: + self._losses_func[loss] = losses_func[loss](reduction='mean') + + def _update_loss(self, loss: str, outputs, inputs): + '''Update the loss and return the weighted loss.''' + # Update the loss + val = self._losses_func[loss](outputs, inputs) + # self.losses_values[loss] += val.detach() + getattr(self, loss).add_(val.detach()) + # Return a weighted sum + weighted_loss = self._params[loss] * val + return weighted_loss + + def reset(self): + '''Reset the losses to 0.''' + for loss in self.losses: + setattr(self, loss, torch.tensor(0.0, device=getattr(self, loss).device)) + setattr(self, "count", torch.tensor(0.0, device=getattr(self, "count").device)) + + def compute(self, split): + '''Compute the losses and return a dictionary with the losses.''' + count = self.count + # Loss dictionary + loss_dict = {loss: getattr(self, loss)/count for loss in self.losses} + # Format the losses for logging + log_dict = { self.loss2logname(loss, split): value.item() + for loss, value in loss_dict.items() if not torch.isnan(value)} + # Reset the losses + self.reset() + return log_dict + + def loss2logname(self, loss: str, split: str): + '''Convert the loss name to a log name.''' + if loss == "total": + log_name = f"{loss}/{split}" + else: + loss_type, name = loss.split("_") + log_name = f"{loss_type}/{name}/{split}" + return log_name diff --git a/motiondiff_modules/mGPT/losses/mgpt.py b/motiondiff_modules/mGPT/losses/mgpt.py new file mode 100644 index 0000000..69846b2 --- /dev/null +++ b/motiondiff_modules/mGPT/losses/mgpt.py @@ -0,0 +1,97 @@ +import torch +import torch.nn as nn +from .base import BaseLosses + + +class CommitLoss(nn.Module): + """ + Useless Wrapper + """ + def __init__(self, **kwargs): + super().__init__() + + def forward(self, commit, commit2, **kwargs): + return commit + + +class GPTLosses(BaseLosses): + + def __init__(self, cfg, stage, num_joints, **kwargs): + # Save parameters + self.stage = stage + recons_loss = cfg.LOSS.ABLATION.RECONS_LOSS + + # Define losses + losses = [] + params = {} + if stage == "vae": + losses.append("recons_feature") + params['recons_feature'] = cfg.LOSS.LAMBDA_FEATURE + + losses.append("recons_velocity") + params['recons_velocity'] = cfg.LOSS.LAMBDA_VELOCITY + + losses.append("vq_commit") + params['vq_commit'] = cfg.LOSS.LAMBDA_COMMIT + elif stage in ["lm_pretrain", "lm_instruct"]: + losses.append("gpt_loss") + params['gpt_loss'] = cfg.LOSS.LAMBDA_CLS + + # Define loss functions & weights + losses_func = {} + for loss in losses: + if loss.split('_')[0] == 'recons': + if recons_loss == "l1": + losses_func[loss] = nn.L1Loss + elif recons_loss == "l2": + losses_func[loss] = nn.MSELoss + elif recons_loss == "l1_smooth": + losses_func[loss] = nn.SmoothL1Loss + elif loss.split('_')[1] in [ + 'commit', 'loss', 'gpt', 'm2t2m', 't2m2t' + ]: + losses_func[loss] = CommitLoss + elif loss.split('_')[1] in ['cls', 'lm']: + losses_func[loss] = nn.CrossEntropyLoss + else: + raise NotImplementedError(f"Loss {loss} not implemented.") + + super().__init__(cfg, losses, params, losses_func, num_joints, + **kwargs) + + def update(self, rs_set): + '''Update the losses''' + total: float = 0.0 + + if self.stage in ["vae"]: + total += self._update_loss("recons_feature", rs_set['m_rst'], + rs_set['m_ref']) + # total += self._update_loss("recons_joints", rs_set['joints_rst'], rs_set['joints_ref']) + nfeats = rs_set['m_rst'].shape[-1] + if nfeats in [263, 135 + 263]: + if nfeats == 135 + 263: + vel_start = 135 + 4 + elif nfeats == 263: + vel_start = 4 + total += self._update_loss( + "recons_velocity", + rs_set['m_rst'][..., vel_start:(self.num_joints - 1) * 3 + + vel_start], + rs_set['m_ref'][..., vel_start:(self.num_joints - 1) * 3 + + vel_start]) + else: + if self._params['recons_velocity'] != 0.0: + raise NotImplementedError( + "Velocity not implemented for nfeats = {})".format(nfeats)) + total += self._update_loss("vq_commit", rs_set['loss_commit'], + rs_set['loss_commit']) + + if self.stage in ["lm_pretrain", "lm_instruct"]: + total += self._update_loss("gpt_loss", rs_set['outputs'].loss, + rs_set['outputs'].loss) + + # Update the total loss + self.total += total.detach() + self.count += 1 + + return total diff --git a/motiondiff_modules/mGPT/metrics/__init__.py b/motiondiff_modules/mGPT/metrics/__init__.py new file mode 100644 index 0000000..33c2081 --- /dev/null +++ b/motiondiff_modules/mGPT/metrics/__init__.py @@ -0,0 +1 @@ +from .base import BaseMetrics diff --git a/motiondiff_modules/mGPT/metrics/base.py b/motiondiff_modules/mGPT/metrics/base.py new file mode 100644 index 0000000..5407719 --- /dev/null +++ b/motiondiff_modules/mGPT/metrics/base.py @@ -0,0 +1,46 @@ +from torch import Tensor, nn +from os.path import join as pjoin +from .mr import MRMetrics +from .t2m import TM2TMetrics +from .mm import MMMetrics +from .m2t import M2TMetrics +from .m2m import PredMetrics + + +class BaseMetrics(nn.Module): + def __init__(self, cfg, datamodule, debug, **kwargs) -> None: + super().__init__() + + njoints = datamodule.njoints + + data_name = datamodule.name + if data_name in ["humanml3d", "kit"]: + self.TM2TMetrics = TM2TMetrics( + cfg=cfg, + dataname=data_name, + diversity_times=30 if debug else cfg.METRIC.DIVERSITY_TIMES, + dist_sync_on_step=cfg.METRIC.DIST_SYNC_ON_STEP, + ) + self.M2TMetrics = M2TMetrics( + cfg=cfg, + w_vectorizer=datamodule.hparams.w_vectorizer, + diversity_times=30 if debug else cfg.METRIC.DIVERSITY_TIMES, + dist_sync_on_step=cfg.METRIC.DIST_SYNC_ON_STEP) + self.MMMetrics = MMMetrics( + cfg=cfg, + mm_num_times=cfg.METRIC.MM_NUM_TIMES, + dist_sync_on_step=cfg.METRIC.DIST_SYNC_ON_STEP, + ) + + self.MRMetrics = MRMetrics( + njoints=njoints, + jointstype=cfg.DATASET.JOINT_TYPE, + dist_sync_on_step=cfg.METRIC.DIST_SYNC_ON_STEP, + ) + self.PredMetrics = PredMetrics( + cfg=cfg, + njoints=njoints, + jointstype=cfg.DATASET.JOINT_TYPE, + dist_sync_on_step=cfg.METRIC.DIST_SYNC_ON_STEP, + task=cfg.model.params.task, + ) diff --git a/motiondiff_modules/mGPT/metrics/m2m.py b/motiondiff_modules/mGPT/metrics/m2m.py new file mode 100644 index 0000000..780d34d --- /dev/null +++ b/motiondiff_modules/mGPT/metrics/m2m.py @@ -0,0 +1,95 @@ +from typing import List + +import torch +from torch import Tensor +from torchmetrics import Metric + +from .utils import * + + +# motion reconstruction metric +class PredMetrics(Metric): + + def __init__(self, + cfg, + njoints: int = 22, + jointstype: str = "mmm", + force_in_meter: bool = True, + align_root: bool = True, + dist_sync_on_step=True, + task: str = "pred", + **kwargs): + super().__init__(dist_sync_on_step=dist_sync_on_step) + + self.name = 'Motion Prdiction' + self.cfg = cfg + self.jointstype = jointstype + self.align_root = align_root + self.task = task + self.force_in_meter = force_in_meter + + self.add_state("count", default=torch.tensor(0), dist_reduce_fx="sum") + self.add_state("count_seq", + default=torch.tensor(0), + dist_reduce_fx="sum") + + self.add_state("APD", + default=torch.tensor([0.0]), + dist_reduce_fx="sum") + self.add_state("ADE", + default=torch.tensor([0.0]), + dist_reduce_fx="sum") + self.add_state("FDE", + default=torch.tensor([0.0]), + dist_reduce_fx="sum") + + self.MR_metrics = ["APD", "ADE", "FDE"] + + # All metric + self.metrics = self.MR_metrics + + def compute(self, sanity_flag): + + count = self.count + count_seq = self.count_seq + mr_metrics = {} + mr_metrics["APD"] = self.APD / count_seq + mr_metrics["ADE"] = self.ADE / count_seq + mr_metrics["FDE"] = self.FDE / count_seq + + # Reset + self.reset() + + return mr_metrics + + def update(self, joints_rst: Tensor, joints_ref: Tensor, + lengths: List[int]): + + assert joints_rst.shape == joints_ref.shape + assert joints_rst.dim() == 4 + # (bs, seq, njoint=22, 3) + + self.count += sum(lengths) + self.count_seq += len(lengths) + + rst = torch.flatten(joints_rst, start_dim=2) + ref = torch.flatten(joints_ref, start_dim=2) + + for i, l in enumerate(lengths): + if self.task == "pred": + pred_start = int(l*self.cfg.ABLATION.predict_ratio) + diff = rst[i,pred_start:] - ref[i,pred_start:] + elif self.task == "inbetween": + inbetween_start = int(l*self.cfg.ABLATION.inbetween_ratio) + inbetween_end = l - int(l*self.cfg.ABLATION.inbetween_ratio) + diff = rst[i,inbetween_start:inbetween_end] - ref[i,inbetween_start:inbetween_end] + else: + print(f"Task {self.task} not implemented.") + diff = rst - ref + + dist = torch.linalg.norm(diff, dim=-1)[None] + + ade = dist.mean(dim=1) + fde = dist[:,-1] + self.ADE = self.ADE + ade + self.FDE = self.FDE + fde diff --git a/motiondiff_modules/mGPT/metrics/m2t.py b/motiondiff_modules/mGPT/metrics/m2t.py new file mode 100644 index 0000000..6089ac0 --- /dev/null +++ b/motiondiff_modules/mGPT/metrics/m2t.py @@ -0,0 +1,345 @@ +from typing import List +import os +import torch +from torch import Tensor +from torchmetrics import Metric +from .utils import * +from bert_score import score as score_bert +import spacy +from ..config import instantiate_from_config + +class M2TMetrics(Metric): + + def __init__(self, + cfg, + w_vectorizer, + dataname='humanml3d', + top_k=3, + bleu_k=4, + R_size=32, + max_text_len=40, + diversity_times=300, + dist_sync_on_step=True, + unit_length=4, + **kwargs): + super().__init__(dist_sync_on_step=dist_sync_on_step) + + self.cfg = cfg + self.dataname = dataname + self.w_vectorizer = w_vectorizer + self.name = "matching, fid, and diversity scores" + # self.text = True if cfg.TRAIN.STAGE in ["diffusion","t2m_gpt"] else False + self.max_text_len = max_text_len + self.top_k = top_k + self.bleu_k = bleu_k + self.R_size = R_size + self.diversity_times = diversity_times + self.unit_length = unit_length + + self.add_state("count", default=torch.tensor(0), dist_reduce_fx="sum") + self.add_state("count_seq", + default=torch.tensor(0), + dist_reduce_fx="sum") + + self.metrics = [] + + # Matching scores + self.add_state("Matching_score", + default=torch.tensor(0.0), + dist_reduce_fx="sum") + self.add_state("gt_Matching_score", + default=torch.tensor(0.0), + dist_reduce_fx="sum") + self.Matching_metrics = ["Matching_score", "gt_Matching_score"] + for k in range(1, top_k + 1): + self.add_state( + f"R_precision_top_{str(k)}", + default=torch.tensor(0.0), + dist_reduce_fx="sum", + ) + self.Matching_metrics.append(f"R_precision_top_{str(k)}") + for k in range(1, top_k + 1): + self.add_state( + f"gt_R_precision_top_{str(k)}", + default=torch.tensor(0.0), + dist_reduce_fx="sum", + ) + self.Matching_metrics.append(f"gt_R_precision_top_{str(k)}") + + self.metrics.extend(self.Matching_metrics) + + # NLG + for k in range(1, top_k + 1): + self.add_state( + f"Bleu_{str(k)}", + default=torch.tensor(0.0), + dist_reduce_fx="sum", + ) + self.metrics.append(f"Bleu_{str(k)}") + + self.add_state("ROUGE_L", + default=torch.tensor(0.0), + dist_reduce_fx="sum") + self.metrics.append("ROUGE_L") + + self.add_state("CIDEr", + default=torch.tensor(0.0), + dist_reduce_fx="sum") + self.metrics.append("CIDEr") + + # Chached batches + self.pred_texts = [] + self.gt_texts = [] + self.add_state("predtext_embeddings", default=[]) + self.add_state("gttext_embeddings", default=[]) + self.add_state("gtmotion_embeddings", default=[]) + + # T2M Evaluator + self._get_t2m_evaluator(cfg) + + self.nlp = spacy.load('en_core_web_sm') + + if self.cfg.model.params.task == 'm2t': + from nlgmetricverse import NLGMetricverse, load_metric + metrics = [ + load_metric("bleu", resulting_name="bleu_1", compute_kwargs={"max_order": 1}), + load_metric("bleu", resulting_name="bleu_4", compute_kwargs={"max_order": 4}), + load_metric("rouge"), + load_metric("cider"), + ] + self.nlg_evaluator = NLGMetricverse(metrics) + + def _get_t2m_evaluator(self, cfg): + """ + load T2M text encoder and motion encoder for evaluating + """ + # init module + self.t2m_textencoder = instantiate_from_config(cfg.METRIC.TM2T.t2m_textencoder) + self.t2m_moveencoder = instantiate_from_config(cfg.METRIC.TM2T.t2m_moveencoder) + self.t2m_motionencoder = instantiate_from_config(cfg.METRIC.TM2T.t2m_motionencoder) + + + # load pretrianed + if self.dataname == "kit": + dataname = "kit" + else: + dataname = "t2m" + + t2m_checkpoint = torch.load(os.path.join( + cfg.METRIC.TM2T.t2m_path, dataname, "text_mot_match/model/finest.tar"), + map_location='cpu') + self.t2m_textencoder.load_state_dict(t2m_checkpoint["text_encoder"]) + self.t2m_moveencoder.load_state_dict( + t2m_checkpoint["movement_encoder"]) + self.t2m_motionencoder.load_state_dict( + t2m_checkpoint["motion_encoder"]) + + # freeze params + self.t2m_textencoder.eval() + self.t2m_moveencoder.eval() + self.t2m_motionencoder.eval() + for p in self.t2m_textencoder.parameters(): + p.requires_grad = False + for p in self.t2m_moveencoder.parameters(): + p.requires_grad = False + for p in self.t2m_motionencoder.parameters(): + p.requires_grad = False + + def _process_text(self, sentence): + sentence = sentence.replace('-', '') + doc = self.nlp(sentence) + word_list = [] + pos_list = [] + for token in doc: + word = token.text + if not word.isalpha(): + continue + if (token.pos_ == 'NOUN' + or token.pos_ == 'VERB') and (word != 'left'): + word_list.append(token.lemma_) + else: + word_list.append(word) + pos_list.append(token.pos_) + return word_list, pos_list + + def _get_text_embeddings(self, texts): + word_embs = [] + pos_ohot = [] + text_lengths = [] + for i, sentence in enumerate(texts): + word_list, pos_list = self._process_text(sentence.strip()) + t_tokens = [ + '%s/%s' % (word_list[i], pos_list[i]) + for i in range(len(word_list)) + ] + + if len(t_tokens) < self.max_text_len: + # pad with "unk" + tokens = ['sos/OTHER'] + t_tokens + ['eos/OTHER'] + sent_len = len(tokens) + tokens = tokens + ['unk/OTHER' + ] * (self.max_text_len + 2 - sent_len) + else: + # crop + tokens = t_tokens[:self.max_text_len] + tokens = ['sos/OTHER'] + tokens + ['eos/OTHER'] + sent_len = len(tokens) + pos_one_hots = [] + word_embeddings = [] + for token in tokens: + word_emb, pos_oh = self.w_vectorizer[token] + pos_one_hots.append(torch.tensor(pos_oh).float()[None]) + word_embeddings.append(torch.tensor(word_emb).float()[None]) + text_lengths.append(sent_len) + pos_ohot.append(torch.cat(pos_one_hots, dim=0)[None]) + word_embs.append(torch.cat(word_embeddings, dim=0)[None]) + + word_embs = torch.cat(word_embs, dim=0).to(self.Matching_score) + pos_ohot = torch.cat(pos_ohot, dim=0).to(self.Matching_score) + text_lengths = torch.tensor(text_lengths).to(self.Matching_score) + + align_idx = np.argsort(text_lengths.data.tolist())[::-1].copy() + + # get text embeddings + text_embeddings = self.t2m_textencoder(word_embs[align_idx], + pos_ohot[align_idx], + text_lengths[align_idx]) + + original_text_embeddings = text_embeddings.clone() + + for idx, sort in enumerate(align_idx): + original_text_embeddings[sort] = text_embeddings[idx] + + return original_text_embeddings + + @torch.no_grad() + def compute(self, sanity_flag): + count = self.count.item() + count_seq = self.count_seq.item() + + # Init metrics dict + metrics = {metric: getattr(self, metric) for metric in self.metrics} + + # Jump in sanity check stage + if sanity_flag: + return metrics + + # Cat cached batches and shuffle + shuffle_idx = torch.randperm(count_seq) + all_motions = torch.cat(self.gtmotion_embeddings, + axis=0).cpu()[shuffle_idx, :] + all_gttexts = torch.cat(self.gttext_embeddings, + axis=0).cpu()[shuffle_idx, :] + all_predtexts = torch.cat(self.predtext_embeddings, + axis=0).cpu()[shuffle_idx, :] + + print("Computing metrics...") + + # Compute r-precision + assert count_seq >= self.R_size + top_k_mat = torch.zeros((self.top_k, )) + for i in range(count_seq // self.R_size): + # [bs=32, 1*256] + group_texts = all_predtexts[i * self.R_size:(i + 1) * self.R_size] + # [bs=32, 1*256] + group_motions = all_motions[i * self.R_size:(i + 1) * self.R_size] + # [bs=32, 32] + dist_mat = euclidean_distance_matrix(group_texts, + group_motions).nan_to_num() + # print(dist_mat[:5]) + self.Matching_score += dist_mat.trace() + argsmax = torch.argsort(dist_mat, dim=1) + top_k_mat += calculate_top_k(argsmax, top_k=self.top_k).sum(axis=0) + + R_count = count_seq // self.R_size * self.R_size + metrics["Matching_score"] = self.Matching_score / R_count + for k in range(self.top_k): + metrics[f"R_precision_top_{str(k+1)}"] = top_k_mat[k] / R_count + + # Compute r-precision with gt + assert count_seq >= self.R_size + top_k_mat = torch.zeros((self.top_k, )) + for i in range(count_seq // self.R_size): + # [bs=32, 1*256] + group_texts = all_gttexts[i * self.R_size:(i + 1) * self.R_size] + # [bs=32, 1*256] + group_motions = all_motions[i * self.R_size:(i + 1) * self.R_size] + # [bs=32, 32] + dist_mat = euclidean_distance_matrix(group_texts, + group_motions).nan_to_num() + # match score + self.gt_Matching_score += dist_mat.trace() + argsmax = torch.argsort(dist_mat, dim=1) + top_k_mat += calculate_top_k(argsmax, top_k=self.top_k).sum(axis=0) + metrics["gt_Matching_score"] = self.gt_Matching_score / R_count + for k in range(self.top_k): + metrics[f"gt_R_precision_top_{str(k+1)}"] = top_k_mat[k] / R_count + + # NLP metrics + scores = self.nlg_evaluator(predictions=self.pred_texts, + references=self.gt_texts) + for k in range(1, self.bleu_k + 1): + metrics[f"Bleu_{str(k)}"] = torch.tensor(scores[f'bleu_{str(k)}'], + device=self.device) + + metrics["ROUGE_L"] = torch.tensor(scores["rouge"]["rougeL"], + device=self.device) + metrics["CIDEr"] = torch.tensor(scores["cider"]['score'],device=self.device) + + # Bert metrics + P, R, F1 = score_bert(self.pred_texts, + self.gt_texts, + lang='en', + rescale_with_baseline=True, + idf=True, + device=self.device, + verbose=False) + + metrics["Bert_F1"] = F1.mean() + + # Reset + self.reset() + self.gt_texts = [] + self.pred_texts = [] + + return {**metrics} + + @torch.no_grad() + def update(self, + feats_ref: Tensor, + pred_texts: List[str], + gt_texts: List[str], + lengths: List[int], + word_embs: Tensor = None, + pos_ohot: Tensor = None, + text_lengths: Tensor = None): + + self.count += sum(lengths) + self.count_seq += len(lengths) + + # motion encoder + m_lens = torch.tensor(lengths, device=feats_ref.device) + align_idx = np.argsort(m_lens.data.tolist())[::-1].copy() + feats_ref = feats_ref[align_idx] + m_lens = m_lens[align_idx] + m_lens = torch.div(m_lens, + self.cfg.DATASET.HUMANML3D.UNIT_LEN, + rounding_mode="floor") + ref_mov = self.t2m_moveencoder(feats_ref[..., :-4]).detach() + m_lens = m_lens // self.unit_length + ref_emb = self.t2m_motionencoder(ref_mov, m_lens) + gtmotion_embeddings = torch.flatten(ref_emb, start_dim=1).detach() + self.gtmotion_embeddings.append(gtmotion_embeddings) + + # text encoder + gttext_emb = self.t2m_textencoder(word_embs, pos_ohot, + text_lengths)[align_idx] + gttext_embeddings = torch.flatten(gttext_emb, start_dim=1).detach() + predtext_emb = self._get_text_embeddings(pred_texts)[align_idx] + predtext_embeddings = torch.flatten(predtext_emb, start_dim=1).detach() + + self.gttext_embeddings.append(gttext_embeddings) + self.predtext_embeddings.append(predtext_embeddings) + + self.pred_texts.extend(pred_texts) + self.gt_texts.extend(gt_texts) diff --git a/motiondiff_modules/mGPT/metrics/mm.py b/motiondiff_modules/mGPT/metrics/mm.py new file mode 100644 index 0000000..5fedabb --- /dev/null +++ b/motiondiff_modules/mGPT/metrics/mm.py @@ -0,0 +1,129 @@ +from typing import List + +import torch +from torch import Tensor +from torchmetrics import Metric +from torchmetrics.functional import pairwise_euclidean_distance +from .utils import * +import os +from ..config import instantiate_from_config + +class MMMetrics(Metric): + full_state_update = True + + def __init__(self, cfg, dataname='humanml3d', mm_num_times=10, dist_sync_on_step=True, **kwargs): + super().__init__(dist_sync_on_step=dist_sync_on_step) + + self.name = "MultiModality scores" + self.cfg = cfg + self.dataname = dataname + self.mm_num_times = mm_num_times + + self.add_state("count", default=torch.tensor(0), dist_reduce_fx="sum") + self.add_state("count_seq", + default=torch.tensor(0), + dist_reduce_fx="sum") + + self.metrics = ["MultiModality"] + self.add_state("MultiModality", + default=torch.tensor(0.), + dist_reduce_fx="sum") + + # chached batches + self.add_state("mm_motion_embeddings", default=[], dist_reduce_fx=None) + + # T2M Evaluator + self._get_t2m_evaluator(cfg) + + def _get_t2m_evaluator(self, cfg): + """ + load T2M text encoder and motion encoder for evaluating + """ + # init module + self.t2m_textencoder = instantiate_from_config(cfg.METRIC.TM2T.t2m_textencoder) + self.t2m_moveencoder = instantiate_from_config(cfg.METRIC.TM2T.t2m_moveencoder) + self.t2m_motionencoder = instantiate_from_config(cfg.METRIC.TM2T.t2m_motionencoder) + + # load pretrianed + if self.dataname == "kit": + dataname = "kit" + else: + dataname = "t2m" + t2m_checkpoint = torch.load(os.path.join( + cfg.METRIC.TM2T.t2m_path, dataname, + "text_mot_match/model/finest.tar"), + map_location="cpu") + + self.t2m_textencoder.load_state_dict(t2m_checkpoint["text_encoder"]) + self.t2m_moveencoder.load_state_dict( + t2m_checkpoint["movement_encoder"]) + self.t2m_motionencoder.load_state_dict( + t2m_checkpoint["motion_encoder"]) + + # freeze params + self.t2m_textencoder.eval() + self.t2m_moveencoder.eval() + self.t2m_motionencoder.eval() + for p in self.t2m_textencoder.parameters(): + p.requires_grad = False + for p in self.t2m_moveencoder.parameters(): + p.requires_grad = False + for p in self.t2m_motionencoder.parameters(): + p.requires_grad = False + + def compute(self, sanity_flag): + count = self.count.item() + count_seq = self.count_seq.item() + + # init metrics + metrics = {metric: getattr(self, metric) for metric in self.metrics} + + # if in sanity check stage then jump + if sanity_flag: + return metrics + + # cat all embeddings + all_mm_motions = torch.cat(self.mm_motion_embeddings, + axis=0).cpu().numpy() + metrics['MultiModality'] = calculate_multimodality_np( + all_mm_motions, self.mm_num_times) + + # Reset + self.reset() + + return {**metrics} + + def update( + self, + feats_rst: Tensor, + lengths_rst: List[int], + ): + self.count += sum(lengths_rst) + self.count_seq += len(lengths_rst) + + align_idx = np.argsort(lengths_rst)[::-1].copy() + feats_rst = feats_rst[align_idx] + lengths_rst = np.array(lengths_rst)[align_idx] + recmotion_embeddings = self.get_motion_embeddings( + feats_rst, lengths_rst) + cache = [0] * len(lengths_rst) + for i in range(len(lengths_rst)): + cache[align_idx[i]] = recmotion_embeddings[i:i + 1] + + mm_motion_embeddings = torch.cat(cache, axis=0).unsqueeze(0) + # self.mm_motion_embeddings.extend(cache) + # print(mm_motion_embeddings.shape) + # # store all mm motion embeddings + self.mm_motion_embeddings.append(mm_motion_embeddings) + + def get_motion_embeddings(self, feats: Tensor, lengths: List[int]): + m_lens = torch.tensor(lengths) + m_lens = torch.div(m_lens, + self.cfg.DATASET.HUMANML3D.UNIT_LEN, + rounding_mode="floor") + + mov = self.t2m_moveencoder(feats[..., :-4]).detach() + emb = self.t2m_motionencoder(mov, m_lens) + + # [bs, nlatent*ndim] <= [bs, nlatent, ndim] + return torch.flatten(emb, start_dim=1).detach() diff --git a/motiondiff_modules/mGPT/metrics/mr.py b/motiondiff_modules/mGPT/metrics/mr.py new file mode 100644 index 0000000..ba5129f --- /dev/null +++ b/motiondiff_modules/mGPT/metrics/mr.py @@ -0,0 +1,97 @@ +from typing import List + +import torch +from torch import Tensor +from torchmetrics import Metric + +from .utils import * + + +# motion reconstruction metric +class MRMetrics(Metric): + + def __init__(self, + njoints, + jointstype: str = "mmm", + force_in_meter: bool = True, + align_root: bool = True, + dist_sync_on_step=True, + **kwargs): + super().__init__(dist_sync_on_step=dist_sync_on_step) + + self.name = 'Motion Reconstructions' + self.jointstype = jointstype + self.align_root = align_root + self.force_in_meter = force_in_meter + + self.add_state("count", default=torch.tensor(0), dist_reduce_fx="sum") + self.add_state("count_seq", + default=torch.tensor(0), + dist_reduce_fx="sum") + + self.add_state("MPJPE", + default=torch.tensor([0.0]), + dist_reduce_fx="sum") + self.add_state("PAMPJPE", + default=torch.tensor([0.0]), + dist_reduce_fx="sum") + self.add_state("ACCEL", + default=torch.tensor([0.0]), + dist_reduce_fx="sum") + # todo + # self.add_state("ROOT", default=torch.tensor([0.0]), dist_reduce_fx="sum") + + self.MR_metrics = ["MPJPE", "PAMPJPE", "ACCEL"] + + # All metric + self.metrics = self.MR_metrics + + def compute(self, sanity_flag): + if self.force_in_meter: + # different jointstypes have different scale factors + # if self.jointstype == 'mmm': + # factor = 1000.0 + # elif self.jointstype == 'humanml3d': + # factor = 1000.0 * 0.75 / 480 + factor = 1000.0 + else: + factor = 1.0 + + count = self.count + count_seq = self.count_seq + mr_metrics = {} + mr_metrics["MPJPE"] = self.MPJPE / count * factor + mr_metrics["PAMPJPE"] = self.PAMPJPE / count * factor + # accel error: joints_gt[:-2] - 2 * joints_gt[1:-1] + joints_gt[2:] + # n-2 for each sequences + mr_metrics["ACCEL"] = self.ACCEL / (count - 2 * count_seq) * factor + + # Reset + self.reset() + + return mr_metrics + + def update(self, joints_rst: Tensor, joints_ref: Tensor, + lengths: List[int]): + assert joints_rst.shape == joints_ref.shape + assert joints_rst.dim() == 4 + # (bs, seq, njoint=22, 3) + + self.count += sum(lengths) + self.count_seq += len(lengths) + + # avoid cuda error of DDP in pampjpe + rst = joints_rst.detach().cpu() + ref = joints_ref.detach().cpu() + + # align root joints index + if self.align_root and self.jointstype in ['mmm', 'humanml3d']: + align_inds = [0] + else: + align_inds = None + + for i in range(len(lengths)): + self.MPJPE += torch.sum( + calc_mpjpe(rst[i], ref[i], align_inds=align_inds)) + self.PAMPJPE += torch.sum(calc_pampjpe(rst[i], ref[i])) + self.ACCEL += torch.sum(calc_accel(rst[i], ref[i])) diff --git a/motiondiff_modules/mGPT/metrics/t2m.py b/motiondiff_modules/mGPT/metrics/t2m.py new file mode 100644 index 0000000..534e10d --- /dev/null +++ b/motiondiff_modules/mGPT/metrics/t2m.py @@ -0,0 +1,259 @@ +from typing import List +import os +import torch +from torch import Tensor +from torchmetrics import Metric +from torchmetrics.functional import pairwise_euclidean_distance +from .utils import * +from ..config import instantiate_from_config + +class TM2TMetrics(Metric): + def __init__(self, + cfg, + dataname='humanml3d', + top_k=3, + R_size=32, + diversity_times=300, + dist_sync_on_step=True, + **kwargs): + super().__init__(dist_sync_on_step=dist_sync_on_step) + + self.cfg = cfg + self.dataname = dataname + self.name = "matching, fid, and diversity scores" + self.top_k = top_k + self.R_size = R_size + self.text = 'lm' in cfg.TRAIN.STAGE and cfg.model.params.task == 't2m' + self.diversity_times = diversity_times + + self.add_state("count", default=torch.tensor(0), dist_reduce_fx="sum") + self.add_state("count_seq", + default=torch.tensor(0), + dist_reduce_fx="sum") + + self.metrics = [] + + # Matching scores + if self.text: + self.add_state("Matching_score", + default=torch.tensor(0.0), + dist_reduce_fx="sum") + self.add_state("gt_Matching_score", + default=torch.tensor(0.0), + dist_reduce_fx="sum") + self.Matching_metrics = ["Matching_score", "gt_Matching_score"] + for k in range(1, top_k + 1): + self.add_state( + f"R_precision_top_{str(k)}", + default=torch.tensor(0.0), + dist_reduce_fx="sum", + ) + self.Matching_metrics.append(f"R_precision_top_{str(k)}") + for k in range(1, top_k + 1): + self.add_state( + f"gt_R_precision_top_{str(k)}", + default=torch.tensor(0.0), + dist_reduce_fx="sum", + ) + self.Matching_metrics.append(f"gt_R_precision_top_{str(k)}") + self.metrics.extend(self.Matching_metrics) + + # Fid + self.add_state("FID", default=torch.tensor(0.0), dist_reduce_fx="sum") + self.metrics.append("FID") + + # Diversity + self.add_state("Diversity", + default=torch.tensor(0.0), + dist_reduce_fx="sum") + self.add_state("gt_Diversity", + default=torch.tensor(0.0), + dist_reduce_fx="sum") + self.metrics.extend(["Diversity", "gt_Diversity"]) + + # Chached batches + self.add_state("text_embeddings", default=[], dist_reduce_fx=None) + self.add_state("recmotion_embeddings", default=[], dist_reduce_fx=None) + self.add_state("gtmotion_embeddings", default=[], dist_reduce_fx=None) + + # T2M Evaluator + self._get_t2m_evaluator(cfg) + + def _get_t2m_evaluator(self, cfg): + """ + load T2M text encoder and motion encoder for evaluating + """ + # init module + self.t2m_textencoder = instantiate_from_config(cfg.METRIC.TM2T.t2m_textencoder) + self.t2m_moveencoder = instantiate_from_config(cfg.METRIC.TM2T.t2m_moveencoder) + self.t2m_motionencoder = instantiate_from_config(cfg.METRIC.TM2T.t2m_motionencoder) + + + # load pretrianed + if self.dataname == "kit": + dataname = "kit" + else: + dataname = "t2m" + + t2m_checkpoint = torch.load(os.path.join( + cfg.METRIC.TM2T.t2m_path, dataname, "text_mot_match/model/finest.tar"), + map_location="cpu") + + self.t2m_textencoder.load_state_dict(t2m_checkpoint["text_encoder"]) + self.t2m_moveencoder.load_state_dict( + t2m_checkpoint["movement_encoder"]) + self.t2m_motionencoder.load_state_dict( + t2m_checkpoint["motion_encoder"]) + + # freeze params + self.t2m_textencoder.eval() + self.t2m_moveencoder.eval() + self.t2m_motionencoder.eval() + for p in self.t2m_textencoder.parameters(): + p.requires_grad = False + for p in self.t2m_moveencoder.parameters(): + p.requires_grad = False + for p in self.t2m_motionencoder.parameters(): + p.requires_grad = False + + @torch.no_grad() + def compute(self, sanity_flag): + count = self.count.item() + count_seq = self.count_seq.item() + + # Init metrics dict + metrics = {metric: getattr(self, metric) for metric in self.metrics} + + # Jump in sanity check stage + if sanity_flag: + return metrics + + # Cat cached batches and shuffle + shuffle_idx = torch.randperm(count_seq) + + all_genmotions = torch.cat(self.recmotion_embeddings, + axis=0).cpu()[shuffle_idx, :] + all_gtmotions = torch.cat(self.gtmotion_embeddings, + axis=0).cpu()[shuffle_idx, :] + + # Compute text related metrics + if self.text: + all_texts = torch.cat(self.text_embeddings, + axis=0).cpu()[shuffle_idx, :] + # Compute r-precision + assert count_seq > self.R_size + top_k_mat = torch.zeros((self.top_k, )) + for i in range(count_seq // self.R_size): + # [bs=32, 1*256] + group_texts = all_texts[i * self.R_size:(i + 1) * self.R_size] + # [bs=32, 1*256] + group_motions = all_genmotions[i * self.R_size:(i + 1) * + self.R_size] + # dist_mat = pairwise_euclidean_distance(group_texts, group_motions) + # [bs=32, 32] + dist_mat = euclidean_distance_matrix( + group_texts, group_motions).nan_to_num() + # print(dist_mat[:5]) + self.Matching_score += dist_mat.trace() + argsmax = torch.argsort(dist_mat, dim=1) + top_k_mat += calculate_top_k(argsmax, + top_k=self.top_k).sum(axis=0) + + R_count = count_seq // self.R_size * self.R_size + metrics["Matching_score"] = self.Matching_score / R_count + for k in range(self.top_k): + metrics[f"R_precision_top_{str(k+1)}"] = top_k_mat[k] / R_count + + # Compute r-precision with gt + assert count_seq > self.R_size + top_k_mat = torch.zeros((self.top_k, )) + for i in range(count_seq // self.R_size): + # [bs=32, 1*256] + group_texts = all_texts[i * self.R_size:(i + 1) * self.R_size] + # [bs=32, 1*256] + group_motions = all_gtmotions[i * self.R_size:(i + 1) * + self.R_size] + # [bs=32, 32] + dist_mat = euclidean_distance_matrix( + group_texts, group_motions).nan_to_num() + # match score + self.gt_Matching_score += dist_mat.trace() + argsmax = torch.argsort(dist_mat, dim=1) + top_k_mat += calculate_top_k(argsmax, + top_k=self.top_k).sum(axis=0) + metrics["gt_Matching_score"] = self.gt_Matching_score / R_count + for k in range(self.top_k): + metrics[f"gt_R_precision_top_{str(k+1)}"] = top_k_mat[k] / R_count + + # tensor -> numpy for FID + all_genmotions = all_genmotions.numpy() + all_gtmotions = all_gtmotions.numpy() + + # Compute fid + mu, cov = calculate_activation_statistics_np(all_genmotions) + gt_mu, gt_cov = calculate_activation_statistics_np(all_gtmotions) + metrics["FID"] = calculate_frechet_distance_np(gt_mu, gt_cov, mu, cov) + + # Compute diversity + assert count_seq > self.diversity_times + metrics["Diversity"] = calculate_diversity_np(all_genmotions, + self.diversity_times) + metrics["gt_Diversity"] = calculate_diversity_np( + all_gtmotions, self.diversity_times) + + # Reset + self.reset() + + return {**metrics} + + @torch.no_grad() + def update(self, + feats_ref: Tensor, + feats_rst: Tensor, + lengths_ref: List[int], + lengths_rst: List[int], + word_embs: Tensor = None, + pos_ohot: Tensor = None, + text_lengths: Tensor = None): + + self.count += sum(lengths_ref) + self.count_seq += len(lengths_ref) + + # T2m motion encoder + align_idx = np.argsort(lengths_ref)[::-1].copy() + feats_ref = feats_ref[align_idx] + lengths_ref = np.array(lengths_ref)[align_idx] + gtmotion_embeddings = self.get_motion_embeddings( + feats_ref, lengths_ref) + cache = [0] * len(lengths_ref) + for i in range(len(lengths_ref)): + cache[align_idx[i]] = gtmotion_embeddings[i:i + 1] + self.gtmotion_embeddings.extend(cache) + + align_idx = np.argsort(lengths_rst)[::-1].copy() + feats_rst = feats_rst[align_idx] + lengths_rst = np.array(lengths_rst)[align_idx] + recmotion_embeddings = self.get_motion_embeddings( + feats_rst, lengths_rst) + cache = [0] * len(lengths_rst) + for i in range(len(lengths_rst)): + cache[align_idx[i]] = recmotion_embeddings[i:i + 1] + self.recmotion_embeddings.extend(cache) + + # T2m text encoder + if self.text: + text_emb = self.t2m_textencoder(word_embs, pos_ohot, text_lengths) + text_embeddings = torch.flatten(text_emb, start_dim=1).detach() + self.text_embeddings.append(text_embeddings) + + def get_motion_embeddings(self, feats: Tensor, lengths: List[int]): + m_lens = torch.tensor(lengths) + m_lens = torch.div(m_lens, + self.cfg.DATASET.HUMANML3D.UNIT_LEN, + rounding_mode="floor") + m_lens = m_lens // self.cfg.DATASET.HUMANML3D.UNIT_LEN + mov = self.t2m_moveencoder(feats[..., :-4]).detach() + emb = self.t2m_motionencoder(mov, m_lens) + + # [bs, nlatent*ndim] <= [bs, nlatent, ndim] + return torch.flatten(emb, start_dim=1).detach() diff --git a/motiondiff_modules/mGPT/metrics/utils.py b/motiondiff_modules/mGPT/metrics/utils.py new file mode 100644 index 0000000..40e536f --- /dev/null +++ b/motiondiff_modules/mGPT/metrics/utils.py @@ -0,0 +1,607 @@ +import numpy as np +import scipy.linalg +import torch +from torch import linalg +import sys + + +def l2_norm(x1, x2, dim): + return torch.linalg.vector_norm(x1 - x2, ord=2, dim=dim) + + +def variance(x, T, dim): + mean = x.mean(dim) + out = (x - mean)**2 + out = out.sum(dim) + return out / (T - 1) + + +def sqrtm(input): + m = input.detach().cpu().numpy().astype(np.float64_) + sqrtm = torch.from_numpy(scipy.linalg.sqrtm(m)).to(input) + return sqrtm + + +# (X - X_train)*(X - X_train) = -2X*X_train + X*X + X_train*X_train +def euclidean_distance_matrix(matrix1, matrix2): + """ + Params: + -- matrix1: N1 x D + -- matrix2: N2 x D + Returns: + -- dist: N1 x N2 + dist[i, j] == distance(matrix1[i], matrix2[j]) + """ + assert matrix1.shape[1] == matrix2.shape[1] + d1 = -2 * torch.mm(matrix1, matrix2.T) # shape (num_test, num_train) + d2 = torch.sum(torch.square(matrix1), axis=1, + keepdims=True) # shape (num_test, 1) + d3 = torch.sum(torch.square(matrix2), axis=1) # shape (num_train, ) + dists = torch.sqrt(d1 + d2 + d3) # broadcasting + return dists + + +def euclidean_distance_matrix_np(matrix1, matrix2): + """ + Params: + -- matrix1: N1 x D + -- matrix2: N2 x D + Returns: + -- dist: N1 x N2 + dist[i, j] == distance(matrix1[i], matrix2[j]) + """ + assert matrix1.shape[1] == matrix2.shape[1] + d1 = -2 * np.dot(matrix1, matrix2.T) # shape (num_test, num_train) + d2 = np.sum(np.square(matrix1), axis=1, + keepdims=True) # shape (num_test, 1) + d3 = np.sum(np.square(matrix2), axis=1) # shape (num_train, ) + dists = np.sqrt(d1 + d2 + d3) # broadcasting + return dists + + +def calculate_top_k(mat, top_k): + size = mat.shape[0] + gt_mat = (torch.unsqueeze(torch.arange(size), + 1).to(mat.device).repeat_interleave(size, 1)) + bool_mat = mat == gt_mat + correct_vec = False + top_k_list = [] + for i in range(top_k): + # print(correct_vec, bool_mat[:, i]) + correct_vec = correct_vec | bool_mat[:, i] + # print(correct_vec) + top_k_list.append(correct_vec[:, None]) + top_k_mat = torch.cat(top_k_list, dim=1) + return top_k_mat + + +def calculate_activation_statistics(activations): + """ + Params: + -- activation: num_samples x dim_feat + Returns: + -- mu: dim_feat + -- sigma: dim_feat x dim_feat + """ + activations = activations.cpu().numpy() + mu = np.mean(activations, axis=0) + sigma = np.cov(activations, rowvar=False) + return mu, sigma + + +def calculate_activation_statistics_np(activations): + """ + Params: + -- activation: num_samples x dim_feat + Returns: + -- mu: dim_feat + -- sigma: dim_feat x dim_feat + """ + mu = np.mean(activations, axis=0) + cov = np.cov(activations, rowvar=False) + return mu, cov + + +# def calculate_frechet_distance(mu1, sigma1, mu2, sigma2, eps=1e-6): +# """Numpy implementation of the Frechet Distance. +# The Frechet distance between two multivariate Gaussians X_1 ~ N(mu_1, C_1) +# and X_2 ~ N(mu_2, C_2) is +# d^2 = ||mu_1 - mu_2||^2 + Tr(C_1 + C_2 - 2*sqrt(C_1*C_2)). +# Stable version by Dougal J. Sutherland. +# Params: +# -- mu1 : Numpy array containing the activations of a layer of the +# inception net (like returned by the function 'get_predictions') +# for generated samples. +# -- mu2 : The sample mean over activations, precalculated on an +# representative data set. +# -- sigma1: The covariance matrix over activations for generated samples. +# -- sigma2: The covariance matrix over activations, precalculated on an +# representative data set. +# Returns: +# -- : The Frechet Distance. +# """ + +# mu1 = torch.atleast_1d(mu1) +# mu2 = torch.atleast_1d(mu2) + +# sigma1 = torch.atleast_2d(sigma1) +# sigma2 = torch.atleast_2d(sigma2) + +# assert mu1.shape == mu2.shape, \ +# 'Training and test mean vectors have different lengths' +# assert sigma1.shape == sigma2.shape, \ +# 'Training and test covariances have different dimensions' + +# diff = mu1 - mu2 + +# # Product might be almost singular +# # covmean, _ = sqrtm(sigma1.dot(sigma2), disp=False) +# covmean = sqrtm(torch.mm(sigma1,sigma2)) +# if not torch.isfinite(covmean).all(): +# msg = ('fid calculation produces singular product; ' +# 'adding %s to diagonal of cov estimates') % eps +# print(msg) +# offset = torch.eye(sigma1.shape[0]) * eps +# # covmean = sqrtm((sigma1 + offset).dot(sigma2 + offset)) +# covmean = sqrtm(torch.mm(sigma1+ offset,sigma2+ offset)) + +# # Numerical error might give slight imaginary component +# if torch.is_complex(covmean): +# if not torch.allclose(torch.diagonal(covmean).imag, 0, atol=1e-3): +# m = torch.max(torch.abs(covmean.imag)) +# raise ValueError('Imaginary component {}'.format(m)) +# covmean = covmean.real + +# tr_covmean = torch.trace(covmean) + +# return (diff.dot(diff) + torch.trace(sigma1) + +# torch.trace(sigma2) - 2 * tr_covmean) + + +def calculate_frechet_distance_np(mu1, sigma1, mu2, sigma2, eps=1e-6): + """Numpy implementation of the Frechet Distance. + The Frechet distance between two multivariate Gaussians X_1 ~ N(mu_1, C_1) + and X_2 ~ N(mu_2, C_2) is + d^2 = ||mu_1 - mu_2||^2 + Tr(C_1 + C_2 - 2*sqrt(C_1*C_2)). + Stable version by Dougal J. Sutherland. + Params: + -- mu1 : Numpy array containing the activations of a layer of the + inception net (like returned by the function 'get_predictions') + for generated samples. + -- mu2 : The sample mean over activations, precalculated on an + representative data set. + -- sigma1: The covariance matrix over activations for generated samples. + -- sigma2: The covariance matrix over activations, precalculated on an + representative data set. + Returns: + -- : The Frechet Distance. + """ + + mu1 = np.atleast_1d(mu1) + mu2 = np.atleast_1d(mu2) + + sigma1 = np.atleast_2d(sigma1) + sigma2 = np.atleast_2d(sigma2) + + assert (mu1.shape == mu2.shape + ), "Training and test mean vectors have different lengths" + assert (sigma1.shape == sigma2.shape + ), "Training and test covariances have different dimensions" + + diff = mu1 - mu2 + # Product might be almost singular + covmean, _ = scipy.linalg.sqrtm(sigma1.dot(sigma2), disp=False) + if not np.isfinite(covmean).all(): + msg = ("fid calculation produces singular product; " + "adding %s to diagonal of cov estimates") % eps + print(msg) + offset = np.eye(sigma1.shape[0]) * eps + covmean = scipy.linalg.sqrtm((sigma1 + offset).dot(sigma2 + offset)) + + # Numerical error might give slight imaginary component + if np.iscomplexobj(covmean): + if not np.allclose(np.diagonal(covmean).imag, 0, atol=1e-3): + m = np.max(np.abs(covmean.imag)) + raise ValueError("Imaginary component {}".format(m)) + # print("Imaginary component {}".format(m)) + covmean = covmean.real + tr_covmean = np.trace(covmean) + + return diff.dot(diff) + np.trace(sigma1) + np.trace( + sigma2) - 2 * tr_covmean + + +def calculate_diversity(activation, diversity_times): + assert len(activation.shape) == 2 + assert activation.shape[0] > diversity_times + num_samples = activation.shape[0] + + first_indices = np.random.choice(num_samples, + diversity_times, + replace=False) + second_indices = np.random.choice(num_samples, + diversity_times, + replace=False) + dist = linalg.norm(activation[first_indices] - activation[second_indices], + axis=1) + return dist.mean() + + +def calculate_diversity_np(activation, diversity_times): + assert len(activation.shape) == 2 + assert activation.shape[0] > diversity_times + num_samples = activation.shape[0] + + first_indices = np.random.choice(num_samples, + diversity_times, + replace=False) + second_indices = np.random.choice(num_samples, + diversity_times, + replace=False) + dist = scipy.linalg.norm(activation[first_indices] - + activation[second_indices], + axis=1) + return dist.mean() + + +def calculate_multimodality_np(activation, multimodality_times): + assert len(activation.shape) == 3 + assert activation.shape[1] > multimodality_times + num_per_sent = activation.shape[1] + + first_dices = np.random.choice(num_per_sent, + multimodality_times, + replace=False) + second_dices = np.random.choice(num_per_sent, + multimodality_times, + replace=False) + dist = scipy.linalg.norm(activation[:, first_dices] - + activation[:, second_dices], + axis=2) + return dist.mean() + + +# motion reconstructions metrics + + +def batch_compute_similarity_transform_torch(S1, S2): + """ + Computes a similarity transform (sR, t) that takes + a set of 3D points S1 (3 x N) closest to a set of 3D points S2, + where R is an 3x3 rotation matrix, t 3x1 translation, s scale. + i.e. solves the orthogonal Procrutes problem. + """ + transposed = False + if S1.shape[0] != 3 and S1.shape[0] != 2: + S1 = S1.permute(0, 2, 1) + S2 = S2.permute(0, 2, 1) + transposed = True + assert S2.shape[1] == S1.shape[1] + + # 1. Remove mean. + mu1 = S1.mean(axis=-1, keepdims=True) + mu2 = S2.mean(axis=-1, keepdims=True) + + X1 = S1 - mu1 + X2 = S2 - mu2 + + # 2. Compute variance of X1 used for scale. + var1 = torch.sum(X1**2, dim=1).sum(dim=1) + + # 3. The outer product of X1 and X2. + K = X1.bmm(X2.permute(0, 2, 1)) + + # 4. Solution that Maximizes trace(R'K) is R=U*V', where U, V are + # singular vectors of K. + U, s, V = torch.svd(K) + + # Construct Z that fixes the orientation of R to get det(R)=1. + Z = torch.eye(U.shape[1], device=S1.device).unsqueeze(0) + Z = Z.repeat(U.shape[0], 1, 1) + Z[:, -1, -1] *= torch.sign(torch.det(U.bmm(V.permute(0, 2, 1)))) + + # Construct R. + R = V.bmm(Z.bmm(U.permute(0, 2, 1))) + + # 5. Recover scale. + scale = torch.cat([torch.trace(x).unsqueeze(0) for x in R.bmm(K)]) / var1 + + # 6. Recover translation. + t = mu2 - (scale.unsqueeze(-1).unsqueeze(-1) * (R.bmm(mu1))) + + # 7. Error: + S1_hat = scale.unsqueeze(-1).unsqueeze(-1) * R.bmm(S1) + t + + if transposed: + S1_hat = S1_hat.permute(0, 2, 1) + + return S1_hat, (scale, R, t) + + +def compute_mpjpe(preds, + target, + valid_mask=None, + pck_joints=None, + sample_wise=True): + """ + Mean per-joint position error (i.e. mean Euclidean distance) + often referred to as "Protocol #1" in many papers. + """ + assert preds.shape == target.shape, print(preds.shape, + target.shape) # BxJx3 + mpjpe = torch.norm(preds - target, p=2, dim=-1) # BxJ + + if pck_joints is None: + if sample_wise: + mpjpe_seq = ((mpjpe * valid_mask.float()).sum(-1) / + valid_mask.float().sum(-1) + if valid_mask is not None else mpjpe.mean(-1)) + else: + mpjpe_seq = mpjpe[valid_mask] if valid_mask is not None else mpjpe + return mpjpe_seq + else: + mpjpe_pck_seq = mpjpe[:, pck_joints] + return mpjpe_pck_seq + + +def align_by_parts(joints, align_inds=None): + if align_inds is None: + return joints + pelvis = joints[:, align_inds].mean(1) + return joints - torch.unsqueeze(pelvis, dim=1) + + +def calc_mpjpe(preds, target, align_inds=[0], sample_wise=True, trans=None): + # Expects BxJx3 + valid_mask = target[:, :, 0] != -2.0 + # valid_mask = torch.BoolTensor(target[:, :, 0].shape) + if align_inds is not None: + preds_aligned = align_by_parts(preds, align_inds=align_inds) + if trans is not None: + preds_aligned += trans + target_aligned = align_by_parts(target, align_inds=align_inds) + else: + preds_aligned, target_aligned = preds, target + mpjpe_each = compute_mpjpe(preds_aligned, + target_aligned, + valid_mask=valid_mask, + sample_wise=sample_wise) + return mpjpe_each + + +def calc_accel(preds, target): + """ + Mean joint acceleration error + often referred to as "Protocol #1" in many papers. + """ + assert preds.shape == target.shape, print(preds.shape, + target.shape) # BxJx3 + assert preds.dim() == 3 + # Expects BxJx3 + # valid_mask = torch.BoolTensor(target[:, :, 0].shape) + accel_gt = target[:-2] - 2 * target[1:-1] + target[2:] + accel_pred = preds[:-2] - 2 * preds[1:-1] + preds[2:] + normed = torch.linalg.norm(accel_pred - accel_gt, dim=-1) + accel_seq = normed.mean(1) + return accel_seq + + +def calc_pampjpe(preds, target, sample_wise=True, return_transform_mat=False): + # Expects BxJx3 + target, preds = target.float(), preds.float() + # extracting the keypoints that all samples have valid annotations + # valid_mask = (target[:, :, 0] != -2.).sum(0) == len(target) + # preds_tranformed, PA_transform = batch_compute_similarity_transform_torch(preds[:, valid_mask], target[:, valid_mask]) + # pa_mpjpe_each = compute_mpjpe(preds_tranformed, target[:, valid_mask], sample_wise=sample_wise) + + preds_tranformed, PA_transform = batch_compute_similarity_transform_torch( + preds, target) + pa_mpjpe_each = compute_mpjpe(preds_tranformed, + target, + sample_wise=sample_wise) + + if return_transform_mat: + return pa_mpjpe_each, PA_transform + else: + return pa_mpjpe_each + + +# from action2motion +def calculate_diversity_multimodality(activations, + labels, + num_labels, + diversity_times=200, + multimodality_times=20): + labels = labels.long() + num_motions = activations.shape[0] # len(labels) + + diversity = 0 + + first_indices = np.random.randint(0, num_motions, diversity_times) + second_indices = np.random.randint(0, num_motions, diversity_times) + for first_idx, second_idx in zip(first_indices, second_indices): + diversity += torch.dist(activations[first_idx, :], + activations[second_idx, :]) + diversity /= diversity_times + + multimodality = 0 + label_quotas = np.zeros(num_labels) + label_quotas[labels.unique( + )] = multimodality_times # if a label does not appear in batch, its quota remains zero + while np.any(label_quotas > 0): + # print(label_quotas) + first_idx = np.random.randint(0, num_motions) + first_label = labels[first_idx] + if not label_quotas[first_label]: + continue + + second_idx = np.random.randint(0, num_motions) + second_label = labels[second_idx] + while first_label != second_label: + second_idx = np.random.randint(0, num_motions) + second_label = labels[second_idx] + + label_quotas[first_label] -= 1 + + first_activation = activations[first_idx, :] + second_activation = activations[second_idx, :] + multimodality += torch.dist(first_activation, second_activation) + + multimodality /= (multimodality_times * num_labels) + + return diversity, multimodality + + +def calculate_fid(statistics_1, statistics_2): + return calculate_frechet_distance_np(statistics_1[0], statistics_1[1], + statistics_2[0], statistics_2[1]) + + +# from: https://github.com/abdulfatir/gan-metrics-pytorch/blob/master/kid_score.py +def polynomial_mmd_averages(codes_g, + codes_r, + n_subsets=50, + subset_size=1000, + ret_var=True, + output=sys.stdout, + **kernel_args): + m = min(codes_g.shape[0], codes_r.shape[0]) + mmds = np.zeros(n_subsets) + if ret_var: + vars = np.zeros(n_subsets) + choice = np.random.choice + + replace = subset_size < len(codes_g) + + for i in range(n_subsets): + g = codes_g[choice(len(codes_g), subset_size, replace=replace)] + r = codes_r[choice(len(codes_r), subset_size, replace=replace)] + o = polynomial_mmd(g, r, **kernel_args, var_at_m=m, ret_var=ret_var) + if ret_var: + mmds[i], vars[i] = o + else: + mmds[i] = o + + return (mmds, vars) if ret_var else mmds + + +def polynomial_mmd(codes_g, + codes_r, + degree=3, + gamma=None, + coef0=1, + var_at_m=None, + ret_var=True): + from sklearn.metrics.pairwise import polynomial_kernel + + # use k(x, y) = (gamma + coef0)^degree + # default gamma is 1 / dim + X = codes_g + Y = codes_r + + K_XX = polynomial_kernel(X, degree=degree, gamma=gamma, coef0=coef0) + K_YY = polynomial_kernel(Y, degree=degree, gamma=gamma, coef0=coef0) + K_XY = polynomial_kernel(X, Y, degree=degree, gamma=gamma, coef0=coef0) + + return _mmd2_and_variance(K_XX, + K_XY, + K_YY, + var_at_m=var_at_m, + ret_var=ret_var) + + +def _mmd2_and_variance(K_XX, + K_XY, + K_YY, + unit_diagonal=False, + mmd_est='unbiased', + block_size=1024, + var_at_m=None, + ret_var=True): + # based on + # https://github.com/dougalsutherland/opt-mmd/blob/master/two_sample/mmd.py + # but changed to not compute the full kernel matrix at once + m = K_XX.shape[0] + assert K_XX.shape == (m, m) + assert K_XY.shape == (m, m) + assert K_YY.shape == (m, m) + if var_at_m is None: + var_at_m = m + + # Get the various sums of kernels that we'll use + # Kts drop the diagonal, but we don't need to compute them explicitly + if unit_diagonal: + diag_X = diag_Y = 1 + sum_diag_X = sum_diag_Y = m + sum_diag2_X = sum_diag2_Y = m + else: + diag_X = np.diagonal(K_XX) + diag_Y = np.diagonal(K_YY) + + sum_diag_X = diag_X.sum() + sum_diag_Y = diag_Y.sum() + + sum_diag2_X = _sqn(diag_X) + sum_diag2_Y = _sqn(diag_Y) + + Kt_XX_sums = K_XX.sum(axis=1) - diag_X + Kt_YY_sums = K_YY.sum(axis=1) - diag_Y + K_XY_sums_0 = K_XY.sum(axis=0) + K_XY_sums_1 = K_XY.sum(axis=1) + + Kt_XX_sum = Kt_XX_sums.sum() + Kt_YY_sum = Kt_YY_sums.sum() + K_XY_sum = K_XY_sums_0.sum() + + if mmd_est == 'biased': + mmd2 = ((Kt_XX_sum + sum_diag_X) / (m * m) + (Kt_YY_sum + sum_diag_Y) / + (m * m) - 2 * K_XY_sum / (m * m)) + else: + assert mmd_est in {'unbiased', 'u-statistic'} + mmd2 = (Kt_XX_sum + Kt_YY_sum) / (m * (m - 1)) + if mmd_est == 'unbiased': + mmd2 -= 2 * K_XY_sum / (m * m) + else: + mmd2 -= 2 * (K_XY_sum - np.trace(K_XY)) / (m * (m - 1)) + + if not ret_var: + return mmd2 + + Kt_XX_2_sum = _sqn(K_XX) - sum_diag2_X + Kt_YY_2_sum = _sqn(K_YY) - sum_diag2_Y + K_XY_2_sum = _sqn(K_XY) + + dot_XX_XY = Kt_XX_sums.dot(K_XY_sums_1) + dot_YY_YX = Kt_YY_sums.dot(K_XY_sums_0) + + m1 = m - 1 + m2 = m - 2 + zeta1_est = ( + 1 / (m * m1 * m2) * + (_sqn(Kt_XX_sums) - Kt_XX_2_sum + _sqn(Kt_YY_sums) - Kt_YY_2_sum) - 1 / + (m * m1)**2 * (Kt_XX_sum**2 + Kt_YY_sum**2) + 1 / (m * m * m1) * + (_sqn(K_XY_sums_1) + _sqn(K_XY_sums_0) - 2 * K_XY_2_sum) - + 2 / m**4 * K_XY_sum**2 - 2 / (m * m * m1) * (dot_XX_XY + dot_YY_YX) + + 2 / (m**3 * m1) * (Kt_XX_sum + Kt_YY_sum) * K_XY_sum) + zeta2_est = (1 / (m * m1) * (Kt_XX_2_sum + Kt_YY_2_sum) - 1 / (m * m1)**2 * + (Kt_XX_sum**2 + Kt_YY_sum**2) + 2 / (m * m) * K_XY_2_sum - + 2 / m**4 * K_XY_sum**2 - 4 / (m * m * m1) * + (dot_XX_XY + dot_YY_YX) + 4 / (m**3 * m1) * + (Kt_XX_sum + Kt_YY_sum) * K_XY_sum) + var_est = (4 * (var_at_m - 2) / (var_at_m * (var_at_m - 1)) * zeta1_est + + 2 / (var_at_m * (var_at_m - 1)) * zeta2_est) + + return mmd2, var_est + + +def _sqn(arr): + flat = np.ravel(arr) + return flat.dot(flat) + + +def calculate_kid(real_activations, generated_activations): + kid_values = polynomial_mmd_averages(real_activations, + generated_activations, + n_subsets=100) + results = (kid_values[0].mean(), kid_values[0].std()) + return results diff --git a/motiondiff_modules/mGPT/models/__init__.py b/motiondiff_modules/mGPT/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/motiondiff_modules/mGPT/models/base.py b/motiondiff_modules/mGPT/models/base.py new file mode 100644 index 0000000..69fe4c8 --- /dev/null +++ b/motiondiff_modules/mGPT/models/base.py @@ -0,0 +1,204 @@ +import os +import numpy as np +import torch +import logging +from pathlib import Path +from pytorch_lightning import LightningModule +from os.path import join as pjoin +from collections import OrderedDict +from ..metrics import BaseMetrics +from ..config import get_obj_from_str + + +class BaseModel(LightningModule): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # self.configure_metrics() + + # Ablation + self.test_step_outputs = [] + self.times = [] + self.rep_i = 0 + + def training_step(self, batch, batch_idx): + return self.allsplit_step("train", batch, batch_idx) + + def validation_step(self, batch, batch_idx): + return self.allsplit_step("val", batch, batch_idx) + + def test_step(self, batch, batch_idx): + outputs = self.allsplit_step("test", batch, batch_idx) + self.test_step_outputs.append(outputs) + return outputs + + def predict_step(self, batch, batch_idx): + return self.forward(batch) + + def on_train_epoch_end(self): + # Log steps and losses + dico = self.step_log_dict() + # Log losses + dico.update(self.loss_log_dict('train')) + # Write to log only if not sanity check + if not self.trainer.sanity_checking: + self.log_dict(dico, sync_dist=True, rank_zero_only=True) + + def on_validation_epoch_end(self): + # Log steps and losses + dico = self.step_log_dict() + # Log losses + dico.update(self.loss_log_dict('train')) + dico.update(self.loss_log_dict('val')) + # Log metrics + dico.update(self.metrics_log_dict()) + # Write to log only if not sanity check + if not self.trainer.sanity_checking: + self.log_dict(dico, sync_dist=True, rank_zero_only=True) + + def on_test_epoch_end(self): + # Log metrics + dico = self.metrics_log_dict() + # Write to log only if not sanity check + if not self.trainer.sanity_checking: + self.log_dict(dico, sync_dist=True, rank_zero_only=True) + self.save_npy(self.test_step_outputs) + self.rep_i = self.rep_i + 1 + # Free up the memory + self.test_step_outputs.clear() + + def preprocess_state_dict(self, state_dict): + new_state_dict = OrderedDict() + + # metric_state_dict = self.metrics.state_dict() + loss_state_dict = self._losses.state_dict() + + # for k, v in metric_state_dict.items(): + # new_state_dict['metrics.' + k] = v + + for k, v in loss_state_dict.items(): + new_state_dict['_losses.' + k] = v + + for k, v in state_dict.items(): + if '_losses' not in k and 'Metrics' not in k: + new_state_dict[k] = v + + return new_state_dict + + def load_state_dict(self, state_dict, strict=True): + new_state_dict = self.preprocess_state_dict(state_dict) + super().load_state_dict(new_state_dict, strict) + + def step_log_dict(self): + return { + "epoch": float(self.trainer.current_epoch), + "step": float(self.trainer.current_epoch) + } + + def loss_log_dict(self, split: str): + losses = self._losses['losses_' + split] + loss_dict = losses.compute(split) + return loss_dict + + def metrics_log_dict(self): + + # For TM2TMetrics MM + if self.trainer.datamodule.is_mm and "TM2TMetrics" in self.hparams.metrics_dict: + metrics_dicts = ['MMMetrics'] + else: + metrics_dicts = self.hparams.metrics_dict + + # Compute all metrics + metrics_log_dict = {} + for metric in metrics_dicts: + metrics_dict = getattr( + self.metrics, + metric).compute(sanity_flag=self.trainer.sanity_checking) + metrics_log_dict.update({ + f"Metrics/{metric}": value.item() + for metric, value in metrics_dict.items() + }) + + return metrics_log_dict + + def configure_optimizers(self): + # Optimizer + optim_target = self.hparams.cfg.TRAIN.OPTIM.target + if len(optim_target.split('.')) == 1: + optim_target = 'torch.optim.' + optim_target + optimizer = get_obj_from_str(optim_target)( + params=self.parameters(), **self.hparams.cfg.TRAIN.OPTIM.params) + + # Scheduler + scheduler_target = self.hparams.cfg.TRAIN.LR_SCHEDULER.target + if len(scheduler_target.split('.')) == 1: + scheduler_target = 'torch.optim.lr_scheduler.' + scheduler_target + lr_scheduler = get_obj_from_str(scheduler_target)( + optimizer=optimizer, **self.hparams.cfg.TRAIN.LR_SCHEDULER.params) + + return {'optimizer': optimizer, 'lr_scheduler': lr_scheduler} + + def configure_metrics(self): + self.metrics = BaseMetrics(datamodule=self.datamodule, **self.hparams) + + def save_npy(self, outputs): + cfg = self.hparams.cfg + output_dir = Path( + os.path.join( + cfg.FOLDER, + str(cfg.model.target.split('.')[-2].lower()), + str(cfg.NAME), + "samples_" + cfg.TIME, + )) + if cfg.TEST.SAVE_PREDICTIONS: + lengths = [i[1] for i in outputs] + outputs = [i[0] for i in outputs] + + if cfg.TEST.DATASETS[0].lower() in ["humanml3d", "kit"]: + keyids = self.trainer.datamodule.test_dataset.name_list + for i in range(len(outputs)): + for bid in range( + min(cfg.TEST.BATCH_SIZE, outputs[i].shape[0])): + keyid = keyids[i * cfg.TEST.BATCH_SIZE + bid] + data = self.trainer.datamodule.test_dataset.data_dict[ + keyid] + + motion = torch.tensor(data['motion'], + device=outputs[i].device) + motion = self.datamodule.normalize(motion) + length = data['length'] + text_list = data['text'] + gen_joints = outputs[i][bid][:lengths[i][bid]].cpu( + ).numpy() + if cfg.TEST.REPLICATION_TIMES > 1: + name = f"{keyid}.npy" + else: + name = f"{keyid}.npy" + # save predictions results + npypath = output_dir / name + np.save(npypath, gen_joints) + npypath = output_dir / f"{keyid}_gt.npy" + joints = self.feats2joints(motion).cpu().numpy() + np.save(npypath, joints) + + with open(output_dir / f"{keyid}.txt", "a") as f: + for text in text_list: + f.write(f"{text['caption']}\n") + + elif cfg.TEST.DATASETS[0].lower() in ["humanact12", "uestc"]: + keyids = range(len(self.trainer.datamodule.test_dataset)) + for i in range(len(outputs)): + for bid in range( + min(cfg.TEST.BATCH_SIZE, outputs[i].shape[0])): + keyid = keyids[i * cfg.TEST.BATCH_SIZE + bid] + gen_joints = outputs[i][bid].cpu() + gen_joints = gen_joints.permute(2, 0, + 1)[:lengths[i][bid], + ...].numpy() + if cfg.TEST.REPLICATION_TIMES > 1: + name = f"{keyid}_{self.rep_i}" + else: + name = f"{keyid}.npy" + # save predictions results + npypath = output_dir / name + np.save(npypath, gen_joints) diff --git a/motiondiff_modules/mGPT/models/build_model.py b/motiondiff_modules/mGPT/models/build_model.py new file mode 100644 index 0000000..8a87c9a --- /dev/null +++ b/motiondiff_modules/mGPT/models/build_model.py @@ -0,0 +1,8 @@ +from omegaconf import OmegaConf +from ..config import instantiate_from_config + +def build_model(cfg, datamodule): + model_config = OmegaConf.to_container(cfg.model, resolve=True) + model_config['params']['cfg'] = cfg + model_config['params']['datamodule'] = datamodule + return instantiate_from_config(model_config) diff --git a/motiondiff_modules/mGPT/models/mgpt.py b/motiondiff_modules/mGPT/models/mgpt.py new file mode 100644 index 0000000..4171d9b --- /dev/null +++ b/motiondiff_modules/mGPT/models/mgpt.py @@ -0,0 +1,492 @@ +import numpy as np +import os +import random +import torch +import time +from ..config import instantiate_from_config +from os.path import join as pjoin +from ..losses.mgpt import GPTLosses +from .base import BaseModel +import json +#import mGPT.render.matplot.plot_3d_global as plot_3d + +class MotionGPT(BaseModel): + """ + Stage 1 Motion Tokenizer + Stage 2 Motion-language pretrian + Stage 3 Motion-language instruction tuning + """ + + def __init__(self, + cfg, + datamodule, + lm, + motion_vae, + codebook_size=512, + stage='vae', + debug=True, + condition='text', + task='t2m', + metrics_dict=['TM2TMetrics'], + **kwargs): + + self.save_hyperparameters(ignore='datamodule', logger=False) + self.datamodule = datamodule + super().__init__() + + # Instantiate motion tokenizer + if motion_vae != None: + self.vae = instantiate_from_config(motion_vae) + + # Instantiate motion-language model + self.lm = instantiate_from_config(lm) + + # Freeze the motion tokenizer for lm training + if 'lm' in self.hparams.stage: + self.vae.training = False + for p in self.vae.parameters(): + p.requires_grad = False + + # Instantiate the losses + self._losses = torch.nn.ModuleDict({ + split: GPTLosses(cfg, self.hparams.stage, self.datamodule.njoints) + for split in ["losses_train", "losses_test", "losses_val"] + }) + + # Data transform + self.feats2joints = datamodule.feats2joints + + # Count codebook frequency + self.codePred = [] + self.codeFrequency = torch.zeros((self.hparams.codebook_size, )) + + def forward(self, batch, task="t2m"): + texts = batch["text"] + lengths_ref = batch["length"] + + # Forward + # texts = ['Generate motion: ' + text for text in texts] + outputs, output_texts = self.lm.generate_direct(texts, do_sample=True) + + # Motion Decode + feats_rst_lst = [] + lengths = [] + max_len = 0 + + for i in range(len(texts)): + if task == "pred": + motion = self.vae.decode( + torch.cat((batch["motion"][i], outputs[i]))) + elif task in ["t2m", "m2t", "inbetween"]: + motion = self.vae.decode(outputs[i]) + # motion = self.datamodule.denormalize(motion) + lengths.append(motion.shape[1]) + else: + raise NotImplementedError + + if motion.shape[1] > max_len: + max_len = motion.shape[1] + + if task in ["t2m", "m2t", "pred"]: + feats_rst_lst.append(motion) + + elif task == "inbetween": + motion = torch.cat( + (batch["motion_heading"][i][None], + motion[:, lengths_ref[i] // 4:lengths_ref[i] // 4 * 3, + ...], batch["motion_tailing"][i][None]), + dim=1) + feats_rst_lst.append(motion) + + feats_rst = torch.zeros( + (len(feats_rst_lst), max_len, motion.shape[-1])).to(self.device) + + # padding and concat + for i in range(len(feats_rst_lst)): + feats_rst[i, :feats_rst_lst[i].shape[1], ...] = feats_rst_lst[i] + + # Recover joints for evaluation + joints_rst = self.feats2joints(feats_rst) + + # return set + outputs = { + "texts": output_texts, + "feats": feats_rst, + "joints": joints_rst, + "length": lengths + } + + return outputs + + def train_lm_forward(self, batch): + tokens_ref = batch["motion"] + texts = batch["text"] + lengths = batch["length"] + tasks = batch["tasks"] + all_captions = batch['all_captions'] + if self.hparams.condition == 'caption': + texts = [random.choice(all_captions[i]) for i in range(len(texts))] + + # LLM Forward + outputs = self.lm(texts, tokens_ref, lengths, tasks) + # outputs = self.t2m_gpt.generate(texts) + return {'outputs': outputs} + + @torch.no_grad() + def val_t2m_forward(self, batch): + feats_ref = batch["motion"] + texts = batch["text"] + lengths = batch["length"] + tasks = None + if self.trainer.datamodule.is_mm: + texts = texts * self.hparams.cfg.METRIC.MM_NUM_REPEATS + feats_ref = feats_ref.repeat_interleave( + self.hparams.cfg.METRIC.MM_NUM_REPEATS, dim=0) + lengths = lengths * self.hparams.cfg.METRIC.MM_NUM_REPEATS + instructions = pjoin(self.datamodule.hparams.data_root, + 'template_instructions.json') + instructions = json.load(open(instructions, 'r')) + tasks = [instructions["Text-to-Motion"]["caption"]] * len(texts) + + if self.hparams.condition == 'caption': + tasks = [{ + 'input': [''], + 'output': [''] + }] * len(texts) + + if self.hparams.cfg.DATASET.TASK_PATH: + instructions = pjoin(self.hparams.cfg.DATASET.TASK_PATH) + instructions = json.load(open(instructions, 'r')) + tasks = [instructions["Text-to-Motion"]["t2m"]] * len(texts) + + min_len = lengths.copy() + # Forward + outputs = self.lm.generate_conditional(texts, + lengths=lengths, + stage='test', + tasks=tasks) + + # Motion Decode + feats_rst = torch.zeros_like(feats_ref) + + for i in range(len(texts)): + outputs[i] = torch.clamp(outputs[i], + 0, + self.hparams.codebook_size - 1, + out=None) + + if len(outputs[i]) > 1: + motion = self.vae.decode(outputs[i]) + else: + motion = torch.zeros_like(feats_ref[i:i + 1, ...]) + + min_len[i] = min(motion.shape[1], lengths[i]) + + # Cut Motion + feats_rst[i:i + 1, :min_len[i], ...] = motion[:, :lengths[i]] + + # Recover joints for evaluation + joints_ref = self.feats2joints(feats_ref) + joints_rst = self.feats2joints(feats_rst) + + # Renorm for evaluation + feats_ref = self.datamodule.renorm4t2m(feats_ref) + feats_rst = self.datamodule.renorm4t2m(feats_rst) + + # return set + rs_set = { + "m_ref": feats_ref, + "m_rst": feats_rst, + "joints_ref": joints_ref, + "joints_rst": joints_rst, + "length": min_len + # "length": lengths + } + + return rs_set + + @torch.no_grad() + def val_m2t_forward(self, batch): + self.hparams.metrics_dict = [] + + feats_ref = batch["motion"] + texts = batch["text"] + lengths = batch["length"] + all_captions = batch['all_captions'] + + # Motion Encode + motion_tokens = [] + lengths_tokens = [] + for i in range(len(feats_ref)): + motion_token, _ = self.vae.encode(feats_ref[i:i + 1]) + motion_tokens.append(motion_token[0]) + lengths_tokens.append(motion_token.shape[1]) + + # Forward + outputs = self.lm.generate_conditional(motion_tokens=motion_tokens, + lengths=lengths_tokens, + task="m2t", + stage='test') + + # return set + rs_set = { + "m_ref": feats_ref, + "t_ref": all_captions, + # "t_ref": texts, + "t_pred": outputs, + "length": lengths + } + + return rs_set + + @torch.no_grad() + def val_m2m_forward(self, batch, task="pred"): + feats_ref = batch["motion"] + lengths = batch["length"] + + # Motion Encode + motion_tokens = [] + lengths_tokens = [] + for i in range(len(feats_ref)): + motion_token, _ = self.vae.encode(feats_ref[i:i + 1]) + motion_tokens.append(motion_token[0]) + + # Forward + outputs = self.lm.generate_conditional(motion_tokens=motion_tokens, + lengths=lengths, + task=task, + stage='test') + + # Motion Decode + feats_rst = torch.zeros_like(feats_ref) + min_len = lengths.copy() + + for i in range(len(lengths)): + outputs[i] = torch.clamp(outputs[i], + 0, + self.hparams.codebook_size - 1, + out=None) + + if len(outputs[i]) > 1: + motion = self.vae.decode(outputs[i]) + else: + motion = torch.zeros_like(feats_ref[i:i + 1, ...]) + + min_len[i] = min(motion.shape[1], lengths[i]) + + # Cut Motion + feats_rst[i:i + 1, :min_len[i], ...] = motion[:, :lengths[i]] + + # Recover joints for evaluation + joints_ref = self.feats2joints(feats_ref) + joints_rst = self.feats2joints(feats_rst) + + # Renorm for evaluation + feats_ref = self.datamodule.renorm4t2m(feats_ref) + feats_rst = self.datamodule.renorm4t2m(feats_rst) + + # return set + rs_set = { + "m_ref": feats_ref, + "m_rst": feats_rst, + "joints_ref": joints_ref, + "joints_rst": joints_rst, + "length": min_len + # "length": lengths + } + + return rs_set + + def train_vae_forward(self, batch): + # batch detach + feats_ref = batch["motion"] + joints_ref = self.feats2joints(feats_ref) + # motion encode & decode + feats_rst, loss_commit, perplexity = self.vae(feats_ref) + joints_rst = self.feats2joints(feats_rst) + # return set + rs_set = { + "m_ref": feats_ref, + "joints_ref": joints_ref, + "m_rst": feats_rst, + "joints_rst": joints_rst, + "loss_commit": loss_commit, + "perplexity": perplexity, + } + return rs_set + + @torch.no_grad() + def val_vae_forward(self, batch, split="train"): + # Detach batch + feats_ref = batch["motion"] + lengths = batch["length"] + + # Repeat for multimodal evaluation + if self.trainer.datamodule.is_mm: + feats_ref = feats_ref.repeat_interleave( + self.hparams.cfg.METRIC.MM_NUM_REPEATS, dim=0) + lengths = lengths * self.hparams.cfg.METRIC.MM_NUM_REPEATS + + # Motion encode & decode + feats_rst = torch.zeros_like(feats_ref) + + for i in range(len(feats_ref)): + if lengths[i] == 0: + continue + feats_pred, _, _ = self.vae(feats_ref[i:i + 1, :lengths[i]]) + feats_rst[i:i + 1, :feats_pred.shape[1], :] = feats_pred + + code_pred, _ = self.vae.encode(feats_ref[i:i + 1, :lengths[i]]) + + # codeFre_pred = torch.bincount(code_pred[0], + # minlength=self.hparams.codebook_size).to( + # self.codeFrequency.device) + # self.codePred.append(code_pred[0]) + # self.codeFrequency += codeFre_pred + + # np.save('../memData/results/codeFrequency.npy', + # self.codeFrequency.cpu().numpy()) + + # Recover joints for evaluation + joints_ref = self.feats2joints(feats_ref) + joints_rst = self.feats2joints(feats_rst) + + # Renorm for evaluation + feats_ref = self.datamodule.renorm4t2m(feats_ref) + feats_rst = self.datamodule.renorm4t2m(feats_rst) + + # Return set + rs_set = { + "m_ref": feats_ref, + "joints_ref": joints_ref, + "m_rst": feats_rst, + "joints_rst": joints_rst, + "length": lengths, + } + + return rs_set + + + def allsplit_step(self, split: str, batch, batch_idx): + # Compute the losses + loss = None + + if self.hparams.stage == "vae" and split in ["train", "val"]: + rs_set = self.train_vae_forward(batch) + loss = self._losses['losses_' + split].update(rs_set) + elif self.hparams.stage in ["lm_instruct", "lm_pretrain" + ] and split in ["train"]: + rs_set = self.train_lm_forward(batch) + loss = self._losses['losses_' + split].update(rs_set) + elif self.hparams.stage == 'lm_rl' and split in ['train']: + rs_set = self.train_rl_forward(batch) + loss = None + + # Compute the metrics + if split in ["val", "test"]: + if self.hparams.stage == "vae": + rs_set = self.val_vae_forward(batch, split) + elif self.hparams.stage in ["lm_instruct", "lm_pretrain", "lm_rl"]: + if self.hparams.task == "t2m": + rs_set = self.val_t2m_forward(batch) + elif self.hparams.task == "m2t": + rs_set = self.val_m2t_forward(batch) + elif self.hparams.task in ["m2m", "pred", "inbetween"]: + rs_set = self.val_m2m_forward(batch, self.hparams.task) + + if self.hparams.task not in ["m2t"]: + # MultiModality evaluation sperately + if self.trainer.datamodule.is_mm: + metrics_dicts = ['MMMetrics'] + else: + metrics_dicts = self.hparams.metrics_dict + + if self.hparams.task not in ['pred', 'inbetween']: + metrics_dicts.remove('PredMetrics') + + for metric in metrics_dicts: + lengths = batch['length'] + if metric == "TemosMetric": + getattr(self.metrics, + metric).update(rs_set["joints_rst"], + rs_set["joints_ref"], lengths) + elif metric == "TM2TMetrics": + if self.hparams.stage in [ + "lm_instruct", "lm_pretrain", "lm_rl" + ]: + word_embs = batch['word_embs'] + pos_ohot = batch['pos_ohot'] + text_lengths = batch['text_len'] + if self.trainer.datamodule.is_mm: + word_embs = word_embs.repeat_interleave( + self.hparams.cfg.METRIC.MM_NUM_REPEATS, + dim=0) + pos_ohot = pos_ohot.repeat_interleave( + self.hparams.cfg.METRIC.MM_NUM_REPEATS, + dim=0) + text_lengths = text_lengths.repeat_interleave( + self.hparams.cfg.METRIC.MM_NUM_REPEATS, + dim=0) + else: + word_embs = None + pos_ohot = None + text_lengths = None + + getattr(self.metrics, metric).update( + feats_ref=rs_set["m_ref"], + feats_rst=rs_set["m_rst"], + lengths_ref=lengths, + lengths_rst=rs_set['length'], + word_embs=word_embs, + pos_ohot=pos_ohot, + text_lengths=text_lengths, + ) + elif metric == "UncondMetrics": + getattr(self.metrics, metric).update( + recmotion_embeddings=rs_set["lat_rm"], + gtmotion_embeddings=rs_set["lat_m"], + lengths=lengths, + ) + elif metric == "MRMetrics": + getattr(self.metrics, + metric).update(rs_set["joints_rst"], + rs_set["joints_ref"], lengths) + elif metric == "PredMetrics": + getattr(self.metrics, + metric).update(rs_set["joints_rst"], + rs_set["joints_ref"], lengths) + elif metric == "MMMetrics": + # pass + getattr(self.metrics, + metric).update(rs_set["m_rst"], + rs_set['length']) + else: + raise TypeError(f"Not support this metric {metric}") + + elif self.hparams.task == "m2t" and self.hparams.stage in [ + "lm_instruct", "lm_pretrain", "lm_rl" + ]: + self.hparams.metrics_dict = metrics_dicts = ['M2TMetrics'] + for metric in metrics_dicts: + if metric == "M2TMetrics": + getattr(self.metrics, metric).update( + feats_ref=rs_set["m_ref"], + pred_texts=rs_set["t_pred"], + gt_texts=batch["all_captions"], + lengths=rs_set['length'], + word_embs=batch["word_embs"], + pos_ohot=batch["pos_ohot"], + text_lengths=batch["text_len"], + ) + + # return forward output rather than loss during test + if split in ["test"]: + if self.hparams.task == "t2m": + return rs_set["joints_rst"], rs_set["length"], rs_set[ + "joints_ref"] + # pass + elif self.hparams.task == "m2t": + return rs_set["t_pred"], batch["length"] + # return batch["length"] + + return loss diff --git a/motiondiff_modules/mGPT/models/utils/__init__.py b/motiondiff_modules/mGPT/models/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/motiondiff_modules/mGPT/models/utils/adain.py b/motiondiff_modules/mGPT/models/utils/adain.py new file mode 100644 index 0000000..3588f33 --- /dev/null +++ b/motiondiff_modules/mGPT/models/utils/adain.py @@ -0,0 +1,66 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F + +class AdaptiveInstanceNorm1d(nn.Module): + def __init__(self, num_features, eps=1e-5, momentum=0.1): + super(AdaptiveInstanceNorm1d, self).__init__() + self.num_features = num_features + self.eps = eps + self.momentum = momentum + self.weight = None + self.bias = None + self.register_buffer('running_mean', torch.zeros(num_features)) + self.register_buffer('running_var', torch.ones(num_features)) + + def forward(self, x, direct_weighting=False, no_std=False): + assert self.weight is not None and \ + self.bias is not None, "Please assign AdaIN weight first" + # (bs, nfeats, nframe) <= (nframe, bs, nfeats) + x = x.permute(1,2,0) + + b, c = x.size(0), x.size(1) # batch size & channels + running_mean = self.running_mean.repeat(b) + running_var = self.running_var.repeat(b) + # self.weight = torch.ones_like(self.weight) + + if direct_weighting: + x_reshaped = x.contiguous().view(b * c) + if no_std: + out = x_reshaped + self.bias + else: + out = x_reshaped.mul(self.weight) + self.bias + out = out.view(b, c, *x.size()[2:]) + else: + x_reshaped = x.contiguous().view(1, b * c, *x.size()[2:]) + out = F.batch_norm( + x_reshaped, running_mean, running_var, self.weight, self.bias, + True, self.momentum, self.eps) + out = out.view(b, c, *x.size()[2:]) + + # (nframe, bs, nfeats) <= (bs, nfeats, nframe) + out = out.permute(2,0,1) + return out + + def __repr__(self): + return self.__class__.__name__ + '(' + str(self.num_features) + ')' + +def assign_adain_params(adain_params, model): + # assign the adain_params to the AdaIN layers in model + for m in model.modules(): + if m.__class__.__name__ == "AdaptiveInstanceNorm1d": + mean = adain_params[: , : m.num_features] + std = adain_params[: , m.num_features: 2 * m.num_features] + m.bias = mean.contiguous().view(-1) + m.weight = std.contiguous().view(-1) + if adain_params.size(1) > 2 * m.num_features: + adain_params = adain_params[: , 2 * m.num_features:] + + +def get_num_adain_params(model): + # return the number of AdaIN parameters needed by the model + num_adain_params = 0 + for m in model.modules(): + if m.__class__.__name__ == "AdaptiveInstanceNorm1d": + num_adain_params += 2 * m.num_features + return num_adain_params diff --git a/motiondiff_modules/mGPT/models/utils/blocks.py b/motiondiff_modules/mGPT/models/utils/blocks.py new file mode 100644 index 0000000..e27c198 --- /dev/null +++ b/motiondiff_modules/mGPT/models/utils/blocks.py @@ -0,0 +1,146 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +from motiondiff_modules.mGPT.models.notused import AdaptiveInstanceNorm1d + + +class MLP(nn.Module): + + def __init__(self, cfg, out_dim, is_init): + super(MLP, self).__init__() + dims = cfg.MODEL.MOTION_DECODER.MLP_DIM + n_blk = len(dims) + norm = 'none' + acti = 'lrelu' + + layers = [] + for i in range(n_blk - 1): + layers += LinearBlock(dims[i], dims[i + 1], norm=norm, acti=acti) + layers += LinearBlock(dims[-1], out_dim, norm='none', acti='none') + self.model = nn.Sequential(*layers) + + if is_init: + for m in self.modules(): + if isinstance(m, nn.Linear): + #nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') + nn.init.constant_(m.weight, 1) + elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)): + nn.init.constant_(m.weight, 1) + nn.init.constant_(m.bias, 0) + + def forward(self, x): + return self.model(x.view(x.size(0), -1)) + + +def ZeroPad1d(sizes): + return nn.ConstantPad1d(sizes, 0) + + +def get_acti_layer(acti='relu', inplace=True): + + if acti == 'relu': + return [nn.ReLU(inplace=inplace)] + elif acti == 'lrelu': + return [nn.LeakyReLU(0.2, inplace=inplace)] + elif acti == 'tanh': + return [nn.Tanh()] + elif acti == 'none': + return [] + else: + assert 0, "Unsupported activation: {}".format(acti) + + +def get_norm_layer(norm='none', norm_dim=None): + + if norm == 'bn': + return [nn.BatchNorm1d(norm_dim)] + elif norm == 'in': + # return [nn.InstanceNorm1d(norm_dim, affine=False)] # for rt42! + return [nn.InstanceNorm1d(norm_dim, affine=True)] + elif norm == 'adain': + return [AdaptiveInstanceNorm1d(norm_dim)] + elif norm == 'none': + return [] + else: + assert 0, "Unsupported normalization: {}".format(norm) + + +def get_dropout_layer(dropout=None): + if dropout is not None: + return [nn.Dropout(p=dropout)] + else: + return [] + + +def ConvLayers(kernel_size, + in_channels, + out_channels, + stride=1, + pad_type='reflect', + use_bias=True): + """ + returns a list of [pad, conv] => should be += to some list, then apply sequential + """ + + if pad_type == 'reflect': + pad = nn.ReflectionPad1d + elif pad_type == 'replicate': + pad = nn.ReplicationPad1d + elif pad_type == 'zero': + pad = ZeroPad1d + else: + assert 0, "Unsupported padding type: {}".format(pad_type) + + pad_l = (kernel_size - 1) // 2 + pad_r = kernel_size - 1 - pad_l + return [ + pad((pad_l, pad_r)), + nn.Conv1d(in_channels, + out_channels, + kernel_size=kernel_size, + stride=stride, + bias=use_bias) + ] + + +def ConvBlock(kernel_size, + in_channels, + out_channels, + stride=1, + pad_type='reflect', + dropout=None, + norm='none', + acti='lrelu', + acti_first=False, + use_bias=True, + inplace=True): + """ + returns a list of [pad, conv, norm, acti] or [acti, pad, conv, norm] + """ + + layers = ConvLayers(kernel_size, + in_channels, + out_channels, + stride=stride, + pad_type=pad_type, + use_bias=use_bias) + layers += get_dropout_layer(dropout) + layers += get_norm_layer(norm, norm_dim=out_channels) + acti_layers = get_acti_layer(acti, inplace=inplace) + + if acti_first: + return acti_layers + layers + else: + return layers + acti_layers + + +def LinearBlock(in_dim, out_dim, dropout=None, norm='none', acti='relu'): + + use_bias = True + layers = [] + layers.append(nn.Linear(in_dim, out_dim, bias=use_bias)) + layers += get_dropout_layer(dropout) + layers += get_norm_layer(norm, norm_dim=out_dim) + layers += get_acti_layer(acti) + + return layers diff --git a/motiondiff_modules/mGPT/models/utils/cross_attention.py b/motiondiff_modules/mGPT/models/utils/cross_attention.py new file mode 100644 index 0000000..deb1f05 --- /dev/null +++ b/motiondiff_modules/mGPT/models/utils/cross_attention.py @@ -0,0 +1,412 @@ +# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved +""" +DETR Transformer class. +Copy-paste from torch.nn.Transformer with modifications: + * positional encodings are passed in MHattention + * extra LN at the end of encoder is removed + * decoder returns a stack of activations from all decoding layers +""" +import copy +from typing import List, Optional +from numpy import block + +import torch +import torch.nn.functional as F +from torch import Tensor, nn + + +class SkipTransformerEncoder(nn.Module): + def __init__(self, encoder_layer, num_layers, norm=None): + super().__init__() + self.d_model = encoder_layer.d_model + + self.num_layers = num_layers + self.norm = norm + + assert num_layers % 2 == 1 + + num_block = (num_layers-1)//2 + self.input_blocks = _get_clones(encoder_layer, num_block) + self.middle_block = _get_clone(encoder_layer) + self.output_blocks = _get_clones(encoder_layer, num_block) + self.linear_blocks = _get_clones(nn.Linear(2*self.d_model, self.d_model), num_block) + + self._reset_parameters() + + def _reset_parameters(self): + for p in self.parameters(): + if p.dim() > 1: + nn.init.xavier_uniform_(p) + + def forward(self, src, + mask: Optional[Tensor] = None, + src_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None): + x = src + + xs = [] + for module in self.input_blocks: + x = module(x, src_mask=mask, + src_key_padding_mask=src_key_padding_mask, pos=pos) + xs.append(x) + + x = self.middle_block(x, src_mask=mask, + src_key_padding_mask=src_key_padding_mask, pos=pos) + + for (module, linear) in zip(self.output_blocks, self.linear_blocks): + x = torch.cat([x, xs.pop()], dim=-1) + x = linear(x) + x = module(x, src_mask=mask, + src_key_padding_mask=src_key_padding_mask, pos=pos) + + if self.norm is not None: + x = self.norm(x) + return x + +class SkipTransformerDecoder(nn.Module): + def __init__(self, decoder_layer, num_layers, norm=None): + super().__init__() + self.d_model = decoder_layer.d_model + + self.num_layers = num_layers + self.norm = norm + + assert num_layers % 2 == 1 + + num_block = (num_layers-1)//2 + self.input_blocks = _get_clones(decoder_layer, num_block) + self.middle_block = _get_clone(decoder_layer) + self.output_blocks = _get_clones(decoder_layer, num_block) + self.linear_blocks = _get_clones(nn.Linear(2*self.d_model, self.d_model), num_block) + + self._reset_parameters() + + def _reset_parameters(self): + for p in self.parameters(): + if p.dim() > 1: + nn.init.xavier_uniform_(p) + + def forward(self, tgt, memory, + tgt_mask: Optional[Tensor] = None, + memory_mask: Optional[Tensor] = None, + tgt_key_padding_mask: Optional[Tensor] = None, + memory_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None, + query_pos: Optional[Tensor] = None): + x = tgt + + xs = [] + for module in self.input_blocks: + x = module(x, memory, tgt_mask=tgt_mask, + memory_mask=memory_mask, + tgt_key_padding_mask=tgt_key_padding_mask, + memory_key_padding_mask=memory_key_padding_mask, + pos=pos, query_pos=query_pos) + xs.append(x) + + x = self.middle_block(x, memory, tgt_mask=tgt_mask, + memory_mask=memory_mask, + tgt_key_padding_mask=tgt_key_padding_mask, + memory_key_padding_mask=memory_key_padding_mask, + pos=pos, query_pos=query_pos) + + for (module, linear) in zip(self.output_blocks, self.linear_blocks): + x = torch.cat([x, xs.pop()], dim=-1) + x = linear(x) + x = module(x, memory, tgt_mask=tgt_mask, + memory_mask=memory_mask, + tgt_key_padding_mask=tgt_key_padding_mask, + memory_key_padding_mask=memory_key_padding_mask, + pos=pos, query_pos=query_pos) + + if self.norm is not None: + x = self.norm(x) + + return x + +class Transformer(nn.Module): + + def __init__(self, d_model=512, nhead=8, num_encoder_layers=6, + num_decoder_layers=6, dim_feedforward=2048, dropout=0.1, + activation="relu", normalize_before=False, + return_intermediate_dec=False): + super().__init__() + + encoder_layer = TransformerEncoderLayer(d_model, nhead, dim_feedforward, + dropout, activation, normalize_before) + encoder_norm = nn.LayerNorm(d_model) if normalize_before else None + self.encoder = TransformerEncoder(encoder_layer, num_encoder_layers, encoder_norm) + + decoder_layer = TransformerDecoderLayer(d_model, nhead, dim_feedforward, + dropout, activation, normalize_before) + decoder_norm = nn.LayerNorm(d_model) + self.decoder = TransformerDecoder(decoder_layer, num_decoder_layers, decoder_norm, + return_intermediate=return_intermediate_dec) + + self._reset_parameters() + + self.d_model = d_model + self.nhead = nhead + + def _reset_parameters(self): + for p in self.parameters(): + if p.dim() > 1: + nn.init.xavier_uniform_(p) + + def forward(self, src, mask, query_embed, pos_embed): + # flatten NxCxHxW to HWxNxC + bs, c, h, w = src.shape + src = src.flatten(2).permute(2, 0, 1) + pos_embed = pos_embed.flatten(2).permute(2, 0, 1) + query_embed = query_embed.unsqueeze(1).repeat(1, bs, 1) + mask = mask.flatten(1) + + tgt = torch.zeros_like(query_embed) + memory = self.encoder(src, src_key_padding_mask=mask, pos=pos_embed) + hs = self.decoder(tgt, memory, memory_key_padding_mask=mask, + pos=pos_embed, query_pos=query_embed) + return hs.transpose(1, 2), memory.permute(1, 2, 0).view(bs, c, h, w) + + +class TransformerEncoder(nn.Module): + + def __init__(self, encoder_layer, num_layers, norm=None): + super().__init__() + self.layers = _get_clones(encoder_layer, num_layers) + self.num_layers = num_layers + self.norm = norm + + def forward(self, src, + mask: Optional[Tensor] = None, + src_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None): + output = src + + for layer in self.layers: + output = layer(output, src_mask=mask, + src_key_padding_mask=src_key_padding_mask, pos=pos) + + if self.norm is not None: + output = self.norm(output) + + return output + + +class TransformerDecoder(nn.Module): + + def __init__(self, decoder_layer, num_layers, norm=None, return_intermediate=False): + super().__init__() + self.layers = _get_clones(decoder_layer, num_layers) + self.num_layers = num_layers + self.norm = norm + self.return_intermediate = return_intermediate + + def forward(self, tgt, memory, + tgt_mask: Optional[Tensor] = None, + memory_mask: Optional[Tensor] = None, + tgt_key_padding_mask: Optional[Tensor] = None, + memory_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None, + query_pos: Optional[Tensor] = None): + output = tgt + + intermediate = [] + + for layer in self.layers: + output = layer(output, memory, tgt_mask=tgt_mask, + memory_mask=memory_mask, + tgt_key_padding_mask=tgt_key_padding_mask, + memory_key_padding_mask=memory_key_padding_mask, + pos=pos, query_pos=query_pos) + if self.return_intermediate: + intermediate.append(self.norm(output)) + + if self.norm is not None: + output = self.norm(output) + if self.return_intermediate: + intermediate.pop() + intermediate.append(output) + + if self.return_intermediate: + return torch.stack(intermediate) + + return output.unsqueeze(0) + + +class TransformerEncoderLayer(nn.Module): + + def __init__(self, d_model, nhead, dim_feedforward=2048, dropout=0.1, + activation="relu", normalize_before=False): + super().__init__() + self.d_model = d_model + self.self_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout) + # Implementation of Feedforward model + self.linear1 = nn.Linear(d_model, dim_feedforward) + self.dropout = nn.Dropout(dropout) + self.linear2 = nn.Linear(dim_feedforward, d_model) + + self.norm1 = nn.LayerNorm(d_model) + self.norm2 = nn.LayerNorm(d_model) + self.dropout1 = nn.Dropout(dropout) + self.dropout2 = nn.Dropout(dropout) + + self.activation = _get_activation_fn(activation) + self.normalize_before = normalize_before + + def with_pos_embed(self, tensor, pos: Optional[Tensor]): + return tensor if pos is None else tensor + pos + + def forward_post(self, + src, + src_mask: Optional[Tensor] = None, + src_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None): + q = k = self.with_pos_embed(src, pos) + src2 = self.self_attn(q, k, value=src, attn_mask=src_mask, + key_padding_mask=src_key_padding_mask)[0] + src = src + self.dropout1(src2) + src = self.norm1(src) + src2 = self.linear2(self.dropout(self.activation(self.linear1(src)))) + src = src + self.dropout2(src2) + src = self.norm2(src) + return src + + def forward_pre(self, src, + src_mask: Optional[Tensor] = None, + src_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None): + src2 = self.norm1(src) + q = k = self.with_pos_embed(src2, pos) + src2 = self.self_attn(q, k, value=src2, attn_mask=src_mask, + key_padding_mask=src_key_padding_mask)[0] + src = src + self.dropout1(src2) + src2 = self.norm2(src) + src2 = self.linear2(self.dropout(self.activation(self.linear1(src2)))) + src = src + self.dropout2(src2) + return src + + def forward(self, src, + src_mask: Optional[Tensor] = None, + src_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None): + if self.normalize_before: + return self.forward_pre(src, src_mask, src_key_padding_mask, pos) + return self.forward_post(src, src_mask, src_key_padding_mask, pos) + + +class TransformerDecoderLayer(nn.Module): + + def __init__(self, d_model, nhead, dim_feedforward=2048, dropout=0.1, + activation="relu", normalize_before=False): + super().__init__() + self.self_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout) + self.multihead_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout) + # Implementation of Feedforward model + self.d_model = d_model + self.linear1 = nn.Linear(d_model, dim_feedforward) + self.dropout = nn.Dropout(dropout) + self.linear2 = nn.Linear(dim_feedforward, d_model) + + self.norm1 = nn.LayerNorm(d_model) + self.norm2 = nn.LayerNorm(d_model) + self.norm3 = nn.LayerNorm(d_model) + self.dropout1 = nn.Dropout(dropout) + self.dropout2 = nn.Dropout(dropout) + self.dropout3 = nn.Dropout(dropout) + + self.activation = _get_activation_fn(activation) + self.normalize_before = normalize_before + + def with_pos_embed(self, tensor, pos: Optional[Tensor]): + return tensor if pos is None else tensor + pos + + def forward_post(self, tgt, memory, + tgt_mask: Optional[Tensor] = None, + memory_mask: Optional[Tensor] = None, + tgt_key_padding_mask: Optional[Tensor] = None, + memory_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None, + query_pos: Optional[Tensor] = None): + + q = k = self.with_pos_embed(tgt, query_pos) + tgt2 = self.self_attn(q, k, value=tgt, attn_mask=tgt_mask, + key_padding_mask=tgt_key_padding_mask)[0] + tgt = tgt + self.dropout1(tgt2) + tgt = self.norm1(tgt) + tgt2 = self.multihead_attn(query=self.with_pos_embed(tgt, query_pos), + key=self.with_pos_embed(memory, pos), + value=memory, attn_mask=memory_mask, + key_padding_mask=memory_key_padding_mask)[0] + tgt = tgt + self.dropout2(tgt2) + tgt = self.norm2(tgt) + tgt2 = self.linear2(self.dropout(self.activation(self.linear1(tgt)))) + tgt = tgt + self.dropout3(tgt2) + tgt = self.norm3(tgt) + return tgt + + def forward_pre(self, tgt, memory, + tgt_mask: Optional[Tensor] = None, + memory_mask: Optional[Tensor] = None, + tgt_key_padding_mask: Optional[Tensor] = None, + memory_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None, + query_pos: Optional[Tensor] = None): + tgt2 = self.norm1(tgt) + q = k = self.with_pos_embed(tgt2, query_pos) + tgt2 = self.self_attn(q, k, value=tgt2, attn_mask=tgt_mask, + key_padding_mask=tgt_key_padding_mask)[0] + tgt = tgt + self.dropout1(tgt2) + tgt2 = self.norm2(tgt) + tgt2 = self.multihead_attn(query=self.with_pos_embed(tgt2, query_pos), + key=self.with_pos_embed(memory, pos), + value=memory, attn_mask=memory_mask, + key_padding_mask=memory_key_padding_mask)[0] + tgt = tgt + self.dropout2(tgt2) + tgt2 = self.norm3(tgt) + tgt2 = self.linear2(self.dropout(self.activation(self.linear1(tgt2)))) + tgt = tgt + self.dropout3(tgt2) + return tgt + + def forward(self, tgt, memory, + tgt_mask: Optional[Tensor] = None, + memory_mask: Optional[Tensor] = None, + tgt_key_padding_mask: Optional[Tensor] = None, + memory_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None, + query_pos: Optional[Tensor] = None): + if self.normalize_before: + return self.forward_pre(tgt, memory, tgt_mask, memory_mask, + tgt_key_padding_mask, memory_key_padding_mask, pos, query_pos) + return self.forward_post(tgt, memory, tgt_mask, memory_mask, + tgt_key_padding_mask, memory_key_padding_mask, pos, query_pos) + + +def _get_clone(module): + return copy.deepcopy(module) + +def _get_clones(module, N): + return nn.ModuleList([copy.deepcopy(module) for i in range(N)]) + + +def build_transformer(args): + return Transformer( + d_model=args.hidden_dim, + dropout=args.dropout, + nhead=args.nheads, + dim_feedforward=args.dim_feedforward, + num_encoder_layers=args.enc_layers, + num_decoder_layers=args.dec_layers, + normalize_before=args.pre_norm, + return_intermediate_dec=True, + ) + + +def _get_activation_fn(activation): + """Return an activation function given a string""" + if activation == "relu": + return F.relu + if activation == "gelu": + return F.gelu + if activation == "glu": + return F.glu + raise RuntimeError(F"activation should be relu/gelu, not {activation}.") \ No newline at end of file diff --git a/motiondiff_modules/mGPT/models/utils/position_encoding.py b/motiondiff_modules/mGPT/models/utils/position_encoding.py new file mode 100644 index 0000000..669c677 --- /dev/null +++ b/motiondiff_modules/mGPT/models/utils/position_encoding.py @@ -0,0 +1,192 @@ +# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved +""" +Various positional encodings for the transformer. +""" +import math +from typing import List, Optional + +import numpy as np +import torch +from torch import Tensor, nn + +# from util.misc import NestedTensor + + +class NestedTensor(object): + + def __init__(self, tensors, mask: Optional[Tensor]): + self.tensors = tensors + self.mask = mask + + def to(self, device): + # type: (Device) -> NestedTensor # noqa + cast_tensor = self.tensors.to(device) + mask = self.mask + if mask is not None: + assert mask is not None + cast_mask = mask.to(device) + else: + cast_mask = None + return NestedTensor(cast_tensor, cast_mask) + + def decompose(self): + return self.tensors, self.mask + + def __repr__(self): + return str(self.tensors) + + +class PositionEmbeddingSine(nn.Module): + """ + This is a more standard version of the position embedding, very similar to the one + used by the Attention is all you need paper, generalized to work on images. + """ + + def __init__(self, + num_pos_feats=64, + temperature=10000, + normalize=False, + scale=None): + super().__init__() + self.num_pos_feats = num_pos_feats + self.temperature = temperature + self.normalize = normalize + if scale is not None and normalize is False: + raise ValueError("normalize should be True if scale is passed") + if scale is None: + scale = 2 * math.pi + self.scale = scale + + def forward(self, tensor_list: NestedTensor): + x = tensor_list.tensors + mask = tensor_list.mask + assert mask is not None + not_mask = ~mask + y_embed = not_mask.cumsum(1, dtype=torch.float32) + x_embed = not_mask.cumsum(2, dtype=torch.float32) + if self.normalize: + eps = 1e-6 + y_embed = y_embed / (y_embed[:, -1:, :] + eps) * self.scale + x_embed = x_embed / (x_embed[:, :, -1:] + eps) * self.scale + + dim_t = torch.arange(self.num_pos_feats, + dtype=torch.float32, + device=x.device) + dim_t = self.temperature**(2 * (dim_t // 2) / self.num_pos_feats) + + pos_x = x_embed[:, :, :, None] / dim_t + pos_y = y_embed[:, :, :, None] / dim_t + pos_x = torch.stack( + (pos_x[:, :, :, 0::2].sin(), pos_x[:, :, :, 1::2].cos()), + dim=4).flatten(3) + pos_y = torch.stack( + (pos_y[:, :, :, 0::2].sin(), pos_y[:, :, :, 1::2].cos()), + dim=4).flatten(3) + pos = torch.cat((pos_y, pos_x), dim=3).permute(0, 3, 1, 2) + return pos + + +class PositionEmbeddingLearned(nn.Module): + """ + Absolute pos embedding, learned. + """ + + def __init__(self, num_pos_feats=256): + super().__init__() + self.row_embed = nn.Embedding(50, num_pos_feats) + self.col_embed = nn.Embedding(50, num_pos_feats) + self.reset_parameters() + + def reset_parameters(self): + nn.init.uniform_(self.row_embed.weight) + nn.init.uniform_(self.col_embed.weight) + + def forward(self, tensor_list: NestedTensor): + x = tensor_list.tensors + h, w = x.shape[-2:] + i = torch.arange(w, device=x.device) + j = torch.arange(h, device=x.device) + x_emb = self.col_embed(i) + y_emb = self.row_embed(j) + pos = torch.cat([ + x_emb.unsqueeze(0).repeat(h, 1, 1), + y_emb.unsqueeze(1).repeat(1, w, 1), + ], + dim=-1).permute(2, 0, 1).unsqueeze(0).repeat( + x.shape[0], 1, 1, 1) + return pos + + +class PositionEmbeddingSine1D(nn.Module): + + def __init__(self, d_model, max_len=500, batch_first=False): + super().__init__() + self.batch_first = batch_first + + pe = torch.zeros(max_len, d_model) + position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1) + div_term = torch.exp( + torch.arange(0, d_model, 2).float() * (-np.log(10000.0) / d_model)) + pe[:, 0::2] = torch.sin(position * div_term) + pe[:, 1::2] = torch.cos(position * div_term) + pe = pe.unsqueeze(0).transpose(0, 1) + + self.register_buffer('pe', pe) + + def forward(self, x): + # not used in the final model + if self.batch_first: + pos = self.pe.permute(1, 0, 2)[:, :x.shape[1], :] + else: + pos = self.pe[:x.shape[0], :] + return pos + + +class PositionEmbeddingLearned1D(nn.Module): + + def __init__(self, d_model, max_len=500, batch_first=False): + super().__init__() + self.batch_first = batch_first + # self.dropout = nn.Dropout(p=dropout) + + self.pe = nn.Parameter(torch.zeros(max_len, 1, d_model)) + # self.pe = pe.unsqueeze(0).transpose(0, 1) + + self.reset_parameters() + + def reset_parameters(self): + nn.init.uniform_(self.pe) + + def forward(self, x): + # not used in the final model + if self.batch_first: + pos = self.pe.permute(1, 0, 2)[:, :x.shape[1], :] + else: + x = x + self.pe[:x.shape[0], :] + return x + # return self.dropout(x) + + +def build_position_encoding(N_steps, + position_embedding="sine", + embedding_dim="1D"): + # N_steps = hidden_dim // 2 + if embedding_dim == "1D": + if position_embedding in ('v2', 'sine'): + position_embedding = PositionEmbeddingSine1D(N_steps) + elif position_embedding in ('v3', 'learned'): + position_embedding = PositionEmbeddingLearned1D(N_steps) + else: + raise ValueError(f"not supported {position_embedding}") + elif embedding_dim == "2D": + if position_embedding in ('v2', 'sine'): + # TODO find a better way of exposing other arguments + position_embedding = PositionEmbeddingSine(N_steps, normalize=True) + elif position_embedding in ('v3', 'learned'): + position_embedding = PositionEmbeddingLearned(N_steps) + else: + raise ValueError(f"not supported {position_embedding}") + else: + raise ValueError(f"not supported {embedding_dim}") + + return position_embedding diff --git a/motiondiff_modules/mGPT/models/utils/position_encoding_layer.py b/motiondiff_modules/mGPT/models/utils/position_encoding_layer.py new file mode 100644 index 0000000..699c860 --- /dev/null +++ b/motiondiff_modules/mGPT/models/utils/position_encoding_layer.py @@ -0,0 +1,30 @@ +import numpy as np +import torch +from torch import nn + + +class PositionalEncoding(nn.Module): + + def __init__(self, d_model, dropout=0.1, max_len=5000, batch_first=False): + super().__init__() + self.batch_first = batch_first + + self.dropout = nn.Dropout(p=dropout) + + pe = torch.zeros(max_len, d_model) + position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1) + div_term = torch.exp(torch.arange( + 0, d_model, 2).float() * (-np.log(10000.0) / d_model)) + pe[:, 0::2] = torch.sin(position * div_term) + pe[:, 1::2] = torch.cos(position * div_term) + pe = pe.unsqueeze(0).transpose(0, 1) + + self.register_buffer("pe", pe) + + def forward(self, x): + # not used in the final model + if self.batch_first: + x = x + self.pe.permute(1, 0, 2)[:, : x.shape[1], :] + else: + x = x + self.pe[: x.shape[0], :] + return self.dropout(x) diff --git a/motiondiff_modules/mGPT/models/utils/tools.py b/motiondiff_modules/mGPT/models/utils/tools.py new file mode 100644 index 0000000..89ecab5 --- /dev/null +++ b/motiondiff_modules/mGPT/models/utils/tools.py @@ -0,0 +1,37 @@ +import torch.nn as nn + +def remove_padding(tensors, lengths): + return [tensor[:tensor_length] for tensor, tensor_length in zip(tensors, lengths)] + +class AutoParams(nn.Module): + def __init__(self, **kargs): + try: + for param in self.needed_params: + if param in kargs: + setattr(self, param, kargs[param]) + else: + raise ValueError(f"{param} is needed.") + except : + pass + + try: + for param, default in self.optional_params.items(): + if param in kargs and kargs[param] is not None: + setattr(self, param, kargs[param]) + else: + setattr(self, param, default) + except : + pass + super().__init__() + + +# taken from joeynmt repo +def freeze_params(module: nn.Module) -> None: + """ + Freeze the parameters of this module, + i.e. do not update them during training + + :param module: freeze parameters of this module + """ + for _, p in module.named_parameters(): + p.requires_grad = False diff --git a/motiondiff_modules/mGPT/utils/__init__.py b/motiondiff_modules/mGPT/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/motiondiff_modules/mGPT/utils/demo_utils.py b/motiondiff_modules/mGPT/utils/demo_utils.py new file mode 100644 index 0000000..1a62993 --- /dev/null +++ b/motiondiff_modules/mGPT/utils/demo_utils.py @@ -0,0 +1,79 @@ +import os +from pathlib import Path + + +# load example data +def load_example_input(txt_path): + file = open(txt_path, "r") + Lines = file.readlines() + count = 0 + texts, lens = [], [] + # Strips the newline character + for line in Lines: + count += 1 + s = line.strip() + s_l = s.split(" ")[0] + s_t = s[(len(s_l) + 1):] + lens.append(int(s_l)) + texts.append(s_t) + print("Length-{}: {}".format(s_l, s_t)) + return texts, lens + + +# render batch +def render_batch(npy_dir, execute_python="./scripts/visualize_motion.sh", mode="sequence"): + os.system(f"{execute_python} {npy_dir} {mode}") + + +# render +def render(execute_python, npy_path, jointtype, cfg_path): + # execute_python = "/apdcephfs/share_1227775/shingxchen/libs/blender_bpy/blender-2.93.2-linux-x64/blender" + # execute_python = "/apdcephfs/share_1227775/mingzhenzhu/jiangbiao/libs/blender-2.93.2-linux-x64/blender" + export_scripts = "render.py" + + os.system( + f"{execute_python} --background --python {export_scripts} -- --cfg={cfg_path} --npy={npy_path} --joint_type={jointtype}" + ) + + fig_path = Path(str(npy_path).replace(".npy", ".png")) + return fig_path + + +# origin render +# def render(npy_path, jointtype): +# execute_python = '/apdcephfs/share_1227775/shingxchen/libs/blender_bpy/blender-2.93.2-linux-x64/blender' +# export_scripts = 'render.py' + +# os.system(f"{execute_python} --background --python {export_scripts} -- npy={npy_path} jointstype={jointtype}") + +# fig_path = Path(str(npy_path).replace(".npy",".png")) +# return fig_path + +# export fbx with hand params from pkl files +# refer to /apdcephfs/share_1227775/shingxchen/AIMotion/TMOST/scripts/fbx_output_smplx.py +def export_fbx_hand(pkl_path): + input = pkl_path + output = pkl_path.replace(".pkl", ".fbx") + + execute_python = "/apdcephfs/share_1227775/shingxchen/libs/blender_bpy/blender-2.93.2-linux-x64/blender" + export_scripts = "./scripts/fbx_output_smplx.py" + os.system( + f"{execute_python} -noaudio --background --python {export_scripts}\ + --input {input} \ + --output {output}" + ) + + +# export fbx without hand params from pkl files +# refer to /apdcephfs/share_1227775/shingxchen/AIMotion/TMOST/scripts/fbx_output.py +def export_fbx(pkl_path): + input = pkl_path + output = pkl_path.replace(".pkl", ".fbx") + + execute_python = "/apdcephfs/share_1227775/shingxchen/libs/blender_bpy/blender-2.93.2-linux-x64/blender" + export_scripts = "./scripts/fbx_output.py" + os.system( + f"{execute_python} -noaudio --background --python {export_scripts}\ + --input {input} \ + --output {output}" + ) diff --git a/motiondiff_modules/mGPT/utils/easyconvert.py b/motiondiff_modules/mGPT/utils/easyconvert.py new file mode 100644 index 0000000..2480737 --- /dev/null +++ b/motiondiff_modules/mGPT/utils/easyconvert.py @@ -0,0 +1,84 @@ +from .geometry_tools import * + + +def rep_to_rep(oldtype, newtype, rotations): + if newtype in ["matrix"]: + return to_matrix(oldtype, rotations) + + if oldtype in ["rotvec", "axisangle"]: + return axis_angle_to(newtype, rotations) + elif oldtype in ["matrix"]: + return matrix_to(newtype, rotations) + else: + raise NotImplementedError("Only rotvec and matrix are supported.") + +def nfeats_of(rottype): + if rottype in ["rotvec", "axisangle"]: + return 3 + elif rottype in ["rotquat", "quaternion"]: + return 4 + elif rottype in ["rot6d", "6drot", "rotation6d"]: + return 6 + elif rottype in ["rotmat"]: + return 9 + else: + return TypeError("This rotation type doesn't have features.") + + +def axis_angle_to(newtype, rotations): + if newtype in ["matrix"]: + rotations = axis_angle_to_matrix(rotations) + return rotations + elif newtype in ["rotmat"]: + rotations = axis_angle_to_matrix(rotations) + rotations = matrix_to("rotmat", rotations) + return rotations + elif newtype in ["rot6d", "6drot", "rotation6d"]: + rotations = axis_angle_to_matrix(rotations) + rotations = matrix_to("rot6d", rotations) + return rotations + elif newtype in ["rotquat", "quaternion"]: + rotations = axis_angle_to_quaternion(rotations) + return rotations + elif newtype in ["rotvec", "axisangle"]: + return rotations + else: + raise NotImplementedError + + +def matrix_to(newtype, rotations): + if newtype in ["matrix"]: + return rotations + if newtype in ["rotmat"]: + rotations = rotations.reshape((*rotations.shape[:-2], 9)) + return rotations + elif newtype in ["rot6d", "6drot", "rotation6d"]: + rotations = matrix_to_rotation_6d(rotations) + return rotations + elif newtype in ["rotquat", "quaternion"]: + rotations = matrix_to_quaternion(rotations) + return rotations + elif newtype in ["rotvec", "axisangle"]: + rotations = matrix_to_axis_angle(rotations) + return rotations + else: + raise NotImplementedError + + +def to_matrix(oldtype, rotations): + if oldtype in ["matrix"]: + return rotations + if oldtype in ["rotmat"]: + rotations = rotations.reshape((*rotations.shape[:-2], 3, 3)) + return rotations + elif oldtype in ["rot6d", "6drot", "rotation6d"]: + rotations = rotation_6d_to_matrix(rotations) + return rotations + elif oldtype in ["rotquat", "quaternion"]: + rotations = quaternion_to_matrix(rotations) + return rotations + elif oldtype in ["rotvec", "axisangle"]: + rotations = axis_angle_to_matrix(rotations) + return rotations + else: + raise NotImplementedError diff --git a/motiondiff_modules/mGPT/utils/fixseed.py b/motiondiff_modules/mGPT/utils/fixseed.py new file mode 100644 index 0000000..a43a273 --- /dev/null +++ b/motiondiff_modules/mGPT/utils/fixseed.py @@ -0,0 +1,18 @@ +import numpy as np +import torch +import random + + +def fixseed(seed): + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + + +SEED = 10 +EVALSEED = 0 +# Provoc warning: not fully functionnal yet +# torch.set_deterministic(True) +torch.backends.cudnn.benchmark = False + +fixseed(SEED) diff --git a/motiondiff_modules/mGPT/utils/geometry_conver.py b/motiondiff_modules/mGPT/utils/geometry_conver.py new file mode 100644 index 0000000..5c5c844 --- /dev/null +++ b/motiondiff_modules/mGPT/utils/geometry_conver.py @@ -0,0 +1,550 @@ +# -*- coding: utf-8 -*- + +# Max-Planck-Gesellschaft zur Förderung der Wissenschaften e.V. (MPG) is +# holder of all proprietary rights on this computer program. +# You can only use this computer program if you have closed +# a license agreement with MPG or you get the right to use the computer +# program from someone who is authorized to grant you that right. +# Any use of the computer program without a valid license is prohibited and +# liable to prosecution. +# +# Copyright©2019 Max-Planck-Gesellschaft zur Förderung +# der Wissenschaften e.V. (MPG). acting on behalf of its Max Planck Institute +# for Intelligent Systems. All rights reserved. +# +# Contact: ps-license@tuebingen.mpg.de + +import torch +import numpy as np +from torch.nn import functional as F + + +def axis_angle_to_quaternion(axis_angle): + """ + Convert rotations given as axis/angle to quaternions. + + Args: + axis_angle: Rotations given as a vector in axis angle form, + as a tensor of shape (..., 3), where the magnitude is + the angle turned anticlockwise in radians around the + vector's direction. + + Returns: + quaternions with real part first, as tensor of shape (..., 4). + """ + angles = torch.norm(axis_angle, p=2, dim=-1, keepdim=True) + half_angles = 0.5 * angles + eps = 1e-6 + small_angles = angles.abs() < eps + sin_half_angles_over_angles = torch.empty_like(angles) + sin_half_angles_over_angles[~small_angles] = ( + torch.sin(half_angles[~small_angles]) / angles[~small_angles]) + # for x small, sin(x/2) is about x/2 - (x/2)^3/6 + # so sin(x/2)/x is about 1/2 - (x*x)/48 + sin_half_angles_over_angles[small_angles] = ( + 0.5 - (angles[small_angles] * angles[small_angles]) / 48) + quaternions = torch.cat( + [torch.cos(half_angles), axis_angle * sin_half_angles_over_angles], + dim=-1) + return quaternions + + +def quaternion_to_matrix(quaternions): + """ + Convert rotations given as quaternions to rotation matrices. + + Args: + quaternions: quaternions with real part first, + as tensor of shape (..., 4). + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + r, i, j, k = torch.unbind(quaternions, -1) + two_s = 2.0 / (quaternions * quaternions).sum(-1) + + o = torch.stack( + ( + 1 - two_s * (j * j + k * k), + two_s * (i * j - k * r), + two_s * (i * k + j * r), + two_s * (i * j + k * r), + 1 - two_s * (i * i + k * k), + two_s * (j * k - i * r), + two_s * (i * k - j * r), + two_s * (j * k + i * r), + 1 - two_s * (i * i + j * j), + ), + -1, + ) + return o.reshape(quaternions.shape[:-1] + (3, 3)) + + +def axis_angle_to_matrix(axis_angle): + """ + Convert rotations given as axis/angle to rotation matrices. + + Args: + axis_angle: Rotations given as a vector in axis angle form, + as a tensor of shape (..., 3), where the magnitude is + the angle turned anticlockwise in radians around the + vector's direction. + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + return quaternion_to_matrix(axis_angle_to_quaternion(axis_angle)) + + +def matrix_of_angles(cos, sin, inv=False, dim=2): + assert dim in [2, 3] + sin = -sin if inv else sin + if dim == 2: + row1 = torch.stack((cos, -sin), axis=-1) + row2 = torch.stack((sin, cos), axis=-1) + return torch.stack((row1, row2), axis=-2) + elif dim == 3: + row1 = torch.stack((cos, -sin, 0 * cos), axis=-1) + row2 = torch.stack((sin, cos, 0 * cos), axis=-1) + row3 = torch.stack((0 * sin, 0 * cos, 1 + 0 * cos), axis=-1) + return torch.stack((row1, row2, row3), axis=-2) + + +def matrot2axisangle(matrots): + # This function is borrowed from https://github.com/davrempe/humor/utils/transforms.py + # axisang N x 3 + ''' + :param matrots: N*num_joints*9 + :return: N*num_joints*3 + ''' + import cv2 + batch_size = matrots.shape[0] + matrots = matrots.reshape([batch_size, -1, 9]) + out_axisangle = [] + for mIdx in range(matrots.shape[0]): + cur_axisangle = [] + for jIdx in range(matrots.shape[1]): + a = cv2.Rodrigues(matrots[mIdx, + jIdx:jIdx + 1, :].reshape(3, + 3))[0].reshape( + (1, 3)) + cur_axisangle.append(a) + + out_axisangle.append(np.array(cur_axisangle).reshape([1, -1, 3])) + return np.vstack(out_axisangle) + + +def axisangle2matrots(axisangle): + # This function is borrowed from https://github.com/davrempe/humor/utils/transforms.py + # axisang N x 3 + ''' + :param axisangle: N*num_joints*3 + :return: N*num_joints*9 + ''' + import cv2 + batch_size = axisangle.shape[0] + axisangle = axisangle.reshape([batch_size, -1, 3]) + out_matrot = [] + for mIdx in range(axisangle.shape[0]): + cur_axisangle = [] + for jIdx in range(axisangle.shape[1]): + a = cv2.Rodrigues(axisangle[mIdx, jIdx:jIdx + 1, :].reshape(1, + 3))[0] + cur_axisangle.append(a) + + out_matrot.append(np.array(cur_axisangle).reshape([1, -1, 9])) + return np.vstack(out_matrot) + + +def batch_rodrigues(axisang): + # This function is borrowed from https://github.com/MandyMo/pytorch_HMR/blob/master/src/util.py#L37 + # axisang N x 3 + axisang_norm = torch.norm(axisang + 1e-8, p=2, dim=1) + angle = torch.unsqueeze(axisang_norm, -1) + axisang_normalized = torch.div(axisang, angle) + angle = angle * 0.5 + v_cos = torch.cos(angle) + v_sin = torch.sin(angle) + + quat = torch.cat([v_cos, v_sin * axisang_normalized], dim=1) + rot_mat = quat2mat(quat) + rot_mat = rot_mat.view(rot_mat.shape[0], 9) + return rot_mat + + +def quat2mat(quat): + """ + This function is borrowed from https://github.com/MandyMo/pytorch_HMR/blob/master/src/util.py#L50 + + Convert quaternion coefficients to rotation matrix. + Args: + quat: size = [batch_size, 4] 4 <===>(w, x, y, z) + Returns: + Rotation matrix corresponding to the quaternion -- size = [batch_size, 3, 3] + """ + norm_quat = quat + norm_quat = norm_quat / norm_quat.norm(p=2, dim=1, keepdim=True) + w, x, y, z = norm_quat[:, 0], norm_quat[:, 1], norm_quat[:, + 2], norm_quat[:, + 3] + + batch_size = quat.size(0) + + w2, x2, y2, z2 = w.pow(2), x.pow(2), y.pow(2), z.pow(2) + wx, wy, wz = w * x, w * y, w * z + xy, xz, yz = x * y, x * z, y * z + + rotMat = torch.stack([ + w2 + x2 - y2 - z2, 2 * xy - 2 * wz, 2 * wy + 2 * xz, 2 * wz + 2 * xy, + w2 - x2 + y2 - z2, 2 * yz - 2 * wx, 2 * xz - 2 * wy, 2 * wx + 2 * yz, + w2 - x2 - y2 + z2 + ], + dim=1).view(batch_size, 3, 3) + return rotMat + + +def rotation_matrix_to_angle_axis(rotation_matrix): + """ + This function is borrowed from https://github.com/kornia/kornia + + Convert 3x4 rotation matrix to Rodrigues vector + + Args: + rotation_matrix (Tensor): rotation matrix. + + Returns: + Tensor: Rodrigues vector transformation. + + Shape: + - Input: :math:`(N, 3, 4)` + - Output: :math:`(N, 3)` + + Example: + >>> input = torch.rand(2, 3, 4) # Nx4x4 + >>> output = tgm.rotation_matrix_to_angle_axis(input) # Nx3 + """ + if rotation_matrix.shape[1:] == (3, 3): + rot_mat = rotation_matrix.reshape(-1, 3, 3) + hom = torch.tensor([0, 0, 1], + dtype=torch.float32, + device=rotation_matrix.device).reshape( + 1, 3, 1).expand(rot_mat.shape[0], -1, -1) + rotation_matrix = torch.cat([rot_mat, hom], dim=-1) + + quaternion = rotation_matrix_to_quaternion(rotation_matrix) + aa = quaternion_to_angle_axis(quaternion) + aa[torch.isnan(aa)] = 0.0 + return aa + + +def quaternion_to_angle_axis(quaternion: torch.Tensor) -> torch.Tensor: + """ + This function is borrowed from https://github.com/kornia/kornia + + Convert quaternion vector to angle axis of rotation. + + Adapted from ceres C++ library: ceres-solver/include/ceres/rotation.h + + Args: + quaternion (torch.Tensor): tensor with quaternions. + + Return: + torch.Tensor: tensor with angle axis of rotation. + + Shape: + - Input: :math:`(*, 4)` where `*` means, any number of dimensions + - Output: :math:`(*, 3)` + + Example: + >>> quaternion = torch.rand(2, 4) # Nx4 + >>> angle_axis = tgm.quaternion_to_angle_axis(quaternion) # Nx3 + """ + if not torch.is_tensor(quaternion): + raise TypeError("Input type is not a torch.Tensor. Got {}".format( + type(quaternion))) + + if not quaternion.shape[-1] == 4: + raise ValueError( + "Input must be a tensor of shape Nx4 or 4. Got {}".format( + quaternion.shape)) + # unpack input and compute conversion + q1: torch.Tensor = quaternion[..., 1] + q2: torch.Tensor = quaternion[..., 2] + q3: torch.Tensor = quaternion[..., 3] + sin_squared_theta: torch.Tensor = q1 * q1 + q2 * q2 + q3 * q3 + + sin_theta: torch.Tensor = torch.sqrt(sin_squared_theta) + cos_theta: torch.Tensor = quaternion[..., 0] + two_theta: torch.Tensor = 2.0 * torch.where( + cos_theta < 0.0, torch.atan2(-sin_theta, -cos_theta), + torch.atan2(sin_theta, cos_theta)) + + k_pos: torch.Tensor = two_theta / sin_theta + k_neg: torch.Tensor = 2.0 * torch.ones_like(sin_theta) + k: torch.Tensor = torch.where(sin_squared_theta > 0.0, k_pos, k_neg) + + angle_axis: torch.Tensor = torch.zeros_like(quaternion)[..., :3] + angle_axis[..., 0] += q1 * k + angle_axis[..., 1] += q2 * k + angle_axis[..., 2] += q3 * k + return angle_axis + + +def rotation_matrix_to_quaternion(rotation_matrix, eps=1e-6): + """ + This function is borrowed from https://github.com/kornia/kornia + + Convert 3x4 rotation matrix to 4d quaternion vector + + This algorithm is based on algorithm described in + https://github.com/KieranWynn/pyquaternion/blob/master/pyquaternion/quaternion.py#L201 + + Args: + rotation_matrix (Tensor): the rotation matrix to convert. + + Return: + Tensor: the rotation in quaternion + + Shape: + - Input: :math:`(N, 3, 4)` + - Output: :math:`(N, 4)` + + Example: + >>> input = torch.rand(4, 3, 4) # Nx3x4 + >>> output = tgm.rotation_matrix_to_quaternion(input) # Nx4 + """ + if not torch.is_tensor(rotation_matrix): + raise TypeError("Input type is not a torch.Tensor. Got {}".format( + type(rotation_matrix))) + + if len(rotation_matrix.shape) > 3: + raise ValueError( + "Input size must be a three dimensional tensor. Got {}".format( + rotation_matrix.shape)) + if not rotation_matrix.shape[-2:] == (3, 4): + raise ValueError( + "Input size must be a N x 3 x 4 tensor. Got {}".format( + rotation_matrix.shape)) + + rmat_t = torch.transpose(rotation_matrix, 1, 2) + + mask_d2 = rmat_t[:, 2, 2] < eps + + mask_d0_d1 = rmat_t[:, 0, 0] > rmat_t[:, 1, 1] + mask_d0_nd1 = rmat_t[:, 0, 0] < -rmat_t[:, 1, 1] + + t0 = 1 + rmat_t[:, 0, 0] - rmat_t[:, 1, 1] - rmat_t[:, 2, 2] + q0 = torch.stack([ + rmat_t[:, 1, 2] - rmat_t[:, 2, 1], t0, + rmat_t[:, 0, 1] + rmat_t[:, 1, 0], rmat_t[:, 2, 0] + rmat_t[:, 0, 2] + ], -1) + t0_rep = t0.repeat(4, 1).t() + + t1 = 1 - rmat_t[:, 0, 0] + rmat_t[:, 1, 1] - rmat_t[:, 2, 2] + q1 = torch.stack([ + rmat_t[:, 2, 0] - rmat_t[:, 0, 2], rmat_t[:, 0, 1] + rmat_t[:, 1, 0], + t1, rmat_t[:, 1, 2] + rmat_t[:, 2, 1] + ], -1) + t1_rep = t1.repeat(4, 1).t() + + t2 = 1 - rmat_t[:, 0, 0] - rmat_t[:, 1, 1] + rmat_t[:, 2, 2] + q2 = torch.stack([ + rmat_t[:, 0, 1] - rmat_t[:, 1, 0], rmat_t[:, 2, 0] + rmat_t[:, 0, 2], + rmat_t[:, 1, 2] + rmat_t[:, 2, 1], t2 + ], -1) + t2_rep = t2.repeat(4, 1).t() + + t3 = 1 + rmat_t[:, 0, 0] + rmat_t[:, 1, 1] + rmat_t[:, 2, 2] + q3 = torch.stack([ + t3, rmat_t[:, 1, 2] - rmat_t[:, 2, 1], + rmat_t[:, 2, 0] - rmat_t[:, 0, 2], rmat_t[:, 0, 1] - rmat_t[:, 1, 0] + ], -1) + t3_rep = t3.repeat(4, 1).t() + + mask_c0 = mask_d2 * mask_d0_d1 + mask_c1 = mask_d2 * ~mask_d0_d1 + mask_c2 = ~mask_d2 * mask_d0_nd1 + mask_c3 = ~mask_d2 * ~mask_d0_nd1 + mask_c0 = mask_c0.view(-1, 1).type_as(q0) + mask_c1 = mask_c1.view(-1, 1).type_as(q1) + mask_c2 = mask_c2.view(-1, 1).type_as(q2) + mask_c3 = mask_c3.view(-1, 1).type_as(q3) + + q = q0 * mask_c0 + q1 * mask_c1 + q2 * mask_c2 + q3 * mask_c3 + q /= torch.sqrt(t0_rep * mask_c0 + t1_rep * mask_c1 + # noqa + t2_rep * mask_c2 + t3_rep * mask_c3) # noqa + q *= 0.5 + return q + + +def estimate_translation_np(S, + joints_2d, + joints_conf, + focal_length=5000., + img_size=224.): + """ + This function is borrowed from https://github.com/nkolot/SPIN/utils/geometry.py + + Find camera translation that brings 3D joints S closest to 2D the corresponding joints_2d. + Input: + S: (25, 3) 3D joint locations + joints: (25, 3) 2D joint locations and confidence + Returns: + (3,) camera translation vector + """ + + num_joints = S.shape[0] + # focal length + f = np.array([focal_length, focal_length]) + # optical center + center = np.array([img_size / 2., img_size / 2.]) + + # transformations + Z = np.reshape(np.tile(S[:, 2], (2, 1)).T, -1) + XY = np.reshape(S[:, 0:2], -1) + O = np.tile(center, num_joints) + F = np.tile(f, num_joints) + weight2 = np.reshape(np.tile(np.sqrt(joints_conf), (2, 1)).T, -1) + + # least squares + Q = np.array([ + F * np.tile(np.array([1, 0]), num_joints), + F * np.tile(np.array([0, 1]), num_joints), + O - np.reshape(joints_2d, -1) + ]).T + c = (np.reshape(joints_2d, -1) - O) * Z - F * XY + + # weighted least squares + W = np.diagflat(weight2) + Q = np.dot(W, Q) + c = np.dot(W, c) + + # square matrix + A = np.dot(Q.T, Q) + b = np.dot(Q.T, c) + + # solution + trans = np.linalg.solve(A, b) + + return trans + + +def estimate_translation(S, joints_2d, focal_length=5000., img_size=224.): + """ + This function is borrowed from https://github.com/nkolot/SPIN/utils/geometry.py + + Find camera translation that brings 3D joints S closest to 2D the corresponding joints_2d. + Input: + S: (B, 49, 3) 3D joint locations + joints: (B, 49, 3) 2D joint locations and confidence + Returns: + (B, 3) camera translation vectors + """ + + device = S.device + # Use only joints 25:49 (GT joints) + S = S[:, 25:, :].cpu().numpy() + joints_2d = joints_2d[:, 25:, :].cpu().numpy() + joints_conf = joints_2d[:, :, -1] + joints_2d = joints_2d[:, :, :-1] + trans = np.zeros((S.shape[0], 3), dtype=np.float6432) + # Find the translation for each example in the batch + for i in range(S.shape[0]): + S_i = S[i] + joints_i = joints_2d[i] + conf_i = joints_conf[i] + trans[i] = estimate_translation_np(S_i, + joints_i, + conf_i, + focal_length=focal_length, + img_size=img_size) + return torch.from_numpy(trans).to(device) + + +def rot6d_to_rotmat_spin(x): + """Convert 6D rotation representation to 3x3 rotation matrix. + Based on Zhou et al., "On the Continuity of Rotation Representations in Neural Networks", CVPR 2019 + Input: + (B,6) Batch of 6-D rotation representations + Output: + (B,3,3) Batch of corresponding rotation matrices + """ + x = x.view(-1, 3, 2) + a1 = x[:, :, 0] + a2 = x[:, :, 1] + b1 = F.normalize(a1) + b2 = F.normalize(a2 - torch.einsum('bi,bi->b', b1, a2).unsqueeze(-1) * b1) + + # inp = a2 - torch.einsum('bi,bi->b', b1, a2).unsqueeze(-1) * b1 + # denom = inp.pow(2).sum(dim=1).sqrt().unsqueeze(-1) + 1e-8 + # b2 = inp / denom + + b3 = torch.cross(b1, b2) + return torch.stack((b1, b2, b3), dim=-1) + + +def rot6d_to_rotmat(x): + x = x.view(-1, 3, 2) + + # Normalize the first vector + b1 = F.normalize(x[:, :, 0], dim=1, eps=1e-6) + + dot_prod = torch.sum(b1 * x[:, :, 1], dim=1, keepdim=True) + # Compute the second vector by finding the orthogonal complement to it + b2 = F.normalize(x[:, :, 1] - dot_prod * b1, dim=-1, eps=1e-6) + + # Finish building the basis by taking the cross product + b3 = torch.cross(b1, b2, dim=1) + rot_mats = torch.stack([b1, b2, b3], dim=-1) + + return rot_mats + + +import mGPT.utils.rotation_conversions as rotation_conversions + + +def rot6d(x_rotations, pose_rep): + time, njoints, feats = x_rotations.shape + + # Compute rotations (convert only masked sequences output) + if pose_rep == "rotvec": + rotations = rotation_conversions.axis_angle_to_matrix(x_rotations) + elif pose_rep == "rotmat": + rotations = x_rotations.view(njoints, 3, 3) + elif pose_rep == "rotquat": + rotations = rotation_conversions.quaternion_to_matrix(x_rotations) + elif pose_rep == "rot6d": + rotations = rotation_conversions.rotation_6d_to_matrix(x_rotations) + else: + raise NotImplementedError("No geometry for this one.") + + rotations_6d = rotation_conversions.matrix_to_rotation_6d(rotations) + return rotations_6d + + +def rot6d_batch(x_rotations, pose_rep): + nsamples, time, njoints, feats = x_rotations.shape + + # Compute rotations (convert only masked sequences output) + if pose_rep == "rotvec": + rotations = rotation_conversions.axis_angle_to_matrix(x_rotations) + elif pose_rep == "rotmat": + rotations = x_rotations.view(-1, njoints, 3, 3) + elif pose_rep == "rotquat": + rotations = rotation_conversions.quaternion_to_matrix(x_rotations) + elif pose_rep == "rot6d": + rotations = rotation_conversions.rotation_6d_to_matrix(x_rotations) + else: + raise NotImplementedError("No geometry for this one.") + + rotations_6d = rotation_conversions.matrix_to_rotation_6d(rotations) + return rotations_6d + + +def rot6d_to_rotvec_batch(pose): + # nsamples, time, njoints, feats = rot6d.shape + bs, nfeats = pose.shape + rot6d = pose.reshape(bs, 24, 6) + rotations = rotation_conversions.rotation_6d_to_matrix(rot6d) + rotvec = rotation_conversions.matrix_to_axis_angle(rotations) + return rotvec.reshape(bs, 24 * 3) diff --git a/motiondiff_modules/mGPT/utils/geometry_tools.py b/motiondiff_modules/mGPT/utils/geometry_tools.py new file mode 100644 index 0000000..e6eafa2 --- /dev/null +++ b/motiondiff_modules/mGPT/utils/geometry_tools.py @@ -0,0 +1,566 @@ +# Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. +# Check PYTORCH3D_LICENCE before use + +import functools +from typing import Optional + +import torch +import torch.nn.functional as F + + +""" +The transformation matrices returned from the functions in this file assume +the points on which the transformation will be applied are column vectors. +i.e. the R matrix is structured as + + R = [ + [Rxx, Rxy, Rxz], + [Ryx, Ryy, Ryz], + [Rzx, Rzy, Rzz], + ] # (3, 3) + +This matrix can be applied to column vectors by post multiplication +by the points e.g. + + points = [[0], [1], [2]] # (3 x 1) xyz coordinates of a point + transformed_points = R * points + +To apply the same matrix to points which are row vectors, the R matrix +can be transposed and pre multiplied by the points: + +e.g. + points = [[0, 1, 2]] # (1 x 3) xyz coordinates of a point + transformed_points = points * R.transpose(1, 0) +""" + + +# Added +def matrix_of_angles(cos, sin, inv=False, dim=2): + assert dim in [2, 3] + sin = -sin if inv else sin + if dim == 2: + row1 = torch.stack((cos, -sin), axis=-1) + row2 = torch.stack((sin, cos), axis=-1) + return torch.stack((row1, row2), axis=-2) + elif dim == 3: + row1 = torch.stack((cos, -sin, 0*cos), axis=-1) + row2 = torch.stack((sin, cos, 0*cos), axis=-1) + row3 = torch.stack((0*sin, 0*cos, 1+0*cos), axis=-1) + return torch.stack((row1, row2, row3),axis=-2) + + +def quaternion_to_matrix(quaternions): + """ + Convert rotations given as quaternions to rotation matrices. + + Args: + quaternions: quaternions with real part first, + as tensor of shape (..., 4). + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + r, i, j, k = torch.unbind(quaternions, -1) + two_s = 2.0 / (quaternions * quaternions).sum(-1) + + o = torch.stack( + ( + 1 - two_s * (j * j + k * k), + two_s * (i * j - k * r), + two_s * (i * k + j * r), + two_s * (i * j + k * r), + 1 - two_s * (i * i + k * k), + two_s * (j * k - i * r), + two_s * (i * k - j * r), + two_s * (j * k + i * r), + 1 - two_s * (i * i + j * j), + ), + -1, + ) + return o.reshape(quaternions.shape[:-1] + (3, 3)) + + +def _copysign(a, b): + """ + Return a tensor where each element has the absolute value taken from the, + corresponding element of a, with sign taken from the corresponding + element of b. This is like the standard copysign floating-point operation, + but is not careful about negative 0 and NaN. + + Args: + a: source tensor. + b: tensor whose signs will be used, of the same shape as a. + + Returns: + Tensor of the same shape as a with the signs of b. + """ + signs_differ = (a < 0) != (b < 0) + return torch.where(signs_differ, -a, a) + + +def _sqrt_positive_part(x): + """ + Returns torch.sqrt(torch.max(0, x)) + but with a zero subgradient where x is 0. + """ + ret = torch.zeros_like(x) + positive_mask = x > 0 + ret[positive_mask] = torch.sqrt(x[positive_mask]) + return ret + + +def matrix_to_quaternion(matrix): + """ + Convert rotations given as rotation matrices to quaternions. + + Args: + matrix: Rotation matrices as tensor of shape (..., 3, 3). + + Returns: + quaternions with real part first, as tensor of shape (..., 4). + """ + if matrix.size(-1) != 3 or matrix.size(-2) != 3: + raise ValueError(f"Invalid rotation matrix shape f{matrix.shape}.") + m00 = matrix[..., 0, 0] + m11 = matrix[..., 1, 1] + m22 = matrix[..., 2, 2] + o0 = 0.5 * _sqrt_positive_part(1 + m00 + m11 + m22) + x = 0.5 * _sqrt_positive_part(1 + m00 - m11 - m22) + y = 0.5 * _sqrt_positive_part(1 - m00 + m11 - m22) + z = 0.5 * _sqrt_positive_part(1 - m00 - m11 + m22) + o1 = _copysign(x, matrix[..., 2, 1] - matrix[..., 1, 2]) + o2 = _copysign(y, matrix[..., 0, 2] - matrix[..., 2, 0]) + o3 = _copysign(z, matrix[..., 1, 0] - matrix[..., 0, 1]) + return torch.stack((o0, o1, o2, o3), -1) + + +def _axis_angle_rotation(axis: str, angle): + """ + Return the rotation matrices for one of the rotations about an axis + of which Euler angles describe, for each value of the angle given. + + Args: + axis: Axis label "X" or "Y or "Z". + angle: any shape tensor of Euler angles in radians + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + + cos = torch.cos(angle) + sin = torch.sin(angle) + one = torch.ones_like(angle) + zero = torch.zeros_like(angle) + + if axis == "X": + R_flat = (one, zero, zero, zero, cos, -sin, zero, sin, cos) + if axis == "Y": + R_flat = (cos, zero, sin, zero, one, zero, -sin, zero, cos) + if axis == "Z": + R_flat = (cos, -sin, zero, sin, cos, zero, zero, zero, one) + + return torch.stack(R_flat, -1).reshape(angle.shape + (3, 3)) + + +def euler_angles_to_matrix(euler_angles, convention: str): + """ + Convert rotations given as Euler angles in radians to rotation matrices. + + Args: + euler_angles: Euler angles in radians as tensor of shape (..., 3). + convention: Convention string of three uppercase letters from + {"X", "Y", and "Z"}. + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + if euler_angles.dim() == 0 or euler_angles.shape[-1] != 3: + raise ValueError("Invalid input euler angles.") + if len(convention) != 3: + raise ValueError("Convention must have 3 letters.") + if convention[1] in (convention[0], convention[2]): + raise ValueError(f"Invalid convention {convention}.") + for letter in convention: + if letter not in ("X", "Y", "Z"): + raise ValueError(f"Invalid letter {letter} in convention string.") + matrices = map(_axis_angle_rotation, convention, torch.unbind(euler_angles, -1)) + return functools.reduce(torch.matmul, matrices) + + +def _angle_from_tan( + axis: str, other_axis: str, data, horizontal: bool, tait_bryan: bool +): + """ + Extract the first or third Euler angle from the two members of + the matrix which are positive constant times its sine and cosine. + + Args: + axis: Axis label "X" or "Y or "Z" for the angle we are finding. + other_axis: Axis label "X" or "Y or "Z" for the middle axis in the + convention. + data: Rotation matrices as tensor of shape (..., 3, 3). + horizontal: Whether we are looking for the angle for the third axis, + which means the relevant entries are in the same row of the + rotation matrix. If not, they are in the same column. + tait_bryan: Whether the first and third axes in the convention differ. + + Returns: + Euler Angles in radians for each matrix in data as a tensor + of shape (...). + """ + + i1, i2 = {"X": (2, 1), "Y": (0, 2), "Z": (1, 0)}[axis] + if horizontal: + i2, i1 = i1, i2 + even = (axis + other_axis) in ["XY", "YZ", "ZX"] + if horizontal == even: + return torch.atan2(data[..., i1], data[..., i2]) + if tait_bryan: + return torch.atan2(-data[..., i2], data[..., i1]) + return torch.atan2(data[..., i2], -data[..., i1]) + + +def _index_from_letter(letter: str): + if letter == "X": + return 0 + if letter == "Y": + return 1 + if letter == "Z": + return 2 + + +def matrix_to_euler_angles(matrix, convention: str): + """ + Convert rotations given as rotation matrices to Euler angles in radians. + + Args: + matrix: Rotation matrices as tensor of shape (..., 3, 3). + convention: Convention string of three uppercase letters. + + Returns: + Euler angles in radians as tensor of shape (..., 3). + """ + if len(convention) != 3: + raise ValueError("Convention must have 3 letters.") + if convention[1] in (convention[0], convention[2]): + raise ValueError(f"Invalid convention {convention}.") + for letter in convention: + if letter not in ("X", "Y", "Z"): + raise ValueError(f"Invalid letter {letter} in convention string.") + if matrix.size(-1) != 3 or matrix.size(-2) != 3: + raise ValueError(f"Invalid rotation matrix shape f{matrix.shape}.") + i0 = _index_from_letter(convention[0]) + i2 = _index_from_letter(convention[2]) + tait_bryan = i0 != i2 + if tait_bryan: + central_angle = torch.asin( + matrix[..., i0, i2] * (-1.0 if i0 - i2 in [-1, 2] else 1.0) + ) + else: + central_angle = torch.acos(matrix[..., i0, i0]) + + o = ( + _angle_from_tan( + convention[0], convention[1], matrix[..., i2], False, tait_bryan + ), + central_angle, + _angle_from_tan( + convention[2], convention[1], matrix[..., i0, :], True, tait_bryan + ), + ) + return torch.stack(o, -1) + + +def random_quaternions( + n: int, dtype: Optional[torch.dtype] = None, device=None, requires_grad=False +): + """ + Generate random quaternions representing rotations, + i.e. versors with nonnegative real part. + + Args: + n: Number of quaternions in a batch to return. + dtype: Type to return. + device: Desired device of returned tensor. Default: + uses the current device for the default tensor type. + requires_grad: Whether the resulting tensor should have the gradient + flag set. + + Returns: + Quaternions as tensor of shape (N, 4). + """ + o = torch.randn((n, 4), dtype=dtype, device=device, requires_grad=requires_grad) + s = (o * o).sum(1) + o = o / _copysign(torch.sqrt(s), o[:, 0])[:, None] + return o + + +def random_rotations( + n: int, dtype: Optional[torch.dtype] = None, device=None, requires_grad=False +): + """ + Generate random rotations as 3x3 rotation matrices. + + Args: + n: Number of rotation matrices in a batch to return. + dtype: Type to return. + device: Device of returned tensor. Default: if None, + uses the current device for the default tensor type. + requires_grad: Whether the resulting tensor should have the gradient + flag set. + + Returns: + Rotation matrices as tensor of shape (n, 3, 3). + """ + quaternions = random_quaternions( + n, dtype=dtype, device=device, requires_grad=requires_grad + ) + return quaternion_to_matrix(quaternions) + + +def random_rotation( + dtype: Optional[torch.dtype] = None, device=None, requires_grad=False +): + """ + Generate a single random 3x3 rotation matrix. + + Args: + dtype: Type to return + device: Device of returned tensor. Default: if None, + uses the current device for the default tensor type + requires_grad: Whether the resulting tensor should have the gradient + flag set + + Returns: + Rotation matrix as tensor of shape (3, 3). + """ + return random_rotations(1, dtype, device, requires_grad)[0] + + +def standardize_quaternion(quaternions): + """ + Convert a unit quaternion to a standard form: one in which the real + part is non negative. + + Args: + quaternions: Quaternions with real part first, + as tensor of shape (..., 4). + + Returns: + Standardized quaternions as tensor of shape (..., 4). + """ + return torch.where(quaternions[..., 0:1] < 0, -quaternions, quaternions) + + +def quaternion_raw_multiply(a, b): + """ + Multiply two quaternions. + Usual torch rules for broadcasting apply. + + Args: + a: Quaternions as tensor of shape (..., 4), real part first. + b: Quaternions as tensor of shape (..., 4), real part first. + + Returns: + The product of a and b, a tensor of quaternions shape (..., 4). + """ + aw, ax, ay, az = torch.unbind(a, -1) + bw, bx, by, bz = torch.unbind(b, -1) + ow = aw * bw - ax * bx - ay * by - az * bz + ox = aw * bx + ax * bw + ay * bz - az * by + oy = aw * by - ax * bz + ay * bw + az * bx + oz = aw * bz + ax * by - ay * bx + az * bw + return torch.stack((ow, ox, oy, oz), -1) + + +def quaternion_multiply(a, b): + """ + Multiply two quaternions representing rotations, returning the quaternion + representing their composition, i.e. the versor with nonnegative real part. + Usual torch rules for broadcasting apply. + + Args: + a: Quaternions as tensor of shape (..., 4), real part first. + b: Quaternions as tensor of shape (..., 4), real part first. + + Returns: + The product of a and b, a tensor of quaternions of shape (..., 4). + """ + ab = quaternion_raw_multiply(a, b) + return standardize_quaternion(ab) + + +def quaternion_invert(quaternion): + """ + Given a quaternion representing rotation, get the quaternion representing + its inverse. + + Args: + quaternion: Quaternions as tensor of shape (..., 4), with real part + first, which must be versors (unit quaternions). + + Returns: + The inverse, a tensor of quaternions of shape (..., 4). + """ + + return quaternion * quaternion.new_tensor([1, -1, -1, -1]) + + +def quaternion_apply(quaternion, point): + """ + Apply the rotation given by a quaternion to a 3D point. + Usual torch rules for broadcasting apply. + + Args: + quaternion: Tensor of quaternions, real part first, of shape (..., 4). + point: Tensor of 3D points of shape (..., 3). + + Returns: + Tensor of rotated points of shape (..., 3). + """ + if point.size(-1) != 3: + raise ValueError(f"Points are not in 3D, f{point.shape}.") + real_parts = point.new_zeros(point.shape[:-1] + (1,)) + point_as_quaternion = torch.cat((real_parts, point), -1) + out = quaternion_raw_multiply( + quaternion_raw_multiply(quaternion, point_as_quaternion), + quaternion_invert(quaternion), + ) + return out[..., 1:] + + +def axis_angle_to_matrix(axis_angle): + """ + Convert rotations given as axis/angle to rotation matrices. + + Args: + axis_angle: Rotations given as a vector in axis angle form, + as a tensor of shape (..., 3), where the magnitude is + the angle turned anticlockwise in radians around the + vector's direction. + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + return quaternion_to_matrix(axis_angle_to_quaternion(axis_angle)) + + +def matrix_to_axis_angle(matrix): + """ + Convert rotations given as rotation matrices to axis/angle. + + Args: + matrix: Rotation matrices as tensor of shape (..., 3, 3). + + Returns: + Rotations given as a vector in axis angle form, as a tensor + of shape (..., 3), where the magnitude is the angle + turned anticlockwise in radians around the vector's + direction. + """ + return quaternion_to_axis_angle(matrix_to_quaternion(matrix)) + + +def axis_angle_to_quaternion(axis_angle): + """ + Convert rotations given as axis/angle to quaternions. + + Args: + axis_angle: Rotations given as a vector in axis angle form, + as a tensor of shape (..., 3), where the magnitude is + the angle turned anticlockwise in radians around the + vector's direction. + + Returns: + quaternions with real part first, as tensor of shape (..., 4). + """ + angles = torch.norm(axis_angle, p=2, dim=-1, keepdim=True) + half_angles = 0.5 * angles + eps = 1e-6 + small_angles = angles.abs() < eps + sin_half_angles_over_angles = torch.empty_like(angles) + sin_half_angles_over_angles[~small_angles] = ( + torch.sin(half_angles[~small_angles]) / angles[~small_angles] + ) + # for x small, sin(x/2) is about x/2 - (x/2)^3/6 + # so sin(x/2)/x is about 1/2 - (x*x)/48 + sin_half_angles_over_angles[small_angles] = ( + 0.5 - (angles[small_angles] * angles[small_angles]) / 48 + ) + quaternions = torch.cat( + [torch.cos(half_angles), axis_angle * sin_half_angles_over_angles], dim=-1 + ) + return quaternions + + +def quaternion_to_axis_angle(quaternions): + """ + Convert rotations given as quaternions to axis/angle. + + Args: + quaternions: quaternions with real part first, + as tensor of shape (..., 4). + + Returns: + Rotations given as a vector in axis angle form, as a tensor + of shape (..., 3), where the magnitude is the angle + turned anticlockwise in radians around the vector's + direction. + """ + norms = torch.norm(quaternions[..., 1:], p=2, dim=-1, keepdim=True) + half_angles = torch.atan2(norms, quaternions[..., :1]) + angles = 2 * half_angles + eps = 1e-6 + small_angles = angles.abs() < eps + sin_half_angles_over_angles = torch.empty_like(angles) + sin_half_angles_over_angles[~small_angles] = ( + torch.sin(half_angles[~small_angles]) / angles[~small_angles] + ) + # for x small, sin(x/2) is about x/2 - (x/2)^3/6 + # so sin(x/2)/x is about 1/2 - (x*x)/48 + sin_half_angles_over_angles[small_angles] = ( + 0.5 - (angles[small_angles] * angles[small_angles]) / 48 + ) + return quaternions[..., 1:] / sin_half_angles_over_angles + + +def rotation_6d_to_matrix(d6: torch.Tensor) -> torch.Tensor: + """ + Converts 6D rotation representation by Zhou et al. [1] to rotation matrix + using Gram--Schmidt orthogonalisation per Section B of [1]. + Args: + d6: 6D rotation representation, of size (*, 6) + + Returns: + batch of rotation matrices of size (*, 3, 3) + + [1] Zhou, Y., Barnes, C., Lu, J., Yang, J., & Li, H. + On the Continuity of Rotation Representations in Neural Networks. + IEEE Conference on Computer Vision and Pattern Recognition, 2019. + Retrieved from http://arxiv.org/abs/1812.07035 + """ + + a1, a2 = d6[..., :3], d6[..., 3:] + b1 = F.normalize(a1, dim=-1) + b2 = a2 - (b1 * a2).sum(-1, keepdim=True) * b1 + b2 = F.normalize(b2, dim=-1) + b3 = torch.cross(b1, b2, dim=-1) + return torch.stack((b1, b2, b3), dim=-2) + + +def matrix_to_rotation_6d(matrix: torch.Tensor) -> torch.Tensor: + """ + Converts rotation matrices to 6D rotation representation by Zhou et al. [1] + by dropping the last row. Note that 6D representation is not unique. + Args: + matrix: batch of rotation matrices of size (*, 3, 3) + + Returns: + 6D rotation representation, of size (*, 6) + + [1] Zhou, Y., Barnes, C., Lu, J., Yang, J., & Li, H. + On the Continuity of Rotation Representations in Neural Networks. + IEEE Conference on Computer Vision and Pattern Recognition, 2019. + Retrieved from http://arxiv.org/abs/1812.07035 + """ + return matrix[..., :2, :].clone().reshape(*matrix.size()[:-2], 6) diff --git a/motiondiff_modules/mGPT/utils/joints.py b/motiondiff_modules/mGPT/utils/joints.py new file mode 100644 index 0000000..98199c6 --- /dev/null +++ b/motiondiff_modules/mGPT/utils/joints.py @@ -0,0 +1,444 @@ +mmm_joints = [ + "root", + "BP", + "BT", + "BLN", + "BUN", + "LS", + "LE", + "LW", + "RS", + "RE", + "RW", + "LH", + "LK", + "LA", + "LMrot", + "LF", + "RH", + "RK", + "RA", + "RMrot", + "RF", +] + +humanml3d_joints = [ + "root", + "RH", + "LH", + "BP", + "RK", + "LK", + "BT", + "RMrot", + "LMrot", + "BLN", + "RF", + "LF", + "BMN", + "RSI", + "LSI", + "BUN", + "RS", + "LS", + "RE", + "LE", + "RW", + "LW", +] + +smplx_joints = [ + "pelvis", + "left_hip", + "right_hip", + "spine1", + "left_knee", + "right_knee", + "spine2", + "left_ankle", + "right_ankle", + "spine3", + "left_foot", + "right_foot", + "neck", + "left_collar", + "right_collar", + "head", + "left_shoulder", + "right_shoulder", + "left_elbow", + "right_elbow", + "left_wrist", + "right_wrist", + "jaw", + "left_eye_smplhf", + "right_eye_smplhf", + "left_index1", + "left_index2", + "left_index3", + "left_middle1", + "left_middle2", + "left_middle3", + "left_pinky1", + "left_pinky2", + "left_pinky3", + "left_ring1", + "left_ring2", + "left_ring3", + "left_thumb1", + "left_thumb2", + "left_thumb3", + "right_index1", + "right_index2", + "right_index3", + "right_middle1", + "right_middle2", + "right_middle3", + "right_pinky1", + "right_pinky2", + "right_pinky3", + "right_ring1", + "right_ring2", + "right_ring3", + "right_thumb1", + "right_thumb2", + "right_thumb3", + "nose", + "right_eye", + "left_eye", + "right_ear", + "left_ear", + "left_big_toe", + "left_small_toe", + "left_heel", + "right_big_toe", + "right_small_toe", + "right_heel", + "left_thumb", + "left_index", + "left_middle", + "left_ring", + "left_pinky", + "right_thumb", + "right_index", + "right_middle", + "right_ring", + "right_pinky", + "right_eye_brow1", + "right_eye_brow2", + "right_eye_brow3", + "right_eye_brow4", + "right_eye_brow5", + "left_eye_brow5", + "left_eye_brow4", + "left_eye_brow3", + "left_eye_brow2", + "left_eye_brow1", + "nose1", + "nose2", + "nose3", + "nose4", + "right_nose_2", + "right_nose_1", + "nose_middle", + "left_nose_1", + "left_nose_2", + "right_eye1", + "right_eye2", + "right_eye3", + "right_eye4", + "right_eye5", + "right_eye6", + "left_eye4", + "left_eye3", + "left_eye2", + "left_eye1", + "left_eye6", + "left_eye5", + "right_mouth_1", + "right_mouth_2", + "right_mouth_3", + "mouth_top", + "left_mouth_3", + "left_mouth_2", + "left_mouth_1", + "left_mouth_5", # 59 in OpenPose output + "left_mouth_4", # 58 in OpenPose output + "mouth_bottom", + "right_mouth_4", + "right_mouth_5", + "right_lip_1", + "right_lip_2", + "lip_top", + "left_lip_2", + "left_lip_1", + "left_lip_3", + "lip_bottom", + "right_lip_3", + # Face contour + "right_contour_1", + "right_contour_2", + "right_contour_3", + "right_contour_4", + "right_contour_5", + "right_contour_6", + "right_contour_7", + "right_contour_8", + "contour_middle", + "left_contour_8", + "left_contour_7", + "left_contour_6", + "left_contour_5", + "left_contour_4", + "left_contour_3", + "left_contour_2", + "left_contour_1", +] + +smplxnh_joints = [ + "pelvis", + "left_hip", + "right_hip", + "spine1", + "left_knee", + "right_knee", + "spine2", + "left_ankle", + "right_ankle", + "spine3", + "left_foot", + "right_foot", + "neck", + "left_collar", + "right_collar", + "head", + "left_shoulder", + "right_shoulder", + "left_elbow", + "right_elbow", + "left_wrist", + "right_wrist", +] + +smplh_joints = [ + "pelvis", + "left_hip", + "right_hip", + "spine1", + "left_knee", + "right_knee", + "spine2", + "left_ankle", + "right_ankle", + "spine3", + "left_foot", + "right_foot", + "neck", + "left_collar", + "right_collar", + "head", + "left_shoulder", + "right_shoulder", + "left_elbow", + "right_elbow", + "left_wrist", + "right_wrist", + "left_index1", + "left_index2", + "left_index3", + "left_middle1", + "left_middle2", + "left_middle3", + "left_pinky1", + "left_pinky2", + "left_pinky3", + "left_ring1", + "left_ring2", + "left_ring3", + "left_thumb1", + "left_thumb2", + "left_thumb3", + "right_index1", + "right_index2", + "right_index3", + "right_middle1", + "right_middle2", + "right_middle3", + "right_pinky1", + "right_pinky2", + "right_pinky3", + "right_ring1", + "right_ring2", + "right_ring3", + "right_thumb1", + "right_thumb2", + "right_thumb3", + "nose", + "right_eye", + "left_eye", + "right_ear", + "left_ear", + "left_big_toe", + "left_small_toe", + "left_heel", + "right_big_toe", + "right_small_toe", + "right_heel", + "left_thumb", + "left_index", + "left_middle", + "left_ring", + "left_pinky", + "right_thumb", + "right_index", + "right_middle", + "right_ring", + "right_pinky", +] + +smplnh_joints = [ + "pelvis", + "left_hip", + "right_hip", + "spine1", + "left_knee", + "right_knee", + "spine2", + "left_ankle", + "right_ankle", + "spine3", + "left_foot", + "right_foot", + "neck", + "left_collar", + "right_collar", + "head", + "left_shoulder", + "right_shoulder", + "left_elbow", + "right_elbow", + "left_wrist", + "right_wrist", +] + +mmm2smplh_correspondence = { + "root": "pelvis", + "BP": "spine1", + "BT": "spine3", + "BLN": "neck", + "BUN": "head", + "LS": "left_shoulder", + "LE": "left_elbow", + "LW": "left_wrist", + "RS": "right_shoulder", + "RE": "right_elbow", + "RW": "right_wrist", + "LH": "left_hip", + "LK": "left_knee", + "LA": "left_ankle", + "LMrot": "left_heel", + "LF": "left_foot", + "RH": "right_hip", + "RK": "right_knee", + "RA": "right_ankle", + "RMrot": "right_heel", + "RF": "right_foot", +} + +smplh2mmm_correspondence = { + val: key + for key, val in mmm2smplh_correspondence.items() +} +smplh2mmm_indexes = [ + smplh_joints.index(mmm2smplh_correspondence[x]) for x in mmm_joints +] + +smplnh2smplh_correspondence = {key: key for key in smplnh_joints} +smplh2smplnh_correspondence = { + val: key + for key, val in smplnh2smplh_correspondence.items() +} + +smplh2smplnh_indexes = [ + smplh_joints.index(smplnh2smplh_correspondence[x]) for x in smplnh_joints +] + +mmm_kinematic_tree = [ + [0, 1, 2, 3, 4], # body + [3, 5, 6, 7], # right arm + [3, 8, 9, 10], # left arm + [0, 11, 12, 13, 14, 15], # right leg + [0, 16, 17, 18, 19, 20], +] # left leg + +humanml3d_kinematic_tree = [ + [0, 3, 6, 9, 12, 15], # body + [9, 14, 17, 19, 21], # right arm + [9, 13, 16, 18, 20], # left arm + [0, 2, 5, 8, 11], # right leg + [0, 1, 4, 7, 10], +] # left leg + +smplh_to_mmm_scaling_factor = 480 / 0.75 +mmm_to_smplh_scaling_factor = 0.75 / 480 + +mmm_joints_info = { + "root": + mmm_joints.index("root"), + "feet": [ + mmm_joints.index("LMrot"), + mmm_joints.index("RMrot"), + mmm_joints.index("LF"), + mmm_joints.index("RF"), + ], + "shoulders": [mmm_joints.index("LS"), + mmm_joints.index("RS")], + "hips": [mmm_joints.index("LH"), + mmm_joints.index("RH")], +} + +smplnh_joints_info = { + "root": + smplnh_joints.index("pelvis"), + "feet": [ + smplnh_joints.index("left_ankle"), + smplnh_joints.index("right_ankle"), + smplnh_joints.index("left_foot"), + smplnh_joints.index("right_foot"), + ], + "shoulders": [ + smplnh_joints.index("left_shoulder"), + smplnh_joints.index("right_shoulder"), + ], + "hips": + [smplnh_joints.index("left_hip"), + smplnh_joints.index("right_hip")], +} + +infos = {"mmm": mmm_joints_info, "smplnh": smplnh_joints_info} + +smplh_indexes = {"mmm": smplh2mmm_indexes, "smplnh": smplh2smplnh_indexes} + +root_joints = { + "mmm": mmm_joints_info["root"], + "mmmns": mmm_joints_info["root"], + "smplmmm": mmm_joints_info["root"], + "smplnh": smplnh_joints_info["root"], + "smplh": smplh_joints.index("pelvis"), +} + + +def get_root_idx(joinstype): + return root_joints[joinstype] + + +# def mmm2smpl(joints_mmm): +# mmm2smplnh_indexes = [] +# for x in smplnh_joints: +# if x in smplh2mmm_correspondence: +# mmm2smplnh_indexes.append(mmm_joints.index(smplh2mmm_correspondence[x])) + +# spine2 = 0.5*(joints[mmm_joints.index("spine1")] + joints[mmm_joints.index("spine3")]) + +# joints = joints_mmm[indexes] +# return joints diff --git a/motiondiff_modules/mGPT/utils/load_checkpoint.py b/motiondiff_modules/mGPT/utils/load_checkpoint.py new file mode 100644 index 0000000..1214958 --- /dev/null +++ b/motiondiff_modules/mGPT/utils/load_checkpoint.py @@ -0,0 +1,34 @@ +import torch + +def load_pretrained(cfg, model, logger, phase="train"): + logger.info(f"Loading pretrain model from {cfg.TRAIN.PRETRAINED}") + if phase == "train": + ckpt_path = cfg.TRAIN.PRETRAINED + elif phase == "test": + ckpt_path = cfg.TEST.CHECKPOINTS + + state_dict = torch.load(ckpt_path, map_location="cpu")["state_dict"] + model.load_state_dict(state_dict, strict=True) + return model + + +def load_pretrained_vae(cfg, model, logger): + state_dict = torch.load(cfg.TRAIN.PRETRAINED_VAE, + map_location="cpu")['state_dict'] + logger.info(f"Loading pretrain vae from {cfg.TRAIN.PRETRAINED_VAE}") + # Extract encoder/decoder + from collections import OrderedDict + vae_dict = OrderedDict() + for k, v in state_dict.items(): + if "motion_vae" in k: + name = k.replace("motion_vae.", "") + vae_dict[name] = v + elif "vae" in k: + name = k.replace("vae.", "") + vae_dict[name] = v + if hasattr(model, 'vae'): + model.vae.load_state_dict(vae_dict, strict=True) + else: + model.motion_vae.load_state_dict(vae_dict, strict=True) + + return model diff --git a/motiondiff_modules/mGPT/utils/logger.py b/motiondiff_modules/mGPT/utils/logger.py new file mode 100644 index 0000000..6e1cafe --- /dev/null +++ b/motiondiff_modules/mGPT/utils/logger.py @@ -0,0 +1,68 @@ +from pathlib import Path +import os +import time +import logging +from omegaconf import OmegaConf +from pytorch_lightning.utilities.rank_zero import rank_zero_only + +def create_logger(cfg, phase='train'): + # root dir set by cfg + root_output_dir = Path(cfg.FOLDER) + # set up logger + if not root_output_dir.exists(): + print('=> creating {}'.format(root_output_dir)) + root_output_dir.mkdir() + + cfg_name = cfg.NAME + model = cfg.model.target.split('.')[-2] + cfg_name = os.path.basename(cfg_name).split('.')[0] + + final_output_dir = root_output_dir / model / cfg_name + cfg.FOLDER_EXP = str(final_output_dir) + + time_str = time.strftime('%Y-%m-%d-%H-%M-%S') + + new_dir(cfg, phase, time_str, final_output_dir) + + head = '%(asctime)-15s %(message)s' + logger = config_logger(final_output_dir, time_str, phase, head) + if logger is None: + logger = logging.getLogger() + logger.setLevel(logging.CRITICAL) + logging.basicConfig(format=head) + return logger + + +@rank_zero_only +def config_logger(final_output_dir, time_str, phase, head): + log_file = '{}_{}_{}.log'.format('log', time_str, phase) + final_log_file = final_output_dir / log_file + logging.basicConfig(filename=str(final_log_file)) + logger = logging.getLogger() + logger.setLevel(logging.INFO) + console = logging.StreamHandler() + formatter = logging.Formatter(head) + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + file_handler = logging.FileHandler(final_log_file, 'w') + file_handler.setFormatter(logging.Formatter(head)) + file_handler.setLevel(logging.INFO) + logging.getLogger('').addHandler(file_handler) + return logger + + +@rank_zero_only +def new_dir(cfg, phase, time_str, final_output_dir): + # new experiment folder + cfg.TIME = str(time_str) + if os.path.exists(final_output_dir) and not os.path.exists(cfg.TRAIN.RESUME) and not cfg.DEBUG and phase not in ['test', 'demo']: + file_list = sorted(os.listdir(final_output_dir), reverse=True) + for item in file_list: + if item.endswith('.log'): + os.rename(str(final_output_dir), str(final_output_dir) + '_' + cfg.TIME) + break + final_output_dir.mkdir(parents=True, exist_ok=True) + # write config yaml + config_file = '{}_{}_{}.yaml'.format('config', time_str, phase) + final_config_file = final_output_dir / config_file + OmegaConf.save(config=cfg, f=final_config_file) diff --git a/motiondiff_modules/mGPT/utils/misc.py b/motiondiff_modules/mGPT/utils/misc.py new file mode 100644 index 0000000..4f2a68d --- /dev/null +++ b/motiondiff_modules/mGPT/utils/misc.py @@ -0,0 +1,29 @@ +import torch + + +def to_numpy(tensor): + if torch.is_tensor(tensor): + return tensor.cpu().numpy() + elif type(tensor).__module__ != 'numpy': + raise ValueError("Cannot convert {} to numpy array".format( + type(tensor))) + return tensor + + +def to_torch(ndarray): + if type(ndarray).__module__ == 'numpy': + return torch.from_numpy(ndarray) + elif not torch.is_tensor(ndarray): + raise ValueError("Cannot convert {} to torch tensor".format( + type(ndarray))) + return ndarray + + +def cleanexit(): + import sys + import os + try: + sys.exit(0) + except SystemExit: + os._exit(0) + diff --git a/motiondiff_modules/mGPT/utils/rotation_conversions.py b/motiondiff_modules/mGPT/utils/rotation_conversions.py new file mode 100644 index 0000000..770c3bf --- /dev/null +++ b/motiondiff_modules/mGPT/utils/rotation_conversions.py @@ -0,0 +1,551 @@ +# Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. +# Check PYTORCH3D_LICENCE before use + +import functools +from typing import Optional + +import torch +import torch.nn.functional as F + + +""" +The transformation matrices returned from the functions in this file assume +the points on which the transformation will be applied are column vectors. +i.e. the R matrix is structured as + + R = [ + [Rxx, Rxy, Rxz], + [Ryx, Ryy, Ryz], + [Rzx, Rzy, Rzz], + ] # (3, 3) + +This matrix can be applied to column vectors by post multiplication +by the points e.g. + + points = [[0], [1], [2]] # (3 x 1) xyz coordinates of a point + transformed_points = R * points + +To apply the same matrix to points which are row vectors, the R matrix +can be transposed and pre multiplied by the points: + +e.g. + points = [[0, 1, 2]] # (1 x 3) xyz coordinates of a point + transformed_points = points * R.transpose(1, 0) +""" + + +def quaternion_to_matrix(quaternions): + """ + Convert rotations given as quaternions to rotation matrices. + + Args: + quaternions: quaternions with real part first, + as tensor of shape (..., 4). + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + r, i, j, k = torch.unbind(quaternions, -1) + two_s = 2.0 / (quaternions * quaternions).sum(-1) + + o = torch.stack( + ( + 1 - two_s * (j * j + k * k), + two_s * (i * j - k * r), + two_s * (i * k + j * r), + two_s * (i * j + k * r), + 1 - two_s * (i * i + k * k), + two_s * (j * k - i * r), + two_s * (i * k - j * r), + two_s * (j * k + i * r), + 1 - two_s * (i * i + j * j), + ), + -1, + ) + return o.reshape(quaternions.shape[:-1] + (3, 3)) + + +def _copysign(a, b): + """ + Return a tensor where each element has the absolute value taken from the, + corresponding element of a, with sign taken from the corresponding + element of b. This is like the standard copysign floating-point operation, + but is not careful about negative 0 and NaN. + + Args: + a: source tensor. + b: tensor whose signs will be used, of the same shape as a. + + Returns: + Tensor of the same shape as a with the signs of b. + """ + signs_differ = (a < 0) != (b < 0) + return torch.where(signs_differ, -a, a) + + +def _sqrt_positive_part(x): + """ + Returns torch.sqrt(torch.max(0, x)) + but with a zero subgradient where x is 0. + """ + ret = torch.zeros_like(x) + positive_mask = x > 0 + ret[positive_mask] = torch.sqrt(x[positive_mask]) + return ret + + +def matrix_to_quaternion(matrix): + """ + Convert rotations given as rotation matrices to quaternions. + + Args: + matrix: Rotation matrices as tensor of shape (..., 3, 3). + + Returns: + quaternions with real part first, as tensor of shape (..., 4). + """ + if matrix.size(-1) != 3 or matrix.size(-2) != 3: + raise ValueError(f"Invalid rotation matrix shape f{matrix.shape}.") + m00 = matrix[..., 0, 0] + m11 = matrix[..., 1, 1] + m22 = matrix[..., 2, 2] + o0 = 0.5 * _sqrt_positive_part(1 + m00 + m11 + m22) + x = 0.5 * _sqrt_positive_part(1 + m00 - m11 - m22) + y = 0.5 * _sqrt_positive_part(1 - m00 + m11 - m22) + z = 0.5 * _sqrt_positive_part(1 - m00 - m11 + m22) + o1 = _copysign(x, matrix[..., 2, 1] - matrix[..., 1, 2]) + o2 = _copysign(y, matrix[..., 0, 2] - matrix[..., 2, 0]) + o3 = _copysign(z, matrix[..., 1, 0] - matrix[..., 0, 1]) + return torch.stack((o0, o1, o2, o3), -1) + + +def _axis_angle_rotation(axis: str, angle): + """ + Return the rotation matrices for one of the rotations about an axis + of which Euler angles describe, for each value of the angle given. + + Args: + axis: Axis label "X" or "Y or "Z". + angle: any shape tensor of Euler angles in radians + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + + cos = torch.cos(angle) + sin = torch.sin(angle) + one = torch.ones_like(angle) + zero = torch.zeros_like(angle) + + if axis == "X": + R_flat = (one, zero, zero, zero, cos, -sin, zero, sin, cos) + if axis == "Y": + R_flat = (cos, zero, sin, zero, one, zero, -sin, zero, cos) + if axis == "Z": + R_flat = (cos, -sin, zero, sin, cos, zero, zero, zero, one) + + return torch.stack(R_flat, -1).reshape(angle.shape + (3, 3)) + + +def euler_angles_to_matrix(euler_angles, convention: str): + """ + Convert rotations given as Euler angles in radians to rotation matrices. + + Args: + euler_angles: Euler angles in radians as tensor of shape (..., 3). + convention: Convention string of three uppercase letters from + {"X", "Y", and "Z"}. + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + if euler_angles.dim() == 0 or euler_angles.shape[-1] != 3: + raise ValueError("Invalid input euler angles.") + if len(convention) != 3: + raise ValueError("Convention must have 3 letters.") + if convention[1] in (convention[0], convention[2]): + raise ValueError(f"Invalid convention {convention}.") + for letter in convention: + if letter not in ("X", "Y", "Z"): + raise ValueError(f"Invalid letter {letter} in convention string.") + matrices = map(_axis_angle_rotation, convention, torch.unbind(euler_angles, -1)) + return functools.reduce(torch.matmul, matrices) + + +def _angle_from_tan( + axis: str, other_axis: str, data, horizontal: bool, tait_bryan: bool +): + """ + Extract the first or third Euler angle from the two members of + the matrix which are positive constant times its sine and cosine. + + Args: + axis: Axis label "X" or "Y or "Z" for the angle we are finding. + other_axis: Axis label "X" or "Y or "Z" for the middle axis in the + convention. + data: Rotation matrices as tensor of shape (..., 3, 3). + horizontal: Whether we are looking for the angle for the third axis, + which means the relevant entries are in the same row of the + rotation matrix. If not, they are in the same column. + tait_bryan: Whether the first and third axes in the convention differ. + + Returns: + Euler Angles in radians for each matrix in data as a tensor + of shape (...). + """ + + i1, i2 = {"X": (2, 1), "Y": (0, 2), "Z": (1, 0)}[axis] + if horizontal: + i2, i1 = i1, i2 + even = (axis + other_axis) in ["XY", "YZ", "ZX"] + if horizontal == even: + return torch.atan2(data[..., i1], data[..., i2]) + if tait_bryan: + return torch.atan2(-data[..., i2], data[..., i1]) + return torch.atan2(data[..., i2], -data[..., i1]) + + +def _index_from_letter(letter: str): + if letter == "X": + return 0 + if letter == "Y": + return 1 + if letter == "Z": + return 2 + + +def matrix_to_euler_angles(matrix, convention: str): + """ + Convert rotations given as rotation matrices to Euler angles in radians. + + Args: + matrix: Rotation matrices as tensor of shape (..., 3, 3). + convention: Convention string of three uppercase letters. + + Returns: + Euler angles in radians as tensor of shape (..., 3). + """ + if len(convention) != 3: + raise ValueError("Convention must have 3 letters.") + if convention[1] in (convention[0], convention[2]): + raise ValueError(f"Invalid convention {convention}.") + for letter in convention: + if letter not in ("X", "Y", "Z"): + raise ValueError(f"Invalid letter {letter} in convention string.") + if matrix.size(-1) != 3 or matrix.size(-2) != 3: + raise ValueError(f"Invalid rotation matrix shape f{matrix.shape}.") + i0 = _index_from_letter(convention[0]) + i2 = _index_from_letter(convention[2]) + tait_bryan = i0 != i2 + if tait_bryan: + central_angle = torch.asin( + matrix[..., i0, i2] * (-1.0 if i0 - i2 in [-1, 2] else 1.0) + ) + else: + central_angle = torch.acos(matrix[..., i0, i0]) + + o = ( + _angle_from_tan( + convention[0], convention[1], matrix[..., i2], False, tait_bryan + ), + central_angle, + _angle_from_tan( + convention[2], convention[1], matrix[..., i0, :], True, tait_bryan + ), + ) + return torch.stack(o, -1) + + +def random_quaternions( + n: int, dtype: Optional[torch.dtype] = None, device=None, requires_grad=False +): + """ + Generate random quaternions representing rotations, + i.e. versors with nonnegative real part. + + Args: + n: Number of quaternions in a batch to return. + dtype: Type to return. + device: Desired device of returned tensor. Default: + uses the current device for the default tensor type. + requires_grad: Whether the resulting tensor should have the gradient + flag set. + + Returns: + Quaternions as tensor of shape (N, 4). + """ + o = torch.randn((n, 4), dtype=dtype, device=device, requires_grad=requires_grad) + s = (o * o).sum(1) + o = o / _copysign(torch.sqrt(s), o[:, 0])[:, None] + return o + + +def random_rotations( + n: int, dtype: Optional[torch.dtype] = None, device=None, requires_grad=False +): + """ + Generate random rotations as 3x3 rotation matrices. + + Args: + n: Number of rotation matrices in a batch to return. + dtype: Type to return. + device: Device of returned tensor. Default: if None, + uses the current device for the default tensor type. + requires_grad: Whether the resulting tensor should have the gradient + flag set. + + Returns: + Rotation matrices as tensor of shape (n, 3, 3). + """ + quaternions = random_quaternions( + n, dtype=dtype, device=device, requires_grad=requires_grad + ) + return quaternion_to_matrix(quaternions) + + +def random_rotation( + dtype: Optional[torch.dtype] = None, device=None, requires_grad=False +): + """ + Generate a single random 3x3 rotation matrix. + + Args: + dtype: Type to return + device: Device of returned tensor. Default: if None, + uses the current device for the default tensor type + requires_grad: Whether the resulting tensor should have the gradient + flag set + + Returns: + Rotation matrix as tensor of shape (3, 3). + """ + return random_rotations(1, dtype, device, requires_grad)[0] + + +def standardize_quaternion(quaternions): + """ + Convert a unit quaternion to a standard form: one in which the real + part is non negative. + + Args: + quaternions: Quaternions with real part first, + as tensor of shape (..., 4). + + Returns: + Standardized quaternions as tensor of shape (..., 4). + """ + return torch.where(quaternions[..., 0:1] < 0, -quaternions, quaternions) + + +def quaternion_raw_multiply(a, b): + """ + Multiply two quaternions. + Usual torch rules for broadcasting apply. + + Args: + a: Quaternions as tensor of shape (..., 4), real part first. + b: Quaternions as tensor of shape (..., 4), real part first. + + Returns: + The product of a and b, a tensor of quaternions shape (..., 4). + """ + aw, ax, ay, az = torch.unbind(a, -1) + bw, bx, by, bz = torch.unbind(b, -1) + ow = aw * bw - ax * bx - ay * by - az * bz + ox = aw * bx + ax * bw + ay * bz - az * by + oy = aw * by - ax * bz + ay * bw + az * bx + oz = aw * bz + ax * by - ay * bx + az * bw + return torch.stack((ow, ox, oy, oz), -1) + + +def quaternion_multiply(a, b): + """ + Multiply two quaternions representing rotations, returning the quaternion + representing their composition, i.e. the versor with nonnegative real part. + Usual torch rules for broadcasting apply. + + Args: + a: Quaternions as tensor of shape (..., 4), real part first. + b: Quaternions as tensor of shape (..., 4), real part first. + + Returns: + The product of a and b, a tensor of quaternions of shape (..., 4). + """ + ab = quaternion_raw_multiply(a, b) + return standardize_quaternion(ab) + + +def quaternion_invert(quaternion): + """ + Given a quaternion representing rotation, get the quaternion representing + its inverse. + + Args: + quaternion: Quaternions as tensor of shape (..., 4), with real part + first, which must be versors (unit quaternions). + + Returns: + The inverse, a tensor of quaternions of shape (..., 4). + """ + + return quaternion * quaternion.new_tensor([1, -1, -1, -1]) + + +def quaternion_apply(quaternion, point): + """ + Apply the rotation given by a quaternion to a 3D point. + Usual torch rules for broadcasting apply. + + Args: + quaternion: Tensor of quaternions, real part first, of shape (..., 4). + point: Tensor of 3D points of shape (..., 3). + + Returns: + Tensor of rotated points of shape (..., 3). + """ + if point.size(-1) != 3: + raise ValueError(f"Points are not in 3D, f{point.shape}.") + real_parts = point.new_zeros(point.shape[:-1] + (1,)) + point_as_quaternion = torch.cat((real_parts, point), -1) + out = quaternion_raw_multiply( + quaternion_raw_multiply(quaternion, point_as_quaternion), + quaternion_invert(quaternion), + ) + return out[..., 1:] + + +def axis_angle_to_matrix(axis_angle): + """ + Convert rotations given as axis/angle to rotation matrices. + + Args: + axis_angle: Rotations given as a vector in axis angle form, + as a tensor of shape (..., 3), where the magnitude is + the angle turned anticlockwise in radians around the + vector's direction. + + Returns: + Rotation matrices as tensor of shape (..., 3, 3). + """ + return quaternion_to_matrix(axis_angle_to_quaternion(axis_angle)) + + +def matrix_to_axis_angle(matrix): + """ + Convert rotations given as rotation matrices to axis/angle. + + Args: + matrix: Rotation matrices as tensor of shape (..., 3, 3). + + Returns: + Rotations given as a vector in axis angle form, as a tensor + of shape (..., 3), where the magnitude is the angle + turned anticlockwise in radians around the vector's + direction. + """ + return quaternion_to_axis_angle(matrix_to_quaternion(matrix)) + + +def axis_angle_to_quaternion(axis_angle): + """ + Convert rotations given as axis/angle to quaternions. + + Args: + axis_angle: Rotations given as a vector in axis angle form, + as a tensor of shape (..., 3), where the magnitude is + the angle turned anticlockwise in radians around the + vector's direction. + + Returns: + quaternions with real part first, as tensor of shape (..., 4). + """ + angles = torch.norm(axis_angle, p=2, dim=-1, keepdim=True) + half_angles = 0.5 * angles + eps = 1e-6 + small_angles = angles.abs() < eps + sin_half_angles_over_angles = torch.empty_like(angles) + sin_half_angles_over_angles[~small_angles] = ( + torch.sin(half_angles[~small_angles]) / angles[~small_angles] + ) + # for x small, sin(x/2) is about x/2 - (x/2)^3/6 + # so sin(x/2)/x is about 1/2 - (x*x)/48 + sin_half_angles_over_angles[small_angles] = ( + 0.5 - (angles[small_angles] * angles[small_angles]) / 48 + ) + quaternions = torch.cat( + [torch.cos(half_angles), axis_angle * sin_half_angles_over_angles], dim=-1 + ) + return quaternions + + +def quaternion_to_axis_angle(quaternions): + """ + Convert rotations given as quaternions to axis/angle. + + Args: + quaternions: quaternions with real part first, + as tensor of shape (..., 4). + + Returns: + Rotations given as a vector in axis angle form, as a tensor + of shape (..., 3), where the magnitude is the angle + turned anticlockwise in radians around the vector's + direction. + """ + norms = torch.norm(quaternions[..., 1:], p=2, dim=-1, keepdim=True) + half_angles = torch.atan2(norms, quaternions[..., :1]) + angles = 2 * half_angles + eps = 1e-6 + small_angles = angles.abs() < eps + sin_half_angles_over_angles = torch.empty_like(angles) + sin_half_angles_over_angles[~small_angles] = ( + torch.sin(half_angles[~small_angles]) / angles[~small_angles] + ) + # for x small, sin(x/2) is about x/2 - (x/2)^3/6 + # so sin(x/2)/x is about 1/2 - (x*x)/48 + sin_half_angles_over_angles[small_angles] = ( + 0.5 - (angles[small_angles] * angles[small_angles]) / 48 + ) + return quaternions[..., 1:] / sin_half_angles_over_angles + + +def rotation_6d_to_matrix(d6: torch.Tensor) -> torch.Tensor: + """ + Converts 6D rotation representation by Zhou et al. [1] to rotation matrix + using Gram--Schmidt orthogonalisation per Section B of [1]. + Args: + d6: 6D rotation representation, of size (*, 6) + + Returns: + batch of rotation matrices of size (*, 3, 3) + + [1] Zhou, Y., Barnes, C., Lu, J., Yang, J., & Li, H. + On the Continuity of Rotation Representations in Neural Networks. + IEEE Conference on Computer Vision and Pattern Recognition, 2019. + Retrieved from http://arxiv.org/abs/1812.07035 + """ + + a1, a2 = d6[..., :3], d6[..., 3:] + b1 = F.normalize(a1, dim=-1) + b2 = a2 - (b1 * a2).sum(-1, keepdim=True) * b1 + b2 = F.normalize(b2, dim=-1) + b3 = torch.cross(b1, b2, dim=-1) + return torch.stack((b1, b2, b3), dim=-2) + + +def matrix_to_rotation_6d(matrix: torch.Tensor) -> torch.Tensor: + """ + Converts rotation matrices to 6D rotation representation by Zhou et al. [1] + by dropping the last row. Note that 6D representation is not unique. + Args: + matrix: batch of rotation matrices of size (*, 3, 3) + + Returns: + 6D rotation representation, of size (*, 6) + + [1] Zhou, Y., Barnes, C., Lu, J., Yang, J., & Li, H. + On the Continuity of Rotation Representations in Neural Networks. + IEEE Conference on Computer Vision and Pattern Recognition, 2019. + Retrieved from http://arxiv.org/abs/1812.07035 + """ + return matrix[..., :2, :].clone().reshape(*matrix.size()[:-2], 6) diff --git a/motiondiff_modules/mGPT/utils/sample_utils.py b/motiondiff_modules/mGPT/utils/sample_utils.py new file mode 100644 index 0000000..724b109 --- /dev/null +++ b/motiondiff_modules/mGPT/utils/sample_utils.py @@ -0,0 +1,18 @@ +import logging +from pathlib import Path +logger = logging.getLogger(__name__) + +def cfg_mean_nsamples_resolution(cfg): + if cfg.mean and cfg.number_of_samples > 1: + logger.error("All the samples will be the mean.. cfg.number_of_samples=1 will be forced.") + cfg.number_of_samples = 1 + + return cfg.number_of_samples == 1 + + +def get_path(sample_path: Path, is_amass: bool, gender: str, split: str, onesample: bool, mean: bool, fact: float): + extra_str = ("_mean" if mean else "") if onesample else "_multi" + fact_str = "" if fact == 1 else f"{fact}_" + gender_str = gender + "_" if is_amass else "" + path = sample_path / f"{fact_str}{gender_str}{split}{extra_str}" + return path diff --git a/motiondiff_modules/mGPT/utils/temos_utils.py b/motiondiff_modules/mGPT/utils/temos_utils.py new file mode 100644 index 0000000..888fd69 --- /dev/null +++ b/motiondiff_modules/mGPT/utils/temos_utils.py @@ -0,0 +1,133 @@ +from typing import Dict, List + +import numpy as np +import torch +from torch import Tensor + +import mGPT.utils.geometry_conver as geometry_conver + + +def lengths_to_mask(lengths: List[int], + device: torch.device, + max_len: int = None) -> Tensor: + lengths = torch.tensor(lengths, device=device) + max_len = max_len if max_len else max(lengths) + mask = torch.arange(max_len, device=device).expand( + len(lengths), max_len) < lengths.unsqueeze(1) + return mask + + +def detach_to_numpy(tensor): + return tensor.detach().cpu().numpy() + + +def remove_padding(tensors, lengths): + return [ + tensor[:tensor_length] + for tensor, tensor_length in zip(tensors, lengths) + ] + + +def nfeats_of(rottype): + if rottype in ["rotvec", "axisangle"]: + return 3 + elif rottype in ["rotquat", "quaternion"]: + return 4 + elif rottype in ["rot6d", "6drot", "rotation6d"]: + return 6 + elif rottype in ["rotmat"]: + return 9 + else: + return TypeError("This rotation type doesn't have features.") + + +def axis_angle_to(newtype, rotations): + if newtype in ["matrix"]: + rotations = geometry_conver.axis_angle_to_matrix(rotations) + return rotations + elif newtype in ["rotmat"]: + rotations = geometry_conver.axis_angle_to_matrix(rotations) + rotations = matrix_to("rotmat", rotations) + return rotations + elif newtype in ["rot6d", "6drot", "rotation6d"]: + rotations = geometry_conver.axis_angle_to_matrix(rotations) + rotations = matrix_to("rot6d", rotations) + return rotations + elif newtype in ["rotquat", "quaternion"]: + rotations = geometry_conver.axis_angle_to_quaternion(rotations) + return rotations + elif newtype in ["rotvec", "axisangle"]: + return rotations + else: + raise NotImplementedError + + +def matrix_to(newtype, rotations): + if newtype in ["matrix"]: + return rotations + if newtype in ["rotmat"]: + rotations = rotations.reshape((*rotations.shape[:-2], 9)) + return rotations + elif newtype in ["rot6d", "6drot", "rotation6d"]: + rotations = geometry_conver.matrix_to_rotation_6d(rotations) + return rotations + elif newtype in ["rotquat", "quaternion"]: + rotations = geometry_conver.matrix_to_quaternion(rotations) + return rotations + elif newtype in ["rotvec", "axisangle"]: + rotations = geometry_conver.matrix_to_axis_angle(rotations) + return rotations + else: + raise NotImplementedError + + +def to_matrix(oldtype, rotations): + if oldtype in ["matrix"]: + return rotations + if oldtype in ["rotmat"]: + rotations = rotations.reshape((*rotations.shape[:-2], 3, 3)) + return rotations + elif oldtype in ["rot6d", "6drot", "rotation6d"]: + rotations = geometry_conver.rotation_6d_to_matrix(rotations) + return rotations + elif oldtype in ["rotquat", "quaternion"]: + rotations = geometry_conver.quaternion_to_matrix(rotations) + return rotations + elif oldtype in ["rotvec", "axisangle"]: + rotations = geometry_conver.axis_angle_to_matrix(rotations) + return rotations + else: + raise NotImplementedError + + +# TODO: use a real subsampler.. +def subsample(num_frames, last_framerate, new_framerate): + step = int(last_framerate / new_framerate) + assert step >= 1 + frames = np.arange(0, num_frames, step) + return frames + + +# TODO: use a real upsampler.. +def upsample(motion, last_framerate, new_framerate): + step = int(new_framerate / last_framerate) + assert step >= 1 + + # Alpha blending => interpolation + alpha = np.linspace(0, 1, step + 1) + last = np.einsum("l,...->l...", 1 - alpha, motion[:-1]) + new = np.einsum("l,...->l...", alpha, motion[1:]) + + chuncks = (last + new)[:-1] + output = np.concatenate(chuncks.swapaxes(1, 0)) + # Don't forget the last one + output = np.concatenate((output, motion[[-1]])) + return output + + +if __name__ == "__main__": + motion = np.arange(105) + submotion = motion[subsample(len(motion), 100.0, 12.5)] + newmotion = upsample(submotion, 12.5, 100) + + print(newmotion) diff --git a/motiondiff_modules/mGPT/utils/tensors.py b/motiondiff_modules/mGPT/utils/tensors.py new file mode 100644 index 0000000..1661438 --- /dev/null +++ b/motiondiff_modules/mGPT/utils/tensors.py @@ -0,0 +1,74 @@ +import torch + + +def lengths_to_mask(lengths): + max_len = max(lengths) + mask = torch.arange(max_len, device=lengths.device).expand( + len(lengths), max_len) < lengths.unsqueeze(1) + return mask + + +def collate_tensors(batch): + dims = batch[0].dim() + max_size = [max([b.size(i) for b in batch]) for i in range(dims)] + size = (len(batch),) + tuple(max_size) + canvas = batch[0].new_zeros(size=size) + for i, b in enumerate(batch): + sub_tensor = canvas[i] + for d in range(dims): + sub_tensor = sub_tensor.narrow(d, 0, b.size(d)) + sub_tensor.add_(b) + return canvas + + +def collate(batch): + databatch = [b[0] for b in batch] + labelbatch = [b[1] for b in batch] + lenbatch = [len(b[0][0][0]) for b in batch] + + databatchTensor = collate_tensors(databatch) + labelbatchTensor = torch.as_tensor(labelbatch) + lenbatchTensor = torch.as_tensor(lenbatch) + + maskbatchTensor = lengths_to_mask(lenbatchTensor) + # x - [bs, njoints, nfeats, lengths] + # - nfeats, the representation of a joint + # y - [bs] + # mask - [bs, lengths] + # lengths - [bs] + batch = {"x": databatchTensor, "y": labelbatchTensor, + "mask": maskbatchTensor, 'lengths': lenbatchTensor} + return batch + + +# slow version with padding +def collate_data3d_slow(batch): + batchTensor = {} + for key in batch[0].keys(): + databatch = [b[key] for b in batch] + batchTensor[key] = collate_tensors(databatch) + batch = batchTensor + # theta - [bs, lengths, 85], theta shape (85,) + # - (np.array([1., 0., 0.]), pose(72), shape(10)), axis=0) + # kp_2d - [bs, lengths, njoints, nfeats], nfeats (x,y,weight) + # kp_3d - [bs, lengths, njoints, nfeats], nfeats (x,y,z) + # w_smpl - [bs, lengths] zeros + # w_3d - [bs, lengths] zeros + return batch + +def collate_data3d(batch): + batchTensor = {} + for key in batch[0].keys(): + databatch = [b[key] for b in batch] + if key == "paths": + batchTensor[key] = databatch + else: + batchTensor[key] = torch.stack(databatch,axis=0) + batch = batchTensor + # theta - [bs, lengths, 85], theta shape (85,) + # - (np.array([1., 0., 0.]), pose(72), shape(10)), axis=0) + # kp_2d - [bs, lengths, njoints, nfeats], nfeats (x,y,weight) + # kp_3d - [bs, lengths, njoints, nfeats], nfeats (x,y,z) + # w_smpl - [bs, lengths] zeros + # w_3d - [bs, lengths] zeros + return batch diff --git a/motiondiff_modules/mogen/__init__.py b/motiondiff_modules/mogen/__init__.py new file mode 100644 index 0000000..387db6c --- /dev/null +++ b/motiondiff_modules/mogen/__init__.py @@ -0,0 +1,56 @@ +import warnings + +import custom_mmpkg.custom_mmcv as mmcv +from packaging.version import parse + +from .version import __version__ + + +def digit_version(version_str: str, length: int = 4): + """Convert a version string into a tuple of integers. + This method is usually used for comparing two versions. For pre-release + versions: alpha < beta < rc. + Args: + version_str (str): The version string. + length (int): The maximum number of version levels. Default: 4. + Returns: + tuple[int]: The version info in digits (integers). + """ + version = parse(version_str) + assert version.release, f'failed to parse version {version_str}' + release = list(version.release) + release = release[:length] + if len(release) < length: + release = release + [0] * (length - len(release)) + if version.is_prerelease: + mapping = {'a': -3, 'b': -2, 'rc': -1} + val = -4 + # version.pre can be None + if version.pre: + if version.pre[0] not in mapping: + warnings.warn(f'unknown prerelease version {version.pre[0]}, ' + 'version checking may go wrong') + else: + val = mapping[version.pre[0]] + release.extend([val, version.pre[-1]]) + else: + release.extend([val, 0]) + + elif version.is_postrelease: + release.extend([1, version.post]) + else: + release.extend([0, 0]) + return tuple(release) + + +mmcv_minimum_version = '1.3.17' #Dirty hacking for custom_mmcv +mmcv_maximum_version = '1.9.0' +mmcv_version = digit_version(mmcv.__version__) + + +assert (mmcv_version >= digit_version(mmcv_minimum_version) + and 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__', 'digit_version'] \ No newline at end of file diff --git a/motiondiff_modules/mogen/apis/__init__.py b/motiondiff_modules/mogen/apis/__init__.py new file mode 100644 index 0000000..da67d82 --- /dev/null +++ b/motiondiff_modules/mogen/apis/__init__.py @@ -0,0 +1,13 @@ +from motiondiff_modules.mogen.apis import test, train +from motiondiff_modules.mogen.apis.test import ( + collect_results_cpu, + collect_results_gpu, + multi_gpu_test, + single_gpu_test, +) +from motiondiff_modules.mogen.apis.train import set_random_seed, train_model + +__all__ = [ + 'collect_results_cpu', 'collect_results_gpu', 'multi_gpu_test', + 'single_gpu_test', 'set_random_seed', 'train_model' +] \ No newline at end of file diff --git a/motiondiff_modules/mogen/apis/test.py b/motiondiff_modules/mogen/apis/test.py new file mode 100644 index 0000000..a4afa2d --- /dev/null +++ b/motiondiff_modules/mogen/apis/test.py @@ -0,0 +1,160 @@ +import os.path as osp +import pickle +import shutil +import tempfile +import time + +import custom_mmpkg.custom_mmcv as mmcv +import torch +import torch.distributed as dist +from custom_mmpkg.custom_mmcv.runner import get_dist_info + + +def single_gpu_test(model, data_loader): + """Test with single gpu.""" + model.eval() + results = [] + dataset = data_loader.dataset + prog_bar = mmcv.ProgressBar(len(dataset)) + for i, data in enumerate(data_loader): + with torch.no_grad(): + result = model(return_loss=False, **data) + + batch_size = len(result) + if isinstance(result, list): + results.extend(result) + else: + results.append(result) + + batch_size = data['motion'].size(0) + for _ in range(batch_size): + prog_bar.update() + return results + + +def multi_gpu_test(model, data_loader, tmpdir=None, gpu_collect=False): + """Test model with multiple gpus. + This method tests model with multiple gpus and collects the results + under two different modes: gpu and cpu modes. By setting 'gpu_collect=True' + it encodes results to gpu tensors and use gpu communication for results + collection. On cpu mode it saves the results on different gpus to 'tmpdir' + and collects them by the rank 0 worker. + Args: + model (nn.Module): Model to be tested. + data_loader (nn.Dataloader): Pytorch data loader. + tmpdir (str): Path of directory to save the temporary results from + different gpus under cpu mode. + gpu_collect (bool): Option to use either gpu or cpu to collect results. + Returns: + list: The prediction results. + """ + model.eval() + results = [] + dataset = data_loader.dataset + rank, world_size = get_dist_info() + if rank == 0: + # Check if tmpdir is valid for cpu_collect + if (not gpu_collect) and (tmpdir is not None and osp.exists(tmpdir)): + raise OSError((f'The tmpdir {tmpdir} already exists.', + ' Since tmpdir will be deleted after testing,', + ' please make sure you specify an empty one.')) + prog_bar = mmcv.ProgressBar(len(dataset)) + time.sleep(2) # This line can prevent deadlock problem in some cases. + for i, data in enumerate(data_loader): + with torch.no_grad(): + result = model(return_loss=False, **data) + if isinstance(result, list): + results.extend(result) + else: + results.append(result) + + if rank == 0: + batch_size = data['motion'].size(0) + for _ in range(batch_size * world_size): + prog_bar.update() + + # collect results from all ranks + if gpu_collect: + results = collect_results_gpu(results, len(dataset)) + else: + results = collect_results_cpu(results, len(dataset), tmpdir) + return results + + +def collect_results_cpu(result_part, size, tmpdir=None): + """Collect results in cpu.""" + rank, world_size = get_dist_info() + # create a tmp dir if it is not specified + if tmpdir is None: + MAX_LEN = 512 + # 32 is whitespace + dir_tensor = torch.full((MAX_LEN, ), + 32, + dtype=torch.uint8, + device='cuda') + if rank == 0: + mmcv.mkdir_or_exist('.dist_test') + tmpdir = tempfile.mkdtemp(dir='.dist_test') + tmpdir = torch.tensor( + bytearray(tmpdir.encode()), dtype=torch.uint8, device='cuda') + dir_tensor[:len(tmpdir)] = tmpdir + dist.broadcast(dir_tensor, 0) + tmpdir = dir_tensor.cpu().numpy().tobytes().decode().rstrip() + else: + mmcv.mkdir_or_exist(tmpdir) + # dump the part result to the dir + mmcv.dump(result_part, osp.join(tmpdir, f'part_{rank}.pkl')) + dist.barrier() + # collect all parts + if rank != 0: + return None + else: + # load results of all parts from tmp dir + part_list = [] + for i in range(world_size): + part_file = osp.join(tmpdir, f'part_{i}.pkl') + part_result = mmcv.load(part_file) + part_list.append(part_result) + # sort the results + ordered_results = [] + for res in zip(*part_list): + ordered_results.extend(list(res)) + # the dataloader may pad some samples + ordered_results = ordered_results[:size] + # remove tmp dir + shutil.rmtree(tmpdir) + return ordered_results + + +def collect_results_gpu(result_part, size): + """Collect results in gpu.""" + rank, world_size = get_dist_info() + # dump result part to tensor with pickle + part_tensor = torch.tensor( + bytearray(pickle.dumps(result_part)), dtype=torch.uint8, device='cuda') + # gather all result part tensor shape + shape_tensor = torch.tensor(part_tensor.shape, device='cuda') + shape_list = [shape_tensor.clone() for _ in range(world_size)] + dist.all_gather(shape_list, shape_tensor) + # padding result part tensor to max length + shape_max = torch.tensor(shape_list).max() + part_send = torch.zeros(shape_max, dtype=torch.uint8, device='cuda') + part_send[:shape_tensor[0]] = part_tensor + part_recv_list = [ + part_tensor.new_zeros(shape_max) for _ in range(world_size) + ] + # gather all result part + dist.all_gather(part_recv_list, part_send) + + if rank == 0: + part_list = [] + for recv, shape in zip(part_recv_list, shape_list): + part_result = pickle.loads(recv[:shape[0]].cpu().numpy().tobytes()) + part_list.append(part_result) + # sort the results + ordered_results = [] + for res in zip(*part_list): + ordered_results.extend(list(res)) + # the dataloader may pad some samples + ordered_results = ordered_results[:size] + return ordered_results \ No newline at end of file diff --git a/motiondiff_modules/mogen/apis/train.py b/motiondiff_modules/mogen/apis/train.py new file mode 100644 index 0000000..7be1cd9 --- /dev/null +++ b/motiondiff_modules/mogen/apis/train.py @@ -0,0 +1,165 @@ +import random +import warnings + +import numpy as np +import torch +from custom_mmpkg.custom_mmcv.parallel import MMDataParallel, MMDistributedDataParallel +from custom_mmpkg.custom_mmcv.runner import ( + DistSamplerSeedHook, + Fp16OptimizerHook, + OptimizerHook, + build_runner, +) + +from motiondiff_modules.mogen.core.distributed_wrapper import DistributedDataParallelWrapper +from motiondiff_modules.mogen.core.evaluation import DistEvalHook, EvalHook +from motiondiff_modules.mogen.core.optimizer import build_optimizers +from motiondiff_modules.mogen.datasets import build_dataloader, build_dataset +from motiondiff_modules.mogen.utils import get_root_logger + + +def set_random_seed(seed, deterministic=False): + """Set random seed. + Args: + seed (int): Seed to be used. + deterministic (bool): Whether to set the deterministic option for + CUDNN backend, i.e., set `torch.backends.cudnn.deterministic` + to True and `torch.backends.cudnn.benchmark` to False. + Default: False. + """ + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + torch.cuda.manual_seed_all(seed) + if deterministic: + torch.backends.cudnn.deterministic = True + torch.backends.cudnn.benchmark = False + + +def train_model(model, + dataset, + cfg, + distributed=False, + validate=False, + timestamp=None, + device='cuda', + meta=None): + """Main api for training model.""" + logger = get_root_logger(cfg.log_level) + + # prepare data loaders + dataset = dataset if isinstance(dataset, (list, tuple)) else [dataset] + + data_loaders = [ + build_dataloader( + ds, + cfg.data.samples_per_gpu, + cfg.data.workers_per_gpu, + # cfg.gpus will be ignored if distributed + num_gpus=len(cfg.gpu_ids), + dist=distributed, + round_up=True, + seed=cfg.seed) for ds in dataset + ] + + # determine whether use adversarial training precess or not + use_adverserial_train = cfg.get('use_adversarial_train', False) + + # put model on gpus + if distributed: + find_unused_parameters = cfg.get('find_unused_parameters', True) + # Sets the `find_unused_parameters` parameter in + # torch.nn.parallel.DistributedDataParallel + if use_adverserial_train: + # Use DistributedDataParallelWrapper for adversarial training + model = DistributedDataParallelWrapper( + model, + device_ids=[torch.cuda.current_device()], + broadcast_buffers=False, + find_unused_parameters=find_unused_parameters) + else: + model = MMDistributedDataParallel( + model.cuda(), + device_ids=[torch.cuda.current_device()], + broadcast_buffers=False, + find_unused_parameters=find_unused_parameters) + else: + if device == 'cuda': + model = MMDataParallel( + model.cuda(cfg.gpu_ids[0]), device_ids=cfg.gpu_ids) + elif device == 'cpu': + model = model.cpu() + else: + raise ValueError(F'unsupported device name {device}.') + + # build runner + optimizer = build_optimizers(model, cfg.optimizer) + + if cfg.get('runner') is None: + cfg.runner = { + 'type': 'EpochBasedRunner', + 'max_epochs': cfg.total_epochs + } + warnings.warn( + 'config is now expected to have a `runner` section, ' + 'please set `runner` in your config.', UserWarning) + + runner = build_runner( + cfg.runner, + default_args=dict( + model=model, + batch_processor=None, + optimizer=optimizer, + work_dir=cfg.work_dir, + logger=logger, + meta=meta)) + + # an ugly walkaround to make the .log and .log.json filenames the same + runner.timestamp = timestamp + + if use_adverserial_train: + # The optimizer step process is included in the train_step function + # of the model, so the runner should NOT include optimizer hook. + optimizer_config = None + else: + # fp16 setting + fp16_cfg = cfg.get('fp16', None) + if fp16_cfg is not None: + optimizer_config = Fp16OptimizerHook( + **cfg.optimizer_config, **fp16_cfg, distributed=distributed) + elif distributed and '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), + custom_hooks_config=cfg.get('custom_hooks', None)) + if distributed: + runner.register_hook(DistSamplerSeedHook()) + + # register eval hooks + if validate: + val_dataset = build_dataset(cfg.data.val, dict(test_mode=True)) + val_dataloader = build_dataloader( + val_dataset, + samples_per_gpu=cfg.data.samples_per_gpu, + workers_per_gpu=cfg.data.workers_per_gpu, + dist=distributed, + shuffle=False, + round_up=True) + eval_cfg = cfg.get('evaluation', {}) + eval_cfg['by_epoch'] = cfg.runner['type'] != 'IterBasedRunner' + eval_hook = DistEvalHook if distributed else EvalHook + runner.register_hook(eval_hook(val_dataloader, **eval_cfg)) + + if cfg.resume_from: + runner.resume(cfg.resume_from) + elif cfg.load_from: + runner.load_checkpoint(cfg.load_from) + runner.run(data_loaders, cfg.workflow) \ No newline at end of file diff --git a/motiondiff_modules/mogen/core/__init__.py b/motiondiff_modules/mogen/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/motiondiff_modules/mogen/core/distributed_wrapper.py b/motiondiff_modules/mogen/core/distributed_wrapper.py new file mode 100644 index 0000000..9d08caa --- /dev/null +++ b/motiondiff_modules/mogen/core/distributed_wrapper.py @@ -0,0 +1,136 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.nn as nn +from custom_mmpkg.custom_mmcv.parallel import MODULE_WRAPPERS, MMDistributedDataParallel +from custom_mmpkg.custom_mmcv.parallel.scatter_gather import scatter_kwargs +from torch.cuda._utils import _get_device_index + + +@MODULE_WRAPPERS.register_module() +class DistributedDataParallelWrapper(nn.Module): + """A DistributedDataParallel wrapper for models in 3D mesh estimation task. + + In 3D mesh estimation task, there is a need to wrap different modules in + the models with separate DistributedDataParallel. Otherwise, it will cause + errors for GAN training. + More specific, the GAN model, usually has two sub-modules: + generator and discriminator. If we wrap both of them in one + standard DistributedDataParallel, it will cause errors during training, + because when we update the parameters of the generator (or discriminator), + the parameters of the discriminator (or generator) is not updated, which is + not allowed for DistributedDataParallel. + So we design this wrapper to separately wrap DistributedDataParallel + for generator and discriminator. + In this wrapper, we perform two operations: + 1. Wrap the modules in the models with separate MMDistributedDataParallel. + Note that only modules with parameters will be wrapped. + 2. Do scatter operation for 'forward', 'train_step' and 'val_step'. + Note that the arguments of this wrapper is the same as those in + `torch.nn.parallel.distributed.DistributedDataParallel`. + Args: + module (nn.Module): Module that needs to be wrapped. + device_ids (list[int | `torch.device`]): Same as that in + `torch.nn.parallel.distributed.DistributedDataParallel`. + dim (int, optional): Same as that in the official scatter function in + pytorch. Defaults to 0. + broadcast_buffers (bool): Same as that in + `torch.nn.parallel.distributed.DistributedDataParallel`. + Defaults to False. + find_unused_parameters (bool, optional): Same as that in + `torch.nn.parallel.distributed.DistributedDataParallel`. + Traverse the autograd graph of all tensors contained in returned + value of the wrapped module’s forward function. Defaults to False. + kwargs (dict): Other arguments used in + `torch.nn.parallel.distributed.DistributedDataParallel`. + """ + + def __init__(self, + module, + device_ids, + dim=0, + broadcast_buffers=False, + find_unused_parameters=False, + **kwargs): + super().__init__() + assert len(device_ids) == 1, ( + 'Currently, DistributedDataParallelWrapper only supports one' + 'single CUDA device for each process.' + f'The length of device_ids must be 1, but got {len(device_ids)}.') + self.module = module + self.dim = dim + self.to_ddp( + device_ids=device_ids, + dim=dim, + broadcast_buffers=broadcast_buffers, + find_unused_parameters=find_unused_parameters, + **kwargs) + self.output_device = _get_device_index(device_ids[0], True) + + def to_ddp(self, device_ids, dim, broadcast_buffers, + find_unused_parameters, **kwargs): + """Wrap models with separate MMDistributedDataParallel. + + It only wraps the modules with parameters. + """ + for name, module in self.module._modules.items(): + if next(module.parameters(), None) is None: + module = module.cuda() + elif all(not p.requires_grad for p in module.parameters()): + module = module.cuda() + else: + module = MMDistributedDataParallel( + module.cuda(), + device_ids=device_ids, + dim=dim, + broadcast_buffers=broadcast_buffers, + find_unused_parameters=find_unused_parameters, + **kwargs) + self.module._modules[name] = module + + def scatter(self, inputs, kwargs, device_ids): + """Scatter function. + + Args: + inputs (Tensor): Input Tensor. + kwargs (dict): Args for + ``mmcv.parallel.scatter_gather.scatter_kwargs``. + device_ids (int): Device id. + """ + return scatter_kwargs(inputs, kwargs, device_ids, dim=self.dim) + + def forward(self, *inputs, **kwargs): + """Forward function. + + Args: + inputs (tuple): Input data. + kwargs (dict): Args for + ``mmcv.parallel.scatter_gather.scatter_kwargs``. + """ + inputs, kwargs = self.scatter(inputs, kwargs, + [torch.cuda.current_device()]) + return self.module(*inputs[0], **kwargs[0]) + + def train_step(self, *inputs, **kwargs): + """Train step function. + + Args: + inputs (Tensor): Input Tensor. + kwargs (dict): Args for + ``mmcv.parallel.scatter_gather.scatter_kwargs``. + """ + inputs, kwargs = self.scatter(inputs, kwargs, + [torch.cuda.current_device()]) + output = self.module.train_step(*inputs[0], **kwargs[0]) + return output + + def val_step(self, *inputs, **kwargs): + """Validation step function. + + Args: + inputs (tuple): Input data. + kwargs (dict): Args for ``scatter_kwargs``. + """ + inputs, kwargs = self.scatter(inputs, kwargs, + [torch.cuda.current_device()]) + output = self.module.val_step(*inputs[0], **kwargs[0]) + return output \ No newline at end of file diff --git a/motiondiff_modules/mogen/core/evaluation/__init__.py b/motiondiff_modules/mogen/core/evaluation/__init__.py new file mode 100644 index 0000000..d9ba07a --- /dev/null +++ b/motiondiff_modules/mogen/core/evaluation/__init__.py @@ -0,0 +1,4 @@ +from motiondiff_modules.mogen.core.evaluation.eval_hooks import DistEvalHook, EvalHook +from motiondiff_modules.mogen.core.evaluation.builder import build_evaluator + +__all__ = ["DistEvalHook", "EvalHook", "build_evaluator"] \ No newline at end of file diff --git a/motiondiff_modules/mogen/core/evaluation/builder.py b/motiondiff_modules/mogen/core/evaluation/builder.py new file mode 100644 index 0000000..92fb565 --- /dev/null +++ b/motiondiff_modules/mogen/core/evaluation/builder.py @@ -0,0 +1,29 @@ +import copy +import numpy as np +from custom_mmpkg.custom_mmcv.utils import Registry +from .evaluators.precision_evaluator import PrecisionEvaluator +from .evaluators.matching_score_evaluator import MatchingScoreEvaluator +from .evaluators.fid_evaluator import FIDEvaluator +from .evaluators.diversity_evaluator import DiversityEvaluator +from .evaluators.multimodality_evaluator import MultiModalityEvaluator + +EVALUATORS = Registry('evaluators') + +EVALUATORS.register_module(name='R Precision', module=PrecisionEvaluator) +EVALUATORS.register_module(name='Matching Score', module=MatchingScoreEvaluator) +EVALUATORS.register_module(name='FID', module=FIDEvaluator) +EVALUATORS.register_module(name='Diversity', module=DiversityEvaluator) +EVALUATORS.register_module(name='MultiModality', module=MultiModalityEvaluator) + + +def build_evaluator(metric, eval_cfg, data_len, eval_indexes): + cfg = copy.deepcopy(eval_cfg) + cfg.update(metric) + cfg.pop('metrics') + cfg['data_len'] = data_len + cfg['eval_indexes'] = eval_indexes + evaluator = EVALUATORS.build(cfg) + if evaluator.append_indexes is not None: + for i in range(eval_cfg['replication_times']): + eval_indexes[i] = np.concatenate((eval_indexes[i], evaluator.append_indexes[i]), axis=0) + return evaluator, eval_indexes diff --git a/motiondiff_modules/mogen/core/evaluation/eval_hooks.py b/motiondiff_modules/mogen/core/evaluation/eval_hooks.py new file mode 100644 index 0000000..38cb338 --- /dev/null +++ b/motiondiff_modules/mogen/core/evaluation/eval_hooks.py @@ -0,0 +1,138 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import tempfile +import warnings + +from custom_mmpkg.custom_mmcv.runner import DistEvalHook as BaseDistEvalHook +from custom_mmpkg.custom_mmcv.runner import EvalHook as BaseEvalHook + +mogen_GREATER_KEYS = [] +mogen_LESS_KEYS = [] + + +class EvalHook(BaseEvalHook): + + def __init__(self, + dataloader, + start=None, + interval=1, + by_epoch=True, + save_best=None, + rule=None, + test_fn=None, + greater_keys=mogen_GREATER_KEYS, + less_keys=mogen_LESS_KEYS, + **eval_kwargs): + if test_fn is None: + from motiondiff_modules.mogen.apis import single_gpu_test + test_fn = single_gpu_test + + # remove "gpu_collect" from eval_kwargs + if 'gpu_collect' in eval_kwargs: + warnings.warn( + '"gpu_collect" will be deprecated in EvalHook.' + 'Please remove it from the config.', DeprecationWarning) + _ = eval_kwargs.pop('gpu_collect') + + # update "save_best" according to "key_indicator" and remove the + # latter from eval_kwargs + if 'key_indicator' in eval_kwargs or isinstance(save_best, bool): + warnings.warn( + '"key_indicator" will be deprecated in EvalHook.' + 'Please use "save_best" to specify the metric key,' + 'e.g., save_best="pa-mpjpe".', DeprecationWarning) + + key_indicator = eval_kwargs.pop('key_indicator', None) + if save_best is True and key_indicator is None: + raise ValueError('key_indicator should not be None, when ' + 'save_best is set to True.') + save_best = key_indicator + + super().__init__(dataloader, start, interval, by_epoch, save_best, + rule, test_fn, greater_keys, less_keys, **eval_kwargs) + + def evaluate(self, runner, results): + + with tempfile.TemporaryDirectory() as tmp_dir: + eval_res = self.dataloader.dataset.evaluate( + results, + work_dir=tmp_dir, + logger=runner.logger, + **self.eval_kwargs) + + for name, val in eval_res.items(): + runner.log_buffer.output[name] = val + runner.log_buffer.ready = True + + if self.save_best is not None: + if self.key_indicator == 'auto': + self._init_rule(self.rule, list(eval_res.keys())[0]) + + return eval_res[self.key_indicator] + + return None + + +class DistEvalHook(BaseDistEvalHook): + + def __init__(self, + dataloader, + start=None, + interval=1, + by_epoch=True, + save_best=None, + rule=None, + test_fn=None, + greater_keys=mogen_GREATER_KEYS, + less_keys=mogen_LESS_KEYS, + broadcast_bn_buffer=True, + tmpdir=None, + gpu_collect=False, + **eval_kwargs): + + if test_fn is None: + from motiondiff_modules.mogen.apis import multi_gpu_test + test_fn = multi_gpu_test + + # update "save_best" according to "key_indicator" and remove the + # latter from eval_kwargs + if 'key_indicator' in eval_kwargs or isinstance(save_best, bool): + warnings.warn( + '"key_indicator" will be deprecated in EvalHook.' + 'Please use "save_best" to specify the metric key,' + 'e.g., save_best="pa-mpjpe".', DeprecationWarning) + + key_indicator = eval_kwargs.pop('key_indicator', None) + if save_best is True and key_indicator is None: + raise ValueError('key_indicator should not be None, when ' + 'save_best is set to True.') + save_best = key_indicator + + super().__init__(dataloader, start, interval, by_epoch, save_best, + rule, test_fn, greater_keys, less_keys, + broadcast_bn_buffer, tmpdir, gpu_collect, + **eval_kwargs) + + def evaluate(self, runner, results): + """Evaluate the results. + Args: + runner (:obj:`mmcv.Runner`): The underlined training runner. + results (list): Output results. + """ + with tempfile.TemporaryDirectory() as tmp_dir: + eval_res = self.dataloader.dataset.evaluate( + results, + work_dir=tmp_dir, + logger=runner.logger, + **self.eval_kwargs) + + for name, val in eval_res.items(): + runner.log_buffer.output[name] = val + runner.log_buffer.ready = True + + if self.save_best is not None: + if self.key_indicator == 'auto': + # infer from eval_results + self._init_rule(self.rule, list(eval_res.keys())[0]) + return eval_res[self.key_indicator] + + return None \ No newline at end of file diff --git a/motiondiff_modules/mogen/core/evaluation/evaluators/__init__.py b/motiondiff_modules/mogen/core/evaluation/evaluators/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/motiondiff_modules/mogen/core/evaluation/evaluators/base_evaluator.py b/motiondiff_modules/mogen/core/evaluation/evaluators/base_evaluator.py new file mode 100644 index 0000000..e63ed45 --- /dev/null +++ b/motiondiff_modules/mogen/core/evaluation/evaluators/base_evaluator.py @@ -0,0 +1,144 @@ +import torch +import numpy as np +from ..utils import get_metric_statistics + + +class BaseEvaluator(object): + + def __init__(self, + batch_size=None, + drop_last=False, + replication_times=1, + replication_reduction='statistics', + eval_begin_idx=None, + eval_end_idx=None): + self.batch_size = batch_size + self.drop_last = drop_last + self.replication_times = replication_times + self.replication_reduction = replication_reduction + assert replication_reduction in ['statistics', 'mean', 'concat'] + self.eval_begin_idx = eval_begin_idx + self.eval_end_idx = eval_end_idx + + def evaluate(self, results): + total_len = len(results) + partial_len = total_len // self.replication_times + all_metrics = [] + for replication_idx in range(self.replication_times): + partial_results = results[ + replication_idx * partial_len: (replication_idx + 1) * partial_len] + if self.batch_size is not None: + batch_metrics = [] + for batch_start in range(self.eval_begin_idx, self.eval_end_idx, self.batch_size): + batch_results = partial_results[batch_start: batch_start + self.batch_size] + if len(batch_results) < self.batch_size and self.drop_last: + continue + batch_metrics.append(self.single_evaluate(batch_results)) + all_metrics.append(self.concat_batch_metrics(batch_metrics)) + else: + batch_results = partial_results[self.eval_begin_idx: self.eval_end_idx] + all_metrics.append(self.single_evaluate(batch_results)) + all_metrics = np.stack(all_metrics, axis=0) + if self.replication_reduction == 'statistics': + values = get_metric_statistics(all_metrics, self.replication_times) + elif self.replication_reduction == 'mean': + values = np.mean(all_metrics, axis=0) + elif self.replication_reduction == 'concat': + values = all_metrics + return self.parse_values(values) + + def prepare_results(self, results): + text = [] + pred_motion = [] + pred_motion_length = [] + pred_motion_mask = [] + motion = [] + motion_length = [] + motion_mask = [] + token = [] + # count the maximum motion length + T = max([result['motion'].shape[0] for result in results]) + for result in results: + cur_motion = result['motion'] + if cur_motion.shape[0] < T: + padding_values = torch.zeros((T - cur_motion.shape[0], cur_motion.shape[1])) + padding_values = padding_values.type_as(pred_motion) + cur_motion = torch.cat([cur_motion, padding_values], dim=0) + motion.append(cur_motion) + cur_pred_motion = result['pred_motion'] + if cur_pred_motion.shape[0] < T: + padding_values = torch.zeros((T - cur_pred_motion.shape[0], cur_pred_motion.shape[1])) + padding_values = padding_values.type_as(cur_pred_motion) + cur_pred_motion = torch.cat([cur_pred_motion, padding_values], dim=0) + pred_motion.append(cur_pred_motion) + cur_motion_mask = result['motion_mask'] + if cur_motion_mask.shape[0] < T: + padding_values = torch.zeros((T - cur_motion_mask.shape[0])) + padding_values = padding_values.type_as(cur_motion_mask) + cur_motion_mask= torch.cat([cur_motion_mask, padding_values], dim=0) + motion_mask.append(cur_motion_mask) + cur_pred_motion_mask = result['pred_motion_mask'] + if cur_pred_motion_mask.shape[0] < T: + padding_values = torch.zeros((T - cur_pred_motion_mask.shape[0])) + padding_values = padding_values.type_as(cur_pred_motion_mask) + cur_pred_motion_mask= torch.cat([cur_pred_motion_mask, padding_values], dim=0) + pred_motion_mask.append(cur_pred_motion_mask) + motion_length.append(result['motion_length'].item()) + pred_motion_length.append(result['pred_motion_length'].item()) + if 'text' in result.keys(): + text.append(result['text']) + if 'token' in result.keys(): + token.append(result['token']) + + motion = torch.stack(motion, dim=0) + pred_motion = torch.stack(pred_motion, dim=0) + motion_mask = torch.stack(motion_mask, dim=0) + pred_motion_mask = torch.stack(pred_motion_mask, dim=0) + motion_length = torch.Tensor(motion_length).to(motion.device).long() + pred_motion_length = torch.Tensor(pred_motion_length).to(motion.device).long() + output = { + 'pred_motion': pred_motion, + 'pred_motion_mask': pred_motion_mask, + 'pred_motion_length': pred_motion_length, + 'motion': motion, + 'motion_mask': motion_mask, + 'motion_length': motion_length, + 'text': text, + 'token': token + } + return output + + def to_device(self, device): + for model in self.model_list: + model.to(device) + + def motion_encode(self, motion, motion_length, motion_mask, device): + N = motion.shape[0] + motion_emb = [] + batch_size = 32 + cur_idx = 0 + with torch.no_grad(): + while cur_idx < N: + cur_motion = motion[cur_idx: cur_idx + batch_size].to(device) + cur_motion_length = motion_length[cur_idx: cur_idx + batch_size].to(device) + cur_motion_mask = motion_mask[cur_idx: cur_idx + batch_size].to(device) + cur_motion_emb = self.motion_encoder(cur_motion, cur_motion_length, cur_motion_mask) + motion_emb.append(cur_motion_emb) + cur_idx += batch_size + motion_emb = torch.cat(motion_emb, dim=0) + return motion_emb + + def text_encode(self, text, token, device): + N = len(text) + text_emb = [] + batch_size = 32 + cur_idx = 0 + with torch.no_grad(): + while cur_idx < N: + cur_text = text[cur_idx: cur_idx + batch_size] + cur_token = token[cur_idx: cur_idx + batch_size] + cur_text_emb = self.text_encoder(cur_text, cur_token, device) + text_emb.append(cur_text_emb) + cur_idx += batch_size + text_emb = torch.cat(text_emb, dim=0) + return text_emb \ No newline at end of file diff --git a/motiondiff_modules/mogen/core/evaluation/evaluators/diversity_evaluator.py b/motiondiff_modules/mogen/core/evaluation/evaluators/diversity_evaluator.py new file mode 100644 index 0000000..3bce77e --- /dev/null +++ b/motiondiff_modules/mogen/core/evaluation/evaluators/diversity_evaluator.py @@ -0,0 +1,52 @@ +import numpy as np +import torch + +from ..get_model import get_motion_model +from .base_evaluator import BaseEvaluator +from ..utils import calculate_diversity + + +class DiversityEvaluator(BaseEvaluator): + + def __init__(self, + data_len=0, + motion_encoder_name=None, + motion_encoder_path=None, + num_samples=300, + batch_size=None, + drop_last=False, + replication_times=1, + replication_reduction='statistics', + **kwargs): + super().__init__( + replication_times=replication_times, + replication_reduction=replication_reduction, + batch_size=batch_size, + drop_last=drop_last, + eval_begin_idx=0, + eval_end_idx=data_len + ) + self.num_samples = num_samples + self.append_indexes = None + self.motion_encoder = get_motion_model(motion_encoder_name, motion_encoder_path) + self.model_list = [self.motion_encoder] + + def single_evaluate(self, results): + results = self.prepare_results(results) + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + motion = results['motion'] + pred_motion = results['pred_motion'] + pred_motion_length = results['pred_motion_length'] + pred_motion_mask = results['pred_motion_mask'] + self.motion_encoder.to(device) + self.motion_encoder.eval() + with torch.no_grad(): + pred_motion_emb = self.motion_encode(pred_motion, pred_motion_length, pred_motion_mask, device).cpu().detach().numpy() + diversity = calculate_diversity(pred_motion_emb, self.num_samples) + return diversity + + def parse_values(self, values): + metrics = {} + metrics['Diversity (mean)'] = values[0] + metrics['Diversity (conf)'] = values[1] + return metrics diff --git a/motiondiff_modules/mogen/core/evaluation/evaluators/fid_evaluator.py b/motiondiff_modules/mogen/core/evaluation/evaluators/fid_evaluator.py new file mode 100644 index 0000000..627910d --- /dev/null +++ b/motiondiff_modules/mogen/core/evaluation/evaluators/fid_evaluator.py @@ -0,0 +1,58 @@ +import numpy as np +import torch + +from ..get_model import get_motion_model +from .base_evaluator import BaseEvaluator +from ..utils import ( + calculate_activation_statistics, + calculate_frechet_distance) + + +class FIDEvaluator(BaseEvaluator): + + def __init__(self, + data_len=0, + motion_encoder_name=None, + motion_encoder_path=None, + batch_size=None, + drop_last=False, + replication_times=1, + replication_reduction='statistics', + **kwargs): + super().__init__( + replication_times=replication_times, + replication_reduction=replication_reduction, + batch_size=batch_size, + drop_last=drop_last, + eval_begin_idx=0, + eval_end_idx=data_len + ) + self.append_indexes = None + self.motion_encoder = get_motion_model(motion_encoder_name, motion_encoder_path) + self.model_list = [self.motion_encoder] + + def single_evaluate(self, results): + results = self.prepare_results(results) + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + pred_motion = results['pred_motion'] + + pred_motion_length = results['pred_motion_length'] + pred_motion_mask = results['pred_motion_mask'] + motion = results['motion'] + motion_length = results['motion_length'] + motion_mask = results['motion_mask'] + self.motion_encoder.to(device) + self.motion_encoder.eval() + with torch.no_grad(): + pred_motion_emb = self.motion_encode(pred_motion, pred_motion_length, pred_motion_mask, device).cpu().detach().numpy() + gt_motion_emb = self.motion_encode(motion, motion_length, motion_mask, device).cpu().detach().numpy() + gt_mu, gt_cov = calculate_activation_statistics(gt_motion_emb) + pred_mu, pred_cov = calculate_activation_statistics(pred_motion_emb) + fid = calculate_frechet_distance(gt_mu, gt_cov, pred_mu, pred_cov) + return fid + + def parse_values(self, values): + metrics = {} + metrics['FID (mean)'] = values[0] + metrics['FID (conf)'] = values[1] + return metrics diff --git a/motiondiff_modules/mogen/core/evaluation/evaluators/matching_score_evaluator.py b/motiondiff_modules/mogen/core/evaluation/evaluators/matching_score_evaluator.py new file mode 100644 index 0000000..a1d3441 --- /dev/null +++ b/motiondiff_modules/mogen/core/evaluation/evaluators/matching_score_evaluator.py @@ -0,0 +1,71 @@ +import numpy as np +import torch + +from ..get_model import get_motion_model, get_text_model +from .base_evaluator import BaseEvaluator +from ..utils import calculate_top_k, euclidean_distance_matrix + + +class MatchingScoreEvaluator(BaseEvaluator): + + def __init__(self, + data_len=0, + text_encoder_name=None, + text_encoder_path=None, + motion_encoder_name=None, + motion_encoder_path=None, + top_k=3, + batch_size=32, + drop_last=False, + replication_times=1, + replication_reduction='statistics', + **kwargs): + super().__init__( + replication_times=replication_times, + replication_reduction=replication_reduction, + batch_size=batch_size, + drop_last=drop_last, + eval_begin_idx=0, + eval_end_idx=data_len + ) + self.append_indexes = None + self.text_encoder = get_text_model(text_encoder_name, text_encoder_path) + self.motion_encoder = get_motion_model(motion_encoder_name, motion_encoder_path) + self.top_k = top_k + self.model_list = [self.text_encoder, self.motion_encoder] + + def single_evaluate(self, results): + results = self.prepare_results(results) + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + motion = results['motion'] + pred_motion = results['pred_motion'] + pred_motion_length = results['pred_motion_length'] + pred_motion_mask = results['pred_motion_mask'] + text = results['text'] + token = results['token'] + self.text_encoder.to(device) + self.motion_encoder.to(device) + self.text_encoder.eval() + self.motion_encoder.eval() + with torch.no_grad(): + word_emb = self.text_encode(text, token, device=device).cpu().detach().numpy() + motion_emb = self.motion_encode(pred_motion, pred_motion_length, pred_motion_mask, device).cpu().detach().numpy() + dist_mat = euclidean_distance_matrix(word_emb, motion_emb) + matching_score = dist_mat.trace() + all_size = word_emb.shape[0] + return matching_score, all_size + + def concat_batch_metrics(self, batch_metrics): + matching_score_sum = 0 + all_size = 0 + for batch_matching_score, batch_all_size in batch_metrics: + matching_score_sum += batch_matching_score + all_size += batch_all_size + matching_score = matching_score_sum / all_size + return matching_score + + def parse_values(self, values): + metrics = {} + metrics['Matching Score (mean)'] = values[0] + metrics['Matching Score (conf)'] = values[1] + return metrics diff --git a/motiondiff_modules/mogen/core/evaluation/evaluators/multimodality_evaluator.py b/motiondiff_modules/mogen/core/evaluation/evaluators/multimodality_evaluator.py new file mode 100644 index 0000000..16f0b18 --- /dev/null +++ b/motiondiff_modules/mogen/core/evaluation/evaluators/multimodality_evaluator.py @@ -0,0 +1,63 @@ +import numpy as np +import torch + +from ..get_model import get_motion_model +from .base_evaluator import BaseEvaluator +from ..utils import calculate_multimodality + + +class MultiModalityEvaluator(BaseEvaluator): + + def __init__(self, + data_len=0, + motion_encoder_name=None, + motion_encoder_path=None, + num_samples=100, + num_repeats=30, + num_picks=10, + batch_size=None, + drop_last=False, + replication_times=1, + replication_reduction='statistics', + **kwargs): + super().__init__( + replication_times=replication_times, + replication_reduction=replication_reduction, + batch_size=batch_size, + drop_last=drop_last, + eval_begin_idx=data_len, + eval_end_idx=data_len + num_samples * num_repeats + ) + self.num_samples = num_samples + self.num_repeats = num_repeats + self.num_picks = num_picks + self.append_indexes = [] + for i in range(replication_times): + append_indexes = [] + selected_indexs = np.random.choice(data_len, self.num_samples) + for index in selected_indexs: + append_indexes = append_indexes + [index] * self.num_repeats + self.append_indexes.append(np.array(append_indexes)) + self.motion_encoder = get_motion_model(motion_encoder_name, motion_encoder_path) + self.model_list = [self.motion_encoder] + + def single_evaluate(self, results): + results = self.prepare_results(results) + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + motion = results['motion'] + pred_motion = results['pred_motion'] + pred_motion_length = results['pred_motion_length'] + pred_motion_mask = results['pred_motion_mask'] + self.motion_encoder.to(device) + self.motion_encoder.eval() + with torch.no_grad(): + pred_motion_emb = self.motion_encode(pred_motion, pred_motion_length, pred_motion_mask, device).cpu().detach().numpy() + pred_motion_emb = pred_motion_emb.reshape((self.num_samples, self.num_repeats, -1)) + multimodality = calculate_multimodality(pred_motion_emb, self.num_picks) + return multimodality + + def parse_values(self, values): + metrics = {} + metrics['MultiModality (mean)'] = values[0] + metrics['MultiModality (conf)'] = values[1] + return metrics diff --git a/motiondiff_modules/mogen/core/evaluation/evaluators/precision_evaluator.py b/motiondiff_modules/mogen/core/evaluation/evaluators/precision_evaluator.py new file mode 100644 index 0000000..09063a7 --- /dev/null +++ b/motiondiff_modules/mogen/core/evaluation/evaluators/precision_evaluator.py @@ -0,0 +1,74 @@ +import numpy as np +import torch + +from ..get_model import get_motion_model, get_text_model +from .base_evaluator import BaseEvaluator +from ..utils import calculate_top_k, euclidean_distance_matrix + + +class PrecisionEvaluator(BaseEvaluator): + + def __init__(self, + data_len=0, + text_encoder_name=None, + text_encoder_path=None, + motion_encoder_name=None, + motion_encoder_path=None, + top_k=3, + batch_size=32, + drop_last=False, + replication_times=1, + replication_reduction='statistics', + **kwargs): + super().__init__( + replication_times=replication_times, + replication_reduction=replication_reduction, + batch_size=batch_size, + drop_last=drop_last, + eval_begin_idx=0, + eval_end_idx=data_len + ) + self.append_indexes = None + self.text_encoder = get_text_model(text_encoder_name, text_encoder_path) + self.motion_encoder = get_motion_model(motion_encoder_name, motion_encoder_path) + self.top_k = top_k + self.model_list = [self.text_encoder, self.motion_encoder] + + def single_evaluate(self, results): + results = self.prepare_results(results) + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + motion = results['motion'] + pred_motion = results['pred_motion'] + pred_motion_length = results['pred_motion_length'] + pred_motion_mask = results['pred_motion_mask'] + text = results['text'] + token = results['token'] + self.text_encoder.to(device) + self.motion_encoder.to(device) + self.text_encoder.eval() + self.motion_encoder.eval() + with torch.no_grad(): + word_emb = self.text_encode(text, token, device=device).cpu().detach().numpy() + motion_emb = self.motion_encode(pred_motion, pred_motion_length, pred_motion_mask, device).cpu().detach().numpy() + dist_mat = euclidean_distance_matrix(word_emb, motion_emb) + argsmax = np.argsort(dist_mat, axis=1) + top_k_mat = calculate_top_k(argsmax, top_k=self.top_k) + top_k_count = top_k_mat.sum(axis=0) + all_size = word_emb.shape[0] + return top_k_count, all_size + + def concat_batch_metrics(self, batch_metrics): + top_k_count = 0 + all_size = 0 + for batch_top_k_count, batch_all_size in batch_metrics: + top_k_count += batch_top_k_count + all_size += batch_all_size + R_precision = top_k_count / all_size + return R_precision + + def parse_values(self, values): + metrics = {} + for top_k in range(self.top_k): + metrics['R_precision Top %d (mean)' % (top_k + 1)] = values[0][top_k] + metrics['R_precision Top %d (conf)' % (top_k + 1)] = values[1][top_k] + return metrics diff --git a/motiondiff_modules/mogen/core/evaluation/get_model.py b/motiondiff_modules/mogen/core/evaluation/get_model.py new file mode 100644 index 0000000..503d9ab --- /dev/null +++ b/motiondiff_modules/mogen/core/evaluation/get_model.py @@ -0,0 +1,46 @@ +from motiondiff_modules.mogen.models import build_submodule + + +def get_motion_model(name, ckpt_path): + if name == 'kit_ml': + model = build_submodule(dict( + type='T2MMotionEncoder', + input_size=251, + movement_hidden_size=512, + movement_latent_size=512, + motion_hidden_size=1024, + motion_latent_size=512, + )) + else: + model = build_submodule(dict( + type='T2MMotionEncoder', + input_size=263, + movement_hidden_size=512, + movement_latent_size=512, + motion_hidden_size=1024, + motion_latent_size=512, + )) + model.load_pretrained(ckpt_path) + return model + +def get_text_model(name, ckpt_path): + if name == 'kit_ml': + model = build_submodule(dict( + type='T2MTextEncoder', + word_size=300, + pos_size=15, + hidden_size=512, + output_size=512, + max_text_len=20 + )) + else: + model = build_submodule(dict( + type='T2MTextEncoder', + word_size=300, + pos_size=15, + hidden_size=512, + output_size=512, + max_text_len=20 + )) + model.load_pretrained(ckpt_path) + return model diff --git a/motiondiff_modules/mogen/core/evaluation/utils.py b/motiondiff_modules/mogen/core/evaluation/utils.py new file mode 100644 index 0000000..e91d4ac --- /dev/null +++ b/motiondiff_modules/mogen/core/evaluation/utils.py @@ -0,0 +1,130 @@ +import numpy as np +from scipy import linalg + + +def get_metric_statistics(values, replication_times): + mean = np.mean(values, axis=0) + std = np.std(values, axis=0) + conf_interval = 1.96 * std / np.sqrt(replication_times) + return mean, conf_interval + + +# (X - X_train)*(X - X_train) = -2X*X_train + X*X + X_train*X_train +def euclidean_distance_matrix(matrix1, matrix2): + """ + Params: + -- matrix1: N1 x D + -- matrix2: N2 x D + Returns: + -- dist: N1 x N2 + dist[i, j] == distance(matrix1[i], matrix2[j]) + """ + assert matrix1.shape[1] == matrix2.shape[1] + d1 = -2 * np.dot(matrix1, matrix2.T) # shape (num_test, num_train) + d2 = np.sum(np.square(matrix1), axis=1, keepdims=True) # shape (num_test, 1) + d3 = np.sum(np.square(matrix2), axis=1) # shape (num_train, ) + dists = np.sqrt(d1 + d2 + d3) # broadcasting + return dists + + +def calculate_top_k(mat, top_k): + size = mat.shape[0] + gt_mat = np.expand_dims(np.arange(size), 1).repeat(size, 1) + bool_mat = (mat == gt_mat) + correct_vec = False + top_k_list = [] + for i in range(top_k): +# print(correct_vec, bool_mat[:, i]) + correct_vec = (correct_vec | bool_mat[:, i]) + # print(correct_vec) + top_k_list.append(correct_vec[:, None]) + top_k_mat = np.concatenate(top_k_list, axis=1) + return top_k_mat + + +def calculate_activation_statistics(activations): + """ + Params: + -- activation: num_samples x dim_feat + Returns: + -- mu: dim_feat + -- sigma: dim_feat x dim_feat + """ + mu = np.mean(activations, axis=0) + cov = np.cov(activations, rowvar=False) + return mu, cov + +def calculate_frechet_distance(mu1, sigma1, mu2, sigma2, eps=1e-6): + """Numpy implementation of the Frechet Distance. + The Frechet distance between two multivariate Gaussians X_1 ~ N(mu_1, C_1) + and X_2 ~ N(mu_2, C_2) is + d^2 = ||mu_1 - mu_2||^2 + Tr(C_1 + C_2 - 2*sqrt(C_1*C_2)). + Stable version by Dougal J. Sutherland. + Params: + -- mu1 : Numpy array containing the activations of a layer of the + inception net (like returned by the function 'get_predictions') + for generated samples. + -- mu2 : The sample mean over activations, precalculated on an + representative data set. + -- sigma1: The covariance matrix over activations for generated samples. + -- sigma2: The covariance matrix over activations, precalculated on an + representative data set. + Returns: + -- : The Frechet Distance. + """ + + mu1 = np.atleast_1d(mu1) + mu2 = np.atleast_1d(mu2) + + sigma1 = np.atleast_2d(sigma1) + sigma2 = np.atleast_2d(sigma2) + + assert mu1.shape == mu2.shape, \ + 'Training and test mean vectors have different lengths' + assert sigma1.shape == sigma2.shape, \ + 'Training and test covariances have different dimensions' + + diff = mu1 - mu2 + + # Product might be almost singular + covmean, _ = linalg.sqrtm(sigma1.dot(sigma2), disp=False) + if not np.isfinite(covmean).all(): + msg = ('fid calculation produces singular product; ' + 'adding %s to diagonal of cov estimates') % eps + print(msg) + offset = np.eye(sigma1.shape[0]) * eps + covmean = linalg.sqrtm((sigma1 + offset).dot(sigma2 + offset)) + + # Numerical error might give slight imaginary component + if np.iscomplexobj(covmean): + if not np.allclose(np.diagonal(covmean).imag, 0, atol=1e-3): + m = np.max(np.abs(covmean.imag)) + raise ValueError('Imaginary component {}'.format(m)) + covmean = covmean.real + + tr_covmean = np.trace(covmean) + + return (diff.dot(diff) + np.trace(sigma1) + + np.trace(sigma2) - 2 * tr_covmean) + + +def calculate_diversity(activation, diversity_times): + assert len(activation.shape) == 2 + assert activation.shape[0] > diversity_times + num_samples = activation.shape[0] + + first_indices = np.random.choice(num_samples, diversity_times, replace=False) + second_indices = np.random.choice(num_samples, diversity_times, replace=False) + dist = linalg.norm(activation[first_indices] - activation[second_indices], axis=1) + return dist.mean() + + +def calculate_multimodality(activation, multimodality_times): + assert len(activation.shape) == 3 + assert activation.shape[1] > multimodality_times + num_per_sent = activation.shape[1] + + first_dices = np.random.choice(num_per_sent, multimodality_times, replace=False) + second_dices = np.random.choice(num_per_sent, multimodality_times, replace=False) + dist = linalg.norm(activation[:, first_dices] - activation[:, second_dices], axis=2) + return dist.mean() diff --git a/motiondiff_modules/mogen/core/optimizer/__init__.py b/motiondiff_modules/mogen/core/optimizer/__init__.py new file mode 100644 index 0000000..193050b --- /dev/null +++ b/motiondiff_modules/mogen/core/optimizer/__init__.py @@ -0,0 +1,3 @@ +from .builder import OPTIMIZERS, build_optimizers + +__all__ = ['build_optimizers', 'OPTIMIZERS'] \ No newline at end of file diff --git a/motiondiff_modules/mogen/core/optimizer/builder.py b/motiondiff_modules/mogen/core/optimizer/builder.py new file mode 100644 index 0000000..b3705a1 --- /dev/null +++ b/motiondiff_modules/mogen/core/optimizer/builder.py @@ -0,0 +1,52 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from custom_mmpkg.custom_mmcv.runner import build_optimizer +from custom_mmpkg.custom_mmcv.utils import Registry + +OPTIMIZERS = Registry('optimizers') + + +def build_optimizers(model, cfgs): + """Build multiple optimizers from configs. If `cfgs` contains several dicts + for optimizers, then a dict for each constructed optimizers will be + returned. If `cfgs` only contains one optimizer config, the constructed + optimizer itself will be returned. For example, + + 1) Multiple optimizer configs: + + .. code-block:: python + + optimizer_cfg = dict( + model1=dict(type='SGD', lr=lr), + model2=dict(type='SGD', lr=lr)) + + The return dict is + ``dict('model1': torch.optim.Optimizer, 'model2': torch.optim.Optimizer)`` + + 2) Single optimizer config: + + .. code-block:: python + + optimizer_cfg = dict(type='SGD', lr=lr) + + The return is ``torch.optim.Optimizer``. + + Args: + model (:obj:`nn.Module`): The model with parameters to be optimized. + cfgs (dict): The config dict of the optimizer. + + Returns: + dict[:obj:`torch.optim.Optimizer`] | :obj:`torch.optim.Optimizer`: + The initialized optimizers. + """ + optimizers = {} + if hasattr(model, 'module'): + model = model.module + # determine whether 'cfgs' has several dicts for optimizers + if all(isinstance(v, dict) for v in cfgs.values()): + for key, cfg in cfgs.items(): + cfg_ = cfg.copy() + module = getattr(model, key) + optimizers[key] = build_optimizer(module, cfg_) + return optimizers + + return build_optimizer(model, cfgs) \ No newline at end of file diff --git a/motiondiff_modules/mogen/datasets/__init__.py b/motiondiff_modules/mogen/datasets/__init__.py new file mode 100644 index 0000000..403118c --- /dev/null +++ b/motiondiff_modules/mogen/datasets/__init__.py @@ -0,0 +1,11 @@ +from .base_dataset import BaseMotionDataset +from .text_motion_dataset import TextMotionDataset +from .builder import DATASETS, PIPELINES, build_dataloader, build_dataset +from .pipelines import Compose +from .samplers import DistributedSampler + + +__all__ = [ + 'BaseMotionDataset', 'TextMotionDataset', 'DATASETS', 'PIPELINES', 'build_dataloader', + 'build_dataset', 'Compose', 'DistributedSampler' +] \ No newline at end of file diff --git a/motiondiff_modules/mogen/datasets/base_dataset.py b/motiondiff_modules/mogen/datasets/base_dataset.py new file mode 100644 index 0000000..ef7cca6 --- /dev/null +++ b/motiondiff_modules/mogen/datasets/base_dataset.py @@ -0,0 +1,117 @@ +import os +import copy +from typing import Optional, Union + +import numpy as np +from torch.utils.data import Dataset + +from .pipelines import Compose +from .builder import DATASETS +from motiondiff_modules.mogen.core.evaluation import build_evaluator + + +@DATASETS.register_module() +class BaseMotionDataset(Dataset): + """Base motion dataset. + Args: + data_prefix (str): the prefix of data path. + pipeline (list): a list of dict, where each element represents + a operation defined in `mogen.datasets.pipelines`. + ann_file (str | None, optional): the annotation file. When ann_file is + str, the subclass is expected to read from the ann_file. When + ann_file is None, the subclass is expected to read according + to data_prefix. + test_mode (bool): in train mode or test mode. Default: None. + dataset_name (str | None, optional): the name of dataset. It is used + to identify the type of evaluation metric. Default: None. + """ + + def __init__(self, + data_prefix: str, + pipeline: list, + dataset_name: Optional[Union[str, None]] = None, + fixed_length: Optional[Union[int, None]] = None, + ann_file: Optional[Union[str, None]] = None, + motion_dir: Optional[Union[str, None]] = None, + eval_cfg: Optional[Union[dict, None]] = None, + test_mode: Optional[bool] = False): + super(BaseMotionDataset, self).__init__() + + self.data_prefix = data_prefix + self.pipeline = Compose(pipeline) + self.dataset_name = dataset_name + self.fixed_length = fixed_length + self.ann_file = os.path.join(data_prefix, 'datasets', dataset_name, ann_file) + self.motion_dir = os.path.join(data_prefix, 'datasets', dataset_name, motion_dir) + self.eval_cfg = copy.deepcopy(eval_cfg) + self.test_mode = test_mode + + self.load_annotations() + if self.test_mode: + self.prepare_evaluation() + + def load_anno(self, name): + motion_path = os.path.join(self.motion_dir, name + '.npy') + motion_data = np.load(motion_path) + return {'motion': motion_data} + + + def load_annotations(self): + """Load annotations from ``ann_file`` to ``data_infos``""" + self.data_infos = [] + for line in open(self.ann_file, 'r').readlines(): + line = line.strip() + self.data_infos.append(self.load_anno(line)) + + + def prepare_data(self, idx: int): + """"Prepare raw data for the f'{idx'}-th data.""" + results = copy.deepcopy(self.data_infos[idx]) + results['dataset_name'] = self.dataset_name + results['sample_idx'] = idx + return self.pipeline(results) + + def __len__(self): + """Return the length of current dataset.""" + if self.test_mode: + return len(self.eval_indexes) + elif self.fixed_length is not None: + return self.fixed_length + return len(self.data_infos) + + def __getitem__(self, idx: int): + """Prepare data for the ``idx``-th data. + As for video dataset, we can first parse raw data for each frame. Then + we combine annotations from all frames. This interface is used to + simplify the logic of video dataset and other special datasets. + """ + if self.test_mode: + idx = self.eval_indexes[idx] + elif self.fixed_length is not None: + idx = idx % len(self.data_infos) + return self.prepare_data(idx) + + def prepare_evaluation(self): + self.evaluators = [] + self.eval_indexes = [] + for _ in range(self.eval_cfg['replication_times']): + eval_indexes = np.arange(len(self.data_infos)) + if self.eval_cfg.get('shuffle_indexes', False): + np.random.shuffle(eval_indexes) + self.eval_indexes.append(eval_indexes) + for metric in self.eval_cfg['metrics']: + evaluator, self.eval_indexes = build_evaluator( + metric, self.eval_cfg, len(self.data_infos), self.eval_indexes) + self.evaluators.append(evaluator) + + self.eval_indexes = np.concatenate(self.eval_indexes) + + def evaluate(self, results, work_dir, logger=None): + metrics = {} + device = results[0]['motion'].device + for evaluator in self.evaluators: + evaluator.to_device(device) + metrics.update(evaluator.evaluate(results)) + if logger is not None: + logger.info(metrics) + return metrics diff --git a/motiondiff_modules/mogen/datasets/builder.py b/motiondiff_modules/mogen/datasets/builder.py new file mode 100644 index 0000000..66be732 --- /dev/null +++ b/motiondiff_modules/mogen/datasets/builder.py @@ -0,0 +1,113 @@ +import platform +import random +from functools import partial +from typing import Optional, Union + +import numpy as np +from custom_mmpkg.custom_mmcv.parallel import collate +from custom_mmpkg.custom_mmcv.runner import get_dist_info +from custom_mmpkg.custom_mmcv.utils import Registry, build_from_cfg +from torch.utils.data import DataLoader +from torch.utils.data.dataset import Dataset + +from .samplers import DistributedSampler + +if platform.system() != 'Windows': + # https://github.com/pytorch/pytorch/issues/973 + import resource + rlimit = resource.getrlimit(resource.RLIMIT_NOFILE) + base_soft_limit = rlimit[0] + hard_limit = rlimit[1] + soft_limit = min(max(4096, base_soft_limit), hard_limit) + resource.setrlimit(resource.RLIMIT_NOFILE, (soft_limit, hard_limit)) + +DATASETS = Registry('dataset') +PIPELINES = Registry('pipeline') + + +def build_dataset(cfg: Union[dict, list, tuple], + default_args: Optional[Union[dict, None]] = None): + """"Build dataset by the given config.""" + from .dataset_wrappers import ( + ConcatDataset, + RepeatDataset, + ) + if isinstance(cfg, (list, tuple)): + dataset = ConcatDataset([build_dataset(c, default_args) for c in cfg]) + elif cfg['type'] == 'RepeatDataset': + dataset = RepeatDataset( + build_dataset(cfg['dataset'], default_args), cfg['times']) + else: + dataset = build_from_cfg(cfg, DATASETS, default_args) + + return dataset + + +def build_dataloader(dataset: Dataset, + samples_per_gpu: int, + workers_per_gpu: int, + num_gpus: Optional[int] = 1, + dist: Optional[bool] = True, + shuffle: Optional[bool] = True, + round_up: Optional[bool] = True, + seed: Optional[Union[int, None]] = None, + persistent_workers: Optional[bool] = True, + **kwargs): + """Build PyTorch DataLoader. + In distributed training, each GPU/process has a dataloader. + In non-distributed training, there is only one dataloader for all GPUs. + Args: + dataset (:obj:`Dataset`): A PyTorch dataset. + samples_per_gpu (int): Number of training samples 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. + num_gpus (int, optional): Number of GPUs. Only used in non-distributed + training. + dist (bool, optional): Distributed training/test or not. Default: True. + shuffle (bool, optional): Whether to shuffle the data at every epoch. + Default: True. + round_up (bool, optional): Whether to round up the length of dataset by + adding extra samples to make it evenly divisible. Default: True. + kwargs: any keyword argument to be used to initialize DataLoader + Returns: + DataLoader: A PyTorch dataloader. + """ + rank, world_size = get_dist_info() + if dist: + sampler = DistributedSampler( + dataset, world_size, rank, shuffle=shuffle, round_up=round_up) + shuffle = False + batch_size = samples_per_gpu + num_workers = workers_per_gpu + else: + sampler = None + batch_size = num_gpus * samples_per_gpu + num_workers = num_gpus * workers_per_gpu + + init_fn = partial( + worker_init_fn, num_workers=num_workers, rank=rank, + seed=seed) if seed is not None else None + + data_loader = DataLoader( + dataset, + batch_size=batch_size, + sampler=sampler, + num_workers=num_workers, + collate_fn=partial(collate, samples_per_gpu=samples_per_gpu), + pin_memory=False, + shuffle=shuffle, + worker_init_fn=init_fn, + persistent_workers=persistent_workers, + **kwargs) + + return data_loader + + +def worker_init_fn(worker_id: int, num_workers: int, rank: int, seed: int): + """Init random seed for each worker.""" + # 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) \ No newline at end of file diff --git a/motiondiff_modules/mogen/datasets/dataset_wrappers.py b/motiondiff_modules/mogen/datasets/dataset_wrappers.py new file mode 100644 index 0000000..a86d092 --- /dev/null +++ b/motiondiff_modules/mogen/datasets/dataset_wrappers.py @@ -0,0 +1,42 @@ +from torch.utils.data.dataset import ConcatDataset as _ConcatDataset +from torch.utils.data.dataset import Dataset + +from .builder import DATASETS + + +@DATASETS.register_module() +class ConcatDataset(_ConcatDataset): + """A wrapper of concatenated dataset. + Same as :obj:`torch.utils.data.dataset.ConcatDataset`, but + add `get_cat_ids` function. + Args: + datasets (list[:obj:`Dataset`]): A list of datasets. + """ + + def __init__(self, datasets: list): + super(ConcatDataset, self).__init__(datasets) + + +@DATASETS.register_module() +class RepeatDataset(object): + """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 (:obj:`Dataset`): The dataset to be repeated. + times (int): Repeat times. + """ + + def __init__(self, dataset: Dataset, times: int): + self.dataset = dataset + self.times = times + + self._ori_len = len(self.dataset) + + def __getitem__(self, idx: int): + return self.dataset[idx % self._ori_len] + + def __len__(self): + return self.times * self._ori_len \ No newline at end of file diff --git a/motiondiff_modules/mogen/datasets/pipelines/__init__.py b/motiondiff_modules/mogen/datasets/pipelines/__init__.py new file mode 100644 index 0000000..2700cf7 --- /dev/null +++ b/motiondiff_modules/mogen/datasets/pipelines/__init__.py @@ -0,0 +1,18 @@ +from .compose import Compose +from .formatting import ( + to_tensor, + ToTensor, + Transpose, + Collect, + WrapFieldsToLists +) +from .transforms import ( + Crop, + RandomCrop, + Normalize +) + +__all__ = [ + 'Compose', 'to_tensor', 'Transpose', 'Collect', 'WrapFieldsToLists', 'ToTensor', + 'Crop', 'RandomCrop', 'Normalize' +] \ No newline at end of file diff --git a/motiondiff_modules/mogen/datasets/pipelines/compose.py b/motiondiff_modules/mogen/datasets/pipelines/compose.py new file mode 100644 index 0000000..42497a7 --- /dev/null +++ b/motiondiff_modules/mogen/datasets/pipelines/compose.py @@ -0,0 +1,42 @@ +from collections.abc import Sequence + +from custom_mmpkg.custom_mmcv.utils import build_from_cfg + +from ..builder import PIPELINES + + +@PIPELINES.register_module() +class Compose(object): + """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('transform must be callable or a dict, but got' + f' {type(transform)}') + + def __call__(self, 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 += f'\n {t}' + format_string += '\n)' + return format_string \ No newline at end of file diff --git a/motiondiff_modules/mogen/datasets/pipelines/formatting.py b/motiondiff_modules/mogen/datasets/pipelines/formatting.py new file mode 100644 index 0000000..86dc76d --- /dev/null +++ b/motiondiff_modules/mogen/datasets/pipelines/formatting.py @@ -0,0 +1,134 @@ +from collections.abc import Sequence + +import custom_mmpkg.custom_mmcv as mmcv +import numpy as np +import torch +from custom_mmpkg.custom_mmcv.parallel import DataContainer as DC +from PIL import Image + +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 + elif isinstance(data, np.ndarray): + return torch.from_numpy(data) + elif isinstance(data, Sequence) and not mmcv.is_str(data): + return torch.tensor(data) + elif isinstance(data, int): + return torch.LongTensor([data]) + elif isinstance(data, float): + return torch.FloatTensor([data]) + else: + raise TypeError( + f'Type {type(data)} cannot be converted to tensor.' + 'Supported types are: `numpy.ndarray`, `torch.Tensor`, ' + '`Sequence`, `int` and `float`') + + +@PIPELINES.register_module() +class ToTensor(object): + + def __init__(self, keys): + self.keys = keys + + def __call__(self, results): + for key in self.keys: + results[key] = to_tensor(results[key]) + return results + + def __repr__(self): + return self.__class__.__name__ + f'(keys={self.keys})' + + +@PIPELINES.register_module() +class Transpose(object): + + def __init__(self, keys, order): + self.keys = keys + self.order = order + + def __call__(self, results): + for key in self.keys: + results[key] = results[key].transpose(self.order) + return results + + def __repr__(self): + return self.__class__.__name__ + \ + f'(keys={self.keys}, order={self.order})' + + +@PIPELINES.register_module() +class Collect(object): + """Collect data from the loader relevant to the specific task. + + This is usually the last stage of the data loader pipeline. + + Args: + keys (Sequence[str]): Keys of results to be collected in ``data``. + meta_keys (Sequence[str], optional): Meta keys to be converted to + ``mmcv.DataContainer`` and collected in ``data[motion_metas]``. + Default: ``('filename', 'ori_filename', 'ori_shape', 'motion_shape', 'motion_mask')`` + + Returns: + dict: The result dict contains the following keys + - keys in``self.keys`` + - ``motion_metas`` if available + """ + + def __init__(self, + keys, + meta_keys=('filename', 'ori_filename', 'ori_shape', 'motion_shape', 'motion_mask')): + self.keys = keys + self.meta_keys = meta_keys + + def __call__(self, results): + data = {} + motion_meta = {} + for key in self.meta_keys: + if key in results: + motion_meta[key] = results[key] + data['motion_metas'] = DC(motion_meta, cpu_only=True) + for key in self.keys: + data[key] = results[key] + return data + + def __repr__(self): + return self.__class__.__name__ + \ + f'(keys={self.keys}, meta_keys={self.meta_keys})' + + +@PIPELINES.register_module() +class WrapFieldsToLists(object): + """Wrap fields of the data dictionary into lists for evaluation. + + This class can be used as a last step of a test or validation + pipeline for single image evaluation or inference. + + Example: + >>> test_pipeline = [ + >>> dict(type='LoadImageFromFile'), + >>> dict(type='Normalize', + mean=[123.675, 116.28, 103.53], + std=[58.395, 57.12, 57.375], + to_rgb=True), + >>> dict(type='ImageToTensor', keys=['img']), + >>> dict(type='Collect', keys=['img']), + >>> dict(type='WrapIntoLists') + >>> ] + """ + + def __call__(self, results): + # Wrap dict fields into lists + for key, val in results.items(): + results[key] = [val] + return results + + def __repr__(self): + return f'{self.__class__.__name__}()' \ No newline at end of file diff --git a/motiondiff_modules/mogen/datasets/pipelines/transforms.py b/motiondiff_modules/mogen/datasets/pipelines/transforms.py new file mode 100644 index 0000000..c4a1665 --- /dev/null +++ b/motiondiff_modules/mogen/datasets/pipelines/transforms.py @@ -0,0 +1,120 @@ +import math +import random + +import custom_mmpkg.custom_mmcv as mmcv +import numpy as np + +from ..builder import PIPELINES +import torch +from typing import Optional, Tuple, Union + + +@PIPELINES.register_module() +class Crop(object): + r"""Crop motion sequences. + + Args: + crop_size (int): The size of the cropped motion sequence. + """ + def __init__(self, + crop_size: Optional[Union[int, None]] = None): + self.crop_size = crop_size + assert self.crop_size is not None + + def __call__(self, results): + motion = results['motion'] + length = len(motion) + if length >= self.crop_size: + idx = random.randint(0, length - self.crop_size) + motion = motion[idx: idx + self.crop_size] + results['motion_length'] = self.crop_size + else: + padding_length = self.crop_size - length + D = motion.shape[1:] + padding_zeros = np.zeros((padding_length, *D), dtype=np.float32) + motion = np.concatenate([motion, padding_zeros], axis=0) + results['motion_length'] = length + assert len(motion) == self.crop_size + results['motion'] = motion + results['motion_shape'] = motion.shape + if length >= self.crop_size: + results['motion_mask'] = torch.ones(self.crop_size).numpy() + else: + results['motion_mask'] = torch.cat( + (torch.ones(length), torch.zeros(self.crop_size - length))).numpy() + return results + + + def __repr__(self): + repr_str = self.__class__.__name__ + f'(crop_size={self.crop_size})' + return repr_str + +@PIPELINES.register_module() +class RandomCrop(object): + r"""Random crop motion sequences. Each sequence will be padded with zeros to the maximum length. + + Args: + min_size (int or None): The minimum size of the cropped motion sequence (inclusive). + max_size (int or None): The maximum size of the cropped motion sequence (inclusive). + """ + def __init__(self, + min_size: Optional[Union[int, None]] = None, + max_size: Optional[Union[int, None]] = None): + self.min_size = min_size + self.max_size = max_size + assert self.min_size is not None + assert self.max_size is not None + + def __call__(self, results): + motion = results['motion'] + length = len(motion) + crop_size = random.randint(self.min_size, self.max_size) + if length > crop_size: + idx = random.randint(0, length - crop_size) + motion = motion[idx: idx + crop_size] + results['motion_length'] = crop_size + else: + results['motion_length'] = length + padding_length = self.max_size - min(crop_size, length) + if padding_length > 0: + D = motion.shape[1:] + padding_zeros = np.zeros((padding_length, *D), dtype=np.float32) + motion = np.concatenate([motion, padding_zeros], axis=0) + results['motion'] = motion + results['motion_shape'] = motion.shape + if length >= self.max_size and crop_size == self.max_size: + results['motion_mask'] = torch.ones(self.max_size).numpy() + else: + results['motion_mask'] = torch.cat(( + torch.ones(min(length, crop_size)), + torch.zeros(self.max_size - min(length, crop_size))), dim=0).numpy() + assert len(motion) == self.max_size + return results + + + def __repr__(self): + repr_str = self.__class__.__name__ + f'(min_size={self.min_size}' + repr_str += f', max_size={self.max_size})' + return repr_str + +@PIPELINES.register_module() +class Normalize(object): + """Normalize motion sequences. + + Args: + mean_path (str): Path of mean file. + std_path (str): Path of std file. + """ + + def __init__(self, mean_path, std_path, eps=1e-9): + self.mean = np.load(mean_path) + self.std = np.load(std_path) + self.eps = eps + + def __call__(self, results): + motion = results['motion'] + motion = (motion - self.mean) / (self.std + self.eps) + results['motion'] = motion + results['motion_norm_mean'] = self.mean + results['motion_norm_std'] = self.std + return results diff --git a/motiondiff_modules/mogen/datasets/samplers/__init__.py b/motiondiff_modules/mogen/datasets/samplers/__init__.py new file mode 100644 index 0000000..bb67128 --- /dev/null +++ b/motiondiff_modules/mogen/datasets/samplers/__init__.py @@ -0,0 +1,3 @@ +from .distributed_sampler import DistributedSampler + +__all__ = ['DistributedSampler'] \ No newline at end of file diff --git a/motiondiff_modules/mogen/datasets/samplers/distributed_sampler.py b/motiondiff_modules/mogen/datasets/samplers/distributed_sampler.py new file mode 100644 index 0000000..a46a086 --- /dev/null +++ b/motiondiff_modules/mogen/datasets/samplers/distributed_sampler.py @@ -0,0 +1,42 @@ +import torch +from torch.utils.data import DistributedSampler as _DistributedSampler + + +class DistributedSampler(_DistributedSampler): + + def __init__(self, + dataset, + num_replicas=None, + rank=None, + shuffle=True, + round_up=True): + super().__init__(dataset, num_replicas=num_replicas, rank=rank) + self.shuffle = shuffle + self.round_up = round_up + if self.round_up: + self.total_size = self.num_samples * self.num_replicas + else: + self.total_size = len(self.dataset) + + def __iter__(self): + # deterministically shuffle based on epoch + if self.shuffle: + g = torch.Generator() + g.manual_seed(self.epoch) + 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 + if self.round_up: + indices = ( + indices * + int(self.total_size / len(indices) + 1))[:self.total_size] + assert len(indices) == self.total_size + + # subsample + indices = indices[self.rank:self.total_size:self.num_replicas] + if self.round_up: + assert len(indices) == self.num_samples + + return iter(indices) diff --git a/motiondiff_modules/mogen/datasets/text_motion_dataset.py b/motiondiff_modules/mogen/datasets/text_motion_dataset.py new file mode 100644 index 0000000..4c26dcd --- /dev/null +++ b/motiondiff_modules/mogen/datasets/text_motion_dataset.py @@ -0,0 +1,93 @@ +import json +import os +import os.path +from abc import ABCMeta +from collections import OrderedDict +from typing import Any, List, Optional, Union + +import custom_mmpkg.custom_mmcv as mmcv +import copy +import numpy as np +import torch +import torch.distributed as dist +from custom_mmpkg.custom_mmcv.runner import get_dist_info + +from .base_dataset import BaseMotionDataset +from .builder import DATASETS + + +@DATASETS.register_module() +class TextMotionDataset(BaseMotionDataset): + """TextMotion dataset. + + Args: + text_dir (str): Path to the directory containing the text files. + """ + def __init__(self, + data_prefix: str, + pipeline: list, + dataset_name: Optional[Union[str, None]] = None, + fixed_length: Optional[Union[int, None]] = None, + ann_file: Optional[Union[str, None]] = None, + motion_dir: Optional[Union[str, None]] = None, + text_dir: Optional[Union[str, None]] = None, + token_dir: Optional[Union[str, None]] = None, + clip_feat_dir: Optional[Union[str, None]] = None, + eval_cfg: Optional[Union[dict, None]] = None, + fine_mode: Optional[bool] = False, + test_mode: Optional[bool] = False): + self.text_dir = os.path.join(data_prefix, 'datasets', dataset_name, text_dir) + if token_dir is not None: + self.token_dir = os.path.join(data_prefix, 'datasets', dataset_name, token_dir) + else: + self.token_dir = None + if clip_feat_dir is not None: + self.clip_feat_dir = os.path.join(data_prefix, 'datasets', dataset_name, clip_feat_dir) + else: + self.clip_feat_dir = None + self.fine_mode = fine_mode + super(TextMotionDataset, self).__init__( + data_prefix=data_prefix, + pipeline=pipeline, + dataset_name=dataset_name, + fixed_length=fixed_length, + ann_file=ann_file, + motion_dir=motion_dir, + eval_cfg=eval_cfg, + test_mode=test_mode) + + def load_anno(self, name): + results = super().load_anno(name) + text_path = os.path.join(self.text_dir, name + '.txt') + text_data = [] + for line in open(text_path, 'r'): + text_data.append(line.strip()) + results['text'] = text_data + if self.token_dir is not None: + token_path = os.path.join(self.token_dir, name + '.txt') + token_data = [] + for line in open(token_path, 'r'): + token_data.append(line.strip()) + results['token'] = token_data + if self.clip_feat_dir is not None: + clip_feat_path = os.path.join(self.clip_feat_dir, name + '.npy') + clip_feat = torch.from_numpy(np.load(clip_feat_path)) + results['clip_feat'] = clip_feat + return results + + def prepare_data(self, idx: int): + """"Prepare raw data for the f'{idx'}-th data.""" + results = copy.deepcopy(self.data_infos[idx]) + text_list = results['text'] + idx = np.random.randint(0, len(text_list)) + if self.fine_mode: + results['text'] = json.loads(text_list[idx]) + else: + results['text'] = text_list[idx] + if 'clip_feat' in results.keys(): + results['clip_feat'] = results['clip_feat'][idx] + if 'token' in results.keys(): + results['token'] = results['token'][idx] + results['dataset_name'] = self.dataset_name + results['sample_idx'] = idx + return self.pipeline(results) diff --git a/motiondiff_modules/mogen/models/__init__.py b/motiondiff_modules/mogen/models/__init__.py new file mode 100644 index 0000000..7f46d5b --- /dev/null +++ b/motiondiff_modules/mogen/models/__init__.py @@ -0,0 +1,7 @@ +from .architectures import * +from .losses import * +from .rnns import * +from .transformers import * +from .attentions import * +from .builder import * +from .utils import * \ No newline at end of file diff --git a/motiondiff_modules/mogen/models/architectures/__init__.py b/motiondiff_modules/mogen/models/architectures/__init__.py new file mode 100644 index 0000000..0e7b46c --- /dev/null +++ b/motiondiff_modules/mogen/models/architectures/__init__.py @@ -0,0 +1,6 @@ +from .vae_architecture import MotionVAE +from .diffusion_architecture import MotionDiffusion + +__all__ = [ + 'MotionVAE', 'MotionDiffusion' +] \ No newline at end of file diff --git a/motiondiff_modules/mogen/models/architectures/base_architecture.py b/motiondiff_modules/mogen/models/architectures/base_architecture.py new file mode 100644 index 0000000..c245006 --- /dev/null +++ b/motiondiff_modules/mogen/models/architectures/base_architecture.py @@ -0,0 +1,135 @@ +from abc import ABCMeta, abstractmethod +from collections import OrderedDict + +import torch +import torch.distributed as dist +from custom_mmpkg.custom_mmcv.runner import BaseModule + + +def to_cpu(x): + if isinstance(x, torch.Tensor): + return x.detach().cpu() + return x + + +class BaseArchitecture(BaseModule): + """Base class for mogen architecture.""" + + def __init__(self, init_cfg=None): + super(BaseArchitecture, self).__init__(init_cfg) + + def forward_train(self, **kwargs): + pass + + def forward_test(self, **kwargs): + pass + + def _parse_losses(self, losses): + """Parse the raw 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 train_step(self, data, optimizer): + """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 (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) + loss, log_vars = self._parse_losses(losses) + + outputs = dict( + loss=loss, log_vars=log_vars, num_samples=len(data['motion'])) + + return outputs + + def val_step(self, data, optimizer=None): + """The iteration step during validation. + This method shares the same signature as :func:`train_step`, but used + during val epochs. Note that the evaluation after training epochs is + not implemented with this method, but an evaluation hook. + """ + losses = self(**data) + loss, log_vars = self._parse_losses(losses) + + outputs = dict( + loss=loss, log_vars=log_vars, num_samples=len(data['motion'])) + + return outputs + + def forward(self, **kwargs): + if self.training: + return self.forward_train(**kwargs) + else: + return self.forward_test(**kwargs) + + def split_results(self, results): + B = results['motion'].shape[0] + output = [] + for i in range(B): + batch_output = dict() + batch_output['motion'] = to_cpu(results['motion'][i]) + batch_output['pred_motion'] = to_cpu(results['pred_motion'][i]) + batch_output['motion_length'] = to_cpu(results['motion_length'][i]) + batch_output['motion_mask'] = to_cpu(results['motion_mask'][i]) + if 'pred_motion_length' in results.keys(): + batch_output['pred_motion_length'] = to_cpu(results['pred_motion_length'][i]) + else: + batch_output['pred_motion_length'] = to_cpu(results['motion_length'][i]) + if 'pred_motion_mask' in results: + batch_output['pred_motion_mask'] = to_cpu(results['pred_motion_mask'][i]) + else: + batch_output['pred_motion_mask'] = to_cpu(results['motion_mask'][i]) + if 'motion_metas' in results.keys(): + motion_metas = results['motion_metas'][i] + if 'text' in motion_metas.keys(): + batch_output['text'] = motion_metas['text'] + if 'token' in motion_metas.keys(): + batch_output['token'] = motion_metas['token'] + output.append(batch_output) + return output diff --git a/motiondiff_modules/mogen/models/architectures/diffusion_architecture.py b/motiondiff_modules/mogen/models/architectures/diffusion_architecture.py new file mode 100644 index 0000000..124dee3 --- /dev/null +++ b/motiondiff_modules/mogen/models/architectures/diffusion_architecture.py @@ -0,0 +1,127 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F + +from .base_architecture import BaseArchitecture +from ..builder import ( + ARCHITECTURES, + build_architecture, + build_submodule, + build_loss +) +from ..utils.gaussian_diffusion import ( + GaussianDiffusion, get_named_beta_schedule, create_named_schedule_sampler, + ModelMeanType, ModelVarType, LossType, space_timesteps, SpacedDiffusion +) + +def build_diffusion(cfg): + beta_scheduler = cfg['beta_scheduler'] + diffusion_steps = cfg['diffusion_steps'] + + betas = get_named_beta_schedule(beta_scheduler, diffusion_steps) + model_mean_type = { + 'start_x': ModelMeanType.START_X, + 'previous_x': ModelMeanType.PREVIOUS_X, + 'epsilon': ModelMeanType.EPSILON + }[cfg['model_mean_type']] + model_var_type = { + 'learned': ModelVarType.LEARNED, + 'fixed_small': ModelVarType.FIXED_SMALL, + 'fixed_large': ModelVarType.FIXED_LARGE, + 'learned_range': ModelVarType.LEARNED_RANGE + }[cfg['model_var_type']] + if cfg.get('respace', None) is not None: + diffusion = SpacedDiffusion( + use_timesteps=space_timesteps(diffusion_steps, cfg['respace']), + betas=betas, + model_mean_type=model_mean_type, + model_var_type=model_var_type, + loss_type=LossType.MSE + ) + else: + diffusion = GaussianDiffusion( + betas=betas, + model_mean_type=model_mean_type, + model_var_type=model_var_type, + loss_type=LossType.MSE) + return diffusion + + +@ARCHITECTURES.register_module() +class MotionDiffusion(BaseArchitecture): + + def __init__(self, + model=None, + loss_recon=None, + diffusion_train=None, + diffusion_test=None, + init_cfg=None, + inference_type='ddpm', + **kwargs): + super().__init__(init_cfg=init_cfg, **kwargs) + self.model = build_submodule(model) + self.loss_recon = build_loss(loss_recon) + self.diffusion_train = build_diffusion(diffusion_train) + self.diffusion_test = build_diffusion(diffusion_test) + self.sampler = create_named_schedule_sampler('uniform', self.diffusion_train) + self.inference_type = inference_type + + def forward(self, **kwargs): + motion, motion_mask = kwargs['motion'].float(), kwargs['motion_mask'].float() + sample_idx = kwargs.get('sample_idx', None) + clip_feat = kwargs.get('clip_feat', None) + B, T = motion.shape[:2] + text = [] + for i in range(B): + text.append(kwargs['motion_metas'][i]['text']) + + if self.training: + t, _ = self.sampler.sample(B, motion.device) + output = self.diffusion_train.training_losses( + model=self.model, + x_start=motion, + t=t, + model_kwargs={ + 'motion_mask': motion_mask, + 'motion_length': kwargs['motion_length'], + 'text': text, + 'clip_feat': clip_feat, + 'sample_idx': sample_idx} + ) + pred, target = output['pred'], output['target'] + recon_loss = self.loss_recon(pred, target, reduction_override='none') + recon_loss = (recon_loss.mean(dim=-1) * motion_mask).sum() / motion_mask.sum() + loss = {'recon_loss': recon_loss} + return loss + else: + dim_pose = kwargs['motion'].shape[-1] + model_kwargs = self.model.get_precompute_condition(device=motion.device, text=text, **kwargs) + model_kwargs['motion_mask'] = motion_mask + model_kwargs['sample_idx'] = sample_idx + inference_kwargs = kwargs.get('inference_kwargs', {}) + if self.inference_type == 'ddpm': + output = self.diffusion_test.p_sample_loop( + self.model, + (B, T, dim_pose), + clip_denoised=False, + progress=False, + model_kwargs=model_kwargs, + **inference_kwargs + ) + else: + output = self.diffusion_test.ddim_sample_loop( + self.model, + (B, T, dim_pose), + clip_denoised=False, + progress=False, + model_kwargs=model_kwargs, + eta=0, + **inference_kwargs + ) + if getattr(self.model, "post_process") is not None: + output = self.model.post_process(output) + results = kwargs + results['pred_motion'] = output + results = self.split_results(results) + return results + diff --git a/motiondiff_modules/mogen/models/architectures/vae_architecture.py b/motiondiff_modules/mogen/models/architectures/vae_architecture.py new file mode 100644 index 0000000..83248f8 --- /dev/null +++ b/motiondiff_modules/mogen/models/architectures/vae_architecture.py @@ -0,0 +1,118 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F + +from .base_architecture import BaseArchitecture +from ..builder import ( + ARCHITECTURES, + build_architecture, + build_submodule, + build_loss +) + + +@ARCHITECTURES.register_module() +class PoseVAE(BaseArchitecture): + + def __init__(self, + encoder=None, + decoder=None, + loss_recon=None, + kl_div_loss_weight=None, + init_cfg=None, + **kwargs): + super().__init__(init_cfg=init_cfg, **kwargs) + self.encoder = build_submodule(encoder) + self.decoder = build_submodule(decoder) + self.loss_recon = build_loss(loss_recon) + self.kl_div_loss_weight = kl_div_loss_weight + + def reparameterize(self, mu, logvar): + std = torch.exp(logvar / 2) + + eps = std.data.new(std.size()).normal_() + latent_code = eps.mul(std).add_(mu) + return latent_code + + def encode(self, pose): + mu, logvar = self.encoder(pose) + return mu + + def forward(self, **kwargs): + motion = kwargs['motion'].float() + B, T = motion.shape[:2] + pose = motion.reshape(B * T, -1) + pose = pose[:, :-4] + + mu, logvar = self.encoder(pose) + z = self.reparameterize(mu, logvar) + pred = self.decoder(z) + + loss = dict() + recon_loss = self.loss_recon(pred, pose, reduction_override='none') + loss['recon_loss'] = recon_loss + if self.kl_div_loss_weight is not None: + loss_kl = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp()) + loss['kl_div_loss'] = (loss_kl * self.kl_div_loss_weight) + + return loss + + +@ARCHITECTURES.register_module() +class MotionVAE(BaseArchitecture): + + def __init__(self, + encoder=None, + decoder=None, + loss_recon=None, + kl_div_loss_weight=None, + init_cfg=None, + **kwargs): + super().__init__(init_cfg=init_cfg, **kwargs) + self.encoder = build_submodule(encoder) + self.decoder = build_submodule(decoder) + self.loss_recon = build_loss(loss_recon) + self.kl_div_loss_weight = kl_div_loss_weight + + def sample(self, std=1, latent_code=None): + if latent_code is not None: + z = latent_code + else: + z = torch.randn(1, 7, self.decoder.latent_dim).cuda() * std + output = self.decoder(z) + if self.use_normalization: + output = output * self.motion_std + output = output + self.motion_mean + return output + + def reparameterize(self, mu, logvar): + std = torch.exp(logvar / 2) + + eps = std.data.new(std.size()).normal_() + latent_code = eps.mul(std).add_(mu) + return latent_code + + def encode(self, motion, motion_mask): + mu, logvar = self.encoder(motion, motion_mask) + return self.reparameterize(mu, logvar) + + def decode(self, z, motion_mask): + return self.decoder(z, motion_mask) + + def forward(self, **kwargs): + motion, motion_mask = kwargs['motion'].float(), kwargs['motion_mask'] + B, T = motion.shape[:2] + + mu, logvar = self.encoder(motion, motion_mask) + z = self.reparameterize(mu, logvar) + pred = self.decoder(z, motion_mask) + + loss = dict() + recon_loss = self.loss_recon(pred, motion, reduction_override='none') + recon_loss = (recon_loss.mean(dim=-1) * motion_mask).sum() / motion_mask.sum() + loss['recon_loss'] = recon_loss + if self.kl_div_loss_weight is not None: + loss_kl = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp()) + loss['kl_div_loss'] = (loss_kl * self.kl_div_loss_weight) + + return loss \ No newline at end of file diff --git a/motiondiff_modules/mogen/models/attentions/__init__.py b/motiondiff_modules/mogen/models/attentions/__init__.py new file mode 100644 index 0000000..50a70f1 --- /dev/null +++ b/motiondiff_modules/mogen/models/attentions/__init__.py @@ -0,0 +1,6 @@ +from .efficient_attention import ( + EfficientSelfAttention, + EfficientCrossAttention +) +from .semantics_modulated import SemanticsModulatedAttention +from .base_attention import BaseMixedAttention \ No newline at end of file diff --git a/motiondiff_modules/mogen/models/attentions/base_attention.py b/motiondiff_modules/mogen/models/attentions/base_attention.py new file mode 100644 index 0000000..a78dccb --- /dev/null +++ b/motiondiff_modules/mogen/models/attentions/base_attention.py @@ -0,0 +1,146 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +from ..utils.stylization_block import StylizationBlock +from ..builder import ATTENTIONS + + +@ATTENTIONS.register_module() +class BaseMixedAttention(nn.Module): + + def __init__(self, latent_dim, + text_latent_dim, + num_heads, + dropout, + time_embed_dim): + super().__init__() + self.num_heads = num_heads + + self.norm = nn.LayerNorm(latent_dim) + self.text_norm = nn.LayerNorm(text_latent_dim) + + self.query = nn.Linear(latent_dim, latent_dim) + self.key_text = nn.Linear(text_latent_dim, latent_dim) + self.value_text = nn.Linear(text_latent_dim, latent_dim) + self.key_motion = nn.Linear(latent_dim, latent_dim) + self.value_motion = nn.Linear(latent_dim, latent_dim) + + self.dropout = nn.Dropout(dropout) + self.proj_out = StylizationBlock(latent_dim, time_embed_dim, dropout) + + def forward(self, x, xf, emb, src_mask, cond_type, **kwargs): + """ + x: B, T, D + xf: B, N, L + """ + B, T, D = x.shape + N = xf.shape[1] + x.shape[1] + H = self.num_heads + # B, T, D + query = self.query(self.norm(x)).view(B, T, H, -1) + # B, N, D + text_cond_type = ((cond_type % 10) > 0).float().view(B, 1, 1).repeat(1, xf.shape[1], 1) + key = torch.cat(( + self.key_text(self.text_norm(xf)), + self.key_motion(self.norm(x)) + ), dim=1).view(B, N, H, -1) + + attention = torch.einsum('bnhl,bmhl->bnmh', query, key) + motion_mask = src_mask.view(B, 1, T, 1) + text_mask = text_cond_type.view(B, 1, -1, 1) + mask = torch.cat((text_mask, motion_mask), dim=2) + attention = attention + (1 - mask) * -1000000 + attention = F.softmax(attention, dim=2) + + value = torch.cat(( + self.value_text(self.text_norm(xf)) * text_cond_type, + self.value_motion(self.norm(x)) * src_mask, + ), dim=1).view(B, N, H, -1) + + y = torch.einsum('bnmh,bmhl->bnhl', attention, value).reshape(B, T, D) + y = x + self.proj_out(y, emb) + return y + + +@ATTENTIONS.register_module() +class BaseSelfAttention(nn.Module): + + def __init__(self, latent_dim, + num_heads, + dropout, + time_embed_dim): + super().__init__() + self.num_heads = num_heads + + self.norm = nn.LayerNorm(latent_dim) + self.query = nn.Linear(latent_dim, latent_dim) + self.key = nn.Linear(latent_dim, latent_dim) + self.value = nn.Linear(latent_dim, latent_dim) + + self.dropout = nn.Dropout(dropout) + self.proj_out = StylizationBlock(latent_dim, time_embed_dim, dropout) + + def forward(self, x, emb, src_mask, **kwargs): + """ + x: B, T, D + """ + B, T, D = x.shape + H = self.num_heads + # B, T, D + query = self.query(self.norm(x)).view(B, T, H, -1) + # B, N, D + key = self.key(self.norm(x)).view(B, T, H, -1) + + attention = torch.einsum('bnhl,bmhl->bnmh', query, key) + mask = src_mask.view(B, 1, T, 1) + attention = attention + (1 - mask) * -1000000 + attention = F.softmax(attention, dim=2) + value = (self.value(self.norm(x)) * src_mask).view(B, T, H, -1) + y = torch.einsum('bnmh,bmhl->bnhl', attention, value).reshape(B, T, D) + y = x + self.proj_out(y, emb) + return y + + +@ATTENTIONS.register_module() +class BaseCrossAttention(nn.Module): + + def __init__(self, latent_dim, + text_latent_dim, + num_heads, + dropout, + time_embed_dim): + super().__init__() + self.num_heads = num_heads + + self.norm = nn.LayerNorm(latent_dim) + self.text_norm = nn.LayerNorm(text_latent_dim) + + self.query = nn.Linear(latent_dim, latent_dim) + self.key = nn.Linear(text_latent_dim, latent_dim) + self.value = nn.Linear(text_latent_dim, latent_dim) + + self.dropout = nn.Dropout(dropout) + self.proj_out = StylizationBlock(latent_dim, time_embed_dim, dropout) + + def forward(self, x, xf, emb, src_mask, cond_type, **kwargs): + """ + x: B, T, D + xf: B, N, L + """ + B, T, D = x.shape + N = xf.shape[1] + H = self.num_heads + # B, T, D + query = self.query(self.norm(x)).view(B, T, H, -1) + # B, N, D + text_cond_type = ((cond_type % 10) > 0).float().view(B, 1, 1).repeat(1, xf.shape[1], 1) + key = self.key(self.text_norm(xf)).view(B, N, H, -1) + attention = torch.einsum('bnhl,bmhl->bnmh', query, key) + mask = text_cond_type.view(B, 1, -1, 1) + attention = attention + (1 - mask) * -1000000 + attention = F.softmax(attention, dim=2) + + value = (self.value(self.text_norm(xf)) * text_cond_type).view(B, N, H, -1) + y = torch.einsum('bnmh,bmhl->bnhl', attention, value).reshape(B, T, D) + y = x + self.proj_out(y, emb) + return y diff --git a/motiondiff_modules/mogen/models/attentions/efficient_attention.py b/motiondiff_modules/mogen/models/attentions/efficient_attention.py new file mode 100644 index 0000000..77a07cf --- /dev/null +++ b/motiondiff_modules/mogen/models/attentions/efficient_attention.py @@ -0,0 +1,87 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +from ..utils.stylization_block import StylizationBlock +from ..builder import ATTENTIONS + + +@ATTENTIONS.register_module() +class EfficientSelfAttention(nn.Module): + + def __init__(self, latent_dim, num_heads, dropout, time_embed_dim=None): + super().__init__() + self.num_heads = num_heads + self.norm = nn.LayerNorm(latent_dim) + self.query = nn.Linear(latent_dim, latent_dim) + self.key = nn.Linear(latent_dim, latent_dim) + self.value = nn.Linear(latent_dim, latent_dim) + self.dropout = nn.Dropout(dropout) + self.time_embed_dim = time_embed_dim + if time_embed_dim is not None: + self.proj_out = StylizationBlock(latent_dim, time_embed_dim, dropout) + + def forward(self, x, src_mask, emb=None, **kwargs): + """ + x: B, T, D + """ + B, T, D = x.shape + H = self.num_heads + # B, T, D + query = self.query(self.norm(x)) + # B, T, D + key = (self.key(self.norm(x)) + (1 - src_mask) * -1000000) + query = F.softmax(query.view(B, T, H, -1), dim=-1) + key = F.softmax(key.view(B, T, H, -1), dim=1) + # B, T, H, HD + value = (self.value(self.norm(x)) * src_mask).view(B, T, H, -1) + # B, H, HD, HD + attention = torch.einsum('bnhd,bnhl->bhdl', key, value) + y = torch.einsum('bnhd,bhdl->bnhl', query, attention).reshape(B, T, D) + if self.time_embed_dim is None: + y = x + y + else: + y = x + self.proj_out(y, emb) + return y + + +@ATTENTIONS.register_module() +class EfficientCrossAttention(nn.Module): + + def __init__(self, latent_dim, text_latent_dim, num_heads, dropout, time_embed_dim): + super().__init__() + self.num_heads = num_heads + self.norm = nn.LayerNorm(latent_dim) + self.text_norm = nn.LayerNorm(text_latent_dim) + self.query = nn.Linear(latent_dim, latent_dim) + self.key = nn.Linear(text_latent_dim, latent_dim) + self.value = nn.Linear(text_latent_dim, latent_dim) + self.dropout = nn.Dropout(dropout) + self.proj_out = StylizationBlock(latent_dim, time_embed_dim, dropout) + + def forward(self, x, xf, emb, cond_type=None, **kwargs): + """ + x: B, T, D + xf: B, N, L + """ + B, T, D = x.shape + N = xf.shape[1] + H = self.num_heads + # B, T, D + query = self.query(self.norm(x)) + # B, N, D + key = self.key(self.text_norm(xf)) + query = F.softmax(query.view(B, T, H, -1), dim=-1) + if cond_type is None: + key = F.softmax(key.view(B, N, H, -1), dim=1) + # B, N, H, HD + value = self.value(self.text_norm(xf)).view(B, N, H, -1) + else: + text_cond_type = ((cond_type % 10) > 0).float().view(B, 1, 1).repeat(1, xf.shape[1], 1) + key = key + (1 - text_cond_type) * -1000000 + key = F.softmax(key.view(B, N, H, -1), dim=1) + value = self.value(self.text_norm(xf) * text_cond_type).view(B, N, H, -1) + # B, H, HD, HD + attention = torch.einsum('bnhd,bnhl->bhdl', key, value) + y = torch.einsum('bnhd,bhdl->bnhl', query, attention).reshape(B, T, D) + y = x + self.proj_out(y, emb) + return y diff --git a/motiondiff_modules/mogen/models/attentions/semantics_modulated.py b/motiondiff_modules/mogen/models/attentions/semantics_modulated.py new file mode 100644 index 0000000..e883a70 --- /dev/null +++ b/motiondiff_modules/mogen/models/attentions/semantics_modulated.py @@ -0,0 +1,82 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +from ..utils.stylization_block import StylizationBlock +from ..builder import ATTENTIONS + + +def zero_module(module): + """ + Zero out the parameters of a module and return it. + """ + for p in module.parameters(): + p.detach().zero_() + return module + + +@ATTENTIONS.register_module() +class SemanticsModulatedAttention(nn.Module): + + def __init__(self, latent_dim, + text_latent_dim, + num_heads, + dropout, + time_embed_dim): + super().__init__() + self.num_heads = num_heads + + self.norm = nn.LayerNorm(latent_dim) + self.text_norm = nn.LayerNorm(text_latent_dim) + + self.query = nn.Linear(latent_dim, latent_dim) + self.key_text = nn.Linear(text_latent_dim, latent_dim) + self.value_text = nn.Linear(text_latent_dim, latent_dim) + self.key_motion = nn.Linear(latent_dim, latent_dim) + self.value_motion = nn.Linear(latent_dim, latent_dim) + + self.retr_norm1 = nn.LayerNorm(2 * latent_dim) + self.retr_norm2 = nn.LayerNorm(latent_dim) + self.key_retr = nn.Linear(2 * latent_dim, latent_dim) + self.value_retr = zero_module(nn.Linear(latent_dim, latent_dim)) + + self.dropout = nn.Dropout(dropout) + self.proj_out = StylizationBlock(latent_dim, time_embed_dim, dropout) + + def forward(self, x, xf, emb, src_mask, cond_type, re_dict=None): + """ + x: B, T, D + xf: B, N, L + """ + B, T, D = x.shape + re_motion = re_dict['re_motion'] + re_text = re_dict['re_text'] + re_mask = re_dict['re_mask'] + re_mask = re_mask.reshape(B, -1, 1) + N = xf.shape[1] + x.shape[1] + re_motion.shape[1] * re_motion.shape[2] + H = self.num_heads + # B, T, D + query = self.query(self.norm(x)) + # B, N, D + text_cond_type = (cond_type % 10 > 0).float() + retr_cond_type = (cond_type // 10 > 0).float() + re_text = re_text.repeat(1, 1, re_motion.shape[2], 1) + re_feat_key = torch.cat((re_motion, re_text), dim=-1).reshape(B, -1, 2 * D) + key = torch.cat(( + self.key_text(self.text_norm(xf)) + (1 - text_cond_type) * -1000000, + self.key_retr(self.retr_norm1(re_feat_key)) + (1 - retr_cond_type) * -1000000 + (1 - re_mask) * -1000000, + self.key_motion(self.norm(x)) + (1 - src_mask) * -1000000 + ), dim=1) + query = F.softmax(query.view(B, T, H, -1), dim=-1) + key = F.softmax(key.view(B, N, H, -1), dim=1) + # B, N, H, HD + re_feat_value = re_motion.reshape(B, -1, D) + value = torch.cat(( + self.value_text(self.text_norm(xf)) * text_cond_type, + self.value_retr(self.retr_norm2(re_feat_value)) * retr_cond_type * re_mask, + self.value_motion(self.norm(x)) * src_mask, + ), dim=1).view(B, N, H, -1) + # B, H, HD, HD + attention = torch.einsum('bnhd,bnhl->bhdl', key, value) + y = torch.einsum('bnhd,bhdl->bnhl', query, attention).reshape(B, T, D) + y = x + self.proj_out(y, emb) + return y \ No newline at end of file diff --git a/motiondiff_modules/mogen/models/builder.py b/motiondiff_modules/mogen/models/builder.py new file mode 100644 index 0000000..ff98d5e --- /dev/null +++ b/motiondiff_modules/mogen/models/builder.py @@ -0,0 +1,32 @@ +from custom_mmpkg.custom_mmcv.cnn import MODELS as MMCV_MODELS +from custom_mmpkg.custom_mmcv.utils import Registry + + +def build_from_cfg(cfg, registry, default_args=None): + if cfg is None: + return None + return MMCV_MODELS.build_func(cfg, registry, default_args) + + +MODELS = Registry('models', parent=MMCV_MODELS, build_func=build_from_cfg) + +LOSSES = MODELS +ARCHITECTURES = MODELS +SUBMODULES = MODELS +ATTENTIONS = MODELS + +def build_loss(cfg): + """Build loss.""" + return LOSSES.build(cfg) + +def build_architecture(cfg): + """Build framework.""" + return ARCHITECTURES.build(cfg) + +def build_submodule(cfg): + """Build submodule.""" + return SUBMODULES.build(cfg) + +def build_attention(cfg): + """Build attention.""" + return ATTENTIONS.build(cfg) diff --git a/motiondiff_modules/mogen/models/losses/__init__.py b/motiondiff_modules/mogen/models/losses/__init__.py new file mode 100644 index 0000000..c893bf2 --- /dev/null +++ b/motiondiff_modules/mogen/models/losses/__init__.py @@ -0,0 +1,13 @@ +from .mse_loss import MSELoss +from .utils import ( + convert_to_one_hot, + reduce_loss, + weight_reduce_loss, + weighted_loss, +) + + +__all__ = [ + 'convert_to_one_hot', 'reduce_loss', 'weight_reduce_loss', 'weighted_loss', + 'MSELoss' +] \ No newline at end of file diff --git a/motiondiff_modules/mogen/models/losses/mse_loss.py b/motiondiff_modules/mogen/models/losses/mse_loss.py new file mode 100644 index 0000000..585538f --- /dev/null +++ b/motiondiff_modules/mogen/models/losses/mse_loss.py @@ -0,0 +1,70 @@ +import torch.nn as nn +import torch.nn.functional as F + +from ..builder import LOSSES +from .utils import weighted_loss + + +def gmof(x, sigma): + """Geman-McClure error function.""" + x_squared = x**2 + sigma_squared = sigma**2 + return (sigma_squared * x_squared) / (sigma_squared + x_squared) + + +@weighted_loss +def mse_loss(pred, target): + """Warpper of mse loss.""" + return F.mse_loss(pred, target, reduction='none') + + +@weighted_loss +def mse_loss_with_gmof(pred, target, sigma): + """Extended MSE Loss with GMOF.""" + loss = F.mse_loss(pred, target, reduction='none') + loss = gmof(loss, sigma) + return loss + + +@LOSSES.register_module() +class MSELoss(nn.Module): + """MSELoss. + Args: + reduction (str, optional): The method that reduces the loss to a + scalar. Options are "none", "mean" and "sum". + loss_weight (float, optional): The weight of the loss. Defaults to 1.0 + """ + + def __init__(self, reduction='mean', loss_weight=1.0): + super().__init__() + assert reduction in (None, 'none', 'mean', 'sum') + reduction = 'none' if reduction is None else reduction + self.reduction = reduction + self.loss_weight = loss_weight + + def forward(self, + pred, + target, + weight=None, + avg_factor=None, + reduction_override=None): + """Forward function of loss. + Args: + pred (torch.Tensor): The prediction. + target (torch.Tensor): The learning target of the prediction. + weight (torch.Tensor, optional): Weight of the loss for each + prediction. Defaults to None. + avg_factor (int, optional): Average factor that is used to average + the loss. Defaults to None. + reduction_override (str, optional): The reduction method used to + override the original reduction method of the loss. + Defaults to None. + Returns: + torch.Tensor: The calculated loss + """ + assert reduction_override in (None, 'none', 'mean', 'sum') + reduction = ( + reduction_override if reduction_override else self.reduction) + loss = self.loss_weight * mse_loss( + pred, target, weight, reduction=reduction, avg_factor=avg_factor) + return loss \ No newline at end of file diff --git a/motiondiff_modules/mogen/models/losses/utils.py b/motiondiff_modules/mogen/models/losses/utils.py new file mode 100644 index 0000000..417b6c5 --- /dev/null +++ b/motiondiff_modules/mogen/models/losses/utils.py @@ -0,0 +1,109 @@ +import functools + +import torch +import torch.nn.functional as F + + +def reduce_loss(loss, reduction): + """Reduce loss as specified. + Args: + loss (Tensor): Elementwise loss tensor. + reduction (str): Options are "none", "mean" and "sum". + Return: + Tensor: Reduced loss tensor. + """ + reduction_enum = F._Reduction.get_enum(reduction) + # none: 0, elementwise_mean:1, sum: 2 + if reduction_enum == 0: + return loss + elif reduction_enum == 1: + return loss.mean() + elif reduction_enum == 2: + return loss.sum() + + +def weight_reduce_loss(loss, weight=None, reduction='mean', avg_factor=None): + """Apply element-wise weight and reduce loss. + Args: + loss (Tensor): Element-wise loss. + weight (Tensor): Element-wise weights. + reduction (str): Same as built-in losses of PyTorch. + avg_factor (float): Average factor when computing the mean of losses. + Returns: + Tensor: Processed loss values. + """ + # if weight is specified, apply element-wise weight + if weight is not None: + loss = loss * weight + + # if avg_factor is not specified, just reduce the loss + if avg_factor is None: + loss = reduce_loss(loss, reduction) + else: + # if reduction is mean, then average the loss by avg_factor + if reduction == 'mean': + loss = loss.sum() / avg_factor + # if reduction is 'none', then do nothing, otherwise raise an error + elif reduction != 'none': + raise ValueError('avg_factor can not be used with reduction="sum"') + return loss + + +def weighted_loss(loss_func): + """Create a weighted version of a given loss function. + To use this decorator, the loss function must have the signature like + `loss_func(pred, target, **kwargs)`. The function only needs to compute + element-wise loss without any reduction. This decorator will add weight + and reduction arguments to the function. The decorated function will have + the signature like `loss_func(pred, target, weight=None, reduction='mean', + avg_factor=None, **kwargs)`. + :Example: + >>> import torch + >>> @weighted_loss + >>> def l1_loss(pred, target): + >>> return (pred - target).abs() + >>> pred = torch.Tensor([0, 2, 3]) + >>> target = torch.Tensor([1, 1, 1]) + >>> weight = torch.Tensor([1, 0, 1]) + >>> l1_loss(pred, target) + tensor(1.3333) + >>> l1_loss(pred, target, weight) + tensor(1.) + >>> l1_loss(pred, target, reduction='none') + tensor([1., 1., 2.]) + >>> l1_loss(pred, target, weight, avg_factor=2) + tensor(1.5000) + """ + + @functools.wraps(loss_func) + def wrapper(pred, + target, + weight=None, + reduction='mean', + avg_factor=None, + **kwargs): + # get element-wise loss + loss = loss_func(pred, target, **kwargs) + loss = weight_reduce_loss(loss, weight, reduction, avg_factor) + return loss + + return wrapper + + +def convert_to_one_hot(targets: torch.Tensor, classes) -> torch.Tensor: + """This function converts target class indices to one-hot vectors, given + the number of classes. + Args: + targets (Tensor): The ground truth label of the prediction + with shape (N, 1) + classes (int): the number of classes. + Returns: + Tensor: Processed loss values. + """ + assert (torch.max(targets).item() < + classes), 'Class Index must be less than number of classes' + one_hot_targets = torch.zeros((targets.shape[0], classes), + dtype=torch.long, + device=targets.device) + one_hot_targets.scatter_(1, targets.long(), 1) + return one_hot_targets diff --git a/motiondiff_modules/mogen/models/rnns/__init__.py b/motiondiff_modules/mogen/models/rnns/__init__.py new file mode 100644 index 0000000..b730b23 --- /dev/null +++ b/motiondiff_modules/mogen/models/rnns/__init__.py @@ -0,0 +1 @@ +from .t2m_bigru import T2MMotionEncoder, T2MTextEncoder \ No newline at end of file diff --git a/motiondiff_modules/mogen/models/rnns/t2m_bigru.py b/motiondiff_modules/mogen/models/rnns/t2m_bigru.py new file mode 100644 index 0000000..4ff7242 --- /dev/null +++ b/motiondiff_modules/mogen/models/rnns/t2m_bigru.py @@ -0,0 +1,260 @@ +import torch +import torch.nn as nn +import numpy as np +import time +import math +from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence +import torch.nn.functional as F +from ..builder import SUBMODULES + +from motiondiff_modules.mogen.models.utils.word_vectorizer import WordVectorizer + + +def init_weight(m): + if isinstance(m, nn.Conv1d) or isinstance(m, nn.Linear) or isinstance(m, nn.ConvTranspose1d): + nn.init.xavier_normal_(m.weight) + # m.bias.data.fill_(0.01) + if m.bias is not None: + nn.init.constant_(m.bias, 0) + + +def reparameterize(mu, logvar): + s_var = logvar.mul(0.5).exp_() + eps = s_var.data.new(s_var.size()).normal_() + return eps.mul(s_var).add_(mu) + + +# batch_size, dimension and position +# output: (batch_size, dim) +def positional_encoding(batch_size, dim, pos): + assert batch_size == pos.shape[0] + positions_enc = np.array([ + [pos[j] / np.power(10000, (i-i%2)/dim) for i in range(dim)] + for j in range(batch_size) + ], dtype=np.float32) + positions_enc[:, 0::2] = np.sin(positions_enc[:, 0::2]) + positions_enc[:, 1::2] = np.cos(positions_enc[:, 1::2]) + return torch.from_numpy(positions_enc).float() + + +def get_padding_mask(batch_size, seq_len, cap_lens): + cap_lens = cap_lens.data.tolist() + mask_2d = torch.ones((batch_size, seq_len, seq_len), dtype=torch.float32) + for i, cap_len in enumerate(cap_lens): + mask_2d[i, :, :cap_len] = 0 + return mask_2d.bool(), 1 - mask_2d[:, :, 0].clone() + + +class PositionalEncoding(nn.Module): + + def __init__(self, d_model, max_len=300): + super(PositionalEncoding, self).__init__() + + pe = torch.zeros(max_len, d_model) + position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1) + div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model)) + pe[:, 0::2] = torch.sin(position * div_term) + pe[:, 1::2] = torch.cos(position * div_term) + # pe = pe.unsqueeze(0).transpose(0, 1) + self.register_buffer('pe', pe) + + def forward(self, pos): + return self.pe[pos] + + +@SUBMODULES.register_module() +class T2MMotionEncoder(nn.Module): + + def __init__(self, + input_size, + movement_hidden_size, + movement_latent_size, + motion_hidden_size, + motion_latent_size): + super().__init__() + self.movement_encoder = MovementConvEncoder( + input_size=input_size-4, + hidden_size=movement_hidden_size, + output_size=movement_latent_size) + self.motion_encoder = MotionEncoderBiGRUCo( + input_size=movement_latent_size, + hidden_size=motion_hidden_size, + output_size=motion_latent_size + ) + + def load_pretrained(self, ckpt_path): + checkpoint = torch.load(ckpt_path, map_location='cpu') + self.movement_encoder.load_state_dict(checkpoint['movement_encoder']) + self.motion_encoder.load_state_dict(checkpoint['motion_encoder']) + + def forward(self, motion, motion_length, motion_mask): + motion = motion.detach().float() + sort_idx = np.argsort(motion_length.data.tolist())[::-1].copy() + rank_idx = np.empty_like(sort_idx) + rank_idx[sort_idx] = np.arange(len(motion_length)) + motion = motion[sort_idx] + motion_length = motion_length[sort_idx] + + movements = self.movement_encoder(motion[..., :-4]).detach() + m_lens = motion_length // 4 + motion_embedding = self.motion_encoder(movements, m_lens) + motion_embedding_ordered = motion_embedding[rank_idx] + return motion_embedding_ordered + + +@SUBMODULES.register_module() +class T2MTextEncoder(nn.Module): + + def __init__(self, + word_size, + pos_size, + hidden_size, + output_size, + max_text_len): + super().__init__() + self.text_encoder = TextEncoderBiGRUCo( + word_size=word_size, + pos_size=pos_size, + hidden_size=hidden_size, + output_size=output_size, + ) + self.w_vectorizer = WordVectorizer('./data/glove', 'our_vab') + self.max_text_len = max_text_len + + def load_pretrained(self, ckpt_path): + checkpoint = torch.load(ckpt_path, map_location='cpu') + self.text_encoder.load_state_dict(checkpoint['text_encoder']) + + def forward(self, text, token, device): + B = len(text) + pos_one_hot = [] + word_emb = [] + sent_len = [] + for i in range(B): + tokens = token[i].split(" ") + if len(tokens) < self.max_text_len: + tokens = ['sos/OTHER'] + tokens + ['eos/OTHER'] + batch_sent_len = len(tokens) + tokens = tokens + ['unk/OTHER'] * (self.max_text_len + 2 - batch_sent_len) + else: + tokens = tokens[: self.max_text_len] + tokens = ['sos/OTHER'] + tokens + ['eos/OTHER'] + batch_sent_len = len(tokens) + sent_len.append(batch_sent_len) + batch_word_emb = [] + batch_pos_one_hot = [] + for cur_token in tokens: + cur_word_emb, cur_pos_one_hot = self.w_vectorizer[cur_token] + cur_word_emb = torch.from_numpy(cur_word_emb).float() + cur_pos_one_hot = torch.from_numpy(cur_pos_one_hot).float() + batch_word_emb.append(cur_word_emb) + batch_pos_one_hot.append(cur_pos_one_hot) + + batch_word_emb = torch.stack(batch_word_emb, dim=0) + batch_pos_one_hot = torch.stack(batch_pos_one_hot, dim=0) + word_emb.append(batch_word_emb) + pos_one_hot.append(batch_pos_one_hot) + word_emb = torch.stack(word_emb, dim=0).to(device) + pos_one_hot = torch.stack(pos_one_hot, dim=0).to(device) + sent_len = torch.tensor(sent_len, dtype=torch.long).to(device) + text_embedding = self.text_encoder(word_emb, pos_one_hot, sent_len) + return text_embedding + + +class TextEncoderBiGRUCo(nn.Module): + def __init__(self, word_size, pos_size, hidden_size, output_size): + super(TextEncoderBiGRUCo, self).__init__() + + self.pos_emb = nn.Linear(pos_size, word_size) + self.input_emb = nn.Linear(word_size, hidden_size) + self.gru = nn.GRU(hidden_size, hidden_size, batch_first=True, bidirectional=True) + self.output_net = nn.Sequential( + nn.Linear(hidden_size * 2, hidden_size), + nn.LayerNorm(hidden_size), + nn.LeakyReLU(0.2, inplace=True), + nn.Linear(hidden_size, output_size) + ) + + self.input_emb.apply(init_weight) + self.pos_emb.apply(init_weight) + self.output_net.apply(init_weight) + # self.linear2.apply(init_weight) + # self.batch_size = batch_size + self.hidden_size = hidden_size + self.hidden = nn.Parameter(torch.randn((2, 1, self.hidden_size), requires_grad=True)) + + # input(batch_size, seq_len, dim) + def forward(self, word_embs, pos_onehot, cap_lens): + num_samples = word_embs.shape[0] + + pos_embs = self.pos_emb(pos_onehot) + inputs = word_embs + pos_embs + input_embs = self.input_emb(inputs) + hidden = self.hidden.repeat(1, num_samples, 1) + + cap_lens = cap_lens.data.tolist() + emb = pack_padded_sequence(input_embs, cap_lens, batch_first=True, enforce_sorted=False) + + gru_seq, gru_last = self.gru(emb, hidden) + + gru_last = torch.cat([gru_last[0], gru_last[1]], dim=-1) + + return self.output_net(gru_last) + + +class MovementConvEncoder(nn.Module): + def __init__(self, input_size, hidden_size, output_size): + super(MovementConvEncoder, self).__init__() + self.main = nn.Sequential( + nn.Conv1d(input_size, hidden_size, 4, 2, 1), + nn.Dropout(0.2, inplace=True), + nn.LeakyReLU(0.2, inplace=True), + nn.Conv1d(hidden_size, output_size, 4, 2, 1), + nn.Dropout(0.2, inplace=True), + nn.LeakyReLU(0.2, inplace=True), + ) + self.out_net = nn.Linear(output_size, output_size) + self.main.apply(init_weight) + self.out_net.apply(init_weight) + + def forward(self, inputs): + inputs = inputs.permute(0, 2, 1) + outputs = self.main(inputs).permute(0, 2, 1) + # print(outputs.shape) + return self.out_net(outputs) + + +class MotionEncoderBiGRUCo(nn.Module): + def __init__(self, input_size, hidden_size, output_size): + super(MotionEncoderBiGRUCo, self).__init__() + + self.input_emb = nn.Linear(input_size, hidden_size) + self.gru = nn.GRU(hidden_size, hidden_size, batch_first=True, bidirectional=True) + self.output_net = nn.Sequential( + nn.Linear(hidden_size*2, hidden_size), + nn.LayerNorm(hidden_size), + nn.LeakyReLU(0.2, inplace=True), + nn.Linear(hidden_size, output_size) + ) + + self.input_emb.apply(init_weight) + self.output_net.apply(init_weight) + self.hidden_size = hidden_size + self.hidden = nn.Parameter(torch.randn((2, 1, self.hidden_size), requires_grad=True)) + + # input(batch_size, seq_len, dim) + def forward(self, inputs, m_lens): + num_samples = inputs.shape[0] + + input_embs = self.input_emb(inputs) + hidden = self.hidden.repeat(1, num_samples, 1) + + cap_lens = m_lens.data.tolist() + emb = pack_padded_sequence(input_embs, cap_lens, batch_first=True) + + gru_seq, gru_last = self.gru(emb, hidden) + + gru_last = torch.cat([gru_last[0], gru_last[1]], dim=-1) + + return self.output_net(gru_last) + diff --git a/motiondiff_modules/mogen/models/transformers/__init__.py b/motiondiff_modules/mogen/models/transformers/__init__.py new file mode 100644 index 0000000..17e7fc6 --- /dev/null +++ b/motiondiff_modules/mogen/models/transformers/__init__.py @@ -0,0 +1,5 @@ +from .actor import ACTOREncoder, ACTORDecoder +from .motiondiffuse import MotionDiffuseTransformer +from .remodiffuse import ReMoDiffuseTransformer +from .mdm import MDMTransformer +from .position_encoding import SinusoidalPositionalEncoding, LearnedPositionalEncoding \ No newline at end of file diff --git a/motiondiff_modules/mogen/models/transformers/actor.py b/motiondiff_modules/mogen/models/transformers/actor.py new file mode 100644 index 0000000..02d1b19 --- /dev/null +++ b/motiondiff_modules/mogen/models/transformers/actor.py @@ -0,0 +1,189 @@ +from cv2 import norm +import torch +from torch import layer_norm, nn +from custom_mmpkg.custom_mmcv.runner import BaseModule +import numpy as np + +from ..builder import SUBMODULES +from .position_encoding import SinusoidalPositionalEncoding, LearnedPositionalEncoding +import math + + +@SUBMODULES.register_module() +class ACTOREncoder(BaseModule): + def __init__(self, + max_seq_len=16, + njoints=None, + nfeats=None, + input_feats=None, + latent_dim=256, + output_dim=256, + condition_dim=None, + num_heads=4, + ff_size=1024, + num_layers=8, + activation='gelu', + dropout=0.1, + use_condition=False, + num_class=None, + use_final_proj=False, + output_var=False, + pos_embedding='sinusoidal', + init_cfg=None): + super().__init__(init_cfg=init_cfg) + self.njoints = njoints + self.nfeats = nfeats + if input_feats is None: + assert self.njoints is not None and self.nfeats is not None + self.input_feats = njoints * nfeats + else: + self.input_feats = input_feats + self.max_seq_len = max_seq_len + self.latent_dim = latent_dim + self.condition_dim = condition_dim + self.use_condition = use_condition + self.num_class = num_class + self.use_final_proj = use_final_proj + self.output_var = output_var + self.skelEmbedding = nn.Linear(self.input_feats, self.latent_dim) + if self.use_condition: + if num_class is None: + self.mu_layer = build_MLP(self.condition_dim, self.latent_dim) + if self.output_var: + self.sigma_layer = build_MLP(self.condition_dim, self.latent_dim) + else: + self.mu_layer = nn.Parameter(torch.randn(num_class, self.latent_dim)) + if self.output_var: + self.sigma_layer = nn.Parameter(torch.randn(num_class, self.latent_dim)) + else: + if self.output_var: + self.query = nn.Parameter(torch.randn(2, self.latent_dim)) + else: + self.query = nn.Parameter(torch.randn(1, self.latent_dim)) + if pos_embedding == 'sinusoidal': + self.pos_encoder = SinusoidalPositionalEncoding(latent_dim, dropout) + else: + self.pos_encoder = LearnedPositionalEncoding(latent_dim, dropout, max_len=max_seq_len + 2) + seqTransEncoderLayer = nn.TransformerEncoderLayer( + d_model=self.latent_dim, + nhead=num_heads, + dim_feedforward=ff_size, + dropout=dropout, + activation=activation) + self.seqTransEncoder = nn.TransformerEncoder( + seqTransEncoderLayer, + num_layers=num_layers) + + def forward(self, motion, motion_mask=None, condition=None): + B, T = motion.shape[:2] + motion = motion.view(B, T, -1) + feature = self.skelEmbedding(motion) + if self.use_condition: + if self.output_var: + if self.num_class is None: + sigma_query = self.sigma_layer(condition).view(B, 1, -1) + else: + sigma_query = self.sigma_layer[condition.long()].view(B, 1, -1) + feature = torch.cat((sigma_query, feature), dim=1) + if self.num_class is None: + mu_query = self.mu_layer(condition).view(B, 1, -1) + else: + mu_query = self.mu_layer[condition.long()].view(B, 1, -1) + feature = torch.cat((mu_query, feature), dim=1) + else: + query = self.query.view(1, -1, self.latent_dim).repeat(B, 1, 1) + feature = torch.cat((query, feature), dim=1) + if self.output_var: + motion_mask = torch.cat((torch.zeros(B, 2).to(motion.device), 1 - motion_mask), dim=1).bool() + else: + motion_mask = torch.cat((torch.zeros(B, 1).to(motion.device), 1 - motion_mask), dim=1).bool() + feature = feature.permute(1, 0, 2).contiguous() + feature = self.pos_encoder(feature) + feature = self.seqTransEncoder(feature, src_key_padding_mask=motion_mask) + if self.use_final_proj: + mu = self.final_mu(feature[0]) + if self.output_var: + sigma = self.final_sigma(feature[1]) + return mu, sigma + return mu + else: + if self.output_var: + return feature[0], feature[1] + else: + return feature[0] + + +@SUBMODULES.register_module() +class ACTORDecoder(BaseModule): + + def __init__(self, + max_seq_len=16, + njoints=None, + nfeats=None, + input_feats=None, + input_dim=256, + latent_dim=256, + condition_dim=None, + num_heads=4, + ff_size=1024, + num_layers=8, + activation='gelu', + dropout=0.1, + use_condition=False, + num_class=None, + pos_embedding='sinusoidal', + init_cfg=None): + super().__init__(init_cfg=init_cfg) + if input_dim != latent_dim: + self.linear = nn.Linear(input_dim, latent_dim) + else: + self.linear = nn.Identity() + self.njoints = njoints + self.nfeats = nfeats + if input_feats is None: + assert self.njoints is not None and self.nfeats is not None + self.input_feats = njoints * nfeats + else: + self.input_feats = input_feats + self.max_seq_len = max_seq_len + self.input_dim = input_dim + self.latent_dim = latent_dim + self.condition_dim = condition_dim + self.use_condition = use_condition + self.num_class = num_class + if self.use_condition: + if num_class is None: + self.condition_bias = build_MLP(condition_dim, latent_dim) + else: + self.condition_bias = nn.Parameter(torch.randn(num_class, latent_dim)) + if pos_embedding == 'sinusoidal': + self.pos_encoder = SinusoidalPositionalEncoding(latent_dim, dropout) + else: + self.pos_encoder = LearnedPositionalEncoding(latent_dim, dropout, max_len=max_seq_len) + seqTransDecoderLayer = nn.TransformerDecoderLayer( + d_model=self.latent_dim, + nhead=num_heads, + dim_feedforward=ff_size, + dropout=dropout, + activation=activation) + self.seqTransDecoder = nn.TransformerDecoder( + seqTransDecoderLayer, + num_layers=num_layers) + + self.final = nn.Linear(self.latent_dim, self.input_feats) + + def forward(self, input, motion_mask=None, condition=None): + B = input.shape[0] + T = self.max_seq_len + input = self.linear(input) + if self.use_condition: + if self.num_class is None: + condition = self.condition_bias(condition) + else: + condition = self.condition_bias[condition.long()].squeeze(1) + input = input + condition + query = self.pos_encoder.pe[:T, :].view(T, 1, -1).repeat(1, B, 1) + input = input.view(1, B, -1) + feature = self.seqTransDecoder(tgt=query, memory=input, tgt_key_padding_mask=(1 - motion_mask).bool()) + pose = self.final(feature).permute(1, 0, 2).contiguous() + return pose diff --git a/motiondiff_modules/mogen/models/transformers/diffusion_transformer.py b/motiondiff_modules/mogen/models/transformers/diffusion_transformer.py new file mode 100644 index 0000000..6adad84 --- /dev/null +++ b/motiondiff_modules/mogen/models/transformers/diffusion_transformer.py @@ -0,0 +1,251 @@ +from abc import ABCMeta, abstractmethod +from cv2 import norm +import torch +from torch import layer_norm, nn +import torch.nn.functional as F +from custom_mmpkg.custom_mmcv.runner import BaseModule +import numpy as np + +from ..builder import SUBMODULES, build_attention +from .position_encoding import SinusoidalPositionalEncoding, LearnedPositionalEncoding +from ..utils.stylization_block import StylizationBlock +import math +import clip + + +def timestep_embedding(timesteps, dim, max_period=10000): + """ + Create sinusoidal timestep embeddings. + :param timesteps: a 1-D Tensor of N indices, one per batch element. + These may be fractional. + :param dim: the dimension of the output. + :param max_period: controls the minimum frequency of the embeddings. + :return: an [N x dim] Tensor of positional embeddings. + """ + half = dim // 2 + freqs = torch.exp( + -math.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32) / half + ).to(device=timesteps.device) + args = timesteps[:, None].float() * freqs[None] + embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1) + if dim % 2: + embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1) + return embedding + + +def set_requires_grad(nets, requires_grad=False): + """Set requies_grad for all the networks. + + Args: + nets (nn.Module | list[nn.Module]): A list of networks or a single + network. + requires_grad (bool): Whether the networks require gradients or not + """ + if not isinstance(nets, list): + nets = [nets] + for net in nets: + if net is not None: + for param in net.parameters(): + param.requires_grad = requires_grad + + +def zero_module(module): + """ + Zero out the parameters of a module and return it. + """ + for p in module.parameters(): + p.detach().zero_() + return module + + +class FFN(nn.Module): + + def __init__(self, latent_dim, ffn_dim, dropout, time_embed_dim): + super().__init__() + self.linear1 = nn.Linear(latent_dim, ffn_dim) + self.linear2 = zero_module(nn.Linear(ffn_dim, latent_dim)) + self.activation = nn.GELU() + self.dropout = nn.Dropout(dropout) + self.proj_out = StylizationBlock(latent_dim, time_embed_dim, dropout) + + def forward(self, x, emb, **kwargs): + y = self.linear2(self.dropout(self.activation(self.linear1(x)))) + y = x + self.proj_out(y, emb) + return y + + +class DecoderLayer(nn.Module): + + def __init__(self, + sa_block_cfg=None, + ca_block_cfg=None, + ffn_cfg=None): + super().__init__() + self.sa_block = build_attention(sa_block_cfg) + self.ca_block = build_attention(ca_block_cfg) + self.ffn = FFN(**ffn_cfg) + + def forward(self, **kwargs): + if self.sa_block is not None: + x = self.sa_block(**kwargs) + kwargs.update({'x': x}) + if self.ca_block is not None: + x = self.ca_block(**kwargs) + kwargs.update({'x': x}) + if self.ffn is not None: + x = self.ffn(**kwargs) + return x + + +class DiffusionTransformer(BaseModule, metaclass=ABCMeta): + def __init__(self, + input_feats, + max_seq_len=240, + latent_dim=512, + time_embed_dim=2048, + num_layers=8, + sa_block_cfg=None, + ca_block_cfg=None, + ffn_cfg=None, + text_encoder=None, + use_cache_for_text=False, + init_cfg=None): + super().__init__(init_cfg=init_cfg) + self.input_feats = input_feats + self.max_seq_len = max_seq_len + self.latent_dim = latent_dim + self.num_layers = num_layers + self.time_embed_dim = time_embed_dim + self.sequence_embedding = nn.Parameter(torch.randn(max_seq_len, latent_dim)) + + self.use_cache_for_text = use_cache_for_text + if use_cache_for_text: + self.text_cache = {} + self.build_text_encoder(text_encoder) + + # Input Embedding + self.joint_embed = nn.Linear(self.input_feats, self.latent_dim) + + self.time_embed = nn.Sequential( + nn.Linear(self.latent_dim, self.time_embed_dim), + nn.SiLU(), + nn.Linear(self.time_embed_dim, self.time_embed_dim), + ) + self.build_temporal_blocks(sa_block_cfg, ca_block_cfg, ffn_cfg) + + # Output Module + self.out = zero_module(nn.Linear(self.latent_dim, self.input_feats)) + + def build_temporal_blocks(self, sa_block_cfg, ca_block_cfg, ffn_cfg): + self.temporal_decoder_blocks = nn.ModuleList() + for i in range(self.num_layers): + self.temporal_decoder_blocks.append( + DecoderLayer( + sa_block_cfg=sa_block_cfg, + ca_block_cfg=ca_block_cfg, + ffn_cfg=ffn_cfg + ) + ) + + def build_text_encoder(self, text_encoder): + + text_latent_dim = text_encoder['latent_dim'] + num_text_layers = text_encoder.get('num_layers', 0) + text_ff_size = text_encoder.get('ff_size', 2048) + pretrained_model = text_encoder['pretrained_model'] + text_num_heads = text_encoder.get('num_heads', 4) + dropout = text_encoder.get('dropout', 0) + activation = text_encoder.get('activation', 'gelu') + self.use_text_proj = text_encoder.get('use_text_proj', False) + + if pretrained_model == 'clip': + self.clip, _ = clip.load('ViT-B/32', "cpu") + set_requires_grad(self.clip, False) + if text_latent_dim != 512: + self.text_pre_proj = nn.Linear(512, text_latent_dim) + else: + self.text_pre_proj = nn.Identity() + else: + raise NotImplementedError() + + if num_text_layers > 0: + self.use_text_finetune = True + textTransEncoderLayer = nn.TransformerEncoderLayer( + d_model=text_latent_dim, + nhead=text_num_heads, + dim_feedforward=text_ff_size, + dropout=dropout, + activation=activation) + self.textTransEncoder = nn.TransformerEncoder( + textTransEncoderLayer, + num_layers=num_text_layers) + else: + self.use_text_finetune = False + self.text_ln = nn.LayerNorm(text_latent_dim) + if self.use_text_proj: + self.text_proj = nn.Sequential( + nn.Linear(text_latent_dim, self.time_embed_dim) + ) + + def encode_text(self, text, clip_feat, device): + B = len(text) + text = clip.tokenize(text, truncate=True).to(device) + if clip_feat is None: + with torch.no_grad(): + x = self.clip.token_embedding(text).type(self.clip.dtype) # [batch_size, n_ctx, d_model] + + x = x + self.clip.positional_embedding.type(self.clip.dtype) + x = x.permute(1, 0, 2) # NLD -> LND + x = self.clip.transformer(x) + x = self.clip.ln_final(x).type(self.clip.dtype) + else: + x = clip_feat.type(self.clip.dtype).to(device).permute(1, 0, 2) + + # T, B, D + x = self.text_pre_proj(x) + xf_out = self.textTransEncoder(x) + xf_out = self.text_ln(xf_out) + if self.use_text_proj: + xf_proj = self.text_proj(xf_out[text.argmax(dim=-1), torch.arange(xf_out.shape[1])]) + # B, T, D + xf_out = xf_out.permute(1, 0, 2) + return xf_proj, xf_out + else: + xf_out = xf_out.permute(1, 0, 2) + return xf_out + + @abstractmethod + def get_precompute_condition(self, **kwargs): + pass + + @abstractmethod + def forward_train(self, h, src_mask, emb, **kwargs): + pass + + @abstractmethod + def forward_test(self, h, src_mask, emb, **kwargs): + pass + + def forward(self, motion, timesteps, motion_mask=None, **kwargs): + """ + motion: B, T, D + """ + B, T = motion.shape[0], motion.shape[1] + conditions = self.get_precompute_condition(device=motion.device, **kwargs) + if len(motion_mask.shape) == 2: + src_mask = motion_mask.clone().unsqueeze(-1) + else: + src_mask = motion_mask.clone() + + if self.use_text_proj: + emb = self.time_embed(timestep_embedding(timesteps, self.latent_dim)) + conditions['xf_proj'] + else: + emb = self.time_embed(timestep_embedding(timesteps, self.latent_dim)) + # B, T, latent_dim + h = self.joint_embed(motion) + h = h + self.sequence_embedding.unsqueeze(0)[:, :T, :] + + if self.training: + return self.forward_train(h=h, src_mask=src_mask, emb=emb, timesteps=timesteps, **conditions) + else: + return self.forward_test(h=h, src_mask=src_mask, emb=emb, timesteps=timesteps, **conditions) diff --git a/motiondiff_modules/mogen/models/transformers/mdm.py b/motiondiff_modules/mogen/models/transformers/mdm.py new file mode 100644 index 0000000..a1d64b1 --- /dev/null +++ b/motiondiff_modules/mogen/models/transformers/mdm.py @@ -0,0 +1,212 @@ +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F +import clip + +from ..builder import SUBMODULES + + +def convert_weights(model: nn.Module): + """Convert applicable model parameters to fp32""" + + def _convert_weights_to_fp32(l): + if isinstance(l, (nn.Conv1d, nn.Conv2d, nn.Linear)): + l.weight.data = l.weight.data.float() + if l.bias is not None: + l.bias.data = l.bias.data.float() + + if isinstance(l, nn.MultiheadAttention): + for attr in [*[f"{s}_proj_weight" for s in ["in", "q", "k", "v"]], "in_proj_bias", "bias_k", "bias_v"]: + tensor = getattr(l, attr) + if tensor is not None: + tensor.data = tensor.data.float() + + for name in ["text_projection", "proj"]: + if hasattr(l, name): + attr = getattr(l, name) + if attr is not None: + attr.data = attr.data.float() + + model.apply(_convert_weights_to_fp32) + + +@SUBMODULES.register_module() +class MDMTransformer(nn.Module): + def __init__(self, + input_feats=263, + latent_dim=256, + ff_size=1024, + num_layers=8, + num_heads=4, + dropout=0.1, + activation="gelu", + clip_dim=512, + clip_version=None, + guide_scale=1.0, + cond_mask_prob=0.1, + use_official_ckpt=False, + **kwargs): + super().__init__() + + self.latent_dim = latent_dim + self.ff_size = ff_size + self.num_layers = num_layers + self.num_heads = num_heads + self.dropout = dropout + self.activation = activation + self.clip_dim = clip_dim + self.input_feats = input_feats + self.guide_scale = guide_scale + self.use_official_ckpt = use_official_ckpt + + self.cond_mask_prob = cond_mask_prob + self.poseEmbedding = nn.Linear(self.input_feats, self.latent_dim) + self.sequence_pos_encoder = PositionalEncoding(self.latent_dim, self.dropout) + + seqTransEncoderLayer = nn.TransformerEncoderLayer(d_model=self.latent_dim, + nhead=self.num_heads, + dim_feedforward=self.ff_size, + dropout=self.dropout, + activation=self.activation) + + self.seqTransEncoder = nn.TransformerEncoder(seqTransEncoderLayer, + num_layers=self.num_layers) + + self.embed_timestep = TimestepEmbedder(self.latent_dim, self.sequence_pos_encoder) + + + self.embed_text = nn.Linear(self.clip_dim, self.latent_dim) + self.clip_version = clip_version + self.clip_model = self.load_and_freeze_clip(clip_version) + + self.poseFinal = nn.Linear(self.latent_dim, self.input_feats) + + + def load_and_freeze_clip(self, clip_version): + clip_model, clip_preprocess = clip.load(clip_version, device='cpu', + jit=False) # Must set jit=False for training + clip.model.convert_weights( + clip_model) # Actually this line is unnecessary since clip by default already on float16 + + clip_model.eval() + for p in clip_model.parameters(): + p.requires_grad = False + + return clip_model + + + def mask_cond(self, cond, force_mask=False): + bs, d = cond.shape + if force_mask: + return torch.zeros_like(cond) + elif self.training and self.cond_mask_prob > 0.: + mask = torch.bernoulli(torch.ones(bs, device=cond.device) * self.cond_mask_prob).view(bs, 1) # 1-> use null_cond, 0-> use real cond + return cond * (1. - mask) + else: + return cond + + def encode_text(self, raw_text): + # raw_text - list (batch_size length) of strings with input text prompts + device = next(self.parameters()).device + max_text_len = 20 + if max_text_len is not None: + default_context_length = 77 + context_length = max_text_len + 2 # start_token + 20 + end_token + assert context_length < default_context_length + texts = clip.tokenize(raw_text, context_length=context_length, truncate=True).to(device) + zero_pad = torch.zeros([texts.shape[0], default_context_length-context_length], dtype=texts.dtype, device=texts.device) + texts = torch.cat([texts, zero_pad], dim=1) + return self.clip_model.encode_text(texts).float() + + def get_precompute_condition(self, text, device=None, **kwargs): + if not self.training and device == torch.device('cpu'): + convert_weights(self.clip_model) + text_feat = self.encode_text(text) + return {'text_feat': text_feat} + + def post_process(self, motion): + assert len(motion.shape) == 3 + if self.use_official_ckpt: + motion[:, :, :4] = motion[:, :, :4] * 25 + return motion + + def forward(self, motion, timesteps, text_feat=None, **kwargs): + """ + motion: B, T, D + timesteps: [batch_size] (int) + """ + B, T, D = motion.shape + device = motion.device + if text_feat is None: + enc_text = self.get_precompute_condition(**kwargs)['text_feat'] + else: + enc_text = text_feat + if self.training: + # T, B, D + motion = self.poseEmbedding(motion).permute(1, 0, 2) + + emb = self.embed_timestep(timesteps) # [1, bs, d] + emb += self.embed_text(self.mask_cond(enc_text, force_mask=False)) + + xseq = self.sequence_pos_encoder(torch.cat((emb, motion), axis=0)) + output = self.seqTransEncoder(xseq)[1:] + + # B, T, D + output = self.poseFinal(output).permute(1, 0, 2) + return output + else: + # T, B, D + motion = self.poseEmbedding(motion).permute(1, 0, 2) + + emb = self.embed_timestep(timesteps) # [1, bs, d] + emb_uncond = emb + self.embed_text(self.mask_cond(enc_text, force_mask=True)) + emb_text = emb + self.embed_text(self.mask_cond(enc_text, force_mask=False)) + + xseq = self.sequence_pos_encoder(torch.cat((emb_uncond, motion), axis=0)) + xseq_text = self.sequence_pos_encoder(torch.cat((emb_text, motion), axis=0)) + output = self.seqTransEncoder(xseq)[1:] + output_text = self.seqTransEncoder(xseq_text)[1:] + # B, T, D + output = self.poseFinal(output).permute(1, 0, 2) + output_text = self.poseFinal(output_text).permute(1, 0, 2) + scale = self.guide_scale + output = output + scale * (output_text - output) + return output + + +class PositionalEncoding(nn.Module): + def __init__(self, d_model, dropout=0.1, max_len=5000): + super(PositionalEncoding, self).__init__() + self.dropout = nn.Dropout(p=dropout) + + pe = torch.zeros(max_len, d_model) + position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1) + div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-np.log(10000.0) / d_model)) + pe[:, 0::2] = torch.sin(position * div_term) + pe[:, 1::2] = torch.cos(position * div_term) + pe = pe.unsqueeze(0).transpose(0, 1) + + self.register_buffer('pe', pe) + + def forward(self, x): + # not used in the final model + x = x + self.pe[:x.shape[0], :] + return self.dropout(x) + + +class TimestepEmbedder(nn.Module): + def __init__(self, latent_dim, sequence_pos_encoder): + super().__init__() + self.latent_dim = latent_dim + self.sequence_pos_encoder = sequence_pos_encoder + + time_embed_dim = self.latent_dim + self.time_embed = nn.Sequential( + nn.Linear(self.latent_dim, time_embed_dim), + nn.SiLU(), + nn.Linear(time_embed_dim, time_embed_dim), + ) + + def forward(self, timesteps): + return self.time_embed(self.sequence_pos_encoder.pe[timesteps]).permute(1, 0, 2) diff --git a/motiondiff_modules/mogen/models/transformers/motiondiffuse.py b/motiondiff_modules/mogen/models/transformers/motiondiffuse.py new file mode 100644 index 0000000..136708a --- /dev/null +++ b/motiondiff_modules/mogen/models/transformers/motiondiffuse.py @@ -0,0 +1,41 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +import numpy as np + +from ..builder import SUBMODULES +from .diffusion_transformer import DiffusionTransformer + + +@SUBMODULES.register_module() +class MotionDiffuseTransformer(DiffusionTransformer): + def __init__(self, **kwargs): + super().__init__(**kwargs) + + def get_precompute_condition(self, + text=None, + xf_proj=None, + xf_out=None, + device=None, + clip_feat=None, + **kwargs): + if xf_proj is None or xf_out is None: + xf_proj, xf_out = self.encode_text(text, clip_feat, device) + return {'xf_proj': xf_proj, 'xf_out': xf_out} + + def post_process(self, motion): + return motion + + def forward_train(self, h=None, src_mask=None, emb=None, xf_out=None, **kwargs): + B, T = h.shape[0], h.shape[1] + for module in self.temporal_decoder_blocks: + h = module(x=h, xf=xf_out, emb=emb, src_mask=src_mask) + output = self.out(h).view(B, T, -1).contiguous() + return output + + def forward_test(self, h=None, src_mask=None, emb=None, xf_out=None, **kwargs): + B, T = h.shape[0], h.shape[1] + for module in self.temporal_decoder_blocks: + h = module(x=h, xf=xf_out, emb=emb, src_mask=src_mask) + output = self.out(h).view(B, T, -1).contiguous() + return output diff --git a/motiondiff_modules/mogen/models/transformers/position_encoding.py b/motiondiff_modules/mogen/models/transformers/position_encoding.py new file mode 100644 index 0000000..efdd6e2 --- /dev/null +++ b/motiondiff_modules/mogen/models/transformers/position_encoding.py @@ -0,0 +1,35 @@ +import torch +import torch.nn as nn +import numpy as np + + +class SinusoidalPositionalEncoding(nn.Module): + def __init__(self, d_model, dropout=0.1, max_len=5000): + super(SinusoidalPositionalEncoding, self).__init__() + self.dropout = nn.Dropout(p=dropout) + + pe = torch.zeros(max_len, d_model) + position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1) + div_term = torch.arange(0, d_model, 2).float() + div_term = div_term * (-np.log(10000.0) / d_model) + div_term = torch.exp(div_term) + pe[:, 0::2] = torch.sin(position * div_term) + pe[:, 1::2] = torch.cos(position * div_term) + pe = pe.unsqueeze(0).transpose(0, 1) + # T, 1, D + self.register_buffer('pe', pe) + + def forward(self, x): + x = x + self.pe[:x.shape[0]] + return self.dropout(x) + + +class LearnedPositionalEncoding(nn.Module): + def __init__(self, d_model, dropout=0.1, max_len=5000): + super(LearnedPositionalEncoding, self).__init__() + self.dropout = nn.Dropout(p=dropout) + self.pe = nn.Parameter(torch.randn(max_len, 1, d_model)) + + def forward(self, x): + x = x + self.pe[:x.shape[0]] + return self.dropout(x) diff --git a/motiondiff_modules/mogen/models/transformers/remodiffuse.py b/motiondiff_modules/mogen/models/transformers/remodiffuse.py new file mode 100644 index 0000000..5588c61 --- /dev/null +++ b/motiondiff_modules/mogen/models/transformers/remodiffuse.py @@ -0,0 +1,361 @@ +from cv2 import norm +import torch +import torch.nn.functional as F +from torch import layer_norm, nn +import numpy as np +import clip +import random +import math + +from ..builder import SUBMODULES, build_attention +from .diffusion_transformer import DiffusionTransformer + + +def zero_module(module): + """ + Zero out the parameters of a module and return it. + """ + for p in module.parameters(): + p.detach().zero_() + return module + + +def set_requires_grad(nets, requires_grad=False): + """Set requies_grad for all the networks. + + Args: + nets (nn.Module | list[nn.Module]): A list of networks or a single + network. + requires_grad (bool): Whether the networks require gradients or not + """ + if not isinstance(nets, list): + nets = [nets] + for net in nets: + if net is not None: + for param in net.parameters(): + param.requires_grad = requires_grad + + +class FFN(nn.Module): + + def __init__(self, latent_dim, ffn_dim, dropout): + super().__init__() + self.linear1 = nn.Linear(latent_dim, ffn_dim) + self.linear2 = zero_module(nn.Linear(ffn_dim, latent_dim)) + self.activation = nn.GELU() + self.dropout = nn.Dropout(dropout) + + def forward(self, x, **kwargs): + y = self.linear2(self.dropout(self.activation(self.linear1(x)))) + y = x + y + return y + + +class EncoderLayer(nn.Module): + + def __init__(self, + sa_block_cfg=None, + ca_block_cfg=None, + ffn_cfg=None): + super().__init__() + self.sa_block = build_attention(sa_block_cfg) + self.ffn = FFN(**ffn_cfg) + + def forward(self, **kwargs): + if self.sa_block is not None: + x = self.sa_block(**kwargs) + kwargs.update({'x': x}) + if self.ffn is not None: + x = self.ffn(**kwargs) + return x + + +class RetrievalDatabase(nn.Module): + + def __init__(self, + num_retrieval=None, + topk=None, + retrieval_file=None, + latent_dim=512, + output_dim=512, + num_layers=2, + num_motion_layers=4, + kinematic_coef=0.1, + max_seq_len=196, + num_heads=8, + ff_size=1024, + stride=4, + sa_block_cfg=None, + ffn_cfg=None, + dropout=0): + super().__init__() + self.num_retrieval = num_retrieval + self.topk = topk + self.latent_dim = latent_dim + self.stride = stride + self.kinematic_coef = kinematic_coef + self.num_layers = num_layers + self.num_motion_layers = num_motion_layers + self.max_seq_len = max_seq_len + data = np.load(retrieval_file) + self.text_features = torch.Tensor(data['text_features']) + self.captions = data['captions'] + self.motions = data['motions'] + self.m_lengths = data['m_lengths'] + self.clip_seq_features = data['clip_seq_features'] + self.train_indexes = data.get('train_indexes', None) + self.test_indexes = data.get('test_indexes', None) + + self.latent_dim = latent_dim + self.output_dim = output_dim + self.motion_proj = nn.Linear(self.motions.shape[-1], self.latent_dim) + self.motion_pos_embedding = nn.Parameter(torch.randn(max_seq_len, self.latent_dim)) + self.motion_encoder_blocks = nn.ModuleList() + for i in range(num_motion_layers): + self.motion_encoder_blocks.append( + EncoderLayer( + sa_block_cfg=sa_block_cfg, + ffn_cfg=ffn_cfg + ) + ) + TransEncoderLayer = nn.TransformerEncoderLayer( + d_model=self.latent_dim, + nhead=num_heads, + dim_feedforward=ff_size, + dropout=dropout, + activation="gelu") + self.text_encoder = nn.TransformerEncoder( + TransEncoderLayer, + num_layers=num_layers) + self.results = {} + + def extract_text_feature(self, text, clip_model, device): + text = clip.tokenize([text], truncate=True).to(device) + with torch.no_grad(): + text_features = clip_model.encode_text(text) + return text_features + + def encode_text(self, text, device): + with torch.no_grad(): + text = clip.tokenize(text, truncate=True).to(device) + x = self.clip.token_embedding(text).type(self.clip.dtype) # [batch_size, n_ctx, d_model] + + x = x + self.clip.positional_embedding.type(self.clip.dtype) + x = x.permute(1, 0, 2) # NLD -> LND + x = self.clip.transformer(x) + x = self.clip.ln_final(x).type(self.clip.dtype) + + # B, T, D + xf_out = x.permute(1, 0, 2) + return xf_out + + def retrieve(self, caption, length, clip_model, device, idx=None): + if self.training and self.train_indexes is not None and idx is not None: + idx = idx.item() + indexes = self.train_indexes[idx] + data = [] + cnt = 0 + for retr_idx in indexes: + if retr_idx != idx: + data.append(retr_idx) + cnt += 1 + if cnt == self.topk: + break + random.shuffle(data) + return data[:self.num_retrieval] + + elif not self.training and self.test_indexes is not None and idx is not None: + idx = idx.item() + indexes = self.test_indexes[idx] + data = [] + cnt = 0 + for retr_idx in indexes: + data.append(retr_idx) + cnt += 1 + if cnt == self.topk: + break + # random.shuffle(data) + return data[:self.num_retrieval] + else: + value = hash(caption) + if value in self.results: + return self.results[value] + text_feature = self.extract_text_feature(caption, clip_model, device) + + rel_length = torch.LongTensor(self.m_lengths).to(device) + rel_length = torch.abs(rel_length - length) / torch.clamp(rel_length, min=length) + semantic_score = F.cosine_similarity(self.text_features.to(device), text_feature) + kinematic_score = torch.exp(-rel_length * self.kinematic_coef) + score = semantic_score * kinematic_score + indexes = torch.argsort(score, descending=True) + data = [] + cnt = 0 + for idx in indexes: + caption, motion, m_length = self.captions[idx], self.motions[idx], self.m_lengths[idx] + if not self.training or m_length != length: + cnt += 1 + data.append(idx.item()) + if cnt == self.num_retrieval: + self.results[value] = data + return data + assert False + + def generate_src_mask(self, T, length): + B = len(length) + src_mask = torch.ones(B, T) + for i in range(B): + for j in range(length[i], T): + src_mask[i, j] = 0 + return src_mask + + def forward(self, captions, lengths, clip_model, device, idx=None): + B = len(captions) + all_indexes = [] + for b_ix in range(B): + length = int(lengths[b_ix]) + if idx is None: + batch_indexes = self.retrieve(captions[b_ix], length, clip_model, device) + else: + batch_indexes = self.retrieve(captions[b_ix], length, clip_model, device, idx[b_ix]) + all_indexes.extend(batch_indexes) + all_indexes = np.array(all_indexes) + N = all_indexes.shape[0] + all_motions = torch.Tensor(self.motions[all_indexes]).to(device) + all_m_lengths = torch.Tensor(self.m_lengths[all_indexes]).long() + all_captions = self.captions[all_indexes].tolist() + + T = all_motions.shape[1] + src_mask = self.generate_src_mask(T, all_m_lengths).to(device) + raw_src_mask = src_mask.clone() + re_motion = self.motion_proj(all_motions) + self.motion_pos_embedding.unsqueeze(0) + for module in self.motion_encoder_blocks: + re_motion = module(x=re_motion, src_mask=src_mask.unsqueeze(-1)) + re_motion = re_motion.view(B, self.num_retrieval, T, -1).contiguous() + # stride + re_motion = re_motion[:, :, ::self.stride, :].contiguous() + + src_mask = src_mask[:, ::self.stride].contiguous() + src_mask = src_mask.view(B, self.num_retrieval, -1).contiguous() + + T = 77 + all_text_seq_features = torch.Tensor(self.clip_seq_features[all_indexes]).to(device) + all_text_seq_features = all_text_seq_features.permute(1, 0, 2) + re_text = self.text_encoder(all_text_seq_features) + re_text = re_text.permute(1, 0, 2).view(B, self.num_retrieval, T, -1).contiguous() + re_text = re_text[:, :, -1:, :].contiguous() + + # T = re_motion.shape[2] + # re_feat = re_feat.view(B, self.num_retrieval * T, -1).contiguous() + re_dict = dict( + re_text=re_text, + re_motion=re_motion, + re_mask=src_mask, + raw_motion=all_motions, + raw_motion_length=all_m_lengths, + raw_motion_mask=raw_src_mask) + return re_dict + + +@SUBMODULES.register_module() +class ReMoDiffuseTransformer(DiffusionTransformer): + def __init__(self, + retrieval_cfg=None, + scale_func_cfg=None, + **kwargs): + super().__init__(**kwargs) + self.database = RetrievalDatabase(**retrieval_cfg) + self.scale_func_cfg = scale_func_cfg + + def scale_func(self, timestep): + coarse_scale = self.scale_func_cfg['coarse_scale'] + w = (1 - (1000 - timestep) / 1000) * coarse_scale + 1 + if timestep > 100: + if random.randint(0, 1) == 0: + output = { + 'both_coef': w, + 'text_coef': 0, + 'retr_coef': 1 - w, + 'none_coef': 0 + } + else: + output = { + 'both_coef': 0, + 'text_coef': w, + 'retr_coef': 0, + 'none_coef': 1 - w + } + else: + both_coef = self.scale_func_cfg['both_coef'] + text_coef = self.scale_func_cfg['text_coef'] + retr_coef = self.scale_func_cfg['retr_coef'] + none_coef = 1 - both_coef - text_coef - retr_coef + output = { + 'both_coef': both_coef, + 'text_coef': text_coef, + 'retr_coef': retr_coef, + 'none_coef': none_coef + } + return output + + def get_precompute_condition(self, + text=None, + motion_length=None, + xf_out=None, + re_dict=None, + device=None, + sample_idx=None, + clip_feat=None, + **kwargs): + if xf_out is None: + xf_out = self.encode_text(text, clip_feat, device) + output = {'xf_out': xf_out} + if re_dict is None: + re_dict = self.database(text, motion_length, self.clip, device, idx=sample_idx) + output['re_dict'] = re_dict + return output + + def post_process(self, motion): + return motion + + def forward_train(self, h=None, src_mask=None, emb=None, xf_out=None, re_dict=None, **kwargs): + B, T = h.shape[0], h.shape[1] + cond_type = torch.randint(0, 100, size=(B, 1, 1)).to(h.device) + for module in self.temporal_decoder_blocks: + h = module(x=h, xf=xf_out, emb=emb, src_mask=src_mask, cond_type=cond_type, re_dict=re_dict) + + output = self.out(h).view(B, T, -1).contiguous() + return output + + def forward_test(self, h=None, src_mask=None, emb=None, xf_out=None, re_dict=None, timesteps=None, **kwargs): + B, T = h.shape[0], h.shape[1] + both_cond_type = torch.zeros(B, 1, 1).to(h.device) + 99 + text_cond_type = torch.zeros(B, 1, 1).to(h.device) + 1 + retr_cond_type = torch.zeros(B, 1, 1).to(h.device) + 10 + none_cond_type = torch.zeros(B, 1, 1).to(h.device) + + all_cond_type = torch.cat(( + both_cond_type, text_cond_type, retr_cond_type, none_cond_type + ), dim=0) + h = h.repeat(4, 1, 1) + xf_out = xf_out.repeat(4, 1, 1) + emb = emb.repeat(4, 1) + src_mask = src_mask.repeat(4, 1, 1) + if re_dict['re_motion'].shape[0] != h.shape[0]: + re_dict['re_motion'] = re_dict['re_motion'].repeat(4, 1, 1, 1) + re_dict['re_text'] = re_dict['re_text'].repeat(4, 1, 1, 1) + re_dict['re_mask'] = re_dict['re_mask'].repeat(4, 1, 1) + for module in self.temporal_decoder_blocks: + h = module(x=h, xf=xf_out, emb=emb, src_mask=src_mask, cond_type=all_cond_type, re_dict=re_dict) + out = self.out(h).view(4 * B, T, -1).contiguous() + out_both = out[:B].contiguous() + out_text = out[B: 2 * B].contiguous() + out_retr = out[2 * B: 3 * B].contiguous() + out_none = out[3 * B:].contiguous() + + coef_cfg = self.scale_func(int(timesteps[0])) + both_coef = coef_cfg['both_coef'] + text_coef = coef_cfg['text_coef'] + retr_coef = coef_cfg['retr_coef'] + none_coef = coef_cfg['none_coef'] + output = out_both * both_coef + out_text * text_coef + out_retr * retr_coef + out_none * none_coef + return output diff --git a/motiondiff_modules/mogen/models/utils/__init__.py b/motiondiff_modules/mogen/models/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/motiondiff_modules/mogen/models/utils/gaussian_diffusion.py b/motiondiff_modules/mogen/models/utils/gaussian_diffusion.py new file mode 100644 index 0000000..93946c7 --- /dev/null +++ b/motiondiff_modules/mogen/models/utils/gaussian_diffusion.py @@ -0,0 +1,1281 @@ +""" +This code is borrowed from https://github.com/openai/guided-diffusion/blob/main/guided_diffusion/gaussian_diffusion.py +""" + +import enum +import math + +import numpy as np +import torch as th + + +from abc import ABC, abstractmethod +import torch.distributed as dist +import comfy.utils + +def create_named_schedule_sampler(name, diffusion): + """ + Create a ScheduleSampler from a library of pre-defined samplers. + :param name: the name of the sampler. + :param diffusion: the diffusion object to sample for. + """ + if name == "uniform": + return UniformSampler(diffusion) + elif name == "loss-second-moment": + return LossSecondMomentResampler(diffusion) + else: + raise NotImplementedError(f"unknown schedule sampler: {name}") + + +class ScheduleSampler(ABC): + """ + A distribution over timesteps in the diffusion process, intended to reduce + variance of the objective. + By default, samplers perform unbiased importance sampling, in which the + objective's mean is unchanged. + However, subclasses may override sample() to change how the resampled + terms are reweighted, allowing for actual changes in the objective. + """ + + @abstractmethod + def weights(self): + """ + Get a numpy array of weights, one per diffusion step. + The weights needn't be normalized, but must be positive. + """ + + def sample(self, batch_size, device): + """ + Importance-sample timesteps for a batch. + :param batch_size: the number of timesteps. + :param device: the torch device to save to. + :return: a tuple (timesteps, weights): + - timesteps: a tensor of timestep indices. + - weights: a tensor of weights to scale the resulting losses. + """ + w = self.weights() + p = w / np.sum(w) + indices_np = np.random.choice(len(p), size=(batch_size,), p=p) + indices = th.from_numpy(indices_np).long().to(device) + weights_np = 1 / (len(p) * p[indices_np]) + weights = th.from_numpy(weights_np).float().to(device) + return indices, weights + + +class UniformSampler(ScheduleSampler): + def __init__(self, diffusion): + self.diffusion = diffusion + self._weights = np.ones([diffusion.num_timesteps]) + + def weights(self): + return self._weights + + +class LossAwareSampler(ScheduleSampler): + def update_with_local_losses(self, local_ts, local_losses): + """ + Update the reweighting using losses from a model. + Call this method from each rank with a batch of timesteps and the + corresponding losses for each of those timesteps. + This method will perform synchronization to make sure all of the ranks + maintain the exact same reweighting. + :param local_ts: an integer Tensor of timesteps. + :param local_losses: a 1D Tensor of losses. + """ + batch_sizes = [ + th.tensor([0], dtype=th.int32, device=local_ts.device) + for _ in range(dist.get_world_size()) + ] + dist.all_gather( + batch_sizes, + th.tensor([len(local_ts)], dtype=th.int32, device=local_ts.device), + ) + + # Pad all_gather batches to be the maximum batch size. + batch_sizes = [x.item() for x in batch_sizes] + max_bs = max(batch_sizes) + + timestep_batches = [th.zeros(max_bs).to(local_ts) for bs in batch_sizes] + loss_batches = [th.zeros(max_bs).to(local_losses) for bs in batch_sizes] + dist.all_gather(timestep_batches, local_ts) + dist.all_gather(loss_batches, local_losses) + timesteps = [ + x.item() for y, bs in zip(timestep_batches, batch_sizes) for x in y[:bs] + ] + losses = [x.item() for y, bs in zip(loss_batches, batch_sizes) for x in y[:bs]] + self.update_with_all_losses(timesteps, losses) + + @abstractmethod + def update_with_all_losses(self, ts, losses): + """ + Update the reweighting using losses from a model. + Sub-classes should override this method to update the reweighting + using losses from the model. + This method directly updates the reweighting without synchronizing + between workers. It is called by update_with_local_losses from all + ranks with identical arguments. Thus, it should have deterministic + behavior to maintain state across workers. + :param ts: a list of int timesteps. + :param losses: a list of float losses, one per timestep. + """ + + +class LossSecondMomentResampler(LossAwareSampler): + def __init__(self, diffusion, history_per_term=10, uniform_prob=0.001): + self.diffusion = diffusion + self.history_per_term = history_per_term + self.uniform_prob = uniform_prob + self._loss_history = np.zeros( + [diffusion.num_timesteps, history_per_term], dtype=np.float64 + ) + self._loss_counts = np.zeros([diffusion.num_timesteps], dtype=np.int) + + def weights(self): + if not self._warmed_up(): + return np.ones([self.diffusion.num_timesteps], dtype=np.float64) + weights = np.sqrt(np.mean(self._loss_history ** 2, axis=-1)) + weights /= np.sum(weights) + weights *= 1 - self.uniform_prob + weights += self.uniform_prob / len(weights) + return weights + + def update_with_all_losses(self, ts, losses): + for t, loss in zip(ts, losses): + if self._loss_counts[t] == self.history_per_term: + # Shift out the oldest loss term. + self._loss_history[t, :-1] = self._loss_history[t, 1:] + self._loss_history[t, -1] = loss + else: + self._loss_history[t, self._loss_counts[t]] = loss + self._loss_counts[t] += 1 + + def _warmed_up(self): + return (self._loss_counts == self.history_per_term).all() + + +def mean_flat(tensor): + """ + Take the mean over all non-batch dimensions. + """ + return tensor.mean(dim=list(range(1, len(tensor.shape)))) + + +def normal_kl(mean1, logvar1, mean2, logvar2): + """ + Compute the KL divergence between two gaussians. + Shapes are automatically broadcasted, so batches can be compared to + scalars, among other use cases. + """ + tensor = None + for obj in (mean1, logvar1, mean2, logvar2): + if isinstance(obj, th.Tensor): + tensor = obj + break + assert tensor is not None, "at least one argument must be a Tensor" + + # Force variances to be Tensors. Broadcasting helps convert scalars to + # Tensors, but it does not work for th.exp(). + logvar1, logvar2 = [ + x if isinstance(x, th.Tensor) else th.tensor(x).to(tensor) + for x in (logvar1, logvar2) + ] + + return 0.5 * ( + -1.0 + + logvar2 + - logvar1 + + th.exp(logvar1 - logvar2) + + ((mean1 - mean2) ** 2) * th.exp(-logvar2) + ) + + +def approx_standard_normal_cdf(x): + """ + A fast approximation of the cumulative distribution function of the + standard normal. + """ + return 0.5 * (1.0 + th.tanh(np.sqrt(2.0 / np.pi) * (x + 0.044715 * th.pow(x, 3)))) + + +def discretized_gaussian_log_likelihood(x, *, means, log_scales): + """ + Compute the log-likelihood of a Gaussian distribution discretizing to a + given image. + :param x: the target images. It is assumed that this was uint8 values, + rescaled to the range [-1, 1]. + :param means: the Gaussian mean Tensor. + :param log_scales: the Gaussian log stddev Tensor. + :return: a tensor like x of log probabilities (in nats). + """ + assert x.shape == means.shape == log_scales.shape + centered_x = x - means + inv_stdv = th.exp(-log_scales) + plus_in = inv_stdv * (centered_x + 1.0 / 255.0) + cdf_plus = approx_standard_normal_cdf(plus_in) + min_in = inv_stdv * (centered_x - 1.0 / 255.0) + cdf_min = approx_standard_normal_cdf(min_in) + log_cdf_plus = th.log(cdf_plus.clamp(min=1e-12)) + log_one_minus_cdf_min = th.log((1.0 - cdf_min).clamp(min=1e-12)) + cdf_delta = cdf_plus - cdf_min + log_probs = th.where( + x < -0.999, + log_cdf_plus, + th.where(x > 0.999, log_one_minus_cdf_min, th.log(cdf_delta.clamp(min=1e-12))), + ) + assert log_probs.shape == x.shape + return log_probs + + +def get_named_beta_schedule(schedule_name, num_diffusion_timesteps): + """ + Get a pre-defined beta schedule for the given name. + + The beta schedule library consists of beta schedules which remain similar + in the limit of num_diffusion_timesteps. + Beta schedules may be added, but should not be removed or changed once + they are committed to maintain backwards compatibility. + """ + if schedule_name == "linear": + # Linear schedule from Ho et al, extended to work for any number of + # diffusion steps. + scale = 1000 / num_diffusion_timesteps + beta_start = scale * 0.0001 + beta_end = scale * 0.02 + return np.linspace( + beta_start, beta_end, num_diffusion_timesteps, dtype=np.float64 + ) + elif schedule_name == "cosine": + return betas_for_alpha_bar( + num_diffusion_timesteps, + lambda t: math.cos((t + 0.008) / 1.008 * math.pi / 2) ** 2, + ) + else: + raise NotImplementedError(f"unknown beta schedule: {schedule_name}") + + +def betas_for_alpha_bar(num_diffusion_timesteps, alpha_bar, max_beta=0.999): + """ + Create a beta schedule that discretizes the given alpha_t_bar function, + which defines the cumulative product of (1-beta) over time from t = [0,1]. + + :param num_diffusion_timesteps: the number of betas to produce. + :param alpha_bar: a lambda that takes an argument t from 0 to 1 and + produces the cumulative product of (1-beta) up to that + part of the diffusion process. + :param max_beta: the maximum beta to use; use values lower than 1 to + prevent singularities. + """ + betas = [] + for i in range(num_diffusion_timesteps): + t1 = i / num_diffusion_timesteps + t2 = (i + 1) / num_diffusion_timesteps + betas.append(min(1 - alpha_bar(t2) / alpha_bar(t1), max_beta)) + return np.array(betas) + + +class ModelMeanType(enum.Enum): + """ + Which type of output the model predicts. + """ + + PREVIOUS_X = enum.auto() # the model predicts x_{t-1} + START_X = enum.auto() # the model predicts x_0 + EPSILON = enum.auto() # the model predicts epsilon + + +class ModelVarType(enum.Enum): + """ + What is used as the model's output variance. + + The LEARNED_RANGE option has been added to allow the model to predict + values between FIXED_SMALL and FIXED_LARGE, making its job easier. + """ + + LEARNED = enum.auto() + FIXED_SMALL = enum.auto() + FIXED_LARGE = enum.auto() + LEARNED_RANGE = enum.auto() + + +class LossType(enum.Enum): + MSE = enum.auto() # use raw MSE loss (and KL when learning variances) + RESCALED_MSE = ( + enum.auto() + ) # use raw MSE loss (with RESCALED_KL when learning variances) + KL = enum.auto() # use the variational lower-bound + RESCALED_KL = enum.auto() # like KL, but rescale to estimate the full VLB + + def is_vb(self): + return self == LossType.KL or self == LossType.RESCALED_KL + + +class GaussianDiffusion: + """ + Utilities for training and sampling diffusion models. + + Ported directly from here, and then adapted over time to further experimentation. + https://github.com/hojonathanho/diffusion/blob/1e0dceb3b3495bbe19116a5e1b3596cd0706c543/diffusion_tf/diffusion_utils_2.py#L42 + + :param betas: a 1-D numpy array of betas for each diffusion timestep, + starting at T and going to 1. + :param model_mean_type: a ModelMeanType determining what the model outputs. + :param model_var_type: a ModelVarType determining how variance is output. + :param loss_type: a LossType determining the loss function to use. + :param rescale_timesteps: if True, pass floating point timesteps into the + model so that they are always scaled like in the + original paper (0 to 1000). + """ + + def __init__( + self, + *, + betas, + model_mean_type, + model_var_type, + loss_type, + rescale_timesteps=False, + ): + self.model_mean_type = model_mean_type + self.model_var_type = model_var_type + self.loss_type = loss_type + self.rescale_timesteps = rescale_timesteps + + # Use float64 for accuracy. + betas = np.array(betas, dtype=np.float64) + self.betas = betas + assert len(betas.shape) == 1, "betas must be 1-D" + assert (betas > 0).all() and (betas <= 1).all() + + self.num_timesteps = int(betas.shape[0]) + + alphas = 1.0 - betas + self.alphas_cumprod = np.cumprod(alphas, axis=0) + self.alphas_cumprod_prev = np.append(1.0, self.alphas_cumprod[:-1]) + self.alphas_cumprod_next = np.append(self.alphas_cumprod[1:], 0.0) + assert self.alphas_cumprod_prev.shape == (self.num_timesteps,) + + # calculations for diffusion q(x_t | x_{t-1}) and others + self.sqrt_alphas_cumprod = np.sqrt(self.alphas_cumprod) + self.sqrt_one_minus_alphas_cumprod = np.sqrt(1.0 - self.alphas_cumprod) + self.log_one_minus_alphas_cumprod = np.log(1.0 - self.alphas_cumprod) + self.sqrt_recip_alphas_cumprod = np.sqrt(1.0 / self.alphas_cumprod) + self.sqrt_recipm1_alphas_cumprod = np.sqrt(1.0 / self.alphas_cumprod - 1) + + # calculations for posterior q(x_{t-1} | x_t, x_0) + self.posterior_variance = ( + betas * (1.0 - self.alphas_cumprod_prev) / (1.0 - self.alphas_cumprod) + ) + # log calculation clipped because the posterior variance is 0 at the + # beginning of the diffusion chain. + self.posterior_log_variance_clipped = np.log( + np.append(self.posterior_variance[1], self.posterior_variance[1:]) + ) + self.posterior_mean_coef1 = ( + betas * np.sqrt(self.alphas_cumprod_prev) / (1.0 - self.alphas_cumprod) + ) + self.posterior_mean_coef2 = ( + (1.0 - self.alphas_cumprod_prev) + * np.sqrt(alphas) + / (1.0 - self.alphas_cumprod) + ) + + def q_mean_variance(self, x_start, t): + """ + Get the distribution q(x_t | x_0). + + :param x_start: the [N x C x ...] tensor of noiseless inputs. + :param t: the number of diffusion steps (minus 1). Here, 0 means one step. + :return: A tuple (mean, variance, log_variance), all of x_start's shape. + """ + mean = ( + _extract_into_tensor(self.sqrt_alphas_cumprod, t, x_start.shape) * x_start + ) + variance = _extract_into_tensor(1.0 - self.alphas_cumprod, t, x_start.shape) + log_variance = _extract_into_tensor( + self.log_one_minus_alphas_cumprod, t, x_start.shape + ) + return mean, variance, log_variance + + def q_sample(self, x_start, t, noise=None): + """ + Diffuse the data for a given number of diffusion steps. + + In other words, sample from q(x_t | x_0). + + :param x_start: the initial data batch. + :param t: the number of diffusion steps (minus 1). Here, 0 means one step. + :param noise: if specified, the split-out normal noise. + :return: A noisy version of x_start. + """ + if noise is None: + noise = th.randn_like(x_start) + assert noise.shape == x_start.shape + return ( + _extract_into_tensor(self.sqrt_alphas_cumprod, t, x_start.shape) * x_start + + _extract_into_tensor(self.sqrt_one_minus_alphas_cumprod, t, x_start.shape) + * noise + ) + + def q_posterior_mean_variance(self, x_start, x_t, t): + """ + Compute the mean and variance of the diffusion posterior: + + q(x_{t-1} | x_t, x_0) + + """ + assert x_start.shape == x_t.shape + posterior_mean = ( + _extract_into_tensor(self.posterior_mean_coef1, t, x_t.shape) * x_start + + _extract_into_tensor(self.posterior_mean_coef2, t, x_t.shape) * x_t + ) + posterior_variance = _extract_into_tensor(self.posterior_variance, t, x_t.shape) + posterior_log_variance_clipped = _extract_into_tensor( + self.posterior_log_variance_clipped, t, x_t.shape + ) + assert ( + posterior_mean.shape[0] + == posterior_variance.shape[0] + == posterior_log_variance_clipped.shape[0] + == x_start.shape[0] + ) + return posterior_mean, posterior_variance, posterior_log_variance_clipped + + def p_mean_variance( + self, model, x, t, clip_denoised=True, denoised_fn=None, model_kwargs=None + ): + """ + Apply the model to get p(x_{t-1} | x_t), as well as a prediction of + the initial x, x_0. + + :param model: the model, which takes a signal and a batch of timesteps + as input. + :param x: the [N x C x ...] tensor at time t. + :param t: a 1-D Tensor of timesteps. + :param clip_denoised: if True, clip the denoised signal into [-1, 1]. + :param denoised_fn: if not None, a function which applies to the + x_start prediction before it is used to sample. Applies before + clip_denoised. + :param model_kwargs: if not None, a dict of extra keyword arguments to + pass to the model. This can be used for conditioning. + :return: a dict with the following keys: + - 'mean': the model mean output. + - 'variance': the model variance output. + - 'log_variance': the log of 'variance'. + - 'pred_xstart': the prediction for x_0. + """ + if model_kwargs is None: + model_kwargs = {} + + B, C = x.shape[:2] + assert t.shape == (B,) + model_output = model(x, self._scale_timesteps(t), **model_kwargs) + + if self.model_var_type in [ModelVarType.LEARNED, ModelVarType.LEARNED_RANGE]: + assert model_output.shape == (B, 2 * C, *x.shape[2:]) + model_output, model_var_values = th.split(model_output, C, dim=1) + if self.model_var_type == ModelVarType.LEARNED: + model_log_variance = model_var_values + model_variance = th.exp(model_log_variance) + else: + min_log = _extract_into_tensor( + self.posterior_log_variance_clipped, t, x.shape + ) + max_log = _extract_into_tensor(np.log(self.betas), t, x.shape) + # The model_var_values is [-1, 1] for [min_var, max_var]. + frac = (model_var_values + 1) / 2 + model_log_variance = frac * max_log + (1 - frac) * min_log + model_variance = th.exp(model_log_variance) + else: + model_variance, model_log_variance = { + # for fixedlarge, we set the initial (log-)variance like so + # to get a better decoder log likelihood. + ModelVarType.FIXED_LARGE: ( + np.append(self.posterior_variance[1], self.betas[1:]), + np.log(np.append(self.posterior_variance[1], self.betas[1:])), + ), + ModelVarType.FIXED_SMALL: ( + self.posterior_variance, + self.posterior_log_variance_clipped, + ), + }[self.model_var_type] + model_variance = _extract_into_tensor(model_variance, t, x.shape) + model_log_variance = _extract_into_tensor(model_log_variance, t, x.shape) + + def process_xstart(x): + if denoised_fn is not None: + x = denoised_fn(x) + if clip_denoised: + return x.clamp(-1, 1) + return x + + if self.model_mean_type == ModelMeanType.PREVIOUS_X: + pred_xstart = process_xstart( + self._predict_xstart_from_xprev(x_t=x, t=t, xprev=model_output) + ) + model_mean = model_output + elif self.model_mean_type in [ModelMeanType.START_X, ModelMeanType.EPSILON]: + if self.model_mean_type == ModelMeanType.START_X: + pred_xstart = process_xstart(model_output) + else: + pred_xstart = process_xstart( + self._predict_xstart_from_eps(x_t=x, t=t, eps=model_output) + ) + model_mean, _, _ = self.q_posterior_mean_variance( + x_start=pred_xstart, x_t=x, t=t + ) + else: + raise NotImplementedError(self.model_mean_type) + + assert ( + model_mean.shape == model_log_variance.shape == pred_xstart.shape == x.shape + ) + return { + "mean": model_mean, + "variance": model_variance, + "log_variance": model_log_variance, + "pred_xstart": pred_xstart, + } + + def _predict_xstart_from_eps(self, x_t, t, eps): + assert x_t.shape == eps.shape + return ( + _extract_into_tensor(self.sqrt_recip_alphas_cumprod, t, x_t.shape) * x_t + - _extract_into_tensor(self.sqrt_recipm1_alphas_cumprod, t, x_t.shape) * eps + ) + + def _predict_xstart_from_xprev(self, x_t, t, xprev): + assert x_t.shape == xprev.shape + return ( # (xprev - coef2*x_t) / coef1 + _extract_into_tensor(1.0 / self.posterior_mean_coef1, t, x_t.shape) * xprev + - _extract_into_tensor( + self.posterior_mean_coef2 / self.posterior_mean_coef1, t, x_t.shape + ) + * x_t + ) + + def _predict_eps_from_xstart(self, x_t, t, pred_xstart): + return ( + _extract_into_tensor(self.sqrt_recip_alphas_cumprod, t, x_t.shape) * x_t + - pred_xstart + ) / _extract_into_tensor(self.sqrt_recipm1_alphas_cumprod, t, x_t.shape) + + def _scale_timesteps(self, t): + if self.rescale_timesteps: + return t.float() * (1000.0 / self.num_timesteps) + return t + + def condition_mean(self, cond_fn, p_mean_var, x, t, model_kwargs=None): + """ + Compute the mean for the previous step, given a function cond_fn that + computes the gradient of a conditional log probability with respect to + x. In particular, cond_fn computes grad(log(p(y|x))), and we want to + condition on y. + + This uses the conditioning strategy from Sohl-Dickstein et al. (2015). + """ + gradient = cond_fn(x, self._scale_timesteps(t), **model_kwargs) + new_mean = ( + p_mean_var["mean"].float() + p_mean_var["variance"] * gradient.float() + ) + return new_mean + + def condition_score(self, cond_fn, p_mean_var, x, t, model_kwargs=None): + """ + Compute what the p_mean_variance output would have been, should the + model's score function be conditioned by cond_fn. + + See condition_mean() for details on cond_fn. + + Unlike condition_mean(), this instead uses the conditioning strategy + from Song et al (2020). + """ + alpha_bar = _extract_into_tensor(self.alphas_cumprod, t, x.shape) + + eps = self._predict_eps_from_xstart(x, t, p_mean_var["pred_xstart"]) + eps = eps - (1 - alpha_bar).sqrt() * cond_fn( + x, self._scale_timesteps(t), **model_kwargs + ) + + out = p_mean_var.copy() + out["pred_xstart"] = self._predict_xstart_from_eps(x, t, eps) + out["mean"], _, _ = self.q_posterior_mean_variance( + x_start=out["pred_xstart"], x_t=x, t=t + ) + return out + + def p_sample( + self, + model, + x, + t, + clip_denoised=True, + denoised_fn=None, + cond_fn=None, + pre_seq=None, + transl_req=None, + model_kwargs=None, + ): + """ + Sample x_{t-1} from the model at the given timestep. + + :param model: the model to sample from. + :param x: the current tensor at x_{t-1}. + :param t: the value of t, starting at 0 for the first diffusion step. + :param clip_denoised: if True, clip the x_start prediction to [-1, 1]. + :param denoised_fn: if not None, a function which applies to the + x_start prediction before it is used to sample. + :param cond_fn: if not None, this is a gradient function that acts + similarly to the model. + :param model_kwargs: if not None, a dict of extra keyword arguments to + pass to the model. This can be used for conditioning. + :return: a dict containing the following keys: + - 'sample': a random sample from the model. + - 'pred_xstart': a prediction of x_0. + """ + # concat seq + if pre_seq is not None: + T = pre_seq.shape[1] + noise = th.randn_like(pre_seq) + x_t = self.q_sample(pre_seq, t, noise=noise) + x[:, :T, :] = x_t + + if transl_req is not None: + for item in transl_req: + noise = th.randn(2).type_as(x) + transl = th.Tensor(item[1:]).type_as(x) + x_t = self.q_sample(transl, t, noise=noise) + x[:, :2, item[0]] = x_t + + out = self.p_mean_variance( + model, + x, + t, + clip_denoised=clip_denoised, + denoised_fn=denoised_fn, + model_kwargs=model_kwargs, + ) + noise = th.randn_like(x) + nonzero_mask = ( + (t != 0).float().view(-1, *([1] * (len(x.shape) - 1))) + ) # no noise when t == 0 + if cond_fn is not None: + out["mean"] = self.condition_mean( + cond_fn, out, x, t, model_kwargs=model_kwargs + ) + sample = out["mean"] + nonzero_mask * th.exp(0.5 * out["log_variance"]) * noise + return {"sample": sample, "pred_xstart": out["pred_xstart"]} + + def p_sample_loop( + self, + model, + shape, + noise=None, + clip_denoised=True, + denoised_fn=None, + cond_fn=None, + model_kwargs=None, + seed=None, + device=None, + pre_seq=None, + transl_req=None, + progress=False, + ): + """ + Generate samples from the model. + + :param model: the model module. + :param shape: the shape of the samples, (N, C, H, W). + :param noise: if specified, the noise from the encoder to sample. + Should be of the same shape as `shape`. + :param clip_denoised: if True, clip x_start predictions to [-1, 1]. + :param denoised_fn: if not None, a function which applies to the + x_start prediction before it is used to sample. + :param cond_fn: if not None, this is a gradient function that acts + similarly to the model. + :param model_kwargs: if not None, a dict of extra keyword arguments to + pass to the model. This can be used for conditioning. + :param device: if specified, the device to create the samples on. + If not specified, use a model parameter's device. + :param progress: if True, show a tqdm progress bar. + :return: a non-differentiable batch of samples. + """ + final = None + for sample in self.p_sample_loop_progressive( + model, + shape, + noise=noise, + clip_denoised=clip_denoised, + denoised_fn=denoised_fn, + cond_fn=cond_fn, + model_kwargs=model_kwargs, + seed=seed, + device=device, + pre_seq=pre_seq, + transl_req=transl_req, + progress=progress, + ): + final = sample + return final["sample"] + + def p_sample_loop_progressive( + self, + model, + shape, + noise=None, + clip_denoised=True, + denoised_fn=None, + cond_fn=None, + model_kwargs=None, + seed=None, + device=None, + pre_seq=None, + transl_req=None, + progress=False, + ): + """ + Generate samples from the model and yield intermediate samples from + each timestep of diffusion. + + Arguments are the same as p_sample_loop(). + Returns a generator over dicts, where each dict is the return value of + p_sample(). + """ + if device is None: + device = next(model.parameters()).device + if seed is not None: + th.manual_seed(seed) + assert isinstance(shape, (tuple, list)) + if noise is not None: + img = noise + else: + img = th.randn(*shape, device=device) + indices = list(range(self.num_timesteps))[::-1] + if progress: + # Lazy import so that we don't depend on tqdm. + from tqdm.auto import tqdm + + indices = tqdm(indices) + pbar = comfy.utils.ProgressBar(len(indices)) + for i in indices: + t = th.tensor([i] * shape[0], device=device) + with th.no_grad(): + out = self.p_sample( + model, + img, + t, + clip_denoised=clip_denoised, + denoised_fn=denoised_fn, + cond_fn=cond_fn, + model_kwargs=model_kwargs, + pre_seq=pre_seq, + transl_req=transl_req + ) + yield out + img = out["sample"] + pbar.update(1) + + def ddim_sample( + self, + model, + x, + t, + clip_denoised=True, + denoised_fn=None, + cond_fn=None, + model_kwargs=None, + seed=None, + eta=0.0, + pre_seq=None, + ): + """ + Sample x_{t-1} from the model using DDIM. + + Same usage as p_sample(). + """ + if seed is not None: + th.manual_seed(seed) + if pre_seq is not None: + T = pre_seq.shape[1] + noise = th.randn_like(pre_seq) + x_t = self.q_sample(pre_seq, t, noise=noise) + x[:, :T, :] = x_t + + out = self.p_mean_variance( + model, + x, + t, + clip_denoised=clip_denoised, + denoised_fn=denoised_fn, + model_kwargs=model_kwargs, + ) + if cond_fn is not None: + out = self.condition_score(cond_fn, out, x, t, model_kwargs=model_kwargs) + + # Usually our model outputs epsilon, but we re-derive it + # in case we used x_start or x_prev prediction. + eps = self._predict_eps_from_xstart(x, t, out["pred_xstart"]) + + alpha_bar = _extract_into_tensor(self.alphas_cumprod, t, x.shape) + alpha_bar_prev = _extract_into_tensor(self.alphas_cumprod_prev, t, x.shape) + sigma = ( + eta + * th.sqrt((1 - alpha_bar_prev) / (1 - alpha_bar)) + * th.sqrt(1 - alpha_bar / alpha_bar_prev) + ) + # Equation 12. + noise = th.randn_like(x) + mean_pred = ( + out["pred_xstart"] * th.sqrt(alpha_bar_prev) + + th.sqrt(1 - alpha_bar_prev - sigma ** 2) * eps + ) + nonzero_mask = ( + (t != 0).float().view(-1, *([1] * (len(x.shape) - 1))) + ) # no noise when t == 0 + sample = mean_pred + nonzero_mask * sigma * noise + return {"sample": sample, "pred_xstart": out["pred_xstart"]} + + def ddim_reverse_sample( + self, + model, + x, + t, + clip_denoised=True, + denoised_fn=None, + model_kwargs=None, + eta=0.0, + pre_seq=None, + ): + """ + Sample x_{t+1} from the model using DDIM reverse ODE. + """ + assert eta == 0.0, "Reverse ODE only for deterministic path" + out = self.p_mean_variance( + model, + x, + t, + clip_denoised=clip_denoised, + denoised_fn=denoised_fn, + model_kwargs=model_kwargs, + ) + # Usually our model outputs epsilon, but we re-derive it + # in case we used x_start or x_prev prediction. + eps = ( + _extract_into_tensor(self.sqrt_recip_alphas_cumprod, t, x.shape) * x + - out["pred_xstart"] + ) / _extract_into_tensor(self.sqrt_recipm1_alphas_cumprod, t, x.shape) + alpha_bar_next = _extract_into_tensor(self.alphas_cumprod_next, t, x.shape) + + # Equation 12. reversed + mean_pred = ( + out["pred_xstart"] * th.sqrt(alpha_bar_next) + + th.sqrt(1 - alpha_bar_next) * eps + ) + + return {"sample": mean_pred, "pred_xstart": out["pred_xstart"]} + + def ddim_sample_loop( + self, + model, + shape, + noise=None, + clip_denoised=True, + denoised_fn=None, + cond_fn=None, + model_kwargs=None, + seed=None, + device=None, + progress=False, + eta=0.0, + pre_seq=None, + ): + """ + Generate samples from the model using DDIM. + + Same usage as p_sample_loop(). + """ + final = None + for sample in self.ddim_sample_loop_progressive( + model, + shape, + noise=noise, + clip_denoised=clip_denoised, + denoised_fn=denoised_fn, + cond_fn=cond_fn, + model_kwargs=model_kwargs, + seed=seed, + device=device, + progress=progress, + eta=eta, + pre_seq=pre_seq, + ): + final = sample + return final["sample"] + + def ddim_sample_loop_progressive( + self, + model, + shape, + noise=None, + clip_denoised=True, + denoised_fn=None, + cond_fn=None, + model_kwargs=None, + seed=None, + device=None, + progress=False, + eta=0.0, + pre_seq=None, + ): + """ + Use DDIM to sample from the model and yield intermediate samples from + each timestep of DDIM. + + Same usage as p_sample_loop_progressive(). + """ + if seed is not None: + th.manual_seed(seed) + if device is None: + device = next(model.parameters()).device + assert isinstance(shape, (tuple, list)) + if noise is not None: + img = noise + else: + img = th.randn(*shape, device=device) + indices = list(range(self.num_timesteps))[::-1] + + if progress: + # Lazy import so that we don't depend on tqdm. + from tqdm.auto import tqdm + + indices = tqdm(indices) + pbar = comfy.utils.ProgressBar(len(indices)) + for i in indices: + t = th.tensor([i] * shape[0], device=device) + with th.no_grad(): + out = self.ddim_sample( + model, + img, + t, + clip_denoised=clip_denoised, + denoised_fn=denoised_fn, + cond_fn=cond_fn, + model_kwargs=model_kwargs, + eta=eta, + pre_seq=pre_seq, + ) + yield out + img = out["sample"] + pbar.update(1) + + def _vb_terms_bpd( + self, model, x_start, x_t, t, clip_denoised=True, model_kwargs=None + ): + """ + Get a term for the variational lower-bound. + + The resulting units are bits (rather than nats, as one might expect). + This allows for comparison to other papers. + + :return: a dict with the following keys: + - 'output': a shape [N] tensor of NLLs or KLs. + - 'pred_xstart': the x_0 predictions. + """ + true_mean, _, true_log_variance_clipped = self.q_posterior_mean_variance( + x_start=x_start, x_t=x_t, t=t + ) + out = self.p_mean_variance( + model, x_t, t, clip_denoised=clip_denoised, model_kwargs=model_kwargs + ) + kl = normal_kl( + true_mean, true_log_variance_clipped, out["mean"], out["log_variance"] + ) + kl = mean_flat(kl) / np.log(2.0) + + decoder_nll = -discretized_gaussian_log_likelihood( + x_start, means=out["mean"], log_scales=0.5 * out["log_variance"] + ) + assert decoder_nll.shape == x_start.shape + decoder_nll = mean_flat(decoder_nll) / np.log(2.0) + + # At the first timestep return the decoder NLL, + # otherwise return KL(q(x_{t-1}|x_t,x_0) || p(x_{t-1}|x_t)) + output = th.where((t == 0), decoder_nll, kl) + return {"output": output, "pred_xstart": out["pred_xstart"]} + + def training_losses(self, model, x_start, t, model_kwargs=None, noise=None): + """ + Compute training losses for a single timestep. + + :param model: the model to evaluate loss on. + :param x_start: the [N x C x ...] tensor of inputs. + :param t: a batch of timestep indices. + :param model_kwargs: if not None, a dict of extra keyword arguments to + pass to the model. This can be used for conditioning. + :param noise: if specified, the specific Gaussian noise to try to remove. + :return: a dict with the key "loss" containing a tensor of shape [N]. + Some mean or variance settings may also have other keys. + """ + if model_kwargs is None: + model_kwargs = {} + if noise is None: + noise = th.randn_like(x_start) + x_t = self.q_sample(x_start, t, noise=noise) + + terms = {} + + if self.loss_type == LossType.KL or self.loss_type == LossType.RESCALED_KL: + terms["loss"] = self._vb_terms_bpd( + model=model, + x_start=x_start, + x_t=x_t, + t=t, + clip_denoised=False, + model_kwargs=model_kwargs, + )["output"] + if self.loss_type == LossType.RESCALED_KL: + terms["loss"] *= self.num_timesteps + elif self.loss_type == LossType.MSE or self.loss_type == LossType.RESCALED_MSE: + model_output = model(x_t, self._scale_timesteps(t), **model_kwargs) + + if self.model_var_type in [ + ModelVarType.LEARNED, + ModelVarType.LEARNED_RANGE, + ]: + B, C = x_t.shape[:2] + assert model_output.shape == (B, C * 2, *x_t.shape[2:]) + model_output, model_var_values = th.split(model_output, C, dim=1) + # Learn the variance using the variational bound, but don't let + # it affect our mean prediction. + frozen_out = th.cat([model_output.detach(), model_var_values], dim=1) + terms["vb"] = self._vb_terms_bpd( + model=lambda *args, r=frozen_out: r, + x_start=x_start, + x_t=x_t, + t=t, + clip_denoised=False, + )["output"] + if self.loss_type == LossType.RESCALED_MSE: + # Divide by 1000 for equivalence with initial implementation. + # Without a factor of 1/1000, the VB term hurts the MSE term. + terms["vb"] *= self.num_timesteps / 1000.0 + + target = { + ModelMeanType.PREVIOUS_X: self.q_posterior_mean_variance( + x_start=x_start, x_t=x_t, t=t + )[0], + ModelMeanType.START_X: x_start, + ModelMeanType.EPSILON: noise, + }[self.model_mean_type] + assert model_output.shape == target.shape == x_start.shape + terms["mse"] = mean_flat((target - model_output) ** 2).view(-1, 1).mean(-1) + # if "vb" in terms: + # terms["loss"] = terms["mse"] + terms["vb"] + # else: + # terms["loss"] = terms["mse"] + terms["target"] = target + terms["pred"] = model_output + else: + raise NotImplementedError(self.loss_type) + + return terms + + def _prior_bpd(self, x_start): + """ + Get the prior KL term for the variational lower-bound, measured in + bits-per-dim. + + This term can't be optimized, as it only depends on the encoder. + + :param x_start: the [N x C x ...] tensor of inputs. + :return: a batch of [N] KL values (in bits), one per batch element. + """ + batch_size = x_start.shape[0] + t = th.tensor([self.num_timesteps - 1] * batch_size, device=x_start.device) + qt_mean, _, qt_log_variance = self.q_mean_variance(x_start, t) + kl_prior = normal_kl( + mean1=qt_mean, logvar1=qt_log_variance, mean2=0.0, logvar2=0.0 + ) + return mean_flat(kl_prior) / np.log(2.0) + + def calc_bpd_loop(self, model, x_start, clip_denoised=True, model_kwargs=None): + """ + Compute the entire variational lower-bound, measured in bits-per-dim, + as well as other related quantities. + + :param model: the model to evaluate loss on. + :param x_start: the [N x C x ...] tensor of inputs. + :param clip_denoised: if True, clip denoised samples. + :param model_kwargs: if not None, a dict of extra keyword arguments to + pass to the model. This can be used for conditioning. + + :return: a dict containing the following keys: + - total_bpd: the total variational lower-bound, per batch element. + - prior_bpd: the prior term in the lower-bound. + - vb: an [N x T] tensor of terms in the lower-bound. + - xstart_mse: an [N x T] tensor of x_0 MSEs for each timestep. + - mse: an [N x T] tensor of epsilon MSEs for each timestep. + """ + device = x_start.device + batch_size = x_start.shape[0] + + vb = [] + xstart_mse = [] + mse = [] + for t in list(range(self.num_timesteps))[::-1]: + t_batch = th.tensor([t] * batch_size, device=device) + noise = th.randn_like(x_start) + x_t = self.q_sample(x_start=x_start, t=t_batch, noise=noise) + # Calculate VLB term at the current timestep + with th.no_grad(): + out = self._vb_terms_bpd( + model, + x_start=x_start, + x_t=x_t, + t=t_batch, + clip_denoised=clip_denoised, + model_kwargs=model_kwargs, + ) + vb.append(out["output"]) + xstart_mse.append(mean_flat((out["pred_xstart"] - x_start) ** 2)) + eps = self._predict_eps_from_xstart(x_t, t_batch, out["pred_xstart"]) + mse.append(mean_flat((eps - noise) ** 2)) + + vb = th.stack(vb, dim=1) + xstart_mse = th.stack(xstart_mse, dim=1) + mse = th.stack(mse, dim=1) + + prior_bpd = self._prior_bpd(x_start) + total_bpd = vb.sum(dim=1) + prior_bpd + return { + "total_bpd": total_bpd, + "prior_bpd": prior_bpd, + "vb": vb, + "xstart_mse": xstart_mse, + "mse": mse, + } + + +def _extract_into_tensor(arr, timesteps, broadcast_shape): + """ + Extract values from a 1-D numpy array for a batch of indices. + + :param arr: the 1-D numpy array. + :param timesteps: a tensor of indices into the array to extract. + :param broadcast_shape: a larger shape of K dimensions with the batch + dimension equal to the length of timesteps. + :return: a tensor of shape [batch_size, 1, ...] where the shape has K dims. + """ + res = th.from_numpy(arr).to(device=timesteps.device)[timesteps].float() + while len(res.shape) < len(broadcast_shape): + res = res[..., None] + return res.expand(broadcast_shape) + + +def space_timesteps(num_timesteps, section_counts): + """ + Create a list of timesteps to use from an original diffusion process, + given the number of timesteps we want to take from equally-sized portions + of the original process. + + For example, if there's 300 timesteps and the section counts are [10,15,20] + then the first 100 timesteps are strided to be 10 timesteps, the second 100 + are strided to be 15 timesteps, and the final 100 are strided to be 20. + + :param num_timesteps: the number of diffusion steps in the original + process to divide up. + :param section_counts: either a list of numbers, or a string containing + comma-separated numbers, indicating the step count + per section. As a special case, use "ddimN" where N + is a number of steps to use the striding from the + DDIM paper. + :return: a set of diffusion steps from the original process to use. + """ + if isinstance(section_counts, str): + if section_counts.startswith("ddim"): + desired_count = int(section_counts[len("ddim") :]) + for i in range(1, num_timesteps): + if len(range(0, num_timesteps, i)) == desired_count: + return set(range(0, num_timesteps, i)) + raise ValueError(f"cannot create exactly {num_timesteps} steps with an integer stride") + elif section_counts == "fast27": + # steps = space_timesteps(num_timesteps, "10,10,3,2,2") + # steps = space_timesteps(num_timesteps, "30,30,16,12,12") + steps = space_timesteps(num_timesteps, "15,15,8,6,6") + + # Help reduce DDIM artifacts from noisiest timesteps. + steps.remove(num_timesteps - 1) + steps.add(num_timesteps - 3) + return steps + section_counts = [int(x) for x in section_counts.split(",")] + size_per = num_timesteps // len(section_counts) + extra = num_timesteps % len(section_counts) + start_idx = 0 + all_steps = [] + for i, section_count in enumerate(section_counts): + size = size_per + (1 if i < extra else 0) + if size < section_count: + raise ValueError(f"cannot divide section of {size} steps into {section_count}") + if section_count <= 1: + frac_stride = 1 + else: + frac_stride = (size - 1) / (section_count - 1) + cur_idx = 0.0 + taken_steps = [] + for _ in range(section_count): + taken_steps.append(start_idx + round(cur_idx)) + cur_idx += frac_stride + all_steps += taken_steps + start_idx += size + return set(all_steps) + + +class SpacedDiffusion(GaussianDiffusion): + """ + A diffusion process which can skip steps in a base diffusion process. + + :param use_timesteps: a collection (sequence or set) of timesteps from the + original diffusion process to retain. + :param kwargs: the kwargs to create the base diffusion process. + """ + + def __init__(self, use_timesteps, **kwargs): + self.use_timesteps = set(use_timesteps) + self.timestep_map = [] + self.original_num_steps = len(kwargs["betas"]) + + base_diffusion = GaussianDiffusion(**kwargs) # pylint: disable=missing-kwoa + last_alpha_cumprod = 1.0 + new_betas = [] + for i, alpha_cumprod in enumerate(base_diffusion.alphas_cumprod): + if i in self.use_timesteps: + new_betas.append(1 - alpha_cumprod / last_alpha_cumprod) + last_alpha_cumprod = alpha_cumprod + self.timestep_map.append(i) + kwargs["betas"] = np.array(new_betas) + super().__init__(**kwargs) + + def p_mean_variance(self, model, *args, **kwargs): + return super().p_mean_variance(self._wrap_model(model), *args, **kwargs) + + def condition_mean(self, cond_fn, *args, **kwargs): + return super().condition_mean(self._wrap_model(cond_fn), *args, **kwargs) + + def condition_score(self, cond_fn, *args, **kwargs): + return super().condition_score(self._wrap_model(cond_fn), *args, **kwargs) + + def _wrap_model(self, model): + if isinstance(model, _WrappedModel): + return model + return _WrappedModel(model, self.timestep_map, self.original_num_steps) + + +class _WrappedModel: + def __init__(self, model, timestep_map, original_num_steps): + self.model = model + self.timestep_map = timestep_map + self.original_num_steps = original_num_steps + + def __call__(self, x, ts, **kwargs): + map_tensor = th.tensor(self.timestep_map, device=ts.device, dtype=ts.dtype) + new_ts = map_tensor[ts] + return self.model(x, new_ts, **kwargs) diff --git a/motiondiff_modules/mogen/models/utils/mlp.py b/motiondiff_modules/mogen/models/utils/mlp.py new file mode 100644 index 0000000..731117e --- /dev/null +++ b/motiondiff_modules/mogen/models/utils/mlp.py @@ -0,0 +1,13 @@ +import torch.nn as nn + + +def build_MLP(dim_list, latent_dim): + model_list = [] + prev = dim_list[0] + for cur in dim_list[1:]: + model_list.append(nn.Linear(prev, cur)) + model_list.append(nn.GELU()) + prev = cur + model_list.append(nn.Linear(prev, latent_dim)) + model = nn.Sequential(*model_list) + return model diff --git a/motiondiff_modules/mogen/models/utils/stylization_block.py b/motiondiff_modules/mogen/models/utils/stylization_block.py new file mode 100644 index 0000000..a221a5d --- /dev/null +++ b/motiondiff_modules/mogen/models/utils/stylization_block.py @@ -0,0 +1,40 @@ +import torch +import torch.nn as nn + + +def zero_module(module): + """ + Zero out the parameters of a module and return it. + """ + for p in module.parameters(): + p.detach().zero_() + return module + + +class StylizationBlock(nn.Module): + + def __init__(self, latent_dim, time_embed_dim, dropout): + super().__init__() + self.emb_layers = nn.Sequential( + nn.SiLU(), + nn.Linear(time_embed_dim, 2 * latent_dim), + ) + self.norm = nn.LayerNorm(latent_dim) + self.out_layers = nn.Sequential( + nn.SiLU(), + nn.Dropout(p=dropout), + zero_module(nn.Linear(latent_dim, latent_dim)), + ) + + def forward(self, h, emb): + """ + h: B, T, D + emb: B, D + """ + # B, 1, 2D + emb_out = self.emb_layers(emb).unsqueeze(1) + # scale: B, 1, D / shift: B, 1, D + scale, shift = torch.chunk(emb_out, 2, dim=2) + h = self.norm(h) * (1 + scale) + shift + h = self.out_layers(h) + return h diff --git a/motiondiff_modules/mogen/models/utils/word_vectorizer.py b/motiondiff_modules/mogen/models/utils/word_vectorizer.py new file mode 100644 index 0000000..68c5956 --- /dev/null +++ b/motiondiff_modules/mogen/models/utils/word_vectorizer.py @@ -0,0 +1,80 @@ +import numpy as np +import pickle +from os.path import join as pjoin + +POS_enumerator = { + 'VERB': 0, + 'NOUN': 1, + 'DET': 2, + 'ADP': 3, + 'NUM': 4, + 'AUX': 5, + 'PRON': 6, + 'ADJ': 7, + 'ADV': 8, + 'Loc_VIP': 9, + 'Body_VIP': 10, + 'Obj_VIP': 11, + 'Act_VIP': 12, + 'Desc_VIP': 13, + 'OTHER': 14, +} + +Loc_list = ('left', 'right', 'clockwise', 'counterclockwise', 'anticlockwise', 'forward', 'back', 'backward', + 'up', 'down', 'straight', 'curve') + +Body_list = ('arm', 'chin', 'foot', 'feet', 'face', 'hand', 'mouth', 'leg', 'waist', 'eye', 'knee', 'shoulder', 'thigh') + +Obj_List = ('stair', 'dumbbell', 'chair', 'window', 'floor', 'car', 'ball', 'handrail', 'baseball', 'basketball') + +Act_list = ('walk', 'run', 'swing', 'pick', 'bring', 'kick', 'put', 'squat', 'throw', 'hop', 'dance', 'jump', 'turn', + 'stumble', 'dance', 'stop', 'sit', 'lift', 'lower', 'raise', 'wash', 'stand', 'kneel', 'stroll', + 'rub', 'bend', 'balance', 'flap', 'jog', 'shuffle', 'lean', 'rotate', 'spin', 'spread', 'climb') + +Desc_list = ('slowly', 'carefully', 'fast', 'careful', 'slow', 'quickly', 'happy', 'angry', 'sad', 'happily', + 'angrily', 'sadly') + +VIP_dict = { + 'Loc_VIP': Loc_list, + 'Body_VIP': Body_list, + 'Obj_VIP': Obj_List, + 'Act_VIP': Act_list, + 'Desc_VIP': Desc_list, +} + + +class WordVectorizer(object): + def __init__(self, meta_root, prefix): + vectors = np.load(pjoin(meta_root, '%s_data.npy'%prefix)) + words = pickle.load(open(pjoin(meta_root, '%s_words.pkl'%prefix), 'rb')) + word2idx = pickle.load(open(pjoin(meta_root, '%s_idx.pkl'%prefix), 'rb')) + self.word2vec = {w: vectors[word2idx[w]] for w in words} + + def _get_pos_ohot(self, pos): + pos_vec = np.zeros(len(POS_enumerator)) + if pos in POS_enumerator: + pos_vec[POS_enumerator[pos]] = 1 + else: + pos_vec[POS_enumerator['OTHER']] = 1 + return pos_vec + + def __len__(self): + return len(self.word2vec) + + def __getitem__(self, item): + word, pos = item.split('/') + if word in self.word2vec: + word_vec = self.word2vec[word] + vip_pos = None + for key, values in VIP_dict.items(): + if word in values: + vip_pos = key + break + if vip_pos is not None: + pos_vec = self._get_pos_ohot(vip_pos) + else: + pos_vec = self._get_pos_ohot(pos) + else: + word_vec = self.word2vec['unk'] + pos_vec = self._get_pos_ohot('OTHER') + return word_vec, pos_vec \ No newline at end of file diff --git a/motiondiff_modules/mogen/smpl/body_models/smpl/J_regressor_extra.npy b/motiondiff_modules/mogen/smpl/body_models/smpl/J_regressor_extra.npy new file mode 100644 index 0000000000000000000000000000000000000000..9352bd03883d2aa179d18b95339be0537a2c89bf GIT binary patch literal 496160 zcmeI*eP~r>90%|jfuW{Jl7)pgGPgua9L1*AMFX+Gx0Nz=p{{MMu%=T}OalwHVP)c5 z7e+6GB}n3YTTV1=yN?kT1DcPr2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PFAdK>aZ5 zN_D2EeGwo)fB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+z|{rTms%g|>N4&nK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0Rrt8$SbevKR@5i2oNAZ zfB*pk1PBlyK!5-N0-YsL|94Z}l4S|!>pBb6eh3gCK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5)OA~0hA>~357mYKiXijjv15FkK+009C72oNAZ zfB*pk1PBlyK!5;&Njve>BjF|7wwRujR_DSK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0?`xrW9i`X$=Ms?GtcFo&e(9k zeAMU-0UZ+{K!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyKp@ZpWp|CQ zZJ4n&u=Cr-pY4BU#+ajltuN5wDvkgF0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PHWIpyb??5036QWPN}(dU+ZF0t5&UAV7cs0RjXF z5FkK+009C72oN9;K7rviYjOw9TjhF4_@YxW0RjXF5D2|M?Wh3-MRz>qI3)B*YJfoU z2&CWI=S2R=8lOwa6RA!J5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7dXWCWTf z9dBGUccpm`Ns{=U#`-=_|7;#hlEkSE0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5;&hzQKG-dRMF)+PZ01PBlyK!5-N0t5&UAV7cs0RjXF5D1w<+nLiH0MK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72n0~z$E8oSY|N>R z2e33H5gbNtdjK2oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oMOHK+iK5 z)@{33_pckR-*(Z$@8}4u=^f2=+oF@OP6-eoK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N h0t5&UAV7cs0RjXF5FkK+009C72oNAZfWVCt_z#wL1_uBD literal 0 HcmV?d00001 diff --git a/motiondiff_modules/mogen/smpl/body_models/smpl/kintree_table.pkl b/motiondiff_modules/mogen/smpl/body_models/smpl/kintree_table.pkl new file mode 100644 index 0000000000000000000000000000000000000000..4a2dd8e88ad95e5138a23319b0aaf472c3bf16a4 GIT binary patch literal 349 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 literal 0 HcmV?d00001 diff --git a/motiondiff_modules/mogen/smpl/human-skin.png b/motiondiff_modules/mogen/smpl/human-skin.png new file mode 100644 index 0000000000000000000000000000000000000000..74b4282a3da6c3435cdaea8a9a1dbe1fe517cd8a GIT binary patch literal 5299542 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 z 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�{3_I@6jV)BC@w81A=--k%;0xYJCr? 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 z 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

!Q7xE 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

3(_S~5kMBO>}CO`P8nAT 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

Lq!QNX3l&qfnoxE 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샮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 Ib)OwQS@06?(R+q;Sa0g`C0d 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�ccsOO4vPuz$>m52uJbJQ?Ls_gm!eAfttdFRH-2 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 TQ`DlBW5^Qq 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%0DQ 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

>?r~9aH4EYQAG@%u6Obvr`K)eI@?Dy**QmkJT1L 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

WyYs<0K>| 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℞USAqe4jo%iv>f*s4b!# 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�hx9$YZ&Pb+PegQhAkwTpD4p(oG76fHNWFOV%~ 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ⓈBynlFDBVzEJXp>rT|PZx>f=JR3Y_30uaI+1(#_gG7iMT6af zI)&fCcs}g-+dtd-+rN>JQ0|i59bcs%o^{SesSuvSqaPkW%pfk{a?Eu9Vfh2cTwPX= zh%q!U5UsX#Q%seX|8%|7h+&9$lVTyFPl&T6ve+uz7s?!-6O@n`EbHFIVC|AgMs#35 z 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�MX5J&`o z8e-Nem$-j76n6xjX2nvjMg}M1w-^z{8nu7<++-a4MfBkAxa2kjmBxpBMUf&|)T&+- zyQ}~%c9wjOCM^9ipIKVf)1hgibAFH)Z%wp*1+K>*OD*j;*1V-_NwQLBsUYG zA{@D;E)s0jWs832Jn?y28lD~)P*$5WvSRbIR1iUCKykNi^LMlqcj_YghmV&ulqf=&6=On3##0$@&>WrTry5c40gj<_SygbxAmo&;kD$9JszH zI1^#zy!2NhYf7*^F9=sI7%QT=mfKAPx@+WC5k9pn4MNZ(T%0h>)LJA^Gr0Go9xsa9 zEYp`tZM)fceunXh8PMBJL;ab=YMOD4?u!ca^W*jM+3B))91@qcEzsx-Nms|qmbZ8B zWh-I}Mu<5Ea+8Db>14xFTN1@qj|33q#p~T!=s0YF59ZI#`a-ch?-H?Oqf8-%R=rQh zjOtVmI!3ozAhh3i)NH%xR-``Zoy&AIm=P2g2&r6MRy%+E?z9iqwxz&v+>*U3G2MOZ>cy_u<6e%73*%RQ5NamVPf+l1JNbBl4je5swNfyG?t+;L9@i7RmL zLF-u3ncfl|BdA@GsSS}4>H`{!RJY-MqbPNtmtBO3o>peJG0Sz<3UTd)>NrhvP~$nf zu2x!_KO_Q_74N^sz#LukCKn{kX+o|uvRBkv5Yq-|FFbQ+5+e0B26M)jqgh#Nj6SS?{cw>_Khk^}dG!#?lvM9Uyx^(0 zC7It?BTiD6j!T@;f>~>xz3A*_oS3K%c+YeWHk+?65xrstJ0eE7HqSJN0KzZ>AJeRV z{d6)11@k=DEuscWsWxaH;w-sho`=X3TQ;-xmK@K#{}b6v8R2KRtKke+WMVQK`p<)C zN%R4Q(OXHVpJkhGQOeckULV?-(XT0@^)ASSCRs+j^DF0vT`oJDnmQ9+86S!JxC7>iVCp3lo| zyTq;6L|$eu&6#ieWv>yYfdh5N!$}8|b!Q^r;Tf`J@mdg3ULqBN_%_bdBNHwWEDf<`Enh8QuQW8vAe1o zoj+75fn?x?J_o$hmXGh&pARe`7brYOIDYU@>VUCWa+l*}{dgh!>z*6}24zpV3^G_K zE8jUC;w@!kuu-JSeK5nP4_)MKyPK5;+CUssb{>w%z*1Z}oHKBV%$S}N!}a9ukBbHw z*vcD<3=UtCc#%_5R7743jEa`vs9atszuLLmg97Ip&|wC zve*D_XHF=Lxbz}6)}{)^0tI>(Ua%#^VM&XQb}1}`l;I+ypAZFv`%QU&z`9rFlOiuT zBQ;|Y>-o&gUga<;4_tgfkYWQy45*Dbv-7Zd9BN8ttuDGCO#s3NIcgwsDcc4d+bV@~ zWUg*<0kkwI!LqZv?@wzu8>A?v!*C3_{qmo$g&~)# zTtrh9SR;dO_CpS2U%V|Unt2Ja@aV6XwOVx6IHEge$VbD-yJze#t6Yk~d6^?jNQ>xc z(cKX%LPw{^k({2vbpk6|7yVoX=Ps3fM!`vIR>m*UC^l{GPj~6Qe@oODOBtmj#VlO0 zfLw~|eOGp0EEwph$r-Y2jt7@HDBu~p6UZax7*89Ye^`5amjjz(7dcCL52OWHNm;Cm z?rQTQ3wL8(T58Z{2$Z0T?q5G_{rC$A9T7{BhgVdqW(0FTJV#a{lQ|v5oSwyu4(H%x zaPgdTmx(dmZfZ6!pJl>?>a0g*CUX=S`_X$3*9{{|@VRHVl$uz5M?mSFhupwY83Xxj z$$fXB3>07fPAu-F22PO*T5xvU*+lUE!;o#LFrFA(`ohJR2rcD}$|-|}`26EvZG3%N zdwavMU;<^2IH-PNSXVER45a-m>tg-f(ZHNK8`|5u-)rZo0Yye84rEEr{iTLdbgDH) zN>vxA-T%%1Ng^9%9%m8=sUfxM-x(banT!?%rZu8^20nYcEKq`Qg@N$nr>!5~q{y9c z$(40;)v&N%5SL<5)_@^vZIKv-!i<CW4d^6;unU-aMKBFd?E z8?T2)SyAN3-hl4NbyJpi-L?>S^7k##JTmXD%&6xqxim!Y0J($$Vv4d{j8}dU(#*?1 zp5n?myyoD5R1WB+*?c}6Bia@T9$CjI6Pl4d=P8%x$T_%JtZ0B@zVM*vVmyAjv**CT zne-1u4dGo+Zkw9UwFN_ZqcDI&`s29d#S1}q>^_KjJv8*aL`I=z_s_b)d0cJoyWcB| zFL&y8Gh19-yATJM@)WI@oj-pdM&V4~U%AE%w1n2B6PnJH^SHQG=-{2l9wj=!=SHIlv?mpRWW?0q}?>I+SUEXR8NhLHj zua^o2B8-;c!Z~N#O58`MSgqDS|FrYxpH^@8^gN6ZZY;|+E{O!A#T|_2*U!k2PngI` z_YQ_6bbA>@I7FitMXHsAIo{;DrnoX9oP3a)G30chwInd3ck?UY+7|XwBJU*@6 zKSD%a!?|6Pi#vq*J)Jo?|K;rSUf2J5ENGIzqyod3h4QuJ=L?ylhNzD7RJ2KdJwSyi z%5JToM&yXOncUmV|Ku{cLI_7^q#5os_L?&yjMQ6-B50T8zbVr(#hAhESc@Sd$nT^6 zdcY__;le2gzDd-!Kx`3%G3DAb8j0vvMCFs%zLtmwQ_Z?YE;!uF`Oc7;CW#a%_Le&l3*-uCmLlsg zkk;@w)z?;w$ZaknxjR|#c9V!`o?XIL0~OToKM*J&2%r5-%e%l<&-3u5MyXb?ydnLH zG{Bbba-sRBJD}+5rvva3&(b?cKqdnPiJ<-Khgk(7(d>eR*B#18%#mZ+hC~g-0dsce zi-%QzmOBSQoLpBC0yt+KBrMi;xmV}_jAiW!Qc$>#8;8~jt8c}8`A?@=5-uuUYYZ#r zVfFSFVlgwgu8W*yMMf$_apIj=w!43J+fCFx8VHQU)AP^_v#z&r0&W|!l9O?2Sv-6G zcDFK4naZ4Ue;6l?0gI^&OP~Vn>WaBD6%aM=$ z`Q-vs%wlrv=Gb4>?(fzgKV38qBZ^rvN%47afwoq?-6|f|afupgNhDhnosuYioo9)1 z%P0jdqK0AwR*76VXUj1Th5hHubEuJOLPk!l%9t<5?zG_+5urq*%f*~Bux%DZ<(#6C z!ET(~?_tE^d|pelG}E?ZZp((kxKkMcx&(0*3t%m)NbX_n$C=_BX3OSr889fSX0>95 z-0ca9OWSUCe*H9SP4`>gDKI7}|87IE6ma9-Za%}S#cRN0H`{JHmokAcX8J?31Hp7%a`?LnqUbry{- z)*8eTLC>Rst7Y6b2{a2tB(Es2G7ZYfFZA;B9W$&7P|1!COYDJHc>v@t0&#~*()+ior_5|yW_ULA=*I=((_ z`S=D}g+H5>b2E$Otc_vw;YJRpY&U#PssF>SuTgB8=a~?c&Et>}Q0A~&9of!#-0Nw} zx4&3_ej(zr+WGwQ=bf{42(HI@`q#F<6tO$fyf_oHWCmiS2B?1}M_qyxW3^d$_^pedD=wGqhifQP`GH26$zbjF*X&`RpxNh z6z=^?{Zes$;|^fNC5_8tO!dj*fcxBF5&8fGdZj0*0WZxVdg)$1!pFocP8#P{9(?=$Rb_~(XzZeD0EJhxl` z8+#na;&SOvA$G;@Es@um2u38pkcgCPe$AUt^v)&r=#G=}2pCdHxU**D14&totR!8j z_+8Te^MCvw{;EL?4xd`1d6-fKG6$+ze?6_;yn&+snFp-0GFo#7iaB~CXU2#WssZa1 zmZhJE+3A?A3B`UCibE*cGMV#sMThtEjOKmx zHl7cgP&jH~xNUlIwVZbcqZ<98^}j#xI-P(Rk~=8XcB(&P1j zOCE*5%Q5tIjfS{L)Nn-^Guz!4)E!McUYz7oq#9U7U~+N~;MQ2g`)AU_Nur1SaMhd@ z;8kX*a#_sP25f0pw1V>2N+9aYJb#Z_$2F_O^Kt|ilTn3Ns*UHa! z6Pb(!uE+sL1hY-cd02%@pRp5k^Km%t&2tQ?1JOFwEH5Z%c)?P!+=c9(sTf@KJj~?e zlFF^evrmGE8f(LXwyjCPQRMVhMk-O@{V*HD`qxiy(xCKgaFr^<6iBvV#rhxr3ZZ}r zzw1u@Q%%Ioj$OEod7#tvL&b4LF=eD-aOnq}(7-d?_m`c2{vE1o7l+WXuFSQJxI;rn z$K?cqrxo)-7#)>VF1IBq={FEOywU9Y%hp73sEFE_V@Qa?MMJ|dkP65KXSr#S24M@b zkD<2l0{XmW71E7AQU)?z0J8-CudSY6*49l9yP4E#bli{0fn78(la6G&F2DyJq+0S| z!PHhMwKmL)rE96sAD-7XyBTn3 z%(9J)?UYF@$A?oyTrs!?nr+1S90Nr(f&0_y+c*Eu_g4^eu&`quqk;G#QPQM}xv8l< znaP(L0ArT)vFq<#*3IheZteZU8?@&`O(`*1Jm+JnH0A!4AWCQ}X3oMr%z;;4mP70@ zKx?=nS=T_P3rX(-q>j8P4nQif!B&v@HO|NpPk1?Z6qY1DKrs)MJkfhqG>U5T@zd(MBD}KDt31o`JW9JXLHv~UhvM>(;HSf8>^adE*jW?Wun1MIkwCQ zZre>l%xV6e)!Vy`eYbMI%V}#iMQF0ifZD~Kku8Sr&gLcBL@wCl?i$<2(Zi z_e%yV&!2G|v6QCs8$<6#8rZV<`H$hEhziRhXL@Z7$l{^srUKNQ&EcZ8b-BDp1>)QO z^}|YQw*T#){d1IR-^pQm1`v&--1SV&kw~<|<@ib%apZfVjy+#rj;rn6>NpjV5*X0# z1N62SQcC?kf-1kxVP##@5-mj&;ao8@&w`$TWNj;4+Y}<@rOOB>f3YAl*?Bnj8)6^+ z^AqmC{`JGkvRP#$lj@o*_N#bSst>Bp)BpWty@*2w>a->Tz)cus4pb_IAUylNd^ldS zGhhy@_cu75*2r4LAc;ceS|AXopu8==)PrZL`G)8&?S98#wI-}JQ2KDFkpz|hyndc$ zv-|tJzkDGCafpVl=^W?tN#R?`eJlE@wuP9|X4JWgz8mJX&f}*Is}}-6xY2=4r6`3M zYz$2)c;gbRF3slaY4!er7=dDTo|j0Qaqfz`5wcS8U?ColW%_Y-{q`VxNbrTsb1v7T zA1V>i#QPqCK&#ako4*J){n_5F7PwE%Jl=-6q{t#QQZbUllJ`Qc|G40!8?!$jR@>rt z>+P=pJOl%oMl*$cbho7AH#-P3MYID%)SVs3eh6WQ69H#o2IN#$=GG^Ndqe->@dNH4^Z218x@V1t=hSMGBhE^-(ho<0u3Icd z(*nO~1{35D4%-J@;as%ML^xVkW|MafOO=sL(VqE0eI~L2BPkrO4l(HQa^We3hne)I zh`A8khGRc1#7X^Xt8(w%J#`3c&Ulu&zpR|QiwygT{$O`wj+Q_%%r5=3vfZsee)>|D zOB^g<={z+E1vpHkP}%EuOYctL^hpdTHqp=f^Ol7OS>&Y!e0t`ps5&u-?^@y&Jx@jx zkrg>>dFJP(G7d6+LthGMh0gfz?@M-qi=SqYJx z!6dc5y<>4#A*S;MB4ZFcX8~E@EThO`R-C|6aTmb)E@B*?`D`XBF$#Hq3GPWU3Ff;F|st>(rw z*3Ni8H9sfnIT2z5;U3Q{m+PF7P*i@&MIOT{vEBoMg0ATUx)P8JH;=zj0o)a;BxOGTMd z@VG|IF+~KL^K({>`G0?XS-HKrHmlKKP=c0t9yaL62NlfeByS>5mezb<1CcYyl8jp< zep*IJ)C-(v4eSC$hvh>4@QmuX^Dr+fA*dx4)!G^hQufm|K5N$69=%%9QggjT#?2fz zIecEW+}^CiEYTFd>F?FtpT9i2%ayQeMRU=p*AbzGC8mutLN8@|`}nl7Y}SAN;q@lt2e|}Kk$6Ga3t|*!3=`2A<2-N|x4`?`wV%4| zR2I0e4Ku%w?_Q%kzkJSx`)WKNwtWB1=Ih}E0LB92z8FbR;tSQAov$y=>}mB}ldDybuM2q1LbGhBp3}aKQ zo#llwKGTw&<;&(oLz>UVbxF_pGl`cZu+4;jkHz___fvw1Bvz6z=k>(LRxUH_CKFRn zgalA!H_YupH#xt4+GPKqgnZyVr&W-SY*}r5{qXasg`hhA-LA;RaqQk7 zq1Vl4`bE%&IKuV)o7Xtp0pD&eUV{nO_Ls+_@Vm!7;Uqqvd$@RG$b`=R*T4T?=0Aq_ zmiOv;`b=EHtROG*Ika)Qc)vE)jWY?#858Goo{}8;GexkEWDfT~hx=E)LnMNXpMPS< z-DEV+L=qZ_=6Sdn6On|41O&w86p&3y@#i6kzmgU2Fs_Gn2#E!TqM&#SEh$2?O^XyR2^=@UoyJ&#|i5bn)*kAgY ztX8YI6xdJ};_?uaK)h#veAzs9cWKcXue|0G%1kpYpe7WNmqm1PAX9x>@M6j-$p;$` z=QvLvT(O`?4w6#IUNmnEQRK?aW$x^i6P=l#BZM0L^>n=R^UKvW=N=8yoHq8Sa?)q- zHknfuGsfWt}i;^G+!LNL$V#0OZ@T63A zx|q$O&7z{TXeoXIDL2e+Zy-t(VT|z5rNQio_jFEM?{A7Xp^B2&^bV0j-ycw@7R8#l zP_1BjvFPkEI8!VSUXEQEZC*ItBB%KEbkajDm-|AP%xQYpokjx%G25bJPjNZJvASp) z9g&6iZGXlfiN#7L2yv*u_i9-Kamd9BMIdbjfx_Z0;IoB4TZ^1Dtfk;cIhu3&nN*6+ z=a;fdOEKI9#m4i~1#at2%m03!at{&jte;g51_*+HK_h;!lw#-4KkeLi+y3d_1db`? zKk^Qa<-ZA;-XA}$efy`VO_}4<{H^GLDz$ZH}((JaYt(zx}h7+Z{^bqH|qtztKIfw0G0!$r*= zlgnVQJBu<-=i%RP(c;brQvK_PwU6(rznI-VzCMA=ZZXJY{o7Bu{regD?H=W@1~Ewj zHK(Z5b+d^a^0M8nl!||TDl2cEM~WC2TF&~NR|)^|bLH6G(QH1T5N>l$5duo{cdn2? z^m_SlkP#(#vE>RRZE3yP*mrBl1ZGZiRSny0K7Lref7to?L(~W&Zz<9;2!AcO1^##B z$S*5q&xeaofF;gD&9Oh-ncdpO(GV#VMR?jc!^>qEyWqa#0B|s46?Y(AsxC5kCA990 zWmxYL*v{iX%u3TcGnLznpQ%>suSeu)b4Z&69tH}?^7bx@!bB9tJobnTV2#c?2;Ui- zP^;C47WnGr24%zq>lH33i$A-|k`}yhnT^rWuQXvgDV|WRijZ+qfq;KP^udgUOvmSp zGo#+$5#_Ok(_LaK+>6I9ysqsptGGLfhmE}Uk^0Q3`h3AcfMf?nah0Os0y8WH(>PB! z&+ysSly7fl%AuzR|7}=a&OZF}dI=@>kX#2kFeX`ns zXa+(Q=b6Vpr8u_|dF68sIS7_COrs!dSz_R55age)FR%G(ySPK_;#izoVzQsBiTpO; zfbi&o)0Z4LTbWhP*aMys{m;MK`t2_faWGCqGu$1;YN08Q%Rka1J4IHEtgwY|*(cHy1OH$MBfBw|DirB0+rpFuT3${wbVI z5wVFLC~~#Og>aP@S#{YkYnm7$k8s0ro`pZ3Gpo{?88XQ0c5^IrWgQ!o$GWU;1i->j z`Rya#rI8k1{p*L8J28JT2|$Rjof{Sl>H4M)kqG=IlC>}Dl$lep=egG zdr42zOp)*M^UK=DcSkyNaR{0rg<5>Sbk-L??^&Z%^XG~)G&=9cKrISkiQj9c_&vj& zRS_#PAQEiMpf*mTXj1qvMdq{PW#{kzf|!b-=Sbr1Wp&cP@v`yt1E!c7^(gKnr#s#> z|CK7(J16v%W@WwkIdT86@p?Gn40kW@rHJMuNvwp~NAbl&IqW2nl(txZJzR*c-1bFt z1?|L2^%yPG%`#ZAZmjvvE7re$N(}1;+8`iGNHvFQ98)bZEhxuLq{9*0eZ=m08 zLd{c1>GS4h{m0*I`SzEflOYO)GZ)UACf}jfY#fKJ?;kkNli?eNox0tVKwtNvA}`c9342raz(QHFXsc0QUmjkW#nMK7%xl=h3m3;aRiJ7 z8;uGi2L}xO45X^1?_-_^vM}G(lq?%v)Kp^vRmR`*`DNqWUA5Cs{C-V;t}onbs2mqx zD)#+p)>cOa-QR$b@@yy$6S*Yd;7gPSs??aphhm}s_`|cqQ1r2xV6nm9&6m$ymbr_- z+G-Qg2bY}Zgj3@8DyMacyyxuj%{kIs_KiODvzK+lV1k);aIL<4*j}1D?5tKRCseNI z>3K@}bBB~x96I_yJ6wudm@&qKurZv6=S5c{Z*ZCJ zzyHmV&`%c!op25c*9l?>7bQ7|*9#gSob|^~E6WYo>31z~EMbldP=ob$$8n!f@NjN= zZhT}T^KfKT1~Z|EjCa?74>s)ZJRG|E6x9J|LPoX6nTDZk8jMKM4kep1>gl%2m+?p! zkHyd|9R1UsR4sm9MG45|VH$)Hm)>7be+IN%*mOCxW%WhCdH9g0WR>!-+3_O=mdws8 zKE#-GRvAPa>Ei6qhmF@OE^9OZR*Ef~yEex2;qN5!sfbo*?zq&kqApa&?*l7do4dEi z=bx^!m7BRp#Bz;^8FG`%jHstbjprWnhVy6Jmc>rt)IEBE@f6wduVMfQq#R)~UQe5C z32Z5l@5H264vI%CISPd!%XXpY7#9)iO=p!CDqRs1%+xjrX-W%~Xs!O43Mq8F5NQD? zR6o>g(Cx#$cWo7l(-QfUDBjlhZz|B~{IcZqb>fM+E0Z}`V?tpbgBd$^C*Xk6;>t{* z!;V9R-hflKQP8xmdJZkQ2)rqFckw)Svvq@unnUTE&9-=PcDqB-x=2LFq02ZAo91^( z1)XTQzd@CK+ANNq?$3v<-+$9tM&aPX3`27PTw6CAUq6McYZUIRH;5rdIAfCoh(ekP zM<$;?F4){T?DQFt6|e~7^0=+b#m&b-mA7*~#BIxZaTQbyB>T_btzfw0L;H#Wz-rHb z`LDKai?xrxgd-bgP5~9hv9F*Y;Pc~>xwOTWWwrD9<%(ta*<_^iTr3PtCOGJ{)^FS6PL@02o zH3_(a7F7_lRA%?3?%<%(-|cZ6F_eJov%sBgC+-Dcdkb8NCNc{IpKuQs-HVZV$;O;c z<9Y7N)@vBpUl8jf>a&4&cN~Xm%l`OussfkSwS)s?&WN5s&V74((;%t6z1u`>O2^Ro z_49(I44OgF`P$J-G<+6Xj*(urKm0rawLi93|8P_$=re6;5+Jw`>!l^1M+*2^ zKVJ_gXmL?a7p*Y(r|u!SJQMY+wk9+vMXBXdYgHj(C4f{e>=Ec%E!%Bqm&NAnqCM$6X7)CgRTOnj)Cm+y*d<%D zXt7NJYr|(WfyN(mN~ouLmOTNprRg$Gi_D5emCiKtv#%^S)GOW3ND>k7oH5melq)L* z*u^1|35C+`MvP$NobBPb>m;@{JTn|(t*czMa}M-mGctKe`LGGh^>QK1 zjZ5Bpx)){_BG^vWu}T<6X$LskMUe1J#PS2dU46JX6qRj3Nr!T!HNh) z1M+d62kLW6&s|Lj=PhNTw||IK;K11=#zEbW$P!B#?*$Z;JV!E!+%&kwGspTi$M2O= zJW}!X3VbIWH8-yh${g<0g(z?&$1D5gadtCAhH=Q>Uk}W0Fs!SKJ8)35aG`7|YAr_z zO*)_Py_V|p6eplmk-2D8D6>Z-4v7xR5UqjUhInt5CQ?C7LvW#V&l9tRrth-MF084) z>*YdU;19$4h)akDr*nTjQ)JYF1#XKTeGVHGz|3Uck!c38IXrJjHaxp(cG2om4b{}& z^{ZnE&w>_P#J!T1*nk>8`vp^8*A-dm&Eq>-n0Sc5AN>d_;7IeO^zKo_!9`iirlL~4 z?pyCZV>=IJ;A&ZVoT67uM2AsuOTkS+9K+mSwtRepIC_-;m3=)aD7?o9gfRU)BJza` zS-Mu&MNxbPaUEj@N#WD)spz~gqf9svM?d1MsMQh4`^%q+WwGP)heQWn^950XQAeyr zWhCSLsgEE`z}Vq4j|0m(19iK^@v4<0m#Nk5s!Yi^WClxDU9B2Jin~8=7PiF zv%&(=2uZ%2g&N5>6avnO9vWPND=ML@m#u4}9-Wx?+El+s+L0E{rNlg~n9bs*9L`E7 zj7>bB`tt#-@-3XZ$h6jbf;f`8u3?DM!Y9=dq~f6tZ0qKAVv0T?-9qt8jCW$+M3Nw* zgg^{atYHr^e#F-%p}2)%ZYCjI;LGhFNP=x~>d+X|KO6RI)2@-MjB6|&J5rVwcNN+c0r&OO4;B%aHE*5&@H%P)eyaC0kTTzi%?_C#E67O#;D;%O+9QLmT2Uy{$9 zNEGvJMh!39re$nF+;@HZrq9`Ec3|9*yZU@?eC|Q(8!>wvh$%7jb1sApLB36o6t}uK zA^Gil%+F;89x1N!T8kH(s2l4g)^d!~XUfYe8j6Gj{|%gequ_kZm=Ec9StY9KUq5X= zzij#bPa>eS<^&VwwUh2E!AvPSLx%_kpq$16g(;9c&}-y^C%$S`}Nn;miG_; zS^E(&=*#MYj(+;{aU2mB1u>2g^o*b#!}`xZt=-<#3yU5^bIkyO?&;Le(KEp$?J{O} zf@kmk3@vNKEvAS%_0fsU(nUj>I*Xk=_7?XvX>y1$vEgxviqz|;FY}iqlumbXMDSGY z4k#Wg5L_^R(c^e<50s#}WX0#1#Mf4;)$?#c z^Re6V_7UV-(%jSkuHDm^GNp0`x4gY;XF5m)LF`tXx45Gi@r>DKTUTrUwT=St&u&@wm>uUWt6W-?3;k~Tksv8}J9KZKF>Ic@V<_2tLp(N;qLYi#zCUe!|M2(obm7?o*Vyb`%YPAA5XsP= zPyY_~7YfvC#!`n+$T?8jjRgFcE2m2Hjp zjP9@gdV$u^HOv`^9I{%GcXh&DvIv#DY@4zN8=L=`l)1<5_rU)0!QHVVUX?$upSk@7 zArW&V@tFmVE>x<=-~ZX4r#HuOD#iwaw`kZK1ZlYYk5f5aT&5N&=#dFcOqrS4^V9Y} zf46pjmow9I!XxHDKVQ06M0Q!y_tZ}-=Wge*+qy1TnD`ylUoYGK>EBtse?){xsV>?m zEn=NG{BI$O5>`$_k6%bX9eC+t7jc)LsasGHu;^_VvQ~;Hc@DK^bc%*t<6~+bv?KxS*9A95Z1!_al2a#R^e0(Uwb1z`Q%Jxm*!$aANs;17RRgiPnL* z2a=f1|C}|+=q_V~6Y=I2s&v)CDe{cZZD|!t9mnDEe329Km%HThyrHq@!p@(~mKK&> z4pJ@-+zCCc*-*Xi%aa@GXJn>R-ELPB9CL0dKF#i=NCj8s2y+aY}9Zi#W9o?Zhz%U;yiNk z#DQlWPR5>}3kaR}UG+XQLp9Vx-nZ$0;6fCL}De!)Z9r8oV^3Z)4fi z5Q#P(pHA8vU4zKchrV|?LetQXqIV)!HPBP7I?aw3B7Nw9vdEfFb&4`x5&yxuz4wTp zp@2oTDuz#$12WL(CTa)?j3jca8raET(5hw@4Y5GO+%;b6;`0Fhd+T~}5Do}@L%c$Q zS(CsjBFk=RARO*87qi{8P~kf;_FZUp=7ox0cXmBT6zI%i*1vvQSv}8vdH<$aNLwK) zBfak2)q~l^(YHoFGN-K&p=eHnz9nOA3uYL8=UNa1K&;}Q#T?{m#g?}>7bTX8JMNHB ziNaXJ0317M8$6RG;9l0C$snse&rLE>g~Qws)O88vNavx5rs?}X zfze&$#;QqFSk*6kpXK#Hxx9M?R5M~#`ApSTLnO_->&a*x)Y`|>=6bVAhkmUgLc70R zdSH@2*bn()qegU`l_18UzF0oK3&(83iJV5t=(c$sXGKPcf_{_3?qyvyd(#lRl%TH- zeovlJKaX9mFD{T9alHG>7wJiWV`E;0^ALM+CQE@sf%DWx>RZjs_6O#n?y4Nb>fdgP z?jX@q@epZ=sTm~&MXh0;0KGs$zm_teL76&#{BFy)@9un6%~&sjd_6Ct$Gipe8#`Vw z@Sv{6;)%pq!}(NOnm4d^;Y=DL?dAQ$h220Q*OW!h&ryQiJRik#xNLEL=1g{X?WP=d zMpS(L5LK-<8n%Fb?mgZ~it&`0y@ro}Ui-F&exg6VWJK#qxX{j7UPm%8eoJc>VR%O#q5GIQHvxvDdQOJh=9xMY5jq_d_! zyT|;AG#{H6q5iV^4Eg;0;SO8QfJ7t1{V`@N(SKRw(~wnavC(r(9e%zfQqT+v|32>y zLp{p+wm*JedQ~e=7HVRr0@3=RXBLiQQvv`y;Dle z9@Y@avH#D%JB6#+oox`&`0Vs1id#fmj}X(`-+UgqzhKa*nm-JX*wkm99dmG}UySo` zLmQXWqySN*dwM-r=CHY}9^trd{{7Wz756LmhfWYQkw_}U6{IQ|NJBCTkJIOun3s;; zZR`*Lzn-d_Rij=+x=Sp>mks2TP5aD&IV$%c6`@{vqg6hk?z{ipx%-~E+Ex(e}ajXaO+upr)P zyW2^Zhuo^bxE;IA33R`~bzZCW{RP#*Cbdrk@}m&-c6;-O`0XRG3AILsC9zm=Q_&5` z!82bPt4-)9KRCLamQw63(O{3HQWhc~L#_(^v%6x_B4EUUuL1OQCx{~}T%}Q$B@S4) z=I5Nqi5u}*Z2t1i^K@_#myw4rs4E?O%9IXeHw(pr!A`*e&SHZv7c)JWXW}YVSJ!tq zV9w)&tG?-Za0CX1t{^_}Vj(7pFL|XHfrSj0G*~Q}97|p3(Mfcu@Z@>$h{c>5@AP@6 zMSE>)WUcn@PIcsNwUn_@iJ1k?kcZ!LfAc|ZG32b{Ai=ZJZf|-aIhbA6z+^EWwA2Fk z!6L+0Zond+nwORj(TQ6w+dY~tWF{F*7m06<3a5o>bJOA@}m}&7b9C z4>Tm4@1C2!N>R(qX({ianD;0LFBnG36QVM#U?6>YwxMw45NEmHMK`fxq9`m|xKCSB z9IBzAI=t13yTLRZ^5GftlB7tju`tgHPc{hpewlfD9&iPB(!#9t-JfZo_d1*t?$BhW z*AYUI=hKHTRNXP|o`*9rJ(2xov0zlVtyP_}~$KlUm zKXw050A!`4{Ja>HxpFtMVf%T)m33OfXJT|gP>H#$a_1NeIFbgS)OJ7S>Y1ba_7hI{-b3|})7@-9sl&8xE$3Mh`j`F%` zNoJ+|Llzm`PXms~<^B=pDjO54aJ7Ee`Qr~49Nq3$ROB4WP#meQ8qbH7+uduP0jEK! zR?a;Z4BM&&TrI^H>4@kV=V|kJS=;U~q7*fx%x+%pZyq1?_0x|1u;u<1XgAg~Xp&tB zchkF>k(c8|=c&v!!%(om{Y}?UUS{b1Yt{O3N<>#6 zelaZd`;R}YtT$`RCb#W4oTO71KLcwL50pHZxZNS1F~wv|4PV0PS&$zp4D*NuY^Q4g z^s70|`r}iM1-i$y6oC+v&6Ads5IzjX!a($D`vb8bQ+e$?3kwJU97wkmg~Ky@o~KaU z9QKXpmo1>E1Yrk1%l?S0O}bch#zowg+!CY?z)`OHh`2Y>sMg2=9#E^>=o0O4*w6R~ z4mm_0ntq2>G{|!69l$r%ricI$qgq2$)^-tUF(PXmyOr$*hYaX5H6mkbibA4Thl>6r;5}2L&EMCN z)MkySVT!tcaqGI{q+OzjbZ;w96z?+#Bjebe0DxF24p+GxnWzuq4sdjP#gf(s51vCf zQO~XSH`Q$Of^0M`tqTS*PX3zebH>?)t@dYijiG3*j!-4V;Nor#hlSsRtK1r6e`&DP zUoW|BZ06-xcabmNH#(oy$lv^~6Kb9{j-nFk#qG`KSLa~*t}?k`%*dAAM)Rg2A;0&!EOvhVw03{Tz24nPJ_F6G%w7yTNVsSz@}<-eb2E=vS+yy; zVNTC?Zg20P!nos)8S(4|JpvDrCAjOY#xObl+#)e}CO|QZxTNnrvXE0hGFnTy+3*^Vn?Fe5koplv1(H_Y87D-#02*DqTtOCi6ExJ;PmzX z-eRz6S7fGy7U+*T{FQ?nR4^{nX%=8V?2#)Flkg6u^O+*k{V7To$tS-q0-E}O5oD4P zg4=TJVHV*+dE2~>OZ|FdruMwXy`9g8&BX=Wc7n3EZh|O zexw?M^>dj?Si&0T6|_DZ9zjyh6U4g^hqm?C$d0PmlW`o8Jv;yZFRmI$mOke|zg4Q) z{=mF4T$-eO&ccjVlSt?i8;BmNCnP@IbPdmB;UXg$AKJ1yZRGam{~U+cDPn`4XDL&69-u?NBIKL&)Oox^MV_Zps%IHP*uv0|470lEq zcqGB5F)EYsO%#QoCnSPICr9x1bpe#hi*5~jq0+v6Sx#>_gLEK%;{cNjF)FL ziwMD4KR>@Ldb1!&1-)?hzTj}NZ`tl55@*5>i8;&d23Pk83ao(;U`5Zg<^oAbsrNzO z%NgWH_%0Th3Y}2kbCPA<^nG*QI3egSoHviilNRQkk(`5(oiDwQ5)WVp6A>H3^Ux_6 zlSsX3w!>%3=L|zLCXy^7Hf#;iJp}2BO=v;eBaPQsmvS$Z>Ka8PFs3%qloV@*8m)rV zX&u7cQX?YHJlbkdDBOWdA27`H?&ire40#6f(|A2V8{E`amlPe@vdBeLv?K;zyM+0c9N$iJ!WpyOli+{R&PF}cy4q}r z$YdmQb%MLWXeE*0vZeP8LO9gH1;Pu8D@N}=+e@=5kKkRgcLi{(%R_UkD;rEgf7VIR)mJR-xXo z)AKp4t?p7shQ&;%k!bX@!hS}!Dshceh#3{Ek)2Cadui>e!WwB$Y00EG_a5xj>wOo+3`I?@#5<>UT4DSG!|ws)?5al2|bg z)=CvBcszbMjudWOCfV4WuJ}Q&qnf_aFM|{*Onazk6&HX(4hOl+h^or@DZ*zOhvL0^ z@rq(&9H$zQex4wIcd4gF%A%f7jk9QBcKPgw4`uHk?)VktJ7J6J!$Qv7%5pFjMf$H0_XImCv}vny{*SbjZ%%8X3;ZQ*iTJL7hPb(mH3@R?N zN{~5anG68LVXcc0gX27b`0tmc8KXWNU%e~l#0#wz)C8kTb$T(RNNa1{koCB__q2W+)@ZN*%(T0mh~ ztpEAD*>)41qgb(8ChoOF^QkDPv4|M>JeMtU$-;G_P9TXM$Xj7(SFF;&RGp}3+lk{b^7LPIX)74thqeyFI89cNw9$W9PiFx+^3 zNxWgxd?0^+xAFLL#~gpwnR&_jidg+2C@~ZtaSIRV`CnxH85R z>YEPRi2+Z+5TQyO7Xwy)|6?+@u2|dFSUzG9)A7EHr)Q-1ub=+zorgqOazzS1i_ad7 zb$@(Wz28y0SuCV_ztsC01dkYu%rRV`#2$~IH_y&x(NfAV_%9HsRA3#Kb+f)dU7$5h zjyQ@p+p@aobGuos=EN7(Q)`eO((sUrE3@PzQHG)q8>~CUZi1*mXITYuTRlo`DRZ-- zX|^C8yuO^$V2*9BBFC8ew>jKBOzKN^z)*l|i3((MTJNXuidKvIgFx^*_E{7>W>wb6 zm4)t@6eH+u zeF(>fgt!9(>~4ir4gCH&LV$5H;U4X#E?#7^h=O4LwC-v1JEcEAt&pli@r}wXCcI1vE*ydn;!`#P3xP^7<<1u9q zQ*COBeK9MFarF6?FXHTs!8HYHjjk%zev8LxY2KHKkaK!;kj3+t{~w z#XGjuMGvXw;oYx3ow5yn2OuGpB-+ut#GdW;X7=z1#_YtWi@r!C0t3pjS;F*y-y0&m zk`T-?QEi*k!N%z`hyCe&(CV(|{(AV(9*YAP8`gM!;Qr^?RFaFBi`RK}>pys*EKr?JeF3Wh3|D&&%V}>f5{Z&p+`zO~upD(LFF57NHn~ zCp!=HPesq0&rR-#uM4WqNcHtRPwRjF4H2D@;arn|z5a5>i4rQbGG^-Q>a&2?!+UIy zFG?*QDS$YsX)%)#JybMCCn=N#!e}DQTjZIK&p#CzQYqwBREUd1C_X2hn4(+>bjFNX zz9@PvNOg>S?m+;cIme!#FaW+uKpR=>Ahj{Fi}eOXc5SDIlE}t)U(W?xkoSc^}(JZ1p*f&f>CHMX5^c?>E zV_YI4D1czUXJHSm?x!>Qgvf2972-_1->PM4hYnIf}X6rKnp{ryo0=YM3&-SA?BZce)jWFOqPr$P@=STLrlxzvt}!a8qk8Nfe6676EGW?omSPizE4{e zFT|N#L^=2zUZxDxOLKpr$Bo^3L=ySg!o$=l20;?^d-u?p$nW1oa@#^^u-&mUZXq@u z!)$`MR*D-SFyESIxAwpPZ~wzz151mS%cdR#&n<&%eO&^*iiN6{xUEKEj3Tf&%zrIWd>IZ1>s~-lI5_;$4?NqV1+BmI%$Y40#9@_6+g0-`@^v?< zXE9sBhc}f^%)+sx94P(%ucxD=-ae$jHZz;gFRQn^6f0DK3L!V3NYfwz`H%gya({D- z;`y?2dv~YCdh>#n$|4jGBQ*}C)F|AOt6}tR3qEgA3-;Y?e@6aSTZHYSn%t1Bl)JTI=G(w>LEpzZbsftnK0? z2&7XiIZA~}t9L0Jndwwgo~UQ8?pDsjhbuUQOo`2A>)SV*uP?{^FpsWOYqxjD4c*?Y z0O7*SLKb^m-j&h4u{{nwD+_alIrt>f370-|Y)g871_qMuL`T+QYmPje7EaZK2I69` zBa^IP5W#_05uUAkv;-75Or7ohB%4`SWV!Gt_y9J)0smdL zyA7P{wJjnUFoRJjKn#+kmM^jB6BUNP8=i>@{2)m;ZM#|D55-^f*HdbH$4I$*eU|2D zXKu{bCB!mBH4S$}j_yK*?b}~MEyg9rhEO{=%Jh=Q=G&zVETku#tB zY3==+&11I}?_)^QWyJfAQ~|S&TLv3yTK4uA$)Pz05O0B#mEOpj5lp;$j0eF`J`r z>6#$IzS?wAR&Bl%0O_LEMVWA|W!JU;e&>(hJ;%#RsK{&c<-~%TmYC*R(p?>DV7g>P z-G+GYMxrncWd7(fG{XQ|^)(h$=B4gQ~ku0Ge!}4Fn}!G zbKylsEae~EcUh3s5EDX?J4rx{Ci8lxMO**|-laC&@lDhrVKbA9u3$jx*_ZzL^dG<5 z^8U?*RIS-KP8a3W3WR0)?07~oS2TjNF`$~ zbcJhAh7(5H5E+d#hB?F8g+)9m322IpAkDH?ol}e#lCTGNn$rT#$Xr&uSVTKGZRlm= z`Sd&Z{*jhvj5*psH#c;+@+vHhbN$*mr?vP;6kHF|+Y{Iq@gQ%Fsn7L02G` zSwFLn8|gf7p?^&oyfYk$81A=qQRJRkk?5HB5gmyX&lY?JiVo6Zj>|BQg)&A5P#`Ee zPYm%TNZYkMHpvjj71ac_C2_2_dXC>zoNvl!}NB)lN90vT&@XNZFA@ zYY|Hc)bp}lj2ZJhtQ;>Zw>L!2`1#sj9+PuEzPt{$t7EdQK4+|>TitJ^JREBu*2S-3tAL%mS3>Ew}OzO&|&V~{{rUqG-uJSBEOD@%6+1Ow7$1 zh_1Gx&Z1CwL`;UvPqnH~*L;%SC-Tedc9WrEK7Kk4ur)VUZ8zNE5POk8aUALy%S@up zQrtC~u+?(_b&dF$*-yn6&Ew^>YQ`C$@6o#gBagwEY_)MnDY4M9dUQ# z>O{s|u9DO_oG4B4`vet{{~gVa16b_Bc>~3niR{E#xe)e>rJjmob_ebdg-%OCE=OAk zrAbUA9zpR+5Wv({-MqQpoaAgS3Mt#>Jj#hrWSW`H!|~()S3uMby@9veu)@4Q>1G@Pl@GeyknhUjnUJKJ_DWo zGL#jk+#D}Nc>A5QfPTrdc=prgzKcjPd-r(W*B7D^@#linYKlO!v=i}}^+Y_go1xbb zUH2gavMEAjh@{OkiQnUZVYu|6+R}}th#KY26cLwgqXBp(dZQ_RkKbLv-zD-14I6mx z>#|-*IihxJpAmab86_ds=iXWK5}1@YXXBh=K#av*5`}8>`Q^R9-O1%f+nYIpH8iV>&0YNEVx~r?qdtxvB+9S|K}yaSZj%0%!fg zp|4O|)t!32jq$u73^#OObT6`~2w=m>bx$)c)&qiXe=s`YyFZ- zsr=ET1|#lo4(9rH(E!x2Az#Gv?7cAQk1t;woM*~;92ySh9Ahmj;jUM+Ii7cQO)IIVyF358-0 zF$N+KII!TLTsR>t!D_8`{Qj?I=V1*Q%S7zC0=s&X!Tg`omrN5#E{~cxV=+T~;dxvg zxcdtZC3kJiQr%TSN64IxTRL8zi;X6(5S20#QWOi&(mYBb#0$;eYhuNS*(E-*Sg69d za2L+C>3r(1htPiGJZ!n&q4XRo(&U7}`DCMukl?~h&q}dr7&2~Ja!imO28aWbXsm>| z>R&&dio#+?%0&yr+WvI)?z&o87P+na>*-mLx4Vm`y8mn!jAC*mFY9LGa5TJf*15>H zBIk@6SqK`6Ih}<}6CvI*j(QBo_H!{kM#_v!!*}M~Ks`Q>JsfDoRl{{ztUsR`st_G) zwSv_0gd3r2fK%auB{tmO*_R4YX5eL_N4qTUMqss}w;yFAxEzU z-jcb?7~)xLP6DAL5Ca1?`!;=f=c`@h=ymw)REl70r2q85+w0jhfR?(daN z<>n2Fs|K--R5wl)=!3<%<(QbwbA^S=T$H6X%Jvp&=~~Q) z`^DhF5)ROvCO09I7~wKt-{7LYl!ENa645U>%Qam1rO@X;r)*uKOz8?F0Rp*AbX``U z^oH)_6t@7%!THDEZ2Rrs0L%P_W}k>O;NHz_|J#4HF@|m5e~W_Mrk`(X-XQ_d=* zd_BC;wIrNmyb78}cQ!aaFa$qcs`5$qYArs*D8+2uyoQ78&m{ct2nuCzPrD)%g(mbY z#O3~m<>>=M!xHp_!Sg)mL(GUYh-_Gc6&n&dRk#I~&BZ>dh0+3$L&6Dx<02RCv@z57 zN}(W^WXJB!|L8XM-S0HUI{hLf;j>JbnVNxLbSw5b|FR4=on2 zPC`cjVrX{Tv=|SOFoy?$EWDtKlcPcIH7ql0Lh9$C#ZXRp5p8Fl9nnqG`s+)J<7JScmf#1sq+93S0FXE~xqNix8R+|<5qK)_-)!!x@q^K9`l@K+C>R%y^)AL{y7H>Bft^lRYf#u*5 zevE6RS*eIx80mREg}}_XcVCdSl;LbCx}s=F9+8JG_$48(fc$9dO&QCaf6R0DV|R2p zo+F;5O91W9LPX{(8`w$LPBX#HvgU z>|eYxK`r4(<-$7~{Zg6T$x`QG?d=-`?dTtmN5oIm5`+Iz&49;e7gLJK`JbaQ^$yi` zd3T3mX$nN0-{Wj&jfogF)(xhi=)B%RYZ5GiYC@be>7!$GE7N@7-A|is@%m$g@FV6! zXNagU7*=FL7Rcf3sio>!s(C?n`i#?Q7(3qMD!La@_#U6Rq!(&JsieO!GI+Dk;unKWpj!$#GI9lC0zDSpylK zvso7>8$BOz=P?qdC}PlR@#K_s#Tk`i7{@dlKBH6IBhFkqb_gEew1xAN5mFLFai*6@ zXn7t&Yt8J#=GPBfK7NxRnCG2GusLpB@tv%FM5^+chXIu=F(}BNI)7xy@OeeMy;XNED+K9WhJA z944ZPEJYb9Mr2IQk4f-wGu8_NbHB%|=ctB=gcz@<=QU4rlf!xX`Lf;o%)#flyuFKH zP^$lIbo6%CDPA3b#w8-vgzlU{WRP6h{ff+s(`qQ7+eFn zVOnvD9quGYvtzywSN2>s#7ab@1sBXb8?~?;)5i1DiD0Y);B+6S8(RjQ?$wPY)=$3+ z-`nrmu_Us_OG=Rn-^;lIy- z5vnk%?3ehASXx6MaC_6;$%tf{6Br#P5%k$b!l1z_$8`DqG@RVG?}~V9m?==a($NoP z>K?`R1>c7in6u8^mixOKHI|lk8!h5!X$DR>eW#?lC}&KMoTDggq?jB1Tx|&=T%xVe zXmKS{4++Ly49N%-cQ}Wrpht`k1m6Ai@ScbBw?r@?sfvaZCw#9#3+_YF!z8@wyE4!z z`l&c_8on6AQIpu4=D&usol%lwe|aQhnj2mtr(!AXwA7g8aUS1rZg|gweH9|J<{Tmf zs2i5X-lgpS8KJjrG2>Wcf2-&_d><|_jW~N!;=Eo04Ud96iMoo+0lpJnL_G9! z`Lyx$_?mGzy{ln=-k)wBwvH%{+g;>ikxx?ZWDo+E>13SAzq$vlNfA@iG`CemDUHK; zt|*3)Df&FkWRyqj#DDr<|NUQyGt;tT4x#RAt5R?0rKXTzaCY_Qm(_K#<#yL_ggA1~ zjAt(Ws*6KTNIDFNWM0;k-96-_vGwka_j%YtX95Oy*}avKkWvtKSBRAAt~SRxeIVo8 zE{I(gOoJJ!D6pq8&d!V5YGP=?-;Md&V@_9#rYy8^>}XaO6cK?EEH?3_2kyKr$c3eP z=Ji66K=l-c;lR?+b)kXUE%as&B1OmoE@&i}y$a^AMf*t`8Yg-O;z> z*dvPynMLFEw9ya6Ik<2F3m+hvsg@Oy1j|&q(b$yL^xYLUzkT>}emWvvXOfwgA-?q9 za3=LYgEJqH8CTu$=F7)-W!4!AuZDPrg5O){F%T09C=+zxXaRn~y|;*kNV&(lbj&UY zq{wJaIfUn7^Ee}ObaY?zCdDZ8h6cnVUffNa=Wff}M?^dflY+9YtIgLF3%%u{(B=SV zAQx>~3pTP%`*ZF3UG zr`H#_gZlom<(~dokTqNw;|Rsc@0)HDx`O&pw(evhxUN!#s?GpzN>1Q)HJj=C#<@vM z|Ja{a-oERO9y1XdPA9i4Z*ML%qxfrCB}&oYblWuaShh_fwYJ{E@reA{aM+?lO=SvOcO<7AKIh@F3d)rxt)*I*azAANuCchb;pg-D_0w~}#|#Ig&c7j* zw`1BLAp$}F&|eQ*wwrZEL%m);KrY4eXW_zMJhaXsM+BmU7 zazXbfmKMdVEt?{S=$O_0vcGJ3d&k{~@lHm+w&bS2-8^yxg9fkhqE}^qrh!T+KIERh zOr3DTxAd4`T#?taXyI(kfHDoPYE#a(BB9rs= z)DXt{A;Fk(3a8g_jrU_Bt%ZZHNt9h?w}M4o1tQzJ_a1`_Ej~kZi}M^qw9;fveOX?$ zOT>YOUZqOVZqw}i^Y6CY--DF1u5#dW`Kj#E*Hc(zE{XYjP$0r(YUlexyd{z9Db69@ zcf8LKY8dMT2xJBXJF16ji(F})7faw;A%+$KZiFDfQSCthn90dh*VT@nf10fus1-Gw z!vbm)~d0>c2N;1ATw`^KgH6 zq-i2vC~itMZ6YuNSugTSq7btF%#l@cFC+Sc#4QdA?R@z=3zv2f5f&|^+RdGOP8e#4 z5OG4@CF}S?ya?B<`hYPm%ka8wk)b=Ib~1=hIqP9|C+p$de_ZHnDH4QPu?C?>MSNO0 zcR7$Fc$6!243Dop*3;Z#R2b|lL?GC|kO@f{C9|Y|EID95Tff9z6T#}P0VCa2} zWF5{!8W$wp@9_dOb7`0P(_n1FdH4c&T;20B4V{NC#cjr-D$jH%)P%EB?;jW5BMId6 zof`6;z4kUn&LJ9Sg2K|)P4g*YU>j&g^E|xXKMuW@IYOZ|i0(TmjTD%e*}{x&_Ia#L zh3p<7rsI2M1$3vV73k6)%E-MgBQ!q%8Pi=Vzi52w|^#8O4;ELLq=e<7C^=daHX zP7%T!vA%e1oHDsdk+l}I4GMhu+*xb>-KXe~k=*4|XT*t!u{{J?Ni;)|V@Yv`ZROmI zVvi^4jWvmeSI6rwPCqil;?XfY8HbYI`PvelWm)a~`eEz)H_axLy^j0Q=-9`f&Ba&D z+TzZ3GV5Zt-hCOpEXkD6^%>3-r>Cf;;Y142QCL^(Pe0GsRnaXnK!HFKeN_-q=l-(w z?E~%k^f&|JqDREeIDo1yZS`n{ z?WVlz<^HDS)J(H_Q6kpO%?4byzaCZ)6~WramQ_x3iQ{!%PGca(cz(I@q<34^?Uy?( z5jRTpSs8@pgSBC)Ha>s&ypweXO@;S&QG(?xPVWgt5p#d~@4elebcp+0-`#mwNn}Yb z>HT?F@#nXAhBxoSIg_Me(~8-oiHvh}EbzIYdHr-Oq}O(C2GWw^O`?<^KBif%oF|74WdGh zRT{CU7@Xs-blT4#Sipc2(dqGdtM}O-Fl=ukP+IS1#q9j~hppd!^S%bu5JshCv6T8) z^Su&Hnh~qYdS#{vYSv&?(Tj0Djti;Y4az|?sEKS}m&MwD`H%nizm}v>G7ge(3G^R- z*m!pn~>-5Q^#2 zBI8mQ?-2Ho7w)h5#2hNIm>&D?3z6;3m8Zy_<{+Td!1FREimI1sQ^@4Vc~1y-pl_KY z#xIv>Ap_#3t*f1X{%&LUtSd*_u5w&*sp&akKy)0tO?r3bpzL=1;WP3*&isPgb{=ahUa8^|Cd^_q*Q-B{DM86R;J^(Y~36& zqulVO3=@Q3!U^KPjk8EYVy#dI!wbpecaK;c1sxGYZIkP8YZJ>fo^imN*L z?)v93PGH;Ha>*6upjf$_RQhJx0r8Y5IQrL5Ut+u-7%prK(Y4-(RimR8LX8$nQ7(>6 zN=7!a=I4MSIY?Wv%Q?z(xYVNjAD;VWaRxZqW3}VQ-~D~KxpT3kEY(1*uNr2%nc0_y z$_?%#h(H`lzrM6+*Pln165TQuna!;=EIFr(Uyw;;B06ko83n{^#5P72`k)W43#luqY|TO>I04Lxjn5xW5F|@@! zqq+xq!B%Q4)8Sw#GvUCQuiTmqtIC*FrrhTD5mC3xvRHq70U>?Y;8jbp?3Ppx=7<6~ zIdaMzR@S>!4Dg-Gu}Hk;&-t6q-)d&FUhh*bBNf3^uaqa7X8q5<`TKpIX&8n(=iD)P zJymnrG#_lUaj(BPAr$G;RX2zbfTrn!0ff-WwtKv@L@5vd&W-P@BDf^(B@F zvpX56wrD8F+5K}{RvXVRxEI&dXqHPhrsqb!!YwFw&$u+$OIm>H^Ww969@g%6AlirG zRJhCmKVNm^M882-J)IGwpSlAn;E)q_roVe>YPhWip@aFzImdBYiRB7Z=Zx-{y(|0F zpUt8r(F(CG#dGuWT+DF&;!I?1pudZv6kH;5Z=s%^tZQmjb}xsL-v6MUrtmrSt3o4A z4B}G6QIRNfCYMU__o*%J0@G3%Ikz~QDafGoP_9GV#dM0+x@ZAde?f}#EDABqkW-C! zl48l=cID5@8kQtBiMmPXSW%mhY(haML~NIOnYC>Rp`P4<5YJg{zT~;Tc^wOZSq06- zNYT69Qtx&1bMf`ST}lV-5d*@U-TD4;iKWZ;$Mn^fo_XPE&EyI(oR|DQ<`_XPG2HRW zrma!u=v!a0_ zoqz74uBxx)yeaXsi+EIvXf|aD;SI&CqjxLkfmp2rINTwmWL|L36Zl{lK9+5>@p?t9 zgdB-QJ$W9GweSc-Mjdpr*rU&$D!O;+rPw17)g8U zs$A9ec1sTMuAI+^a9JYG0K&X^>~h;x=BF}umb0$?AwejAu6extNnBSq3|LV%DY4$I zL12f77UG!=eQnMLHn^lIxHT?GcxM39pGClh0(ps$yr)u~Mw-WY02h1M`M3XS_5B;@ zf^HbHWB31A%P(^uP{h`oM{3^R{hTCGh^}plIblG$#<+nn!tV~Bdx2rV_<7?_D~x3- zMS{F6dKzO`=|@l=u~59$ji>H?_T7c%ml}dCekK#7Eec9q!0U^9J}-v22U{qB88TH6 zOK)>nqsR>3d8Q`m=iq&YrS+1Q4D8Vh@!LuCbN>88{r>>{EmJADP$PL_B*BYl6#c|^ zU6Z493fo?{4FaecgbZNJFK21`-6CobLvV?`N{C?a-dIf(w-lLLMz?~T-^q#%{rW@< z8Ru<`-eI1)=Fk@Bi7hK;WJ6R*CtYI3lmw!pE?PwGaGtCP6+{=sJ=rh!ibNnZhWJ6P z$ggo8R@WsKNaTOe1d)hzQXZLE87F8Efim{x@;&Oe6tgr_jMQX*4v_?x)%kog)W~&N zovw*z-^)U$1#rO@V)zYWhx80EU!AjBP*hw97*U@-%NiF0j2jCm+MN1)I)A4g(N1v| z#Q7eJuEmmS3q-!V_dUrhK*~tr`_oU1e2Q6#xCLd7FN<=ZCHylN^ctL`@q(8i0zmYx zy8*O;x>viYBJz(p?n;H-p8G){n~$HUZ8zZn*XWx!5QJRx1i7YN1bEUK$G2f&}N#A z6T2ajRzZ1NwoP?WHdApHR6+l<+9C!Nf4^aeN3n=R@2bzuh2OV((ELDHR?KV-QEHBP z^BJ4r9I0Un#jKf>LSJAP85%ka+>CD^Rb`lIZ=!e%^x#}rD;6V}`kZjvA-JiU3pR+~ zD1s?jc&6j3;I64Kn8Pf9$cb^dVMl%ZoPJLDEiMtCM0h!JTZFn05Q`+sd7}jhNP8z4 zcjqi8YHxGa&6eV=3M&&F|p+H-dyQCqy0*CxS1R3Xp(a?3-;fN z{ET^lh=BN+3O``;`+Dpz5avm0D4I(}yh^e5zyCk~r@zkR!1ChQajNIn4<9u3(+BJr z=FD^V9G(EaKtaFWmB&g&+p=vJC3I7+vBlzzF00qm4}YMY$Miw{`S{W>LrPt`R+!_5 ze81WnFw$svPcJz0a8b)%e363-(d}lHS8W=YXfcFC$&l0TMT_S>)ncLEw3Oj+hFi)9 zC#!P68izf7SQ)3)`&%Gd_NOgx9|=`ARHzLMd@Bk}I*+PbYi)V|9=UXI%~l{$>#}$g zguL5+o~{t)LZFmOmgW3)sKwuh89U2jCvr$jKW$K*mYwBT9N08vuPvKnr zPpY1mHAN{*#|Wv}Tq7^ZRpd7vHgaH_BSDw<4}9;3I~;_Z8i9G4abPKbCdWERLF7#< zg)5bZFB;vNupbQ$iO6^IgTmh(D3(%gO z5Ft6v-G6Q%6eqA=4MkSTxr-b^mtxZ#_eA{X90STs&)S+6>S|)$iWM7&E6*y(7Yir_ zGa=8i1ImzjU6&QhQ7lCErx(+`tMMswI@tlsgObora-(Ml-Y>)CX?_kaZy(BuALrpi zsO&_zsJPlSQ|*_AMLAjP7Haf$btUMsxXTykT+Nw|Gkw-@&AH2^3VAffu=4x~RBE7% z<*uesB^Ui>zSO}K$?=nhESi>(fi)0~Xc`MHGi$4r^Kc|l3zdC#@-oX(OOxlPjqX_M z(wg<3e^>#o`VtvH#9B|8Sh(=}84&|ktCi6m`T6xToGD2;Xl8KEo;Y`xlpC}peA&3- zUhy;4q@Y(Z2j%QS)#QIj!6~sNNQ!?<4cRoSBk*o_>Jey zj;ER;DUyM*YTJf81`!@<7)O^`sf%?KN+aFX!URic?9J@#T?Ls6QWW=wq4u1Xs6a!` zI=+Wgq^cPx$UD2ZBUcUB`5qaCBy^kL{ag@bGAH5_AW(CW;CeySjboP^S_75a&F15$ zFD|iQt;ixPAlv9&Oxe*Tsn3gQ7~K6Q5a<0+VX0zR&fJ-VEh%HL`LLXW`v%d0B9%s9 z>6q2cxFe^0^dKZzQtHlW&wu@ATR*x#>yf z$zp`rPann%U;a-ZjLm{vAm=SaA9QCiFHw%v^S~0ZhYO>vI!iqNxwvSrL?nz{#lxLf zMyds{;bnk|)fQjq6gbC->P_gwd_T3+K;>GS1Qf-)oK6wSjTi|@Jg4R_`SjxjlEExC zUtccZQFbbv33K?+;^_pYoae3kxznZ4f63b}a)$H#@$A^u>g~<%vJwk{t7ByZY7oR1 zOV2FpuZ!b|$l{q$_$f-ILE+DHi>`mK4KoR7x#WL$^lua@72LOZkgdhWh>S!Ewji9P=ON-Pa`XQ}Sc39-X3pI2(;bJPmYOA<4L zsO8yYmfVpf51l$66pcVJUP3x%x}4WU{+%tiJ2L-Pn^tj;!nwa~s@eOG-yv{m%HMCM}oGLZs{-LO!QCdNvScGb&2+nX$4%H%4d7?8BDhz1Twyiezrw@j1 zcSHs*%Ajp6MbGeaJ$AUyEqX!-lOm(ul;>%<7x+8Z6hFiJk#&GDxLk_QadDZc55@V% zMZYh~Ux-{-R8I`_!#29=p~1Tvbps! zfw3rBT+(G{BhTn0$g*Nq*Uiq)A7;xI=Sq)$nS$oFZSEYb<@)pXp8CCsSxh*h7$I2- z>(C-W)p&jZ&%C-|9sdmD{YIY>0&@X4X8Qh0v2wm_B2J>Dxf`R%d~iI}gOI;+6ZF&FDnNsK`#rrudj6*tmXlkgaT_7wfr6|5{;&WC# zN4f;4qb=cs+tLD!o@Nb-B1kb2ldd=rJSv=+2JsmwQ4)vMh~+CVB~?V(4GD-2f4;U= z<`&jmLxQ73zXQb}*Xlux>3W8V?ib=0_xZKf2k~!P<%(>{n5DBsZpT%>6Gf3a_j^x5 zwIPyXOYy1gcC+*A6NI>15({2)>t`}9kz&KyHHlgjiyLaZlHv*dz8w*fM$rW$$V8g3 z6cJK2Z&4fp-kAk)TzUpmU&p@enjc<*B1_>E#5@$@%FLBrxQuTk*18Wx6K2t_{(d^_ z3xzu%CbgCbH{(JEVx3zn<2o3{&}>);U@8fAGwRz+KrT5N1$AtWl;O;=z&H_Ns|N90 zi+Nx&SUO2_3o6gqg`S={&Nclm(UX8Gy!tH9=;B6XP%SXGKm^)ucPu%FFZ}Um*S28p z4gru28#Fi2IF**kR*KGkigbMWS_0`010kt+P9WZ`nt7yis>Nb{Oq$vVfdez!NhxC_ z5`J&%hn3$8+q@vWN4wuZi~Yqpf*)!6J-x7#n2+PJ?Z4n?$p)rv?C#NE7}5gn7~Zd`EloLNANYk|q<_a}ij zW`5&5t#lXflIjxYsYQLmz0e%CYj2a?cHOm9zWCbx~RwG9hiy2hI5%UFQc_( zq;AVUhpo+%N%h{~RDfqk9aBjy#hg-`sd=ofj9k)Ui^FYZys9vn2^R;a zfChF{zbOyVn_zEPmy2V5ydKup8;Ay;+08GS4WeOLVEshC`b~ok4KDD&GjEg4xs_sd zxRbAa`~^8WMFl1o*j!e-D&>X&CloXsAkg{E1rinu%7)@1g~JC4M5>g}9KzLFtz&Rb z=ja?G&{0_E@+B^{01bU6Y`jI5I~;@KSL9_vBk}UCZ|^oC7KOf9VAK=hn?(Ziy+(2e zPB_sRC&EEX!?L$5?$ET>&?GvZJQjdM7d(+=9OTiFMVAw^BH2Wb!;!&?iP)bm;#neF z-7%9lA5@Rwncz_VwRJNCnLrLBWqwD4pv=NPY&;*<-kf|vR2+xebeU-Q$cvwpiZOgx zYOVw}|K3xUBnLL`tf<04c~-7TDbImO zg;-9C$8p6~i&`;f!q`V-!^pYOs1-`Fi#u=h?ipNo=O-O^7Vc>^c0hBNQh=cBcz#zq z|NOhnWwT|w`QikN{Lt{qp($Sh7Wg(Zg&@_VW~G~T6**M?U6y2U5?}RFf$Bb zkz-qH&iL{ScHZ@4-)(;W;ZGb1D@!2w=dpXOQtS0R8L^-nI;X0L6>>LWpt^u`(hvXL zow_nEHC(GcAipSXF@!Swxg0R}$CnkWservA8a1>YDT|O!dy)hwfSEx67^8dM;QdWY zew!vI_r$whHwX>jRH@tD7jbgB7m4sn${x(Ztsx;%jYxx><=uSo$AKMDm7WjYLZoqa zxo9p!$m7J4aw_gY!@yD%1EJ+kKdj#0{rx6-kpp8(gQFA|qxYi}cPV0jR#%UXFe|ZG zU`#{}tnNs|Tjq4@Iek9l*c<74s}PZ}jw~1uu(_;(<1X%y7{ZMEdCOr2#nSAV zLa1=cWf$(;5zp@kaT&#>bT*E!pQ!WNg}6cTQeL_R$~FFsoVCo)OG0Q6du$FX{j~c2 z9XX{9gs_U=xn7Z<#9gO6YlDMqoQQQ|2Ce8~XTn{lA=5AD@Cvas7jK68wLd-`*~(!& z2A#DwxpW)i7UqaZhrAG$U<&mg2dZ?542V~5${)~ z`5Xcc!zwX)^vBWPIqJHrAw^ znC&k)i)|!|&8#Ip*61N9ooP|XY)L+sK?tNM#Os=Y z`H-Cbq!rn;iCo((2;+>Wv{=Y26!<}yUE$Emu@*#4m&%x&jenhx^C2KCAr1rqV1d|7 zv6XNg(qYvfpCX~TBPsBjWeyB?d*s@yE-}TBgrK8A_!Q5fYM*rz!dPxa2x-RCi8#x) zd3;By?iOdC&<`JA!wex>0+t6C@5sg>m5(X`>51n;``2F2+)i=gKjuI1I*}6LcYO84(~1!=VXSN znw8`@0SbaHB8en2sKgKV?hfG@vohU-No3xWsi+?>v(h|cehDEv->KOTYug>4Ys!a5 zycFj#6=&W+KkD%eL&Ax1?AG2stRh}TcXY+_2ad$D-EHhITSvSjWe>sL)6eOaY>~Xy)#o(m*%u$qQEJh z!QY>waq1^0U4k+aBq(^3=?eX6d;4%ID&nML zzY|7S386_ugNbE=gvuB zD+C-6V>iu%LrC8_GlpTUqNbdqYnjcvr?7ZN+$Cp<%YvordHAzLDxigFpe}BX82cU+ zO3oi)j+@0r2;&v>oUy+^pX08sDJsW*R@9w8e)l-)?S`mioWUnzmWKCS9?N&ag&(u% zAntLYjD5j@NV4Y_=r~wFFHOCIBETrFC!BF! zw%#=BZZL=WTsCT#x~{&LOjNgl*;O`Addvt(-aX>}6sL}=o^-L?<|X{O~f3=!;8)c7nu1JXQ$2D20wJ~0zB)aAnagT|%0Ak8>v2yCDV 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%0A2yU8B2j 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%0Ad<9H*aIwRp@3{=0Pxv5uCJ$$(K8nsdfwzhh~s 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%0Dn`RF=NY8ya%Q~0 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