diff --git a/docs/tutorials/quantum-kernel-training.ipynb b/docs/tutorials/quantum-kernel-training.ipynb
index 9ca5223336d..286f46e135f 100644
--- a/docs/tutorials/quantum-kernel-training.ipynb
+++ b/docs/tutorials/quantum-kernel-training.ipynb
@@ -10,9 +10,39 @@
"description: Build a Qiskit pattern for evaluating entries into a quantum kernel matrix used for binary classification.\n",
"---\n",
"\n",
+ "{/* cspell:ignore mapsto forall */}\n",
"\n",
"# Quantum kernel training\n",
- "*Usage estimate: under one minute on an Eagle r3 processor (NOTE: This is an estimate only. Your runtime might vary.)*"
+ "*Usage estimate: under one minute on a Heron r3 processor (NOTE: This is an estimate only. Your runtime might vary.)*"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bd3bec67",
+ "metadata": {},
+ "source": [
+ "## Learning outcomes\n",
+ "After completing this tutorial, you can expect to understand the following information:\n",
+ "\n",
+ " * Kernel methods and their uses\n",
+ " * Quantum kernels and how they can provide enhanced feature spaces\n",
+ " * Quantum kernel circuit construction\n",
+ " * How to train a quantum kernel using a [Qiskit pattern](/docs/guides/intro-to-patterns): map, optimize, execute, and post-process"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ba36136c",
+ "metadata": {},
+ "source": [
+ "## Prerequisites\n",
+ "It is recommended that you familiarize yourself with quantum kernels, why they are important, and how they are used in practice.\n",
+ "\n",
+ " * [Covariant quantum kernels for data with group structure](https://arxiv.org/abs/2105.03406) (paper)\n",
+ " * [Introduction to Quantum Kernels and Support Vector Machines](https://www.youtube.com/watch?v=GVhCOTzAkCM) (video)\n",
+ " * [Quantum Kernels in Practice](https://www.youtube.com/watch?v=LmQcSxgINis) (video)\n",
+ "\n",
+ "It is also useful to have a basic understanding of group theory."
]
},
{
@@ -21,8 +51,20 @@
"metadata": {},
"source": [
"## Background\n",
- "\n",
- "This tutorial shows how to build a `Qiskit pattern` for evaluating entries into a quantum kernel matrix used for binary classification. For more information on `Qiskit patterns` and how `Qiskit Serverless` can be used to deploy them to the cloud for managed execution, visit our [docs page on IBM Quantum® Platform](/docs/guides/serverless)."
+ "Kernel methods are commonplace in machine learning applications.\n",
+ "In this context, \"kernel\" refers to the kernel matrix or individual entries therein.\n",
+ "In general, a kernel is a similarity measure between data encoded in a high-dimensional _feature space_ and can be utilized, for example, in classification tasks with support vector machines.\n",
+ "\n",
+ "Quantum kernel methods are those which use quantum computers to estimate a kernel.\n",
+ "It is known that quantum computers can encode data in quantum-enhanced feature spaces, effectively replacing classical analogs.\n",
+ "For $\\vec{x} \\in \\mathbb{R}$ and $\\Psi(\\vec{x}) \\in \\mathbb{R}^{d'}$, typically with $d' >d$, $\\Psi(\\vec{x})$ is a feature map, $\\vec{x} \\mapsto \\Psi(\\vec{x})$.\n",
+ "The goal of $\\Psi(\\vec{x})$ is to make categories of data separated by a hyperplane.\n",
+ "Taking the vectors in the feature-mapped space as arguments, kernel function $K(\\vec{x}, \\vec{y}) = \\langle{\\Psi(\\vec{x}) | \\Psi(\\vec{y}) \\rangle{}}$ returns their inner product: $K: \\mathbb{R}^d \\rightarrow$ $\\mathbb{R}^d$.\n",
+ "Classically, feature maps of interest are those in which the kernel function can be easily evaluated;\n",
+ "as in, when the inner product in the feature-mapped space can be written in terms of the original data vectors and $\\Psi(\\vec{x})$ and $\\Psi(\\vec{y})$ do not need to be constructed.\n",
+ "In the case of quantum kernels, feature mapping is performed by a quantum circuit, and the kernel is estimated using the measurement probabilities sampled from the circuit.\n",
+ "\n",
+ "This tutorial shows how to build a Qiskit pattern for evaluating entries into a quantum kernel matrix used for binary classification."
]
},
{
@@ -33,8 +75,8 @@
"## Requirements\n",
"\n",
"Before starting this tutorial, be sure you have the following installed:\n",
- "- Qiskit SDK v1.0 or later, with [visualization](/docs/api/qiskit/visualization) support\n",
- "- Qiskit Runtime v0.22 or later (`pip install qiskit-ibm-runtime`)"
+ "- Qiskit SDK v2.3.1 or later, with [visualization](/docs/api/qiskit/visualization) support\n",
+ "- Qiskit Runtime v0.44.0 or later (`pip install qiskit-ibm-runtime`)"
]
},
{
@@ -47,26 +89,13 @@
},
{
"cell_type": "code",
- "execution_count": 2,
+ "execution_count": null,
"id": "4405f2da-ce6e-4b97-960a-bb04730cfb6d",
"metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\n",
- "\n",
- "\u001b7\u001b[1A\u001b[1G\u001b[27G[Files: 0 Bytes: 0 [0 B/s] Re]\u001b8\u001b7\u001b[2A\u001b[1G\u001b[27G[https://raw.githubusercontent.]\u001b8\u001b7\u001b[1S\u001b[3A\u001b[1G\u001b[0JSaving 'dataset_graph7.csv.1'\n",
- "\u001b8\u001b7\u001b[2A\u001b[1Gdataset_graph7.csv.1 100% [=============================>] 20.25K --.-KB/s\u001b8\u001b7\u001b[1S\u001b[3A\u001b[1G\u001b[0JHTTP response 200 [https://raw.githubusercontent.com/qiskit-community/prototype-quantum-kernel-training/main/data/dataset_graph7.csv]\n",
- "\u001b8\u001b7\u001b[2A\u001b[1Gdataset_graph7.csv.1 100% [=============================>] 20.25K --.-KB/s\u001b8\u001b7\u001b[1A\u001b[1G\u001b[27G[Files: 1 Bytes: 20.25K [93.33]\u001b8\u001b[m\u001b[m\u001b[m\u001b[m"
- ]
- }
- ],
+ "outputs": [],
"source": [
- "!wget https://raw.githubusercontent.com/qiskit-community/prototype-quantum-kernel-training/main/data/dataset_graph7.csv\n",
- "\n",
"# General Imports and helper functions\n",
+ "import urllib.request\n",
"\n",
"import pandas as pd\n",
"import numpy as np\n",
@@ -74,13 +103,17 @@
"\n",
"\n",
"from qiskit.circuit import Parameter, ParameterVector, QuantumCircuit\n",
- "from qiskit.circuit.library import UnitaryOverlap\n",
+ "from qiskit.circuit.library import unitary_overlap\n",
+ "from qiskit.primitives import StatevectorSampler\n",
"from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n",
"\n",
"from qiskit_ibm_runtime import QiskitRuntimeService, Sampler\n",
"\n",
- "# from qiskit_serverless import IBMServerlessClient, QiskitFunction\n",
- "from qiskit_ibm_catalog import QiskitServerless, QiskitFunction\n",
+ "# Download the dataset (portable across platforms)\n",
+ "urllib.request.urlretrieve(\n",
+ " \"https://raw.githubusercontent.com/qiskit-community/prototype-quantum-kernel-training/main/data/dataset_graph7.csv\",\n",
+ " \"dataset_graph7.csv\",\n",
+ ")\n",
"\n",
"\n",
"def visualize_counts(res_counts, num_qubits, num_shots):\n",
@@ -117,24 +150,45 @@
" return X_train"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "small-scale-intro",
+ "metadata": {},
+ "source": [
+ "## Small-scale simulator example\n",
+ "\n",
+ "In this section, we walk through the four steps of the Qiskit pattern on a seven-qubit instance of the labeling-cosets-with-error problem and evaluate a single kernel matrix entry using the `StatevectorSampler` primitive from Qiskit. A statevector simulator is exact (up to shot noise) and shows us the method end-to-end without consuming QPU time. We then repeat the same instance on real hardware in the hardware example section."
+ ]
+ },
{
"cell_type": "markdown",
"id": "6ddce42e-a365-451d-972d-24c1306ac47b",
"metadata": {},
"source": [
- "## Step 1: Map classical inputs to a quantum problem\n",
+ "### Step 1: Map classical inputs to a quantum problem\n",
"\n",
"* Input: Training dataset.\n",
"* Output: Abstract circuit for calculating a kernel matrix entry.\n",
"\n",
- "Create the quantum circuit used to evaluate one entry in the kernel matrix. We use the input data to determine the rotation angles for the circuit's parametrized gates. We will use data samples `x1=14` and `x2=19`.\n",
+ "The binary classification problem we aim to solve here is referred to as \"[_labeling cosets with error_](https://arxiv.org/abs/2105.03406).\" The input training dataset contains a group structure, consisting of two cosets formed by a group and subgroup.\n",
+ "The group is taken to be $G = SU(2)^{\\otimes n}$ for qubits, which is the special unitary group of\n",
+ "$2 \\times 2$ matrices and has wide applicability in nature; e.g., the Standard Model of particle physics.\n",
+ "We take the (graph-stabilizer) subgroup $S_\\text{graph} < G$ with $S_\\text{graph} = \\langle \\{ X_i \\otimes _{k:(k,i) \\in \\mathcal{E}} Z_k\\} _{i \\in \\mathcal{V}} \\} \\rangle$ for a graph with edges $\\mathcal{E}$ and vertices $\\mathcal{V}$.\n",
+ "Note that the stabilizers fix a stabilizer state such that $D_s | \\psi \\rangle = | \\psi \\rangle,~ \\forall s \\in S_\\text{graph}$.\n",
+ "Finally, we define two left-cosets $C_\\pm = c_\\pm S_\\text{graph}$ by drawing two $c_\\pm \\in G$ at random.\n",
+ "\n",
+ "For more details about the dataset and how it is generated, see [this notebook](https://github.com/qiskit-community/prototype-quantum-kernel-training/blob/main/docs/background/qkernels_and_data_w_group_structure.ipynb) from the [Quantum Kernel Training Toolkit](https://github.com/qiskit-community/prototype-quantum-kernel-training/tree/main).\n",
+ "\n",
+ "We create the quantum circuit used to evaluate one entry in the kernel matrix.\n",
+ "The input data is used to determine the rotation angles for the circuit's parametrized gates.\n",
+ "For simplicity, we will use data samples `x1=14` and `x2=19`.\n",
"\n",
"***Note: The dataset used in this tutorial can be downloaded [here](https://github.com/qiskit-community/prototype-quantum-kernel-training/blob/main/data/dataset_graph7.csv).***"
]
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": 2,
"id": "70d6faff-9a56-44bb-b26f-f573a8c90889",
"metadata": {},
"outputs": [
@@ -144,7 +198,7 @@
""
]
},
- "execution_count": 3,
+ "execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
@@ -178,76 +232,47 @@
"unitary2 = fm.assign_parameters(list(X_train[x2]) + [np.pi / 2])\n",
"\n",
"# Create the overlap circuit\n",
- "overlap_circ = UnitaryOverlap(unitary1, unitary2)\n",
+ "overlap_circ = unitary_overlap(unitary1, unitary2)\n",
"overlap_circ.measure_all()\n",
"overlap_circ.draw(\"mpl\", scale=0.6, style=\"iqp\")"
]
},
{
"cell_type": "markdown",
- "id": "158d8cec-1d92-4105-ac64-6f801dec4259",
+ "id": "step2-small-md",
"metadata": {},
"source": [
- "## Step 2: Optimize problem for quantum hardware execution\n",
+ "### Step 2: Optimize problem for quantum hardware execution\n",
"\n",
- "* Input: Abstract circuit, not optimized for a particular backend\n",
- "* Output: Target circuit and observable, optimized for the selected QPU\n",
+ "* Input: Abstract circuit, not optimized for a particular backend.\n",
+ "* Output: Target circuit, optimized for the selected QPU.\n",
"\n",
- "Use the `generate_preset_pass_manager` function from Qiskit to specify an optimization routine for our circuit with respect to the QPU on which we plan to run the experiment. We set `optimization_level=3` , which means we will use the preset pass manager which provides the highest level of optimization."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "49607b34-9723-493d-85da-bd97c1351104",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- ""
- ]
- },
- "execution_count": 4,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "service = QiskitRuntimeService()\n",
- "backend = service.least_busy(\n",
- " operational=True, simulator=False, min_num_qubits=overlap_circ.num_qubits\n",
- ")\n",
- "pm = generate_preset_pass_manager(optimization_level=3, backend=backend)\n",
- "overlap_ibm = pm.run(overlap_circ)\n",
- "overlap_ibm.draw(\"mpl\", scale=0.6, idle_wires=False, fold=-1, style=\"iqp\")"
+ "For the statevector simulator path used in this section, no backend-specific optimization is required: the abstract circuit can be sampled directly. We exercise this step in the hardware example below, where the circuit is transpiled against a real QPU using `generate_preset_pass_manager` with `optimization_level=3`."
]
},
{
"cell_type": "markdown",
- "id": "9359b92c-a130-44d1-ba11-752f8f4935a0",
+ "id": "step3-small-md",
"metadata": {},
"source": [
- "## Step 3: Execute using Qiskit primitives\n",
+ "### Step 3: Execute using Qiskit primitives\n",
"\n",
- "* Input: Target circuit\n",
- "* Output: Quasi-probability distribution\n",
+ "* Input: Abstract circuit.\n",
+ "* Output: Quasi-probability distribution.\n",
"\n",
- "Use the `Sampler` primitive from Qiskit Runtime to reconstruct a quasi-probability distribution of states yielded from sampling the circuit. For the task of generating a kernel matrix, we are particularly interested in the probability of measuring the |0> state.\n",
- "\n",
- "For this demo, we will run on a QPU with `qiskit-ibm-runtime` primitives. To run on `qiskit` statevector-based primitives, replace the block of code using Qiskit IBM® Runtime primitives with the commented block."
+ "Use the `StatevectorSampler` primitive from Qiskit to reconstruct a quasi-probability distribution of states yielded from sampling the circuit. For the task of generating a kernel matrix, we are particularly interested in the probability of measuring the |0> state."
]
},
{
"cell_type": "code",
- "execution_count": 6,
- "id": "d2f4f6cf-067e-4d53-aa04-7ca9c803d3e1",
+ "execution_count": 3,
+ "id": "step3-small-code",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -255,120 +280,154 @@
}
],
"source": [
- "num_shots = 10_000\n",
- "\n",
- "## Evaluate the problem using statevector-based primitives from Qiskit\n",
- "# from qiskit.primitives import StatevectorSampler\n",
- "\n",
- "# sampler = StatevectorSampler()\n",
- "# results = sampler.run([overlap_circ]).result()\n",
- "# counts = results[0].data.meas.get_int_counts()\n",
- "\n",
- "# Evaluate the problem using a QPU via Qiskit IBM Runtime\n",
+ "sampler = StatevectorSampler()\n",
"\n",
- "sampler = Sampler(mode=backend)\n",
- "results = sampler.run([overlap_ibm]).result()\n",
+ "# Execute and get counts\n",
+ "num_shots = 10_000\n",
+ "results = sampler.run([overlap_circ], shots=num_shots).result()\n",
"counts = results[0].data.meas.get_int_counts()\n",
"\n",
+ "# Plot counts\n",
"visualize_counts(counts, num_qubits, num_shots)"
]
},
{
"cell_type": "markdown",
- "id": "1b750103-c369-4651-9092-db0385294c46",
+ "id": "step4-small-md",
"metadata": {},
"source": [
- "## Step 4: Post-process and return result in desired classical format\n",
+ "### Step 4: Post-process and return result in desired classical format\n",
"\n",
- "* Input: Probability distribution\n",
- "* Output: A single kernel matrix element\n",
+ "* Input: Probability distribution.\n",
+ "* Output: A single kernel matrix element.\n",
"\n",
- "Calculate the probability of measuring |0> on the overlap circuit, and populate the kernel matrix in the position corresponding to the samples represented by this particular overlap circuit (row 15, column 20). In this visualization, darker red indicates fidelities closer to 1.0. To fill out the entire kernel matrix, we need to run a quantum experiment for each entry."
+ "Calculate the probability of measuring $|0 \\rangle$ on the overlap circuit, and populate the kernel matrix in the position corresponding to the samples represented by this particular overlap circuit (row 15, column 20)."
]
},
{
"cell_type": "code",
- "execution_count": 7,
- "id": "8efcb466-3110-4e60-82a6-185f0dca1771",
+ "execution_count": 4,
+ "id": "step4-small-code",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "Fidelity: 0.1279\n"
+ "Fidelity (simulator): 0.8261\n"
]
}
],
"source": [
- "# Calculate the fidelity, or the probability to measure 0\n",
"kernel_matrix[x1, x2] = counts.get(0, 0.0) / num_shots\n",
- "print(f\"Fidelity: {kernel_matrix[x1, x2]}\")"
+ "print(f\"Fidelity (simulator): {kernel_matrix[x1, x2]}\")"
]
},
{
- "attachments": {},
"cell_type": "markdown",
- "id": "dec33657-9055-4fdc-b146-dba0e5882719",
+ "id": "large-scale-intro",
"metadata": {},
"source": [
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "id": "5b0397d6-6673-45cb-9d38-7e9faadba4a1",
- "metadata": {},
- "source": [
- "## Deploy the Qiskit pattern to the cloud\n",
- "\n",
- "To do this, move the source code above to a file, `./source/generate_kernel_entry.py`, wrap the code in a script which takes inputs returns the final solution, and finally upload it to a remote cluster using the `QiskitFunction` class from `Qiskit Serverless`. For guidance on specifying external dependencies, passing input arguments, and more, check out the [Qiskit Serverless guides](https://qiskit.github.io/qiskit-serverless/function_features/index.html#function-features).\n",
+ "## Hardware example\n",
"\n",
- "The input to the Pattern is a pair of data samples, `x1` and `x2`. The output is the fidelity between the two samples. This value will be used to populate the kernel matrix entry corresponding to these two samples."
+ "A quantum kernel matrix has $\\mathcal{O}(N^2)$ entries for $N$ training samples, and each entry requires running an overlap circuit whose two-qubit-gate depth grows with the size of the feature map. As a result, scaling this tutorial to a larger problem has two compounding costs: the QPU time per kernel matrix grows quadratically with $N$, and the depth of `unitary_overlap` (which composes the feature map with its adjoint) erodes fidelity at the system size and connectivity of current hardware. To keep the demo short and to make a clean comparison, we therefore run the **same** seven-qubit instance from the small-scale example on a real QPU and compare the fidelity of a single kernel matrix entry against the simulator value computed above."
]
},
{
"cell_type": "code",
- "execution_count": null,
- "id": "8ce74c3c-4212-4c75-ae55-1394813c89a6",
+ "execution_count": 5,
+ "id": "d2f4f6cf-067e-4d53-aa04-7ca9c803d3e1",
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Using backend: ibm_pittsburgh\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Fidelity (hardware): 0.7517\n"
+ ]
+ }
+ ],
"source": [
- "serverless = QiskitServerless()\n",
+ "# ------------------------------ Step 1 ------------------------------\n",
+ "# Prepare training data\n",
+ "X_train = get_training_data()\n",
"\n",
- "kernel_entry_pattern = QiskitFunction(\n",
- " title=\"generate-kernel-entry\",\n",
- " entrypoint=\"generate_kernel_entry.py\",\n",
- " working_dir=\"./source/\",\n",
- ")\n",
+ "# Empty kernel matrix\n",
+ "num_samples = np.shape(X_train)[0]\n",
+ "kernel_matrix = np.full((num_samples, num_samples), np.nan)\n",
"\n",
- "serverless.upload(kernel_entry_pattern)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "f5b1e64a-881e-459e-a425-7876e56d73de",
- "metadata": {},
- "source": [
- "## Run the Qiskit pattern as a managed service\n",
+ "# Prepare feature map for computing overlap\n",
+ "num_features = np.shape(X_train)[1]\n",
+ "num_qubits = int(num_features / 2)\n",
+ "entangler_map = [[0, 2], [3, 4], [2, 5], [1, 4], [2, 3], [4, 6]]\n",
+ "fm = QuantumCircuit(num_qubits)\n",
+ "training_param = Parameter(\"θ\")\n",
+ "feature_params = ParameterVector(\"x\", num_qubits * 2)\n",
+ "fm.ry(training_param, fm.qubits)\n",
+ "for cz in entangler_map:\n",
+ " fm.cz(cz[0], cz[1])\n",
+ "for i in range(num_qubits):\n",
+ " fm.rz(-2 * feature_params[2 * i + 1], i)\n",
+ " fm.rx(-2 * feature_params[2 * i], i)\n",
+ "\n",
+ "# Assign tunable parameter to known optimal value and set the data params for first two samples\n",
+ "x1 = 14\n",
+ "x2 = 19\n",
+ "unitary1 = fm.assign_parameters(list(X_train[x1]) + [np.pi / 2])\n",
+ "unitary2 = fm.assign_parameters(list(X_train[x2]) + [np.pi / 2])\n",
+ "\n",
+ "# Create the overlap circuit\n",
+ "overlap_circ = unitary_overlap(unitary1, unitary2)\n",
+ "overlap_circ.measure_all()\n",
+ "\n",
+ "# ------------------------------ Step 2 ------------------------------\n",
+ "service = QiskitRuntimeService()\n",
+ "# backend = service.least_busy(\n",
+ "# operational=True, simulator=False, min_num_qubits=overlap_circ.num_qubits\n",
+ "# )\n",
+ "backend = service.backend(\"ibm_pittsburgh\")\n",
+ "print(f\"Using backend: {backend.name}\")\n",
+ "pm = generate_preset_pass_manager(optimization_level=3, backend=backend)\n",
+ "overlap_ibm = pm.run(overlap_circ)\n",
+ "\n",
+ "# ------------------------------ Step 3 ------------------------------\n",
+ "sampler = Sampler(mode=backend)\n",
+ "sampler.options.environment.job_tags = [\"TUT_QKT\"]\n",
"\n",
- "Once we have uploaded the pattern to the cloud, we can easily run it using the `IBMServerlessProvider` client. For simplicity, we will use an exact quantum simulator in the cloud environment, so the fidelity we calculate will be exact."
+ "num_shots = 10_000\n",
+ "results = sampler.run([overlap_ibm], shots=num_shots).result()\n",
+ "counts = results[0].data.meas.get_int_counts()\n",
+ "visualize_counts(counts, num_qubits, num_shots)\n",
+ "\n",
+ "# ------------------------------ Step 4 ------------------------------\n",
+ "kernel_matrix[x1, x2] = counts.get(0, 0.0) / num_shots\n",
+ "print(f\"Fidelity (hardware): {kernel_matrix[x1, x2]}\")"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "c70725fe-57e9-42ed-a0a4-daf0222ddc3a",
+ "cell_type": "markdown",
+ "id": "dec33657-9055-4fdc-b146-dba0e5882719",
"metadata": {},
- "outputs": [],
"source": [
- "generate_kernel_entry = serverless.load(\"generate-kernel-entry\")\n",
- "job = generate_kernel_entry.run(\n",
- " sample1=list(X_train[x1]), sample2=list(X_train[x2])\n",
- ")\n",
+ "To fill out the entire kernel matrix, we would run a quantum experiment for each of its $N(N+1)/2$ unique entries. The figure below shows the resulting matrix for this dataset; darker red indicates fidelities closer to 1.0.\n",
"\n",
- "kernel_matrix[x1, x2] = job.result()[\"fidelity\"]\n",
- "print(f\"fidelity: {kernel_matrix[x1, x2]}\")"
+ ""
]
},
{
@@ -376,11 +435,17 @@
"id": "6847b837",
"metadata": {},
"source": [
- "## Tutorial survey\n",
+ "## Next steps\n",
"\n",
- "Please take this short survey to provide feedback on this tutorial. Your insights will help us improve our content offerings and user experience.\n",
+ "\n",
+ "If you found this work interesting, you might be interested in the following material:\n",
"\n",
- "[Link to survey](https://your.feedback.ibm.com/jfe/form/SV_6xsFvUYV1pNHCqW)"
+ " - [Quantum Kernel Training Toolkit](https://github.com/qiskit-community/prototype-quantum-kernel-training/tree/main) - the prototype repository this tutorial is based on\n",
+ " - [Quantum Kernel Training for Machine Learning Applications](https://qiskit-community.github.io/qiskit-machine-learning/tutorials/08_quantum_kernel_trainer.html) - a Qiskit Machine Learning tutorial showing how to train the trainable parameter\n",
+ " - [Introduction to Quantum Machine Learning](/learning/courses/quantum-machine-learning/introduction) - a course on quantum machine learning\n",
+ " - [Quantum Machine Learning from IBM Research](https://research.ibm.com/topics/quantum-machine-learning) - an overview of QML research at IBM\n",
+ " - [Covariant quantum kernels for data with group structure](https://arxiv.org/abs/2105.03406) - the paper this tutorial is based on\n",
+ ""
]
}
],
diff --git a/public/docs/images/tutorials/quantum-kernel-training/extracted-outputs/49607b34-9723-493d-85da-bd97c1351104-0.avif b/public/docs/images/tutorials/quantum-kernel-training/extracted-outputs/49607b34-9723-493d-85da-bd97c1351104-0.avif
deleted file mode 100644
index 3293181b4a6..00000000000
Binary files a/public/docs/images/tutorials/quantum-kernel-training/extracted-outputs/49607b34-9723-493d-85da-bd97c1351104-0.avif and /dev/null differ
diff --git a/public/docs/images/tutorials/quantum-kernel-training/extracted-outputs/70d6faff-9a56-44bb-b26f-f573a8c90889-0.avif b/public/docs/images/tutorials/quantum-kernel-training/extracted-outputs/70d6faff-9a56-44bb-b26f-f573a8c90889-0.avif
index 0b18998e44e..16ae2ce9e08 100644
Binary files a/public/docs/images/tutorials/quantum-kernel-training/extracted-outputs/70d6faff-9a56-44bb-b26f-f573a8c90889-0.avif and b/public/docs/images/tutorials/quantum-kernel-training/extracted-outputs/70d6faff-9a56-44bb-b26f-f573a8c90889-0.avif differ
diff --git a/public/docs/images/tutorials/quantum-kernel-training/extracted-outputs/d2f4f6cf-067e-4d53-aa04-7ca9c803d3e1-0.avif b/public/docs/images/tutorials/quantum-kernel-training/extracted-outputs/d2f4f6cf-067e-4d53-aa04-7ca9c803d3e1-0.avif
deleted file mode 100644
index 3386708722c..00000000000
Binary files a/public/docs/images/tutorials/quantum-kernel-training/extracted-outputs/d2f4f6cf-067e-4d53-aa04-7ca9c803d3e1-0.avif and /dev/null differ
diff --git a/public/docs/images/tutorials/quantum-kernel-training/extracted-outputs/d2f4f6cf-067e-4d53-aa04-7ca9c803d3e1-1.avif b/public/docs/images/tutorials/quantum-kernel-training/extracted-outputs/d2f4f6cf-067e-4d53-aa04-7ca9c803d3e1-1.avif
new file mode 100644
index 00000000000..e25bbafcff7
Binary files /dev/null and b/public/docs/images/tutorials/quantum-kernel-training/extracted-outputs/d2f4f6cf-067e-4d53-aa04-7ca9c803d3e1-1.avif differ
diff --git a/public/docs/images/tutorials/quantum-kernel-training/extracted-outputs/step3-small-code-0.avif b/public/docs/images/tutorials/quantum-kernel-training/extracted-outputs/step3-small-code-0.avif
new file mode 100644
index 00000000000..5cb48c962bc
Binary files /dev/null and b/public/docs/images/tutorials/quantum-kernel-training/extracted-outputs/step3-small-code-0.avif differ