Barren Plateaus#
Overview#
Barren plateaus are the greatest difficulties in the gradient-based optimization for a large family of random parameterized quantum circuits (PQC). The gradients vanish almost everywhere. In this example, we will show barren plateaus in quantum neural networks (QNNs).
Setup#
[1]:
import numpy as np
import tensorflow as tf
import tensorcircuit as tc
tc.set_backend("tensorflow")
tc.set_dtype("complex64")
Rx = tc.gates.rx
Ry = tc.gates.ry
Rz = tc.gates.rz
Parameters#
[2]:
n = 4 # The number of qubits
nlayers = 1 # The number of circuit layers
ncircuits = 3 # The number of circuits with different initial parameters
ntrials = 2 # The number of random circuits with different structures
Generating QNN#
[3]:
def op_expectation(params, seed, n, nlayers):
paramsc = tc.backend.cast(params, dtype="float32") # parameters of gates
seedc = tc.backend.cast(seed, dtype="float32") # parameters of circuit structure
c = tc.Circuit(n)
for i in range(n):
c.ry(i, theta=np.pi / 4)
for l in range(nlayers):
for i in range(n):
# choose one gate from Rx, Ry, and Rz gates with equal prob=1/3; status is the seed.
c.unitary_kraus(
[Rx(paramsc[i, l]), Ry(paramsc[i, l]), Rz(paramsc[i, l])],
i,
prob=[1 / 3, 1 / 3, 1 / 3],
status=seedc[i, l],
)
for i in range(n - 1):
c.cz(i, i + 1)
return tc.backend.real(
c.expectation((tc.gates.z(), [0]), (tc.gates.z(), [1]))
) # expectations of <Z_0Z_1>
[4]:
# use vmap and vvag to get the expectations of ZZ observable and gradients of different random circuit instances
op_expectation_vmap_vvag = tc.backend.jit(
tc.backend.vmap(
tc.backend.vvag(op_expectation, argnums=0, vectorized_argnums=0),
vectorized_argnums=1,
)
)
Batch Variance Computation#
[5]:
seed = tc.array_to_tensor(
np.random.uniform(low=0.0, high=1.0, size=[ntrials, n, nlayers]), dtype="float32"
)
params = tc.array_to_tensor(
np.random.uniform(low=0.0, high=2 * np.pi, size=[ncircuits, n, nlayers]),
dtype="float32",
)
e, grad = op_expectation_vmap_vvag(
params, seed, n, nlayers
) # the expectations of ZZ observable and gradients of different random circuits
grad_var = tf.math.reduce_std(tf.math.reduce_std(grad, axis=0), axis=0)[
0, 0
] # the gradient variance of the first parameter
print("The variance of the gradients is:", grad_var.numpy())
The variance of the gradients is: 0.19805922
Results#
The gradient variances in QNNs (\(nlayers=50\), \(ntrials=20\), \(ncircuits=20\)). The landscape become exponentially barren with increasing qubit number.