Мы рады поделиться с вами запуском Qiskit Machine Learning 0.6, который упрощает квантовое машинное обучение, как никогда раньше. Этот последний выпуск знаменует собой важную веху в нашем путешествии, поскольку он завершает переход алгоритмов машинного обучения в примитивы Qiskit. Это достижение является самым существенным скачком в функциональности с момента нашего первоначального запуска два года назад.

В последних двух выпусках наши усилия по разработке были сосредоточены на этом переходе, который включал перенос ключевых вычислительных блоков, таких как квантовые ядра и квантовые нейронные сети, на примитивы. Кроме того, мы ввели расширенную поддержку примитивов в наших алгоритмах, используя такие базовые алгоритмы Qiskit, как градиенты на основе примитивов и точность состояния.

Если вы не знакомы с примитивами Qiskit, мы рекомендуем вам прочитать нашу предыдущую публикацию в блоге о том, что они из себя представляют и почему они так важны.

Новые возможности

Давайте подробнее рассмотрим последнюю версию и изучим новые функции, которые она может предложить. Ниже приводится краткое описание его структуры.

Архитектура модуля остается в основном такой же. Он по-прежнему предоставляет фундаментальные вычислительные строительные блоки, такие как квантовые ядра, квантовые нейронные сети и алгоритмы квантового машинного обучения, такие как квантовые классификаторы и регрессоры. Но разница в их реализации и новых примитивах, которые они используют. Давайте подробнее рассмотрим новые реализации, начиная с новой реализации Quantum Kernel.

Новое квантовое ядро

Предыдущая реализация состояла из одного класса, который делал все, начиная от построения схем и их выполнения, заканчивая оценкой перекрытия между цепями и отслеживанием предоставленных пользователем параметров обучения. Таким образом, реализация стала сложной и негибкой, а добавить поддержку новых примитивов было непросто. Для решения этих проблем мы представили новый гибкий и расширяемый дизайн квантовых ядер. Цели нового дизайна заключаются в следующем:

  • Рефакторинг модуля с использованием Qiskit Primitives и использование алгоритма точности. Теперь пользователи могут подключать свои собственные реализации расчетов точности.
  • Извлеките функцию обучаемости для выделенного класса.
  • Представьте базовый класс, который может быть расширен другими реализациями ядра.

Новые ядра предоставляют один и тот же интерфейс, но различаются тем, как они выполняют квантовые схемы. В более ранних версиях пользователям приходилось создавать QuantumInstance и передавать его экземпляру квантового ядра. Роль QuantumInstance заключалась в том, чтобы обернуть серверную часть, выполнить схемы и обеспечить устранение ошибок. Теперь вместо использования QuantumInstance пользователи создают экземпляр реализации примитива Sampler, например. они могут выбрать эталонный сэмплер (используя встроенный симулятор Qiskit) или аппаратный сэмплер времени выполнения, передать его алгоритму точности, а затем передать точность новой реализации квантового ядра.

Давайте взглянем на классы на приведенной выше диаграмме, а затем рассмотрим, как можно построить новое квантовое ядро.

Новая иерархия, показанная на диаграмме выше, показывает:

  • Представлен базовый и абстрактный класс BaseKernel. Все предоставленные реализации наследуют этот класс.
  • Добавлено квантовое ядро ​​на основе точности FidelityQuantumKernel. Это прямая замена уже существующего QuantumKernel. Разница в том, что новый класс использует экземпляр точности для оценки перекрытий и построения матрицы ядра.
  • Введен новый абстрактный класс TrainableKernel , чтобы обобщить возможность обучения квантовых ядер.
  • Введено основанное на точности обучаемое квантовое ядро ​​TrainableFidelityQuantumKernel. Это замена QuantumKernel, если требуется обучаемое ядро. Тренировочный класс QuantumKernelTrainer теперь принимает обе реализации квантового ядра, новую и из более ранних версий.
  • Существует также специальная реализация FidelityStatevectorKernel, которая оптимизирована для использования только карт объектов, реализованных на основе вектора состояния. Таким образом, вычислительная сложность снижается с O(N²) до O(N). Эта реализация работает только на симуляторе вектора состояния, не требует примитивного экземпляра и очень удобна для проверки концепций, где необходимы быстрые вычисления.

