TomekKaszynski commited on
Commit
b886932
·
verified ·
1 Parent(s): 666fbff

Add model card

Browse files
Files changed (1) hide show
  1. README.md +142 -0
README.md ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ tags:
4
+ - emergent-communication
5
+ - intuitive-physics
6
+ - world-models
7
+ - compositional-communication
8
+ - gumbel-softmax
9
+ - dinov2
10
+ - physics
11
+ language: en
12
+ pipeline_tag: other
13
+ ---
14
+
15
+ # Emergent Compositional Communication for Latent World Properties
16
+
17
+ [![arXiv](https://img.shields.io/badge/arXiv-2604.03266-b31b1b.svg)](https://arxiv.org/abs/2604.03266)
18
+ [![GitHub](https://img.shields.io/badge/GitHub-emergent--physics--comm-blue)](https://github.com/TomekKaszynski/emergent-physics-comm)
19
+
20
+ **Tomasz Kaszyński**, 2026
21
+
22
+ ## Summary
23
+
24
+ Neural agents with different vision backbones develop shared compositional languages about physical properties through a discrete Gumbel-Softmax bottleneck. Each message position self-organizes to encode a specific physical property (elasticity, friction). The protocol achieves 91.5% accuracy on unseen collision outcomes and 85.6% on real camera footage (Physics 101 dataset).
25
+
26
+ ## Model Architecture
27
+
28
+ **CompositionalSender** — the core trainable module:
29
+
30
+ ```
31
+ TemporalEncoder:
32
+ Conv1d(384 → 256, k=3) → ReLU
33
+ Conv1d(256 → 128, k=3) → ReLU
34
+ AdaptiveAvgPool1d(1)
35
+ Linear(128 → 128) → ReLU
36
+
37
+ Message Heads (×2):
38
+ Linear(128 → 8) → Gumbel-Softmax(τ=1.0)
39
+
40
+ Output: 2 discrete tokens per agent, each ∈ {0, ..., 7}
41
+ ```
42
+
43
+ - **Input:** Frozen DINOv2-S features (384-dim per frame)
44
+ - **Bottleneck:** 2 heads × vocab 8 = 16-dim one-hot message per agent
45
+ - **Sender params:** 412,176
46
+ - **Receiver params:** 12,610
47
+
48
+ ## Checkpoints
49
+
50
+ | File | Description | Size |
51
+ |------|-------------|------|
52
+ | `phase54b_model.pt` | Main result model (DINOv2 features, 2-agent, 2×8 bottleneck) | 3.5 MB |
53
+ | `phase54c_model.pt` | Best multi-seed variant | 3.5 MB |
54
+ | `phase54c_seed42_model.pt` | Seed 42 | 3.3 MB |
55
+ | `phase54c_seed123_model.pt` | Seed 123 | 3.3 MB |
56
+ | `phase54c_seed456_model.pt` | Seed 456 | 3.3 MB |
57
+ | `phase54c_seed789_model.pt` | Seed 789 | 3.3 MB |
58
+ | `phase54c_seed1337_model.pt` | Seed 1337 | 3.3 MB |
59
+ | `phase87_phys101_spring_features.pt` | Pre-extracted DINOv2 features for Physics 101 spring (206 clips) | 3.2 MB |
60
+
61
+ ## Checkpoint Format
62
+
63
+ Each `.pt` file is a dictionary with keys:
64
+
65
+ ```python
66
+ {
67
+ "sender_2x8": <state_dict>, # CompositionalSender weights
68
+ "receiver_2x8": <state_dict>, # CompositionalReceiver weights
69
+ "sender_1x64": <state_dict>, # Alternative 1×64 bottleneck sender
70
+ "receiver_1x64": <state_dict>, # Alternative 1×64 receiver
71
+ }
72
+ ```
73
+
74
+ ## Usage
75
+
76
+ ```python
77
+ import torch
78
+ import torch.nn as nn
79
+ import torch.nn.functional as F
80
+
81
+ class TemporalEncoder(nn.Module):
82
+ def __init__(self, hidden_dim=128, input_dim=384, n_frames=4):
83
+ super().__init__()
84
+ ks = min(3, n_frames)
85
+ self.temporal = nn.Sequential(
86
+ nn.Conv1d(input_dim, 256, kernel_size=ks, padding=ks // 2), nn.ReLU(),
87
+ nn.Conv1d(256, 128, kernel_size=ks, padding=ks // 2), nn.ReLU(),
88
+ nn.AdaptiveAvgPool1d(1))
89
+ self.fc = nn.Sequential(nn.Linear(128, hidden_dim), nn.ReLU())
90
+ def forward(self, x):
91
+ return self.fc(self.temporal(x.permute(0, 2, 1)).squeeze(-1))
92
+
93
+ class CompositionalSender(nn.Module):
94
+ def __init__(self, hidden_dim=128, input_dim=384, vocab_size=8, n_heads=2):
95
+ super().__init__()
96
+ self.encoder = TemporalEncoder(hidden_dim, input_dim)
97
+ self.vocab_size = vocab_size
98
+ self.heads = nn.ModuleList([nn.Linear(hidden_dim, vocab_size) for _ in range(n_heads)])
99
+ def forward(self, x, tau=1.0):
100
+ h = self.encoder(x)
101
+ tokens = [head(h).argmax(dim=-1) for head in self.heads]
102
+ return torch.stack(tokens, dim=-1) # [batch, n_heads]
103
+
104
+ # Load
105
+ ckpt = torch.load("phase54c_model.pt", map_location="cpu")
106
+ sender = CompositionalSender(hidden_dim=128, input_dim=384, vocab_size=8, n_heads=2)
107
+ sender.load_state_dict(ckpt["sender_2x8"])
108
+ sender.eval()
109
+
110
+ # Run on DINOv2 features: [batch, n_frames, 384]
111
+ features = torch.randn(1, 4, 384) # Replace with real DINOv2 features
112
+ tokens = sender(features)
113
+ print(f"Discrete physics code: {tokens}") # e.g., tensor([[3, 7]])
114
+ ```
115
+
116
+ ## Training Details
117
+
118
+ - **Dataset:** Physics 101 ramp scenario (surface friction + elasticity)
119
+ - **Backbone:** Frozen DINOv2-S (dinov2_vits14, 21M params, not included)
120
+ - **Training:** 400 epochs, Adam (sender lr=1e-3, receiver lr=3e-3)
121
+ - **Gumbel-Softmax:** τ annealed from 3.0 → 1.0, hard after epoch 30
122
+ - **Iterated learning:** Receiver reset every 40 epochs (3 parallel receivers)
123
+ - **Entropy regularization:** coefficient=0.03 when entropy < 0.1
124
+
125
+ ## Key Results
126
+
127
+ - **91.5% accuracy** on unseen collision outcomes (80 random seeds)
128
+ - **85.6% accuracy** on real camera footage (Physics 101)
129
+ - **PosDis = 0.999** — near-perfect positional disentanglement
130
+ - **25× compression** with 94% predictive performance retained
131
+ - Works across V-JEPA 2, DINOv2, and CLIP ViT-L/14
132
+
133
+ ## Citation
134
+
135
+ ```bibtex
136
+ @article{kaszynski2026emergent,
137
+ title={Emergent Compositional Communication for Latent World Properties},
138
+ author={Kaszy{\'n}ski, Tomasz},
139
+ journal={arXiv preprint arXiv:2604.03266},
140
+ year={2026}
141
+ }
142
+ ```