Approches et formes variationnelles
Au cœur de tous les algorithmes variationnels se trouve l'idée clé d'analyser les différences entre les états, qui sont commodément liés par une cartographie bien conçue (par exemple, continue, différentiable) à partir d'un ensemble de paramètres ou de variables - d'où le nom.
Tout d'abord, nous verrons comment construire des circuits paramétrés à la main. Nous utiliserons ces circuits pour définir un site Couches de portes paramétrées qui sont répétées un certain nombre de fois et dont les paramètres sont optimisés au cours de l'algorithme pour minimiser la fonction de coût. qui représente une collection d'états paramétrés à explorer par notre algorithme variationnel. Ensuite, nous construirons notre site Combinaison d'un opérateur de référence et d'une forme variationnelle, pour décrire l'espace de recherche que nous explorons. en appliquant cette forme variationnelle à notre état de référence.
Nous verrons également comment arbitrer entre vitesse et précision lors de l'exploration de cet espace de recherche.
Circuits quantiques paramétrés
Les algorithmes variationnels fonctionnent en explorant et en comparant une gamme d'états quantiques , qui dépendent d'un ensemble fini de paramètres . Ces états peuvent être préparés à l'aide d'un circuit quantique paramétré, où les portes sont définies avec des paramètres accordables. Il est possible de créer ce circuit paramétré sans lier des angles spécifiques pour l'instant :
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:
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:
Forme variationnelle et Ansatz
Pour optimiser de manière itérative à partir d'un état de référence vers un état cible , nous devons définir une forme variationnelle qui représente une collection d'états paramétrés que notre algorithme variationnel doit explorer :
Notez que l'état paramétré dépend à la fois de l'état de référence , qui ne dépend d'aucun paramètre, et de la forme variationnelle , qui dépend toujours de paramètres. Nous appelons la combinaison de ces deux moitiés un ansatz : .
Alors que nous construisons notre ansatz pour représenter une collection d'états paramétrés à explorer par notre algorithme variationnel, nous nous rendons compte d'un problème important : la dimensionnalité. Un système -qubit (c'est-à-dire un espace de Hilbert) possède un grand nombre d'états quantiques distincts dans l'espace de configuration. Nous aurions besoin d'un nombre considérable de paramètres pour l'explorer pleinement. D'un point de vue quantitatif, sa dimensionnalité est . Pour aggraver les choses, la complexité d'exécution des algorithmes de recherche, et d'autres, croît de manière exponentielle avec cette dimensionnalité, un phénomène souvent désigné dans la littérature comme la malédiction de la dimensionnalité.
Pour pallier cet inconvénient, il est courant d'imposer des contraintes raisonnables sur la forme variationnelle, de sorte que seuls les états les plus pertinents soient explorés. La recherche d'un ansatz tronqué efficace est un domaine de recherche actif, mais nous couvrirons deux modèles courants.
Approches heuristiques et compromis
Si vous ne disposez d'aucune information sur votre problème particulier permettant de limiter la dimensionnalité, vous pouvez essayer une famille arbitraire de circuits paramétrés comportant moins de paramètres. Cependant, il y a des compromis à prendre en compte :
- Vitesse : en réduisant l'espace de recherche, l'algorithme peut fonctionner plus rapidement.
- Précision : En réduisant l'espace, on risque d'exclure la solution réelle du problème, ce qui conduit à des solutions sous-optimales.
- Le bruit : Les circuits plus profonds sont affectés par le bruit, et nous devons donc expérimenter la connectivité, les portes et la fidélité des portes de notre ansatz.
Il existe un compromis fondamental entre la qualité (ou même la solvabilité) et la rapidité : plus il y a de paramètres, plus vous avez de chances d'obtenir un résultat précis, mais plus l'exécution de l'algorithme prendra de temps.
Circuits N-locaux
L'un des exemples les plus répandus de réponses heuristiques est celui des circuits N-locaux, et ce pour plusieurs raisons :
- Mise en œuvre efficace : L'ansatz N-local est généralement composé de portes locales simples qui peuvent être mises en œuvre efficacement sur un ordinateur quantique, en utilisant un petit nombre de qubits physiques. Cela facilite la construction et l'optimisation des circuits quantiques.
- Capture des corrélations importantes : L'ansatz N-local peut capturer des corrélations importantes entre les qubits d'un système quantique, même avec un petit nombre de portes. En effet, les portes locales peuvent agir sur les qubits voisins et créer un enchevêtrement entre eux, ce qui peut être important pour simuler des systèmes quantiques complexes.
Ces circuits sont constitués de couches de rotation et d'enchevêtrement qui sont répétées alternativement une ou plusieurs fois comme suit :
- Chaque couche est constituée de portes d'une taille maximale de , où doit être inférieur au nombre de qubits.
- Pour une couche de rotation, les portes sont empilées les unes sur les autres. Nous pouvons utiliser des opérations de rotation standard, telles que
RXouCRZ. - Pour une couche d'intrication, nous pouvons utiliser des portes comme
Toffoliportes ouCXavec une stratégie d'enchevêtrement. - Les deux types de couches peuvent être paramétrés ou non, mais au moins l'une d'entre elles doit contenir des paramètres. Sinon, sans au moins un paramètre, il n'y aurait pas de variations!
- En option, une couche de rotation supplémentaire est ajoutée à la fin du circuit.
Par exemple, créons un circuit de cinq qubits NLocal avec des blocs de rotation formés par RX et CRZ des blocs d'intrication formés par des portes Toffoli qui agissent sur les qubits , , et et des répétitions de chaque couche.
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:
Dans l'exemple ci-dessus, la plus grande porte est la porte de Toffoli, qui agit sur trois qubits, ce qui rend le circuit -local. Le type de circuits -locaux le plus couramment utilisé est -local avec des portes de rotation à qubit unique et -qubit entanglement gates.
Créons un circuit -local en utilisant la classe Qiskit TwoLocal de Qiskit. La syntaxe est la même que celle de NLocal, mais il y a quelques différences. Par exemple, la plupart des portes, telles que RX, RZ, et CNOT, peuvent être transmises sous forme de chaînes de caractères sans importer les portes ou créer une 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")Output:
Dans ce cas, nous avons utilisé la distribution d'intrication linéaire, où chaque qubit est intriqué avec le suivant. Pour en savoir plus sur les autres stratégies, consultez la documentation de TwoLocal .
SU2 efficace
efficient_su2 est un circuit efficace sur le plan matériel qui consiste en des couches d'opérations à qubit unique couvrant SU(2) et CX enchevêtrements. Il s'agit d'un modèle heuristique qui peut être utilisé pour préparer des fonctions d'onde d'essai pour les algorithmes quantiques variationnels ou comme circuit de classification pour l'apprentissage automatique.
from qiskit.circuit.library import efficient_su2
ansatz = efficient_su2(4, su2_gates=["rx", "y"], entanglement="linear", reps=1)
ansatz.decompose().draw("mpl")Output:
Approches spécifiques au problème
Alors que les réponses heuristiques et matérielles efficaces nous aident à résoudre un problème de manière naïve, nous pouvons utiliser des connaissances spécifiques au problème pour restreindre l'espace de recherche de notre circuit à un type spécifique. Cela nous permettra de gagner en rapidité sans perdre en précision dans notre processus de recherche.
Optimisation
Dans un problème de coupe maximale, nous voulons partitionner les nœuds d'un graphe de manière à maximiser le nombre d'arêtes entre les nœuds de groupes différents. La partition max-cut souhaitée pour le graphe ci-dessous est claire : le 0e nœud à gauche doit être séparé du reste des nœuds à droite par une coupure.
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"
)Output:
Pour utiliser l'algorithme QAOA pour un problème de coupe maximale, nous avons besoin d'un hamiltonien de Pauli qui code le coût de manière à ce que la valeur d'espérance minimale de l'opérateur corresponde au nombre maximal d'arêtes entre les nœuds de deux groupes différents.
Pour cet exemple simple, l'opérateur est une combinaison linéaire de termes avec des opérateurs Z sur des nœuds reliés par une arête (rappelons que le 0e qubit est le plus à droite) : . Une fois l'opérateur construit, l'ansatz pour l'algorithme QAOA peut facilement être construit en utilisant le circuit QAOAAnsatz de la bibliothèque de circuits 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")Output:
L'image précédente illustre l'ansatz en portes de base pour plus de clarté. Cependant, il peut être exprimé en plusieurs niveaux de décomposition en changeant l'argument reps ou en dessinant le circuit sans la méthode de décomposition. Par exemple, la représentation suivante montre directement la structure du QAOA avec la valeur par défaut des reps, qui est reps=1.
ansatz.decompose(reps=2).draw("mpl")Output:
Apprentissage automatique quantique
Dans le domaine de l'apprentissage automatique, une application courante est la classification des données en deux catégories ou plus. Il s'agit d'encoder un point de données dans une carte de caractéristiques qui fait correspondre des vecteurs de caractéristiques classiques à l'espace de Hilbert quantique. La construction de cartes de caractéristiques quantiques basées sur des circuits quantiques paramétrés qui sont difficiles à simuler classiquement est une étape importante vers l'obtention d'un avantage potentiel sur les approches classiques d'apprentissage automatique et constitue un domaine actif de la recherche actuelle.
Le site zz_feature_map peut être utilisé pour créer un circuit paramétré. Nous pouvons transmettre nos points de données à la carte de caractéristiques ( ) et une forme variationnelle distincte pour transmettre les poids en tant que paramètres ( ).
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")Output:
Récapitulatif
Cette leçon vous a appris à définir votre espace de recherche à l'aide d'une forme variationnelle :
- Préparer des états avec un circuit quantique paramétré, où les portes sont définies avec des paramètres accordables
- Comment construire des réponses qui permettent de trouver un compromis entre vitesse et précision?
- Réponses heuristiques
- Réponses spécifiques aux problèmes
Notre charge de travail variationnelle de haut niveau se présente comme suit :
Pour chaque paramètre variationnel , un état quantique différent sera produit. Pour trouver les paramètres optimaux, nous devons définir une fonction de coût spécifique au problème pour mettre à jour de manière itérative les paramètres de notre ansatz.