Infer each item’s deviation from the collection mean using only raw values.
Every item should receive its own value minus the mean of the collection. The mean is absent from the input, so the model must combine peer information and use it when decoding each original coordinate.
Seed 3710 on gpu: 9 of 9 behavioral checks met. See the measurements below.
Insights
The model can compare each value with the collection’s average without being given that average. Independently varying collection locations make an item’s raw value alone a poor predictor. One learned branch summary works together with each repeated target’s aligned visible value; the summary is not the decoder’s only source of information.
Common translations preserve the correct deviations, while complete-item permutations should move predictions with their items. Both controls pass, although error increases after translation and permutation drift is nonzero. The result supports approximate aggregation and routing for six-item collections. It does not establish exact set equivariance, variable-length behavior, or peer selection by category.
Setup
Code
"""Infer every item's deviation from the mean of six raw peer values.Wide random row locations make the item's own value a poor shortcut. A sharedsummary must support the repeated predictions. Common translations preservetargets, while whole-item permutations should permute the answers with them.Run this file with --help for seed, training-budget, and reporting options."""from __future__ import annotationsfrom collections.abc import Iteratorfrom functools import partialimport lightning.pytorch as litimport numpy as npimport torchfrom reporting import reportimport relflow as rfPROOF_ID ="P035"ITEMS =6
Adding 1 to every value moves the mean to 3.5. The first example’s deviation targets remain correct. This illustrates the common-translation intervention.
Reversing the first collection preserves its mean. The targets move with their items, and predictions should follow the same order. These are mathematically correct targets; the proof measures how closely learned predictions respect this relationship.
Synthetic data and controls
Code
def records(*, rows: int, seed: int) -> Iterator[dict]:"""Generate collections with independent locations and centered residuals.""" rng = np.random.default_rng(seed)for _ inrange(rows): basis = rng.normal(size=ITEMS) basis -= basis.mean() basis /= np.sqrt(np.mean(np.square(basis))) scale =float(rng.uniform(0.25, 1.1)) mean =float(rng.uniform(-3.5, 3.5)) deviations = scale * basis values = mean + deviations items: list[dict[str, float]] = []for value, deviation inzip(values, deviations, strict=True): item = {"value": float(value), "deviation": float(deviation)} items.append(item)yield {"items": items}def targets(rows: list[dict]) -> np.ndarray:return np.asarray([item["deviation"] for row in rows for item in row["items"]])def predict(model: rf.Model, rows: list[dict]) -> np.ndarray: inputs = [ {"items": [{key: value for key, value in item.items() if key !="deviation"} for item in row["items"]]}for row in rows ] output = model.predict(inputs).to_pylist()return np.asarray( [value["content"] for row in output for value in row["predictions"]["collection/items/deviation"]] )def rmse(actual: np.ndarray, predicted: np.ndarray |float) ->float:returnfloat(np.sqrt(np.mean(np.square(actual - predicted))))def translate(rows: list[dict], seed: int) ->list[dict]:"""Shift visible values while retaining the original relative targets.""" rng = np.random.default_rng(seed) result = []for row in rows: offset =float(rng.uniform(-2.5, 2.5)) result.append({"items": [{**item, "value": item["value"] + offset} for item in row["items"]]})return resultdef permute_items(rows: list[dict], seed: int) ->tuple[list[dict], np.ndarray]:"""Reorder complete records and retain indices for comparing predictions.""" rng = np.random.default_rng(seed) result, flattened = [], []for index, row inenumerate(rows): order = rng.permutation(ITEMS) result.append({"items": [row["items"][i] for i in order]}) flattened.extend(index * ITEMS + order)return result, np.asarray(flattened)
Model tree
Figure 1: The item branch learns one summary and the root keeps its routed output. Each masked deviation also has its own visible value as query context.
The item branch uses rf.Attention(n_outputs=1, n_layers=2) and the root uses reduction=None. Each repeated target also has its aligned visible value as query context.
How it works
The learned summary can provide collection context to a decoder conditioned on each item’s visible value. Wide random shifts between rows make an item’s value alone a poor predictor of its deviation. Adding one constant to all six values preserves every target, and permuting whole items should reorder the predictions in exactly the same way.
Repeat three core seeds and ten calibration seeds. Test varying cardinality, empty collections, and missing values, and tighten the equivariance contract. The grouped case adds membership selection; the supplied-mean control removes aggregation.
Reproduce
Run by stable ID from the repository root:
uv run python proofs/run.py P035
Or run the self-contained script directly:
PYTHONPATH=proofs uv run python proofs/relational/ungrouped_peer_deviation.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.