Quantekernel-Training
Schätzung för d'r Verbruch: unger eener Menutt op enem Eagle r3 Prozessor (OPJEPASS: Dat es nor en Schätzung. Ding Laufzick künnt angers sin.)
Hintergrund
Dat Tutorial zeich, wi mer e Qiskit-Muster baut för et Usrechne vun Indräsch en ene Quantekernel-Matrix, di för binär Klassifikation jebruch weed. Mih Informazjune övver Qiskit-Muster un wi Qiskit Serverless doför jebruch weed kann, se en de Cloud ze deploye för et Verwalte vun d'r Usföhrung, fingk de op uns Dokumentazjuns-Sick övver IBM Quantum® Platform.
Vörussetzunge
Ih dat de met däm Tutorial aanfängks, stell sescher, dat de dat hee häs installeet:
- Qiskit SDK v1.0 oder späder, met Visualisierung-Ungerstötzung
- Qiskit Runtime v0.22 oder späder (
pip install qiskit-ibm-runtime)
Opbau
!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
Schrett 1: Klassische Indäte op e Quanteproblem afbilde
- Indabe: Trainingsdatensatz.
- Usjoov: Abstrakte Schaltkreis för et Berechne vun enem Kernelmatrix-Indraach.
Baut dä Quanteschaltkreis, dä jebruch weed för et Usrechne vun enem eenzije Indraach en d'r Kernelmatrix. Mer bruche di Indabe-Date för ze bestimme, wat di Rotazjuns-Wengkel för di parametriseerde Gates sin. Mer wäde di Daate-Probe x1=14 un x2=19 bruche.
Opjepass: Dä Datensatz, dä en däm Tutorial jebruch weed, kann hee eronjerjelohde wäde.
# 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")
Schrett 2: Dat Problem för Quantehardware-Usföhrung optimiere
- Indabe: Abstrakte Schaltkreis, nit optimeet för e bestemmp Backend
- Usjoov: Ziel-Schaltkreis un Observable, optimeet för di usjesöchte QPU
Bruuch di generate_preset_pass_manager-Funkzjun vun Qiskit för ene Optimeerungslauf för uns Schaltkreis ze spezifiziere, bezoche op di QPU, op dä mer et Experimente lofe losse welle. Mer sätze optimization_level=3, wat bedügg, dat mer dä vördefineerte Pass Manager bruche, dä et hühste Optimeerungsniveau bringk.
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")
Schrett 3: Usföhrung met Qiskit-Primitive
- Indabe: Ziel-Schaltkreis
- Usjoov: Quasi-Wohrschinglichkeitsverdeijlung
Bruuch dä Sampler-Primitiv vun Qiskit Runtime för en Quasi-Wohrschinglichkeitsverdeijlung vun Zoschtäng ze rekonstrueere, di us däm Sample vum Schaltkreis eruskomme. För et Erstelle vun ene Kernelmatrix sin mer besöngers interesseet aan d'r Wohrschinglichkeit, dä |0>-Zoschdand ze mässe.
För dat Demo losse mer dat op ener QPU met qiskit-ibm-runtime-Primitive. För et Lofe op qiskit-Statevector-baseerde Primitive, ersetze dä Codeblock för Qiskit IBM® Runtime-Primitive dörch dä kommenteete 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)
Schrett 4: Nohbeärbeide un et Resultat em jewönschte klassische Format zeröckjevve
- Indabe: Wohrschinglichkeitsverdeijlung
- Usjoov: E eenzel Kernelmatrix-Element
Berächne di Wohrschinglichkeit för et Mässe vun |0> op däm Overlap-Schaltkreis un föll di Kernelmatrix aan d'r Posizjun, di dä Probe entsprich, di dörch dämm bestemmp Overlap-Schaltkreis dojestellt wääde (Reih 15, Kolonn 20). En dä Visualisierung zeich dunkleres Rut Fidelitäte nöher aan 1.0 aan. För di ganze Kernelmatrix uszfölle, mosse mer e Quanteexperimente för jede Indraach lofe losse.
# 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
Dat Qiskit-Muster en de Cloud deploye
För dat ze maache, övverdraach dä Quellcode vun bovven en en Datei, ./source/generate_kernel_entry.py, pack dä Code en e Skript, dat Indabe nimmp un di endgöltije Lüsung zeröckjitt, un lad et dann op ene Ferncluster rop met d'r QiskitFunction-Klass vun Qiskit Serverless. För Anwijsunge övver et Spezifiziere vun externe Abhängigkeite, et Üvverjävve vun Indabe-Argumente un mih, luur noh de Qiskit Serverless-Anlijdunge.
Di Indabe för dat Muster es e Paar vun Daate-Probe, x1 un x2. Di Usjoov es di Fidelität zwesche dä zwei Probe. Dämm Wäät weed jebruch för dä Kernelmatrix-Indraach ze fölle, dä dä zwei Probe entsprich.
serverless = QiskitServerless()
kernel_entry_pattern = QiskitFunction(
title="generate-kernel-entry",
entrypoint="generate_kernel_entry.py",
working_dir="./source/",
)
serverless.upload(kernel_entry_pattern)
Dat Qiskit-Muster als verwalldete Deens lofe losse
Nohdämm mer dat Muster en de Cloud ropjelohde han, künne mer et einfach met däm IBMServerlessProvider-Client lofe losse. För et einfacher ze maache, wäde mer ene exakte Quantesimulator en d'r Cloud-Ömjevvung bruche, su dat di Fidelität, di mer berechne, exakt es.
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-Ömfrooch
Maach met bei dä koot Ömfrooch, öm Feedback för dat Tutorial ze jevve. Ding Einsichte wääde uns hälfe, uns Inhalte un di Benotzer-Erfahrung ze verbessere.