Korean
언어
English
Bengali
French
Hindi
Italian
Japanese
Korean
Malayalam
Russian
Spanish
Tamil
Turkish
Vietnamese
Shortcuts

참고

이 페이지는 docs/tutorials/08_quantum_kernel_trainer.ipynb 에서 생성되었다.

기계 학습 응용프로그램(Application) 을 위한 양자 커널 학습

본 튜토리얼에서는, 기계학습 응용을 위해 레이블이 지정된 데이터셋에서 양자 커널을 학습시킬 것이다. 기본 단계들을 설명하기 위해,우리는 이진 분류 태스크에 대해 양자 커널 정렬 (Quantum Kernel Alignment, QKA)을 사용할 것이다. QKA는 최대 SVM (서포트 벡터 머신) 여백으로 수렴하면서 매개변수화된 양자 커널을 데이터셋에 반복적으로 적응시키는 기술이다. QKA에 대한 자세한 정보는 “Covariant quantum kernels for data with group structure.” 에서 찾을 수 있다.

양자 커널 학습의 시작점은 QuantumKernelTrainer 클래스이다. 기본 단계들은 다음과 같다:

  1. 데이터셋 준비

  2. 양자 특징 맵(feature map) 정의

  3. QuantumKernelQuantumKernelTrainer 객체 설정

  4. QuantumKernelTrainer.fit 메소드를 활용하여 주어진 데이터셋에서 커널 매개변수들을 학습

  5. 학습된 양자 커널을 기계학습 모델로 전달

로컬, 외부 및 Qiskit 패키지 가져오기 & 최적화를 위한 콜백(callback) 클래스 정의

[1]:
# External imports
from pylab import cm
import pandas as pd
from sklearn import metrics
import numpy as np
import matplotlib.pyplot as plt

%matplotlib inline

# Qiskit imports
from qiskit import QuantumCircuit
from qiskit.circuit import ParameterVector
from qiskit.providers.aer import AerSimulator
from qiskit.visualization import circuit_drawer
from qiskit.algorithms.optimizers import SPSA
from qiskit.circuit.library import ZZFeatureMap
from qiskit_machine_learning.kernels import QuantumKernel
from qiskit_machine_learning.kernels.algorithms import QuantumKernelTrainer
from qiskit_machine_learning.algorithms import QSVC
from qiskit_machine_learning.datasets import ad_hoc_data


class QKTCallback:
    """Callback wrapper class."""

    def __init__(self) -> None:
        self._data = [[] for i in range(5)]

    def callback(self, x0, x1=None, x2=None, x3=None, x4=None):
        """
        Args:
            x0: number of function evaluations
            x1: the parameters
            x2: the function value
            x3: the stepsize
            x4: whether the step was accepted
        """
        self._data[0].append(x0)
        self._data[1].append(x1)
        self._data[2].append(x2)
        self._data[3].append(x3)
        self._data[4].append(x4)

    def get_callback_data(self):
        return self._data

    def clear_callback_data(self):
        self._data = [[] for i in range(5)]

데이터셋 준비

이번에는 Qiskit Machine Learning의 ad_hoc.py 데이터 세트를 사용하여 커널 훈련 과정을 살펴보자. 문서를 참고한다.

[2]:
adhoc_dimension = 2
X_train, y_train, X_test, y_test, adhoc_total = ad_hoc_data(
    training_size=20,
    test_size=5,
    n=adhoc_dimension,
    gap=0.3,
    plot_data=False,
    one_hot=False,
    include_sample_total=True,
)

plt.figure(figsize=(5, 5))
plt.ylim(0, 2 * np.pi)
plt.xlim(0, 2 * np.pi)
plt.imshow(
    np.asmatrix(adhoc_total).T,
    interpolation="nearest",
    origin="lower",
    cmap="RdBu",
    extent=[0, 2 * np.pi, 0, 2 * np.pi],
)

