梯度和变分优化#
概述#
TensorCircuit 旨在使参数化量子门的优化变得简单、快速和方便。 在本说明中,我们回顾了如何获得电路梯度和运行变分优化。
设置#
[1]:
import numpy as np
import scipy.optimize as optimize
import tensorflow as tf
import tensorcircuit as tc
K = tc.set_backend("tensorflow")
PQC#
考虑一个作用于 \(n\) 个量子比特的变分电路,由 \(k\) 层组成,其中每一层包含相邻量子比特之间的参数化 \(e^{i\theta X\otimes X}\) 门, 然后是一系列参数化的单量子比特 \(Z\) 和 \(X\) 旋转。 我们现在展示如何在 TensorCircuit 中实现此类电路,以及如何使用机器学习后端之一轻松高效地计算损失函数和梯度。
一般\(n,k\)的电路和参数集可以定义如下::
[2]:
def qcircuit(n, k, params):
c = tc.Circuit(n)
for j in range(k):
for i in range(n - 1):
c.exp1(
i, i + 1, theta=params[j * (3 * n - 1) + i], unitary=tc.gates._xx_matrix
)
for i in range(n):
c.rz(i, theta=params[j * (3 * n - 1) + n - 1 + i])
c.rx(i, theta=params[j * (3 * n - 1) + 2 * n - 1 + i])
return c
举个例子,我们取 \(n=3, k=2\) ,设置 TensorFlow 作为我们的后端,定义一个能量损失函数来最小化
[3]:
n = 3
k = 2
def energy(params):
c = qcircuit(n, k, params)
e = c.expectation_ps(x=[0, 1]) + c.expectation_ps(x=[1, 2])
return K.real(e)
梯度和即时编译#
使用 ML 后端对自动微分的支持,我们现在可以快速计算能量和能量相对于参数的梯度。
[4]:
energy_val_grad = K.value_and_grad(energy)
这将创建一个函数,给定一组参数作为输入,返回能量和能量梯度。如果只需要梯度,则可以通过 K.grad(energy)
计算。 虽然我们可以直接在一组参数上运行上述代码,但如果要对能量进行多次评估,则可以通过使用该函数的即时编译版本来节省大量时间。
[5]:
energy_val_grad_jit = K.jit(energy_val_grad)
使用 K.jit
,能量和梯度的初始评估可能需要更长的时间,但随后的评估将明显快于非 jitted 代码。 我们建议始终使用 jit
,只要函数是 张量输入,张量输出
的形式,我们已经努力使电路模拟器的各个方面都与 JIT 兼容。
通过 ML 后端进行优化#
有了可用的能量函数和梯度,参数的优化就很简单了。下面是一个如何通过随机梯度下降来做到这一点的例子。
[6]:
learning_rate = 2e-2
opt = K.optimizer(tf.keras.optimizers.SGD(learning_rate))
def grad_descent(params, i):
val, grad = energy_val_grad_jit(params)
params = opt.update(grad, params)
if i % 10 == 0:
print(f"i={i}, energy={val}")
return params
params = K.implicit_randn(k * (3 * n - 1))
for i in range(100):
params = grad_descent(params, i)
i=0, energy=0.11897378414869308
i=10, energy=-0.3692811131477356
i=20, energy=-0.7194114923477173
i=30, energy=-0.904697597026825
i=40, energy=-1.013866662979126
i=50, energy=-1.1042678356170654
i=60, energy=-1.1998062133789062
i=70, energy=-1.308410406112671
i=80, energy=-1.4276418685913086
i=90, energy=-1.5474387407302856
通过 Scipy 界面进行优化#
使用机器学习后端进行优化的另一种方法是使用 SciPy。 这可以通过 scipy_interface
API 调用来完成,并允许使用基于梯度(例如 BFGS)和非基于梯度(例如 COBYLA)的优化器,这在 ML 后端是不可用的。
[7]:
f_scipy = tc.interfaces.scipy_interface(energy, shape=[k * (3 * n - 1)], jit=True)
params = K.implicit_randn(k * (3 * n - 1))
r = optimize.minimize(f_scipy, params, method="L-BFGS-B", jac=True)
r
/Users/shixin/Cloud/newwork/quantum-information/codebases/tensorcircuit/tensorcircuit/interfaces.py:237: ComplexWarning: Casting complex values to real discards the imaginary part
scipy_gs = scipy_gs.astype(np.float64)
[7]:
fun: -2.000000476837158
hess_inv: <16x16 LbfgsInvHessProduct with dtype=float64>
jac: array([ 2.43186951e-04, -1.50322914e-04, 8.94665718e-05, 1.18807920e-05,
2.95639038e-05, 1.19209290e-07, -5.96046448e-08, -2.98023224e-08,
0.00000000e+00, -1.19209290e-07, 3.90738450e-07, 9.34305717e-07,
-8.22039729e-05, 1.19209290e-07, 0.00000000e+00, 0.00000000e+00])
message: 'CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH'
nfev: 60
nit: 19
njev: 60
status: 0
success: True
x: array([ 2.35625520e+00, 7.85409154e-01, 1.57088576e+00, 2.10625989e-05,
-1.57088425e+00, -1.70256902e+00, -5.33743572e-01, 3.11436816e-01,
1.26543793e+00, 1.91663337e+00, -1.15901008e-07, -1.76623396e-05,
-1.59972887e-04, -8.97072367e-01, 1.79929630e+00, -9.67278961e-01])
上面的第一行指定了要提供给要最小化的函数的参数的形状,这里是能量函数。 jit=True
参数会自动处理能量函数的即时编译。 通过将 gradient=False
参数提供给scipy_interface
,同样可以有效地执行无梯度优化。
[8]:
f_scipy = tc.interfaces.scipy_interface(
energy, shape=[k * (3 * n - 1)], jit=True, gradient=False
)
params = K.implicit_randn(k * (3 * n - 1))
r = optimize.minimize(f_scipy, params, method="COBYLA")
r
[8]:
fun: -1.9999911785125732
maxcv: 0.0
message: 'Optimization terminated successfully.'
nfev: 386
status: 1
success: True
x: array([ 7.87597857e-01, -5.14158452e-01, -1.56560250e+00, -3.15230777e-04,
9.91532990e-01, 5.95588091e-01, 1.38523058e+00, -3.59642968e-04,
-3.23365306e-01, -4.16465772e-01, -7.32259085e-03, 6.53997758e-05,
7.71203778e-01, 2.46256921e+00, 8.78602039e-01, -3.51989842e-01])