Grundlegende Klassifizierung: Klassifizieren von Daten mit dem QDK

In dieser Führungslinie erfahren Sie, wie Sie einen Quantum-Sequenzial-Klassifikator ausführen, der in Q# mit der Quantum Machine Learning-Bibliothek des QDK geschrieben wurde. Dazu trainieren wir ein einfaches sequenzielles Modell mit einer in Q# definierten Klassifizierungsstruktur. Das Modell wird mit einem Halbmond-Dataset mit Trainings- und Prüfungsdaten trainiert, die Sie in den Codebeispielen finden. Wir erstellen unser Q# Projekt entweder mit einem Python- oder C#-Programm, um Daten zu laden und Q# Vorgänge abrufen zu können.

Voraussetzungen

dotnet add package Microsoft.Quantum.MachineLearning

Q#-Klassifizierercode

Zunächst erstellen wir eine Datei mit dem Namen Training.qs und fügen ihr den folgenden Code hinzu:

namespace Microsoft.Quantum.Samples {
    open Microsoft.Quantum.Convert;
    open Microsoft.Quantum.Intrinsic;
    open Microsoft.Quantum.Canon;
    open Microsoft.Quantum.Arrays;
    open Microsoft.Quantum.MachineLearning;
    open Microsoft.Quantum.Math;

    function WithProductKernel(scale : Double, sample : Double[]) : Double[] {
        return sample + [scale * Fold(TimesD, 1.0, sample)];
    }

    function Preprocessed(samples : Double[][]) : Double[][] {
        let scale = 1.0;

        return Mapped(
            WithProductKernel(scale, _),
            samples
        );
    }

    function DefaultSchedule(samples : Double[][]) : SamplingSchedule {
        return SamplingSchedule([
            0..Length(samples) - 1
        ]);
    }

    function ClassifierStructure() : ControlledRotation[] {
        return [
            ControlledRotation((0, new Int[0]), PauliX, 4),
            ControlledRotation((0, new Int[0]), PauliZ, 5),
            ControlledRotation((1, new Int[0]), PauliX, 6),
            ControlledRotation((1, new Int[0]), PauliZ, 7),
            ControlledRotation((0, [1]), PauliX, 0),
            ControlledRotation((1, [0]), PauliX, 1),
            ControlledRotation((1, new Int[0]), PauliZ, 2),
            ControlledRotation((1, new Int[0]), PauliX, 3)
        ];
    }

    operation TrainHalfMoonModel(
        trainingVectors : Double[][],
        trainingLabels : Int[],
        initialParameters : Double[][]
    ) : (Double[], Double) {
        let samples = Mapped(
            LabeledSample,
            Zipped(Preprocessed(trainingVectors), trainingLabels)
        );
        Message("Ready to train.");
        let (optimizedModel, nMisses) = TrainSequentialClassifier(
            Mapped(
                SequentialModel(ClassifierStructure(), _, 0.0),
                initialParameters
            ),
            samples,
            DefaultTrainingOptions()
                w/ LearningRate <- 0.1
                w/ MinibatchSize <- 15
                w/ Tolerance <- 0.005
                w/ NMeasurements <- 10000
                w/ MaxEpochs <- 16
                w/ VerboseMessage <- Message,
            DefaultSchedule(trainingVectors),
            DefaultSchedule(trainingVectors)
        );
        Message($"Training complete, found optimal parameters: {optimizedModel::Parameters}");
        return (optimizedModel::Parameters, optimizedModel::Bias);
    }

    operation ValidateHalfMoonModel(
        validationVectors : Double[][],
        validationLabels : Int[],
        parameters : Double[],
        bias : Double
    ) : Double {
        let samples = Mapped(
            LabeledSample,
            Zipped(Preprocessed(validationVectors), validationLabels)
        );
        let tolerance = 0.005;
        let nMeasurements = 10000;
        let results = ValidateSequentialClassifier(
            SequentialModel(ClassifierStructure(), parameters, bias),
            samples,
            tolerance,
            nMeasurements,
            DefaultSchedule(validationVectors)
        );
        return IntAsDouble(results::NMisclassifications) / IntAsDouble(Length(samples));
    }

    operation ClassifyHalfMoonModel(
        samples : Double[][],
        parameters : Double[],
        bias : Double,
        tolerance  : Double,
        nMeasurements : Int
    )
    : Int[] {
        let model = Default<SequentialModel>()
            w/ Structure <- ClassifierStructure()
            w/ Parameters <- parameters
            w/ Bias <- bias;
        let features = Preprocessed(samples);
        let probabilities = EstimateClassificationProbabilities(
            tolerance, model,
            features, nMeasurements
        );
        return InferredLabels(model::Bias, probabilities);
    }

}

Bei den wichtigsten Funktionen und Vorgängen, die im obigen Code definiert sind, handelt es sich um:

  • ClassifierStructure() : ControlledRotation[] : In dieser Funktion legen wir die Struktur unseres Leitungsmodells fest, indem wir die Ebenen der gesteuerten Gates hinzufügen, die wir berücksichtigen. Dieser Schritt entspricht der Deklaration von Neuronenebenen in einem sequenziellen Deep Learning-Modell.
  • TrainHalfMoonModel() : (Double[], Double) : Dieser Vorgang ist der Hauptteil des Codes und definiert das Training. Hier laden wir die Beispiele aus dem in der Bibliothek enthaltenen Dataset, legen die Hyperparameter und die Anfangsparameter für das Training fest und starten das Training, indem wir den in der Bibliothek enthaltenen Vorgang TrainSequentialClassifier aufrufen. Es gibt die Parameter und den Bias aus, die den Klassifikator bestimmen.
  • ValidateHalfMoonModel(parameters : Double[], bias : Double) : Int : Dieser Vorgang definiert den Validierungsprozess zum Bewerten des Modells. Hier laden wir die Proben für die Validierung, die Anzahl der Messungen pro Probe sowie die Toleranz. Es gibt die Anzahl der Fehlklassifizierungen für den gewählten Probenstapel zur Validierung aus.

Hostprogramm

Im nächsten Schritt erstellen wir im gleichen Ordner ein Hostprogramm. Ihr Hostprogramm besteht aus drei Teilen:

  • Laden Sie das Dataset data.json und wählen Sie einen Satz von Klassifiziererparametern aus, in dem Sie Ihre Trainingsiterationen für Ihr Modell starten möchten.

  • Führen Sie das Training aus, um die Parameter und das Bias des Modells zu bestimmen.

  • Validieren Sie das Modell nach dem Training, um seine Genauigkeit zu ermitteln.

    Um den Q# Klassifikator in Python auszuführen, speichern Sie den folgenden Code alshost.py. Denken Sie daran, dass Sie auch die Q# Datei Training.qs benötigen, die oben in diesem Tutorial beschrieben wird.

    
    import json
    
    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.colors as colors
    import matplotlib.cm as cmx
    plt.style.use('ggplot')
    
    import qsharp
    
    from Microsoft.Quantum.Samples import (
        TrainHalfMoonModel, ValidateHalfMoonModel, ClassifyHalfMoonModel
    )
    
    if __name__ == "__main__":
        with open('data.json') as f:
            data = json.load(f)
        parameter_starting_points = [
            [0.060057, 3.00522,  2.03083,  0.63527,  1.03771, 1.27881, 4.10186,  5.34396],
            [0.586514, 3.371623, 0.860791, 2.92517,  1.14616, 2.99776, 2.26505,  5.62137],
            [1.69704,  1.13912,  2.3595,   4.037552, 1.63698, 1.27549, 0.328671, 0.302282],
            [5.21662,  6.04363,  0.224184, 1.53913,  1.64524, 4.79508, 1.49742,  1.545]
         ]
    
        (parameters, bias) = TrainHalfMoonModel.simulate(
            trainingVectors=data['TrainingData']['Features'],
            trainingLabels=data['TrainingData']['Labels'],
            initialParameters=parameter_starting_points
        )
    
        miss_rate = ValidateHalfMoonModel.simulate(
            validationVectors=data['ValidationData']['Features'],
            validationLabels=data['ValidationData']['Labels'],
            parameters=parameters, bias=bias
        )
    
        print(f"Miss rate: {miss_rate:0.2%}")
    
        # Classify the validation so that we can plot it.
        actual_labels = data['ValidationData']['Labels']
        classified_labels = ClassifyHalfMoonModel.simulate(
            samples=data['ValidationData']['Features'],
            parameters=parameters, bias=bias,
            tolerance=0.005, nMeasurements=10_000
        )
    
    
        # To plot samples, it's helpful to have colors for each.
        # We'll plot four cases:
        # - actually 0, classified as 0
        # - actually 0, classified as 1
        # - actually 1, classified as 1
        # - actually 1, classified as 0
        cases = [
            (0, 0),
            (0, 1),
            (1, 1),
            (1, 0)
        ]
        # We can use these cases to define markers and colormaps for plotting.
        markers = [
            '.' if actual == classified else 'x'
            for (actual, classified) in cases
        ]
        colormap = cmx.ScalarMappable(colors.Normalize(vmin=0, vmax=len(cases) - 1))
        colors = [colormap.to_rgba(idx_case) for (idx_case, case) in enumerate(cases)]
    
        # It's also really helpful to have the samples as a NumPy array so that we
        # can find masks for each of the four cases.
        samples = np.array(data['ValidationData']['Features'])
    
        # Finally, we loop over the cases above and plot the samples that match
        # each.
        for (idx_case, ((actual, classified), marker, color)) in enumerate(zip(cases, markers, colors)):
            mask = np.logical_and(
                np.equal(actual_labels, actual),
                np.equal(classified_labels, classified)
            )
            if not np.any(mask):
                continue
            plt.scatter(
                samples[mask, 0],
                samples[mask, 1],
                c=[color],
                label=f"Was {actual}, classified {classified}",
                marker=marker
            )
        plt.legend()
        plt.show()
    

    Anschließend können Sie Ihr Python-Hostprogramm an der Befehlszeile ausführen:

    $ python host.py
    
    Preparing Q# environment...
    [...]
    Observed X.XX% misclassifications.
    

Nächste Schritte

Zunächst können Sie mit dem Code spielen und versuchen, einige Parameter zu ändern, um zu sehen, wie sich dies auf das Training auswirkt. Im nächsten Tutorial, Entwerfen Sie Ihren eigenen Klassifikator lernen Sie, wie Sie die Struktur des Klassifikators definieren.