주 콘텐츠로 건너뛰기

양자 커널 훈련

사용 예상 시간: Eagle r3 프로세서에서 1분 미만 (참고: 이는 추정치이며, 실제 실행 시간은 다를 수 있습니다.)

배경

이 튜토리얼에서는 이진 분류에 사용되는 양자 커널 행렬의 항목을 평가하기 위한 Qiskit pattern을 구축하는 방법을 설명합니다. Qiskit patternsQiskit Serverless를 사용하여 관리형 실행을 위해 클라우드에 배포하는 방법에 대한 자세한 내용은 IBM Quantum® Platform 문서 페이지를 참조하세요.

요구 사항

이 튜토리얼을 시작하기 전에 다음이 설치되어 있는지 확인하세요:

  • Qiskit SDK v1.0 이상 (시각화 지원 포함)
  • Qiskit Runtime v0.22 이상 (pip install qiskit-ibm-runtime)

설정

# 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

1단계: 고전적 입력을 양자 문제로 변환

  • 입력: 훈련 데이터셋
  • 출력: 커널 행렬 항목 계산을 위한 추상 Circuit

커널 행렬의 한 항목을 평가하는 데 사용되는 양자 Circuit을 생성합니다. 입력 데이터를 사용하여 Circuit의 매개변수화된 게이트에 대한 회전 각도를 결정합니다. 데이터 샘플 x1=14x2=19를 사용하겠습니다.

참고: 이 튜토리얼에 사용된 데이터셋은 여기에서 다운로드할 수 있습니다.

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

이전 코드 셀의 출력

2단계: 양자 하드웨어 실행을 위한 문제 최적화

  • 입력: 특정 Backend에 최적화되지 않은 추상 Circuit
  • 출력: 선택된 QPU에 최적화된 목표 Circuit과 관측량

Qiskit의 generate_preset_pass_manager 함수를 사용하여 실험을 실행할 QPU에 맞는 Circuit 최적화 루틴을 지정합니다. 가장 높은 수준의 최적화를 제공하는 사전 설정 패스 매니저를 사용하도록 optimization_level=3으로 설정합니다.

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

이전 코드 셀의 출력

3단계: Qiskit 프리미티브를 사용한 실행

  • 입력: 목표 Circuit
  • 출력: 준확률 분포

Qiskit Runtime의 Sampler 프리미티브를 사용하여 Circuit 샘플링으로부터 얻은 상태의 준확률 분포를 재구성합니다. 커널 행렬 생성 작업에서는 특히 |0> 상태를 측정할 확률에 관심이 있습니다.

이 데모에서는 qiskit-ibm-runtime 프리미티브를 사용하여 QPU에서 실행합니다. qiskit statevector 기반 프리미티브로 실행하려면, Qiskit IBM® Runtime 프리미티브를 사용하는 코드 블록을 주석 처리된 블록으로 교체하세요.

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)

이전 코드 셀의 출력

4단계: 후처리 및 원하는 고전적 형식으로 결과 반환

  • 입력: 확률 분포
  • 출력: 단일 커널 행렬 요소

오버랩 Circuit에서 |0>을 측정할 확률을 계산하고, 이 특정 오버랩 Circuit이 나타내는 샘플에 해당하는 위치(행 15, 열 20)에 커널 행렬을 채웁니다. 이 시각화에서 더 진한 빨간색은 1.0에 가까운 충실도를 나타냅니다. 전체 커널 행렬을 채우려면 각 항목에 대해 양자 실험을 실행해야 합니다.

# 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

Qiskit 패턴을 클라우드에 배포

이를 위해 위의 소스 코드를 ./source/generate_kernel_entry.py 파일로 이동하고, 입력을 받아 최종 솔루션을 반환하는 스크립트로 코드를 감싼 다음, Qiskit ServerlessQiskitFunction 클래스를 사용하여 원격 클러스터에 업로드합니다. 외부 종속성 지정, 입력 인수 전달 등에 대한 지침은 Qiskit Serverless 가이드를 참조하세요.

패턴의 입력은 데이터 샘플 쌍 x1x2입니다. 출력은 두 샘플 간의 충실도입니다. 이 값은 이 두 샘플에 해당하는 커널 행렬 항목을 채우는 데 사용됩니다.

serverless = QiskitServerless()

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

serverless.upload(kernel_entry_pattern)

관리형 서비스로 Qiskit 패턴 실행

패턴을 클라우드에 업로드한 후에는 IBMServerlessProvider 클라이언트를 사용하여 쉽게 실행할 수 있습니다. 간단히 하기 위해 클라우드 환경에서 정확한 양자 시뮬레이터를 사용하므로 계산되는 충실도는 정확한 값이 됩니다.

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

튜토리얼 설문조사

이 튜토리얼에 대한 피드백을 제공하기 위해 짧은 설문조사에 참여해 주세요. 여러분의 의견은 콘텐츠 품질과 사용자 경험 향상에 도움이 됩니다.

설문조사 링크

Note: This survey is provided by IBM Quantum and relates to the original English content. To give feedback on doQumentation's website, translations, or code execution, please open a GitHub issue.