1277 lines (1276 with data), 138.7 kB
{
"cells": [
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"id": "7ILFj2S_FYD7",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"outputId": "a38a9194-8a47-4c6b-b445-5ab77aec87ae"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Time in seconds since beginning of run: 1700553348.7650504\n",
"Tue Nov 21 07:55:48 2023\n"
]
}
],
"source": [
"# This cell is added by sphinx-gallery\n",
"# It can be customized to whatever you like\n",
"%matplotlib inline\n",
"# !pip install pennylane\n",
"import time\n",
"seconds = time.time()\n",
"print(\"Time in seconds since beginning of run:\", seconds)\n",
"local_time = time.ctime(seconds)\n",
"print(local_time)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Icx_yDlaFYD8"
},
"source": [
"::: {#kernel_based_training}\n",
":::\n",
"\n",
"Kernel-based training of quantum models with scikit-learn\n",
"=========================================================\n",
"\n",
"::: {.meta}\n",
":property=\\\"og:description\\\": Train a quantum machine learning model\n",
"based on the idea of quantum kernels. :property=\\\"og:image\\\":\n",
"<https://pennylane.ai/qml/_images/kernel_based_scaling.png>\n",
":::\n",
"\n",
"::: {.related}\n",
"tutorial\\_variational\\_classifier Variational classifier\n",
":::\n",
"\n",
"*Author: Maria Schuld --- Posted: 03 February 2021. Last updated: 3\n",
"February 2021.*\n",
"\n",
"Over the last few years, quantum machine learning research has provided\n",
"a lot of insights on how we can understand and train quantum circuits as\n",
"machine learning models. While many connections to neural networks have\n",
"been made, it becomes increasingly clear that their mathematical\n",
"foundation is intimately related to so-called *kernel methods*, the most\n",
"famous of which is the [support vector machine\n",
"(SVM)](https://en.wikipedia.org/wiki/Support-vector_machine) (see for\n",
"example [Schuld and Killoran (2018)](https://arxiv.org/abs/1803.07128),\n",
"[Havlicek et al. (2018)](https://arxiv.org/abs/1804.11326), [Liu et al.\n",
"(2020)](https://arxiv.org/abs/2010.02174), [Huang et al.\n",
"(2020)](https://arxiv.org/pdf/2011.01938), and, for a systematic summary\n",
"which we will follow here, [Schuld\n",
"(2021)](https://arxiv.org/abs/2101.11020)).\n",
"\n",
"The link between quantum models and kernel methods has important\n",
"practical implications: we can replace the common [variational\n",
"approach](https://pennylane.ai/qml/glossary/variational_circuit.html) to\n",
"quantum machine learning with a classical kernel method where the\n",
"kernel---a small building block of the overall algorithm---is computed\n",
"by a quantum device. In many situations there are guarantees that we get\n",
"better or at least equally good results.\n",
"\n",
"This demonstration explores how kernel-based training compares with\n",
"[variational\n",
"training](https://pennylane.ai/qml/demos/tutorial_variational_classifier.html)\n",
"in terms of the number of quantum circuits that have to be evaluated.\n",
"For this we train a quantum machine learning model with a kernel-based\n",
"approach using a combination of PennyLane and the\n",
"[scikit-learn](https://scikit-learn.org/) machine learning library. We\n",
"compare this strategy with a variational quantum circuit trained via\n",
"stochastic gradient descent using\n",
"[PyTorch](https://pennylane.readthedocs.io/en/stable/introduction/interfaces/torch.html).\n",
"\n",
"We will see that in a typical small-scale example, kernel-based training\n",
"requires only a fraction of the number of quantum circuit evaluations\n",
"used by variational circuit training, while each evaluation runs a much\n",
"shorter circuit. In general, the relative efficiency of kernel-based\n",
"methods compared to variational circuits depends on the number of\n",
"parameters used in the variational model.\n",
"\n",
"{.align-center}\n",
"\n",
"If the number of variational parameters remains small, e.g., there is a\n",
"square-root-like scaling with the number of data samples (green line),\n",
"variational circuits are almost as efficient as neural networks (blue\n",
"line), and require much fewer circuit evaluations than the quadratic\n",
"scaling of kernel methods (red line). However, with current\n",
"hardware-compatible training strategies, kernel methods scale much\n",
"better than variational circuits that require a number of parameters of\n",
"the order of the training set size (orange line).\n",
"\n",
"In conclusion, **for quantum machine learning applications with many\n",
"parameters, kernel-based training can be a great alternative to the\n",
"variational approach to quantum machine learning**.\n",
"\n",
"After working through this demo, you will:\n",
"\n",
"- be able to use a support vector machine with a quantum kernel\n",
" computed with PennyLane, and\n",
"- be able to compare the scaling of quantum circuit evaluations\n",
" required in kernel-based versus variational training.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "HxLymkJzFYD-"
},
"source": [
"Background\n",
"==========\n",
"\n",
"Let us consider a *quantum model* of the form\n",
"\n",
"$$f(x) = \\langle \\phi(x) | \\mathcal{M} | \\phi(x)\\rangle,$$\n",
"\n",
"where $| \\phi(x)\\rangle$ is prepared by a fixed [embedding\n",
"circuit](https://pennylane.ai/qml/glossary/quantum_embedding.html) that\n",
"encodes data inputs $x$, and $\\mathcal{M}$ is an arbitrary observable.\n",
"This model includes variational quantum machine learning models, since\n",
"the observable can effectively be implemented by a simple measurement\n",
"that is preceded by a variational circuit:\n",
"\n",
"{.align-center}\n",
"\n",
"|\n",
"\n",
"For example, applying a circuit $G(\\theta)$ and then measuring the\n",
"Pauli-Z observable $\\sigma^0_z$ of the first qubit implements the\n",
"trainable measurement\n",
"$\\mathcal{M}(\\theta) = G^{\\dagger}(\\theta) \\sigma^0_z G(\\theta)$.\n",
"\n",
"The main practical consequence of approaching quantum machine learning\n",
"with a kernel approach is that instead of training $f$ variationally, we\n",
"can often train an equivalent classical kernel method with a kernel\n",
"executed on a quantum device. This *quantum kernel* is given by the\n",
"mutual overlap of two data-encoding quantum states,\n",
"\n",
"$$\\kappa(x, x') = | \\langle \\phi(x') | \\phi(x)\\rangle|^2.$$\n",
"\n",
"Kernel-based training therefore bypasses the processing and measurement\n",
"parts of common variational circuits, and only depends on the data\n",
"encoding.\n",
"\n",
"If the loss function $L$ is the [hinge\n",
"loss](https://en.wikipedia.org/wiki/Hinge_loss), the kernel method\n",
"corresponds to a standard [support vector\n",
"machine](https://en.wikipedia.org/wiki/Support-vector_machine) (SVM) in\n",
"the sense of a maximum-margin classifier. Other convex loss functions\n",
"lead to more general variations of support vector machines.\n",
"\n",
"::: {.note}\n",
"::: {.title}\n",
"Note\n",
":::\n",
"\n",
"More precisely, we can replace variational with kernel-based training if\n",
"the optimisation problem can be written as minimizing a cost of the form\n",
"\n",
"$$\\min_f \\lambda\\; \\mathrm{tr}\\{\\mathcal{M}^2\\} + \\frac{1}{M}\\sum_{m=1}^M L(f(x^m), y^m),$$\n",
"\n",
"which is a regularized empirical risk with training data samples\n",
"$(x^m, y^m)_{m=1\\dots M}$, regularization strength\n",
"$\\lambda \\in \\mathbb{R}$, and loss function $L$.\n",
"\n",
"Theory predicts that kernel-based training will always find better or\n",
"equally good minima of this risk. However, to show this here we would\n",
"have to either regularize the variational training by the trace of the\n",
"squared observable, or switch off regularization in the classical SVM,\n",
"which removes a lot of its strength. The kernel-based and the\n",
"variational training in this demonstration therefore optimize slightly\n",
"different cost functions, and it is out of our scope to establish\n",
"whether one training method finds a better minimum than the other.\n",
":::\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "8_TvIr7KFYD-"
},
"source": [
"Kernel-based training\n",
"=====================\n",
"\n",
"First, we will turn to kernel-based training of quantum models. As\n",
"stated above, an example implementation is a standard support vector\n",
"machine with a kernel computed by a quantum circuit.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "hbFKg322FYD_"
},
"source": [
"We begin by importing all sorts of useful methods:\n"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"id": "zWAwDR4bFYD_"
},
"outputs": [],
"source": [
"import numpy as np\n",
"import torch\n",
"from torch.nn.functional import relu\n",
"\n",
"from sklearn.svm import SVC\n",
"from sklearn.datasets import load_iris\n",
"from sklearn.preprocessing import StandardScaler\n",
"from sklearn.model_selection import train_test_split\n",
"from sklearn.metrics import accuracy_score\n",
"\n",
"import pennylane as qml\n",
"from pennylane.templates import AngleEmbedding, StronglyEntanglingLayers\n",
"from pennylane.operation import Tensor\n",
"\n",
"import matplotlib.pyplot as plt\n",
"\n",
"np.random.seed(42)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "j7oFk7h_FYD_"
},
"source": [
"The second step is to define a data set. Since the performance of the\n",
"models is not the focus of this demo, we can just use the first two\n",
"classes of the famous [Iris data\n",
"set](https://en.wikipedia.org/wiki/Iris_flower_data_set). Dating back to\n",
"as far as 1936, this toy data set consists of 100 samples of four\n",
"features each, and gives rise to a very simple classification problem.\n"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"id": "WvuXbfgdFYD_"
},
"outputs": [],
"source": [
"X, y = load_iris(return_X_y=True)\n",
"\n",
"# pick inputs and labels from the first two classes only,\n",
"# corresponding to the first 100 samples\n",
"X = X[:100]\n",
"y = y[:100]\n",
"\n",
"# scaling the inputs is important since the embedding we use is periodic\n",
"scaler = StandardScaler().fit(X)\n",
"X_scaled = scaler.transform(X)\n",
"\n",
"# scaling the labels to -1, 1 is important for the SVM and the\n",
"# definition of a hinge loss\n",
"y_scaled = 2 * (y - 0.5)\n",
"\n",
"X_train, X_test, y_train, y_test = train_test_split(X_scaled, y_scaled)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "VZkrzcMNFYD_"
},
"source": [
"We use the [angle-embedding\n",
"template](https://pennylane.readthedocs.io/en/stable/code/api/pennylane.templates.embeddings.AngleEmbedding.html)\n",
"which needs as many qubits as there are features:\n"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "tUVa9ujbFYEA",
"outputId": "796cf44f-b877-4dc0-80bd-5d1a0343f41b"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"4"
]
},
"metadata": {},
"execution_count": 27
}
],
"source": [
"n_qubits = len(X_train[0])\n",
"n_qubits"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "N37TLkzeFYEA"
},
"source": [
"To implement the kernel we could prepare the two states\n",
"$| \\phi(x) \\rangle$, $| \\phi(x') \\rangle$ on different sets of qubits\n",
"with angle-embedding routines $S(x), S(x')$, and measure their overlap\n",
"with a small routine called a [SWAP\n",
"test](https://en.wikipedia.org/wiki/Swap_test).\n",
"\n",
"However, we need only half the number of qubits if we prepare\n",
"$| \\phi(x)\\rangle$ and then apply the inverse embedding with $x'$ on the\n",
"same qubits. We then measure the projector onto the initial state\n",
"$|0..0\\rangle \\langle 0..0|$.\n",
"\n",
"{.align-center}\n",
"\n",
"To verify that this gives us the kernel:\n",
"\n",
"$$\\begin{aligned}\n",
"\\begin{align*}\n",
" \\langle 0..0 |S(x') S(x)^{\\dagger} \\mathcal{M} S(x')^{\\dagger} S(x) | 0..0\\rangle &= \\langle 0..0 |S(x') S(x)^{\\dagger} |0..0\\rangle \\langle 0..0| S(x')^{\\dagger} S(x) | 0..0\\rangle \\\\\n",
" &= |\\langle 0..0| S(x')^{\\dagger} S(x) | 0..0\\rangle |^2\\\\\n",
" &= | \\langle \\phi(x') | \\phi(x)\\rangle|^2 \\\\\n",
" &= \\kappa(x, x').\n",
"\\end{align*}\n",
"\\end{aligned}$$\n",
"\n",
"Note that a projector $|0..0 \\rangle \\langle 0..0|$ can be constructed\n",
"using the `qml.Hermitian` observable in PennyLane.\n",
"\n",
"Altogether, we use the following quantum node as a *quantum kernel\n",
"evaluator*:\n"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"id": "rHzc6uMuFYEA"
},
"outputs": [],
"source": [
"dev_kernel = qml.device(\"lightning.qubit\", wires=n_qubits)\n",
"\n",
"projector = np.zeros((2**n_qubits, 2**n_qubits))\n",
"projector[0, 0] = 1\n",
"\n",
"@qml.qnode(dev_kernel, interface=\"autograd\")\n",
"def kernel(x1, x2):\n",
" \"\"\"The quantum kernel.\"\"\"\n",
" AngleEmbedding(x1, wires=range(n_qubits))\n",
" qml.adjoint(AngleEmbedding)(x2, wires=range(n_qubits))\n",
" return qml.expval(qml.Hermitian(projector, wires=range(n_qubits)))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "QcD4S3OpFYEA"
},
"source": [
"A good sanity check is whether evaluating the kernel of a data point and\n",
"itself returns 1:\n"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "lvP52fIhFYEA",
"outputId": "921ea204-6586-48a2-d99e-298163dbb655"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"array(1.)"
]
},
"metadata": {},
"execution_count": 29
}
],
"source": [
"kernel(X_train[0], X_train[0])"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Pu8CMyQAFYEA"
},
"source": [
"The way an SVM with a custom kernel is implemented in scikit-learn\n",
"requires us to pass a function that computes a matrix of kernel\n",
"evaluations for samples in two different datasets A, B. If A=B, this is\n",
"the [Gram matrix](https://en.wikipedia.org/wiki/Gramian_matrix).\n"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"id": "fBu0EPZFFYEB"
},
"outputs": [],
"source": [
"def kernel_matrix(A, B):\n",
" \"\"\"Compute the matrix whose entries are the kernel\n",
" evaluated on pairwise data from sets A and B.\"\"\"\n",
" return np.array([[kernel(a, b) for b in B] for a in A])"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ASIEjcT6FYEB"
},
"source": [
"Training the SVM optimizes internal parameters that basically weigh\n",
"kernel functions. It is a breeze in scikit-learn, which is designed as a\n",
"high-level machine learning library:\n"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"id": "tLbJYFQGFYEB"
},
"outputs": [],
"source": [
"svm = SVC(kernel=kernel_matrix).fit(X_train, y_train)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "nThUR4IXFYEB"
},
"source": [
"Let's compute the accuracy on the test set.\n"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "NRSdpmEyFYEB",
"outputId": "2af2e55c-c9a2-4e73-97d2-26c31167dcf5"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"1.0"
]
},
"metadata": {},
"execution_count": 32
}
],
"source": [
"predictions = svm.predict(X_test)\n",
"accuracy_score(predictions, y_test)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5RXKvK_rFYEB"
},
"source": [
"The SVM predicted all test points correctly. How many times was the\n",
"quantum device evaluated?\n"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "_kMQ-EWUFYEB",
"outputId": "0ef2819f-7e1f-4752-f6ea-4a60f65a8e44"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"7501"
]
},
"metadata": {},
"execution_count": 33
}
],
"source": [
"dev_kernel.num_executions"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "xCtWwFvKFYEB"
},
"source": [
"This number can be derived as follows: For $M$ training samples, the SVM\n",
"must construct the $M \\times M$ dimensional kernel gram matrix for\n",
"training. To classify $M_{\\rm pred}$ new samples, the SVM needs to\n",
"evaluate the kernel at most $M_{\\rm pred}M$ times to get the pairwise\n",
"distances between training vectors and test samples.\n",
"\n",
"::: {.note}\n",
"::: {.title}\n",
"Note\n",
":::\n",
"\n",
"Depending on the implementation of the SVM, only $S \\leq M_{\\rm pred}$\n",
"*support vectors* are needed.\n",
":::\n",
"\n",
"Let us formulate this as a function, which can be used at the end of the\n",
"demo to construct the scaling plot shown in the introduction.\n"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"id": "M_1hcicYFYEC"
},
"outputs": [],
"source": [
"def circuit_evals_kernel(n_data, split):\n",
" \"\"\"Compute how many circuit evaluations one needs for kernel-based\n",
" training and prediction.\"\"\"\n",
"\n",
" M = int(np.ceil(split * n_data))\n",
" Mpred = n_data - M\n",
"\n",
" n_training = M * M\n",
" n_prediction = M * Mpred\n",
"\n",
" return n_training + n_prediction"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "gpqajoRIFYEC"
},
"source": [
"With $M = 75$ and $M_{\\rm pred} = 25$, the number of kernel evaluations\n",
"can therefore be estimated as:\n"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "-w_PvUeiFYEC",
"outputId": "5cc9cfbb-0735-45cc-8f78-1958aa719f1f"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"7500"
]
},
"metadata": {},
"execution_count": 35
}
],
"source": [
"circuit_evals_kernel(n_data=len(X), split=len(X_train) /(len(X_train) + len(X_test)))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "9ANsscoCFYEC"
},
"source": [
"The single additional evaluation can be attributed to evaluating the\n",
"kernel once above as a sanity check.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "K5xjmPw-FYEC"
},
"source": [
"A similar example using variational training\n",
"============================================\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "aNqXbXFOFYEC"
},
"source": [
"Using the variational principle of training, we can propose an *ansatz*\n",
"for the variational circuit and train it directly. By increasing the\n",
"number of layers of the ansatz, its expressivity increases. Depending on\n",
"the ansatz, we may only search through a subspace of all measurements\n",
"for the best candidate.\n",
"\n",
"Remember from above, the variational training does not optimize\n",
"*exactly* the same cost as the SVM, but we try to match them as closely\n",
"as possible. For this we use a bias term in the quantum model, and train\n",
"on the hinge loss.\n",
"\n",
"We also explicitly use the\n",
"[parameter-shift](https://pennylane.ai/qml/glossary/parameter_shift.html)\n",
"differentiation method in the quantum node, since this is a method which\n",
"works on hardware as well. While `diff_method='backprop'` or\n",
"`diff_method='adjoint'` would reduce the number of circuit evaluations\n",
"significantly, they are based on tricks that are only suitable for\n",
"simulators, and can therefore not scale to more than a few dozen qubits.\n"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"id": "f6NP0_uYFYEC"
},
"outputs": [],
"source": [
"dev_var = qml.device(\"lightning.qubit\", wires=n_qubits)\n",
"\n",
"@qml.qnode(dev_var, interface=\"torch\", diff_method=\"parameter-shift\")\n",
"def quantum_model(x, params):\n",
" \"\"\"A variational quantum model.\"\"\"\n",
"\n",
" # embedding\n",
" AngleEmbedding(x, wires=range(n_qubits))\n",
"\n",
" # trainable measurement\n",
" StronglyEntanglingLayers(params, wires=range(n_qubits), imprimitive=qml.ops.CZ)\n",
" return qml.expval(qml.PauliZ(0))\n",
"\n",
"def quantum_model_plus_bias(x, params, bias):\n",
" \"\"\"Adding a bias.\"\"\"\n",
" return quantum_model(x, params) + bias\n",
"\n",
"def hinge_loss(predictions, targets):\n",
" \"\"\"Implements the hinge loss.\"\"\"\n",
" all_ones = torch.ones_like(targets)\n",
" hinge_loss = all_ones - predictions * targets\n",
" # trick: since the max(0,x) function is not differentiable,\n",
" # use the mathematically equivalent relu instead\n",
" hinge_loss = relu(hinge_loss)\n",
" return hinge_loss"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "SzBKHcSHFYEC"
},
"source": [
"We now summarize the usual training and prediction steps into two\n",
"functions similar to scikit-learn\\'s `fit()` and `predict()`. While it\n",
"feels cumbersome compared to the one-liner used to train the kernel\n",
"method, PennyLane---like other differentiable programming\n",
"libraries---provides a lot more control over the particulars of\n",
"training.\n",
"\n",
"In our case, most of the work is to convert between numpy and torch,\n",
"which we need for the differentiable `relu` function used in the hinge\n",
"loss.\n"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"id": "RX37EVmAFYEC"
},
"outputs": [],
"source": [
"def quantum_model_train(n_layers, steps, batch_size):\n",
" \"\"\"Train the quantum model defined above.\"\"\"\n",
"\n",
" params = np.random.random((n_layers, n_qubits, 3))\n",
" params_torch = torch.tensor(params, requires_grad=True)\n",
" bias_torch = torch.tensor(0.0)\n",
"\n",
" opt = torch.optim.Adam([params_torch, bias_torch], lr=0.1)\n",
"\n",
" loss_history = []\n",
" for i in range(steps):\n",
"\n",
" batch_ids = np.random.choice(len(X_train), batch_size)\n",
"\n",
" X_batch = X_train[batch_ids]\n",
" y_batch = y_train[batch_ids]\n",
"\n",
" X_batch_torch = torch.tensor(X_batch, requires_grad=False)\n",
" y_batch_torch = torch.tensor(y_batch, requires_grad=False)\n",
"\n",
" def closure():\n",
" opt.zero_grad()\n",
" preds = torch.stack(\n",
" [quantum_model_plus_bias(x, params_torch, bias_torch) for x in X_batch_torch]\n",
" )\n",
" loss = torch.mean(hinge_loss(preds, y_batch_torch))\n",
"\n",
" # bookkeeping\n",
" current_loss = loss.detach().numpy().item()\n",
" loss_history.append(current_loss)\n",
" if i % 10 == 0:\n",
" print(\"step\", i, \", loss\", current_loss)\n",
"\n",
" loss.backward()\n",
" return loss\n",
"\n",
" opt.step(closure)\n",
"\n",
" return params_torch, bias_torch, loss_history\n",
"\n",
"\n",
"def quantum_model_predict(X_pred, trained_params, trained_bias):\n",
" \"\"\"Predict using the quantum model defined above.\"\"\"\n",
"\n",
" p = []\n",
" for x in X_pred:\n",
"\n",
" x_torch = torch.tensor(x)\n",
" pred_torch = quantum_model_plus_bias(x_torch, trained_params, trained_bias)\n",
" pred = pred_torch.detach().numpy().item()\n",
" if pred > 0:\n",
" pred = 1\n",
" else:\n",
" pred = -1\n",
"\n",
" p.append(pred)\n",
" return p"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YbUBFaZyFYED"
},
"source": [
"Let's train the variational model and see how well we are doing on the\n",
"test set.\n"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 656
},
"id": "S32qfGLIFYED",
"outputId": "cf8abfcf-ffa8-40ca-f869-3e95bb4bfe99"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"step 0 , loss 1.3954538582486848\n",
"step 10 , loss 1.0327197958428413\n",
"step 20 , loss 0.7384115263490277\n",
"step 30 , loss 0.6520626179157314\n",
"step 40 , loss 0.23666090760002514\n",
"step 50 , loss 0.5875523002081291\n",
"step 60 , loss 0.2570026003906574\n",
"step 70 , loss 0.35849991622711386\n",
"step 80 , loss 0.5062554348569632\n",
"step 90 , loss 0.40632180996652634\n",
"accuracy on test set: 0.96\n"
]
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
],
"image/png": "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\n"
},
"metadata": {}
}
],
"source": [
"n_layers = 2\n",
"batch_size = 20\n",
"steps = 100\n",
"trained_params, trained_bias, loss_history = quantum_model_train(n_layers, steps, batch_size)\n",
"\n",
"pred_test = quantum_model_predict(X_test, trained_params, trained_bias)\n",
"print(\"accuracy on test set:\", accuracy_score(pred_test, y_test))\n",
"\n",
"plt.plot(loss_history)\n",
"plt.ylim((0, 1))\n",
"plt.xlabel(\"steps\")\n",
"plt.ylabel(\"cost\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "7UUepRlfFYED"
},
"source": [
"The variational circuit has a slightly lower accuracy than the SVM---but\n",
"this depends very much on the training settings we used. Different\n",
"random parameter initializations, more layers, or more steps may indeed\n",
"get perfect test accuracy.\n",
"\n",
"How often was the device executed?\n"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "vFzkl7opFYED",
"outputId": "b6c2b50a-a7d9-4521-f6a4-3d8dde8f463c"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"74025"
]
},
"metadata": {},
"execution_count": 39
}
],
"source": [
"dev_var.num_executions"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "SB4anfqDFYED"
},
"source": [
"That is a lot more than the kernel method took!\n",
"\n",
"Let's try to understand this value. In each optimization step, the\n",
"variational circuit needs to compute the partial derivative of all\n",
"trainable parameters for each sample in a batch. Using parameter-shift\n",
"rules, we require roughly two circuit evaluations per partial\n",
"derivative. Prediction uses only one circuit evaluation per sample.\n",
"\n",
"We can formulate this as another function that will be used in the\n",
"scaling plot below.\n"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {
"id": "r4QgXbYyFYED"
},
"outputs": [],
"source": [
"def circuit_evals_variational(n_data, n_params, n_steps, shift_terms, split, batch_size):\n",
" \"\"\"Compute how many circuit evaluations are needed for\n",
" variational training and prediction.\"\"\"\n",
"\n",
" M = int(np.ceil(split * n_data))\n",
" Mpred = n_data - M\n",
"\n",
" n_training = n_params * n_steps * batch_size * shift_terms\n",
" n_prediction = Mpred\n",
"\n",
" return n_training + n_prediction"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2g-4wyHjFYED"
},
"source": [
"This estimates the circuit evaluations in variational training as:\n"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "bjte-rnJFYED",
"outputId": "99ff347a-2cdd-4173-d13a-4ac089189755"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"96025"
]
},
"metadata": {},
"execution_count": 41
}
],
"source": [
"circuit_evals_variational(\n",
" n_data=len(X),\n",
" n_params=len(trained_params.flatten()),\n",
" n_steps=steps,\n",
" shift_terms=2,\n",
" split=len(X_train) /(len(X_train) + len(X_test)),\n",
" batch_size=batch_size,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "VSZsO_dKFYEE"
},
"source": [
"The estimate is a bit higher because it does not account for some\n",
"optimizations that PennyLane performs under the hood.\n",
"\n",
"It is important to note that while they are trained in a similar manner,\n",
"the number of variational circuit evaluations differs from the number of\n",
"neural network model evaluations in classical machine learning, which\n",
"would be given by:\n"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {
"id": "Fb_RYocFFYEE"
},
"outputs": [],
"source": [
"def model_evals_nn(n_data, n_params, n_steps, split, batch_size):\n",
" \"\"\"Compute how many model evaluations are needed for neural\n",
" network training and prediction.\"\"\"\n",
"\n",
" M = int(np.ceil(split * n_data))\n",
" Mpred = n_data - M\n",
"\n",
" n_training = n_steps * batch_size\n",
" n_prediction = Mpred\n",
"\n",
" return n_training + n_prediction"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "qUbh-TfMFYEE"
},
"source": [
"In each step of neural network training, and due to the clever\n",
"implementations of automatic differentiation, the backpropagation\n",
"algorithm can compute a gradient for all parameters in (more-or-less) a\n",
"single run. For all we know at this stage, the no-cloning principle\n",
"prevents variational circuits from using these tricks, which leads to\n",
"`n_training` in `circuit_evals_variational` depending on the number of\n",
"parameters, but not in `model_evals_nn`.\n",
"\n",
"For the same example as used here, a neural network would therefore have\n",
"far fewer model evaluations than both variational and kernel-based\n",
"training:\n"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "dQBhj_t6FYEE",
"outputId": "63fa0d38-b1eb-46dc-c388-7ee9187040b6"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"2025"
]
},
"metadata": {},
"execution_count": 43
}
],
"source": [
"model_evals_nn(\n",
" n_data=len(X),\n",
" n_params=len(trained_params.flatten()),\n",
" n_steps=steps,\n",
" split=len(X_train) /(len(X_train) + len(X_test)),\n",
" batch_size=batch_size,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "QDYAPIOzFYEE"
},
"source": [
"Which method scales best?\n",
"=========================\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "pbmoRlqkFYEE"
},
"source": [
"The answer to this question depends on how the variational model is set\n",
"up, and we need to make a few assumptions:\n",
"\n",
"1. Even if we use single-batch stochastic gradient descent, in which\n",
" every training step uses exactly one training sample, we would want\n",
" to see every training sample at least once on average. Therefore,\n",
" the number of steps should scale at least linearly with the number\n",
" of training data samples.\n",
"\n",
"2. Modern neural networks often have many more parameters than training\n",
" samples. But we do not know yet whether variational circuits really\n",
" need that many parameters as well. We will therefore use two cases\n",
" for comparison:\n",
"\n",
" 2a) the number of parameters grows linearly with the training data,\n",
" or `n_params = M`,\n",
"\n",
" 2b) the number of parameters saturates at some point, which we model\n",
" by setting `n_params = sqrt(M)`.\n",
"\n",
"Note that compared to the example above with 75 training samples and 24\n",
"parameters, a) overestimates the number of evaluations, while b)\n",
"underestimates it.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "zCDSt4etFYEE"
},
"source": [
"This is how the three methods compare:\n"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 487
},
"id": "uiR1Zpi9FYEE",
"outputId": "0b78acdb-b93e-4ab8-9340-6db10cdc2f7b"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
],
"image/png": "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5ZdffrHbT/v27Rk5ciSjR48mICCALl26OFTn0qVLqVGjBu7u7gwYMIDExER++OEHQkND8fPzY9SoUXb3eL7R/v376dChA15eXnh7e9O4cWN27dpl275161bat2+Pu7s7fn5+dOnShaioKABWrlzJXXfdha+vL6VKlaJnz56cPHkyx2PdeCo24z388ccf1KpVC09PT7p27UpERITtNenp6YwaNcp2jFdeeYVhw4bRp08fu3336tWLOXPm5HhsIUQxUEzG1WVWsoKdUpCacOcfSuW5xIEDB3L16lXWr19vWxcZGcnKlSsZMmQIAPHx8XTv3p21a9eyd+9eunbtSq9evbKEhcmTJ1O/fn327t3Lm2++edNjf/XVVzzzzDM8/vjjHDhwgCVLllC1atVcX/Pqq6/y3HPPceTIEbp06XJL+8hJq1atmDp1Kt7e3kRERBAREcGYMWOybbtlyxbc3d2pVauWw8d5/fXX+eijj9i1axdOTk52F/Js3ryZoUOH8txzz3H48GG++eYbZs6cyYQJE2xtjEYjn376KYcOHeKHH35g3bp1vPzyy3bHSExM5P333+fbb7/l0KFDBAUF5VjPSy+9xEcffcTOnTsJDAykV69ett7Q5ORkGjduzLJlyzh48CCPP/44Dz30EH/99ZfdPn744QfMZjNbt27l66+/dqjOTz/9lDlz5rBy5Uo2bNhA3759Wb58OcuXL+enn37im2++Yf78+TnWP2TIECpUqMDOnTvZvXs3r776Ks7OzgDs27ePTp06Ubt2bbZt28aWLVvo1auXLSgmJCTwwgsvsGvXLtauXYvRaKRv374O9XAmJiYyefJkfvrpJzZt2kR4eLjd983777/PrFmzmDFjBlu3biU2NjbbsaPNmjXjr7/+srvbjRCiGClG4+rsqCIsJiZGASomJibLtqSkJHX48GGVlJR0fWVKvFJjve/8IyXeoffVu3dv9cgjj9iWv/nmG1WuXDllsVhyfE1YWJj67LPPbMshISGqT58+Dh23XLly6vXXX89xO6AWLlyolFLq1KlTClBTp07N8z4yXrN3717buqioKAWo9evXK6WUWr9+vQJUVFSUUkqpGTNmKB8fn5vW/vHHH6vKlSvnqeaM42cca82aNbb2y5YtU4Dt+6ZTp07qvffes9vnTz/9pMqWLZtjLfPmzVOlSpWyLc+YMUMBat++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\n"
},
"metadata": {}
}
],
"source": [
"variational_training1 = []\n",
"variational_training2 = []\n",
"kernelbased_training = []\n",
"nn_training = []\n",
"x_axis = range(0, 2000, 100)\n",
"\n",
"for M in x_axis:\n",
"\n",
" var1 = circuit_evals_variational(\n",
" n_data=M, n_params=M, n_steps=M, shift_terms=2, split=0.75, batch_size=1\n",
" )\n",
" variational_training1.append(var1)\n",
"\n",
" var2 = circuit_evals_variational(\n",
" n_data=M, n_params=round(np.sqrt(M)), n_steps=M,\n",
" shift_terms=2, split=0.75, batch_size=1\n",
" )\n",
" variational_training2.append(var2)\n",
"\n",
" kernel = circuit_evals_kernel(n_data=M, split=0.75)\n",
" kernelbased_training.append(kernel)\n",
"\n",
" nn = model_evals_nn(\n",
" n_data=M, n_params=M, n_steps=M, split=0.75, batch_size=1\n",
" )\n",
" nn_training.append(nn)\n",
"\n",
"\n",
"plt.plot(x_axis, nn_training, linestyle='--', label=\"neural net\")\n",
"plt.plot(x_axis, variational_training1, label=\"var. circuit (linear param scaling)\")\n",
"plt.plot(x_axis, variational_training2, label=\"var. circuit (srqt param scaling)\")\n",
"plt.plot(x_axis, kernelbased_training, label=\"(quantum) kernel\")\n",
"plt.xlabel(\"size of data set\")\n",
"plt.ylabel(\"number of evaluations\")\n",
"plt.legend()\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "_l8YJhi-FYEF"
},
"source": [
"This is the plot we saw at the beginning. With current\n",
"hardware-compatible training methods, whether kernel-based training\n",
"requires more or fewer quantum circuit evaluations than variational\n",
"training depends on how many parameters the latter needs. If variational\n",
"circuits turn out to be as parameter-hungry as neural networks,\n",
"kernel-based training will outperform them for common machine learning\n",
"tasks. However, if variational learning only turns out to require few\n",
"parameters (or if more efficient training methods are found),\n",
"variational circuits could in principle match the linear scaling of\n",
"neural networks trained with backpropagation.\n",
"\n",
"The practical take-away from this demo is that unless your variational\n",
"circuit has significantly fewer parameters than training data, kernel\n",
"methods could be a much faster alternative!\n",
"\n",
"Finally, it is important to note that fault-tolerant quantum computers\n",
"may change the picture for both quantum and classical machine learning.\n",
"As mentioned in [Schuld (2021)](https://arxiv.org/abs/2101.11020), early\n",
"results from the quantum machine learning literature show that larger\n",
"quantum computers will most likely enable us to reduce the quadratic\n",
"scaling of kernel methods to linear scaling, which may make classical as\n",
"well as quantum kernel methods a strong alternative to neural networks\n",
"for big data processing one day.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "KXAwo2htFYEF"
},
"source": [
"About the author\n",
"================\n"
]
},
{
"cell_type": "code",
"source": [
"seconds = time.time()\n",
"print(\"Time in seconds since end of run:\", seconds)\n",
"local_time = time.ctime(seconds)\n",
"print(local_time)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "vTY1vkGZCnKK",
"outputId": "d3054d5d-bb53-43af-a029-cddcf39de692"
},
"execution_count": 45,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Time in seconds since end of run: 1700553716.0580668\n",
"Tue Nov 21 08:01:56 2023\n"
]
}
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.17"
},
"colab": {
"provenance": []
}
},
"nbformat": 4,
"nbformat_minor": 0
}