Game of Life autoencoder β step 148,500
A convolutional autoencoder trained to reconstruct Conway's Game of Life frames
near-exactly: 128Γ128 binary grid β z β βΒΉβ°Β²β΄ β 128Γ128 logits.
alive-F1 0.9169 (dead-F1 0.9997) on the full validation set at threshold 0.5; round-trip cosine 0.999 on real frames.
This checkpoint exists so the accompanying study can be independently verified. The point of that study is that reconstruction fidelity like the above does not imply a latent you can predict, plan, or sample in β see Known limitations.
- Code and full results: themantralab/gol-emergence-pipeline
- Training corpus: themantralab/gol-emergence-pipeline (dataset)
Loading
The architecture lives in model.py in the GitHub repository β it is not
duplicated here, so there is one definition rather than two that can drift.
git clone https://github.com/themantralab/gol-emergence-pipeline.git
cd gol-emergence-pipeline
pip install -r requirements.txt
import torch
from huggingface_hub import hf_hub_download
from model import Encoder, Decoder
path = hf_hub_download("themantralab/gol-emergence-pipeline", "best.pt")
ckpt = torch.load(path, map_location="cpu", weights_only=False)
print(ckpt["step"], ckpt["metrics"]) # 148500, alive_f1 0.916896
enc, dec = Encoder(), Decoder(kernel_size=1)
enc.load_state_dict(ckpt["encoder"]); enc.eval()
dec.load_state_dict(ckpt["decoder"]); dec.eval()
import engine, numpy as np
grid = engine.embed_seeds(np.random.randint(0, 2, (1, 16, 16), dtype=np.uint8))
x = torch.from_numpy(grid.astype(np.float32)).unsqueeze(1)
with torch.no_grad():
z = enc(x) # (1, 1024)
recon = torch.sigmoid(dec(z)).squeeze() > 0.5
Place checkpoints/best.pt in the repository root to run the diagnostics
unmodified β they all load that path.
Checkpoint contents: encoder, decoder (state dicts), step, metrics,
per_q (per-lifespan-quartile validation metrics).
269,139,477 bytes, SHA-256 b2a2ca4b9e19c9e24070b347d45ccf9ec72261a74ae43a62dccb84dfc9247243.
Architecture
67,281,873 parameters, CPU-only training, 150,000 steps (~30 h).
- Encoder (tile-disjoint). Three
kernel=2, stride=2downsample stages with1Γ1channel-mixing refines, then a linear projection to βΒΉβ°Β²β΄. Each of the 16Γ16 trunk positions sees exactly one disjoint 8Γ8 input tile β no overlapping receptive fields.python3 model.pyverifies this: flip one input pixel and exactly 1 of 256 trunk positions changes, while ~988 of the 1024 latent dimensions do. - Decoder (halo-free). Linear projection, three
PixelShuffle2Γ upsamples withkernel=1convolutions, final1Γ1conv. No layer mixes signal between adjacent output pixels, so the decoder cannot paint a probability halo around true cells β which is what makes near-exact cell placement possible.
Trained with four losses (reconstruction, a smoothness term matching latent
cosine to frame IoU, a soft norm bound, and angular uniformity) under three
schedules that are required for convergence. Details in
design/03_final_architecture.md.
Intended use
Reproducing and extending the measurements in the linked repository. This is a research artifact for studying representation properties, not a component to build on β the limitations below are the finding, not bugs to work around.
Known limitations
These are measured, with the producing script named. Full tables in RESULTS.md.
- Does not linearize the dynamics. A learned
z_t β z_{t+1}predictor collapses under closed-loop rollout β F1 0.344 Β± 0.011 at horizon 1 to 0.009 Β± 0.003 at horizon 60 β while the teacher-forced ceiling stays flat at 0.929β0.946. Predicting no change beats it at every horizon. (dynamics_probe.py,persistence_baseline.py) - Worse than nine statistics at describing behaviour. 0.625 Β± 0.012 balanced
accuracy on four held-out behaviour classes, against 0.842 Β± 0.010 for nine
hand-computed population statistics. (
probe_behavior_class.py) - Not translation invariant. A three-cell diagonal displacement of an
identical trajectory drops latent cosine to 0.294, at the cross-seed floor of
0.115 Β± 0.207. This follows from the smoothness objective, which trains cosine
toward frame IoU. (
n4_offset_curve.py) - Placement-bound. Reconstruction F1 0.921 at the trained centre, 0.325 at
the grid border. Seeds were trained at centre-biased offsets in [24, 88].
(
border_test.py) - Confidently wrong off-manifold. Latents sampled from the prior decode to
~6.7Γ the real live-cell density while the decoder reports max-probability
1.000. Decoder confidence is not a validity signal.
(
world_model_readiness.py)
Training data
1.5M random 16Γ16 seeds simulated under B3/S23 on a 128Γ128 grid, embedded at centre-biased random offsets. Trajectories are generated on the fly by the reference simulator rather than stored. See the dataset.
Citation
@misc{koegler2026golae,
author = {Koegler, Maxwell},
title = {{Game of Life autoencoder (step 148,500)}},
year = {2026},
publisher = {Mantra Labs},
url = {https://huggingface.co/themantralab/gol-emergence-pipeline}
}