Lewati ke konten utama

Pelatihan kernel kuantum

Perkiraan penggunaan: kurang dari satu menit pada prosesor Heron r3 (CATATAN: Ini hanya perkiraan. Waktu eksekusi kamu bisa berbeda.)

Hasil pembelajaran

Setelah menyelesaikan tutorial ini, kamu diharapkan dapat memahami hal-hal berikut:

  • Metode kernel dan kegunaannya
  • Kernel kuantum dan bagaimana mereka dapat menyediakan ruang fitur yang ditingkatkan
  • Konstruksi sirkuit kernel kuantum
  • Cara melatih kernel kuantum menggunakan pola Qiskit: pemetaan, optimasi, eksekusi, dan pasca-pemrosesan

Prasyarat

Disarankan agar kamu mengenal kernel kuantum, mengapa mereka penting, dan bagaimana penggunaannya dalam praktik.

Juga berguna untuk memiliki pemahaman dasar tentang teori grup.

Latar Belakang

Metode kernel sudah umum digunakan dalam aplikasi machine learning. Dalam konteks ini, "kernel" mengacu pada matriks kernel atau entri-entri individualnya. Secara umum, kernel adalah ukuran kesamaan antara data yang dikodekan dalam ruang fitur berdimensi tinggi dan dapat dimanfaatkan, misalnya, dalam tugas klasifikasi dengan support vector machine.

Metode kernel kuantum adalah yang menggunakan komputer kuantum untuk memperkirakan kernel. Diketahui bahwa komputer kuantum dapat mengkodekan data dalam ruang fitur yang ditingkatkan secara kuantum, secara efektif menggantikan analog klasikal. Untuk xR\vec{x} \in \mathbb{R} dan Ψ(x)Rd\Psi(\vec{x}) \in \mathbb{R}^{d'}, biasanya dengan d>dd' >d, Ψ(x)\Psi(\vec{x}) adalah peta fitur, xΨ(x)\vec{x} \mapsto \Psi(\vec{x}). Tujuan Ψ(x)\Psi(\vec{x}) adalah membuat kategori data terpisah oleh sebuah hiperplane. Mengambil vektor-vektor dalam ruang yang telah dipetakan oleh fitur sebagai argumen, fungsi kernel K(x,y)=Ψ(x)Ψ(y)K(\vec{x}, \vec{y}) = \langle{\Psi(\vec{x}) | \Psi(\vec{y}) \rangle{}} mengembalikan perkalian dalam mereka: K:RdK: \mathbb{R}^d \rightarrow Rd\mathbb{R}^d. Secara klasikal, peta fitur yang menarik adalah yang fungsi kernelnya dapat dengan mudah dievaluasi; yaitu, ketika perkalian dalam di ruang yang dipetakan fitur dapat ditulis dalam bentuk vektor data asli dan Ψ(x)\Psi(\vec{x}) serta Ψ(y)\Psi(\vec{y}) tidak perlu dikonstruksi. Dalam kasus kernel kuantum, pemetaan fitur dilakukan oleh sirkuit kuantum, dan kernel diperkirakan menggunakan probabilitas pengukuran yang diambil sampelnya dari sirkuit.

Tutorial ini menunjukkan cara membangun pola Qiskit untuk mengevaluasi entri dalam matriks kernel kuantum yang digunakan untuk klasifikasi biner.

Persyaratan

Sebelum memulai tutorial ini, pastikan kamu sudah menginstal hal-hal berikut:

  • Qiskit SDK v2.3.1 atau lebih baru, dengan dukungan visualisasi
  • Qiskit Runtime v0.44.0 atau lebih baru (pip install qiskit-ibm-runtime)

Pengaturan

# 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

Contoh simulator skala kecil

Dalam bagian ini, kita menelusuri empat langkah pola Qiskit pada instans tujuh-qubit dari masalah pelabelan-koset-dengan-error dan mengevaluasi satu entri matriks kernel menggunakan primitif StatevectorSampler dari Qiskit. Simulator statevector bersifat eksak (hingga shot noise) dan menunjukkan metode ini dari ujung ke ujung tanpa mengonsumsi waktu QPU. Kita kemudian mengulang instans yang sama pada perangkat keras nyata di bagian contoh perangkat keras.

Langkah 1: Petakan input klasikal ke masalah kuantum

  • Input: Dataset pelatihan.
  • Output: Circuit abstrak untuk menghitung entri matriks kernel.

Masalah klasifikasi biner yang ingin kita selesaikan di sini disebut sebagai "pelabelan koset dengan error." Dataset pelatihan input memuat struktur grup, yang terdiri dari dua koset yang dibentuk oleh sebuah grup dan subgrup. Grup diambil sebagai G=SU(2)nG = SU(2)^{\otimes n} untuk qubit, yang merupakan grup uniter khusus dari matriks 2×22 \times 2 dan memiliki penerapan luas di alam; misalnya, Model Standar fisika partikel. Kita mengambil subgrup (graph-stabilizer) Sgraph<GS_\text{graph} < G dengan Sgraph={Xik:(k,i)EZk}iV}S_\text{graph} = \langle \{ X_i \otimes _{k:(k,i) \in \mathcal{E}} Z_k\} _{i \in \mathcal{V}} \} \rangle untuk graf dengan sisi E\mathcal{E} dan simpul V\mathcal{V}. Perlu dicatat bahwa stabilizer menetapkan sebuah state stabilizer sehingga Dsψ=ψ, sSgraphD_s | \psi \rangle = | \psi \rangle,~ \forall s \in S_\text{graph}. Terakhir, kita mendefinisikan dua koset kiri C±=c±SgraphC_\pm = c_\pm S_\text{graph} dengan mengambil dua c±Gc_\pm \in G secara acak.

