Lumaktaw sa pangunahing nilalaman

Quantum kernel training

Tinantyang paggamit: wala pang isang minuto sa Eagle r3 processor (PAALALA: Ito ay tantya lamang. Maaaring mag-iba ang inyong runtime.)

Background​

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. Para sa karagdagang impormasyon tungkol sa Qiskit patterns at kung paano magagamit ang Qiskit Serverless upang i-deploy ang mga ito sa cloud para sa managed execution, bisitahin ang aming docs page sa IBM Quantum® Platform.

Requirements​

Bago magsimula ng tutorial na ito, tiyaking nakainstall ang mga sumusunod:

  • Qiskit SDK v1.0 o mas bago, na may visualization support
  • Qiskit Runtime v0.22 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-catalog qiskit-ibm-runtime
!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[Files: 0  Bytes: 0  [0 B/s] Re]87[https://raw.githubusercontent.]87Saving 'dataset_graph7.csv.1'
87dataset_graph7.csv.1 100% [=============================>] 20.25K --.-KB/s87HTTP response 200 [https://raw.githubusercontent.com/qiskit-community/prototype-quantum-kernel-training/main/data/dataset_graph7.csv]
87dataset_graph7.csv.1 100% [=============================>] 20.25K --.-KB/s87[Files: 1 Bytes: 20.25K [93.33]8

Step 1: Map classical inputs to a quantum problem​

  • Input: Training dataset.
  • Output: Abstract circuit para sa pagkalkula ng kernel matrix entry.

Lumikha ng quantum circuit na ginagamit upang suriin ang isang entry sa kernel matrix. Ginagamit natin ang input data upang matukoy ang mga rotation angle para sa parametrized gates ng circuit. 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 = UnitaryOverlap(unitary1, unitary2)
overlap_circ.measure_all()
overlap_circ.draw("mpl", scale=0.6, style="iqp")

Output of the previous code cell

Step 2: Optimize problem for quantum hardware execution​

  • Input: Abstract circuit, na hindi pa nao-optimize para sa partikular na backend
  • Output: Target circuit at observable, na nao-optimize para sa piniling QPU

Gamitin ang generate_preset_pass_manager function mula sa Qiskit upang tukuyin ang optimization routine para sa ating circuit na may kaugnayan sa QPU kung saan balak nating patakbuhin ang eksperimento. Itinakda natin ang optimization_level=3, na nangangahulugang gagamitin natin ang preset pass manager na nagbibigay ng pinakamataas na antas ng optimization.

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

Output of the previous code cell

Step 3: Execute using Qiskit primitives​

  • Input: Target circuit
  • Output: Quasi-probability distribution

Gamitin ang Sampler primitive mula sa Qiskit Runtime 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.

Para sa demo na ito, patakbuhin natin ito sa QPU gamit ang qiskit-ibm-runtime primitives. Upang patakbuhin ito sa qiskit statevector-based primitives, palitan ang block ng code na gumagamit ng Qiskit IBM® Runtime primitives ng commented 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)

Output of the previous code cell

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 |0> 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). Sa visualization na ito, ang mas madilim na pula ay nagsasaad ng mga fidelity na mas malapit sa 1.0. Upang mapunan ang buong kernel matrix, kailangan nating patakbuhin ang quantum experiment para sa bawat entry.

# 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

kernel_matrix.png

Deploy the Qiskit pattern to the cloud​

Upang gawin ito, ilipat ang source code sa itaas sa isang file, ./source/generate_kernel_entry.py, balutin ang code sa isang script na tumatanggap ng mga input at nagbabalik ng final solution, at sa wakas ay i-upload ito sa remote cluster gamit ang QiskitFunction class mula sa Qiskit Serverless. Para sa gabay sa pagtukoy ng mga external dependency, pagpasa ng mga input argument, at iba pa, tingnan ang Qiskit Serverless guides.

Ang input sa Pattern ay isang pares ng mga data sample, x1 at x2. Ang output ay ang fidelity sa pagitan ng dalawang sample. Ang halagang ito ay gagamitin upang punan ang kernel matrix entry na tumutugma sa dalawang sample na ito.

serverless = QiskitServerless()

kernel_entry_pattern = QiskitFunction(
title="generate-kernel-entry",
entrypoint="generate_kernel_entry.py",
working_dir="./source/",
)

serverless.upload(kernel_entry_pattern)

Run the Qiskit pattern as a managed service​

Kapag na-upload na natin ang pattern sa cloud, madali na nating patakbuhin ito gamit ang IBMServerlessProvider client. Para sa simplicity, gagamitin natin ang isang exact quantum simulator sa cloud environment, kaya ang fidelity na kakalkulahin natin ay magiging eksakto.

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 survey​

Mangyaring sagutan ang maikling survey na ito upang magbigay ng feedback tungkol sa tutorial na ito. Ang inyong mga pananaw ay makakatulong sa amin na mapabuti ang aming mga content offering at user experience.

Link to survey