Hello,
I am trying to use parameter shift rule to obtain the gradient of a QNode with respect to one of the input parameters. To speed-up the process, I want to use argnum=
parameter to take the gradient w.r.t just one parameter of my choice. I need to specify the parameter index in the argnum=
. I am not able to understand how to count the index of the parameter, when there are two sets of inputs. In particular, I have two sets of parameters, weights and X as shown in the code below. I want to take the derivative w.r.to the parameters in X (it has just 1 element).
By trial and error, I found that the index goes like: the elements of weights and X and then weights again, as it is the order of gate layers in the circuit. Therefore, to obtain the gradient w.r.t the elements in X, I chose the argnum=3*x +1
.
I tried to take the gradient w.r.t all parameters without specifying argnum
and by specifying argnum to be 3*x+1 to match the results. While these results match for 2 qubits, for 3 qubits, these results do not match as shown below. When I tried to make similar tests for the argnum=1,2,3..
which correspond the elements W, they seem to match in both the cases as well.
I might be doing a simple arithmatic error. However, I would truly appreciate if someone gives an idea about how to count the index of the parameters when there are multiple sets of input parameters. Thanks in advance!
# Put code here
import pennylane as qml
from pennylane import numpy as np
from pennylane.templates import StronglyEntanglingLayers
dev = qml.device('default.qubit', wires=3)
r=3
np.random.seed(42)
def S(x):
"""Data encoding circuit block."""
for w in range(r):
qml.RX(x, wires=w)
def W(theta):
"""Trainable circuit block."""
StronglyEntanglingLayers(theta, wires=range(r))
@qml.qnode(dev)
def circuit(w, x):
W(w[0])
S(x)
W(w[1])
return qml.expval(qml.PauliZ(wires=0))
X = np.linspace(0, 1, 2, requires_grad=True)
weights = 2 * np.pi * np.random.random(size=(2, 1, r, 3), requires_grad=True)
d1 = []
d2 = []
for i in X:
d1.append(qml.gradients.param_shift(circuit, argnum=r*3+1)(weights, i)[1])
d2.append(qml.gradients.param_shift(circuit)(weights, i)[1])
print(d1)
print(d2)
If you want help with diagnosing an error, please put the full error message below:
Output
[tensor(-0.1784049, requires_grad=True), tensor(-0.35629666, requires_grad=True)]
[tensor(-0.27362937, requires_grad=True), tensor(-0.43677208, requires_grad=True)]
And, finally, make sure to include the versions of your packages. Specifically, show us the output of qml.about()
.
Name: PennyLane
Version: 0.35.1
Summary: PennyLane is a cross-platform Python library for quantum computing, quantum machine learning, and quantum chemistry. Train a quantum computer the same way as a neural network.
Home-page: GitHub - PennyLaneAI/pennylane: PennyLane is a cross-platform Python library for quantum computing, quantum machine learning, and quantum chemistry. Train a quantum computer the same way as a neural network.
Author:
Author-email:
License: Apache License 2.0
Location: c:\users\hedge\miniconda3\envs\quantum_fourier_model\lib\site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, requests, rustworkx, scipy, semantic-version, toml, typing-extensions
Required-by: PennyLane_Lightning
Platform info: Windows-10-10.0.22631-SP0
Python version: 3.10.13
Numpy version: 1.26.4
Scipy version: 1.12.0
Installed devices:
- default.clifford (PennyLane-0.35.1)
- default.gaussian (PennyLane-0.35.1)
- default.mixed (PennyLane-0.35.1)
- default.qubit (PennyLane-0.35.1)
- default.qubit.autograd (PennyLane-0.35.1)
- default.qubit.jax (PennyLane-0.35.1)
- default.qubit.legacy (PennyLane-0.35.1)
- default.qubit.tf (PennyLane-0.35.1)
- default.qubit.torch (PennyLane-0.35.1)
- default.qutrit (PennyLane-0.35.1)
- null.qubit (PennyLane-0.35.1)
- lightning.qubit (PennyLane_Lightning-0.35.1)