IBM Qiskit量子计算-操作-Qiskit梯度框架
admin
2023-07-26 10:40:30
0

梯度框架允许评估量子梯度和与之相关的函数。除了一下形式的标准的期望数值的一阶梯度。


梯度框架也支持二阶梯度(Hessians),和量子态 Quantum Fisher Information (QFI)的评估。



Imports

#General imports
import numpy as np

#Operator Imports
from qiskit.opflow import Z, X, I, StateFn, CircuitStateFn, SummedOp
from qiskit.opflow.gradients import Gradient, NaturalGradient, QFI, Hessian

#Circuit imports
from qiskit.circuit import QuantumCircuit, QuantumRegister, Parameter, ParameterVector, ParameterExpression
from qiskit.circuit.library import EfficientSU2

第一阶梯度

考虑有输入状态 ,参数化的Ansatz 和观察到的 的参数化量子态 。我们想要计算:

Gradients w.r.t. Measurement Operator Parameters

期望值的梯度w.r.t. 是一个测量操作的系数,分别观察 ,例如


首先,我们定义量子态 和Hamiltonian 是可以观察的。然后,状态和Hamiltonian就被包裹进一个对象,定义期望值

# Instantiate the quantum state
a = Parameter('a')
b = Parameter('b')
q = QuantumRegister(1)
qc = QuantumCircuit(q)
qc.h(q)
qc.rz(a, q[0])
qc.rx(b, q[0])

# Instantiate the Hamiltonian observable
H = (2 * X) + Z

# Combine the Hamiltonian observable and the state
op = ~StateFn(H) @ CircuitStateFn(primitive=qc, coeff=1.)

# Print the operator corresponding to the expectation value
print(op)

# 结果
ComposedOp([
OperatorMeasurement(2.0 * X
+ 1.0 * Z),
CircuitStateFn(
┌───┐┌───────┐┌───────┐
q0: ┤ H ├┤ Rz(a) ├┤ Rx(b) ├
└───┘└───────┘└───────┘
)
])

我们给我们想要评估的梯度,创建一组参数。现在,这一列和期望值操作用于生成表示梯度的操作。

params = [a, b]

# Define the values to be assigned to the parameters
value_dict = {a: np.pi / 4, b: np.pi}

# Convert the operator and the gradient target params into the respective operator
grad = Gradient().convert(operator = op, params = params)

# Print the operator corresponding to the Gradient
print(grad)

# 结果是
ListOp([
SummedOp([
ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌─────────────┐┌───────┐┌───┐
q0: ┤ H ├┤ Rz(a + π/2) ├┤ Rx(b) ├┤ H ├
└───┘└─────────────┘└───────┘└───┘
)
]),
-1.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌─────────────┐┌───────┐┌───┐
q0: ┤ H ├┤ Rz(a - π/2) ├┤ Rx(b) ├┤ H ├
└───┘└─────────────┘└───────┘└───┘
)
]),
0.5 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌─────────────┐┌───────┐
q0: ┤ H ├┤ Rz(a + π/2) ├┤ Rx(b) ├
└───┘└─────────────┘└───────┘
)
]),
-0.5 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌─────────────┐┌───────┐
q0: ┤ H ├┤ Rz(a - π/2) ├┤ Rx(b) ├
└───┘└─────────────┘└───────┘
)
])
]),
SummedOp([
ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌─────────────┐┌───┐
q0: ┤ H ├┤ Rz(a) ├┤ Rx(b + π/2) ├┤ H ├
└───┘└───────┘└─────────────┘└───┘
)
]),
-1.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌─────────────┐┌───┐
q0: ┤ H ├┤ Rz(a) ├┤ Rx(b - π/2) ├┤ H ├
└───┘└───────┘└─────────────┘└───┘
)
]),
0.5 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌─────────────┐
q0: ┤ H ├┤ Rz(a) ├┤ Rx(b + π/2) ├
└───┘└───────┘└─────────────┘
)
]),
-0.5 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌─────────────┐
q0: ┤ H ├┤ Rz(a) ├┤ Rx(b - π/2) ├
└───┘└───────┘└─────────────┘
)
])
])
])

然后剩下需要做的是将值分配给参数并评估梯度操作。

# Assign the parameters and evaluate the gradient
grad_result = grad.assign_parameters(value_dict).eval()
print('Gradient', grad_result)

# 结果
Gradient [(-1.414213562373094+0j), (-0.7071067811865477+0j)]

Gradients w.r.t. State Parameters

期望值w.r.t.的梯度是一个状态 参数,例如

分别是样本的概率w.r.t. 一个状态 参数,例如

梯度w.r.t.状态参数可用不同方法评估。每个方法都有各自优势和劣势。

# Define the Hamiltonian with fixed coefficients
H = 0.5 * X - 1 * Z
# Define the parameters w.r.t. we want to compute the gradients
params = [a, b]
# Define the values to be assigned to the parameters
value_dict = { a: np.pi / 4, b: np.pi}

# Combine the Hamiltonian observable and the state into an expectation value operator
op = ~StateFn(H) @ CircuitStateFn(primitive=qc, coeff=1.)
print(op)

# 结果
ComposedOp([
OperatorMeasurement(0.5 * X
- 1.0 * Z),
CircuitStateFn(
┌───┐┌───────┐┌───────┐
q0: ┤ H ├┤ Rz(a) ├┤ Rx(b) ├
└───┘└───────┘└───────┘
)
])

Parameter Shift Gradients

考虑Hermitian操作符 带有两个独特的特征根 ,作为参数量子化量子门的生成器

然后,量子梯度能够使用特征根 依赖于参数的偏移来计算。所有的标准、参数化量子门都能偏移 等,


概率梯度可以计算

# Convert the expectation value into an operator corresponding to the gradient w.r.t. the state parameters using
# the parameter shift method.
state_grad = Gradient(grad_method='param_shift').convert(operator=op, params=params)
# Print the operator corresponding to the gradient
print(state_grad)
# Assign the parameters and evaluate the gradient
state_grad_result = state_grad.assign_parameters(value_dict).eval()
print('State gradient computed with parameter shift', state_grad_result)

# 结果
ListOp([
SummedOp([
0.25 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌─────────────┐┌───────┐┌───┐
q0: ┤ H ├┤ Rz(a + π/2) ├┤ Rx(b) ├┤ H ├
└───┘└─────────────┘└───────┘└───┘
)
]),
-0.25 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌─────────────┐┌───────┐┌───┐
q0: ┤ H ├┤ Rz(a - π/2) ├┤ Rx(b) ├┤ H ├
└───┘└─────────────┘└───────┘└───┘
)
]),
-0.5 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌─────────────┐┌───────┐
q0: ┤ H ├┤ Rz(a + π/2) ├┤ Rx(b) ├
└───┘└─────────────┘└───────┘
)
]),
0.5 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌─────────────┐┌───────┐
q0: ┤ H ├┤ Rz(a - π/2) ├┤ Rx(b) ├
└───┘└─────────────┘└───────┘
)
])
]),
SummedOp([
0.25 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌─────────────┐┌───┐
q0: ┤ H ├┤ Rz(a) ├┤ Rx(b + π/2) ├┤ H ├
└───┘└───────┘└─────────────┘└───┘
)
]),
-0.25 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌─────────────┐┌───┐
q0: ┤ H ├┤ Rz(a) ├┤ Rx(b - π/2) ├┤ H ├
└───┘└───────┘└─────────────┘└───┘
)
]),
-0.5 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌─────────────┐
q0: ┤ H ├┤ Rz(a) ├┤ Rx(b + π/2) ├
└───┘└───────┘└─────────────┘
)
]),
0.5 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌─────────────┐
q0: ┤ H ├┤ Rz(a) ├┤ Rx(b - π/2) ├
└───┘└───────┘└─────────────┘
)
])
])
])
State gradient computed with parameter shift [(-0.35355339059327356+0j), (0.7071067811865475+0j)]

Unitaries Gradients的线性组合

Unitaries能写成 ,其中 表示一个参数化的Hermitian矩阵。进一步,Hermitian矩阵能够分解成Pauli的权重和,例如 ,其中 和 ,对于 作用与 量子比特。因此, 的梯度表示为


将Simulating physical phenomena by quantum networks中电路结构观察到的组合起来,允许我们使用但量子电路的评估计算梯度。

# Convert the expectation value into an operator corresponding to the gradient w.r.t. the state parameter using
# the linear combination of unitaries method.
state_grad = Gradient(grad_method='lin_comb').convert(operator=op, params=params)

# Print the operator corresponding to the gradient
print(state_grad)

# Assign the parameters and evaluate the gradient
state_grad_result = state_grad.assign_parameters(value_dict).eval()
print('State gradient computed with the linear combination method', state_grad_result)

# 结果
ListOp([
SummedOp([
0.5 * ComposedOp([
OperatorMeasurement(2.0 * ZZ),
CircuitStateFn(
┌────────────┐ ┌───────┐┌───────┐┌────────────┐
q0: ┤ U(π/2,0,π) ├────────■─┤ Rz(a) ├┤ Rx(b) ├┤ U(π/2,0,π) ├
└───┬───┬────┘┌─────┐ │ └─┬───┬─┘└───────┘└────────────┘
q86: ────┤ H ├─────┤ Sdg ├─■───┤ H ├─────────────────────────
└───┘ └─────┘ └───┘
) * 0.7071067811865476
]),
-1.0 * ComposedOp([
OperatorMeasurement(2.0 * ZZ),
CircuitStateFn(
┌────────────┐ ┌───────┐┌───────┐
q0: ┤ U(π/2,0,π) ├────────■─┤ Rz(a) ├┤ Rx(b) ├
└───┬───┬────┘┌─────┐ │ └─┬───┬─┘└───────┘
q92: ────┤ H ├─────┤ Sdg ├─■───┤ H ├───────────
└───┘ └─────┘ └───┘
) * 0.7071067811865476
])
]),
SummedOp([
0.5 * ComposedOp([
OperatorMeasurement(2.0 * ZZ),
CircuitStateFn(
┌────────────┐┌───────┐┌───┐┌───────┐┌────────────┐
q0: ┤ U(π/2,0,π) ├┤ Rz(a) ├┤ X ├┤ Rx(b) ├┤ U(π/2,0,π) ├
└───┬───┬────┘└┬─────┬┘└─┬─┘└─┬───┬─┘└────────────┘
q98: ────┤ H ├──────┤ Sdg ├───■────┤ H ├────────────────
└───┘ └─────┘ └───┘
) * 0.7071067811865476
]),
-1.0 * ComposedOp([
OperatorMeasurement(2.0 * ZZ),
CircuitStateFn(
┌────────────┐┌───────┐┌───┐┌───────┐
q0: ┤ U(π/2,0,π) ├┤ Rz(a) ├┤ X ├┤ Rx(b) ├
└───┬───┬────┘└┬─────┬┘└─┬─┘└─┬───┬─┘
q104: ────┤ H ├──────┤ Sdg ├───■────┤ H ├──
└───┘ └─────┘ └───┘
) * 0.7071067811865476
])
])
])
State gradient computed with the linear combination method [(-0.35355339059327384+0j), (0.7071067811865474+0j)]

有限差分梯度

与其他方法不同,有限差分梯度是用数字估计,而不是分析数值。该实现使用一个中心的差分方法,其中


概率梯度可以计算

# Convert the expectation value into an operator corresponding to the gradient w.r.t. the state parameter using
# the finite difference method.
state_grad = Gradient(grad_method='fin_diff').convert(operator=op, params=params)

# Print the operator corresponding to the gradient
print(state_grad)

# Assign the parameters and evaluate the gradient
state_grad_result = state_grad.assign_parameters(value_dict).eval()
print('State gradient computed with finite difference', state_grad_result)

# 结果
ListOp([
SummedOp([
250000.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌────────────────┐┌───────┐┌───┐
q0: ┤ H ├┤ Rz(a + 1.0e-6) ├┤ Rx(b) ├┤ H ├
└───┘└────────────────┘└───────┘└───┘
)
]),
-250000.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌────────────────┐┌───────┐┌───┐
q0: ┤ H ├┤ Rz(a - 1.0e-6) ├┤ Rx(b) ├┤ H ├
└───┘└────────────────┘└───────┘└───┘
)
]),
-500000.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌────────────────┐┌───────┐
q0: ┤ H ├┤ Rz(a + 1.0e-6) ├┤ Rx(b) ├
└───┘└────────────────┘└───────┘
)
]),
500000.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌────────────────┐┌───────┐
q0: ┤ H ├┤ Rz(a - 1.0e-6) ├┤ Rx(b) ├
└───┘└────────────────┘└───────┘
)
])
]),
SummedOp([
250000.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌────────────────┐┌───┐
q0: ┤ H ├┤ Rz(a) ├┤ Rx(b + 1.0e-6) ├┤ H ├
└───┘└───────┘└────────────────┘└───┘
)
]),
-250000.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌────────────────┐┌───┐
q0: ┤ H ├┤ Rz(a) ├┤ Rx(b - 1.0e-6) ├┤ H ├
└───┘└───────┘└────────────────┘└───┘
)
]),
-500000.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌────────────────┐
q0: ┤ H ├┤ Rz(a) ├┤ Rx(b + 1.0e-6) ├
└───┘└───────┘└────────────────┘
)
]),
500000.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌────────────────┐
q0: ┤ H ├┤ Rz(a) ├┤ Rx(b - 1.0e-6) ├
└───┘└───────┘└────────────────┘
)
])
])
])
State gradient computed with finite difference [(-0.3535533905739581+0j), (0.707106781151+0j)]

