Skip to content

Add barren-plateau control, loss-term gradient conflict, and parameter-space Fisher - #6

Open
Adithyaphani wants to merge 4 commits into
JitheshMithra:mainfrom
Adithyaphani:feat/trainability-diagnostics-role3
Open

Add barren-plateau control, loss-term gradient conflict, and parameter-space Fisher#6
Adithyaphani wants to merge 4 commits into
JitheshMithra:mainfrom
Adithyaphani:feat/trainability-diagnostics-role3

Conversation

@Adithyaphani

Copy link
Copy Markdown

Three scripts in SPECops/src/, no new dependencies, no existing file changed except three
added rows and three glossary bullets in REPRODUCIBILITY.md.

These fill gaps rather than duplicate: gradient_variance.py, effective_rank.py,
activation_diversity.py, shapley_layer_attribution.py, loss_landscape_slice.py and the
fourier_spectrumshock_spectrumfrequency_unit_conversion chain already cover the
diagnostics they cover. PennyLane autodiff throughout — no torch.

1. barren_plateau_control.py — validates gradient_variance.py

gradient_variance_results.csv measures whether our ansatz sits on a barren plateau. Nothing
currently establishes that the estimator would notice one. This runs the identical protocol
(N random inits → variance of one fixed gradient component) on the random parameterised circuit
family of McClean et al. 2018, where the plateau is proven, and fits the decay.

200 inits, depth 2n:

n_qubits=2  grad_variance=2.175e-02
n_qubits=4  grad_variance=1.250e-03
n_qubits=6  grad_variance=1.016e-04
n_qubits=8  grad_variance=1.255e-05

fitted slope (ln)  -1.244
published          -1.374     (McClean et al. 2018, Fig. 5)
r^2                 0.995
relative error      9.4%

Exits non-zero on failure, so it can gate a sweep. This is what lets a flat
gradient_variance_results.csv be reported as "no plateau at this scale" rather than "our
estimator saw nothing".

--also-sweep-grid additionally runs the control at our own 3/4/5 qubit counts, where variance
falls 5.978e-03 → 3.863e-04, a ~15× decay across the same range the QAPINN sweep covers. That's
the number gradient_variance_results.csv should be read against.

Two traps are encoded as defaults: McClean plot in natural log, not log10 (a factor of 2.303
waiting to be misread), and depth has to scale with qubit count or the second moment hasn't
converged and the control fails for reasons unrelated to us.

2. gradient_conflict.py — do the two loss terms agree?

loop.py minimises mse_u + mse_f on shared parameters and nothing measures whether they pull
the same way. It matters for reading the plateau numbers honestly: a stalled config could be a
vanishing gradient or two terms cancelling, and those have opposite fixes (change the ansatz vs.
reweight the loss). loss_landscape_slice.py sees the surface shape but not which term pulls
where.

Full 12-config grid at random init:

config cos (all params) cos (W_q only)
q3_r1 +0.519 −0.495
q4_r1 −0.184 −0.901
q5_r3 +0.712 +0.378
q5_r5 +0.487 +0.458

cos_wq_only is lower than cos_all_params in all 12 configs without exception — the
quantum layer's parameters are consistently the more contested ones, with the classical pre/post
layers absorbing the disagreement. Individual signs are noisy at the default --n-f-batch 5 and
shouldn't be read config-by-config; the ordering is what's stable.
norm_ratio_data_over_residual runs 2.27–53.6 across every config, so the data term also
dominates the update magnitude everywhere.

3. fisher_effective_dimension.py — is the parameter reduction real?

effective_rank.py measures the entropy rank of the post-quantum-layer output matrix. This
measures the same quantity in parameter space: the spectrum of F = JᵀJ/N with
J[i,k] = ∂u(tᵢ,xᵢ)/∂paramₖ. param_count in sweep_results.csv is nominal — it counts array
entries. Rank utilisation says how many of those directions move the model at all.

config params Fisher entropy rank utilisation normalised d_eff
q3_r1 19 1.08 0.057 0.194
q4_r3 41 1.13 0.028 0.129
q5_r5 71 1.37 0.019 0.110

Utilisation falls monotonically as parameters are added — the extra parameters are not buying
proportional reachable capacity.

Caveat, in the script and worth stating here: these are random inits, where the model is close
to linear and low rank is partly expected.
The number that belongs in the report is the
trained one.

Verification

All three were developed and run against main.build_model / main.make_training_data, full
12-config grid for the latter two. Same subprocess-per-config isolation as gradient_variance.py
where the loss goes through pde_residual (three levels of autodiff); skipped where it doesn't,
with a comment explaining which case applies rather than copying the pattern blindly.

Since this repo tracks results/*.csv and *.json as evidence, the generated outputs are
committed alongside the scripts.

Notes for review

  • No sweep_checkpoints/ on the machine these ran on, so every row is random_init.
    Rerunning gradient_conflict.py and fisher_effective_dimension.py with
    --checkpoint-dir sweep_checkpoints on a machine that has them produces the trained-minimum
    rows as well — that's the version worth quoting, particularly for the Fisher table. Both
    scripts already handle it; it's one flag.
  • barren_plateau_control.py is the one I'd merge first even if the other two need work — it
    upgrades a number already in the report from a measurement to a validated measurement.
  • The Fisher script takes --model main_classical for the classical control, resolved by
    importlib the way eval.py does. Untested against that module; if its interface differs
    from main.py's build_model, the fallback path uses the module directly.
  • barren_plateau_control.csv is appended to, so a --also-sweep-grid run leaves a duplicate
    n_qubits=4 row from the two overlapping sweeps. Noted in the glossary. The fit JSON covers
    only the 2/4/6/8 control sweep.

@Adithyaphani

Copy link
Copy Markdown
Author

@JitheshMithra let me know any changes to be made and dropped a message in Discord have a glance into it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant