주 콘텐츠로 건너뛰기

Ansatz와 변분 형식

모든 변분 알고리즘의 핵심에는 상태 간의 차이를 분석하는 핵심 아이디어가 있습니다. 이러한 상태들은 매개변수 또는 변수 집합에서 잘 정의된 매핑(예: 연속, 미분 가능)을 통해 편리하게 연관됩니다. 따라서 이를 "변분"이라고 부르게 됩니다.

먼저 매개변수화된 회로를 수동으로 구성하는 방법을 살펴보겠습니다. 이러한 회로들을 사용하여 변분 알고리즘이 탐색할 매개변수화된 상태 모음을 나타내는 변분 형식을 정의합니다. 그 다음, 이 변분 형식을 참조 상태에 적용하여 ansatz을 구성합니다.

또한 이 검색 공간을 탐색하는 동안 속도와 정확도 간의 균형을 맞추는 방법을 살펴봅니다.

ansatz 논의의 주요 구성요소를 보여주는 다이어그램으로, 휴리스틱 ansatz와 문제 특정 ansatz를 포함합니다.

매개변수화된 양자 회로

변분 알고리즘은 유한한 kk개의 매개변수 θ=(θ0,,θk1)\vec{\theta} = (\theta^0, \ldots, \theta^{k-1})에 의존하는 양자 상태 ψ(θ)|\psi(\vec{\theta})\rangle 범위를 탐색하고 비교함으로써 작동합니다. 이러한 상태들은 조정 가능한 매개변수가 있는 게이트를 사용하여 매개변수화된 양자 회로로 준비할 수 있습니다. 아직 특정 각도를 바인딩하지 않고 이 매개변수화된 회로를 생성할 수 있습니다:

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit rustworkx
from qiskit.circuit import QuantumCircuit, Parameter

theta = Parameter("θ")

qc = QuantumCircuit(3)
qc.rx(theta, 0)
qc.cx(0, 1)
qc.x(2)

qc.draw("mpl")

이전 코드 셀의 출력

from math import pi

angle_list = [pi / 3, pi / 2]
circuits = [qc.assign_parameters({theta: angle}) for angle in angle_list]

for circuit in circuits:
display(circuit.draw("mpl"))

이전 코드 셀의 출력

이전 코드 셀의 출력

변분 형식과 Ansatz

참조 상태 ρ|\rho\rangle에서 목표 상태 ψ(θ)|\psi(\vec\theta)\rangle로 반복적으로 최적화하기 위해, 변분 알고리즘이 탐색할 매개변수화된 상태 모음을 나타내는 변분 형식 UV(θ)U_V(\vec{\theta})를 정의해야 합니다:

0URUR0=ρUV(θ)UA(θ)0=UV(θ)UR0=UV(θ)ρ=ψ(θ)\begin{aligned} |0\rangle \xrightarrow{U_R} U_R|0\rangle & = |\rho\rangle \xrightarrow{U_V(\vec{\theta})} U_A(\vec{\theta})|0\rangle \\[1mm] & = U_V(\vec{\theta})U_R|0\rangle \\[1mm] & = U_V(\vec{\theta})|\rho\rangle \\[1mm] & = |\psi(\vec{\theta})\rangle \\[1mm] \end{aligned}

매개변수화된 상태는 어떤 매개변수에도 의존하지 않는 참조 상태 ρ|\rho\rangle과 항상 매개변수에 의존하는 변분 형식 UV(θ)U_V(\vec{\theta}) 모두에 의존합니다. 이 두 반쪽의 조합을 ansatz라고 부르며, UA(θ):=UV(θ)URU_A(\vec\theta) := U_V(\vec\theta)U_R입니다.

변분 알고리즘이 탐색할 매개변수화된 상태 모음을 나타내는 ansatz를 구성할 때, 우리는 중요한 문제를 깨닫습니다: 차원성입니다. nn-큐빗 시스템(즉, 힐베르트 공간)은 구성 공간에 많은 서로 다른 양자 상태를 가집니다. 완전히 탐색하려면 다루기 어려운 수의 매개변수가 필요합니다. 정량적으로, 그 차원성은 D=22nD = 2^{2n}입니다. 더 나쁜 것은, 검색 알고리즘 및 다른 알고리즘의 런타임 복잡도가 이 차원성과 함께 지수적으로 증가하며, 이를 문헌에서 종종 차원성의 저주라고 부릅니다.

이 문제를 극복하기 위해, 변분 형식에 합리적인 제약을 부과하여 가장 관련성 있는 상태들만 탐색하도록 하는 것이 일반적인 관행입니다. 효율적인 잘린 ansatz를 찾는 것은 활발한 연구 분야이지만, 여기서는 두 가지 일반적인 설계를 다룰 것입니다.

휴리스틱 ansatz와 트레이드오프

특정 문제를 제한하는 데 도움이 될 수 있는 정보가 없으면, 2^개 미만의 매개변수로 임의의 매개변수화된 회로 계열을 시도할 수 있습니다. 그러나 고려해야 할 트레이드오프가 있습니다:

  • 속도: 검색 공간을 줄임으로써 알고리즘을 더 빠르게 실행할 수 있습니다.
  • 정확도: 공간을 줄이면 문제의 실제 해를 제외할 위험이 있어 차선의 해가 나올 수 있습니다.
  • 노이즈: 더 깊은 회로는 노이즈의 영향을 받으므로 ansatz의 연결성, 게이트 및 게이트 충실도로 실험해야 합니다.

품질(또는 해결 가능성)과 속도 사이에는 근본적인 트레이드오프가 있습니다: 매개변수가 많을수록 정확한 결과를 찾을 가능성이 높지만, 알고리즘을 실행하는 데 더 오래 걸립니다.

N-로컬 회로

휴리스틱 ansatz의 가장 널리 사용되는 예 중 하나는 N-로컬 회로이며, 몇 가지 이유가 있습니다:

  • 효율적인 구현: N-로컬 ansatz는 일반적으로 양자 컴퓨터에서 효율적으로 구현할 수 있는 단순하고 로컬한 게이트들로 구성되어 있으며, 적은 수의 물리적 큐빗을 사용합니다. 이는 양자 회로를 구성하고 최적화하기 쉽게 만듭니다.
  • 중요한 상관관계 포착: N-로컬 ansatz는 적은 수의 게이트로도 양자 시스템의 큐빗들 사이의 중요한 상관관계를 포착할 수 있습니다. 이는 로컬 게이트들이 이웃 큐빗들에 작용하고 그들 사이에 얽힘을 생성할 수 있기 때문이며, 이는 복잡한 양자 시스템을 시뮬레이션하는 데 중요할 수 있습니다.

이러한 회로들은 다음과 같이 한 번 이상 교대로 반복되는 회전 계층과 얽힘 계층으로 구성됩니다:

  • 각 계층은 최대 NN 크기의 게이트로 형성되며, 여기서 NN은 큐빗 수보다 낮아야 합니다.
  • 회전 계층의 경우, 게이트들은 서로 쌓여 있습니다. RX 또는 CRZ와 같은 표준 회전 연산을 사용할 수 있습니다.
  • 얽힘 계층의 경우, Toffoli 게이트나 얽힘 전략이 있는 CX와 같은 게이트를 사용할 수 있습니다.
  • 두 유형의 계층 모두 매개변수화될 수도 있고 아닐 수도 있지만, 최소한 하나는 매개변수를 포함해야 합니다. 그렇지 않으면 최소한 하나의 매개변수 없이는 어떤 변형도 없을 것입니다!
  • 선택적으로, 추가 회전 계층이 회로의 끝에 추가됩니다.

예를 들어, 회전 블록이 RXCRZ 게이트로 형성되고, 얽힘 블록이 큐빗 [0,1,2][0,1,2], [0,2,3][0,2,3], [4,2,1][4,2,1][3,1,0][3,1,0]에 작용하는 Toffoli 게이트로 형성되며, 각 계층의 2회 반복으로 5큐빗 NLocal 회로를 생성해봅시다.