自然梯度

一阶梯度的一种特殊类型是自然梯度,已经证明在经典机器学习中有效,已经在量子内容中有所研究。数量表示梯度被称为反转Quantum Fisher Information matrix(QFI)的缩放。


不是反转的QFI,也可以使用带有和不带有正则化的最小二乘法解答


该实现支持ridge和lasso正则化,能够使用L-curve corner search自动搜索好的参数和两种QFI 的对角线元素的扰动。

自然梯度能够用于替代基于梯度为基础的优化器和/或ODE求解器的标准梯度。

# Besides the method to compute the circuit gradients resp. QFI, a regularization method can be chosen:
# `ridge` or `lasso` with automatic parameter search or `perturb_diag_elements` or `perturb_diag`
# which perturb the diagonal elements of the QFI.
nat_grad = NaturalGradient(grad_method='lin_comb', qfi_method='lin_comb_full', regularization='ridge').convert(
operator=op, params=params)

# Assign the parameters and evaluate the gradient
nat_grad_result = nat_grad.assign_parameters(value_dict).eval()
print('Natural gradient computed with linear combination of unitaries', nat_grad_result)

# 结果
Natural gradient computed with linear combination of unitaries [-2.6289756 1.3144878]

Hessians w.r.t. 测量操作符参数

再一次,我们定义作为可观察的量子态 和Hamiltonian 。然后,状态和Hamiltonian都被封装进一个对象,用于定义期望值


# Instantiate the Hamiltonian observable
H = X

# Instantiate the quantum state with two parameters
a = Parameter('a')
b = Parameter('b')

q = QuantumRegister(1)
qc = QuantumCircuit(q)
qc.h(q)
qc.rz(a, q[0])
qc.rx(b, q[0])

# Combine the Hamiltonian observable and the state
op = ~StateFn(H) @ CircuitStateFn(primitive=qc, coeff=1.)

下一步,我们能够选择参数,用于我们想要计算的二阶梯度。

  • 给定元组,Hessian会评估两个参数的二阶梯度。
  • 给定数组,Hessian会评估二阶梯度用于所有参数元组的组合。

在绑定值到参数上后,能够评估Hessian

# Convert the operator and the hessian target coefficients into the respective operator
hessian = Hessian().convert(operator = op, params = [a, b])

# Define the values to be assigned to the parameters
value_dict = {a: np.pi / 4, b: np.pi/4}

# Assign the parameters and evaluate the Hessian w.r.t. the Hamiltonian coefficients
hessian_result = hessian.assign_parameters(value_dict).eval()
print('Hessian \n', np.real(np.array(hessian_result)))

# 结果
Hessian
[[-7.07106781e-01 -5.55111512e-17]
[-5.55111512e-17 -5.55111512e-17]]

Hessians w.r.t. 状态参数

# Define parameters
params = [a, b]

# Get the operator object representing the Hessian
state_hess = Hessian(hess_method='param_shift').convert(operator=op, params=params)
# Assign the parameters and evaluate the Hessian
hessian_result = state_hess.assign_parameters(value_dict).eval()
print('Hessian computed using the parameter shift method\n', (np.array(hessian_result)))

# Get the operator object representing the Hessian
state_hess = Hessian(hess_method='lin_comb').convert(operator=op, params=params)
# Assign the parameters and evaluate the Hessian
hessian_result = state_hess.assign_parameters(value_dict).eval()
print('Hessian computed using the linear combination of unitaries method\n', (np.array(hessian_result)))

# Get the operator object representing the Hessian using finite difference
state_hess = Hessian(hess_method='fin_diff').convert(operator=op, params=params)
# Assign the parameters and evaluate the Hessian
hessian_result = state_hess.assign_parameters(value_dict).eval()
print('Hessian computed with finite difference\n', (np.array(hessian_result)))

# 结果
Hessian computed using the parameter shift method
[[-7.07106781e-01+0.j -5.55111512e-17+0.j]
[-5.55111512e-17+0.j -5.55111512e-17+0.j]]
Hessian computed using the linear combination of unitaries method
[[-7.07106781e-01+0.j 1.40000000e-17+0.j]
[ 1.40000000e-17+0.j 1.11000000e-16+0.j]]
Hessian computed with finite difference
[[-7.07244873e-01+0.j 6.10351562e-05+0.j]
[ 6.10351562e-05+0.j -6.10351562e-05+0.j]]

