变分量子线路梯度计算进阶
在MindQuantum中,我们可以通过Simulator
类的get_expectation_with_grad
方法来获得一个变分量子线路的梯度,在这篇教程中,我们将更进一步的介绍该方法的其他功能,帮助大家来实现更高级的使用方法。
模型介绍
get_expectation_with_grad
方法主要是用来计算如下表达式的值和线路中参数的梯度。
该方法的接口定义如下
Simulator.get_expectation_with_grad(
hams,
circ_right,
circ_left=None,
simulator_left=None,
encoder_params_name=None,
ansatz_params_name=None,
parallel_worker=None
)
下面,我们将一一介绍每个参数的意义。
hams
。线路中的哈密顿量,所需要的类型为MindQuantum中的Hamiltonian
,或者一个包含多个Hamiltonian
的list
数组,对于后一种情况,框架会同时计算出线路关于所有哈密顿量的期望值,和每个期望值关于线路参数的梯度circ_right
。为公式中的\(U_r(\boldsymbol{\theta})\)circ_left
。为公式中的\(U_l(\boldsymbol{\theta})\),当为默认值None
时,circ_left
和circ_right
为同一线路,若需要空线路可单独使用Circuit()创建。simulator_left
。为包含公式中\(\left|\varphi\right>\)的模拟器,你可以通过模拟器的set_qs
、apply_gate
或apply_circuit
方法来设置该模拟器的状态为你需要的状态。当为默认值None
时,\(\left|\varphi\right>=\left|\psi\right>\),而\(\left|\psi\right>\)为当前模拟器所包含的量子态。encoder_params_name
。表明\(U_l(\boldsymbol{\theta})\)和\(U_r(\boldsymbol{\theta})\)中,哪些含参量子门是encoder。在量子神经网络中,encoder对应的参数是用户需要输入的数,不参与训练。当为默认值None
时,线路中没有encoder。ansatz_params_name
。表明\(U_l(\boldsymbol{\theta})\)和\(U_r(\boldsymbol{\theta})\)中,哪些含参量子门是ansatz。在量子神经网络中,ansatz对应的参数由系统或用户初始化,随后由系统根据梯度来更新,参与训练。当为默认值None
时,线路中的所有参数门都是ansatz。parallel_worker
。当hams
包含多个哈密顿量或者encoder的输入包含多个样本点时,MindQuantum会根据此整数为参考来合理地进行并行运算。
多个哈密顿量在多个输入样本点下的期望值
在本任务中,我们想计算如下量子线路在\(\alpha=\text{arctan}(\sqrt{2}), \pi/2\)时,关于哈密顿量\(Z_0, X_0, Y_0\)的期望值。
[1]:
import numpy as np
from mindquantum import QubitOperator
from mindquantum import Simulator
from mindquantum import Circuit, TimeEvolution, Hamiltonian, H
# 定义希尔伯特空间中的旋转轴
axis = QubitOperator('Y0', 1 / np.sqrt(2)) + QubitOperator('X0', -1 / np.sqrt(2))
# 定义trotter分解的阶数
trotter_order = 4
# 利用TimeEvolution来对旋转进行trotter分解
encoder = TimeEvolution(axis, {'alpha': 0.5 / trotter_order}).circuit * trotter_order
encoder
[1]:
q0: ──RY(0.176776695296637*alpha)────RX(-0.176776695296637*alpha)────RY(0.176776695296637*alpha)────RX(-0.176776695296637*alpha)────RY(0.176776695296637*alpha)────RX(-0.176776695296637*alpha)────RY(0.176776695296637*alpha)────RX(-0.176776695296637*alpha)──
下面定义待求期望值的哈密顿量:
[2]:
# 定义哈密顿量集合
hams = [Hamiltonian(QubitOperator('X0')), Hamiltonian(QubitOperator('Y0')), Hamiltonian(QubitOperator('Z0'))]
hams
[2]:
[1.0 [X0] , 1.0 [Y0] , 1.0 [Z0] ]
获取求期望值和梯度的算子:
[3]:
grad_ops = Simulator('projectq', 1).get_expectation_with_grad(hams, encoder, encoder_params_name=encoder.params_name, parallel_worker=6)
grad_ops
[3]:
<mindquantum.simulator.simulator.GradOpsWrapper at 0x7f03a4a60430>
定义alpha
的值:
[4]:
alpha = np.array([[np.arctan(np.sqrt(2))], [np.pi/2]])
alpha
[4]:
array([[0.95531662],
[1.57079633]])
[5]:
f, g = grad_ops(alpha)
print(f)
print(f'shape: {f.shape}')
print('\n')
print(g)
print(f'shape: {g.shape}')
[[0.59389047+0.j 0.55828416+0.j 0.57932107+0.j]
[0.77269648+0.j 0.63465887+0.j 0.01217645+0.j]]
shape: (2, 3)
[[[ 0.45790207+0.j]
[ 0.35200884+0.j]
[-0.80864423+0.j]]
[[ 0.10989151+0.j]
[-0.11512098+0.j]
[-0.9732094 +0.j]]]
shape: (2, 3, 1)
结果分析
根据上面结果我们可以看到,期望值f
的维度为(2, 3)
,不难发现,f
的每一行对应每一个样本点不同哈密顿量期望值,f
的每一列对应每个哈密顿量在不同样本的下的期望值。而对于梯度g
来说,我们也有相似的结论,只不过最后一个维度表示的是不同的线路参数。
计算不同量子态的内积
根据模型,我们只需将哈密顿量设置为单位算符,\(U_l(\boldsymbol{\theta})\) 设置为空的量子线路,那么我们就可以利用 \(U_r(\boldsymbol{\theta})\) 来将 \(\left|\psi\right>\) 旋转到 \(\left|\varphi\right>\)上,而这需要计算出 \(\left|\varphi\right>\)和旋转后的量子态之间的内积。
这里,我们计算如下量子线路对零态进行演化过后的量子态与均匀叠加态之间的内积。
[6]:
circuit = Circuit().ry('a', 0).rz('b', 0).ry('c', 0)
circuit
[6]:
q0: ──RY(a)────RZ(b)────RY(c)──
制备包含均匀叠加态的模拟器:
[7]:
sim_l = Simulator('projectq', 1)
sim_l.apply_gate(H.on(0))
sim_l
[7]:
projectq simulator with 1 qubit.
Current quantum state:
√2/2¦0⟩
√2/2¦1⟩
制备单位哈密顿量:
[8]:
ham = Hamiltonian(QubitOperator(""))
获取内积和梯度计算算子:
[9]:
grad_ops = Simulator('projectq', 1).get_expectation_with_grad(ham, circuit, Circuit(), simulator_left=sim_l)
选择合适的参数:
[10]:
rot_angle = np.array([7.902762e-01, 2.139225e-04, 7.795934e-01])
[11]:
f, g = grad_ops(rot_angle)
print(f)
print('\n')
print(g)
[[0.99999989-7.52279618e-05j]]
[[[ 2.31681689e-04+3.80179652e-05j -5.34806192e-05-3.51659884e-01j
2.31681689e-04-3.80179652e-05j]]]
结果分析
通过计算结果,我们发现最后两个态的内积接近与1,说明我们能够通过如上线路以很高的保真度制备一个均匀叠加态。
[12]:
print(circuit.get_qs(pr=rot_angle, ket=True))
(0.7074343486186319-0.00010695972396782116j)¦0⟩
(0.7067790538448511+√5/3906250j)¦1⟩
若想查询更多关于MindQuantum的API,请点击:https://mindspore.cn/mindquantum/。