from qiskit.circuit.library import NLocal, CCXGate, CRZGate, RXGate
from qiskit.circuit import Parameter

theta = Parameter("θ")
ansatz = NLocal(
num_qubits=5,
rotation_blocks=[RXGate(theta), CRZGate(theta)],
entanglement_blocks=CCXGate(),
entanglement=[[0, 1, 2], [0, 2, 3], [4, 2, 1], [3, 1, 0]],
reps=2,
insert_barriers=True,
)
ansatz.decompose().draw("mpl")

이전 코드 셀의 출력

위의 예에서, 가장 큰 게이트는 3개의 큐빗에 작용하는 Toffoli 게이트이므로 회로는 3-로컬입니다. 가장 일반적으로 사용되는 NN-로컬 회로 유형은 단일 큐빗 회전 게이트와 2-큐빗 얽힘 게이트가 있는 22-로컬 회로입니다.

Qiskit의 TwoLocal 클래스를 사용하여 22-로컬 회로를 만들어봅시다. 구문은 NLocal과 같지만 몇 가지 차이가 있습니다. 예를 들어, RX, RZ, CNOT과 같은 대부분의 게이트는 게이트를 가져오거나 Parameter 인스턴스를 생성하지 않고도 문자열로 전달할 수 있습니다.

from qiskit.circuit.library import TwoLocal

ansatz = TwoLocal(
num_qubits=5,
rotation_blocks=["rx", "rz"],
entanglement_blocks="cx",
entanglement="linear",
reps=2,
insert_barriers=True,
)
ansatz.decompose().draw("mpl")

이전 코드 셀의 출력

이 경우, 각 큐빗이 다음과 얽혀있는 선형 얽힘 분포를 사용했습니다. 다른 전략에 대해 알아보려면 TwoLocal 문서를 참조합니다.

효율적인 SU2

efficient_su2는 SU(2)에 걸친 단일 큐빗 연산의 계층과 CX 얽힘으로 구성된 하드웨어 효율적인 회로입니다. 이는 변분 양자 알고리즘의 시험 파동함수를 준비하거나 머신 러닝을 위한 분류 회로로 사용할 수 있는 휴리스틱 패턴입니다.

from qiskit.circuit.library import efficient_su2

ansatz = efficient_su2(4, su2_gates=["rx", "y"], entanglement="linear", reps=1)
ansatz.decompose().draw("mpl")

이전 코드 셀의 출력

문제 특정 Ansatz

휴리스틱 및 하드웨어 효율적인 ansatz가 문제를 순진한 방식으로 해결하는 데 도움이 되는 동안, 우리는 문제 특정 지식을 사용하여 회로 검색 공간을 특정 유형으로 제한할 수 있습니다. 이는 검색 과정에서 정확도를 잃지 않고 속도를 얻는 데 도움이 될 것입니다.

최적화

최대 컷 문제에서, 우리는 그래프의 노드들을 서로 다른 그룹에 있는 노드들 사이의 간선 수를 최대화하는 방식으로 분할하려고 합니다. 아래 그래프의 원하는 최대 컷 분할은 명확합니다: 왼쪽의 0번째 노드는 컷으로 오른쪽의 나머지 노드들과 분리되어야 합니다.

import rustworkx as rx
from rustworkx.visualization import mpl_draw

n = 4
G = rx.PyGraph()
G.add_nodes_from(range(n))
# The edge syntax is (start, end, weight)
edges = [(0, 1, 1.0), (0, 2, 1.0), (0, 3, 1.0), (1, 2, 1.0), (2, 3, 1.0)]
G.add_edges_from(edges)

mpl_draw(
G, pos=rx.shell_layout(G), with_labels=True, edge_labels=str, node_color="#1192E8"
)

이전 코드 셀의 출력

최대 컷 문제에 QAOA 알고리즘을 활용하려면, 연산자의 최소 기댓값이 두 그룹의 노드들 사이의 최대 간선 수에 해당하는 방식으로 비용을 인코딩하는 Pauli 해밀턴이 필요합니다.

