참고
이 페이지는 tutorials/operators/02_gradients_framework.ipynb 에서 생성되었다.
Qiskit 경사 프레임워크 (Gradient Framework)¶
경사 프레임워크는 양자 함수 뿐만 아니라 양자 경사를 구할 수 있게 해준다. 게다가 다음 형태의 기댓값의 표준 일차 경사도 가능하다.
경사 프레임워크는 이차 경사(헤세 행렬)를 구하는 것과 양자 상태 \(|\psi\left(\theta\right)\rangle\) 의 양자 Fisher 정보(QFI, Quantum Fisher Information)를 구하는 것도 지원한다.
불러오기¶
[1]:
#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
일차 경사 (First Order Gradients)¶
주어진 초기 상태가 \(|\psi\rangle\) 이고 매개변수화된 가설이 \(V\left(\theta\right)\) 인 매개변수화된 양자 상태 \(|\psi\left(\theta\right)\rangle = V\left(\theta\right)|\psi\rangle\) 와 관측가능량 \(\hat{O}\left(\omega\right)=\sum_{i}\omega_i\hat{O}_i\) 에 대해 다음 경사들을 계산할 것이다.
측정 연산자 매개변수에 대한 경사¶
관측가능량 \(\hat{O}\left(\omega\right)\) 의 기댓값을 측정 연산자의 계수에 대한 경사는
먼저, 양자 상태 \(|\psi\left(\theta\right)\rangle\) 와 해밀토니안 \(H\) 를 관측가능량처럼 작용하도록 정의한다. 그런 다음, 상태와 해밀토니안을 기댓값을 정의하는 객체로 랩핑한다.
[2]:
# 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_0: ┤ H ├┤ RZ(a) ├┤ RX(b) ├
└───┘└───────┘└───────┘
)
])
경사를 계산할 수 있는 매개변수 리스트를 구성한다. 이 리스트와 기댓값 연산자는 경사를 나타내는 연산자를 생성하는 데 사용된다.
[3]:
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_0: ┤ H ├┤ RZ(a + 1.5707963267949) ├┤ RX(b) ├┤ H ├
└───┘└─────────────────────────┘└───────┘└───┘
)
]),
-1.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌─────────────────────────┐┌───────┐┌───┐
q0_0: ┤ H ├┤ RZ(a - 1.5707963267949) ├┤ RX(b) ├┤ H ├
└───┘└─────────────────────────┘└───────┘└───┘
)
]),
0.5 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌─────────────────────────┐┌───────┐
q0_0: ┤ H ├┤ RZ(a + 1.5707963267949) ├┤ RX(b) ├
└───┘└─────────────────────────┘└───────┘
)
]),
-0.5 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌─────────────────────────┐┌───────┐
q0_0: ┤ H ├┤ RZ(a - 1.5707963267949) ├┤ RX(b) ├
└───┘└─────────────────────────┘└───────┘
)
])
]),
SummedOp([
ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌─────────────────────────┐┌───┐
q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b + 1.5707963267949) ├┤ H ├
└───┘└───────┘└─────────────────────────┘└───┘
)
]),
-1.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌─────────────────────────┐┌───┐
q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b - 1.5707963267949) ├┤ H ├
└───┘└───────┘└─────────────────────────┘└───┘
)
]),
0.5 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌─────────────────────────┐
q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b + 1.5707963267949) ├
└───┘└───────┘└─────────────────────────┘
)
]),
-0.5 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌─────────────────────────┐
q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b - 1.5707963267949) ├
└───┘└───────┘└─────────────────────────┘
)
])
])
])
남은 일은 매개변수에 값을 할당하고 경사 연산자를 구하는 것이다.
[4]:
# Assign the parameters and evaluate the gradient
grad_result = grad.assign_parameters(value_dict).eval()
print('Gradient', grad_result)
Gradient [(-1.414213562373094+0j), (-0.7071067811865474+0j)]
상태 매개변수에 대한 경사¶
상태 \(|\psi\left(\theta\right)\rangle\) 의 매개변수에 대한 기댓값의 경사는
상태 \(|\psi\left(\theta\right)\rangle\) 의 매개변수에 대한 샘플링 확률의 경우는
상태 매개변수에 대한 경사는 다양한 방법으로 구할 수 있다. 각 방법은 장점과 단점이 있다.
[5]:
# 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_0: ┤ H ├┤ RZ(a) ├┤ RX(b) ├
└───┘└───────┘└───────┘
)
])
매개변수 이동 경사 (Parameter Shift Gradients)¶
주어진 두 유일한 고윳값 \(\pm r\) 을 가지는 에르미트(Hermitian) 연산자 \(g\) 가 생성자로써 작용하는 매개변수화된 양자 게이트는
그러면 양자 경사들은 고윳값 \(r\) 에 의존하는 이동으로 계산될 수 있다. 모든 매개변수화된 기본 Qiskit 게이트들 은 \(\pi/2\) 만큼 이동될 수 있다.
확률 경사도 동등하게 계산된다.
[6]:
# 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_0: ┤ H ├┤ RZ(a + 1.5707963267949) ├┤ RX(b) ├┤ H ├
└───┘└─────────────────────────┘└───────┘└───┘
)
]),
-0.25 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌─────────────────────────┐┌───────┐┌───┐
q0_0: ┤ H ├┤ RZ(a - 1.5707963267949) ├┤ RX(b) ├┤ H ├
└───┘└─────────────────────────┘└───────┘└───┘
)
]),
-0.5 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌─────────────────────────┐┌───────┐
q0_0: ┤ H ├┤ RZ(a + 1.5707963267949) ├┤ RX(b) ├
└───┘└─────────────────────────┘└───────┘
)
]),
0.5 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌─────────────────────────┐┌───────┐
q0_0: ┤ H ├┤ RZ(a - 1.5707963267949) ├┤ RX(b) ├
└───┘└─────────────────────────┘└───────┘
)
])
]),
SummedOp([
0.25 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌─────────────────────────┐┌───┐
q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b + 1.5707963267949) ├┤ H ├
└───┘└───────┘└─────────────────────────┘└───┘
)
]),
-0.25 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌─────────────────────────┐┌───┐
q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b - 1.5707963267949) ├┤ H ├
└───┘└───────┘└─────────────────────────┘└───┘
)
]),
-0.5 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌─────────────────────────┐
q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b + 1.5707963267949) ├
└───┘└───────┘└─────────────────────────┘
)
]),
0.5 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌─────────────────────────┐
q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b - 1.5707963267949) ├
└───┘└───────┘└─────────────────────────┘
)
])
])
])
State gradient computed with parameter shift [(-0.35355339059327356+0j), (0.7071067811865472+0j)]
유니테리 경사의 선형 결합 (Linear Combination of Unitaries Gradients)¶
유니테리들은 \(U\left(\omega\right) = e^{iM\left(\omega\right)}\) 와 같이 쓰여질 수 있는데, 여기서 \(M\left(\omega\right)\) 는 매개변수화된 에르미트 행렬을 나타낸다. 나아가 에르미트 행렬들은 Pauli 항들의 가중 합으로 분해될 수 있는데, 다시 말하면 \(m_p\left(\omega\right)\in\mathbb{R}\) 와 \(j^{\text{th}}\) 큐비트에 작용하는 \(\sigma_{j, p}\in\left\{I, X, Y, Z\right\}\) 에 대한 \(h_p=\bigotimes\limits_{j=0}^{n-1}\sigma_{j, p}\) 로 \(M\left(\omega\right) = \sum_pm_p\left(\omega\right)h_p\) 와 같이 나타낼 수 있다. 고로, \(U_k\left(\omega_k\right)\) 의 경사들은 다음과 같이 주어진다 \begin{equation*} \frac{\partial U_k\left(\omega_k\right)}{\partial\omega_k} = \sum\limits_pi \frac{\partial m_{k,p}\left(\omega_k\right)}{\partial\omega_k}U_k\left(\omega_k\right)h_{k_p}. \end{equation*}
이 결과를 Simulating physical phenomena by quantum networks 에 제시된 회로 구조와 결합하면 단일 양자 회로를 구하여 경사를 계산할 수 있다.
[7]:
# 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(ZZ) * 2.0,
CircuitStateFn(
┌───┐ ┌───────┐┌───────┐┌───┐
q0_0: ┤ H ├────────■─┤ RZ(a) ├┤ RX(b) ├┤ H ├
├───┤┌─────┐ │ └─┬───┬─┘└───────┘└───┘
q81_0: ┤ H ├┤ SDG ├─■───┤ H ├────────────────
└───┘└─────┘ └───┘
) * 0.7071067811865476
]),
-1.0 * ComposedOp([
OperatorMeasurement(ZZ) * 2.0,
CircuitStateFn(
┌───┐ ┌───────┐┌───────┐
q0_0: ┤ H ├────────■─┤ RZ(a) ├┤ RX(b) ├
├───┤┌─────┐ │ └─┬───┬─┘└───────┘
q82_0: ┤ H ├┤ SDG ├─■───┤ H ├───────────
└───┘└─────┘ └───┘
) * 0.7071067811865476
])
]),
SummedOp([
0.5 * ComposedOp([
OperatorMeasurement(ZZ) * 2.0,
CircuitStateFn(
┌───┐┌───────┐┌───┐┌───────┐┌───┐
q0_0: ┤ H ├┤ RZ(a) ├┤ X ├┤ RX(b) ├┤ H ├
├───┤└┬─────┬┘└─┬─┘└─┬───┬─┘└───┘
q83_0: ┤ H ├─┤ SDG ├───■────┤ H ├───────
└───┘ └─────┘ └───┘
) * 0.7071067811865476
]),
-1.0 * ComposedOp([
OperatorMeasurement(ZZ) * 2.0,
CircuitStateFn(
┌───┐┌───────┐┌───┐┌───────┐
q0_0: ┤ H ├┤ RZ(a) ├┤ X ├┤ RX(b) ├
├───┤└┬─────┬┘└─┬─┘└─┬───┬─┘
q84_0: ┤ H ├─┤ SDG ├───■────┤ H ├──
└───┘ └─────┘ └───┘
) * 0.7071067811865476
])
])
])
State gradient computed with the linear combination method [(-0.3535533905932737+0j), (0.7071067811865472+0j)]
유한차 경사 (Finite Difference Gradients)¶
다른 방법들과는 달리, 유한차 경사는 해석적이 아닌 수치적 추정을 한다. 이 구현은 \(\epsilon \ll 1\) 이내의 값 차이를 이용한다.
확률 경사도 동등하게 계산된다.
[8]:
# 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_0: ┤ H ├┤ RZ(a + 1.0e-6) ├┤ RX(b) ├┤ H ├
└───┘└────────────────┘└───────┘└───┘
)
]),
-250000.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌────────────────┐┌───────┐┌───┐
q0_0: ┤ H ├┤ RZ(a - 1.0e-6) ├┤ RX(b) ├┤ H ├
└───┘└────────────────┘└───────┘└───┘
)
]),
-500000.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌────────────────┐┌───────┐
q0_0: ┤ H ├┤ RZ(a + 1.0e-6) ├┤ RX(b) ├
└───┘└────────────────┘└───────┘
)
]),
500000.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌────────────────┐┌───────┐
q0_0: ┤ H ├┤ RZ(a - 1.0e-6) ├┤ RX(b) ├
└───┘└────────────────┘└───────┘
)
])
]),
SummedOp([
250000.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌────────────────┐┌───┐
q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b + 1.0e-6) ├┤ H ├
└───┘└───────┘└────────────────┘└───┘
)
]),
-250000.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌────────────────┐┌───┐
q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b - 1.0e-6) ├┤ H ├
└───┘└───────┘└────────────────┘└───┘
)
]),
-500000.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌────────────────┐
q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b + 1.0e-6) ├
└───┘└───────┘└────────────────┘
)
]),
500000.0 * ComposedOp([
OperatorMeasurement(Z),
CircuitStateFn(
┌───┐┌───────┐┌────────────────┐
q0_0: ┤ H ├┤ RZ(a) ├┤ RX(b - 1.0e-6) ├
└───┘└───────┘└────────────────┘
)
])
])
])
State gradient computed with finite difference [(-0.35355339057345814+0j), (0.707106781149+0j)]
자연 경사¶
일차 경사의 특별한 경우로, 고전 기계 학습(classical machine learning)에서도 유용함이 증명되었고 양자 문맥에서도 연구가 되고 있는 자연 경사가 있다. 이 값은 양자 Fisher 정보 행렬 (Quantum Fisher Information matrix, QFI) 의 역행렬로 보정된 경사를 나타낸다.
QFI의 역 대신에, (정규화를 적용하거나 적용하지 않은) 최소자승법을 사용해서 구할 수도 있다
이 구현은 QFI의 대각 성분의 두 가지 유형의 섭동뿐만 아니라 L-curve corner search 을 사용하여 좋은 매개 변수를 자동 검색함으로써 능선(ridge) 및 라소(lasso) 정규화를 지원한다.
어떤 경사 기반의 최적화나 ODE 해결자를 사용하는 표준 경사 대신에 자연 경사를 사용할 수 있다.
[9]:
# 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.62895551 1.31447775]
헤세 행렬 (Second Order Gradients)¶
경사 프레임워크는 네 가지 유형의 이차 경사를 지원한다.
관측량 \(\hat{O}\left(\omega\right)\) 에 대한 측정 연산자의 계수에 대한 기댓값 경사, \(\frac{\partial^2\langle\psi\left(\theta\right)|\hat{O}\left(\omega\right)|\psi\left(\theta\right)\rangle}{\partial\omega^2}\)
상태 \(|\psi\left(\theta\right)\rangle\) 의 매개변수에 대한 기댓값의 경사, \(\frac{\partial^2\langle\psi\left(\theta\right)|\hat{O}\left(\omega\right)|\psi\left(\theta\right)\rangle}{\partial\theta^2}\)
상태 \(|\psi\left(\theta\right)\rangle\) 의 매개변수에 대한 샘플링 확률의 경사, \(\frac{\partial^2 p_i}{\partial\theta^2} = \frac{\partial^2\langle\psi\left(\theta\right)|i\rangle\langle i|\psi\left(\theta\right)\rangle}{\partial\theta^2}\)
상태 \(|\psi\left(\theta\right)\rangle\) 의 매개변수와 관측량 \(\hat{O}\left(\omega\right)\) 에 대한 측정 연산자의 계수에 대한 경사, \(\frac{\partial^2\langle\psi\left(\theta\right)|\hat{O}\left(\omega\right)|\psi\left(\theta\right)\rangle}{\partial\theta\partial\omega}\)
다음은 첫 두 개의 헤세 유형에 대해 예제들이다. 나머지 헤세 유형들도 이와 비슷하게 구할 수 있다.
측정 연산자 매개변수에 대한 헤세 행렬¶
다시 양자 상태 \(|\psi\left(\theta\right)\rangle\) 와 해밀토니안 \(H\) 를 관측가능량처럼 작용하도록 정의한다. 그런 다음, 상태와 해밀토니안을 기댓값을 정의하는 객체로 랩핑한다.
[10]:
# 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
은 주어진 매개변수들의 모든 가능한 조합들로 이차 경사를 얻을 것이다.
매개변수 값을 매개변수에 바인딩 한 후, 헤세 행렬을 구할 수 있다.
[11]:
# 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 0.00000000e+00]
[ 0.00000000e+00 -5.55111512e-17]]
상태 매개변수에 대한 헤세 행렬¶
[12]:
# 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 0.00000000e+00+0.j]
[ 0.00000000e+00+0.j -5.55111512e-17+0.j]]
Hessian computed using the linear combination of unitaries method
[[-7.07106781e-01+0.j 0.00000000e+00+0.j]
[ 0.00000000e+00+0.j 5.60000000e-17+0.j]]
Hessian computed with finite difference
[[-7.07122803e-01+0.j 3.05175781e-05+0.j]
[ 3.05175781e-05+0.j -6.10351562e-05+0.j]]
양자 Fisher 정보 (Quantum Fisher Information, QFI)¶
양자 Fisher 정보는 메트릭 텐서로써 주어진 입력 상태 \(|\psi\rangle\) 와 매개변수화된 가설 가설 \(V\left(\theta\right)\) 의 표현력을 대표한다.
순수 상태에 대한 QFI의 입력값은
회로 QFI¶
매개변수화된 양자 회로로 생성된 양자 상태에 해당하는 QFI의 값을 구하는 것는 다양한 방식으로 수행될 수 있다.
선형 조합 전체 QFI¶
전체 QFI를 계산하려면 제어 게이트에 간섭하는 것 외에도 작업 중인 큐비트를 활용해야 한다. 다음의 예를 참고하라 Variational ansatz-based quantum simulation of imaginary time evolution.
[13]:
# 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.0000000e+00 -2.0659798e-16]
[-2.0659798e-16 5.0000000e-01]]
블록-대각과 대각 근사¶
QFI의 블록 대각 행렬 표현의 대각 근사화는 추가 큐비트 없이 계산될 수 있다. 이 구현은 Pauli 회전들과 매개변수화가 안 된 게이트들로 푸는 것을 요구한다.
[14]:
# 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¶
추가 불러오기¶
[15]:
# 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
에도 사용될 수 있다. 먼저 해밀토니안과 파동함수 가설을 초기화한다.
[16]:
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
를 정의해서 알고리즘을 실행한다.
[17]:
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: -0.8800000000000001 Reference: -1.85727503
[18]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
Version Information
Qiskit Software | Version |
---|---|
Qiskit | None |
Terra | 0.17.4 |
Aer | 0.8.2 |
Ignis | None |
Aqua | None |
IBM Q Provider | None |
System information | |
Python | 3.8.8 (default, Apr 13 2021, 12:59:45) [Clang 10.0.0 ] |
OS | Darwin |
CPUs | 2 |
Memory (Gb) | 12.0 |
Fri May 28 09:42:47 2021 EDT |
This code is a part of Qiskit
© Copyright IBM 2017, 2021.
This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.
[ ]: