Korean
언어
English
Japanese
German
Korean
Portuguese, Brazilian
French
Shortcuts

참고

이 페이지는 tutorials/algorithms/02_vqe_convergence.ipynb 로부터 생성되었다.

IBM 퀀텀 랩 에서 대화식으로 실행하시오.

VQE 수렴 모니터링

VQEQAOA 와 같은 변분 알고리즘(Variational algorithms)은 사용자에게 알고리즘이 실행되어 최소값으로 수렴할 때 최적화 진행 상황을 모니터링할 수 있는 콜백 메서트를 옵션으로 제공한다. 콜백은 옵티마이저에 의하여 각 functional evaluation 시 호출되며, 현재 옵티마이저의 값, 평가 횟수, 현재 옵티마이저의 매개 변수 등을 제공한다. 특정 옵티마이저에 따라 이는 각 반복 (단계)에 호출되는 것이 아닐 수 있음에 주의하라. 예를 들어, 만약 옵티마이저가 유한 차분 그래디언트를 계산하기 위해 비용 함수를 호출하면 콜백을 통해 확인할 수 있다.

이 노트북은 키스킷의 VQE 알고리즘을 사용하여 선택된 세트의 최적화 프로그램으로 접지 상태 에너지에 대한 수렴 경로 그래프를 구성하는 방법을 설명한다.

[1]:
import numpy as np
import pylab

from qiskit import BasicAer
from qiskit.aqua.operators import X, Z, I
from qiskit.aqua import QuantumInstance, aqua_globals
from qiskit.aqua.algorithms import VQE, NumPyMinimumEigensolver
from qiskit.aqua.components.initial_states import Zero
from qiskit.aqua.components.optimizers import COBYLA, L_BFGS_B, SLSQP
from qiskit.circuit.library import TwoLocal

먼저, VQE에 대한 큐비트 연산자를 만든다. 여기서는 앞서 키스킷의 알고리즘 소개에서 사용된 것과 동일한 (H2 분자에 대하여 원래 Qiskit Chemistry에서 계산된) 연산자를 사용할 것이다.

[2]:
H2_op = (-1.052373245772859 * I ^ I) + \
        (0.39793742484318045 * I ^ Z) + \
        (-0.39793742484318045 * Z ^ I) + \
        (-0.01128010425623538 * Z ^ Z) + \
        (0.18093119978423156 * X ^ X)

비교를 위해 일련의 옵티마이저에 대한 콜백 사용법을 아래에서 확인할 수 있다. H2 Hamiltonian의 최소 에너지는 아주 쉽게 찾을 수 있으므로 맥시터(maxiters) 를 작은 값으로 설정할 것이다.

[3]:
optimizers = [COBYLA(maxiter=80), L_BFGS_B(maxiter=60), SLSQP(maxiter=60)]
converge_cnts = np.empty([len(optimizers)], dtype=object)
converge_vals = np.empty([len(optimizers)], dtype=object)

for i, optimizer in enumerate(optimizers):
    print('\rOptimizer: {}        '.format(type(optimizer).__name__), end='')
    aqua_globals.random_seed = 50
    var_form = TwoLocal(rotation_blocks='ry', entanglement_blocks='cz')

    counts = []
    values = []
    def store_intermediate_result(eval_count, parameters, mean, std):
        counts.append(eval_count)
        values.append(mean)

    vqe = VQE(H2_op, var_form, optimizer, callback=store_intermediate_result,
              quantum_instance=QuantumInstance(backend=BasicAer.get_backend('statevector_simulator')))
    result = vqe.compute_minimum_eigenvalue(operator=H2_op)
    converge_cnts[i] = np.asarray(counts)
    converge_vals[i] = np.asarray(values)
print('\rOptimization complete      ');
Optimization complete

이제 저장한 콜백 데이터에서 각 옵티마이저가 각각의 목적 함수를 호출하여 발생하는 에너지 값을 그려볼 수 있다. 유한 차분 방법을 사용하여 기울기를 계산하는 옵티마이저는 수 많은 평가에서 기울기를 설정하기 위해 가까운 지점에 대한 값을 계산하는 plot과 같은 특성 단계를 가진다. (여기 그래프의 눈금에서는 차이를 구별하기 힘들 정도로 매우 유사한 값을 가진 가까운 지점임)

[4]:
pylab.rcParams['figure.figsize'] = (12, 8)
for i, optimizer in enumerate(optimizers):
    pylab.plot(converge_cnts[i], converge_vals[i], label=type(optimizer).__name__)
pylab.xlabel('Eval count')
pylab.ylabel('Energy')
pylab.title('Energy convergence for various optimizers')
pylab.legend(loc='upper right');
../../_images/tutorials_algorithms_02_vqe_convergence_7_0.png

마지막으로 위의 문제는 여전히 고전적으로 다루기 쉬우므로 NumPyMinimumEigensolver를 사용하여 솔루션에 대한 참조 값을 계산할 수 있다. 이제 에너지가 VQE에 수렴하며 고전적인 정확해(exact solution) 인 최소값으로 이동함에 따라, 이 최소값과 도출된 정확해(exact solution) 의 차이를 그릴 수 있다.

[5]:
npme = NumPyMinimumEigensolver()
result = npme.compute_minimum_eigenvalue(operator=H2_op)
ref_value = result.eigenvalue.real
print(f'Reference value: {ref_value:.5f}')
Reference value: -1.85728
[6]:
pylab.rcParams['figure.figsize'] = (12, 8)
for i, optimizer in enumerate(optimizers):
    pylab.plot(converge_cnts[i], abs(ref_value - converge_vals[i]), label=type(optimizer).__name__)
pylab.xlabel('Eval count')
pylab.ylabel('Energy difference from solution reference value')
pylab.title('Energy convergence for various optimizers')
pylab.yscale('log')
pylab.legend(loc='upper right');
../../_images/tutorials_algorithms_02_vqe_convergence_10_0.png

점진적인 프레임워크(Gradient framework) 사용하기

이제 Qiskit은 오퍼레이터 기능의 일부로서 점진적인 프레임워크를 갖는다. 최적화 계산된 기울기를 사용하여 이제 최적화 단계 자체만 볼 수 있습니다.

[7]:
from qiskit.aqua.operators.gradients import Gradient

aqua_globals.random_seed = 50
var_form = TwoLocal(rotation_blocks='ry', entanglement_blocks='cz')

optimizer = SLSQP(maxiter=60)

counts = []
values = []
def store_intermediate_result(eval_count, parameters, mean, std):
    counts.append(eval_count)
    values.append(mean)

vqe = VQE(H2_op, var_form, optimizer, callback=store_intermediate_result,
          gradient=Gradient(grad_method='fin_diff'),
          quantum_instance=QuantumInstance(backend=BasicAer.get_backend('statevector_simulator')))
result = vqe.compute_minimum_eigenvalue(operator=H2_op)
print(f'Value using Gradient: {result.eigenvalue.real:.5f}')
Value using Gradient: -1.85728
[8]:
pylab.rcParams['figure.figsize'] = (12, 8)
pylab.plot(counts, values, label=type(optimizer).__name__)
pylab.xlabel('Eval count')
pylab.ylabel('Energy')
pylab.title('Energy convergence using Gradient')
pylab.legend(loc='upper right');
../../_images/tutorials_algorithms_02_vqe_convergence_13_0.png

로깅(logging) 을 통한 모니터링

이 코드의 대부분은 Python logging 문을 사용하여 진단하고 추적할 수 있다. 로깅 시에는 로깅 레벨 등을 조정하도록 구성할 수 있다. qiskit.aqua 모듈에서 로깅을 시작하고자 할 때는 다음의 코드를 실행하여 쉽게 시작할 수 있다. 여기서 우리는 로깅 레벨을 INFO 로 설정한다.

[9]:
import logging
from qiskit.aqua import set_qiskit_aqua_logging


set_qiskit_aqua_logging(logging.INFO)

그리고 INFO level logging에서, VQE는 아래와 같이 평가들에 대한 정보를 포함할 것이다.

020-11-04 16:55:33,450:qiskit.aqua.algorithms.minimum_eigen_solvers.vqe:INFO: Energy evaluation returned [-8.88931977] - 6801.61572 (ms), eval count: 1 2020-11-04 16:55:34,463:qiskit.aqua.algorithms.minimum_eigen_solvers.vqe:INFO: Energy evaluation returned [-8.88931977] - 1012.12025 (ms), eval count: 2 2020-11-04 16:55:35,483:qiskit.aqua.algorithms.minimum_eigen_solvers.vqe:INFO: Energy evaluation returned [-8.88931977] - 1019.99474 (ms), eval count: 3 2020-11-04 16:55:36,646:qiskit.aqua.algorithms.minimum_eigen_solvers.vqe:INFO: Energy evaluation returned [-8.88931977] - 1162.09555 (ms), eval count: 4

[10]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright

Version Information

Qiskit SoftwareVersion
Qiskit0.23.0
Terra0.16.0
Aer0.7.0
Ignis0.5.0
Aqua0.8.0
IBM Q Provider0.11.0
System information
Python3.6.1 |Continuum Analytics, Inc.| (default, May 11 2017, 13:09:58) [GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]
OSLinux
CPUs1
Memory (Gb)5.827335357666016
Sat Nov 07 16:21:19 2020 EST

This code is a part of Qiskit

© Copyright IBM 2017, 2020.

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.

[ ]: