import tensorflow as tf
import pennylane as qml
from pennylane import numpy as np
def qnn_patch(image, weights):
dev = qml.device("default.qubit.tf", wires=9)
# Encode the input image into the quantum circuit using patches of 3x3 pixels
for i in range(3):
for j in range(3):
qml.templates.embeddings.AngleEmbedding(image[i:i+3, j:j+3], wires=list(range(3*(i*3+j), 3*(i*3+j+1))))
# Apply the trainable weights to each qubit
for i in range(9):
qml.RY(weights[i], wires=i)
return qml.probs(wires=range(9))
def cost(weights, images, labels):
predictions = [qnn_patch(image, weights) for image in images]
loss = tf.keras.losses.sparse_categorical_crossentropy(labels, predictions)
return tf.reduce_mean(loss)
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
# Preprocess the data
x_train = x_train.astype(np.float32) / 255.0
x_test = x_test.astype(np.float32) / 255.0
y_train = y_train.astype(np.int64)
y_test = y_test.astype(np.int64)
opt = tf.keras.optimizers.Adam(learning_rate=0.1)
weights = tf.Variable(np.random.uniform(low=-np.pi/2, high=np.pi/2, size=(9)), dtype=np.float32)
for epoch in range(10):
with tf.GradientTape() as tape:
loss = cost(weights, x_train[:100], y_train[:100])
gradients = tape.gradient(loss, [weights])
opt.apply_gradients(zip(gradients, [weights]))
print("Epoch {}: Loss = {}".format(epoch+1, loss))
# Evaluate
predictions = [np.argmax(qnn_patch(image, weights)) for image in x_test]
accuracy = np.mean(predictions == y_test)
print("Accuracy: {}".format(accuracy))
During training, it throws an error of valueerror., as its returns list of probabilities from each wires.