Přeskočit na hlavní obsah

Ansaetze a variační formy

Jádrem všech variačních algoritmů je klíčová myšlenka analýzy rozdílů mezi stavy, které jsou pohodlně propojeny nějakým dobře definovaným zobrazením (například spojitým, diferencovatelným) z množiny parametrů nebo proměnných — odtud název.

Nejprve prozkoumáme, jak ručně sestavit parametrizované Circuit. Tyto Circuit použijeme k definování variační formy, která představuje kolekci parametrizovaných stavů, jež má náš variační algoritmus prozkoumat. Poté sestavíme náš ansatz aplikací této variační formy na náš referenční stav.

Prozkoumáme také, jak při prohledávání tohoto prostoru vyvážit rychlost a přesnost.

Diagram zobrazující klíčové komponenty diskuze o ansatzu, včetně heuristických ansaetze a problémově specifických ansaetze.

Parametrizované kvantové Circuit

Variační algoritmy fungují tak, že prochází a porovnávají řadu kvantových stavů ψ(θ)|\psi(\vec{\theta})\rangle, které závisí na konečné množině kk parametrů θ=(θ0,,θk1)\vec{\theta} = (\theta^0, \ldots, \theta^{k-1}). Tyto stavy lze připravit pomocí parametrizovaného kvantového Circuit, kde jsou Gate definovány s nastavitelnými parametry. Parametrizovaný Circuit je možné vytvořit bez navázání konkrétních úhlů:

# 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")

Výstup předchozí buňky kódu

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"))

Výstup předchozí buňky kódu

Výstup předchozí buňky kódu

Variační forma a Ansatz

Abychom mohli iterativně optimalizovat z referenčního stavu ρ|\rho\rangle na cílový stav ψ(θ)|\psi(\vec\theta)\rangle, potřebujeme definovat variační formu UV(θ)U_V(\vec{\theta}), která představuje kolekci parametrizovaných stavů pro náš variační algoritmus:

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}

Všimni si, že parametrizovaný stav závisí jak na referenčním stavu ρ|\rho\rangle, který na žádných parametrech nezávisí, tak na variační formě UV(θ)U_V(\vec{\theta}), která na parametrech vždy závisí. Kombinaci těchto dvou polovin označujeme jako ansatz: UA(θ):=UV(θ)URU_A(\vec\theta) := U_V(\vec\theta)U_R.

Při sestavování ansatzu, který má představovat kolekci parametrizovaných stavů pro náš variační algoritmus, narážíme na důležitý problém: dimenzionalitu. Systém s nn Qubit (tj. Hilbertův prostor) obsahuje obrovské množství různých kvantových stavů v konfiguračním prostoru. K jeho úplnému prozkoumání bychom potřebovali nezvladatelné množství parametrů. Kvantitativně je jeho dimenzionalita D=22nD = 2^{2n}. Situaci dále zhoršuje skutečnost, že časová složitost vyhledávacích algoritmů a podobných metod roste s touto dimenzionalitou exponenciálně — jev v literatuře často označovaný jako prokletí dimenzionality.

Aby se tomuto problému čelilo, je běžnou praxí uložit na variační formu rozumná omezení tak, aby byly prozkoumány pouze nejrelevantnější stavy. Nalezení efektivního zkráceného ansatzu je aktivní oblastí výzkumu, ale probereme dva běžné návrhy.

Heuristické ansaetze a kompromisy

Pokud o svém konkrétním problému nemáš žádné informace, které by ti pomohly omezit dimenzionalitu, můžeš zkusit libovolnou rodinu parametrizovaných Circuit s méně než 22n2^{2n} parametry. Existují však určité kompromisy:

  • Rychlost: Zmenšením prostoru prohledávání může algoritmus běžet rychleji.
  • Přesnost: Zmenšení prostoru může vést k vyloučení skutečného řešení problému a k suboptimálním výsledkům.
  • Šum: Hlubší Circuit jsou náchylnější k šumu, takže je třeba experimentovat s konektivitou ansatzu, Gate a věrností Gate.

Existuje zásadní kompromis mezi kvalitou (nebo vůbec řešitelností) a rychlostí: čím více parametrů, tím pravděpodobnější je nalezení přesného výsledku, ale tím déle algoritmus poběží.

N-lokální Circuit

Jedním z nejpoužívanějších příkladů heuristických ansaetze jsou N-lokální Circuit, a to z několika důvodů:

  • Efektivní implementace: N-lokální ansatz se obvykle skládá z jednoduchých, lokálních Gate, které lze efektivně implementovat na kvantovém počítači s malým počtem fyzických Qubit. To usnadňuje sestavování a optimalizaci kvantových Circuit.
  • Zachycuje důležité korelace: N-lokální ansatz dokáže zachytit důležité korelace mezi Qubit v kvantovém systému i s malým počtem Gate. Lokální Gate totiž mohou působit na sousední Qubit a vytvářet mezi nimi provázanost, která může být klíčová při simulaci složitých kvantových systémů.

Tyto Circuit se skládají z rotačních a provazovacích vrstev, které se střídavě opakují jednou nebo vícekrát, a to následovně:

  • Každá vrstva je tvořena Gate o velikosti nejvýše NN, kde NN musí být menší než počet Qubit.
  • Pro rotační vrstvu jsou Gate naskládány na sebe. Lze použít standardní rotační operace, například RX nebo CRZ.
  • Pro provazovací vrstvu lze použít Gate jako Toffoli Gate nebo CX se strategií provazování.
  • Oba typy vrstev mohou, ale nemusí být parametrizovány, přičemž alespoň jedna z nich musí parametry obsahovat. Jinak by bez alespoň jednoho parametru neexistovaly žádné variace!
  • Volitelně se na konec Circuit přidá dodatečná rotační vrstva.

Vytvoříme například pětiqubitový NLocal Circuit s rotačními bloky tvořenými Gate RX a CRZ, provazovacími bloky tvořenými Toffoli Gate působícími na Qubit [0,1,2][0,1,2], [0,2,3][0,2,3], [4,2,1][4,2,1] a [3,1,0][3,1,0] a 22 opakováními každé vrstvy.

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")

Výstup předchozí buňky kódu

Ve výše uvedeném příkladu je největší Gate Toffoliho Gate, která působí na tři Qubit, takže Circuit je 33-lokální. Nejpoužívanějším typem NN-lokálních Circuit jsou 22-lokální Circuit s jednoqubitovými rotačními Gate a 22-qubitovými provazovacími Gate.

Vytvoříme 22-lokální Circuit pomocí třídy TwoLocal z Qiskitu. Syntaxe je stejná jako u NLocal, ale jsou zde jisté rozdíly. Například většinu Gate, jako RX, RZ a CNOT, lze předat jako řetězce bez importování Gate nebo vytváření instance 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")

Výstup předchozí buňky kódu

V tomto případě jsme použili lineární distribuci provazování, kde je každý Qubit propojen s následujícím. Další strategie najdeš v dokumentaci TwoLocal.

Efficient SU2

efficient_su2 je hardwarově efektivní Circuit sestávající z vrstev jednoqubitových operací pokrývajících SU(2) a provazovacích CX. Jedná se o heuristický vzor, který lze použít k přípravě zkušebních vlnových funkcí pro variační kvantové algoritmy nebo jako klasifikační Circuit pro strojové učení.

from qiskit.circuit.library import efficient_su2

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

Výstup předchozí buňky kódu

Problémově specifické ansaetze

Zatímco heuristické a hardwarově efektivní ansaetze nám pomáhají řešit problém naivním způsobem, můžeme využít znalosti specifické pro daný problém k omezení prostoru prohledávání Circuit na konkrétní typ. To nám pomůže získat rychlost, aniž bychom při prohledávání ztratili přesnost.

Optimalizace

V problému max-cut chceme rozdělit uzly grafu tak, abychom maximalizovali počet hran mezi uzly v různých skupinách. Požadované rozdělení max-cut pro níže uvedený graf je zřejmé: 0. uzel vlevo by měl být oddělen od ostatních uzlů vpravo řezem.

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"
)

Výstup předchozí buňky kódu

K využití algoritmu QAOA pro problém max-cut potřebujeme Pauliho Hamiltonian, který kóduje náklady tak, aby minimální střední hodnota operátoru odpovídala maximálnímu počtu hran mezi uzly ve dvou různých skupinách.

V tomto jednoduchém příkladu je operátor lineární kombinací členů se Z operátory na uzlech propojených hranou (připomeň si, že 0. Qubit je nejvíce vpravo): ZZII+IZZI+ZIIZ+IZIZ+IIZZZZII + IZZI + ZIIZ + IZIZ + IIZZ. Po sestavení operátoru lze ansatz pro algoritmus QAOA snadno vytvořit pomocí Circuit QAOAAnsatz z knihovny Qiskit circuit library.

# 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")

Výstup předchozí buňky kódu

Předchozí obrázek znázorňuje ansatz v základních Gate pro přehlednost. Lze jej však vyjádřit na více úrovních dekompozice změnou argumentu reps nebo vykreslením Circuit bez metody decompose. Například následující reprezentace přímo zobrazuje strukturu QAOA s výchozí hodnotou reps, tedy reps=1.

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

Výstup předchozí buňky kódu

Kvantové strojové učení

Ve strojovém učení je běžnou aplikací klasifikace dat do dvou nebo více kategorií. To zahrnuje kódování datového bodu do příznakové mapy, která mapuje klasické příznakové vektory do kvantového Hilbertova prostoru. Sestavování kvantových příznakových map na základě parametrizovaných kvantových Circuit, které jsou klasicky obtížně simulovatelné, je důležitým krokem k získání potenciální výhody oproti klasickým přístupům strojového učení a je aktivní oblastí aktuálního výzkumu.

zz_feature_map lze použít k vytvoření parametrizovaného Circuit. Lze do něj předat datové body příznakové mapě (xx) a samostatnou variační formu pro předání vah jako parametrů (θ\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")

Výstup předchozí buňky kódu

Shrnutí

V této lekci ses naučil/a, jak definovat prostor prohledávání pomocí variační formy:

  • Příprava stavů s parametrizovaným kvantovým Circuit, kde jsou Gate definovány s nastavitelnými parametry
  • Jak sestavit ansaetze s kompromisem mezi rychlostí a přesností
  • Heuristické ansaetze
  • Problémově specifické ansaetze

Náš vysokoúrovňový variační pracovní postup vypadá takto:

Diagram Circuit zobrazující dvě unitární operace: jednu připravující referenční stav a druhou připravující ansatz.

Pro každý variační parametr θ\vec\theta bude produkován jiný kvantový stav. Abychom našli optimální parametry, musíme definovat problémově specifickou nákladovou funkci pro iterativní aktualizaci parametrů našeho ansatzu.