[PYTHON] Qiskit: Implementierung von Quantum Circuit Learning (QCL)

Quantum Circuit Learning

Quantum Circuit Learning (QCL) ist ein Algorithmus zum Anwenden von Quantencomputern auf maschinelles Lernen. Es wurde für den Betrieb auf dem mittelgroßen Quantencomputer NISQ entwickelt, der keine Fehlerkorrekturfunktion hat.

Referenz: Quantum Circuit Learning

Implementierung

Da die Implementierung von Grund auf schwierig ist, implementieren Sie sie mit qiskit, während Sie auf den qulacs-Code in Quantum Native Dojo verweisen. Es ist.

vollständiger Code

python


# coding : utf-8

import numpy as np
import matplotlib.pyplot as plt
from functools import reduce
from scipy.optimize import minimize
import time

from qiskit import QuantumRegister, QuantumCircuit, ClassicalRegister, execute
from qiskit.quantum_info.analysis import average_data
from qiskit import BasicAer
from qiskit.quantum_info.operators import Operator
from qiskit.aqua.utils import tensorproduct


I_mat = np.array([[1, 0], [0, 1]])
X_mat = np.array([[0, 1], [1, 0]])
Z_mat = np.array([[1, 0], [0, -1]])


def classical_minimize(cost_func, theta_init, method='Nelder-Mead'):
    print('Do classical_minimize !')
    start_time = time.time()
    result = minimize(cost_func, theta_init, method=method)
    print('runnning time; {}'.format(time.time() - start_time))
    print('opt_cost: {}'.format(result.fun))
    theta_opt = result.x
    return theta_opt


class SimpleQuantumCircuitLearning:


    def __init__(self, nqubit, func=lambda x: np.sin(x*np.pi), num_x_train=50, c_depth=3, time_step=0.77):
        self.nqubit = nqubit
        self.func_to_learn = func
        self.num_x_train = num_x_train
        self.c_depth = c_depth
        self.time_step = time_step
        self.x_train = None
        self.y_train = None
        self.InitialTheta = None
        self.time_evol_gate = None

    def initialize(self):
        random_seed = 0
        np.random.seed(random_seed)
        x_min = -1.
        x_max = 1.
        self.x_train = x_min + (x_max - x_min) * np.random.rand(self.num_x_train)
        self.y_train = self.func_to_learn(self.x_train)

    def add_noise(self, mag_noise=0.05):
        self.y_train = self.y_train + mag_noise * np.random.rand(self.num_x_train)

    def input_encode(self, x) -> QuantumCircuit:
        qr = QuantumRegister(self.nqubit)
        cr = ClassicalRegister(self.nqubit)
        qc = QuantumCircuit(qr, cr)
        angle_y = np.arcsin(x)
        angle_z = np.arccos(x ** 2)
        for i in range(self.nqubit):
            qc.ry(angle_y, i)
            qc.rz(angle_z, i)
        return qc

    def make_fullgate(self, list_SiteAndOperator):
        list_Site = [SiteAndOperator[0] for SiteAndOperator in list_SiteAndOperator]
        list_SingleGates = []
        cnt = 0
        for i in range(self.nqubit):
            if i in list_Site:
                list_SingleGates.append(list_SiteAndOperator[cnt][1])
                cnt += 1
            else:
                list_SingleGates.append(I_mat)
        return reduce(np.kron, list_SingleGates)

    def hamiltonian(self, time_step):
        ham = np.zeros((2**self.nqubit, 2**self.nqubit), dtype=complex)
        for i in range(self.nqubit):
            Jx = -1. + 2. * np.random.rand()
            ham += Jx * self.make_fullgate([[i, X_mat]])
            for j in range(i+1, self.nqubit):
                J_ij = -1. + 2. * np.random.rand()
                ham += J_ij * self.make_fullgate([[i, Z_mat], [j, Z_mat]])
        diag, eigen_vecs = np.linalg.eigh(ham)
        time_evol_op = np.dot(np.dot(eigen_vecs, np.diag(np.exp(-1j*time_step*diag))), eigen_vecs.T.conj())
        self.time_evol_gate = Operator(time_evol_op)

    def initial_theta(self):
        np.random.seed(9999)
        theta = np.array([2*np.pi*np.random.rand() for i in range(3 * self.nqubit * self.c_depth)])
        return theta

    def U_out(self, qc, theta):
        qc.unitary(self.time_evol_gate, range(self.nqubit), label='time_evol_gate')
        theta = np.reshape(theta, (3, self.nqubit, self.c_depth))
        for depth in range(self.c_depth):
            for q1 in range(self.nqubit):
                qc.rx(theta[depth][q1][0], q1)
                qc.rz(theta[depth][q1][1], q1)
                qc.rx(theta[depth][q1][2], q1)
        return qc

    def Z0(self):
        tensor = Z_mat
        for i in range(1, self.nqubit):
            tensor = tensorproduct(tensor, I_mat)
        return tensor

    def run_circuit(self, qc):
        NUM_SHOTS = 10000
        seed = 1234
        backend = BasicAer.get_backend('qasm_simulator')
        qc.measure(range(self.nqubit), range(self.nqubit))
        results = execute(qc, backend, shots=NUM_SHOTS, seed_simulator=seed).result()
        return results.get_counts(qc)

    def qcl_pred(self, x, theta):
        qc = self.input_encode(x)
        qc = self.U_out(qc, theta)
        counts = self.run_circuit(qc)
        expectation = average_data(counts, self.Z0())
        return expectation

    def cost_func(self, theta):
        y_pred = [self.qcl_pred(x, theta) for x in self.x_train]
        L = ((y_pred - self.y_train)**2).mean()
        return L

    def minim(self, InitialTheta):
        theta_opt = classical_minimize(self.cost_func, InitialTheta)
        return theta_opt


