phenotypic.tune.run_held_out#
- phenotypic.tune.run_held_out(spec: Any, winner: Any, split: Any, images_by_name: dict[str, Any], *, current_identity: str | None = None) GeneralizationReport[source]#
Re-evaluate the
winneron the held-out plates → aGeneralizationReport.The report-only generalization pass (RESOLVED design — held-out orchestration lives in the run layer, never the engine). It re-runs the winner’s parameters through the spec’s own
Evaluatorover the held-out plates only, then builds a 3-tier verdict bysplit.kind:"group": a real held-out gap (the strongest cross-batch test);"within_group": a real held-out gap plus a weaker-guarantee caveat;"none": data-poor — no untouched held-out set, so no real gap (gap=None,flagged=False); the report falls back to a calibration-stability estimate carrying the winner’sTrial.gap(the per-trial calibration dispersion) withcv_deferred=True.
The winner is never changed;
Trial.gapis not mutated (Option A). Whencurrent_identitydiffers fromsplit.dataset_identitythe report’sdataset_changedis set with a drift warning (the split is reused verbatim on resume; this only annotates the verdict).- Parameters:
spec (Any) – The resolved tuning spec — only
spec.evaluator,spec.pipeline,spec.scorer, andspec.held_out(the gap margins) are read.winner (Any) – The winning trial —
winner.params,winner.score, andwinner.gapare read.split (Any) – The resolved split (its
kind/held_out/group_key/within_group_caveat/dataset_identitydrive the verdict).images_by_name (dict[str, Any]) –
{image.name: image}of the loaded plates.current_identity (str | None) – The current dataset identity (a mismatch vs
split.dataset_identitysetsdataset_changed);Noneskips the drift check.
- Returns:
The
GeneralizationReportto write togeneralization.json.- Return type: