Cette page n'a pas encore été traduite. Vous voyez la version originale en anglais.
Quantum Variational Circuits and Quantum Neural Networks
In this lesson, we implement several variational quantum circuits for a data classification task, so-called variational quantum classifiers (VQCs). At one point, it was common to refer to a subset of VQCs as quantum neural networks (QNNs) in analogy with classical neural networks. Indeed, there are cases where structures borrowed from classical neural networks, such as convolution layers, play an important role in VQCs. In such cases where the analogy is strong, QNNs may be a useful description. But parameterized quantum circuits need not follow the general structure of a neural network; for example, not all data need to be loaded in the first (input) layer; we can load some data in the first layer, apply some gates and then load additional data (a process called data "reuploading"). We should therefore think of QNNs as a subset of parameterized quantum circuits, and we should not be limited in our exploration of useful quantum circuits by the analogy to classical neural networks.
The dataset being addressed in this lesson consists of images containing horizontal and vertical stripes, and our goal is to label unseen images into one of the two categories depending on the orientation of their line. We will accomplish this with a VQC. As we go, we will address ways in which the calculation can be improved and scaled. The dataset here is exceptionally easy to classify classically. It has been chosen for its simplicity so we can focus on the quantum part of this problem, and look at how a dataset attribute might translate to a part of a quantum circuit. It is not reasonable to expect a quantum speed-up for such simple cases where classical algorithms are so efficient.
By the end of this lesson you should be able to:
- Load data from an image into a quantum circuit
- Construct an ansatz for a VQC (or QNN), and adjust it to fit your problem
- Train your VQC/QNN and use it to make accurate predictions on test data
- Scale the problem, and recognize limits of current quantum computers
Data generation
We will start by constructing the data. Data sets are often not explicitly generated as part of the Qiskit patterns framework. But data type and preparation is critical to successfully applying quantum computing to machine learning. The code below defines a data set of images with set pixel dimensions. One full row or column of the image is assigned the value , and the remaining pixels are assigned random values on the interval . The random values are noise in our data. Glance through the code to make sure you understand how the images are generated. Later on we will scale up the images.
# Added by doQumentation — installs packages not in the Binder environment
%pip install -q scikit-learn
# This code defines the images to be classified:
import numpy as np
# Total number of "pixels"/qubits
size = 8
# One dimension of the image (called vertical, but it doesn't matter). Must be a divisor of `size`
vert_size = 2
# The length of the line to be detected (yellow). Must be less than or equal to the smallest dimension of the image (`<=min(vert_size,size/vert_size)`
line_size = 2
def generate_dataset(num_images):
images = []
labels = []
hor_array = np.zeros((size - (line_size - 1) * vert_size, size))
ver_array = np.zeros((round(size / vert_size) * (vert_size - line_size + 1), size))
j = 0
for i in range(0, size - 1):
if i % (size / vert_size) <= (size / vert_size) - line_size:
for p in range(0, line_size):
hor_array[j][i + p] = np.pi / 2
j += 1
# Make two adjacent entries pi/2, then move down to the next row. Careful to avoid the "pixels" at size/vert_size - linesize, because we want to fold this list into a grid.
j = 0
for i in range(0, round(size / vert_size) * (vert_size - line_size + 1)):
for p in range(0, line_size):
ver_array[j][i + p * round(size / vert_size)] = np.pi / 2
j += 1
# Make entries pi/2, spaced by the length/rows, so that when folded, the entries appear on top of each other.
for n in range(num_images):
rng = np.random.randint(0, 2)
if rng == 0:
labels.append(-1)
random_image = np.random.randint(0, len(hor_array))
images.append(np.array(hor_array[random_image]))
elif rng == 1:
labels.append(1)
random_image = np.random.randint(0, len(ver_array))
images.append(np.array(ver_array[random_image]))
# Randomly select 0 or 1 for a horizontal or vertical array, assign the corresponding label.
# Create noise
for i in range(size):
if images[-1][i] == 0:
images[-1][i] = np.random.rand() * np.pi / 4
return images, labels
hor_size = round(size / vert_size)
Note that the code above has also generated labels indicated whether the images contain a vertical (+1) or horizontal (-1) line. We will now use sklearn to split a data set of 100 images into a training and testing set (along with their corresponding labels). Here, we use of the data set for training, with the remaining withheld for testing.
from sklearn.model_selection import train_test_split
np.random.seed(42)
images, labels = generate_dataset(200)
train_images, test_images, train_labels, test_labels = train_test_split(
images, labels, test_size=0.3, random_state=246
)
Let's plot a few elements of our data set to see what these lines look like:
import matplotlib.pyplot as plt
# Make subplot titles so we can identify categories
titles = []
for i in range(8):
title = "category: " + str(train_labels[i])
titles.append(title)
# Generate a figure with nested images using subplots.
fig, ax = plt.subplots(4, 2, figsize=(10, 6), subplot_kw={"xticks": [], "yticks": []})
for i in range(8):
ax[i // 2, i % 2].imshow(
train_images[i].reshape(vert_size, hor_size),
aspect="equal",
)
ax[i // 2, i % 2].set_title(titles[i])
plt.subplots_adjust(wspace=0.1, hspace=0.3)
Each of these images is still paired with its label in train_labels in a simple list form:
print(train_labels[:8])
[1, 1, 1, 1, -1, 1, 1, 1]
Variational quantum classifier: a first attempt
Qiskit patterns step 1: Map the problem to a quantum circuit
The goal is to find a function with parameters that maps a data vector / image to the correct category: . This will be accomplished using a VQC with few layers that can be identified by their distinct purposes: