Upload folder using huggingface_hub
Browse files- README.md +65 -0
- config_v10_split_heldout.yaml +78 -0
- config_v9_alldata.yaml +78 -0
- pose2rot_v10_heldout_epoch60.pt +3 -0
- pose2rot_v8b_best_epoch40.pt +3 -0
- pose2rot_v9_alldata_epoch60.pt +3 -0
README.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
tags:
|
| 4 |
+
- motion-capture
|
| 5 |
+
- pose-estimation
|
| 6 |
+
- inverse-kinematics
|
| 7 |
+
- animation
|
| 8 |
+
- arbitrary-skeleton
|
| 9 |
+
library_name: pytorch
|
| 10 |
+
---
|
| 11 |
+
|
| 12 |
+
# pose2rot — Joint Positions → 6D Rotations for Arbitrary Skeletons
|
| 13 |
+
|
| 14 |
+
Pretrained checkpoints for the **pose2rot** model (`Pose2RotMemoryRestModel`): given a sequence of
|
| 15 |
+
3D joint **positions**, predict per-joint **6D rotations** (forward kinematics then recovers the full
|
| 16 |
+
skeletal animation). One model handles **arbitrary skeletons** across 72 animal species — quadrupeds,
|
| 17 |
+
bipeds, birds, reptiles, dinosaurs, arthropods, limbless snakes — via T5 joint-name embeddings,
|
| 18 |
+
skeleton graph attention, and rest-pose FiLM conditioning.
|
| 19 |
+
|
| 20 |
+
**Code, training recipe, eval & QA scripts:** https://github.com/CHDTevior/pose2rot
|
| 21 |
+
|
| 22 |
+
This is a derivative work of [MocapAnything](https://github.com/phongdaot/MocapAnything)
|
| 23 |
+
(MIT, © 2026 Dao Thien Phong; arXiv:2604.28130 MoCapAnything V2). ~29.7M params.
|
| 24 |
+
|
| 25 |
+
## Checkpoints
|
| 26 |
+
|
| 27 |
+
| file | training data | use case |
|
| 28 |
+
|---|---|---|
|
| 29 |
+
| `pose2rot_v9_alldata_epoch60.pt` | all 72 species | **best for demos / inference** (the species is seen) |
|
| 30 |
+
| `pose2rot_v10_heldout_epoch60.pt` | seen/rare/unseen held-out split (test motions excluded) | the **decisive paper model** for honest cross-topology eval |
|
| 31 |
+
| `pose2rot_v8b_best_epoch40.pt` | all species (earlier converged best) | reference |
|
| 32 |
+
|
| 33 |
+
Each `.pt` holds `{model_state, optimizer_state, epoch}`. Configs: `config_v9_alldata.yaml`,
|
| 34 |
+
`config_v10_split_heldout.yaml` (model section instantiates `Pose2RotMemoryRestModel`).
|
| 35 |
+
|
| 36 |
+
## Results (geodesic angle error, degrees; MoCapAnything V2 reports 6.54° unseen / V1 ~17°)
|
| 37 |
+
|
| 38 |
+
| model | seen | rare | unseen | overall |
|
| 39 |
+
|---|---|---|---|---|
|
| 40 |
+
| v9 all-data (oracle) | 7.2° | 5.9° | 6.4° | **6.53°** ≈ MoCapAnything 6.54° |
|
| 41 |
+
| v10 true held-out | 9.8° | 12.7° | 40.9° | 28.0° |
|
| 42 |
+
|
| 43 |
+
When the species is **seen**, the model matches SOTA (6.5°). On a **true held-out** test, cross-topology
|
| 44 |
+
generalization is a ceiling: unseen species with close training relatives generalize partially (Goat 17°,
|
| 45 |
+
Coyote 19°), topologically distinctive ones do not (Pigeon ~67°, Spider ~73°).
|
| 46 |
+
|
| 47 |
+
## Usage
|
| 48 |
+
|
| 49 |
+
```python
|
| 50 |
+
import torch
|
| 51 |
+
from utils.config_utils import load_yaml_config, instantiate_from_config # from the GitHub repo
|
| 52 |
+
|
| 53 |
+
cfg = load_yaml_config("config_v9_alldata.yaml")
|
| 54 |
+
model = instantiate_from_config(cfg["model"]).eval().cuda()
|
| 55 |
+
model.load_state_dict(torch.load("pose2rot_v9_alldata_epoch60.pt", map_location="cpu")["model_state"])
|
| 56 |
+
# batch dict: position[B,T,J,3] + rest pose + T5 joint embeddings + skeleton graph + reference (see GitHub data/loader_v2.py)
|
| 57 |
+
pred_rot6d = model(batch)["pred_rot6d"] # [B,T,J,6]
|
| 58 |
+
```
|
| 59 |
+
|
| 60 |
+
See https://github.com/CHDTevior/pose2rot for the full data pipeline, training, and evaluation.
|
| 61 |
+
|
| 62 |
+
## License & Citation
|
| 63 |
+
|
| 64 |
+
MIT. Built on [MocapAnything](https://github.com/phongdaot/MocapAnything) (Dao Thien Phong, MIT).
|
| 65 |
+
Please also cite MoCapAnything (arXiv:2604.28130).
|
config_v10_split_heldout.yaml
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
### train_pose2rot_v7_ddp_b4.yaml — v6 recipe (memabl+tvar) at batch4 DDP-2gpu for 3.6x throughput ###
|
| 2 |
+
name: Pose2Rot training
|
| 3 |
+
|
| 4 |
+
runtime:
|
| 5 |
+
device: cuda
|
| 6 |
+
seed: 42
|
| 7 |
+
debug: false
|
| 8 |
+
|
| 9 |
+
output:
|
| 10 |
+
checkpoint_root: ./checkpoints/pose2rot
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
experiment:
|
| 14 |
+
exp: exp_pose2rot_v10_split_heldout
|
| 15 |
+
|
| 16 |
+
model:
|
| 17 |
+
target: models.v2.pose2rot.model.Pose2RotMemoryRestModel
|
| 18 |
+
params:
|
| 19 |
+
q_dim: 256
|
| 20 |
+
rest_layers: 4
|
| 21 |
+
pose_layers: 4
|
| 22 |
+
memory_layers: 4
|
| 23 |
+
decoder_layers: 10
|
| 24 |
+
num_heads: 8
|
| 25 |
+
joint_embed_dim: 768
|
| 26 |
+
temporal_window: 2
|
| 27 |
+
temporal_dropout: 0.1
|
| 28 |
+
decoder_cond_mode: add # add | concat
|
| 29 |
+
pose_rest_film: true
|
| 30 |
+
memory_rest_film: true
|
| 31 |
+
decoder_rest_film: true
|
| 32 |
+
pose_use_graph: true
|
| 33 |
+
use_grad_checkpoint: false
|
| 34 |
+
decoder_use_cross_layers: 0 # MEMORY ABLATION: no decoder cross-attn into memory bank (kill species-constant leakage)
|
| 35 |
+
|
| 36 |
+
train:
|
| 37 |
+
batch_size: 4 # DDP global batch = 4/gpu x 2 gpu = 8
|
| 38 |
+
epochs: 60
|
| 39 |
+
grad_accum_steps: 1
|
| 40 |
+
lr: 0.0002 # DDP 2-gpu global batch 8 at the proven-safe lr2e-4 (test if batch-doubling breaks anti-collapse)
|
| 41 |
+
warmup_steps: 500 # linear LR warmup 0->8e-4 (codex: tame Adam startup at large scaled LR)
|
| 42 |
+
max_ckpt: 100
|
| 43 |
+
num_workers_train: 6 # 6/proc x 2 proc = 12 of 16 cores
|
| 44 |
+
test_every: 1
|
| 45 |
+
pretrain_ckpt: null
|
| 46 |
+
|
| 47 |
+
loss:
|
| 48 |
+
rot_loss_type: smooth_l1
|
| 49 |
+
vel_loss_type: smooth_l1
|
| 50 |
+
acc_loss_type: smooth_l1
|
| 51 |
+
|
| 52 |
+
weight:
|
| 53 |
+
root_wt: 0.1
|
| 54 |
+
fk_wt: 10.0 # FK ramp END=10(用户按MoCapAnything; 比v8b的30温和, fk梯度~0.33<<grad_clip1.0 不会再亚稳发散)
|
| 55 |
+
fk_wt_start: 0.0 # 从0起(纯抗塌缩早期, 让tvar正常破塌缩)
|
| 56 |
+
fk_ramp_start_epoch: 5
|
| 57 |
+
fk_ramp_end_epoch: 15 # 线性 0->10 over epoch5-15, 之后恒10
|
| 58 |
+
vel_wt: 1.0
|
| 59 |
+
acc_wt: 1.0 # 用户要求加 acc(2阶时序平滑); 随机初始化量级~0.0095
|
| 60 |
+
rot_wt: 1.0
|
| 61 |
+
tvar_wt: 2.0 # demeaned-temporal supervision (force motion-tracking, anti-collapse)
|
| 62 |
+
|
| 63 |
+
vis_every: 5
|
| 64 |
+
weight_decay: 0.0
|
| 65 |
+
|
| 66 |
+
eval:
|
| 67 |
+
batch_size: 1
|
| 68 |
+
num_workers: 2
|
| 69 |
+
|
| 70 |
+
data:
|
| 71 |
+
seq_len: 48
|
| 72 |
+
bvh_dir: datasets/zoo1030/bvh
|
| 73 |
+
cache_scale: true
|
| 74 |
+
limit_species_debug: []
|
| 75 |
+
mmap: true
|
| 76 |
+
split_json: datasets/zoo1030/test_split_seen_rare_unseen.json
|
| 77 |
+
train_memory_pkl_path: datasets/zoo1030/cache/species_fps_memory_yAll/fps_select_by_rot_32.pkl
|
| 78 |
+
test_memory_pkl_path: datasets/zoo1030/cache/species_fps_memory_yAll/fps_select_by_rot_32.pkl
|
config_v9_alldata.yaml
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
### train_pose2rot_v7_ddp_b4.yaml — v6 recipe (memabl+tvar) at batch4 DDP-2gpu for 3.6x throughput ###
|
| 2 |
+
name: Pose2Rot training
|
| 3 |
+
|
| 4 |
+
runtime:
|
| 5 |
+
device: cuda
|
| 6 |
+
seed: 42
|
| 7 |
+
debug: false
|
| 8 |
+
|
| 9 |
+
output:
|
| 10 |
+
checkpoint_root: ./checkpoints/pose2rot
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
experiment:
|
| 14 |
+
exp: exp_pose2rot_v9_fk10ramp_60ep
|
| 15 |
+
|
| 16 |
+
model:
|
| 17 |
+
target: models.v2.pose2rot.model.Pose2RotMemoryRestModel
|
| 18 |
+
params:
|
| 19 |
+
q_dim: 256
|
| 20 |
+
rest_layers: 4
|
| 21 |
+
pose_layers: 4
|
| 22 |
+
memory_layers: 4
|
| 23 |
+
decoder_layers: 10
|
| 24 |
+
num_heads: 8
|
| 25 |
+
joint_embed_dim: 768
|
| 26 |
+
temporal_window: 2
|
| 27 |
+
temporal_dropout: 0.1
|
| 28 |
+
decoder_cond_mode: add # add | concat
|
| 29 |
+
pose_rest_film: true
|
| 30 |
+
memory_rest_film: true
|
| 31 |
+
decoder_rest_film: true
|
| 32 |
+
pose_use_graph: true
|
| 33 |
+
use_grad_checkpoint: false
|
| 34 |
+
decoder_use_cross_layers: 0 # MEMORY ABLATION: no decoder cross-attn into memory bank (kill species-constant leakage)
|
| 35 |
+
|
| 36 |
+
train:
|
| 37 |
+
batch_size: 4 # DDP global batch = 4/gpu x 2 gpu = 8
|
| 38 |
+
epochs: 60
|
| 39 |
+
grad_accum_steps: 1
|
| 40 |
+
lr: 0.0002 # DDP 2-gpu global batch 8 at the proven-safe lr2e-4 (test if batch-doubling breaks anti-collapse)
|
| 41 |
+
warmup_steps: 500 # linear LR warmup 0->8e-4 (codex: tame Adam startup at large scaled LR)
|
| 42 |
+
max_ckpt: 100
|
| 43 |
+
num_workers_train: 6 # 6/proc x 2 proc = 12 of 16 cores
|
| 44 |
+
test_every: 1
|
| 45 |
+
pretrain_ckpt: null
|
| 46 |
+
|
| 47 |
+
loss:
|
| 48 |
+
rot_loss_type: smooth_l1
|
| 49 |
+
vel_loss_type: smooth_l1
|
| 50 |
+
acc_loss_type: smooth_l1
|
| 51 |
+
|
| 52 |
+
weight:
|
| 53 |
+
root_wt: 0.1
|
| 54 |
+
fk_wt: 10.0 # FK ramp END=10(用户按MoCapAnything; 比v8b的30温和, fk梯度~0.33<<grad_clip1.0 不会再亚稳发散)
|
| 55 |
+
fk_wt_start: 0.0 # 从0起(纯抗塌缩早期, 让tvar正常破塌缩)
|
| 56 |
+
fk_ramp_start_epoch: 5
|
| 57 |
+
fk_ramp_end_epoch: 15 # 线性 0->10 over epoch5-15, 之后恒10
|
| 58 |
+
vel_wt: 1.0
|
| 59 |
+
acc_wt: 1.0 # 用户要求加 acc(2阶时序平滑); 随机初始化量级~0.0095
|
| 60 |
+
rot_wt: 1.0
|
| 61 |
+
tvar_wt: 2.0 # demeaned-temporal supervision (force motion-tracking, anti-collapse)
|
| 62 |
+
|
| 63 |
+
vis_every: 5
|
| 64 |
+
weight_decay: 0.0
|
| 65 |
+
|
| 66 |
+
eval:
|
| 67 |
+
batch_size: 1
|
| 68 |
+
num_workers: 2
|
| 69 |
+
|
| 70 |
+
data:
|
| 71 |
+
seq_len: 48
|
| 72 |
+
bvh_dir: datasets/zoo1030/bvh
|
| 73 |
+
cache_scale: true
|
| 74 |
+
limit_species_debug: []
|
| 75 |
+
mmap: true
|
| 76 |
+
split_json: datasets/zoo1030/selected_test_split1010.json
|
| 77 |
+
train_memory_pkl_path: datasets/zoo1030/cache/species_fps_memory_yAll/fps_select_by_rot_32.pkl
|
| 78 |
+
test_memory_pkl_path: datasets/zoo1030/cache/species_fps_memory_yAll/fps_select_by_rot_32.pkl
|
pose2rot_v10_heldout_epoch60.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7738568a8087d4f2d9f9fb84ea6ac1dac51b7eca2ab2046df07399a305617f80
|
| 3 |
+
size 325972891
|
pose2rot_v8b_best_epoch40.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:36398c06b7cfade441ca74527b994388f7b1e6da7ee0b81a3c1b8db1a4c76691
|
| 3 |
+
size 325972891
|
pose2rot_v9_alldata_epoch60.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:3a8a075999f7ffbc02bb085f161157f9d9d8369be1799a5779ca6b89131e5d9f
|
| 3 |
+
size 325972891
|