Quantenkernel-Training
Verbrauchsschätzung: unnä ääner Minude uffn Eagle r3 Prozessor (OBACHT: Das is bloß ä Schätzung. Ihre Laufzeit könnt anders säh.)
Hindorgrund
Des Tutorial zeecht, wie mer e Qiskit-Muster baut zum Ausrechnä vun Einträschn in ä Quantenkernel-Matrix, die für binäre Glassifigazioon jebraucht werd. Für mehr Informazioone über Qiskit-Muster un wie Qiskit Serverless verwend werd kann, um se in de Wolge auszurolle für verwaldte Ausführung, gehn Se uff unsre Dogumentazioonsseite über IBM Quantum® Platform.
Voraussetzungn
Bevor Se mit däm Tutorial anfangn, stelln Se sescher, dass Se des hie habm installiert:
- Qiskit SDK v1.0 oddr schbäder, mit Visualisierung-Unnerstützung
- Qiskit Runtime v0.22 oddr schbäder (
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: Glassische Eingabn uff e Quanteprobleeme abbildn
- Eingabe: Trainingsdadnsatz.
- Ausgabe: Abstraggder Schaldgrehs zum Berechnä vun nem Kernelmatrix-Eintrasch.
Baudn Sie den Quantenschaldgrehs, där jebraucht werd zum Ausrechnä vun ääm eenzschn Eintrasch in där Kernelmatrix. Mir brauchm die Eingabe-Dadn zum besteemmä, was de Rotatioonswingl für de parametrisierde Gates sähn. Mir wern die Dadn-Brobn x1=14 un x2=19 verwend.
Obacht: Där Dadnsatz, där in däm Tutorial jebraucht werd, kann hie runnorjeladn wern.
# 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: Des Probleeme für Quantenhardware-Ausführung obdimier'n
- Eingabe: Abstraggder Schaldgrehs, nischt obdimiert für e besteemmdes Backend
- Ausgabe: Ziel-Schaldgrehs un Observable, obdimiert für de ausjesuchde QPU
Verwend' Se de generate_preset_pass_manager-Fungzioon vun Qiskit zum ä Obdimierungslauf für unsrn Schaldgrehs zu schbezifizier'n, was de QPU angeht, uff där mir des Exberiment laafn lassn wolln. Mir setzn optimization_level=3, was bedeudt, dass mir den vordefinierdn Pass Manager verwend', där des höchsde Obdimierungsniveau 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-Brimidie'n
- Eingabe: Ziel-Schaldgrehs
- Ausgabe: Quasi-Wahrscheinlichkeitsverdeilung
Verwend' Se den Sampler-Brimitiv vun Qiskit Runtime zum ä Quasi-Wahrscheinlichkeitsverdeilung vun Zuschdändn zu regunstruier'n, die durchs Sampl'n vum Schaldgrehs rauskummn. Fürs Erstelln vun där Kernelmatrix sähn mir besonders innteressiert an där Wahrscheinlichkeit, den |0>-Zuschdand zu messn.
Für des Demo lassn mir des uff ner QPU mit qiskit-ibm-runtime-Brimidie'n laafn. Zum des uff qiskit-Statevector-basierde Brimidie'n laafn zu lassn, ersetzn Se den Codeblock für Qiskit IBM® Runtime-Brimidie'n durch den gommentierdn 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 un des Resuldad im jewünschdn glassischn Format zurüchgeem
- Eingabe: Wahrscheinlichkeitsverdeilung
- Ausgabe: E eenzsches Kernelmatrix-Element
Rechndn Se de Wahrscheinlichkeit zum |0> uffm Overlap-Schaldgrehs zu messn un fülln Se de Kernelmatrix an där Bosizjoon, die den Brobn entspricht, die durch den besteemmdn Overlap-Schaldgrehs darjeschdelld wern (Reihe 15, Golonne 20). In dieser Visualisierung zeecht dungleres Roote Fidelitäd'n nähä an 1.0. Zum de ganze Kernelmatrix auszufülln, müssn mir e Quantenexberiment für jedn Eintrasch laafn lassn.
# 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
Des Qiskit-Muster in de Wolge ausroll'n
Zum des zu machä, versch' Se den Quellcode vun ob'n in ä Dadei, ./source/generate_kernel_entry.py, packn Se den Code in e Sgriebt, des Eingabn nimmt un de endgüldische Leesung zurüchgibt, un ladn Se's dann uff ä Fern-Cluster rauff mit där QiskitFunction-Glasse vun Qiskit Serverless. Für Anleitungä zum Schbezifizier'n vun externen Abhängigkeidn, zum Übergeem vun Eingabe-Argumändn un mehr, guggn Se in de Qiskit Serverless-Anleitungä.
De Eingabe fürs Muster is e Baar vun Dadn-Brobn, x1 un x2. De Ausgabe is de Fidelität zwischn den beeden Brobn. Dieser Werd werd jebraucht zum den Kernelmatrix-Eintrasch zu fülln, där den beeden Brobn entspricht.
serverless = QiskitServerless()
kernel_entry_pattern = QiskitFunction(
title="generate-kernel-entry",
entrypoint="generate_kernel_entry.py",
working_dir="./source/",
)
serverless.upload(kernel_entry_pattern)
Des Qiskit-Muster als verwaldedn Dienscht laafn lassn
Nachdem mir des Muster in de Wolge rauffjeladn hamm, könn mer's einfach mit däm IBMServerlessProvider-Client laafn lassn. Zum des einfacher zu machä, wern mir än exagdn Quantensimulator in där Wolgen-Umgebung verwend'n, sodass de Fidelität, die mir berechne, exagt 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-Umfrache
Bitte machä Se bei dieser gorzn Umfrache mit, um Feedbagg zu däm Tutorial zu geem. Ihre Einblicke wern uns helfä, unsre Inhalte un de Benutzer-Erfahrung zu verbessern.