Views
No views yet
| Component | Model | Params | Status |
|---|---|---|---|
| Visual encoder | DINOv2-Small (ViT-S/14) | 22M | Frozen |
| Tactile encoder | Sparsh-DINO (ViT-B/16, 6ch) | 86M | Frozen |
| Predictor | CrossAttnPredictor (6-layer, 384-dim) | 16M | Trained |
| Action encoder | MLP (7→384) | 0.15M | Initialized (not yet trained) |
| Total | 125M | 16M trainable |
| Metric | Value |
|---|---|
| Val prediction loss (L2OO) | 0.0108 |
| Train loss (converged) | 0.0112 |
1import torch
2from tactile_jepa.encoders import FrozenDINOv2, FrozenSparsh
3from tactile_jepa.architectures import CrossAttnPredictor, ActionEncoder
4from tactile_jepa.cross_modal_jepa import CrossModalJEPA
5from tactile_jepa.losses import CrossModalLoss
6
7# Build model
8model = CrossModalJEPA(
9 visual_encoder=FrozenDINOv2(),
10 tactile_encoder=FrozenSparsh(),
11 predictor=CrossAttnPredictor(dim=384, depth=6, num_heads=6, num_queries=16,
12 visual_dim=384, output_dim=768, dropout=0.1),
13 action_encoder=ActionEncoder(action_dim=7, hidden_dim=384),
14 predcost=CrossModalLoss(target_dim=768),
15).to("cuda")
16
17# Load checkpoint
18ckpt = torch.load("best.pth.tar", map_location="cuda", weights_only=False)
19model.load_state_dict(ckpt["model_state_dict"], strict=False)
20model.eval()
21
22# Predict tactile from visual input
23# visual_obs: [B, T, 3, 224, 224] ImageNet-normalized
24predicted_tactile = model.predict_tactile(visual_obs) # [B, N_queries, 768]best.pth.tar — Best checkpoint (epoch 0, val_pred=0.0108), 382MBconfig.yaml — Training configuration1@software{tactile_jepa_2026,
2 title={Tactile-JEPA: Cross-Modal Visual-Tactile World Model},
3 author={Julian Saks},
4 year={2026},
5 url={https://github.com/kingulio8238/tactile_jepa}
6}