yoga-posture-models / README.md
Arko007's picture
Upload README.md with huggingface_hub
3d6a1ea verified
|
Raw
History Blame Contribute Delete
13.1 kB
---
language:
- en
license: cc-by-nc-sa-4.0
tags:
- yoga
- posture-correction
- pose-estimation
- pytorch
- resmlp
- gru
- attention
- computer-vision
- mediapipe
datasets:
- custom
metrics:
- accuracy
- f1
pipeline_tag: tabular-classification
model-index:
- name: YogaResMLP (Single-Head Classifier)
results:
- task:
type: tabular-classification
dataset:
name: yoga-pose-features-dataset
type: custom
metrics:
- name: Validation Pose Accuracy
type: accuracy
value: 92.84
- name: Yoga3HeadMLP (Multi-Output Model)
results:
- task:
type: tabular-classification
dataset:
name: yoga-pose-features-dataset
type: custom
metrics:
- name: Base Pose Identification Accuracy
type: accuracy
value: 93.38
- name: Pose Correctness Accuracy
type: accuracy
value: 96.81
- name: YogaSequenceLSTM (ST-GCN/Sequence Model)
results:
- task:
type: sequence-classification
dataset:
name: yoga-pose-features-dataset
type: custom
metrics:
- name: Flow Sequence Validation Accuracy
type: accuracy
value: 75.25
---
# Smart Yoga Posture Correction System (Project P05)
This repository hosts the model weights and label encoders for the **Smart Yoga Posture Correction System** (Final Year Project P05, RCC IIT Kolkata).
The system leverages a multi-model cooperative framework to classify and correct yoga poses:
1. **Single-Head ResMLP Model (`mlp_model.pth`)**: A frame-level static posture classifier trained on 15 biomechanical joint angles, achieving **92.84%** validation accuracy across 29 classes.
2. **3-Head MLP Model (`mlp_3head_model.pth`)**: A multi-output static posture model predicting **Pose ID** (across 23 base classes, achieving **93.38%** pose accuracy), **Pose Correctness** (achieving **96.81%** accuracy), and **Joint Angle Deviations** (regression output) simultaneously.
3. **Sequence Flow Model (`stgcn_sequence_model.pth`)**: A hybrid 1D Temporal Convolution + Stacked Residual GRU + Self-Attention model trained on 60-frame skeleton coordinate sequences, achieving **75.25%** validation accuracy across 27 classes.
All models incorporate class-weight smoothing and normalization techniques to resolve pose imbalance and coordinate noise.
---
## Model Architectures & Training Logs
### 1. Static Pose Classifier (Single-Head ResMLP)
#### Architecture
The **ResMLP** classifier processes 15 frame-level joint angles (computed from MediaPipe Pose landmarks):
* **Input Layer**: `Linear(15 -> 256)` followed by Batch Normalization and `GELU` activation.
* **Residual blocks**: 2 stacked residual blocks. Each block consists of:
* `Linear(256 -> 256)` -> `BatchNorm1d` -> `GELU` -> `Dropout(0.3)`
* `Linear(256 -> 256)` -> `BatchNorm1d` -> `GELU` -> `Dropout(0.3)`
* Residual skip connection: `x_out = x + block(x)`
* **Classification Head**: `Linear(256 -> 128)` -> `BatchNorm1d` -> `GELU` -> `Dropout(0.2)` -> `Linear(128 -> 29)`.
#### Dataset & Preprocessing
* **Dataset size**: 654,488 frames in total.
* **Train size**: 523,590 frames
* **Validation size**: 130,898 frames
* **Class Weights**: Smoothed using the square-root count inverse function `1.0 / sqrt(count)` to prevent minor classes (such as `transition/unknown` and `lunge_pose`) from dominating the gradients.
#### Training Performance & Curves
* **Best Validation Loss**: **0.1644** at Epoch 39.
* **Final Epoch (40/40)**:
* **Train Loss**: 0.2238 | **Train Acc**: 90.78%
* **Val Loss**: 0.1651 | **Val Acc**: 92.84%
Below is the training progress for selected epochs:
| Epoch | Train Loss | Train Acc | Val Loss | Val Acc |
|---|---|---|---|---|
| Epoch 01 | 0.6523 | 77.57% | 0.3930 | 83.94% |
| Epoch 02 | 0.4576 | 82.71% | 0.3231 | 86.79% |
| Epoch 03 | 0.4080 | 84.19% | 0.3005 | 87.17% |
| Epoch 04 | 0.3811 | 85.05% | 0.2700 | 88.29% |
| Epoch 05 | 0.3620 | 85.71% | 0.2756 | 87.24% |
| Epoch 10 | 0.3102 | 87.56% | 0.2421 | 89.24% |
| Epoch 20 | 0.2732 | 89.00% | 0.2091 | 90.78% |
| Epoch 30 | 0.2420 | 90.18% | 0.1872 | 91.57% |
| Epoch 39 | 0.2259 | 90.73% | **0.1644** | 92.66% |
| Epoch 40 | 0.2238 | 90.78% | 0.1651 | **92.84%** |
#### Static Pose Classification Report
```
precision recall f1-score support
chair_pose 0.56 0.94 0.70 366
chaturanga 0.45 1.00 0.62 5
child 0.06 0.57 0.10 7
child_pose 0.91 0.99 0.95 3260
cobra_pose 0.90 0.96 0.93 5116
corpse 0.36 0.85 0.51 20
downward_dog 0.90 0.95 0.92 4398
halfway_lift 0.55 0.94 0.70 479
imperfect_corpse 0.66 0.97 0.78 290
imperfect_plank 0.86 0.96 0.91 1825
imperfect_seated_forward 0.87 0.99 0.92 938
imperfect_triangle 0.87 0.96 0.91 2607
imperfect_upward_dog 0.91 0.97 0.94 2556
lunge_pose 0.97 0.93 0.95 19496
mountain_pose 0.77 0.97 0.86 1233
plank 0.58 0.63 0.61 174
seated_easy_pose 0.94 0.97 0.95 17465
seated_forward 0.91 0.96 0.94 75
seated_staff 0.80 0.94 0.86 1600
standing_forward_fold 0.95 0.96 0.96 7907
standing_pose 0.85 0.92 0.89 1405
table_top 0.51 0.94 0.66 501
transition/unknown 0.98 0.88 0.93 44781
tree_pose 0.73 0.97 0.83 1474
triangle 0.58 0.75 0.66 485
upward_dog 0.42 0.60 0.49 67
upward_salute 0.76 0.99 0.86 528
warrior_1 0.94 0.98 0.96 4736
warrior_2 0.88 0.95 0.91 7104
weighted avg 0.94 0.93 0.93 130898
accuracy 0.93 130898
```
---
### 2. Multi-Output Posture Correction Model (3-Head MLP)
#### Architecture
The **3-Head MLP** classifier processes 15 frame-level joint angles (computed from MediaPipe Pose landmarks):
* **Shared Feature Trunk**:
* Input layer `Linear(15 -> 256)` -> `BatchNorm1d` -> `GELU` activation.
* 2 stacked residual blocks (`ResBlock` of size 256). Each block contains:
* `Linear(256 -> 256)` -> `BatchNorm1d` -> `GELU` -> `Dropout(0.3)`
* `Linear(256 -> 256)` -> `BatchNorm1d` -> `GELU` -> `Dropout(0.3)`
* Skip connection: `x_out = x + block(x)`
* **Head 1: Pose ID (Classification)**:
* `Linear(256 -> 128)` -> `BatchNorm1d` -> `GELU` -> `Dropout(0.2)` -> `Linear(128 -> 23)` (Softmax over 23 base posture classes).
* **Head 2: Correctness (Binary Classification)**:
* `Linear(256 -> 64)` -> `BatchNorm1d` -> `GELU` -> `Dropout(0.2)` -> `Linear(64 -> 1)` (Binary Logit output: correct vs. imperfect/transition).
* **Head 3: Joint Deviation (Regression)**:
* `Linear(256 -> 128)` -> `BatchNorm1d` -> `GELU` -> `Dropout(0.2)` -> `Linear(128 -> 15)` (Predicts normalized deviation values in $[0, 1]$ where 1.0 represents 180° deviation).
#### Dataset & Preprocessing
* **Dataset size**: 654,488 frames in total.
* **Train size**: 523,590 frames
* **Validation size**: 130,898 frames
* **Class Weights**: Smoothed using the square-root count inverse function `1.0 / sqrt(count)` to prevent major classes (such as `transition/unknown` and `lunge_pose`) from dominating the Pose ID loss gradients.
* **Loss Function**: $\mathcal{L}_{total} = \mathcal{L}_{pose} + \mathcal{L}_{correctness} + \mathcal{L}_{deviation}$ (combining Cross-Entropy, Binary Cross-Entropy with logits, and Huber SmoothL1 loss).
#### Training Performance & Curves
* **Best Validation Loss**: **0.2263** at Epoch 39/40.
* **Validation Pose Accuracy**: **93.38%**
* **Validation Correctness Accuracy**: **96.81%**
Below is the training progress for selected epochs:
| Epoch | Train Loss | Train Pose Acc | Val Loss | Val Pose Acc | Val Correctness Acc |
|---|---|---|---|---|---|
| Epoch 01 | 0.8631 | 79.04% | 0.5059 | 86.08% | 92.83% |
| Epoch 02 | 0.6321 | 83.78% | 0.4506 | 87.46% | 93.72% |
| Epoch 03 | 0.5702 | 85.20% | 0.3939 | 89.38% | 94.36% |
| Epoch 04 | 0.5321 | 86.14% | 0.3811 | 88.70% | 94.51% |
| Epoch 05 | 0.5055 | 86.71% | 0.3550 | 90.19% | 94.75% |
| Epoch 10 | 0.4389 | 88.33% | 0.3079 | 91.43% | 95.30% |
| Epoch 20 | 0.3864 | 89.72% | 0.2873 | 91.54% | 95.60% |
| Epoch 30 | 0.3597 | 90.42% | 0.2545 | 92.22% | 96.42% |
| Epoch 39 | 0.3224 | 91.36% | **0.2263** | **93.38%** | **96.81%** |
| Epoch 40 | 0.3215 | 91.37% | 0.2380 | 92.62% | 96.65% |
---
### 3. Sequence Flow Classifier (ST-GCN/GRU-Attention)
#### Architecture
The sequence classifier processes **60-frame coordinate sequences** (shape `[batch_size, 60, 99]`, representing 33 joints in 3D):
* **Coordinate Normalization**: Translates coordinate sequences to be **pelvis-centered** (using the midpoint between the left and right hip joints) and divides by hip-width. This guarantees absolute **translation and scale invariance**.
* **1D Temporal Convolution**: `Conv1d(in_channels=99, out_channels=128, kernel_size=5, padding=2)` -> `BatchNorm1d` -> `GELU` -> `Dropout(0.2)` to smooth coordinate sequence noise.
* **Stacked Residual GRU blocks**: Two bidirectional GRU blocks with hidden dimension 128. Output is projected back from 256 to 128, normalized with LayerNorm, dropped out with 30% rate, and summed with input (residual connection).
* **Self-Attention Pooling**: Learns step importance weights dynamically and returns a weighted summary vector across the 60-frame window.
* **Classification Head**: `Linear(128 -> 64)` -> `GELU` -> `Dropout(0.3)` -> `Linear(64 -> 27)`.
#### Dataset & Preprocessing
* **Total sequences**: 18,165 (60-frame windows).
* **Train size**: 14,532 sequences.
* **Validation size**: 3,633 sequences.
* **Training Hyperparameters**:
* Batch Size: 64
* Optimizer: `AdamW(lr=2e-3, weight_decay=1e-3)`
* Target Metric: Best Validation Accuracy.
#### Training Performance & Curves
* **Best Validation Accuracy**: **75.25%** at Epoch 90.
* **Early Stopping**: Triggered at Epoch 110.
Selected epochs during training:
| Epoch | Train Loss | Train Acc | Val Loss | Val Acc |
|---|---|---|---|---|
| Epoch 01 | 3.7886 | 37.03% | 3.4506 | 45.09% |
| Epoch 02 | 3.4884 | 42.83% | 3.2596 | 49.55% |
| Epoch 10 | 2.9655 | 60.80% | 2.8399 | 64.35% |
| Epoch 20 | 2.7688 | 67.86% | 2.7106 | 68.98% |
| Epoch 30 | 2.6449 | 71.72% | 2.6624 | 69.83% |
| Epoch 50 | 2.5094 | 76.72% | 2.6160 | 72.20% |
| Epoch 90 | 2.3185 | 83.82% | 2.5877 | **75.25%** |
| Epoch 110 | 2.2777 | 85.25% | 2.6001 | 74.40% (Early Stopping) |
---
## Inference and Usage Guide
All model state dicts and label encoder maps can be downloaded and loaded in Python as follows:
```python
import numpy as np
import torch
import torch.nn as nn
# Load label encoders
mlp_classes = np.load("mlp_label_encoder.npy", allow_pickle=True)
mlp_3head_classes = np.load("mlp_3head_pose_encoder.npy", allow_pickle=True)
stgcn_classes = np.load("stgcn_label_encoder.npy", allow_pickle=True)
# 1. Instantiate the Single-Head ResMLP Model
mlp_model = YogaMLP(input_dim=15, num_classes=len(mlp_classes))
mlp_model.load_state_dict(torch.load("mlp_model.pth", map_location="cpu"))
mlp_model.eval()
# 2. Instantiate the 3-Head MLP Model
mlp_3head_model = Yoga3HeadMLP(input_dim=15, num_poses=len(mlp_3head_classes))
mlp_3head_model.load_state_dict(torch.load("mlp_3head_model.pth", map_location="cpu"))
mlp_3head_model.eval()
# 3. Instantiate the Sequence Model
sequence_model = YogaSequenceLSTM(input_dim=99, hidden_dim=128, num_layers=2, num_classes=len(stgcn_classes))
sequence_model.load_state_dict(torch.load("stgcn_sequence_model.pth", map_location="cpu"))
sequence_model.eval()
```
### Cooperative Prediction Protocol
For production deployment (e.g. FastAPI backend):
1. Extract frame joint coordinate sequences (shape `[N, 60, 99]`) using MediaPipe.
2. If the sequence is classified by `stgcn_sequence_model.pth` as `transition/unknown`, the backend falls back to using either the static single-head `mlp_model.pth` or the multi-output `mlp_3head_model.pth` classifier on individual frames.
3. This cooperative approach minimizes false positives, provides real-time latency optimization, and ensures smooth transition tracking while practicing.
---
**RCC Institute of Information Technology, Kolkata**
*Department of Computer Science & Engineering*
*Final Year Project 2026*