Przejdź do głównej treści

Ansaetze and variational forms

U podstaw wszystkich algorytmów wariacyjnych leży kluczowa idea analizowania różnic między stanami, które są wygodnie powiązane za pomocą pewnego dobrze zachowującego się odwzorowania (na przykład ciągłego, różniczkowalnego) ze zbioru parametrów lub zmiennych — stąd nazwa.

Na początku przyjrzymy się, jak ręcznie konstruować sparametryzowane obwody. Użyjemy tych obwodów do zdefiniowania variational form, która reprezentuje kolekcję sparametryzowanych stanów do eksploracji przez nasz algorytm wariacyjny. Następnie skonstruujemy nasz ansatz, stosując tę variational form do naszego stanu referencyjnego.

Zbadamy też, jak wyważyć szybkość i dokładność podczas eksploracji tej przestrzeni poszukiwań.

Diagram przedstawiający kluczowe składniki omówienia ansatzu, w tym heurystyczne ansaetze i ansaetze specyficzne dla problemu.

Parameterized Quantum Circuits

Algorytmy wariacyjne działają poprzez eksplorowanie i porównywanie szeregu stanów kwantowych ψ(θ)|\psi(\vec{\theta})\rangle, które zależą od skończonego zbioru kk parametrów θ=(θ0,,θk1)\vec{\theta} = (\theta^0, \ldots, \theta^{k-1}). Stany te można przygotować za pomocą sparametryzowanego obwodu kwantowego (PQC), w którym bramki są definiowane z regulowanymi parametrami. Możliwe jest utworzenie takiego sparametryzowanego obwodu bez wcześniejszego przypisywania konkretnych kątów:

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

Output of the previous code cell

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

Output of the previous code cell

Output of the previous code cell

Variational Form and Ansatz

Aby iteracyjnie optymalizować od stanu referencyjnego ρ|\rho\rangle do stanu docelowego ψ(θ)|\psi(\vec\theta)\rangle, musimy zdefiniować variational form UV(θ)U_V(\vec{\theta}), która reprezentuje kolekcję sparametryzowanych stanów do eksploracji przez nasz algorytm wariacyjny:

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}

Zauważ, że sparametryzowany stan zależy zarówno od stanu referencyjnego ρ|\rho\rangle, który nie zależy od żadnych parametrów, jak i od variational form UV(θ)U_V(\vec{\theta}), która zawsze zależy od parametrów. Kombinację tych dwóch części nazywamy ansatzem: UA(θ):=UV(θ)URU_A(\vec\theta) := U_V(\vec\theta)U_R.

Konstruując nasz ansatz tak, aby reprezentował kolekcję sparametryzowanych stanów do eksploracji przez algorytm wariacyjny, napotykamy istotny problem: wymiarowość. System nn-qubitowy (czyli przestrzeń Hilberta) zawiera ogromną liczbę różnych stanów kwantowych w przestrzeni konfiguracyjnej. Do jej pełnej eksploracji potrzebowalibyśmy nieporęcznie dużej liczby parametrów. Ilościowo wymiarowość wynosi D=22nD = 2^{2n}. Co gorsza, złożoność obliczeniowa algorytmów przeszukiwania i podobnych rośnie wykładniczo wraz z tą wymiarowością — zjawisko to często określa się w literaturze mianem przekleństwa wymiarowości.

Aby zaradzić temu problemowi, powszechną praktyką jest nakładanie rozsądnych ograniczeń na variational form tak, aby eksplorować tylko najbardziej istotne stany. Znalezienie efektywnego obciętego ansatzu jest aktywnym obszarem badań, ale omówimy dwa popularne podejścia.

Heuristic ansaetze and trade-offs

Jeśli nie masz żadnych informacji o swoim konkretnym problemie, które mogłyby pomóc ograniczyć wymiarowość, możesz wypróbować dowolną rodzinę sparametryzowanych obwodów z liczbą parametrów mniejszą niż 22n2^{2n}. Należy jednak wziąć pod uwagę pewne kompromisy:

  • Szybkość: Zmniejszając przestrzeń poszukiwań, algorytm może działać szybciej.
  • Dokładność: Zawężenie przestrzeni może skutkować wykluczeniem rzeczywistego rozwiązania problemu, prowadząc do suboptymalnych wyników.
  • Szumy: Głębsze Circuit są bardziej podatne na szumy, dlatego musimy eksperymentować z połączeniami, bramkami i wiernością bramek naszego ansatzu.

Istnieje fundamentalny kompromis między jakością (a nawet wykonalnością) a szybkością: im więcej parametrów, tym większe prawdopodobieństwo uzyskania dokładnego wyniku, ale tym dłużej będzie działał algorytm.

N-local circuits

Jednym z najszerzej stosowanych przykładów heurystycznych ansaetze są N-local circuits, i to z kilku powodów:

  • Efektywna implementacja: Ansatz N-lokalny składa się zazwyczaj z prostych, lokalnych bramek, które można efektywnie zaimplementować na komputerze kwantowym, wykorzystując niewielką liczbę fizycznych qubitów. Ułatwia to konstruowanie i optymalizację Circuit kwantowych.
  • Uchwytuje istotne korelacje: Ansatz N-lokalny potrafi uchwycić ważne korelacje między qubitami w układzie kwantowym, nawet przy małej liczbie bramek. Wynika to z faktu, że lokalne bramki mogą działać na sąsiadujących qubitach i tworzyć między nimi splątanie, co może być istotne przy symulowaniu złożonych układów kwantowych.

Obwody te składają się z naprzemiennie powtarzanych (jeden lub więcej razy) warstw rotacji i warstw splątania:

  • Każda warstwa jest tworzona przez bramki o rozmiarze co najwyżej NN, gdzie NN musi być mniejsze od liczby qubitów.
  • W warstwie rotacji bramki są układane jedna na drugiej. Można używać standardowych operacji rotacji, takich jak RX lub CRZ.
  • W warstwie splątania można używać bramek takich jak bramki Toffoli lub CX ze strategią splątania.
  • Oba typy warstw mogą być sparametryzowane lub nie, ale co najmniej jedna z nich musi zawierać parametry. W przeciwnym razie bez choćby jednego parametru nie byłoby żadnych wariacji!
  • Opcjonalnie na końcu obwodu dodaje się dodatkową warstwę rotacji.

Na przykład utwórzmy pięcio-qubitowy obwód NLocal z blokami rotacji złożonymi z bramek RX i CRZ, blokami splątania złożonymi z bramek Toffoli działających na qubitach [0,1,2][0,1,2], [0,2,3][0,2,3], [4,2,1][4,2,1] i [3,1,0][3,1,0] oraz 22 powtórzeniami każdej warstwy.

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

Output of the previous code cell

W powyższym przykładzie największą bramką jest bramka Toffoli działająca na trzech qubitach, co czyni obwód 33-lokalnym. Najczęściej stosowanym typem obwodów NN-lokalnych są obwody 22-lokalne z jednokubitowymi bramkami rotacji i 22-kubitowymi bramkami splątania.

Utwórzmy obwód 22-lokalny, korzystając z klasy TwoLocal w Qiskit. Składnia jest taka sama jak w NLocal, ale istnieją pewne różnice. Na przykład większość bramek, takich jak RX, RZ i CNOT, można przekazywać jako łańcuchy znaków bez importowania bramek ani tworzenia instancji 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")

Output of the previous code cell

W tym przypadku użyliśmy liniowego rozkładu splątania, w którym każdy qubit jest splątany z następnym. Aby dowiedzieć się więcej o innych strategiach, zajrzyj do dokumentacji TwoLocal.

Efficient SU2

efficient_su2 to hardware-efficient Circuit składający się z warstw jednokubitowych operacji obejmujących SU(2) oraz splątań CX. Jest to heurystyczny wzorzec, który można wykorzystać do przygotowywania próbnych funkcji falowych dla wariacyjnych algorytmów kwantowych lub jako Circuit klasyfikacyjny w uczeniu maszynowym.

from qiskit.circuit.library import efficient_su2

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

Output of the previous code cell

Ansaetze specyficzne dla problemu

Podczas gdy heurystyczne i sprzętowo wydajne ansaetze pomagają nam rozwiązać problem w naiwny sposób, możemy wykorzystać wiedzę specyficzną dla danego problemu, aby zawęzić przestrzeń przeszukiwania Circuit do konkretnego typu. Pozwoli nam to zyskać na szybkości bez utraty dokładności w procesie przeszukiwania.

Optymalizacja

W problemie max-cut chcemy podzielić węzły grafu w taki sposób, aby zmaksymalizować liczbę krawędzi między węzłami należącymi do różnych grup. Pożądany podział max-cut dla poniższego grafu jest oczywisty: węzeł 0. po lewej stronie powinien zostać oddzielony od pozostałych węzłów po prawej stronie cięciem.

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

Wynik poprzedniej komórki kodu

Aby wykorzystać algorytm QAOA do rozwiązania problemu max-cut, potrzebujemy Hamiltonianu Pauliego, który koduje koszt w taki sposób, że minimalna wartość oczekiwana operatora odpowiada maksymalnej liczbie krawędzi między węzłami należącymi do dwóch różnych grup.

W tym prostym przykładzie operator jest liniową kombinacją wyrazów z operatorami Z na węzłach połączonych krawędzią (pamiętaj, że 0. qubit jest najbardziej po prawej): ZZII+IZZI+ZIIZ+IZIZ+IIZZZZII + IZZI + ZIIZ + IZIZ + IIZZ. Po skonstruowaniu operatora ansatz dla algorytmu QAOA można łatwo zbudować za pomocą Circuit QAOAAnsatz z biblioteki Circuit Qiskit.

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

Wynik poprzedniej komórki kodu

Poprzedni obraz przedstawia ansatz w podstawowych Gate'ach dla większej przejrzystości. Można go jednak wyrazić na wielu poziomach dekompozycji, zmieniając argument reps lub rysując Circuit bez metody decompose. Na przykład poniższa reprezentacja bezpośrednio pokazuje strukturę QAOA z domyślną wartością reps, czyli reps=1.

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

Wynik poprzedniej komórki kodu

Kwantowe uczenie maszynowe

W uczeniu maszynowym powszechnym zastosowaniem jest klasyfikacja danych do dwóch lub więcej kategorii. Polega to na zakodowaniu punktu danych w feature map, która odwzorowuje klasyczne wektory cech w kwantową przestrzeń Hilberta. Konstruowanie kwantowych feature map opartych na parametryzowanych Circuit kwantowych, które są trudne do symulacji klasycznie, jest ważnym krokiem w kierunku uzyskania potencjalnej przewagi nad klasycznymi metodami uczenia maszynowego i stanowi aktywny obszar bieżących badań.

zz_feature_map może być używany do tworzenia parametryzowanego Circuit. Możemy przekazać nasze punkty danych do feature map (xx) oraz oddzielną formę wariacyjną, aby przekazać wagi jako parametry (θ\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")

Wynik poprzedniej komórki kodu

Podsumowanie

Dzięki tej lekcji nauczyłeś się, jak definiować przestrzeń przeszukiwania za pomocą formy wariacyjnej:

  • Przygotowywać stany za pomocą parametryzowanego Circuit kwantowego, w którym Gate'y są zdefiniowane z przestrajalnymi parametrami
  • Jak konstruować ansaetze z kompromisem między szybkością a dokładnością
  • Heurystyczne ansaetze
  • Ansaetze specyficzne dla problemu

Nasz ogólny wariant wariacyjny wygląda następująco:

Diagram Circuit przedstawiający dwa operatory unitarne: jeden przygotowujący stan referencyjny i drugi przygotowujący ansatz.

Dla każdego parametru wariacyjnego θ\vec\theta powstanie inny stan kwantowy. Aby znaleźć optymalne parametry, musimy zdefiniować funkcję kosztu zależną od problemu, która iteracyjnie aktualizuje parametry naszego ansatzu.