Untuk detail lebih lanjut tentang dataset dan cara pembuatannya, lihat notebook ini dari Quantum Kernel Training Toolkit.

Kita membuat sirkuit kuantum yang digunakan untuk mengevaluasi satu entri dalam matriks kernel. Data input digunakan untuk menentukan sudut rotasi bagi gate-gate terparameter pada sirkuit. Untuk kemudahan, kita akan menggunakan sampel data x1=14 dan x2=19.

Catatan: Dataset yang digunakan dalam tutorial ini dapat diunduh di sini.

# 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")

Output of the previous code cell

Langkah 2: Optimalkan masalah untuk eksekusi pada perangkat keras kuantum

  • Input: Circuit abstrak, belum dioptimalkan untuk backend tertentu.
  • Output: Circuit target, dioptimalkan untuk QPU yang dipilih.

Untuk jalur simulator statevector yang digunakan di bagian ini, tidak diperlukan optimasi khusus backend: circuit abstrak dapat di-sampling langsung. Kita menerapkan langkah ini pada contoh perangkat keras di bawah, di mana circuit ditranspilasi terhadap QPU nyata menggunakan generate_preset_pass_manager dengan optimization_level=3.

Langkah 3: Eksekusi menggunakan primitif Qiskit

  • Input: Circuit abstrak.
  • Output: Distribusi kuasi-probabilitas.

Gunakan primitif StatevectorSampler dari Qiskit untuk merekonstruksi distribusi kuasi-probabilitas dari state-state yang dihasilkan saat men-sampling circuit. Untuk tugas membangkitkan matriks kernel, kita terutama tertarik pada probabilitas mengukur state |0>.

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)

Output of the previous code cell

Langkah 4: Post-process dan kembalikan hasil dalam format klasikal yang diinginkan

  • Input: Distribusi probabilitas.
  • Output: Satu elemen matriks kernel.

Hitung probabilitas mengukur 0|0 \rangle pada circuit overlap, dan isi matriks kernel di posisi yang sesuai dengan sampel yang diwakili oleh circuit overlap ini (baris 15, kolom 20).

kernel_matrix[x1, x2] = counts.get(0, 0.0) / num_shots
print(f"Fidelity (simulator): {kernel_matrix[x1, x2]}")
Fidelity (simulator): 0.8261

Contoh perangkat keras

Matriks kernel kuantum memiliki O(N2)\mathcal{O}(N^2) entri untuk NN sampel pelatihan, dan setiap entri memerlukan menjalankan circuit overlap yang kedalaman gate dua-qubitnya bertumbuh seiring ukuran peta fitur. Akibatnya, penskalaan tutorial ini ke masalah yang lebih besar memiliki dua biaya yang berlipat: waktu QPU per matriks kernel tumbuh secara kuadratik dengan NN, dan kedalaman unitary_overlap (yang mengkomposisi peta fitur dengan adjoint-nya) mengikis fidelitas pada ukuran sistem dan konektivitas perangkat keras saat ini. Agar demo tetap singkat dan perbandingan bersih, kita oleh karena itu menjalankan instans tujuh-qubit yang sama dari contoh skala kecil pada QPU nyata dan membandingkan fidelitas satu entri matriks kernel dengan nilai simulator yang dihitung di atas.

# ------------------------------ 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

Output of the previous code cell

Fidelity (hardware): 0.7517

Untuk mengisi seluruh matriks kernel, kita akan menjalankan eksperimen kuantum untuk setiap entri uniknya sebanyak N(N+1)/2N(N+1)/2. Gambar di bawah ini menunjukkan matriks yang dihasilkan untuk dataset ini; merah lebih gelap menunjukkan fidelitas yang lebih mendekati 1,0.

kernel_matrix.png

Langkah selanjutnya

Recommendations

Jika kamu menemukan karya ini menarik, kamu mungkin tertarik dengan materi berikut: