Quantum kernel training
Tinantyang paggamit: wala pang isang minuto sa Heron r3 processor (PAALALA: Ito ay tantya lamang. Maaaring mag-iba ang iyong runtime.)
Learning outcomes
Pagkatapos makumpleto ang tutorial na ito, maaari mong asahang mauunawaan ang mga sumusunod na impormasyon:
- Mga kernel method at ang kanilang mga gamit
- Mga quantum kernel at kung paano sila nagbibigay ng pinahusay na feature space
- Pagbuo ng quantum kernel circuit
- Paano mag-train ng quantum kernel gamit ang Qiskit pattern: map, optimize, execute, at post-process
Prerequisites
Inirerekomenda na maging pamilyar ka sa mga quantum kernel, kung bakit sila mahalaga, at kung paano sila ginagamit sa praktis.
- Covariant quantum kernels for data with group structure (papel)
- Introduction to Quantum Kernels and Support Vector Machines (video)
- Quantum Kernels in Practice (video)
Kapaki-pakinabang din ang magkaroon ng pangunahing pag-unawa sa group theory.
Background
Ang mga kernel method ay karaniwan sa mga aplikasyon ng machine learning. Sa kontekstong ito, ang "kernel" ay tumutukoy sa kernel matrix o sa mga indibidwal na entry nito. Sa pangkalahatan, ang kernel ay isang sukatan ng pagkakatulad sa pagitan ng data na naka-encode sa isang mataas na dimensyon na feature space at maaaring gamitin, halimbawa, sa mga gawain ng classification gamit ang mga support vector machine.
Ang mga quantum kernel method ay yaong gumagamit ng mga quantum computer upang tantiyahin ang isang kernel. Kilala na ang mga quantum computer ay maaaring mag-encode ng data sa mga quantum-enhanced feature space, na epektibong pinapalitan ang mga klasikal na katumbas. Para sa at , karaniwang may , ang ay isang feature map, . Ang layunin ng ay gawing hiwalay ang mga kategorya ng data sa pamamagitan ng isang hyperplane. Sa pagkuha ng mga vector sa feature-mapped space bilang mga argumento, ang kernel function na ay nagbabalik ng kanilang inner product: . Sa klasikal na paraan, ang mga feature map na interesado ay yaong kung saan ang kernel function ay madaling masuri; ibig sabihin, kapag ang inner product sa feature-mapped space ay maaaring isulat sa mga tuntunin ng mga orihinal na data vector at ang at ay hindi na kailangang itayo. Sa kaso ng mga quantum kernel, ang feature mapping ay isinasagawa ng isang quantum circuit, at ang kernel ay tinatantiya gamit ang mga probability ng pagsukat na na-sample mula sa circuit.
Ipinakikita ng tutorial na ito kung paano bumuo ng Qiskit pattern para sa pagsusuri ng mga entry sa quantum kernel matrix na ginagamit para sa binary classification.
Requirements
Bago magsimula ng tutorial na ito, tiyaking nakainstall ang mga sumusunod:
- Qiskit SDK v2.3.1 o mas bago, na may visualization support
- Qiskit Runtime v0.44.0 o mas bago (
pip install qiskit-ibm-runtime)
Setup
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy pandas qiskit qiskit-ibm-runtime
# General Imports and helper functions
import urllib.request
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from qiskit.circuit import Parameter, ParameterVector, QuantumCircuit
from qiskit.circuit.library import unitary_overlap
from qiskit.primitives import StatevectorSampler
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService, Sampler
# Download the dataset (portable across platforms)
urllib.request.urlretrieve(
"https://raw.githubusercontent.com/qiskit-community/prototype-quantum-kernel-training/main/data/dataset_graph7.csv",
"dataset_graph7.csv",
)
def visualize_counts(res_counts, num_qubits, num_shots):
"""Visualize the outputs from the Qiskit Sampler primitive."""
zero_prob = res_counts.get(0, 0.0)
top_10 = dict(
sorted(res_counts.items(), key=lambda item: item[1], reverse=True)[
:10
]
)
top_10.update({0: zero_prob})
by_key = dict(sorted(top_10.items(), key=lambda item: item[0]))
x_vals, y_vals = list(zip(*by_key.items()))
x_vals = [bin(x_val)[2:].zfill(num_qubits) for x_val in x_vals]
y_vals_prob = []
for t in range(len(y_vals)):
y_vals_prob.append(y_vals[t] / num_shots)
y_vals = y_vals_prob
plt.bar(x_vals, y_vals)
plt.xticks(rotation=75)
plt.title("Results of sampling")
plt.xlabel("Measured bitstring")
plt.ylabel("Probability")
plt.show()
def get_training_data():
"""Read the training data."""
df = pd.read_csv("dataset_graph7.csv", sep=",", header=None)
training_data = df.values[:20, :]
ind = np.argsort(training_data[:, -1])
X_train = training_data[ind][:, :-1]
return X_train
Small-scale simulator example
Sa seksyong ito, tatalakay tayo sa apat na hakbang ng Qiskit pattern sa isang pitong-qubit na instance ng labeling-cosets-with-error problem at suriin ang isang kernel matrix entry gamit ang StatevectorSampler primitive mula sa Qiskit. Ang statevector simulator ay eksakto (hanggang sa shot noise) at ipinapakita sa atin ang paraan mula simula hanggang katapusan nang hindi gumagamit ng QPU time. Uulitin natin ang parehong instance sa tunay na hardware sa seksyon ng hardware example.
Step 1: Map classical inputs to a quantum problem
- Input: Training dataset.
- Output: Abstract circuit para sa pagkalkula ng kernel matrix entry.
Ang binary classification problem na layunin nating lutasin dito ay tinatawag na "labeling cosets with error." Ang input training dataset ay naglalaman ng group structure, na binubuo ng dalawang coset na nabuo ng isang grupo at subgroup. Ang grupo ay kinuha bilang para sa mga qubit, na siyang espesyal na unitary group ng matrices at may malawak na pagiging angkop sa kalikasan; hal., ang Standard Model ng particle physics. Kinukuha natin ang (graph-stabilizer) subgroup na na may para sa isang graph na may mga gilid na at mga vertex na . Tandaan na ang mga stabilizer ay nag-aayos ng stabilizer state upang ang . Sa wakas, nagtatakda tayo ng dalawang left-coset na sa pamamagitan ng pagkuha ng dalawang nang random.
Para sa karagdagang detalye tungkol sa dataset at kung paano ito nalilikha, tingnan ang notebook na ito mula sa Quantum Kernel Training Toolkit.
Lumilikha tayo ng quantum circuit na ginagamit upang suriin ang isang entry sa kernel matrix.
Ginagamit ang input data upang matukoy ang mga rotation angle para sa parametrized gates ng circuit.
Para sa simplicity, gagamitin natin ang mga data sample na x1=14 at x2=19.
Paalala: Ang dataset na ginamit sa tutorial na ito ay maaaring i-download dito.
# Prepare training data
X_train = get_training_data()
# Empty kernel matrix
num_samples = np.shape(X_train)[0]
kernel_matrix = np.full((num_samples, num_samples), np.nan)
# Prepare feature map for computing overlap
num_features = np.shape(X_train)[1]
num_qubits = int(num_features / 2)
entangler_map = [[0, 2], [3, 4], [2, 5], [1, 4], [2, 3], [4, 6]]
fm = QuantumCircuit(num_qubits)
training_param = Parameter("θ")
feature_params = ParameterVector("x", num_qubits * 2)
fm.ry(training_param, fm.qubits)
for cz in entangler_map:
fm.cz(cz[0], cz[1])
for i in range(num_qubits):
fm.rz(-2 * feature_params[2 * i + 1], i)
fm.rx(-2 * feature_params[2 * i], i)
# Assign tunable parameter to known optimal value and set the data params for
# first two samples
x1 = 14
x2 = 19
unitary1 = fm.assign_parameters(list(X_train[x1]) + [np.pi / 2])
unitary2 = fm.assign_parameters(list(X_train[x2]) + [np.pi / 2])
# Create the overlap circuit
overlap_circ = unitary_overlap(unitary1, unitary2)
overlap_circ.measure_all()
overlap_circ.draw("mpl", scale=0.6, style="iqp")
Step 2: Optimize problem for quantum hardware execution
- Input: Abstract circuit, na hindi pa nao-optimize para sa partikular na backend.
- Output: Target circuit, na nao-optimize para sa piniling QPU.
Para sa statevector simulator path na ginagamit sa seksyong ito, walang kailangang backend-specific optimization: ang abstract circuit ay maaaring direktang ma-sample. Isasagawa natin ang hakbang na ito sa hardware example sa ibaba, kung saan ang circuit ay tina-transpile laban sa isang tunay na QPU gamit ang generate_preset_pass_manager na may optimization_level=3.
Step 3: Execute using Qiskit primitives
- Input: Abstract circuit.
- Output: Quasi-probability distribution.
Gamitin ang StatevectorSampler primitive mula sa Qiskit upang muling buuin ang quasi-probability distribution ng mga state na nagmula sa pag-sample ng circuit. Para sa gawain ng pagbuo ng kernel matrix, partikular kaming interesado sa probability ng pagsukat ng |0> state.
sampler = StatevectorSampler()
# Execute and get counts
num_shots = 10_000
results = sampler.run([overlap_circ], shots=num_shots).result()
counts = results[0].data.meas.get_int_counts()
# Plot counts
visualize_counts(counts, num_qubits, num_shots)
Step 4: Post-process and return result in desired classical format
- Input: Probability distribution.
- Output: Isang kernel matrix element.
Kalkulahin ang probability ng pagsukat ng sa overlap circuit, at punan ang kernel matrix sa posisyon na tumutugma sa mga sample na kinakatawan ng partikular na overlap circuit na ito (row 15, column 20).
kernel_matrix[x1, x2] = counts.get(0, 0.0) / num_shots
print(f"Fidelity (simulator): {kernel_matrix[x1, x2]}")
Fidelity (simulator): 0.8261
Hardware example
Ang quantum kernel matrix ay may na mga entry para sa na mga training sample, at bawat entry ay nangangailangan ng pagpapatakbo ng overlap circuit na ang two-qubit-gate depth ay lumalaki kasabay ng laki ng feature map. Bilang resulta, ang pag-scale ng tutorial na ito sa mas malaking problema ay may dalawang compounding cost: ang QPU time bawat kernel matrix ay lumalaki nang quadratically kasabay ng , at ang depth ng unitary_overlap (na gumagawa ng feature map kasama ang adjoint nito) ay nagpapababa ng fidelity sa system size at connectivity ng kasalukuyang hardware. Upang mapanatiling maikli ang demo at makagawa ng malinis na paghahambing, pinapatakbo natin ang parehong pitong-qubit na instance mula sa small-scale example sa isang tunay na QPU at inihahambing ang fidelity ng isang kernel matrix entry laban sa simulator value na kinalkula sa itaas.
# ------------------------------ Step 1 ------------------------------
# Prepare training data
X_train = get_training_data()
# Empty kernel matrix
num_samples = np.shape(X_train)[0]
kernel_matrix = np.full((num_samples, num_samples), np.nan)
# Prepare feature map for computing overlap
num_features = np.shape(X_train)[1]
num_qubits = int(num_features / 2)
entangler_map = [[0, 2], [3, 4], [2, 5], [1, 4], [2, 3], [4, 6]]
fm = QuantumCircuit(num_qubits)
training_param = Parameter("θ")
feature_params = ParameterVector("x", num_qubits * 2)
fm.ry(training_param, fm.qubits)
for cz in entangler_map:
fm.cz(cz[0], cz[1])
for i in range(num_qubits):
fm.rz(-2 * feature_params[2 * i + 1], i)
fm.rx(-2 * feature_params[2 * i], i)
# Assign tunable parameter to known optimal value and
# set the data params for first two samples
x1 = 14
x2 = 19
unitary1 = fm.assign_parameters(list(X_train[x1]) + [np.pi / 2])
unitary2 = fm.assign_parameters(list(X_train[x2]) + [np.pi / 2])
# Create the overlap circuit
overlap_circ = unitary_overlap(unitary1, unitary2)
overlap_circ.measure_all()
# ------------------------------ Step 2 ------------------------------
service = QiskitRuntimeService()
# backend = service.least_busy(
# operational=True, simulator=False, min_num_qubits=overlap_circ.num_qubits
# )
backend = service.backend("ibm_pittsburgh")
print(f"Using backend: {backend.name}")
pm = generate_preset_pass_manager(optimization_level=3, backend=backend)
overlap_ibm = pm.run(overlap_circ)
# ------------------------------ Step 3 ------------------------------
sampler = Sampler(mode=backend)
sampler.options.environment.job_tags = ["TUT_QKT"]
num_shots = 10_000
results = sampler.run([overlap_ibm], shots=num_shots).result()
counts = results[0].data.meas.get_int_counts()
visualize_counts(counts, num_qubits, num_shots)
# ------------------------------ Step 4 ------------------------------
kernel_matrix[x1, x2] = counts.get(0, 0.0) / num_shots
print(f"Fidelity (hardware): {kernel_matrix[x1, x2]}")
Using backend: ibm_pittsburgh
Fidelity (hardware): 0.7517
Upang mapunan ang buong kernel matrix, magpapatakbo tayo ng quantum experiment para sa bawat isa sa na natatanging mga entry nito. Ipinapakita ng figure sa ibaba ang resultang matrix para sa dataset na ito; ang mas madilim na pula ay nagsasaad ng mga fidelity na mas malapit sa 1.0.
Next steps
Kung nakita mong kawili-wili ang gawaing ito, maaaring interesado ka sa mga sumusunod na materyal:
- Quantum Kernel Training Toolkit - ang prototype repository kung saan nakabatay ang tutorial na ito
- Quantum Kernel Training for Machine Learning Applications - isang Qiskit Machine Learning tutorial na nagpapakita kung paano i-train ang trainable parameter
- Introduction to Quantum Machine Learning - isang kurso sa quantum machine learning
- Quantum Machine Learning from IBM Research - isang pangkalahatang-ideya ng QML research sa IBM
- Covariant quantum kernels for data with group structure - ang papel kung saan nakabatay ang tutorial na ito