Averaging identical encoded contributions removes the multiplicity needed to recover their sum.
Seed 3309 on gpu: 2 of 2 behavioral checks met. See the measurements below. The experiment code has changed since this run; these measurements describe its earlier version.
Insights
This Mean configuration discards the count required to recover a sum. With item attention disabled, averaging identical encoded contributions produces the same summary for one copy or many. A larger decoder cannot recover a distinction that no longer reaches it.
The model still learns the contribution average, showing that useful content survives. Its matching sum predictions are the intended limitation, even though the correct totals differ. To predict variable-length totals, preserve multiplicity through a suitable reduction or supply an explicit count. Mean remains useful when repeating the whole collection should leave the desired answer unchanged.
Setup
Code
"""Mean is a weighted-sum footgun when item cardinality varies.Learn the raw average while a no-attention Mean discards multiplicity.Run: uv run python proofs/run.py P013"""from __future__ import annotationsfrom collections.abc import Iteratorimport lightning.pytorch as litimport numpy as npimport torchfrom reporting import reportimport relflow as rfPROOF_ID ="P013"ITEMS =6
Examples
Targets use mask=True; the labels below are supervision hidden from the encoder.
This is the matched count-erasure control. Its encoded Mean summary matches the six-copy example, so the sum predictions agree even though their correct labels differ. The proof does not record those individual predicted values.
Changing the repeated value gives Mean different content to encode. The average target changes to −0.25, but multiplicity is still unavailable to the sum decoder.
Synthetic data and controls
Code
def repeated_contribution_records(*, rows: int, seed: int) -> Iterator[dict]:"""Draw variable counts of repeated products for the Mean counterexample.""" rng = np.random.default_rng(seed)for _ inrange(rows): count =int(rng.integers(1, ITEMS +1)) contribution =float(rng.uniform(-1.25, 1.25))yield {"items": [{"contribution": contribution}] * count,"mean_contribution": contribution,"weighted_sum": count * contribution, }def prediction(model: rf.Model, observations: list[dict], target: str) -> np.ndarray: inputs = [{"items": row["items"]} for row in observations] output = model.predict(inputs)["predictions"].to_pylist()return np.asarray([row[f"record/{target}"]["content"] for row in output], dtype=np.float64)def rmse(actual: np.ndarray, predicted: np.ndarray |float) ->float:returnfloat(np.sqrt(np.mean(np.square(actual - predicted))))def score(*, train: list[dict], test: list[dict], predicted: np.ndarray) ->dict[str, float]:"""Compare held-out RMSE with the constant training-target mean.""" actual = np.asarray([row["mean_contribution"] for row in test], dtype=np.float64) baseline_rmse = rmse( actual, float(np.asarray([row["mean_contribution"] for row in train], dtype=np.float64).mean()) ) measured = rmse(actual, predicted)return {"rmse": measured, "baseline_rmse": baseline_rmse, "nrmse": measured / baseline_rmse}
Model tree
Figure 1: Item attention is off and Mean removes contribution count; later root Attention cannot recover that lost distinction.
How it works
The item branch uses attention=None and rf.Mean(). Every item in a record repeats the same randomly drawn contribution. Averaging its identical encoded tokens produces the same representation for one repetition or six. No later decoder can reconstruct the removed count from that representation.
The model should learn the contribution average. A separate probe compares sum predictions for one and six copies of 0.75: those predictions must agree, although their correct sums are 0.75 and 4.5. The passing assertion therefore demonstrates an information-loss boundary, not successful sum learning.
Check the numerical invariance across seeds. Count-preserving routes are covered separately by Attention sums and visible count with Mean; neither changes what this no-attention Mean configuration discards.
The family’s promotion target is at least three core seeds and ten lightweight calibration seeds.
Reproduce
Run by stable ID from the repository root:
uv run python proofs/run.py P013
Or run the self-contained script directly:
PYTHONPATH=proofs uv run python proofs/aggregation/mean_erases_contribution_count.py
Add --accelerator gpu for CUDA or --seed 42 for another seeded experiment. --steps 2 checks execution with a short training budget; it is recorded as a smoke run.