plt.scatter(
    X_train[np.where(y_train[:] == 0), 0],
    X_train[np.where(y_train[:] == 0), 1],
    marker="s",
    facecolors="w",
    edgecolors="b",
    label="A train",
)
plt.scatter(
    X_train[np.where(y_train[:] == 1), 0],
    X_train[np.where(y_train[:] == 1), 1],
    marker="o",
    facecolors="w",
    edgecolors="r",
    label="B train",
)
plt.scatter(
    X_test[np.where(y_test[:] == 0), 0],
    X_test[np.where(y_test[:] == 0), 1],
    marker="s",
    facecolors="b",
    edgecolors="w",
    label="A test",
)
plt.scatter(
    X_test[np.where(y_test[:] == 1), 0],
    X_test[np.where(y_test[:] == 1), 1],
    marker="o",
    facecolors="r",
    edgecolors="w",
    label="B test",
)

plt.legend(bbox_to_anchor=(1.05, 1), loc="upper left", borderaxespad=0.0)
plt.title("Ad hoc dataset for classification")

plt.show()
../_images/tutorials_08_quantum_kernel_trainer_4_0.png

양자 특징 맵(Quantum Feature Map) 정의

다음으로, 고전적인 데이터를 양자 상태 공간으로 인코딩하는 양자 특징 맵을 설정한다. 훈련 가능한 회전 레이어를 설정하기 위해 QuantumCircuit 을 사용하고 입력 데이터를 표현하기 위해 Qiskit 에서 ZZFeatureMap 을 사용한다.

[3]:
# Create a rotational layer to train. We will rotate each qubit the same amount.
user_params = ParameterVector("θ", 1)
fm0 = QuantumCircuit(2)
fm0.ry(user_params[0], 0)
fm0.ry(user_params[0], 1)

# Use ZZFeatureMap to represent input data
fm1 = ZZFeatureMap(2)

# Create the feature map, composed of our two circuits
fm = fm0.compose(fm1)

print(circuit_drawer(fm))
print(f"Trainable parameters: {user_params}")
     ┌──────────┐┌──────────────────────────┐
q_0: ┤ Ry(θ[0]) ├┤0                         ├
     ├──────────┤│  ZZFeatureMap(x[0],x[1]) │
q_1: ┤ Ry(θ[0]) ├┤1                         ├
     └──────────┘└──────────────────────────┘
Trainable parameters: θ, ['θ[0]']

양자 커널 및 Quantum 커널 Trainer 설정

양자 커널을 훈련시키기 위해서는 QuantumKernel (feature map과 해당 매개변수를 가지고 있음) 과 QuantumKernelTrainer (훈련 프로세스 관리) 가 필요하다.

커널 손실 함수인 SVCLossQuantumKernelTrainer 의 입력으로 선택하여 양자 커널 정렬(Alignment) 을 사용하여 훈련한다. 이는 Qiskit이 제공하는 손실값이므로 svc_loss 문자열을 사용할 수 있으며 손실값을 문자열로 전달할 때는 기본 설정이 사용됨에 유의한다. 사용자 지정 설정의 경우 원하는 옵션을 사용하여 명시적으로 인스턴스화하고 KernelLoss 객체를 QuantumKernelTrainer 에 전달한다.

옵티마이저로 SPSA를 선택하고 initial_point 인자를 사용하여 학습할 수 있는 매개변수를 초기화한다. 참고: initial_point 인자로 전달된 목록의 길이는 feature map에 있는 학습 가능한 매개변수의 수와 같아야 한다.

[4]:
# Use the qasm simulator backend
backend = AerSimulator(method="statevector")

# Instantiate quantum kernel
quant_kernel = QuantumKernel(fm, user_parameters=user_params, quantum_instance=backend)

# Set up the optimizer
cb_qkt = QKTCallback()
spsa_opt = SPSA(maxiter=10, callback=cb_qkt.callback, learning_rate=0.05, perturbation=0.05)

# Instantiate a quantum kernel trainer.
qkt = QuantumKernelTrainer(
    quantum_kernel=quant_kernel, loss="svc_loss", optimizer=spsa_opt, initial_point=[np.pi / 2]
)

