This blog post is about utilizing AWS ML services to build Quantum Convolutional Neural Networks (QCNN). To do so, we utilize Amazon SageMaker, PennyLane, and PyTorch to train and test QCNNs on simulated quantum devices. Previously, it has been demonstrated that QCNNs can be used for binary classification tasks. This blog post will go one step further and show how to construct a QCNN for multi-class classification and apply it to image classification tasks. Based on the steps shown in this post, you can begin to explore the use cases of QCNNs by building, training, and evaluating your own model.
Approach
To implement this solution, we used PennyLane, PyTorch, SageMaker notebooks, and the public MNIST and Fashion-MNIST datasets. The specific notebook instances were ml.m5.2xlarge
- ml.m5.24xlarge
.
PennyLane
PennyLane is a Python library for programming quantum computers. Its differentiable programming paradigm enables the execution and optimization of quantum programs on a variety of simulated and hardware quantum devices. It manages the execution of quantum computations, including the evaluation of circuits and their gradients. This information can then be forwarded to the classical framework, creating seamless quantum-classical pipelines for applications, including the building of Quantum Neural Networks. Additionally, PennyLane offers integration with ML frameworks such as PyTorch.
PyTorch
PyTorch is an open-source, deep learning framework that makes it easy to develop ML models and deploy them to production. PyTorch has been integrated into the PennyLane ecosystem, allowing for the creation of hybrid Quantum-Classical ML models. Furthermore, this integration has allowed for the native training of QML models in SageMaker.
Amazon SageMaker
SageMaker is a fully managed service that provides every developer and data scientist with the ability to build, train, and deploy ML models quickly. SageMaker removes the heavy lifting from each step of the ML process to make it easier to develop high-quality models. With its integration of PyTorch, practitioners are able to build, train, and deploy their own PyTorch models on SageMaker.
Overview of Quantum Computing
Quantum Bits
Quantum computing isn’t built on bits that aren’t binary in nature. Rather, quantum bits (qubits) are two-state quantum mechanical systems that can be a combination of both zero and one at the same time. In addition to this property of “superposition”, qubits can be “entangled”, allowing for N qubits to act as a group rather than in isolation. As a result, qubits can achieve exponentially higher information density (2^N) than the information density of a classical computer (N).
Quantum Circuits
Quantum circuits are the underlying framework for quantum computation. Each circuit is built sequentially and consists of three stages: preparation of a fixed initial state, gate transformations, and measurement of an observable(s).
- Preparation: In the first stage, the qubits are initialized with the quantum or classical data that is going to be used for computation. Several options exist for encoding classical data onto qubits. For our experiment, we elected to use Amplitude embedding, which takes 2^qubits data points as the initial state.
- Transformations: In the second stage, gate-based transforms are applied to the qubits. This stage can be as simple as a one-gate operation or as complex as a grouping of gates. When several gates are grouped, they are often referred to as a unitary.
- Measurement: Lastly, the circuit is completed with the measurement of an observable. This observable may be made up of local observables for each wire in the circuit or just a subset of wires. Prior to this stage, the qubits have been in superposition, representing a mixture of the states 0 and 1. However, when a qubit is measured, this state collapses into either 0 or 1, with an associated probability of doing so.
Quantum Optimization
Variational or parameterized quantum circuits are quantum algorithms that depend on free parameters. Much like standard quantum circuits, they consist of the preparation of the fixed input state, a set of unitaries parameterized by a set of free parameters θ, and measurement of an observable ^B at the output. The output or expectation value, with some classical post-processing, can represent the cost of a given task. Given this cost, the free parameters θ=(θ1,θ2,...) of the circuit can be tuned and optimized. This optimization can leverage a classical optimization algorithm such as stochastic gradient descent or Adam.
Quantum Convolutional Neural Network
Quantum convolutions are a unitary that act on neighboring pairs of qubits. When this unitary is applied to every neighboring pair of qubits, a convolution layer is formed. This convolution layer mirrors the kernel-based convolutional layer found in the classical case. Below is the structure of the convolutional unitary that was used for this project.
These convolutions are followed by pooling layers, which are effected by measuring a subset of the qubits and using the measurement results to control subsequent operations. Shown below is the structure that was used:
The analogue of a fully-connected layer is a multi-qubit operation on the remaining qubits before the final measurement. This essentially maps the information from the remaining qubits to the ancillary qubits for our final measurement. The structure for doing so is the following:
The resulting network architecture is two convolution layers, two pooling layers, and the ancillary mapping.
Building the Model
PennyLane Basics
-
To begin constructing a quantum circuit, we must first define the quantum simulator or hardware device that will be used.
import pennylane as qml dev = qml.device('default.qubit', wires=1) # Specify how many qubits are needed
-
Now that the device is defined, we can begin building our quantum circuit.
@qml.qnode(dev) def circuit(input): qml.RX(input, wires=0) # Quantum Gate return qml.sample(qml.PauliZ(wires=0)) # Measurement of the PauliZ
-
To visualize the circuit, we can call
draw_mpl()
, with the required inputs of the circuit.
from matplotlib import pyplot as plt input = 1 fig, ax = qml.draw_mpl(circuit)(input) plt.show()
Advanced PennyLane
-
Establish the quantum device that will be used for our circuit.
import pennylane as qml num_wires = 12 num_ancilla = 4 device_type = 'lightning.qubit' dev = qml.device(device_type, wires=num_wires)
-
Define the quantum model.
def circuit(num_wires, num_ancilla): @qml.qnode(dev, interface='torch', diff_method='adjoint') def func(inputs, params): work_wires = list(range(num_wires - num_ancilla)) ancilla_wires = list(range(len(work_wires), num_wires)) qml.AmplitudeEmbedding(inputs, wires=work_wires, normalize=True) work_wires, params = Conv1DLayer(unitarity_conv1d, 15)(work_wires, params) work_wires, params = PoolingLayer(unitarity_pool, 2)(work_wires, params) work_wires, params = Conv1DLayer(unitarity_conv1d, 15)(work_wires, params) work_wires, params = PoolingLayer(unitarity_pool, 2)(work_wires, params) unitarity_toffoli(work_wires, ancilla_wires) return [qml.expval(qml.PauliZ(wire)) for wire in ancilla_wires] return func
-
Wrap our quantum circuit into a PyTorch Model.
params_shapes = {"params": 357} qlayer = qml.qnn.TorchLayer(circuit(num_wires, num_ancilla), params_shapes, torch.nn.init.normal_) output = torch.nn.Softmax(dim=1)
-
Initialize the model with the layers that we just made.
model = torch.nn.Sequential(qlayer, output)
Training the Quantum Model
For training, we conducted an experiment on a subset of the MNIST and Fashion-MNIST datasets.
# Hyperparameters
epochs = 8
batch_size = 32
train_samples = len(train_data)
batches = train_samples // batch_size
from tqdm.notebook import trange
opt = torch.optim.Adam(model.parameters(), lr=0.001)
for epoch in range(epochs):
running_loss = 0
batch = 0
model.train()
for batch, i in zip(train_loader, trange(batches)):
data = batch[0]
target = batch[1]
opt.zero_grad()
pred = model(data)
loss_evaluated = loss(pred, target)
loss_evaluated.backward()
opt.step()
running_loss += loss_evaluated
print(running_loss.item() / (i + 1), end='\r')
avg_loss = running_loss / batches
res = [epoch + 1, avg_loss]
print("Epoch: {:2d} | Loss: {:3f} ".format(*res))
Evaluating the Model
correct = 0
total = 0
with torch.no_grad():
model.eval()
for batch in test_loader:
data = batch[0]
target = batch[1]
predicted = model(data)
predicted = torch.argmax(predicted, 1)
total += target.size(0)
correct += (predicted == target).sum().item()
print('Accuracy of the network on {:2d} test images: {:.3f} %'.format(total, (100 * correct / total)))
Saving and Loading the Model
torch.save(model.state_dict(), PATH)
python
Copy code
model = torch.nn.Sequential(qlayer, output)
model.load_state_dict(torch.load(PATH))
model.eval()
Deploying Model to SageMaker Endpoint
To deploy this model to a SageMaker endpoint, one would follow the standard steps for deploying a PyTorch model on SageMaker. The only additional step needed would be to extend the existing PyTorch container instance to include PennyLane.
Results
For the subset of the MNIST dataset, the average accuracy after 8 epochs was 92%. For the Fashion-MNIST dataset, the average accuracy after 8 epochs was 88%.
Next Steps
- There are various methods that can be used to encode data onto the quantum circuit. To be able to further leverage the information density of qubits, these methods should be further explored. This could allow for larger and more complex datasets to be used for training.
- Exploring further, the specific convolutional unitary used in this blog is one of many that could be used. It is possible that there are more efficient methods for conducting the convolution.
- Lastly, due to the quantum circuits being supported in PyTorch, it is possible to explore Quantum-Classical model architectures for multi-class classification. This enables support of transfer learning from well-established pre-built models.
Conclusion
In this post, we demonstrated how quantum computing can be leveraged for multi-class image classification tasks. Moreover, we showed you how this can be accomplished on available Amazon SageMaker instances, using PennyLane for building QCNNs and PyTorch to facilitate model training and deployment. Furthermore, we discussed mechanisms that enabled the construction of QCNNs, and their training.
If you would like to look deeper at the code:
Quantum Deep Learning
Example Jupyter notebooks that demonstrate how to build, train, and deploy machine learning models using Amazon SageMaker.
📚 Background
Amazon SageMaker is a fully managed service for data science and machine learning (ML) workflows You can use Amazon SageMaker to simplify the process of building, training, and deploying ML models.
The SageMaker example notebooks are Jupyter notebooks that demonstrate the usage of Amazon SageMaker.
Quantum machine learning (QML) has emerged as the potential solution to address the challenge of handling an ever-increasing amount of data. With these advancements there is potential for reduced training times, and hybrid quantum-classical architectures.
🛠️ Setup
The quickest setup to run example notebooks includes:
- An AWS account
- Proper IAM User and Role setup
- An Amazon SageMaker Notebook Instance
- An S3 bucket
📓 Examples
Introduction to Seqeuntial Circuits
These examples provide quick walkthroughs to get you up and running with the labeling job…
Top comments (4)
Ok, that's fascinating and makes me want to know more! What would be good resources for the theories behind this?
Hey Mike,
I've been fascinated by quantum computing for a long time! Here are a couple of research papers on using quantum computers for image classification:
Check out Pennylane AI for packages to work with quantum computers.
You can also view my GitHub repo for this project, which includes implementations in TensorFlow and Numpy (note: as of 2022,Tensorflow & Numpy didn't fully support quantum devices). It also has a few more end to end examples if you'd like to try it yourself.
Let me know what you think!
Thanks very much!
Hey there! I hope you enjoyed the read. If I have earned it - Please drop a reaction & Subscribe!