이 간단한 예에서, 연산자는 간선으로 연결된 노드들의 Z 연산자가 있는 항의 선형 조합입니다(0번째 큐빗이 가장 오른쪽임을 기억하세요): ZZII+IZZI+ZIIZ+IZIZ+IIZZZZII + IZZI + ZIIZ + IZIZ + IIZZ. 연산자가 구성되면, QAOA 알고리즘의 ansatz는 Qiskit 회로 라이브러리의 QAOAAnsatz 회로를 사용하여 쉽게 만들 수 있습니다.

# Pre-defined ansatz circuit, operator class and visualization tools
from qiskit.circuit.library import QAOAAnsatz
from qiskit.quantum_info import SparsePauliOp

# Problem to Hamiltonian operator
hamiltonian = SparsePauliOp.from_list(
[("ZZII", 1), ("IZZI", 1), ("ZIIZ", 1), ("IZIZ", 1), ("IIZZ", 1)]
)
# QAOA ansatz circuit
ansatz = QAOAAnsatz(hamiltonian, reps=2)
# Draw
ansatz.decompose(reps=3).draw("mpl")

이전 코드 셀의 출력

위 이미지는 명확성을 위해 기본 게이트의 ansatz를 보여줍니다. 그러나 reps 인자를 변경하거나 분해 방법 없이 회로를 그려서 여러 분해 수준으로 표현할 수 있습니다. 예를 들어, 다음 표현은 기본 reps 값인 reps=1인 QAOA 구조를 직접 보여줍니다.

ansatz.decompose(reps=2).draw("mpl")

이전 코드 셀의 출력

양자 머신 러닝

머신 러닝에서, 일반적인 응용은 데이터를 두 개 이상의 범주로 분류하는 것입니다. 이는 고전 특성 벡터를 양자 힐베르트 공간으로 매핑하는 특성 맵에 데이터 포인트를 인코딩하는 것을 포함합니다. 고전적으로 시뮬레이션하기 어려운 매개변수화된 양자 회로를 기반으로 양자 특성 맵을 구성하는 것은 고전 머신 러닝 접근법에 대한 잠재적 이점을 얻기 위한 중요한 단계이며 현재 연구의 활발한 영역입니다.

zz_feature_map을 사용하여 매개변수화된 회로를 만들 수 있습니다. 우리는 특성 맵에 데이터 포인트를 전달할 수 있으며(xx) 매개변수로 가중치를 전달하기 위한 별도의 변분 형식을 전달할 수 있습니다(θ\theta).

from qiskit.circuit.library import zz_feature_map, TwoLocal

data = [0.1, 0.2]

zz_feature_map_reference = zz_feature_map(feature_dimension=2, reps=2)
zz_feature_map_reference = zz_feature_map_reference.assign_parameters(data)

variation_form = TwoLocal(2, ["ry", "rz"], "cz", reps=2)
vqc_ansatz = zz_feature_map_reference.compose(variation_form)
vqc_ansatz.decompose().draw("mpl")

이전 코드 셀의 출력

요약

이 강의를 통해 여러분은 변분 형식으로 검색 공간을 정의하는 방법을 배웠습니다:

  • 조정 가능한 매개변수가 있는 게이트를 사용하여 매개변수화된 양자 회로로 상태를 준비합니다
  • 속도와 정확도를 트레이드오프하는 ansatz를 구성하는 방법
  • 휴리스틱 ansatz
  • 문제 특정 ansatz

우리의 고수준 변분 워크로드는 다음과 같습니다:

참조 상태를 준비하는 단위와 ansatz를 준비하는 또 다른 단위를 포함하는 회로 다이어그램입니다.

각 변분 매개변수 θ\vec\theta에 대해, 다른 양자 상태가 생성될 것입니다. 최적의 매개변수를 찾으려면, ansatz의 매개변수를 반복적으로 업데이트하기 위해 문제 특정 비용 함수를 정의해야 합니다.