multigeom.pipeline.estimator_variance#

Monte-Carlo variance of the conditional-pair (CC) estimator of G(x) versus the unconditional-conditional (UC) form (paper App. “Conditional-pair estimator”):

    "On a small held-out set of test images with multiple independent Monte
     Carlo realisations per image, the CC estimator yields top-5 eigenvalues of
     G(x) with ~80-95% lower Monte Carlo variance than the UC form at matched
     compute; the UC top eigenvalue further differs from the CC value by a
     per-image-dependent factor of roughly 5-50x."

The two estimators ------------------ Both follow Algorithm 1
(multigeom.geometry.estimator.conditional_pair_estimate): the same log-τ grid and
trapezoid weights w_j, the same forward diffusion x_t = √ᾱ_t x + √(1−ᾱ_t) z, the same
null-token Tweedie denoising x̂ = clip((x_t − √(1−ᾱ_t) ε_θ(x_t,t,0)) / √ᾱ_t, −1, 1), and
the same response sampler r = f_φ(x̂) + σ ξ. They differ only in the row appended to D:

    CC:  √(w_j / (2 N_MC)) · (ε_θ(x_t,t,r_1) − ε_θ(x_t,t,r_2)),   r_1, r_2 i.i.d.
    UC:  √(w_j /    N_MC ) · (ε_θ(x_t,t,r)   − ε_θ(x_t,t,0)),     one r

Scaling of the UC rows. Eq. (eq:line) writes the diffused Fisher as
(1/τ²)·Cov_r[x̂(x_t,r)], and x̂(x_t,r) − x̂(x_t,r') = −√τ (ε(r) − ε(r')) in the
ε-parametrisation. For i.i.d. r_1, r_2, E[(ε_1−ε_2)(ε_1−ε_2)ᵀ] = 2 Cov_r[ε(r)],
hence the 1/2 in CC. The UC form instead centres one draw on the
unconditional prediction. If the models are correct and r is drawn from the
diffused likelihood, the tower property gives E_r[ε(x_t,t,r)] = ε(x_t,t,0), so

    E[(ε(r) − ε(0))(ε(r) − ε(0))ᵀ] = Cov_r[ε(r)],

with no factor 2: the UC row weight is √(w_j/N_MC), and E[D_UCᵀ D_UC] =
E[D_CCᵀ D_CC] = Σ_j w_j E_z Cov_r[ε]. When the null-token prediction is not the
mean of the conditional predictions (imperfect CFG training, or the
point-mass sampler r ~ p(r | x̂(x_t)) instead of p_t(r | x_t)), the UC form
picks up an additional term Σ_j w_j E_z[b_j b_jᵀ] with
b_j = E_r[ε(x_t,t,r)] − ε(x_t,t,0); the CC form is free of it because b_j is
common to both draws and cancels in the subtraction.

Compute. With the repo's Tweedie sampler the null-token pass is needed for x̂
anyway; UC reuses it as its subtraction term, so one UC Monte-Carlo sample
costs 2 UNet passes (null + one conditional) and one CC sample costs 3 (null +
two conditionals). `--compute-match passes` (default) gives UC
round(1.5·N_MC / B)·B samples per timestep so both estimators spend the same
number of UNet passes; `--compute-match samples` uses the same N_MC for both
(the convention of the original measurement script, whose sampler took
responses from the clean image and therefore spent 2 passes on each
estimator).

Output (JSON): for each image the top-k eigenvalues of every realisation of
both estimators, their across-run mean, variance and CV² = Var/mean², the
per-eigenvalue reductions (Var_UC − Var_CC)/Var_UC and (CV²_UC − CV²_CC)/CV²_UC,
the ratio mean λ_1^UC / mean λ_1^CC, and the top-k subspace alignment between
the CC and UC eigenvectors (averaged over runs); plus aggregate medians and a
provenance record. The raw-variance reduction mixes noise with the overall
scale of the two estimates (UC eigenvalues are larger); CV² is scale-free.

Usage:
    python -m multigeom.pipeline.estimator_variance \
        --encoder-cfg inception \
        --encoder-ckpt runs/encoders/inception/V1/best_model.pt \
        --diffusion-ckpt runs/diffusion/inception/V1/final_model.pt \
        --n-images 6 --n-runs 6 --n-mc 100 \
        --out runs/analysis/estimator_variance_inception_V1.json

Functions

main([argv])

Compare the Monte-Carlo variance of the two estimators (command-line entry point).

parse_args([argv])

Command-line arguments of python -m multigeom.pipeline.estimator_variance.

run_variance_study(images, encoder, unet, ...)

Run both estimators n_runs times on every image with independent seeds.

uc_samples_for_matched_passes(n_mc_cc, ...)

UC sample count with the same number of UNet passes as CC (3 vs 2 per sample).