Diagnostics#

A barren plateau is a circuit whose gradients vanish as it widens, which leaves the optimizer nothing to follow. check_barren_plateau() samples gradients at uniformly random weights and compares their variance against a theoretical floor, so you can find out before spending the compute rather than after.

Run it as a pre-flight check:

import pyqit

trainer = pyqit.Trainer(max_epochs=50, check_bp=True, bp_samples=200)
history = trainer.fit(model, dm)

Or call it directly when you want the BPResult without training:

from pyqit.utils.diagnostic import check_barren_plateau

result = check_barren_plateau(model, dm, num_samples=200)
           BP Diagnostic Result : BARREN PLATEAU
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
┃ Metric / Layer              ┃    Value ┃         Status ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
│ Qubits                      │        4 │                │
│ Samples                     │      200 │                │
│ Circuit Executions          │      200 │                │
│ Expected Variance           │ 1.56e-02 │       Baseline │
│ Quantum Variance            │ 3.74e-03 │ BARREN PLATEAU │
├─────────────────────────────┼──────────┼────────────────┤
│ Layer: main_circuit.weights │   0.240x │      ← plateau │
└─────────────────────────────┴──────────┴────────────────┘

Reading the baseline#

The floor depends on how much of the circuit you measure. A local cost, meaning fewer measured wires than qubits, uses 1 / 2 ** n_qubits. A global cost uses 1 / (3 * 4 ** (n_qubits - 1)), which shrinks much faster. Classifier models scale the baseline further through their bp_scale_factor tag.

Only circuit weights are drawn at random. Classical weights, such as a regressor’s output scale or the dense layers of a hybrid, are held at their current values, so the reported variance is the circuit’s and not the product of the circuit’s gradient with a random scale. Their own gradients are still collected and reported as classical_variance. A jointly trained QuantumPipeline is sampled the same way, with the floor taken from its one trainable quantum stage.

Each sample costs one gradient, and what a gradient costs depends on the device. Under backprop it is one circuit execution. Under parameter-shift, which shot-based devices and hardware use, it is 1 + 2 * n_params. The result counts the executions the device ran and reports them as n_executions, so you know what bp_samples bought. The table renders through rich when it is installed and falls back to ASCII when it is not.