Quantenkernel-Training
Verbrauchsschätzung: unter eena Minute uff'm Eagle r3 Prozessor (ACHTUNG: Dit is bloß 'ne Schätzung. Deine Laufzeit könnte anderet aussehen.)
Hintergrund
Dit Tutorial zeicht, wie man 'n Qiskit-Muster baut zum Ausrechnen von Einträjen in 'ne Quantenkernel-Matrix, die für binäre Klassifikation jebraucht wird. Für mehr Infos über Qiskit-Muster und wie Qiskit Serverless benutzt werden kann, um se in die Cloud zu deployen für verwaltete Ausführung, jeh uff unsere Dokumentations-Seite über IBM Quantum® Platform.
Voraussetzungen
Bevor de mit dit Tutorial anfängst, stell sicher, datte dit hier installiert hast:
- Qiskit SDK v1.0 oda späta, mit Visualisierung-Unterstützung
- Qiskit Runtime v0.22 oda späta (
pip install qiskit-ibm-runtime)
Uffbau
!wget https://raw.githubusercontent.com/qiskit-community/prototype-quantum-kernel-training/main/data/dataset_graph7.csv
# General Imports and helper functions
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 UnitaryOverlap
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService, Sampler
# from qiskit_serverless import IBMServerlessClient, QiskitFunction
from qiskit_ibm_catalog import QiskitServerless, QiskitFunction
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
7[1A[1G[27G[Files: 0 Bytes: 0 [0 B/s] Re]87[2A[1G[27G[https://raw.githubusercontent.]87[1S[3A[1G[0JSaving 'dataset_graph7.csv.1'
87[2A[1Gdataset_graph7.csv.1 100% [=============================>] 20.25K --.-KB/s87[1S[3A[1G[0JHTTP response 200 [https://raw.githubusercontent.com/qiskit-community/prototype-quantum-kernel-training/main/data/dataset_graph7.csv]
87[2A[1Gdataset_graph7.csv.1 100% [=============================>] 20.25K --.-KB/s87[1A[1G[27G[Files: 1 Bytes: 20.25K [93.33]8[m[m[m[m
Schritt 1: Klassische Eingaben uff 'n Quantenproblem abbilden
- Eingabe: Trainingsdatensatz.
- Ausgabe: Abstrakter Schaltkreis zum Berechnen von 'n Kernelmatrix-Eintrag.
Bau den Quantenschaltkreis, der jebraucht wird zum Ausrechnen von een einzelnen Eintrag in de Kernelmatrix. Wir brauchen die Eingabe-Daten zum festlegen, wat die Rotationswinkel für die parametrisierten Gates sind. Wir werden die Daten-Proben x1=14 und x2=19 benutzen.
Achtung: Der Datensatz, der in dit Tutorial jebraucht wird, kann hier runterjeladen werden.
# 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 = UnitaryOverlap(unitary1, unitary2)
overlap_circ.measure_all()
overlap_circ.draw("mpl", scale=0.6, style="iqp")
Schritt 2: Det Problem für Quantenhardware-Ausführung optimieren
- Eingabe: Abstrakter Schaltkreis, nischt optimiert für 'n bestimmtet Backend
- Ausgabe: Ziel-Schaltkreis und Observable, optimiert für die ausjesuchte QPU
Benutz die generate_preset_pass_manager-Funktion von Qiskit zum 'n Optimierungslauf für unseren Schaltkreis zu spezifizieren, bezogen uff die QPU, uff der wir det Experiment laufen lassen wollen. Wir setzen optimization_level=3, wat bedeutet, datte wir den vordefiniert Pass Manager benutzen, der dit höchste Optimierungsniveau bringt.
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=overlap_circ.num_qubits
)
pm = generate_preset_pass_manager(optimization_level=3, backend=backend)
overlap_ibm = pm.run(overlap_circ)
overlap_ibm.draw("mpl", scale=0.6, idle_wires=False, fold=-1, style="iqp")
Schritt 3: Ausführung mit Qiskit-Primitiven
- Eingabe: Ziel-Schaltkreis
- Ausgabe: Quasi-Wahrscheinlichkeitsverteilung
Benutz den Sampler-Primitiv von Qiskit Runtime zum 'ne Quasi-Wahrscheinlichkeitsverteilung von Zuständen zu rekonstruieren, die ausm Sampeln vom Schaltkreis rauskommen. Fürs Erstellen von 'ner Kernelmatrix sind wir besonders interessiert an de Wahrscheinlichkeit, den |0>-Zustand zu messen.
Für dit Demo lassen wir det uff 'ner QPU mit qiskit-ibm-runtime-Primitiven laufen. Um det uff qiskit-Statevector-basierte Primitiven laufen zu lassen, ersetz den Codeblock für Qiskit IBM® Runtime-Primitiven durch den kommentierten Block.
num_shots = 10_000
## Evaluate the problem using statevector-based primitives from Qiskit
# from qiskit.primitives import StatevectorSampler
# sampler = StatevectorSampler()
# results = sampler.run([overlap_circ]).result()
# counts = results[0].data.meas.get_int_counts()
# Evaluate the problem using a QPU via Qiskit IBM Runtime
sampler = Sampler(mode=backend)
results = sampler.run([overlap_ibm]).result()
counts = results[0].data.meas.get_int_counts()
visualize_counts(counts, num_qubits, num_shots)
Schritt 4: Nachbearbeitung und det Resultat im jewünschten klassischen Format zurückjeben
- Eingabe: Wahrscheinlichkeitsverteilung
- Ausgabe: 'n einzelnet Kernelmatrix-Element
Berechne die Wahrscheinlichkeit zum |0> uffm Overlap-Schaltkreis zu messen und füll die Kernelmatrix an de Position, die den Proben entspricht, die durch dit bestimmte Overlap-Schaltkreis darjestellt werden (Reihe 15, Spalte 20). In diese Visualisierung zeigt dünkleret Rot Fidelitäten näher an 1.0. Um die janze Kernelmatrix auszufüllen, müssen wir 'n Quantenexperiment für jeden Eintrag laufen lassen.
# Calculate the fidelity, or the probability to measure 0
kernel_matrix[x1, x2] = counts.get(0, 0.0) / num_shots
print(f"Fidelity: {kernel_matrix[x1, x2]}")
Fidelity: 0.1279
Det Qiskit-Muster in die Cloud deployen
Um det zu machen, verschieb den Quellcode von oben in 'ne Datei, ./source/generate_kernel_entry.py, pack den Code in 'n Skript, det Eingaben nimmt und die endgültige Lösung zurückgibt, und lad's dann uff 'n Fern-Cluster hoch mit de QiskitFunction-Klasse von Qiskit Serverless. Für Anleitungen zum Spezifizieren von externen Abhängigkeiten, zum Übergeben von Eingabe-Argumenten und mehr, kiek in die Qiskit Serverless-Anleitungen.
Die Eingabe fürs Muster is 'n Paar von Daten-Proben, x1 und x2. Die Ausgabe is die Fidelität zwischen den beiden Proben. Diser Wert wird jebraucht zum den Kernelmatrix-Eintrag zu füllen, der den beiden Proben entspricht.
serverless = QiskitServerless()
kernel_entry_pattern = QiskitFunction(
title="generate-kernel-entry",
entrypoint="generate_kernel_entry.py",
working_dir="./source/",
)
serverless.upload(kernel_entry_pattern)
Det Qiskit-Muster als verwalteten Dienst laufen lassen
Nachdem wir det Muster in die Cloud hochjeladen haben, können wir't einfach mit'n IBMServerlessProvider-Client laufen lassen. Um't einfacher zu machen, werden wir 'n exakten Quantensimulator in de Cloud-Umgebung benutzen, sodass die Fidelität, die wir berechnen, exakt is.
generate_kernel_entry = serverless.load("generate-kernel-entry")
job = generate_kernel_entry.run(
sample1=list(X_train[x1]), sample2=list(X_train[x2])
)
kernel_matrix[x1, x2] = job.result()["fidelity"]
print(f"fidelity: {kernel_matrix[x1, x2]}")
Tutorial-Umfrage
Bitte mach bei dise kurze Umfrage mit, um Feedback zu dit Tutorial zu jeben. Deine Einsichten werden uns helfen, unsere Inhalte und die Benutzer-Erfahrung zu verbessern.