if __name__ == '__main__':
    x_min = - 1.
    x_max = 1.
    QCL = SimpleQuantumCircuitLearning(nqubit=3)
    QCL.initialize()
    QCL.add_noise(mag_noise=0.05)
    QCL.hamiltonian(time_step=0.77)
    initial_theta = QCL.initial_theta()
    initial_cost = QCL.cost_func(initial_theta)
    ##########################################################
    x_min = - 1.
    x_max = 1.
    xlist = np.arange(x_min, x_max, 0.02)
    y_init = [QCL.qcl_pred(x, initial_theta) for x in xlist]
    plt.plot(xlist, y_init)
    plt.show()
    ##########################################################
    print('initial_cost: {}'.format(initial_cost))
    theta_opt = QCL.minim(initial_theta)
    plt.figure(figsize=(10, 6))
    plt.plot(QCL.x_train, QCL.y_train, "o", label='Teacher')
    plt.plot(xlist, y_init, '--', label='Initial Model Prediction', c='gray')
    y_pred = np.array([QCL.qcl_pred(x, theta_opt) for x in xlist])
    plt.plot(xlist, y_pred, label='Final Model Prediction')
    plt.legend()
    plt.show()

Grundeinstellung

python


    def __init__(self, nqubit, func=lambda x: np.sin(x*np.pi), num_x_train=50, c_depth=3, time_step=0.77):
        self.nqubit = nqubit
        self.func_to_learn = func
        self.num_x_train = num_x_train
        self.c_depth = c_depth
        self.time_step = time_step
        self.x_train = None
        self.y_train = None
        self.InitialTheta = None
        self.time_evol_gate = None
    
    #Trainingsdaten
    def initialize(self):
        random_seed = 0
        np.random.seed(random_seed)
        x_min = -1.
        x_max = 1.
        self.x_train = x_min + (x_max - x_min) * np.random.rand(self.num_x_train)
        self.y_train = self.func_to_learn(self.x_train)

    #Rauschen hinzufügen
    def add_noise(self, mag_noise=0.05):
        self.y_train = self.y_train + mag_noise * np.random.rand(self.num_x_train)

Ergebnis

Die Ausgabe des Ergebnisses ist wie folgt.

initial_cost: 0.20496500050465266
opt_cost: 0.13626398715932975

2020041802.png

Betrachtet man die Ergebnisse, so scheinen die Maximal- und Minimalwerte der endgültigen Modellvorhersage klein zu sein. Dies liegt daran, dass der Wert von verwendet wird.

    def Z0(self):
        tensor = Z_mat
        for i in range(1, self.nqubit):
            tensor = tensorproduct(tensor, I_mat)
        return tensor

Wenn Sie also <2Z> verwenden

    def Z0(self):
        tensor = Z_mat * 2
        for i in range(1, self.nqubit):
            tensor = tensorproduct(tensor, I_mat)
        return tensor

2020041801.png

Und opt_cost

opt_cost: 0.03618545796607254

Und Verbesserung wird gesehen.

Als Ergebnis der Verwendung von <2.5Z> als Test,

2020041803.png

opt_cost: 0.021796774423019367

Zusammenfassung

Grob gesagt habe ich QCL mit Qiskit implementiert. Da sich die Beschreibungsmethode völlig von Qulacs und Blueqat unterscheidet, ist es meiner Meinung nach schwierig, mit der großen Menge an Literatur zu beginnen. Ich hatte übrigens das Gefühl, dass es auch notwendig ist, den Z-Koeffizienten zu optimieren.

Es ist ein ziemlich grober Artikel, aber bitte verzeihen Sie mir, weil er hauptsächlich implementiert ist.

Recommended Posts

Qiskit: Implementierung von Quantum Circuit Learning (QCL)
Qiskit: Implementierung einer Quantenbolzenmaschine
Qiskit: Implementierung von Quantenhypergraphzuständen
Quantum Computer Implementierung von Quantum Walk 2
Quantum Computer Implementierung von Quantum Walk 3
Quantum Computer Implementierung von Quantum Walk 1
Tiefes Lernen der Verstärkung 2 Implementierung des Lernens der Verstärkung
Quantencomputer-Implementierung eines 3-Zustands-Quantenlaufs
Qiskit: Implementierung von QAOA ohne Qiskit Aqua
Othello-Aus der dritten Zeile von "Implementation Deep Learning" (3)
Implementierung eines 3-Schicht-Neuronalen Netzwerks (kein Lernen)
Algorithmus für maschinelles Lernen (Implementierung einer Klassifizierung mit mehreren Klassen)
Othello-Aus der dritten Zeile von "Implementation Deep Learning" (2)
[Lernnotiz] Deep Learning von Grund auf ~ Implementierung von Dropout ~
Implementierung eines Deep Learning-Modells zur Bilderkennung
Tiefes Lernen durch Implementierung (Segmentierung) ~ Implementierung von SegNet ~
Qiskit: Realisierung künstlicher Neuronen mit Quantenschaltungen (Implementierung)
Über das Testen bei der Implementierung von Modellen für maschinelles Lernen
Othello ~ Aus der dritten Zeile von "Implementation Deep Learning" (4) [Ende]
Implementierung des Chainer-Serienlernens mit Mini-Batch variabler Länge
Quantenteleportation mit Qiskit!
Deep Learning 1 Übung des Deep Learning
Implementierung der Fibonacci-Sequenz
Qiskit: Quanten-Fourier-Transformation
[Deep Learning von Grund auf neu] Implementierung der Momentum-Methode und der AdaGrad-Methode
Rank Learning über ein neuronales Netzwerk (RankNet-Implementierung von Chainer)