About this map
Sections
What this is
Quantum algorithms are not written from scratch. They are assembled from a small number of reusable steps, and almost every published method is a different route through the same handful of them.
This is a map of those routes. Circles are the things an algorithm can be holding. Lines are the steps that carry you from one to the next. A method is a path across.
Nothing here is generated. Every line was read out of a paper and checked against it.
How to read it
- Something you can hold — a state, a matrix, a circuit, an answer.
- The same, in the middle of a step you have opened.
- A step. Someone has published a way through it.
- A step whose way through has not been pinned to one method.
- A step nothing published fills yet.
- A step you have opened. What is drawn inside it is how it was done.
- There is a record in the repository for this one.
How to move around
- Two fingers move the map. Pinch to zoom, or hold ctrl and scroll.
- Click a step to open it in place — everything else stays where it is.
- Click a name to read the full record without leaving the map.
- Arrow keys move, plus and minus zoom, zero puts it back.
What a line is claiming
A solid line means a paper puts those two steps together and we have the citation. A long-dashed line means the route is recorded but no single method has been named for that step. A short-dashed line means nothing published fills it — the step is real, the way through is not written yet.
A count after a step's name — ×T/h, ×O(κ) — means the route walks that step that many times rather than once. It is the source's own symbol, and the card says what it stands for and what one turn costs. A step with no count is a step no source we read said is repeated, which is not the same as one taken once.
A line drawn nested under another, on the soft shaded band behind it, is a narrower version of the line above it: the same construction, re-analysed or re-tuned, filling the same step. It is why two lines can draw the identical interior and still be two entries. Lines outside the band are alternatives to their neighbours, not versions of them.
The map does not hide the gaps. An empty step is drawn as an empty step.
What is not here yet
The map covers the algorithm literature. The repository covers circuits and primitives. They overlap less than you would expect, and where a method has no record we say so on its page rather than leaving the space blank.
Where something named here does have a record, its name links straight to it.
Method
Grow the circuit a layer at a time while training it
Do not settle the circuit before optimising it. Start shallow, train what is there, then hold most of it fixed and add the next layer on top — so every step of the search runs on a shallow circuit with few free parameters, which is where a gradient is still large enough to follow.
Open the full recordFills the slot: Minimise the objective over the parameters
Skolik et al. state the strategy in one sentence — "the circuit depth is incrementally grown during optimization, and only subsets of parameters are updated in each training step" — and then hedge the benefit they claim from it: "when considering sampling noise, this strategy can help avoid the problem of barren plateaus of the error surface". *Can help*, and under sampling noise; the reason offered is structural rather than incidental — "the low depth of circuits, low number of parameters trained in one step, and larger magnitude of gradients compared to training the full circuit". The evidence is the part to read before carrying the numbers anywhere, because it is *not chemistry*. The demonstration is "an image-classification task on handwritten digits", and there layerwise learning "attains an % lower generalization error on average in comparison to standard learning schemes for training quantum circuits of the same size", with "the percentage of runs that reach lower test errors ... up to % larger compared to training the full circuit". Both figures are relative to full-circuit training of the same size on that one benchmark, so neither is a claim about the molecular energies the rest of this region is drawn from.
A parameterised circuit family; an objective function of its parameters, evaluated only through estimates bought with a finite shot budget; a starting point; and a stopping rule — a tolerance, an iteration cap, or an exhausted budget.
Parameterised circuit family → State you can preparegrow circuit layers, then retrain in blocks
The ansatz is built layer by layer as (Eq. 3), where each layer factors as (Eq. 2), with a fixed qubit-connectivity operator held constant throughout training. assumption: the paper states 's structure can be arbitrary, so long as layers can be added successively; this paper's own experiments specialize to single-qubit Pauli rotations with built from CZ gates. Growth starts from initial layers (Eq. 1) and proceeds via two hyperparameters: , how many new layers are appended per step, and , the sliding window of trainable depth — e.g. with , , two layers are added each step and any layer more than four back from the current one is frozen. assumption: every layer's angles are initialized to zero when added, which the paper states adds degrees of freedom "without perturbing the current solution". approximation: instead of a joint gradient over the full -layer circuit from the start, phase one takes each step's gradient over only the unfrozen window; phase two drops the permanent freeze and alternates over training a fraction of parameters as one contiguous partition of layers — e.g. a quarter or a half — until convergence.
approximationassumption
A preparation routine for the state at the parameters the search stopped at, and the total number of objective evaluations it consumed. The routine is returned whether or not the search found a minimum; that it stopped is not evidence that it converged.
- Choose a parameterised trial state
Fix the gate structure of a circuit family and leave its rotation angles open. What comes back is not a circuit but the set of states the later optimisation is allowed to search — which is why this is a slot of its own and not a paragraph in one method's write-up.
Layerwise training reaches for this slot once per growth step, not once up front, so what it asks for is not a circuit but a layer it can keep appending. Eq. 4 gives the one it uses: over the qubits, with single-qubit generators drawn from the Pauli operators , , . One angle per qubit and none in the fixed , so a returned layer adds exactly free parameters, and since , a layer appended at zero angles contributes only its fixed until training moves them. assumption: the generators are sampled rather than designed — the paper builds "circuits that consist of layers of randomly chosen gates" after McClean et al., so nothing in this family argues that the target state lies inside it. The reported circuits stack those rotations with CZ gates "coupling arbitrary pairs of qubits" into all-to-all connected layers (Fig. 2).
assumption
given a parameterised circuit family built as a product of layers,
l_i(theta_i) = U_i(theta_i) W (Eq. 2)
with U_i(theta_i) = prod_{k=1..n} exp(-i theta_i,k V_k),
one generator V_k in {X,Y,Z} per qubit (Eq. 4)
and W a fixed two-qubit coupling layer (CZ gates here,
all-to-all connectivity) held constant for the whole run (Sec III, Fig. 2)
an objective L(theta) (binary cross-entropy in the paper's
demonstration) whose gradient is bought by the parameter-
shift rule, two device calls per trained parameter (Eq. 5, Eq. 9)
hyperparameters s (initial layers), p (layers added per
growth step), q (freeze horizon -- how far back from the
current layer a layer may sit and still be trained), el
(epochs per training step), r (fraction of the final-depth
circuit's layers trained per block in phase two)
requires the layer structure itself can be "arbitrary, as long as
they allow successively increasing the number of layers"; the
Pauli-rotation-plus-CZ form given above is this paper's own
numerical choice for its demonstration, not a requirement of
the strategy (Sec III)
# --- phase one: grow the circuit, train only the newest window -----------
L = s
theta_1 .. theta_s = 0 (Eq. 1)
# zero init "provides additional degrees of freedom for the
# optimization routine without perturbing the current
# solution" -- growth does not undo what phase one already
# found (Sec III)
trainable = { theta_1 .. theta_s }
repeat:
for el epochs:
for each theta_i in trainable:
g_i = parameter_shift_grad(theta_i)
# E(theta) = <psi| U(theta)^dagger M U(theta) |psi> (Eq. 7)
# dE/dtheta_i = r * ( E(theta + s_shift*e_i)
# - E(theta - s_shift*e_i) ) (Eq. 9)
# with r = 0.5 and s_shift = pi/(4r) = pi/2. The
# prefactor r is part of the estimator, not only
# of the shift: the raw difference of the two
# shifted expectation values is twice dE/dtheta_i.
# This r is Eq. 9's shift-rule constant, a
# DIFFERENT r from phase two's block fraction below
# each such evaluation costs measurements: cumulative
# count r_dev_i = r_dev_{i-1} + 2*|trainable|*m*b (Eq. 10)
theta_i <- update(theta_i, g_i)
# paper's demonstration uses Adam; not specific to
# the layerwise strategy itself (Sec IV A)
if L has reached the target depth, or the last growth step
did not improve the objective:
break (Sec III)
append p new layers theta_{L+1} .. theta_{L+p} = 0
L = L + p
trainable = { theta_i : i >= L - q }
# the paper defines q by prose, not by a formula: "layers
# more than [q] back from the current layer are frozen",
# illustrated with p = 2, q = 4. Read literally that
# leaves layers L-q .. L trainable, i.e. q+1 of them, and
# the predicate above is that reading (Sec III)
# UNSETTLED, and the paper does not resolve it: the reported
# experiment sets p = q = 2 "with one initial layer that is
# always active during training" and states "three layers
# are trained at once". Three is q+1 with no always-active
# layer counted, or q plus that always-active layer -- so
# the window is q+1 or q depending on how the sentence is
# parsed. If you implement this, fix the convention and
# check it against the paper's three-layer figure (Sec III, Sec IV D)
# the reported experiment also keeps its initial layer
# trainable for the whole of phase one, outside the
# sliding window (Sec IV D)
# --- phase two: retrain in larger contiguous blocks, to full depth -------
# phase one already gives "a sufficiently non-random initialization",
# which the paper gives as the reason it is now safe to widen the
# trainable window (Sec III)
partition theta_1 .. theta_L into contiguous blocks of size
round(r * L) # e.g. a quarter or a half of the circuit's layers (Sec III)
repeat, alternating over the blocks:
unfreeze one block, freeze every other layer
for el epochs:
for each theta_i in the unfrozen block:
g_i = parameter_shift_grad(theta_i) (Eq. 9)
theta_i <- update(theta_i, g_i)
until the objective stops improving
# no more permanent freezing here -- this is what lets phase two
# eventually move every parameter, unlike phase one (Sec III)
return theta_1 .. theta_L and the cumulative device measurement
count r_dev_L (Eq. 10)
# MEASURED, not proved, and only in the noisy regime the paper adds
# on purpose: on one 8-qubit, 21-layer, fully-connected MNIST
# six-vs-nine instance with finite shots (m=10, b=20, 100 runs),
# the best layerwise configuration reaches a lower average test
# error, and about half the cumulative measurements, of the
# highest-success-probability full-circuit run (Sec IV D, Fig. 3, Fig. 4)
# under exact gradients (m = infinity) the paper reports "all tuned
# training strategies seem to perform similarly" -- the advantage
# above is a shot-noise-regime result, not a property that
# distinguishes the two ansatz-growth strategies on their own (Sec III, Appendix)
# the authors expect the advantage mainly with LOCAL cost functions;
# a global cost function hits barren plateaus even at shallow
# depth, which layerwise growth does not fix (Sec III)Skolik, McClean, Mohseni, van der Smagt and Leib count device measurements, not gates: cumulatively (Eq. 10) — two shifted evaluations per trained parameter by the parameter-shift rule (Eq. 9), shots per expectation value ( under operator averaging), samples per batch. A layer carries one angle per qubit (Eq. 4), so layerwise training shrinks per step at the price of more epochs, and nothing bounds the step count: layers are added until they stop improving the objective or a chosen depth is reached, then phase two sweeps "until the algorithm converges". Measured, not proved: on one 8-qubit, 21-layer, fully connected MNIST six-versus-nine instance (, , 100 runs, diverged runs excluded from the averages), the best layerwise configuration converges in about half the cumulative measurements — Fig. 3 plots that count as runtime at an assumed 10 kHz — of the highest-success-probability CDL configuration, which the paper notes is also its slowest. With exact gradients (, ) the appendix reports QPU calls almost equal. The authors expect an advantage mostly with local cost functions.
None found yet.
None found yet.
Skolik's own notebook on TensorFlow Quantum's `research` branch
- Layerwise learning for quantum neural networks
Andrea Skolik, Jarrod R. McClean, Masoud Mohseni, Patrick van der Smagt, Martin Leib · 2020
- TensorFlow Quantum: A Software Framework for Quantum Machine Learning
Michael Broughton, Guillaume Verdon, Trevor McCourt, Antonio J. Martinez, Jae Hyeon Yoo, Sergei V. Isakov, Philip Massey, Ramin Halavati, Murphy Yuezhen Niu, Alexander Zlokapa, Evan Peters, Owen Lockwood, Andrea Skolik, Sofiene Jerbi, Vedran Dunjko, Martin Leib, Michael Streif, David Von Dollen, Hongxiang Chen, Shuxiang Cao, Roeland Wiersema, Hsin-Yuan Huang, Jarrod R. McClean, Ryan Babbush, Sergio Boixo, Dave Bacon, Alan K. Ho, Hartmut Neven, Masoud Mohseni · 2020
About
This is the method's first author writing the method down in code: the notebook's third cell, the second of its markdown cells, reads "Author : Andrea Skolik", "Contributors : Masoud Mohseni", "Created : 2019", "Last updated : 2020-Jun-29", and the paper it belongs to closes by thanking "the TensorFlow Quantum team for providing early access to the library, which was used to perform the simulations in this work". The branch says what the directory is for — the `research` branch README is a heading, "Research", and one sentence, "Each directory in this branch corresponds to an example application in the TensorFlow Quantum whitepaper", whose last three words are a markdown link to arXiv:2003.02989 — and the whitepaper's own section V B 2, "Layerwise quantum circuit learning", claims that "a complete implementation of both phases can be found in the accompanying notebook" and prints the path `research/layerwise_learning/layerwise_learning.ipynb`. Skolik's companion post on the TensorFlow blog, "Layerwise learning for Quantum Neural Networks" of 10 August 2020, "Posted by Andrea Skolik, Volkswagen AG and Leiden University", sends a reader to the same file: "If you'd like to play with the code for this example yourself, check out the notebook on layerwise learning in the TFQ research repository, where we train a QNN on a simulated quantum computer!". The problem statement the notebook opens with is the paper's — "we successively add layers to a QNN during training, which does not only make training faster, but also ensures a better signal-to-noise ratio compared to training the full circuit when done on real hardware" — and it names the constraint the strategy is aimed at: "As the gradients produced by circuits grow smaller, we need more and more measurements from a quantum device to accurately estimate them."
Methods
A layer is `create_layer(qubits, layer_id)`, which picks one of `cirq.rx`, `cirq.ry`, `cirq.rz` per qubit by `random.choice(gate_set)` and follows them with `cirq.CZ(control, target)` over `zip(qubits, qubits[1:])`, and returns three things — the gates bound to the literal angle `0`, the same gates carrying `sympy.Symbol` angles, and the symbols. Phase one is a bare loop over `range(n_layer_steps)` that appends `n_layers_to_add` fresh layers, rebuilds the whole circuit as `circuit += symbol_layers`, appends `cirq.X(readout)`, `cirq.H(readout)`, `cirq.X(readout)` and measures `cirq.Z(readout)`, then wraps it in `tfq.layers.PQC(model_circuit=circuit, operators=readout_op, differentiator=tfq.differentiators.ParameterShift(), initializer=tf.keras.initializers.Zeros)` inside a `tf.keras.Sequential`, compiles with `tf.keras.losses.squared_hinge` and `tf.keras.optimizers.Adam(learning_rate=0.01)`, carries the previous step's angles forward by `model.set_weights([np.pad(weights, (0, n_qubits*n_layers_to_add))])` so the new layer starts at zero, and fits for 20 epochs. **The freezing is the only departure from the paper the notebook flags in its own prose, and it is not the only departure.** The markdown cell above the loop says "We are not going to freeze the previous layers in phase one in this implementation, but simply grow the circuit incrementally", where the paper's phase one trains only a sliding window and the blog post describes the reported experiment as "we add two layers in each step, and freeze the parameters of all previous layers, except the start layer, such that we only train three layers in each step". Three more go unflagged: the `cirq.CZ` ladder against the paper's "circuit with fully-connected layers as described in section III" (chosen there "for our numerical investigations" although "not realistic on NISQ hardware"), `squared_hinge` against "We use the binary cross-entropy as the training objective", and `n_qubits = 6` at ten layers against "we pick a circuit with 8 qubits and 21 layers for our experiments" — and the notebook credits the ladder elsewhere anyway, "a ladder of CZ gates that connect them. This is the same structure as used in [2]", its reference 2 being McClean, Boixo, Smelyanskiy, Babbush and Neven on barren plateaus rather than the layerwise paper. The digit pair and the data encoding are two further departures, recorded in `data`. **The notebook also contradicts itself about the freezing, and a reader meets the wrong side first**: the markdown cell that introduces the two phases still says "we add another set of layers and freeze the parameters of the previous step's layers", nine cells above the cell that says it does not. The Keras summaries printed in the saved output settle which sentence the code follows: `Total params` runs 12, 24, 36, 48, 60 with `Non-trainable params: 0` at every step, so every parameter present is trained at every step and phase one here is layer growth with no freezing in it at all. Phase two does freeze. `train_partition(circuit, trained_weights)` is handed a circuit assembled from `symbol_layers` for the half being trained and, for the other half, layers whose gates have been rebuilt with numeric angles — the notebook's own comment is "We can't alter a gate's parameter directly after it was initialized, so we simply initialize a new gate with the new parameter by using a slightly ugly hack to determine the gate type", and the hack is `if str(g)[:2] == 'Rx':` and its two siblings, popping angles off a reversed copy of the weight vector. With `partition_percentage = 0.5` and `n_sweeps = 2` it alternates the two halves four times, and the summaries read `Total params: 30`, exactly half of 60.
Data
MNIST, loaded by `tf.keras.datasets.mnist.load_data()` and cut down hard. The pair is threes against sixes — `y in [3, 6]`, with `convert_label` sending a 3 to `1.0` and everything else to `-1.0` — which is not the pair the paper reports; the paper's circuit "learns to distinguish between the numbers six and nine". `reduce_image` resizes each image to by `tf.image.resize` and divides by 255; `remove_contradicting` then drops images whose downsampled greyscale array maps to both labels, keying on `str(x)` for the float array `reduce_image` returned rather than on any bitstring, so it runs before thresholding and does not catch two images that agree bit for bit but differ in grey value; and `convert_to_circuit` puts a `cirq.X` on qubit for every pixel above 0.5, so what the circuit finally sees is a binary bitstring rather than the paper's principal-component angles ("we use qubit encoding in combination with principal component analysis (PCA)"). The saved output records 11520 filtered training examples and 1906 filtered test examples, of which `NUM_EXAMPLES = 128` are kept for training. Two things a reader should check before quoting the counts. The notebook prints its own second count wrong — `print("Number of original test examples:", len(x_train))` — so the two 60000s in the output are the same number twice. And the data circuits and the model circuit are not built on the same register: `convert_to_circuit` lays the 16 flattened pixels on `cirq.GridQubit.rect(1, len(values))`, that is qubits to , while the trained circuit lives on `cirq.GridQubit.rect(1, n_qubits)` with `n_qubits = 6` and the observable is `cirq.Z` on `cirq.GridQubit(0, 5)`, so ten of the sixteen pixel qubits carry a data gate and are then touched by no layer and by no measurement.
Code
https://github.com/tensorflow/quantum, branch `research` — not `master`, which does not contain this directory at all — at path `layerwise_learning/layerwise_learning.ipynb`. Python in a Colab notebook, Apache License 2.0: the branch carries a top-level `LICENSE` whose first two lines are "Apache License" and "Version 2.0, January 2004", the first markdown cell reads "Copyright 2020 The TensorFlow Quantum Authors." under five hash marks, and the first code cell is the header itself, its two opening comment lines reading "Licensed under the Apache License, Version 2.0 (the "License");" and "you may not use this file except in compliance with the License." Read 2026-08-27 at blob `a45dbbbe42c6d57561efe1408696633150dafc6f`: 166,906 bytes, 1,167 lines of notebook JSON, 22 cells of which 12 are code and 10 markdown, and 254 lines of Python across the code cells. There are no classes and no importable module — the things to open are `create_layer(qubits, layer_id)`, the phase-one `for layer_id in range(n_layer_steps)` loop, and `train_partition(circuit, trained_weights)`, and phase two reads the notebook globals `layers`, `symbol_layers`, `weights`, `readout` and `readout_op` that phase one left behind, so the cells only run in order. **The content is Skolik's, and the branch has been frozen since 2022.** The file arrived on 2020-02-23 as "Added initial notebook from Andrea"; everything this entry describes as phase two, `train_partition` included, arrived with commit `d905f64c08d5` of 2020-07-01, `+745 -35`, whose message is "Updated LL example" for pull request 279 followed by "@askolik Sent along an update for the layerwise learning notebook to more closely reflect what was done in their new publication: https://arxiv.org/abs/2006.14904" — so the git author, Michael Broughton, is the conduit rather than the author. The three commits after it are version bumps, the last being `92c952f9d29b` of 2022-03-04 by Michael Broughton, "Bump research branch to tf 2.7.0."; the `research` head is `8756d82c1a2c110670919d80fee8e611bd00961e` of the same day, and the notebook still opens with `!pip install --upgrade tensorflow==2.7.0` and `!pip install tensorflow-quantum`. Meanwhile `master` was last committed 2026-07-14, its newest release is `v0.7.6` published 2026-02-25, and `tensorflow-quantum` 0.7.6 was uploaded to PyPI on 2026-02-18 requiring Python `>=3.10`. No tag contains this file, so there is no released version of the notebook to pin.
Results
Everything is simulated — `tfq.layers.PQC` on the default TFQ simulator, no device anywhere in the file — and the only numbers are the squared-hinge losses the saved outputs recorded, because `model.compile` is called with no `metrics=` argument, so `model.evaluate` returns loss alone and no accuracy is computed at any point. Phase one's five `model.evaluate` calls on the 1906 held-out examples read 1.0000, 0.8751, 0.8434, 0.8435 and 0.8098 as the circuit grows from 2 to 10 layers, so the fourth step made it very slightly worse; phase two's four partition trainings read 0.7363, 0.7006, 0.6960 and 0.6798 on the same held-out set. Phase one therefore moved the held-out loss by 0.19, from 1.0000 to 0.8098, across five growth steps, and phase two took it a further 0.13 on a circuit that had stopped growing. Two `plt.plot(training_history)` cells are the only figures, and only the second mixes the phases: `training_history` holds phase one's five entries when the first of them runs and all nine when the second does. None of this reproduces the paper's comparison: there is no complete-depth-learning arm, no repetition count, no shot budget — the paper's own claim is stated for 100 runs at measurements per expectation value on an 8-qubit, 21-layer instance — and the notebook's closing cell says as much about the task itself, "a classical neural network is hard to beat on a simple learning task like this, especially with a basic data encoding scheme as used above".
- Layerwise learning for quantum neural networks
Layerwise learning rebuilt on Qiskit primitives and PyTorch, in `Gopal-Dahale/ILearnQuantum`
About
A second implementation of the same paper on a different stack, written up as a Qiskit blog article rather than as a paper. The repository README states the goal and the scope in three sentences, the first of which carries a markdown link to arXiv:2006.14904 where the word "paper" stands here: "The paper introduces the concept of layerwise learning to train quantum circuits step-by-step by gradually adding layers and training only a subset of parameters. In this article, we implemented the layerwise learning algorithm using Qiskit and PyTorch. We also talked about barren plateaus and the effectiveness of layerwise learning to overcome them." The notebook's own first cell is "Layerwise learning for Quantum Neural Networks with Qiskit and PyTorch" and "Author: Gopal Ramesh Dahale", and the directory README offers three Colab badges — `barren_plateaus.ipynb`, `barren_plateaus_visualization.ipynb` and `ll_qiskit_pytorch.ipynb` — so the barren-plateau motivation is not asserted here but measured in a sibling file. It is worth recording next to the author's own TensorFlow Quantum notebook precisely because it makes the opposite choice on the one thing that notebook skips: this one freezes.
Methods
The layer is `TwoLocal(n_qubits, ['ry', 'rz'], 'cz', skip_final_rotation_layer=True, entanglement='linear', reps=1).decompose()`, so a growth step contributes rotations plus a linear chain of `cz` rather than the paper's all-to-all coupling, and the data layer is a separate `TwoLocal(n_qubits, ['rx'], parameter_prefix='x', skip_final_rotation_layer=True, reps=1).decompose()` with one `rx` per qubit, matching the local-X data layer the paper uses. Phase one loops over `range(n_layer_steps)`, gives each of the two layers added per step its own `ParameterVector` of `num_weights` entries, initialises the step's new parameters to `np.zeros(temp_params.shape) + 0.001` — a deliberate offset from the paper's exact zeros, flagged in the code as "we perform a small deviation from all zeros" — composes them onto `main_qc`, and then freezes: under `if layer_id >= n_layers_to_train:` it takes `layer_params[-n_layers_to_train - 1]`, the growth step that has just fallen out of the window, and calls `main_qc = main_qc.bind_parameters(dict(zip(freeze_params, freeze_param_values)))`, which substitutes numbers for those symbols so they are no longer parameters of the circuit at all. With `n_layers_to_train = 2` and `n_layers_to_add = 2` the trainable set is `np.asarray(layer_params[-n_layers_to_train:]).flatten()`, the two most recent growth steps. The circuit reaches PyTorch through `EstimatorQNN(estimator=estimator, circuit=main_qc, input_params=input_params, weight_params=initial_params, gradient=gradient, input_gradients=False)` wrapped by `TorchConnector` inside `class Net(torch.nn.Module)`, whose `forward` rescales the expectation value with `torch.clamp((self.qnn(x) + 1) / 2, min=0.0, max=1.0)` and whose `loss_func` is `torch.nn.BCELoss()`; the optimiser is `torch.optim.Adam(model.parameters(), lr=0.01)` for 20 epochs per step. Phase two starts from `residual_qc`, the copy that was never bound, splits `layer_param_values` at `int(len(layer_param_values) * partition_percentage)` with `partition_percentage = 0.5`, and alternates: `train_qc = qc.bind_parameters(p2_weights)` to train the first half, `qc.bind_parameters(p1_weights)` to train the second, for `n_sweeps = 2`, this time with `input_gradients=True`. Expectation values and their gradients are bought from `QulacsEstimator()` and `QulacsEstimatorGradient(estimator)` out of `qiskit-qulacs`, installed in the first cell straight from git; the Qiskit-native `Estimator()` and `ReverseEstimatorGradient(estimator)` are imported and then left commented out, "One can use the Qiskit's primitives by uncommenting the lines below".
Data
MNIST again, but a different pair and a different encoding from the TensorFlow Quantum notebook. `torchvision.datasets.MNIST` is filtered to labels 0 and 1 by `np.where(X_train.targets == 0)[0][:n_train_samples // 2]` and its sibling for label 1, with `n_train_samples = 200` and `n_test_samples = 2000`, then shuffled with `random_state=seed` and `seed = 42`. Each image is flattened to 784 values, scaled by , reduced by `sklearn.decomposition.PCA(n_components)` with `n_components = 8`, one component per qubit, and mapped into by `min_max_scaling(x, 0, 2 * np.pi)` — the paper's own scheme, "scaling the component values to lie within , and using the scaled values to parametrize a data layer consisting of local X-gates", with the endpoint reached here because `min_max_scaling` sends the maximum onto it. Eight components out of 784 carry 69.22405% of the training set's variance, and the saved output prints that one figure twice: the second `print` re-reads `pca.explained_variance_ratio_`, which `pca.transform(x_test)` does not change, and is labelled "on train" as well, so the notebook reports no explained-variance figure for the test split at all. Batches are 16, from `DataLoader(..., shuffle=True, batch_size=batch_size, num_workers=2)`. The training split really is 200 examples, 100 of each label; the test split is not 2000, because MNIST's test set holds only 980 zeros against the 1000 the slice asks for, so 1980 examples go into `test_dataloader` and `results` reads the accuracy with that denominator.
Code
https://github.com/Gopal-Dahale/ILearnQuantum at path `layerwise_learning_with_qiskit_and_pytorch/ll_qiskit_pytorch.ipynb`, branch `main`. Python in a Colab notebook. **There is no licence.** The repository has no `LICENSE` file, the GitHub repository record returns `"license": null` and the licence endpoint returns 404 for it, so nothing here grants a reader permission to reuse the code, and that is worth knowing before copying from it. Read 2026-08-27 at blob `8a114532e2408f1654bb7767a27a89a68de39d46`: 662,470 bytes, 1,204 lines of notebook JSON, 25 cells of which 20 are code, and 430 lines of Python across the code cells — most of the size is saved plot images. The two commits that produced the directory are `011c0d0eed63`, 2023-08-24, "Layerwise learning with qiskit and pytorch", and `a5fe68502e3c`, 2023-08-25, "Added readme for layerwise learning"; nothing has touched it since, and the repository carries no tags or releases. Beside the notebook sit `barren_plateaus.ipynb`, `barren_plateaus_visualization.ipynb` and `gradient_variance.csv`, the last a 45-row table of `layers,qubits,variance` over layer counts 1, 3, 5, 10, 15, 20, 50, 100, 200 and qubit counts 2, 4, 6, 8, 10, whose 10-qubit column falls from 0.33654903429237054 at one layer to 0.01893045301547359 at two hundred. The names to open are `class Net(torch.nn.Module)`, the phase-one loop with its `bind_parameters` freeze, and the phase-two sweep loop. **Check the imports before believing the notebook runs.** Its own version table stamps the run as qiskit 0.44.1, qiskit-terra 0.25.1, `qiskit_qulacs` 0.0.1, `qiskit_machine_learning` 0.6.1, Python 3.10.12, "Thu Aug 24 16:25:54 2023 UTC", and the first import cell asks for `from qiskit.algorithms.gradients import ReverseEstimatorGradient`, `from qiskit.utils import algorithm_globals` and `from qiskit.primitives import Estimator`, while the last cell does `import qiskit.tools.jupyter`. Against Qiskit as it stands today — release 2.5.2, published 2026-08-13 — `qiskit/algorithms` and `qiskit/tools` are both absent from the tree, `algorithm_globals` appears nowhere in `qiskit/utils/__init__.py`, `qiskit/primitives/__init__.py` imports no `Estimator` and states "There are currently no implementations of the legacy ``EstimatorV1`` interface in Qiskit", and `qiskit/circuit/quantumcircuit.py` defines `assign_parameters` and no `bind_parameters`, which is the call the freezing is built on. `qiskit-qulacs` itself is alive and Apache-2.0, last pushed 2025-12-15, and `TorchConnector` is still exported by `qiskit_machine_learning.connectors` at release 0.9.1 of 2026-08-19.
Results
A classical simulator throughout — `QulacsEstimator` from `qiskit-qulacs` — with no device and no shot noise, so none of the sampling-noise regime the paper's claim is stated in is exercised here. **Every loss the notebook reports is a training loss.** Both phase loops iterate `for batch in train_dataloader` alone, average `loss.item()` over that epoch's batches and print the average; no loss is ever computed on the held-out split, and `evaluate` returns accuracy rather than loss. The training-set binary cross-entropy at the end of each 20-epoch block runs, across phase one's eight growth steps, 0.3859, 0.3200, 0.3208, 0.3225, 0.3319, 0.3182, 0.3223 and 0.3210 — it improved once and then sat still for six steps — and across phase two's four partition trainings 0.3182, 0.3117, 0.2534 and 0.2056. None of those twelve numbers is comparable with the held-out losses in the entry above. Wall-clock is printed for each phase, "Duration 223.5977 s" and "Duration 354.7637 s". The only held-out figure in the file is an accuracy: the second-to-last cell evaluates the last phase-two model and returns the tuple `(0.9711538553237915, 0.9529569745063782)`, train and test. Read both with their denominators, because `accuracy` returns the fraction correct within a batch and `evaluate` takes `torch.stack(batch_accs).mean()`, an unweighted mean over batches. The training figure averages 13 batches of which the last holds 8 of the 200 examples; the test figure averages 124 batches over 1980 examples rather than the 2000 `n_test_samples` names, of which the last holds 12. One more thing the figures get wrong: the phase-two cell appends each sweep's first-partition loss history to `losses`, which is phase one's list, and only the second partition's to `losses2`, so the side-by-side plot drawn after phase two puts ten blocks under the title "Phase I Training Convergence" and two of them are phase two. There is no complete-depth-learning arm anywhere in the notebook, so nothing here compares layerwise training against training the whole circuit — the comparison the paper's % and % figures are about.
Layerwise VQE training · Qiskit
From the repository — run, not written up from a paper · unsupported
About
Circuit depth grows in stages so each newly introduced layer can be initialized and optimized locally.
Methods
None found yet.
Data
None found yet.
Code
Qiskit
Results
Literature-backed method record; algorithmic scope and evidence boundary reviewed, with no benchmark run claimed.
- Layerwise VQE training
Circuit depth grows in stages so each newly introduced layer can be initialized and optimized locally.
References
- Layerwise learning for quantum neural networks
Andrea Skolik, Jarrod R. McClean, Masoud Mohseni, Patrick van der Smagt, Martin Leib · 2020
Where the routes meet
Every circle is drawn once. This step has no smaller object recorded inside it, so the strands between its two circles are the recorded ways of taking it — one strand per method.
6 recorded ways of doing Minimise the objective over the parameters. Nothing smaller is recorded inside it, so there is no object in the middle to draw.
Everything on this figure that opens is open.
Of the routes that have been taken apart, 15 are built entirely from named slots, 15 hand off part of the work and finish the rest themselves, and 20 are one undivided act. None of the three is a defect; they are different things to reuse.
Every line on this figure, in words
The lines on this figure
- Every line on this figure is one a recorded source takes.
Open the cardRead the full write-up
Where you are
Path
- Estimate an excited-state energy
- Minimise the objective over the parameters
Ways through: 6
Routes that skip it
No recorded route avoids this step.
Narrower kinds
Every step you can open
1 of these have an object recorded in the middle; the rest open into the methods that fill them.
- Solve a nonlinear ODE dy/dt = F(y)
- Replace a spatial domain with a finite grid
- Discretize a PDE into one linear system
- Embed a nonlinear system into a linear one
- Solve a linear ODE du/dt = A(t)u + b(t)
- Recast a non-Hermitian generator as Hamiltonian evolution
- Choose a time discretization or propagator approximation
- Quantum linear solve
- Matrix function
- QSP phase factors
- Polynomial approximation
- Block-encode a matrix
- Prepare an input state
- Amplify a success branch
- Simulate Hamiltonian evolution
- Estimate an observable
- Compile a circuit to a specific device
- Satisfy the hardware connectivity constraint
- Approximate a continuous rotation in a discrete gate set
- Recover a noiseless expectation value by post-processing
- Build logical qubits at a target logical error rate
- Estimate a Hamiltonian's ground-state energy
- Choose a parameterised trial state
- Minimise the objective over the parameters
- Estimate an excited-state energy
- Measure what the machine can actually do
- Recover the period of a periodic function
- Estimate the eigenphase of a unitary
- Find the item a check accepts
- Walk a graph to the vertex you want
- Search a cost Hamiltonian for the assignment it minimises
What is on this map, counted
What is here, counted
147 nodes — 31 slots and 116 methods.
76 of the 147 link to a record in the Atlas, between them naming 89 records. The rest name papers and nothing else: this graph describes work the catalogue has not got yet, and the nodes with no record are the list of what a corpus pass has to go and read.
0 slots have no method recorded, and 32 methods have not been taken apart. Both are shown as what they are rather than left blank.
Every claim here rests on a source. This graph cites 140 papers; they and the 172 the Atlas cites alone are registered in one place, with what each reports and everywhere it is cited from. Papers