Для удобства предыдущая реализация квантового ядра QuantumKernel теперь расширяет оба новых абстрактных класса, описанных выше, и, таким образом, совместима с новыми представленными интерфейсами. Однако эта реализация в настоящее время ожидает прекращения поддержки, будет объявлена ​​устаревшей в будущем выпуске и впоследствии удалена. Вместо этого следует использовать новые квантовые ядра на основе примитивов. Существующие алгоритмы, такие как QSVC, QSVR и другие алгоритмы на основе ядра, были обновлены и работают с обеими реализациями.

Теперь давайте посмотрим, как перейти на новые ядра. Мы покажем шаги, необходимые для создания квантового классификатора ядра, сравнивая новую реализацию с реализацией более ранних версий Qiskit Machine Learning.

Существующая реализация квантового ядра

Во-первых, мы оборачиваем симулятор вектора состояния в квантовый экземпляр.

from qiskit import BasicAer
from qiskit.utils import QuantumInstance

sv_qi = QuantumInstance(
  BasicAer.get_backend("statevector_simulator")
)

Затем мы создаем квантовое ядро.

from qiskit.circuit.library import ZZFeatureMap
from qiskit_machine_learning.kernels import QuantumKernel

feature_map = ZZFeatureMap(2)
previous_kernel = QuantumKernel(feature_map=feature_map, quantum_instance=sv_qi)

И, наконец, мы подходим к классификатору QSVC. Здесь мы пропустили шаги, необходимые для загрузки набора данных.

from qiskit_machine_learning.algorithms import QSVC

qsvc = QSVC(quantum_kernel=previous_kernel)
qsvc.fit(features, labels)

Новая реализация квантового ядра

В новой реализации мы начинаем с создания экземпляра верности. Чтобы создать экземпляр верности, мы передаем сэмплер. Семплер в этом примере является эталонной реализацией Qiskit, вы можете создать экземпляр сэмплера из QiskitRuntimeService, чтобы использовать сервисы времени выполнения Qiskit.

from qiskit.algorithms.state_fidelities import ComputeUncompute
from qiskit.primitives import Sampler

fidelity = ComputeUncompute(sampler=Sampler())

Затем мы создаем новое квантовое ядро ​​с экземпляром Fidelity.

from qiskit.circuit.library import ZZFeatureMap
from qiskit_machine_learning.kernels import FidelityQuantumKernel

feature_map = ZZFeatureMap(2)
new_kernel = FidelityQuantumKernel(feature_map=feature_map, fidelity=fidelity)

Затем мы подбираем классификатор QSVC так же, как и раньше.

from qiskit_machine_learning.algorithms import QSVC

qsvc = QSVC(quantum_kernel=new_kernel)
qsvc.fit(features, labels)

Новые квантовые нейронные сети

Изменения в квантовых нейронных сетях не столь драматичны, как в квантовых ядрах. Кроме того, в качестве замены существующих нейронных сетей представлены две новые сети: SamplerQNN и EstimatorQNN, которые подробно описаны ниже и заменяют ранее существовавшие CircuitQNN, OpflowQNN и TwoLayerQNN. которые сейчас ожидают устаревания.

SamplerQNN

