from sklearn.model_selection import train_test_split #to split data
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pandas as pd
import tensorflow as tf
from tensorflow.keras.layers import Dense
from tensorflow.keras.models import Sequential
import pennylane as qml
def binary(x, y):
keep = (y == 3) | (y == 6)
x, y = x[keep], y[keep]
y = (y == 3)
return x,y
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train, x_test = x_train[..., np.newaxis]/255.0, x_test[..., np.newaxis]/255.0
x_train, y_train = binary(x_train, y_train)
x_test, y_test = binary(x_test, y_test)
x_train = tf.image.resize(x_train, (4,4)).numpy()
x_test = tf.image.resize(x_test, (4,4)).numpy()
print(x_train.shape)
y_train = tf.keras.utils.to_categorical(y_train)
y_test = tf.keras.utils.to_categorical(y_test)
def block(arr, rows, cols):
h, w = arr.shape
assert h % rows == 0, f"{h} rows not divided by {rows}"
assert w % cols == 0, f"{w} cols not divided by {cols}"
return (arr.reshape(h//rows, rows, -1, cols)
.swapaxes(1,2)
.reshape(-1, rows, cols))
size = 4*4
min_size = 2
minc = min_size**2
parts = int(size/minc)
print("parts ", parts)
x_train = [block(x_train[i,:,:,0],min_size,min_size) for i in range(len(x_train))]
n_qubits = 2
dev = qml.device("default.qubit", wires=n_qubits)
@qml.qnode(dev)
def qnode(inputs, weights):
qml.AngleEmbedding(inputs, wires=range(n_qubits))
qml.BasicEntanglerLayers(weights, wires=range(n_qubits))
return [qml.expval(qml.PauliZ(wires=i)) for i in range(n_qubits)]
import pennylane as qml
n_qubits1 = 4
dev = qml.device("default.qubit", wires=4)
@qml.qnode(dev, interface="tf")
def qnode1(inputs, weights):
qml.AngleEmbedding(inputs, wires=range(n_qubits1))
qml.BasicEntanglerLayers(weights, wires=range(n_qubits1))
return [qml.expval(qml.PauliZ(wires=0))]
n_layers = 1
weight_shapes1 = {"weights": (n_layers, 2,2)}
weight_shapes = {"weights": (n_layers, 2)}
qlayer_1 = qml.qnn.KerasLayer(qnode, weight_shapes, output_dim=2)
qlayer_2 = qml.qnn.KerasLayer(qnode, weight_shapes, output_dim=2)
clayer_2 = tf.keras.layers.Dense(2, activation="softmax")
kernel_model_list = []
kernel_model_list_input = []
kernel_model_list_output = []
for i in range(parts):
model_input = tf.keras.Input(shape=(2,2))
qlayer_m = qml.qnn.KerasLayer(qnode1, weight_shapes1, output_dim=1)(model_input)
model = tf.keras.Model(inputs=model_input, outputs=qlayer_m)
kernel_model_list.append(model)
kernel_model_list_input.append(model.input)
kernel_model_list_output.append(model.output)
print("input", len(kernel_model_list_input))
z_input = tf.concat(kernel_model_list_output, axis=1)
x_1, x_2 = tf.split(z_input, 2)
x_1 = qlayer_1(x_1)
x_2 = qlayer_2(x_2)
x = tf.concat([x_1, x_2], axis=1)
z = clayer_2(z_input)
model = tf.keras.Model(inputs=kernel_model_list_input, outputs=z)
model.compile(
loss=tf.keras.losses.categorical_crossentropy,
optimizer=tf.keras.optimizers.Adam(),
metrics=[tf.keras.metrics.categorical_accuracy]
)
fitting = model.fit([*x_train], np.array(y_train), epochs=6, batch_size=4, verbose=2)
resize x_train into 4by4 then divided into 2by2, i.e. total 4 parts. Then trying to process using hybrid qlayer, clayer model. It throws error during fitting i.e. ValueError: Data cardinality is ambiguous:
I used [*x_train] for multiple parts of image during fitting. But it did not work.
can you please help.