양자 커널 학습

양자 커널을 학습하기 위해 데이터 세트 (샘플과 레이블) 에 QuantumKernelTrainerfit 함수를 호출한다.

QuantumKernelTrainer.fit 의 출력값은 QuantumKernelTrainerResult 객체이다. 결과 객체는 다음과 같은 클래스 필드를 포함한다: - optimal_parameters: {parameter: optimal value} 쌍을 포함하는 자료구조 - optimal_point: 학습과정에서 발견되는 최적의 매개변수 값 - optimal_value: 최적점에서의 손실 함수 값 - optimizer_evals: 옵티마이저에서 수행되는 평가의 수 - optimizer_time: 최적화를 수행하는데 소요되는 시간 - quantum_kernel: feature map에 바인딩된 최적값을 갖는 QuantumKernel 객체

[5]:
# Train the kernel using QKT directly
qka_results = qkt.fit(X_train, y_train)
optimized_kernel = qka_results.quantum_kernel
print(qka_results)
{   'optimal_parameters': {ParameterVectorElement(θ[0]): 1.2984045829959046},
    'optimal_point': array([1.29840458]),
    'optimal_value': 11.733763373742224,
    'optimizer_evals': 30,
    'optimizer_time': None,
    'quantum_kernel': <qiskit_machine_learning.kernels.quantum_kernel.QuantumKernel object at 0x7fd7e864f100>}

모델 적합(fit) 및 모델 테스트

학습된 양자 커널을 기계 학습 모델에 전달한 후 모델에 적합(fit)시키고, 새로운 데이터를 사용하여 테스트할 수 있다. 여기서, 우리는 분류를 위해 Qiskit의 QSVC 를 사용할 것이다.

[6]:
# Use QSVC for classification
qsvc = QSVC(quantum_kernel=optimized_kernel)

# Fit the QSVC
qsvc.fit(X_train, y_train)

# Predict the labels
labels_test = qsvc.predict(X_test)

# Evalaute the test accuracy
accuracy_test = metrics.balanced_accuracy_score(y_true=y_test, y_pred=labels_test)
print(f"accuracy test: {accuracy_test}")
accuracy test: 1.0

커널 학습 과정 시각화

콜백 데이터로부터 학습이 진행됨에 따라 손실이 어떻게 변화하는지 그릴 수 있다. 손실이 빠르게 수렴하며, 선택한 입력값들에 대해 이 데이터에서 테스트 정확도가 100%에 도달하는 것을 볼 수 있다.

또한 학습 샘플들 간의 유사성 측도인 최종 커널 행렬을 표시할 수 있다.

[7]:
plot_data = cb_qkt.get_callback_data()  # callback data
K = optimized_kernel.evaluate(X_train)  # kernel matrix evaluated on the training samples

plt.rcParams["font.size"] = 20
fig, ax = plt.subplots(1, 2, figsize=(14, 5))
ax[0].plot([i + 1 for i in range(len(plot_data[0]))], np.array(plot_data[2]), c="k", marker="o")
ax[0].set_xlabel("Iterations")
ax[0].set_ylabel("Loss")
ax[1].imshow(K, cmap=cm.get_cmap("bwr", 20))
fig.tight_layout()
plt.show()
../_images/tutorials_08_quantum_kernel_trainer_14_0.png
[8]:
import qiskit.tools.jupyter

%qiskit_version_table
%qiskit_copyright

Version Information

Qiskit SoftwareVersion
qiskit-terra0.20.0
qiskit-aer0.8.1
qiskit-ignis0.6.0
qiskit-nature0.1.1
qiskit-machine-learning0.3.0
System information
Python version3.8.10
Python compilerClang 10.0.0
Python builddefault, May 19 2021 11:01:55
OSDarwin
CPUs8
Memory (Gb)32.0
Mon Dec 13 13:23:24 2021 CST

This code is a part of Qiskit

© Copyright IBM 2017, 2021.

This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.