Новая квантовая нейронная сеть сэмплера использует примитив сэмплера, градиенты сэмплера и является прямой заменой of CircuitQNN. Новый SamplerQNN предоставляет интерфейс, аналогичный существующему CircuitQNN, с некоторыми отличиями. Вместо `QuantumInstance должен использоваться экземпляр примитива Sampler. Градиенты устанавливаются так же, как в CircuitQNN,, но больше не принимают классы градиента Opflow в качестве входных данных; вместо этого необходимо использовать (необязательно пользовательский) примитивный градиент. Параметр sampling, доступный в CircuitQNN, пока не реализован в SamplerQNN, так как информация о семплах в настоящее время не выставляется сэмплером.

Существующие алгоритмы обучения, такие как VQC, основанные на CircuitQNN, были обновлены, чтобы принимать обе реализации. Реализация NeuralNetworkClassifier не изменилась.

Существующий CircuitQNN в настоящее время ожидает устаревания, будет объявлен устаревшим в будущем выпуске и впоследствии удален.

Мы покажем, как обучить вариационный квантовый классификатор, используя обе сети. Для простоты мы пропустим этап подготовки набора данных в этом примере. Для обеих квантовых нейронных сетей нам еще предстоит построить карту признаков и анзац, они объединят их в единую квантовую схему.

from qiskit import QuantumCircuit
from qiskit.circuit.library import RealAmplitudes

num_inputs = 2
feature_map = ZZFeatureMap(num_inputs)
ansatz = RealAmplitudes(num_inputs, reps=1)

circuit = QuantumCircuit(num_inputs)
circuit.compose(feature_map, inplace=True)
circuit.compose(ansatz, inplace=True)

Нам также нужна интерпретирующая функция. Мы определяем нашу обычную функцию контроля четности, которая отображает битовые строки либо в 0, либо в 1.

def parity(x):
    return "{:b}".format(x).count("1") % 2

Создание классификатора с использованием существующего CircuitQNN

Мы создаем экземпляр CircuitQNN и повторно используем квантовый экземпляр sv_qi, созданный для квантового ядра.

from qiskit_machine_learning.neural_networks import CircuitQNN

circuit_qnn = CircuitQNN(
    circuit=circuit,
    input_params=feature_map.parameters,
    weight_params=ansatz.parameters,
    interpret=parity,
    output_shape=2,
    quantum_instance=sv_qi,
)

Создайте классификатор из сети и обучите его.

rom qiskit_machine_learning.algorithms import NeuralNetworkClassifier

classifier = NeuralNetworkClassifier(
    neural_network=circuit_qnn,
    loss="cross_entropy",
    one_hot=True,
)
classifier.fit(features, labels)

Построение классификатора с использованием нового SamplerQNN

Вместо QuantumInstance создаем экземпляр эталонного Sampler.

from qiskit.primitives import Sampler

sampler = Sampler()

Теперь мы создаем экземпляр SamplerQNN. Разница между этим и CircuitQNN заключается в том, что мы передаем сэмплер вместо квантового экземпляра.

from qiskit_machine_learning.neural_networks import SamplerQNN

sampler_qnn = SamplerQNN(
    circuit=circuit,
    input_params=feature_map.parameters,
    weight_params=ansatz.parameters,
    interpret=parity,
    output_shape=2,
    sampler=sampler,
)

Постройте классификатор и подгоните его, как обычно. Как neural_network мы передаем SamplerQNN, который мы только что создали выше. Это единственное отличие от предыдущей реализации.

classifier = NeuralNetworkClassifier(
    neural_network=sampler_qnn,
    loss="cross_entropy",
    one_hot=True,
)
classifier.fit(features, labels)

Вместо создания квантовой нейронной сети вручную вы можете обучить VQC. Он принимает либо квантовый экземпляр, либо сэмплер, и в зависимости от того, что передается, он автоматически создает либо CircuitQNN, либо SamplerQNN соответственно.

ОценщикQNN

Новая квантовая нейронная сеть оценщика использует примитив оценщика, градиенты оценщика и является прямой заменой OpflowQNN. Новый EstimatorQNN имеет интерфейс, аналогичный существующему OpflowQNN, с некоторыми отличиями. Вместо QuantumInstance должен использоваться экземпляр примитива Estimator. Градиенты задаются так же, как и в OpflowQNN, но он больше не принимает в качестве входных данных классы градиентов Opflow; вместо этого необходимо использовать (необязательно пользовательский) примитивный градиент.

Существующие алгоритмы обучения, такие как VQR, основанные на TwoLayerQNN, были обновлены, чтобы принимать обе реализации. Реализация NeuralNetworkRegressor не изменилась. Существующий OpflowQNN в настоящее время ожидает устаревания, будет объявлен устаревшим в будущем выпуске и впоследствии удален.

Мы покажем, как обучить вариационный квантовый регрессор, используя обе сети. Для простоты мы снова пропустим этап подготовки набора данных и повторно используем схему, которую мы создали для SamplerQNN.

Создание регрессора с использованием существующего OpflowQNN

Мы создаем экземпляр OpflowQNN и повторно используем квантовый экземпляр, созданный для квантового ядра.

from qiskit.opflow import PauliSumOp, StateFn
from qiskit_machine_learning.neural_networks import OpflowQNN

observable = PauliSumOp.from_list([("Z", 1)])
operator = StateFn(observable, is_measurement=True) @ StateFn(circuit)

opflow_qnn = OpflowQNN(
    operator=operator,
    input_params=feature_map.parameters,
    weight_params=ansatz.parameters,
    quantum_instance=sv_qi,
)

Создайте регрессор из сети и обучите его.

from qiskit_machine_learning.algorithms import NeuralNetworkRegressor

regressor = NeuralNetworkRegressor(neural_network=opflow_qnn)
regressor.fit(features, labels)

Построение регрессора с использованием нового EstimatorQNN

В этом примере мы создаем экземпляр эталонного оценщика. В своем собственном коде вы можете создать экземпляр оценщика из QiskitRuntimeService для использования служб времени выполнения Qiskit.

from qiskit.primitives import Estimator

estimator = Estimator()

Теперь мы создаем экземпляр EstimatorQNN. Сеть создает строку Паули Z, которая охватывает все кубиты как наблюдаемую, если она не указана.

from qiskit_machine_learning.neural_networks import EstimatorQNN

estimator_qnn = EstimatorQNN(
    circuit=circuit,
    input_params=feature_map.parameters,
    weight_params=ansatz.parameters,
    estimator=estimator,
)

Постройте вариационный квантовый регрессор и подгоните его.

regressor = NeuralNetworkRegressor(neural_network=estimator_qnn)
regressor.fit(features, labels)

Вместо создания квантовой нейронной сети вручную вы можете обучить VQR. Он принимает либо квантовый экземпляр, либо оценщик, в зависимости от того, что передается, он автоматически создает либо TwoLayerQNN, либо EstimatorQNN соответственно.

Производительность

Для экспериментов по квантовому машинному обучению выбор подходящего бэкенда чрезвычайно важен, особенно при работе с большим количеством кубитов. Если вы еще не проводите свои эксперименты на реальном оборудовании и решаете, использовать ли встроенные эталонные примитивы Qiskit или другой симулятор с Qiskit Machine Learning, мы рекомендуем использовать Qiskit Aer 0.12 или более позднюю версию. Примитивы Qiskit Aer поддерживаются эффективными симуляторами, написанными на C/C++, и их производительность значительно повышается с увеличением числа кубитов. См. график ниже для сравнения:

В этом примере мы обучили простую модель QSVC на различном количестве кубитов. Мы обучили модели классификации на 35 образцах, варьируя только количество кубитов в зависимости от количества признаков. На 6 или менее кубитах разница почти неразличима, но на 8 кубитах разница становится заметной и становится существенной, если количество кубитов больше 10. Таким образом, на основе этих данных, если ваши модели требуют прилично большого количества кубитов, то имитация их на примитивах Aer является очевидным выбором.

С чего начать

Мы рекомендуем пользователям опробовать новую версию Qiskit Machine Learning, используя Qiskit Aer (не забудьте обновить до версии 0.12) для работы на симуляторе и ознакомиться с Qiskit Runtime Service для обучения моделей машинного обучения на реальном оборудовании.