Skip to content

feat: EP review phase 4 — diagnostics & monitoring for EP fits #1335

Description

@Jammy2211

Overview

Phase 4 of the EP framework review (umbrella: PyAutoMind/research/graphical_ep/ep_framework_review.md; audit #1332). EP fits currently emit one evidence/KL plot (graph.png) and a text graph.results; there is no machine-readable fit log, no record of how the mean field evolved, no per-factor status accounting, no guard against the F10 sigma-collapse pathology, and no post-fit summary helpers. This adds all of those, additively (no behaviour change to the fitting itself).

Autonomy: --auto, effective level supervised (feature cap). Plan below per contract; run parks at ship sign-off.
Coexistence note: PyAutoFit is also claimed by the parked ep-graphical-docs task (PR #1334, docs-only). This task's files (expectation_propagation/, new diagnostics module, test_autofit/graphical/) are disjoint from that diff (README, mean_field.py, composed_transform.py, abstract.py docstrings); disjointness is re-verified before ship. Human directed both to proceed in parallel.

Plan

New autofit/graphical/expectation_propagation/diagnostics.py:

  • MeanFieldSnapshot recording per factor-step: step index, factor name, status (success/updated/flag), factor log-evidence, factor KL, and per-variable (mean, std) of the global mean field (arrays summarised as mean-of-means / max-std).
  • EPDiagnostics collector — accumulates snapshots during a run; writers for:
    • ep_history.csv — step, factor, success, flag, log_evidence, kl_divergence;
    • mean_field_history.csv — step, variable, mean, std;
  • mean_field_summary(mean_field) — post-fit text table (variable, mean, std) usable at the end of any example.
  • check_sigma_collapse(...) — the F10 guard: flags variables whose std shrinks monotonically below a floor across steps; returned as warnings, logged at run end, and appended to the results text.

visualise.py upgrades:

  • Enable the (currently commented-out) per-factor evidence/KL curves as graph_factors.png.
  • New mean_field_evolution.png — per-variable mean ± std band vs step, from the diagnostics collector.

optimiser.py wiring:

  • EPOptimiser instantiates EPDiagnostics when paths is set; snapshot after each factor update (cheap float extraction); CSVs written at output_interval; final summary + collapse warnings emitted at run end.
  • Fix F3 while here: guard the unconditional self.visualiser() / _output_results at the end of ParallelEPOptimiser.run (crash when paths=None) — one-line, same file, in scope as the wiring touches these call sites.

Tests (test_autofit/graphical/functionality/test_diagnostics.py, numpy-only):

  • Tiny exact-conjugate graph run via EPOptimiser with paths at tmp_path → CSVs exist, expected columns, row counts match steps×factors; summary text contains all variables.
  • check_sigma_collapse fires on a synthetic collapsing history, silent on a healthy one.
  • ParallelEPOptimiser completion with paths=None no longer raises (F3).

Out of scope: wiring diagnostics calls into workspace examples (follow-up on the parked Phase 3 branch or later); richer aggregated posterior views (graphical_scoping.md limitation 3 — the CSV/plot layer here is its foundation).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions