Saltar al contenido

Aprendizaje automático del kernel cuántico – documentación de Qiskit Machine Learning 0.1.0

6 de mayo de 2021

Nota

Ejecutar de forma interactiva en jupyter notebook.

La tarea general del aprendizaje automático es encontrar y estudiar patrones en los datos. Para muchos conjuntos de datos, los puntos de datos se entienden mejor en un espacio de características de mayor dimensión, mediante el uso de una función del kernel: (k ( vec {x} _i, vec {x} _j) = langle f ( vec {x} _i), f ( vec {x} _j) rangle ) dónde (k ) es la función del kernel, ( vec {x} _i, vec {x} _j ) están (norte) entradas dimensionales, (F) es un mapa de (norte)-dimensión a (metro)-dimensión espacio y ( langle a, b rangle )
denota el producto escalar. Al considerar datos finitos, una función del núcleo se puede representar como una matriz: (K_ {ij} = k ( vec {x} _i, vec {x} _j) ).

En el aprendizaje automático del kernel cuántico, un mapa de características cuánticas ( phi ( vec {x}) ) se utiliza para mapear un vector de características clásico ( vec {x} ) a un espacio cuántico de Hilbert, (| phi ( vec {x}) rangle langle phi ( vec {x}) | ), tal que (K_ {ij} = izquierda | langle phi ^ dagger ( vec {x} _j) | phi ( vec {x} _i) rangle right | ^ {2} ). Consulte Aprendizaje supervisado con espacios de funciones mejoradas cuánticas para obtener más detalles.

En este cuaderno, usamos qiskit para calcular una matriz de kernel usando un mapa de características cuánticas, luego use esta matriz de kernel en scikit-learn algoritmos de clasificación y agrupamiento.

import matplotlib.pyplot as plt
import numpy as np

from sklearn.svm import SVC
from sklearn.cluster import SpectralClustering
from sklearn.metrics import normalized_mutual_info_score

from qiskit import BasicAer
from qiskit.circuit.library import ZZFeatureMap
from qiskit.utils import QuantumInstance, algorithm_globals
from qiskit_machine_learning.algorithms import QSVC
from qiskit_machine_learning.kernels import QuantumKernel
from qiskit_machine_learning.datasets import ad_hoc_data

seed = 12345
algorithm_globals.random_seed = seed

Clasificación

Para nuestro ejemplo de clasificación, usaremos el conjunto de datos ad hoc como se describe en Aprendizaje supervisado con espacios de características mejorados cuánticamente, y el scikit-learn admite clasificación de máquinas vectoriales (svc) algoritmo.

adhoc_dimension = 2
train_features, train_labels, test_features, test_labels, 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(train_features[np.where(train_labels[:] == 0), 0], train_features[np.where(train_labels[:] == 0), 1],
            marker='s', facecolors='w', edgecolors='b', label="A train")
plt.scatter(train_features[np.where(train_labels[:] == 1), 0], train_features[np.where(train_labels[:] == 1), 1],
            marker='o', facecolors='w', edgecolors='r', label="B train")
plt.scatter(test_features[np.where(test_labels[:] == 0), 0], test_features[np.where(test_labels[:] == 0), 1],
            marker='s', facecolors='b', edgecolors='w', label="A test")
plt.scatter(test_features[np.where(test_labels[:] == 1), 0], test_features[np.where(test_labels[:] == 1), 1],
            marker='o', facecolors='r', edgecolors='w', label="B test")

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

plt.show()
https://qiskit.org/_images/tutorials_03_quantum_kernel_3_0.png

Con nuestros conjuntos de datos de entrenamiento y prueba listos, configuramos el QuantumKernel clase para calcular una matriz de kernel usando ZZFeatureMap, y la BasicAer qasm_simulator usando 1024 disparos.

adhoc_feature_map = ZZFeatureMap(feature_dimension=adhoc_dimension,
                                 reps=2, entanglement='linear')

adhoc_backend = QuantumInstance(BasicAer.get_backend('qasm_simulator'), shots=1024,
                                seed_simulator=seed, seed_transpiler=seed)

adhoc_kernel = QuantumKernel(feature_map=adhoc_feature_map, quantum_instance=adhoc_backend)

La scikit-learn svc El algoritmo nos permite definir un kernel personalizado de dos maneras: proporcionando el kernel como una función invocable o precomputando la matriz del kernel. Podemos hacer cualquiera de estos usando el QuantumKernel clase en qiskit.

El siguiente código da al kernel como una función invocable:

adhoc_svc = SVC(kernel=adhoc_kernel.evaluate)
adhoc_svc.fit(train_features, train_labels)
adhoc_score = adhoc_svc.score(test_features, test_labels)

print(f'Callable kernel classification test score: {adhoc_score}')
Callable kernel classification test score: 1.0

El siguiente código precalcula y traza las matrices del kernel de entrenamiento y prueba antes de proporcionarlas al scikit-learn svc algoritmo:

adhoc_matrix_train = adhoc_kernel.evaluate(x_vec=train_features)
adhoc_matrix_test = adhoc_kernel.evaluate(x_vec=test_features,
                                          y_vec=train_features)

fig, axs = plt.subplots(1, 2, figsize=(10, 5))
axs[0].imshow(np.asmatrix(adhoc_matrix_train),
              interpolation='nearest', origin='upper', cmap='Blues')
axs[0].set_title("Ad hoc training kernel matrix")
axs[1].imshow(np.asmatrix(adhoc_matrix_test),
              interpolation='nearest', origin='upper', cmap='Reds')
axs[1].set_title("Ad hoc testing kernel matrix")
plt.show()

adhoc_svc = SVC(kernel='precomputed')
adhoc_svc.fit(adhoc_matrix_train, train_labels)
adhoc_score = adhoc_svc.score(adhoc_matrix_test, test_labels)

print(f'Precomputed kernel classification test score: {adhoc_score}')
https://qiskit.org/_images/tutorials_03_quantum_kernel_9_0.png
Precomputed kernel classification test score: 1.0

qiskit también contiene el qsvc clase que extiende el sklearn svc class, que se puede utilizar de la siguiente manera:

qsvc = QSVC(quantum_kernel=adhoc_kernel)
qsvc.fit(train_features, train_labels)
qsvc_score = qsvc.score(test_features, test_labels)

print(f'QSVC classification test score: {adhoc_score}')
QSVC classification test score: 1.0

Agrupación

Para nuestro ejemplo de agrupamiento, usaremos nuevamente el conjunto de datos ad hoc como se describe en Aprendizaje supervisado con espacios de características mejorados cuánticamente, y el scikit-learn spectral algoritmo de agrupamiento.

Recomendado:  Código de Python de parches de mono

Regeneraremos el conjunto de datos con una brecha mayor entre las dos clases y, como la agrupación en clústeres es una tarea de aprendizaje automático no supervisada, no necesitamos una muestra de prueba.

adhoc_dimension = 2
train_features, train_labels, test_features, test_labels, adhoc_total = ad_hoc_data(
    training_size=25,
    test_size=0,
    n=adhoc_dimension,
    gap=0.6,
    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(train_features[np.where(train_labels[:] == 0), 0], train_features[np.where(train_labels[:] == 0), 1],
            marker='s', facecolors='w', edgecolors='b', label="A")
plt.scatter(train_features[np.where(train_labels[:] == 1), 0], train_features[np.where(train_labels[:] == 1), 1],
            marker='o', facecolors='w', edgecolors='r', label="B")

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

plt.show()
https://qiskit.org/_images/tutorials_03_quantum_kernel_13_0.png

Nuevamente configuramos el QuantumKernel clase para calcular una matriz de kernel usando ZZFeatureMap y BasicAer qasm_simulator usando 1024 disparos.

adhoc_feature_map = ZZFeatureMap(feature_dimension=adhoc_dimension,
                                 reps=2, entanglement='linear')

adhoc_backend = QuantumInstance(BasicAer.get_backend('qasm_simulator'), shots=1024,
                                seed_simulator=seed, seed_transpiler=seed)

adhoc_kernel = QuantumKernel(feature_map=adhoc_feature_map, quantum_instance=adhoc_backend)

El algoritmo de agrupamiento espectral scikit-learn nos permite definir un [custom kernel] de dos formas: proporcionando el núcleo como una función invocable o calculando previamente la matriz del núcleo. Usando la clase QuantumKernel en qiskit, solo podemos usar este último.

El siguiente código precalcula y traza las matrices del kernel antes de proporcionarlo al algoritmo de agrupamiento espectral scikit-learn y puntuar las etiquetas utilizando información mutua normalizada, ya que conocemos las etiquetas de clase a priori.

adhoc_matrix = adhoc_kernel.evaluate(x_vec=train_features)

plt.figure(figsize=(5, 5))
plt.imshow(np.asmatrix(adhoc_matrix), interpolation='nearest', origin='upper', cmap='Greens')
plt.title("Ad hoc clustering kernel matrix")
plt.show()

adhoc_spectral = SpectralClustering(2, affinity="precomputed")
cluster_labels = adhoc_spectral.fit_predict(adhoc_matrix)
cluster_score = normalized_mutual_info_score(cluster_labels, train_labels)

print(f'Clustering score: {cluster_score}')
https://qiskit.org/_images/tutorials_03_quantum_kernel_17_0.png
Clustering score: 0.7287008798015754

scikit-learn tiene otros algoritmos que pueden usar una matriz de kernel precalculada, aquí hay algunos:

import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright

Información de versión

Software Qiskit Versión
Qiskit Ninguno
Terra 0.17.0
Aer 0.8.0
Ignis Ninguno
Agua Ninguno
Proveedor IBM Q Ninguno
Información del sistema
Pitón 3.8.8 (predeterminado, 19 de febrero de 2021, 19:42:00)
[GCC 9.3.0]
SO Linux
CPU 2
Memoria (Gb) 6.791343688964844
Vie 02 abr 20:40:49 2021 UTC
Recomendado:  Búsqueda local iterada desde cero en Python

Este código es parte de Qiskit

© Copyright IBM 2017, 2021.

Este código tiene la licencia de Apache, versión 2.0. Puedes
obtenga una copia de esta licencia en el archivo LICENSE.txt en el directorio raíz
de este árbol de fuentes o en http://www.apache.org/licenses/LICENSE-2.0.

Cualquier modificación o trabajo derivado de este código debe conservar este
aviso de derechos de autor, y los archivos modificados deben llevar un aviso que indique
que han sido alterados de los originales.