World model test

September 10, 2026 · View on GitHub

Status: Release paired runs of tests/WorldModelTest.cpp and tests/CompressionTest.cpp, dim = 8, T = 16. Table is the k-cube Predictor (no a). Not re-run since WorldModel grew a. The tables were produced before the LCN weight layout changed (Sep 10, 2026); the same seeds now draw a different net, so a re-run gives different numbers with the same picture.

Definitions

Symbol / termMeaning
WorldModelFrozen Encoder plus trained Predictor. Does the k-cut. See world_model.md.
EncoderFrozen hypercube reservoir. One window in, one episode, N floats out.
PredictorLCN. This document's table is the k-cube map P(E(xₜ)) → E(xₜ₊₁). WorldModel now uses dim = k+1 and Pack is E(x) cat E(a); this test runs a constant dummy field of length 2ᵏ through the action encoder (no motor).
aAction field, length N. Constant fill here; how to paint a cardinal is later.
E(a)EncodeAction of that field: the whole output of a k-cube encoder. Extra bit-face of P.
DecoderReconstruction meter. k-face in, full field out. Not in the WorldModel loop.
dimEncoder cube dimension. These runs: 8.
NWindow length and encoder vertices, N = 2ᵈⁱᵐ = 256.
kDimension of the kept face. Strictly less than dim. These runs: 7, 6, 5.
subKept vertices, sub = 2ᵏ.
TEncoder passes per episode. These runs: 16.
leakEncoder leak rate. These runs: 0.25.
in_scaleEncoder input scaling. These runs: 0.8.
songOne two-sine draw: its own cycles, phases, amplitudes.
windowN consecutive samples of a song, laid on the cube.
hopSamples between window starts. These runs: hop = N.
pairTwo consecutive windows of the same song. Never across songs.
mixTrain songs. These runs: 640 songs, 8 windows, 4480 pairs.
valUnseen songs for restore-best only. These runs: 128 songs.
testHeld-out songs, not used to pick weights. These runs: 128 songs.
identityMSE of using E(xₜ) as the guess for E(xₜ₊₁). Copy-last.
next-powerMean square of E(xₜ₊₁). MSE of predicting nothing.
mse/identWorldModel pool MSE divided by identity.
mse/powerWorldModel pool MSE divided by next-power. Residual vs k-face energy.
field powerMean square of the sine field. These CompressionTest runs: 0.47638.
dimensional compressionFewer numbers: keep sub = 2ᵏ vertices out of N. Ratio N / sub. Proven by the cut.
semantic compressionThe kept numbers are the ones that matter: structure stays, junk is dropped. At these encoder knobs: rel ≈ 0.40 on jepa_encoder_test.md.
rel(noise/content) on the k-face divided by the same ratio on the field. Semantic score. These runs: ~0.40 at every k.

Look at test mse/power: you want it as low as you can get, with val mse/power about the same number.

The k-cut is dimensional compression: 256 numbers become 128, 64, or 32. That is true before any training. Semantic compression is the filter: the two-sine stays, white noise is damped more than on the raw samples. This document does not run that meter. The paired JepaEncoderTest at the same encoder does: rel ≈ 0.40 at k = 7, 6, and 5, and content RMSE stays large. Reconstruction and next-step here say the smaller face still carries the song and still has a next k-face. Together that is dimensional cut plus a live, filtered code.

The Encoder is frozen. WorldModelTest trains a Predictor on many two-sine songs and scores a held-out mix. CompressionTest, at the same encoder, trains a Decoder to put the field back from the k-face. Decoder is not in the WorldModel loop. Only k changes across the rows; Predictor depth is z_max = 3k. Span 5, tanh_last on, lr = 0.03. WorldModel 800 epochs, CompressionTest 1024 / 512 / 512 fields, 400 epochs.

ksubN / subtest mse/powerval mse/powertest mse/identrecon test MSErecon / powerrel
71280.1370.1360.0770.021414.5 %0.397
6640.1740.1700.0970.024535.1 %0.403
5320.3660.3610.2010.036517.7 %0.409

At k = 7, held residual is ~14 % of next-face energy and val is the same number. Copy-last loses by about 13×. The Decoder puts the field back to 4.5 % of field power. Dimensionally, half the cube is gone. What remains still holds the sines and still predicts the next face on new songs.

k = 6 is the same story, a little looser: held mse/power 0.174, val 0.170, reconstruction 5.1 %. Four times fewer latent vertices, almost the same next-step and almost the same reconstruction.

k = 5 still beats silence and copy-last (mse/power 0.37, mse/ident 0.20), and val still matches test. Reconstruction is 7.7 % of field power. The next-step residual has grown more than the reconstruction residual: the cut is starting to hurt prediction first.

WorldModel detail:

ktrain msetrain mse/powerval msetest mseidentity (test)next-power (test)
70.12275 → 0.003710.0370.012730.013430.1740.098
60.12748 → 0.008900.0880.016310.017280.1780.099
50.13725 → 0.025110.2170.039090.040580.2010.111

Train is tighter than held on every row. That gap is mix-fit, not a collapse: val and test stay together. Identity and next-power stay in the same ballpark (hop = N is still a real jump). k-faces stay live (mean |s| on a train window ~0.20–0.22; full-cube mean |z| = 0.213). Decoder input scale stays ~1.04, so the smaller face is not a gain trick.