Hello!
I am building a quantum classifier based on this paper which is an extension of this Pennylane demo. I find that in my implementation of the referenced paper, the qcuruit
function i.e. the return qml.expval(...)
statement returns a vector of size 3. For example, it returns [0.98952308 0.99227369 0.82933498]
. In my understanding, qml.expval()
should always return a scalar and the documentation does not describe any circumstances in which it returns a vector.
I have reused most of the code from the demo itself while making a few changes to the qcircuit
function and input parameter vector params
. To avoid clutter, I am only specifying the changes I have made below.
dev = qml.device("lightning.gpu", wires=2)
@qml.qnode(dev, interface="autograd")
def qcircuit(params, x, y):
"""A variational quantum circuit representing the Universal classifier with Compact encoding.
Args:
params (array[float]): array of parameters
x (array[float]): single input vector
y (array[float]): single output state density matrix
Returns:
float: fidelity between output state and input
"""
for l in range(params.shape[0]): # Iterate num_layers times
w_0 = params[l, 0, :-1]
b_0 = params[l, 0, -1]
w_1 = params[l, 1, :-1]
b_1 = params[l, 1, -1]
encoding_0 = w_0 * x + b_0
encoding_1 = w_1 * x + b_1
qml.Rot(encoding_0, encoding_0, encoding_0, wires=0)
qml.Rot(encoding_1, encoding_1, encoding_1, wires=1)
qml.CZ([0, 1])
return qml.expval(qml.Hermitian(y, wires=[0]))
Cost is the same as that of the demo. Because of its importance in this issue, I am describing it here again anyway.
def cost(params, x, y, state_labels=None):
"""Cost function to be minimized.
Args:
params (array[float]): array of parameters
x (array[float]): 2-d array of input vectors
y (array[float]): 1-d array of targets
state_labels (array[float]): array of state representations for labels
Returns:
float: loss value to be minimized
"""
# Compute prediction for each input in data batch
loss = 0.0
dm_labels = [density_matrix(s) for s in state_labels]
for i in range(len(x)):
f = qcircuit(params, x[i], dm_labels[y[i]])
loss = loss + (1 - f) ** 2
return loss / len(x)
In the training script, the params
vector is defined as
params = np.random.uniform(size=(num_layers, 4, 3+1), requires_grad=True)
qml.about()
shows:
Name: PennyLane
Version: 0.33.1
Summary: PennyLane is a Python quantum machine learning library by Xanadu Inc.
Home-page: https://github.com/PennyLaneAI/pennylane
Author:
Author-email:
License: Apache License 2.0
Location: /home/vishwa/QC/604/quantum-image-classifier/.venv/lib/python3.10/site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, requests, rustworkx, scipy, semantic-version, toml, typing-extensions
Required-by: PennyLane-Lightning, PennyLane-Lightning-GPU
Platform info: Linux-5.15.133.1-microsoft-standard-WSL2-x86_64-with-glibc2.35
Python version: 3.10.12
Numpy version: 1.26.1
Scipy version: 1.11.3
Installed devices:
- lightning.gpu (PennyLane-Lightning-GPU-0.33.1)
- default.gaussian (PennyLane-0.33.1)
- default.mixed (PennyLane-0.33.1)
- default.qubit (PennyLane-0.33.1)
- default.qubit.autograd (PennyLane-0.33.1)
- default.qubit.jax (PennyLane-0.33.1)
- default.qubit.legacy (PennyLane-0.33.1)
- default.qubit.tf (PennyLane-0.33.1)
- default.qubit.torch (PennyLane-0.33.1)
- default.qutrit (PennyLane-0.33.1)
- null.qubit (PennyLane-0.33.1)
- lightning.qubit (PennyLane-Lightning-0.33.1)