Quantum Fisher Information (QFI)

Quantum Fisher Information是一个度量张量表示以状态 ,参数化的Ansatz 作为输入的,参数化量子态 能力的表示。

对于纯状态的QFI的输入读取


电路QFIs

QFI的评估对应于用参数化量子电路生成的量子状态能够用不同方法生成。

Full QFI的线性组合

为计算QFI,我们使用工作电路和截断控制门。

# Wrap the quantum circuit into a CircuitStateFn
state = CircuitStateFn(primitive=qc, coeff=1.)

# Convert the state and the parameters into the operator object that represents the QFI
qfi = QFI(qfi_method='lin_comb_full').convert(operator=state, params=params)
# Define the values for which the QFI is to be computed
values_dict = {a: np.pi / 4, b: 0.1}

# Assign the parameters and evaluate the QFI
qfi_result = qfi.assign_parameters(values_dict).eval()
print('full QFI \n', np.real(np.array(qfi_result)))

# 结果
full QFI
[[ 1.00000000e+00 -6.73969696e-17]
[-6.73969696e-17 5.00000000e-01]]

Block-diagonal and Diagonal Approximation

块对角线表示QFI的对角线评估能够不用对角线工作量子比特计算。该实现需要展开成Pauli旋转和非参数化的门。

# Convert the state and the parameters into the operator object that represents the QFI
# and set the approximation to 'block_diagonal'
qfi = QFI('overlap_block_diag').convert(operator=state, params=params)

# Assign the parameters and evaluate the QFI
qfi_result = qfi.assign_parameters(values_dict).eval()
print('Block-diagonal QFI \n', np.real(np.array(qfi_result)))

# Convert the state and the parameters into the operator object that represents the QFI
# and set the approximation to 'diagonal'
qfi = QFI('overlap_diag').convert(operator=state, params=params)

# Assign the parameters and evaluate the QFI
qfi_result = qfi.assign_parameters(values_dict).eval()
print('Diagonal QFI \n', np.real(np.array(qfi_result)))

# 结果
Block-diagonal QFI
[[1. 0. ]
[0. 0.5]]
Diagonal QFI
[[1. 0. ]
[0. 0.5]]

应用案例:VQE with gradient-based optimization

额外导入

# Execution Imports
from qiskit import Aer
from qiskit.utils import QuantumInstance

# Algorithm Imports
from qiskit.algorithms import VQE
from qiskit.algorithms.optimizers import CG

梯度框架能够用于基于梯度的VQE。首先,初始化Hamiltonian和波函数ansatz。

from qiskit.opflow import I, X, Z
from qiskit.circuit import QuantumCircuit, ParameterVector
from scipy.optimize import minimize

# Instantiate the system Hamiltonian
h2_hamiltonian = -1.05 * (I ^ I) + 0.39 * (I ^ Z) - 0.39 * (Z ^ I) - 0.01 * (Z ^ Z) + 0.18 * (X ^ X)

# This is the target energy
h2_energy = -1.85727503

# Define the Ansatz
wavefunction = QuantumCircuit(2)
params = ParameterVector('theta', length=8)
it = iter(params)
wavefunction.ry(next(it), 0)
wavefunction.ry(next(it), 1)
wavefunction.rz(next(it), 0)
wavefunction.rz(next(it), 1)
wavefunction.cx(0, 1)
wavefunction.ry(next(it), 0)
wavefunction.ry(next(it), 1)
wavefunction.rz(next(it), 0)
wavefunction.rz(next(it), 1)

# Define the expectation value corresponding to the energy
op = ~StateFn(h2_hamiltonian) @ StateFn(wavefunction)

现在,我们选择是否VQE需要使用Gradient或NaturalGradient,决定QuantumInstance执行量子电路和运行算法。

grad = Gradient(grad_method='lin_comb')

qi_sv = QuantumInstance(Aer.get_backend('aer_simulator_statevector'),
shots=1,
seed_simulator=2,
seed_transpiler=2)

#Conjugate Gradient algorithm
optimizer = CG(maxiter=50)

# Gradient callable
vqe = VQE(wavefunction, optimizer=optimizer, gradient=grad, quantum_instance=qi_sv)

result = vqe.compute_minimum_eigenvalue(h2_hamiltonian)
print('Result:', result.optimal_value, 'Reference:', h2_energy)

# 结果
Result: -1.8404998438277125 Reference: -1.85727503

原文链接

相关内容