#!/usr/bin/env python3 """Summarize the closed Rain parameter-measurement development screen.""" from __future__ import annotations import json import math from pathlib import Path ROOT = Path(__file__).resolve().parents[1] RESULT_ROOT = ROOT / "results" / "ep_bias" / "s0" FILES = { "clean": "clean-e10-n10k-s1988.json", "raw": "raw-e10-n10k-r0p1-s1988.json", "same_rms_noise": "noise-e10-n10k-r0p1-s1988.json", "oracle": "oracle-e10-n10k-r0p1-s1988.json", "innovation_online": "innovation-e10-n10k-r0p1-p0p5-s1988.json", "innovation_cal64_online": "innovation-cal64-e10-n10k-r0p1-p0p5-s1988.json", "innovation_cal1000_frozen": ( "innovation-cal1000-frozen-e1-n10k-r0p1-p0p5-s1988.json"), "constant_cal1000_frozen": ( "constant-cal1000-frozen-e1-n10k-r0p1-p0p5-s1988.json"), } def read(name: str) -> dict: with (RESULT_ROOT / FILES[name]).open(encoding="utf-8") as handle: return json.load(handle) def finite_metric(metric: dict) -> bool: values = ( metric.get("train_cost"), metric.get("test_cost"), metric.get("train_accuracy"), metric.get("test_accuracy"), ) return all(value is not None and math.isfinite(float(value)) for value in values) def json_safe(value): if isinstance(value, float) and not math.isfinite(value): return None if isinstance(value, dict): return {key: json_safe(item) for key, item in value.items()} if isinstance(value, list): return [json_safe(item) for item in value] return value def main() -> None: records = {name: read(name) for name in FILES} rows = {} for name, record in records.items(): metrics = record["metrics"] rows[name] = { "epochs_completed": len(metrics), "all_metrics_finite": all(finite_metric(metric) for metric in metrics), "final_test_accuracy": metrics[-1]["test_accuracy"], "best_test_accuracy": max(metric["test_accuracy"] for metric in metrics), "final_corrector": json_safe(metrics[-1].get("corrector", {})), "protocol": record["protocol"], } report = { "stage": "rain_ep_parameter_measurement_s0", "status": "closed_negative_adapter_with_positive_bias_noise_control", "rows": rows, "observations": { "raw_structured_bias_nonfinite": not rows["raw"]["all_metrics_finite"], "same_rms_noise_remains_finite": rows["same_rms_noise"]["all_metrics_finite"], "clean_final_test_accuracy": rows["clean"]["final_test_accuracy"], "same_rms_noise_final_test_accuracy": rows[ "same_rms_noise"]["final_test_accuracy"], "innovation_online_final_test_accuracy": rows[ "innovation_online"]["final_test_accuracy"], "innovation_cal64_online_final_test_accuracy": rows[ "innovation_cal64_online"]["final_test_accuracy"], "innovation_cal1000_frozen_first_epoch_test_accuracy": rows[ "innovation_cal1000_frozen"]["final_test_accuracy"], "constant_cal1000_frozen_first_epoch_test_accuracy": rows[ "constant_cal1000_frozen"]["final_test_accuracy"], }, "interpretation": ( "At bias ratio 0.1, fixed structured parameter-measurement bias " "makes the raw run nonfinite while same-RMS zero-mean noise remains " "trainable. The parameter-level affine predictor does not recover " "clean learning under online, 64-batch warm-up, or matched 1000-batch " "frozen calibration, so this adapter is closed rather than promoted." ), "test_policy": "development_test_subset_observed_each_epoch", } output = RESULT_ROOT.parent / "s0_summary.json" output.write_text( json.dumps(report, indent=2, sort_keys=True, allow_nan=False) + "\n") print(json.dumps(report, indent=2, sort_keys=True, allow_nan=False)) if __name__ == "__main__": main()