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
- Das Microsoft Quantum Development Kit.
- Erstellen Sie ein Q# Projekt entweder für ein Python-Host-Programm oder einem C#-Host-Programm.
- Um ihrem Q# Projekt das Microsoft.Quantum.MachineLearning-Paket hinzuzufügen, führen Sie den folgenden Befehl aus dem Stammverzeichnis Ihres Projektordners aus:
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 VorgangTrainSequentialClassifier
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.
- Python mit Visual Studio Code oder Befehlszeile
- C# mit Visual Studio Code oder Befehlszeile
- C# mit Visual Studio 2022
Um den Q# Klassifikator in Python auszuführen, speichern Sie den folgenden Code als
host.py
. Denken Sie daran, dass Sie auch die Q# DateiTraining.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.