File size: 10,056 Bytes
58b3e34 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | # Pose Classifier Guide
## Overview
The pose classifier predicts the orientation of animals (zebras, giraffes, etc.) relative to the camera position from aerial drone footage. This is critical for navigation and behavior analysis.
## 8-Class Pose Classification System
### Pose Classes
The classifier identifies **8 discrete pose orientations** arranged in a circle around the animal:
1. **front** - Animal facing directly toward camera
2. **front-left** - Animal facing camera, angled to the left (~45°)
3. **left** - Animal's left side visible, perpendicular to camera
4. **back-left** - Animal facing away, angled to the left (~45°)
5. **back** - Animal facing directly away from camera
6. **back-right** - Animal facing away, angled to the right (~45°)
7. **right** - Animal's right side visible, perpendicular to camera
8. **front-right** - Animal facing camera, angled to the right (~45°)
### Visual Reference

The diagram shows the 8 pose classes arranged in a circle. The camera is positioned at the bottom, and the animal (zebra) is in the center. Each orange dot represents one of the 8 possible pose classifications.
## Example Poses
### Front Pose
**Label:** `front`
The animal is facing directly toward the camera, with the head and front body visible.

---
### Front-Left Pose
**Label:** `front-left`
The animal is facing toward the camera but angled to its left (camera's right), showing both the front and left side.

---
### Front-Right Pose
**Label:** `front-right`
The animal is facing toward the camera but angled to its right (camera's left), showing both the front and right side.

---
### Left Pose
**Label:** `left`
The animal's left side is visible, perpendicular to the camera. This is a pure profile view.

---
### Right Pose
**Label:** `right`
The animal's right side is visible, perpendicular to the camera. This is a pure profile view from the opposite side.

---
### Back-Left Pose
**Label:** `back-left`
The animal is facing away from the camera but angled to its left, showing the rear-left quarter.

---
### Back-Right Pose
**Label:** `back-right`
The animal is facing away from the camera but angled to its right, showing the rear-right quarter.

---
### Back Pose
**Label:** `back`
The animal is facing directly away from the camera, with the rear and back visible.

---
## Model Architecture
### DINOv2 + MLP Head
The pose classifier uses a **frozen DINOv2 backbone** with a **trainable MLP classification head**:
```
Input Image (224×224)
↓
DINOv2 Vision Transformer (frozen)
- Small: 384-dim features
- Base: 768-dim features
- Large: 1024-dim features
↓
MLP Head (trainable)
- LayerNorm
- Linear(feat_dim -> 256) + GELU + Dropout(0.3)
- Linear(256 -> 128) + GELU + Dropout(0.3)
- Linear(128 -> 8)
↓
Output Logits (8 classes)
```
### Why DINOv2?
- **Self-supervised learning** on diverse images provides strong visual features
- **Frozen backbone** reduces training time and prevents overfitting
- **Small memory footprint** suitable for deployment
- **Robust to varying image quality** from aerial footage
## Training Pipeline
### Data Organization
Training data is organized in folder structure:
```
pose_labels/
_reference.png # Visual guide
front/ # Front-facing animals
front-left/ # Front-left quarter
left/ # Left profile
back-left/ # Back-left quarter
back/ # Back-facing animals
back-right/ # Back-right quarter
right/ # Right profile
front-right/ # Front-right quarter
```
Or via CSV files with columns: `image_path, pose`
### Data Augmentation
**Geometric Augmentation with Label Swapping:**
- Horizontal flip applied with 50% probability
- When flipped, pose labels are swapped according to symmetry:
- `left` <-> `right`
- `front-left` <-> `front-right`
- `back-left` <-> `back-right`
- `front` and `back` remain unchanged
**Color/Transform Augmentation:**
- Random crop (256px -> 224px)
- Color jitter: brightness (±30%), contrast (±30%), saturation (±20%)
- Random rotation (±15°)
**Class Balancing:**
- Weighted random sampler ensures equal representation of all 8 classes during training
### Training Configuration
```bash
python train_pose_classifier.py \
--data_dir ./pose_labels \
--model_size small \
--epochs 30 \
--batch_size 32 \
--lr 1e-3
```
**Key Parameters:**
- **Model size**: `small`, `base`, or `large` (DINOv2 variant)
- **Optimizer**: AdamW with weight decay 0.01
- **Loss**: CrossEntropyLoss with label smoothing (0.1)
- **Scheduler**: CosineAnnealingLR
- **Mixed precision**: Automatic on GPU
**Training Output:**
- Best model saved to `checkpoints/best_pose_model.pth`
- Includes confusion matrix and per-class accuracy
- Optional ONNX export for deployment
## Usage in Navigation
### Integration with Detection Pipeline
The pose classifier is used in the navigation system after animal detection:
```python
from navigation.policy.pose_classifier import ViewPointClassifier
from PIL import Image
# Initialize classifier
classifier = ViewPointClassifier(
weight_path="model_weights/best_june_24_2025_IA_classifier_016.pth",
device="cpu",
threshold=0.5
)
# Process detected animal crops
crops = [Image.open(path) for path in detection_crops]
poses = classifier(crops) # Returns list of pose strings
# Use poses for navigation decisions
for pose in poses:
if "front" in pose:
print("Animal is facing camera - approach with caution")
elif "back" in pose:
print("Animal is facing away - good for following")
```
### Multi-Label Pose System (Alternative)
The `ViewPointClassifier` in `pose_classifier.py` uses a different approach:
- **5 multi-label classes**: `up, front, back, right, left`
- **EfficientNet-B4** backbone trained on zebra crops
- **Input size**: 512×512 pixels
- **Output**: Concatenated string (e.g., `"upfrontright"`)
- **Threshold**: 0.5 (configurable)
This allows detecting compound poses like "animal is facing front-right while looking up."
## Performance Considerations
### Inference Speed
- **DINOv2-small**: ~15-20ms per image (CPU)
- **DINOv2-base**: ~30-40ms per image (CPU)
- **GPU acceleration**: 5-10x faster
### Accuracy Targets
- **Overall accuracy**: >85% on validation set
- **Critical classes** (front/back): >90% accuracy
- **Confusion**: Most errors occur between adjacent classes (e.g., front vs. front-left)
### Deployment Notes
- Model checkpoint: ~150MB (small), ~350MB (base)
- ONNX export available for optimized inference
- Batch processing recommended for multiple detections
## Common Issues & Tips
### Issue: Poor performance on occluded animals
**Solution**: Train with more occluded examples or use confidence thresholding
### Issue: Confusion between adjacent poses
**Solution**: This is expected due to continuous nature of orientations; consider using pose groups (front-facing vs. side-facing vs. back-facing)
### Issue: Inconsistent predictions across frames
**Solution**: Apply temporal smoothing or majority voting across consecutive frames
### Issue: Different performance on zebras vs. other species
**Solution**: Retrain with balanced dataset across species, or train species-specific models
## Dataset Statistics
Current training data distribution (from folder structure):
- Folders: `front`, `front-left`, `front-right`, `left`, `right`, `back-left`, `back-right`, `back`
- Images per class: Variable (check with `train_pose_classifier.py --data_dir pose_labels`)
- Species: Primarily zebras and giraffes
- Source: Aerial drone footage from Mpala and OPC sessions
## References
- DINOv2 Paper: [https://arxiv.org/abs/2304.07193](https://arxiv.org/abs/2304.07193)
- VARe-ID (ViewPoint Classifier): [https://github.com/ziesski/VARe-ID](https://github.com/ziesski/VARe-ID)
- Individual identification of wildlife: [https://doi.org/10.1007/s10344-021-01549-4](Review on methods used for wildlife species and individual identification)
- Training script: [train_pose_classifier.py](train_pose_classifier.py)
- Navigation integration: [navigation/policy/pose_classifier.py](../navigation/policy/pose_classifier.py)
## Quick Start
1. **Prepare data**: Organize images in `pose_labels/` folders by class
2. **Train model**: `python train_pose_classifier.py --data_dir ./pose_labels --epochs 30`
3. **Evaluate**: Check confusion matrix and per-class accuracy in output
4. **Export**: Use `--export_onnx` flag for optimized deployment
5. **Integrate**: Load checkpoint and use for inference on detection crops
|