Мы рассмотрели подготовку квантового состояния 1 кубита и провели оптимизацию с использованием классической техники оптимизации.
Теперь мы рассмотрим еще немного оптимизации состояния 1 кубита.
Настоящий номер
Мы провели оптимизацию создания любого квантового состояния на трехмерной блох-сфере. Теперь мы думаем только о действительном числе. Обычно при машинном обучении нам нужно только реальное число.
Раньше мы использовали вентиль u3 для создания квантового состояния, а теперь мы используем вентиль Ry в диапазоне от 0 до pi.
Инструменты
Мы используем blueqat и байесовскую оптимизацию на python.
!pip install blueqat !pip install bayesian-optimization
Рай ротация
Мы просто пробуем поворот. Теперь у нас есть случайный угол для пробы. В качестве симулятора бэкэнда по умолчанию используется бэкэнд numpy, на этот раз я просто выбираю бэкэнд numba в качестве симулятора.
from blueqat import Circuit from bayes_opt import BayesianOptimization from blueqat import BlueqatGlobalSetting BlueqatGlobalSetting.set_default_backend('numba') import time import math import numpy as np angle = math.pi * np.random.random() start = time.time() a = Circuit(1).ry(angle)[0].run() end = time.time() print(end - start) print(a)
У нас есть,
0.001172780990600586 [0.81528649+0.j 0.5790578 +0.j]
Теперь мы знаем, что это работает.
Оптимизация
Мы делаем оптимизацию, используя байесовскую оптимизацию, которая проверяет приоритет данных.
Пример показывает, что нам нужно целевое квантовое состояние как суперпозиция |0› и |1›, а вектор состояния будет [0,707…, 0,707…]
def f(angle, target = np.array([np.sqrt(0.5),np.sqrt(0.5)])): a = Circuit(1).ry(angle)[0].run() return -(a[0].real - target[0])**2 - (a[1].real - target[1])**2 pbounds = {'angle': (0, math.pi)} optimizer = BayesianOptimization(f=f, pbounds=pbounds) start = time.time() optimizer.maximize(init_points=10, n_iter=10) print(time.time() - start) print(optimizer.max)
Мы получили
| iter | target | angle | ------------------------------------- | 1 | -0.2953 | 2.672 | | 2 | -0.3306 | 2.737 | | 3 | -0.2533 | 2.588 | | 4 | -0.299 | 2.679 | | 5 | -0.5585 | 0.03892 | | 6 | -0.04497 | 1.996 | | 7 | -0.5805 | 0.007542 | | 8 | -0.1332 | 2.305 | | 9 | -0.1585 | 2.372 | | 10 | -0.1206 | 2.269 | | 11 | -0.01659 | 1.313 | | 12 | -6.594e-0 | 1.587 | | 13 | -8.6e-06 | 1.565 | | 14 | -1.051e-0 | 1.57 | | 15 | -3.189e-0 | 1.574 | | 16 | -3.774e-0 | 1.559 | | 17 | -0.000250 | 1.602 | | 18 | -0.000131 | 1.548 | | 19 | -0.000179 | 1.598 | | 20 | -0.000117 | 1.549 | ===================================== 47.76689958572388 {'target': -1.0507579819273144e-07, 'params': {'angle': 1.5701480188461168}}
Давайте проверим результат, и у нас есть хорошее приближение к целевому значению.
Circuit(1).ry(1.5701480188461168)[0].run() #=>array([0.70733596+0.j, 0.70687753+0.j])
и затем мы пробуем |1› как цель
def f(angle, target = np.array([0,1])): a = Circuit(1).ry(angle)[0].run() return -(a[0].real - target[0])**2 - (a[1].real - target[1])**2 pbounds = {'angle': (0, math.pi)} optimizer = BayesianOptimization(f=f, pbounds=pbounds) start = time.time() optimizer.maximize(init_points=10, n_iter=10) print(time.time() - start) print(optimizer.max)
У нас есть,
| iter | target | angle | ------------------------------------- | 1 | -0.4881 | 1.714 | | 2 | -0.04444 | 2.719 | | 3 | -0.00382 | 3.018 | | 4 | -1.097 | 0.9368 | | 5 | -0.002545 | 3.041 | | 6 | -0.09438 | 2.525 | | 7 | -0.02024 | 2.857 | | 8 | -0.001584 | 3.062 | | 9 | -1.22 | 0.8011 | | 10 | -1.81 | 0.1901 | | 11 | -3.749e-3 | 3.142 | | 12 | -3.749e-3 | 3.142 | | 13 | -1.257e-1 | 3.142 | | 14 | -3.511e-1 | 3.142 | | 15 | -1.284e-1 | 3.142 | | 16 | -1.284e-1 | 3.142 | | 17 | -1.551e-1 | 3.142 | | 18 | -1.551e-1 | 3.142 | | 19 | -6.033e-1 | 3.142 | | 20 | -7.728e-1 | 3.142 | ===================================== 24.23820424079895 {'target': -3.749399456654644e-33, 'params': {'angle': 3.141592653589793}}
Ускорьте байесовскую оптимизацию
Узким местом схемы оптимизации является не квантовая схема, а явно процесс оптимизации БО.
Теперь мы попробуем использовать гиперопт, чтобы получить гораздо больше скорости.
from blueqat import Circuit import time import math import numpy as np from hyperopt import hp, tpe, Trials, fmin def f(angle, target = np.array([0,1])): a = Circuit(1).ry(angle)[0].run() return (a[0].real - target[0])**2 + (a[1].real - target[1])**2 start = time.time() best = fmin(f, space = hp.uniform('angle', 0, math.pi), algo=tpe.suggest, max_evals=100, verbose=1) print(time.time() - start) print(best)
Да, это очень хорошо.
100%|██████████| 100/100 [00:00<00:00, 293.91it/s, best loss: 4.2970620825684156e-08] 0.3623378276824951 {'angle': 3.141178066465152}
И как суперпозиция
from blueqat import Circuit import time import math import numpy as np from hyperopt import hp, tpe, Trials, fmin def f(angle, target = np.array([np.sqrt(0.5),np.sqrt(0.5)])): a = Circuit(1).ry(angle)[0].run() return (a[0].real - target[0])**2 + (a[1].real - target[1])**2 start = time.time() best = fmin(f, space = hp.uniform('angle', 0, math.pi), algo=tpe.suggest, max_evals=100, verbose=1) print(time.time() - start) print(best)
Это также имеет хорошее приближение в данный момент.
100%|██████████| 100/100 [00:00<00:00, 330.35it/s, best loss: 8.988237686812778e-06] 0.3093442916870117 {'angle': 1.576792406987552}
Нам удалось оптимизировать и создать квантовый вектор состояния с помощью классической схемы оптимизации.