Re-scopes Layer 2 into a cheaper, architecture-general neural collapse proof
before the LLM rung. Realises the same Wright–Fisher abstractions in real trained
generative models on a fully-synthetic sandbox with an exact oracle, reusing
knowledge.metrics/truth/seeding and the output contract so neural curves overlay
the Layer-1 analytic curves.
- src/neural/: synthetic token-grammar sandbox (lossless identity + stochastic
style), ExactOracle, HistogramModel bridge, generation loop, experiment runner
- HARD GATE passed: histogram lineage reproduces Layer 1 exactly (neutral decay,
exact H_eq, tracks run_lineage) — tests/test_neural_validation.py
- torch models: autoregressive RNN + MLP (VAE implemented, not yet fidelity-
passing); determinism seeding derived from the SeedSequence stream
- N0 bridge (neural g*=0.047 ≈ Layer-1 0.048), N1 collapse-in-weights, N2 phase
boundary, N5 architecture-generality (collapse + grounding-rescue in histogram
+ RNN + MLP). Manifests/configs committed; parquet gitignored, hashes tracked
- additive backward-compatible save_artifacts extension; Makefile neural targets
Finding: neural smoothing partially resists H-collapse, so forward-KL and tail
survival are the sharp neural collapse metrics (H is smooth, per Layer 1).
92 tests green. Remaining (tasks/todo.md): N4 merge, N2 refine, N3/N6, VAE
fidelity, MNIST tier, figures. LLM/LoRA rung and C3 deferred.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
100 lines
4.2 KiB
Python
100 lines
4.2 KiB
Python
"""Stage B — the HARD GATE: the neural runner reproduces the Layer-1 analytic core.
|
|
|
|
With ``model.kind == "histogram"`` the neural generational step (train-on-parent's-samples
|
|
+ grounding) is *exactly* neutral Wright-Fisher drift with immigration. This module asserts
|
|
that the neural runner reproduces the two closed forms Layer 1 is validated against
|
|
(blueprint 2.4-1 neutral heterozygosity decay, 2.4-3 exact mutation-drift equilibrium) and
|
|
that its mean H-trajectory tracks ``knowledge.lineage.run_lineage`` directly. If any of
|
|
these fail the neural plumbing is wrong — no real network should be trained until they pass.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import numpy as np
|
|
import pytest
|
|
|
|
from knowledge.lineage import run_lineage
|
|
from knowledge.seeding import spawn_seeds
|
|
from neural.generation_loop import run_generative_lineage
|
|
from neural.synthetic import make_mode_truth
|
|
from neural.config import SyntheticCfg
|
|
|
|
|
|
def theory_decay(H0: float, n: int, t: np.ndarray) -> np.ndarray:
|
|
return H0 * (1.0 - 1.0 / n) ** np.asarray(t, dtype=float)
|
|
|
|
|
|
def theory_H_eq(n: int, m: int, H_star: float) -> float:
|
|
return H_star * m * (2 * n + m - 1) / (n + 2 * n * m + m * m)
|
|
|
|
|
|
def _mean_H(cfg: dict, n_rep: int, master: int = 20260704) -> np.ndarray:
|
|
"""Mean heterozygosity trajectory over ``n_rep`` histogram-model replicates."""
|
|
seeds = spawn_seeds(master, n_rep)
|
|
Hs = [run_generative_lineage(cfg, int(s.generate_state(1)[0]))["heterozygosity"].to_numpy()
|
|
for s in seeds]
|
|
return np.mean(np.stack(Hs), axis=0)
|
|
|
|
|
|
# --- Pred. 1: neutral heterozygosity decay ----------------------------------------------
|
|
|
|
def test_bridge_neutral_decay_matches_theory():
|
|
K, n, gens, reps = 50, 100, 20, 800
|
|
cfg = {
|
|
"synthetic": {"K": K, "R": 1, "zipf_s": 1.1, "init": "uniform",
|
|
"style_len": 2, "style_vocab": 4, "id_base": 2},
|
|
"model": {"kind": "histogram"},
|
|
"dynamics": {"n": n, "grounding": {"m": 0}},
|
|
"generations": gens,
|
|
}
|
|
H_sim = _mean_H(cfg, reps)
|
|
t = np.arange(gens + 1)
|
|
H_theory = theory_decay(1.0 - 1.0 / K, n, t)
|
|
rel_err = np.abs(H_sim - H_theory) / H_theory
|
|
assert rel_err.max() < 0.03, f"max rel err {rel_err.max():.4f} exceeds 0.03"
|
|
|
|
|
|
# --- Pred. 3: exact mutation-drift equilibrium under grounding ---------------------------
|
|
|
|
def test_bridge_grounded_equilibrium_matches_theory():
|
|
K, n, m, gens, reps = 80, 100, 8, 220, 300
|
|
cfg = {
|
|
"synthetic": {"K": K, "R": 1, "zipf_s": 1.1, "init": "uniform",
|
|
"style_len": 2, "style_vocab": 4, "id_base": 2},
|
|
"model": {"kind": "histogram"},
|
|
"dynamics": {"n": n, "grounding": {"m": m}}, # R=1 -> proportional immigration
|
|
"generations": gens,
|
|
}
|
|
H_sim_traj = _mean_H(cfg, reps)
|
|
H_sim = float(H_sim_traj[-60:].mean()) # stationary average
|
|
td = make_mode_truth(SyntheticCfg(K=K, R=1, zipf_s=1.1))
|
|
H_star = 1.0 - float(np.sum(td.p_star ** 2))
|
|
H_eq = theory_H_eq(n, m, H_star)
|
|
assert H_sim == pytest.approx(H_eq, rel=0.05), f"sim {H_sim:.4f} vs theory {H_eq:.4f}"
|
|
|
|
|
|
# --- Direct bridge: histogram lineage tracks Layer-1 run_lineage -------------------------
|
|
|
|
def test_bridge_tracks_layer1_trajectory():
|
|
K, n, m, gens, reps = 60, 120, 6, 40, 400
|
|
neural_cfg = {
|
|
"synthetic": {"K": K, "R": 1, "zipf_s": 1.1, "init": "uniform",
|
|
"style_len": 2, "style_vocab": 4, "id_base": 2},
|
|
"model": {"kind": "histogram"},
|
|
"dynamics": {"n": n, "grounding": {"m": m}},
|
|
"generations": gens,
|
|
}
|
|
layer1_cfg = {
|
|
"truth": {"K": K, "R": 1, "zipf_s": 1.1, "init": "uniform"},
|
|
"dynamics": {"n": n, "grounding": {"m": m, "policy": "proportional"}},
|
|
"generations": gens,
|
|
}
|
|
seeds = spawn_seeds(20260704, reps)
|
|
H_neural = np.mean(np.stack([
|
|
run_generative_lineage(neural_cfg, int(s.generate_state(1)[0]))["heterozygosity"].to_numpy()
|
|
for s in seeds]), axis=0)
|
|
H_layer1 = np.mean(np.stack([
|
|
run_lineage(layer1_cfg, int(s.generate_state(1)[0]))["heterozygosity"].to_numpy()
|
|
for s in seeds]), axis=0)
|
|
rel_err = np.abs(H_neural - H_layer1) / H_layer1
|
|
assert rel_err.max() < 0.03, f"neural vs Layer-1 max rel err {rel_err.max():.4f}"
|