MachineSex/tests/test_neural_validation.py
Giorgio Gilestro 840b6b00b3 Layer 1.5: architecture-general neural existence proof
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>
2026-07-04 21:02:49 +01:00

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}"