From 854909aa35cdaef12afbe927380b953acba5a61f Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Tue, 12 Nov 2019 19:15:20 -0800 Subject: [PATCH 1/7] Ported most logic into Q# in prep for Python host. --- .../half-moons/HalfMoons.csproj | 19 +++ .../machine-learning/half-moons/Program.cs | 72 +++++++++ .../machine-learning/half-moons/Training.qs | 102 +++++++++++++ .../machine-learning/half-moons/moon-test.csv | 15 ++ .../half-moons/sorted-data.csv | 137 ++++++++++++++++++ 5 files changed, 345 insertions(+) create mode 100644 samples/machine-learning/half-moons/HalfMoons.csproj create mode 100644 samples/machine-learning/half-moons/Program.cs create mode 100644 samples/machine-learning/half-moons/Training.qs create mode 100644 samples/machine-learning/half-moons/moon-test.csv create mode 100644 samples/machine-learning/half-moons/sorted-data.csv diff --git a/samples/machine-learning/half-moons/HalfMoons.csproj b/samples/machine-learning/half-moons/HalfMoons.csproj new file mode 100644 index 000000000000..cb3369a172e9 --- /dev/null +++ b/samples/machine-learning/half-moons/HalfMoons.csproj @@ -0,0 +1,19 @@ + + + + Exe + netcoreapp3.0 + x64 + + + + + + + + + + + + + diff --git a/samples/machine-learning/half-moons/Program.cs b/samples/machine-learning/half-moons/Program.cs new file mode 100644 index 000000000000..f35e97666551 --- /dev/null +++ b/samples/machine-learning/half-moons/Program.cs @@ -0,0 +1,72 @@ +using Microsoft.Quantum.Simulation.Core; +using Microsoft.Quantum.Simulation.Simulators; +using System; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Collections.Generic; +using System.Threading.Tasks; +using static System.Math; + +namespace Microsoft.Quantum.Samples +{ + using Microsoft.Quantum.MachineLearning; + using Microsoft.Quantum.MachineLearning.Interop; + + class Program + { + /// + /// Simple 2D data classes that are, however, not linearly separable + /// + /// true iff fewer that 3 misclassifications are achieved on test data + static async Task Main() + { + var (vectors, labels) = LoadDataFromCsv("sorted-data.csv"); + var paramSource = new double[][] + { + new double[] {0.060057, 3.00522, 2.03083, 0.63527, 1.03771, 1.27881, 4.10186, 5.34396}, + new double[] {0.586514, 3.371623, 0.860791, 2.92517, 1.14616, 2.99776, 2.26505, 5.62137}, + new double[] {1.69704, 1.13912, 2.3595, 4.037552, 1.63698, 1.27549, 0.328671, 0.302282}, + new double[] { 5.21662, 6.04363, 0.224184, 1.53913, 1.64524, 4.79508, 1.49742, 1.5455} + }; + using var targetMachine = new QuantumSimulator(false, 12345678); + var (optimizedParameters, optimizedBias) = await Train.Run( + targetMachine, + new QArray>(vectors.Select(vector => new QArray(vector))), + new QArray(labels), + new QArray>(paramSource.Select(parameterSet => new QArray(parameterSet))) + ); + + //NOW DO SOME TESTING + var (testVecs, testLabs) = LoadDataFromCsv("moon-test.csv"); + var testMisses = await Validate.Run( + targetMachine, + new QArray>(testVecs.Select(vector => new QArray(vector))), + new QArray(testLabs), + optimizedParameters, + optimizedBias + ); + System.Console.WriteLine($"Observed {testMisses} out of {testVecs.Count} validation samples."); + } //HalfMoonsExample + + + static (List, List) LoadDataFromCsv(string dataPath, double offset = 0.0, double filler = 1.0) + { + var vectors = new List(); + var labels = new List(); + using var dataReader = new StreamReader(dataPath); + while (dataReader.ReadLine() is string line) + { + var tokens = line.Split(','); + var x = double.Parse(tokens[0]) + offset; + var y = double.Parse(tokens[1]) + offset; + //pre-applying "product state" kernel + var vec = new double[] { x, y }; + vectors.Add(vec); + labels.Add(long.Parse(tokens[2])); + } + return (vectors, labels); + } + + } +} diff --git a/samples/machine-learning/half-moons/Training.qs b/samples/machine-learning/half-moons/Training.qs new file mode 100644 index 000000000000..42f51408d69e --- /dev/null +++ b/samples/machine-learning/half-moons/Training.qs @@ -0,0 +1,102 @@ +namespace Microsoft.Quantum.Samples { + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Arrays; + open Microsoft.Quantum.MachineLearning; + open Microsoft.Quantum.Math; + + function WithOffset(offset : Double, sample : Double[]) : Double[] { + return Mapped(TimesD(offset, _), sample); + } + + function WithProductKernel(scale : Double, sample : Double[]) : Double[] { + return sample + [scale * Fold(TimesD, 1.0, sample)]; + } + + function Preprocessed(samples : Double[][]) : Double[][] { + let offset = 0.75; + let scale = 1.0; + + return Mapped( + Compose( + WithOffset(offset, _), + WithProductKernel(scale, _) + ), + samples + ); + } + + function DefaultSchedule(samples : Double[][]) : Int[][] { + return [ + [0, 1, Length(samples) - 1] + ]; + } + + // FIXME: This needs to return a GateSequence value, but that requires adapting + // TrainQcccSequential. + function ClassifierStructure() : Int[][] { + // FIXME: Change these to Pauli values, change Y to be 3. + let (x, y, z) = (1, 2, 3); + return [ + [4, x, 0], + [5, z, 0], + [6, x, 1], + [7, z, 1], + [0, x, 0, 1], + [1, x, 1, 0], + [2, z, 1], + [3, x, 1] + ]; + } + + operation Train( + trainingVectors : Double[][], + trainingLabels : Int[], + initialParameters : Double[][] + ) : (Double[], Double) { + let nQubits = 2; + let learningRate = 0.1; + let minibatchSize = 15; + let tolerance = 0.005; + let nMeasurements = 10000; + let maxEpochs = 16; + let ppVectors = Preprocessed(trainingVectors); + Message("Ready to train."); + let (optimizedParameters, optimialBias) = TrainQcccSequential( + nQubits, + ClassifierStructure(), + initialParameters, + ppVectors, trainingLabels, + DefaultSchedule(trainingVectors), + DefaultSchedule(trainingVectors), + learningRate, tolerance, minibatchSize, + maxEpochs, + nMeasurements + ); + Message($"Training complete, found optimal parameters: {optimizedParameters}"); + return (optimizedParameters, optimialBias); + } + + operation Validate( + validationVectors : Double[][], + validationLabels : Int[], + parameters : Double[], + bias : Double + ) : Int { + let nQubits = 2; + let tolerance = 0.005; + let nMeasurements = 10000; + return CountValidationMisses( + tolerance, + nQubits, + validationVectors, + validationLabels, + DefaultSchedule(validationVectors), + ClassifierStructure(), + parameters, + bias, + nMeasurements + ); + } + +} diff --git a/samples/machine-learning/half-moons/moon-test.csv b/samples/machine-learning/half-moons/moon-test.csv new file mode 100644 index 000000000000..b846b4e34875 --- /dev/null +++ b/samples/machine-learning/half-moons/moon-test.csv @@ -0,0 +1,15 @@ +0.883898709935946,0.,1 +1.1793893456320759,0.3748347849076317,1 +0.5231831310352743,0.900818803609586,1 +0.30081607582696224,0.9615554053041235,1 +-0.06340157706002579,1.224735863277014,1 +-0.5382643095868677,1.0133143141607128,1 +-0.5975208094029268,0.561438878658366,1 +-0.766231190604878,0.19526118857958627,1 +0.14060021668138722,0.4,0 +0.05239183271831849,-0.008592101868396151,0 +0.36087228857768316,-0.3470962748964499,0 +0.7371834528946137,-0.3046817236779634,0 +1.0706889634601606,-0.7207038198913537,0 +1.487876633223481,-0.37571084836184543,0 +1.8726657414770358,-0.16558447370672003,0 diff --git a/samples/machine-learning/half-moons/sorted-data.csv b/samples/machine-learning/half-moons/sorted-data.csv new file mode 100644 index 000000000000..e8ff8575ec3b --- /dev/null +++ b/samples/machine-learning/half-moons/sorted-data.csv @@ -0,0 +1,137 @@ +-0.00035731158553797826,-0.06346656877546791,0 +-0.0012062337869831463,-0.15157022343854742,0 +-0.014980621149421162,0.7452612548840972,1 +-0.03536657731228199,0.36450905608465584,0 +-0.08658898925520085,0.8549594407803911,1 +-0.08780040610147566,0.3158448974605273,0 +-0.11041961535964329,0.029508550947450807,0 +-0.1236937998311684,0.8915912980454145,1 +-0.1381620621317352,0.100136328149671,0 +-0.14962800792227093,0.03490175212127222,0 +-0.16703979749984005,1.1061592722104854,1 +-0.18702040402999198,0.6909521716931064,1 +-0.274906632066767,0.94407037626692,1 +-0.40035386722930877,0.9640718547110079,1 +-0.42645222935272076,0.8084904468062676,1 +-0.44580392648704686,0.8279493796060237,1 +-0.4565691026559081,1.026935374542866,1 +-0.47115221818532443,1.1627266622606667,1 +-0.48113754393867386,1.0177743873407035,1 +-0.5573460215796026,0.9347902465129836,1 +-0.5629032983072818,0.7552388504286991,1 +-0.6349597854601028,0.43957861193628395,1 +-0.6559537333860002,0.5512056376068405,1 +-0.675859772306459,0.8831917431313464,1 +-0.6789437666097666,0.33724531848285233,1 +-0.7184386804472017,0.1970015971182835,1 +-0.7265600758299311,0.312525805601502,1 +-0.7471807053856604,0.6879169346941071,1 +-0.7501513130996611,0.5868387512254272,1 +-0.7675714408206668,0.3111027708930208,1 +-0.8211557055524259,0.7060386061700794,1 +-0.8523667503036682,0.8760469456594606,1 +-0.9318185748767674,0.5922375073085167,1 +-0.9360478798593356,0.7217802547976218,1 +-0.9458822433124261,0.5463806510445365,1 +-0.9927882574787499,0.37272854954816614,1 +-1.0794720450455788,0.,1 +-1.0903971011972062,0.15043830790243995,1 +-1.1240595085750649,0.06868659592655377,1 +-1.214345522322524,0.0522205845910377,1 +-1.2478207683344034,0.09971541915389676,1 +0.015790851198098987,0.8176667797938731,1 +0.024025073005429665,0.19498421190371337,0 +0.04070325327489788,0.249948540045528,0 +0.05330457430838108,1.0564351286097744,1 +0.08150549868348289,1.0466409152302647,1 +0.13545436353822082,-0.28735571909099844,0 +0.13790002655139869,0.8079245980111084,1 +0.14330248971296777,0.16878957858332952,0 +0.15111162653375743,-0.48726422061762564,0 +0.15241120217118012,0.7882780938447811,1 +0.1684510563335908,-0.16516768291416295,0 +0.1889645905680306,0.04426699518384147,0 +0.19707578589348906,-0.2380232166101135,0 +0.21923185570294207,1.0258464978767086,1 +0.2272375409453048,-0.2660358584515484,0 +0.23414554456624714,-0.1821040168632353,0 +0.23872423712311908,-0.5521479642401027,0 +0.28398615786926007,-0.5053038255570522,0 +0.2913326625188073,0.9961989575986329,1 +0.3492829018038269,0.814349058873698,1 +0.35875569081458425,-0.07308833776422552,0 +0.362865905625692,0.8093526658754205,1 +0.3745589417707047,-0.06441622857939078,0 +0.3862048923032335,0.897812088282051,1 +0.44463324389734504,0.8059192934499005,1 +0.45996051267747096,1.0931047101235087,1 +0.47441840271450164,-0.5671490088420339,0 +0.4792391502435683,0.8766676237020283,1 +0.49674365935819675,0.7262766499720068,1 +0.5254035987296022,-0.5304074709596346,0 +0.5515696762477782,0.7047403349020965,1 +0.5583796023696284,-0.3479717584215746,0 +0.5637841185957758,0.7379114816809925,1 +0.6077488386907419,-0.6479590594758237,0 +0.6336773725676798,0.4013212953811713,1 +0.6417404109261109,-0.2616928728716996,0 +0.6468024469374531,0.5723741631150826,1 +0.6519740444333493,-0.39192657875894454,0 +0.6671288712714325,0.7610985060640911,1 +0.6932965033438983,-0.5691093818942972,0 +0.7169235943848092,0.8787011825169279,1 +0.735662886386677,-0.5139463255333367,0 +0.7372698027976039,0.5213352096575902,1 +0.7418878900815039,0.7002467277813453,1 +0.7664851841222006,-0.6514816641294779,0 +0.7725057509267337,0.8420004414490583,1 +0.7826795986676983,0.18277102726722777,1 +0.7940103483510714,0.4372365151467599,1 +0.7979464168249012,0.34798699949141526,1 +0.8260330228824426,-0.49820898981569917,0 +0.842288240480912,0.36875379048411394,1 +0.851971206551066,0.39348082552085084,1 +0.86205044244621,0.19841586681120152,1 +0.8649902905009432,-0.8610121773585954,0 +0.8918712515887249,0.04342395954912626,1 +0.9330218289777374,-0.3206460583629134,0 +0.9415223350819799,0.09922080120808434,1 +0.9803048280161961,-0.4510040235742361,0 +1.0208043681386143,-0.8751310593605329,0 +1.052488336309264,0.4328256302831184,1 +1.0985310687439107,0.14973497839506208,1 +1.1339205799760226,-0.43403293167637014,0 +1.1565732261285677,-0.6595940690524519,0 +1.1602020363874843,-0.2934418893827161,0 +1.2682099135173655,-0.6278842301450488,0 +1.2728317781228748,0.09730915590736164,1 +1.2811702965638943,-0.3447002832792715,0 +1.314987405783858,-0.3575003637607095,0 +1.385688958936755,-0.40535754675580093,0 +1.3971199048085738,-0.5457951846994613,0 +1.5012513595709254,-0.5463014889465386,0 +1.5172077595677511,-0.6206057874342353,0 +1.5231911523171273,-0.34631140825430407,0 +1.580210458744003,-0.15260672753941906,0 +1.6079210210735444,-0.19380515481338,0 +1.6104405670902222,-0.11669112572858897,0 +1.6183753843243038,-0.503965099128002,0 +1.6201999823810802,-0.33683064921830785,0 +1.6576017564472596,-0.4885701807109335,0 +1.6845310670806912,-0.2311093840793329,0 +1.7410140105531124,-0.3425370707868646,0 +1.8363547966325138,0.14677633121227235,0 +1.8486093722400083,-0.2787461884436434,0 +1.951337189006637,0.30510300479138863,0 +1.9714210183447758,0.012927048499541016,0 +1.9870163765527555,0.1911013992299178,0 +1.9932458483843853,-0.1645193522473022,0 +2.0030979227790873,0.2522312038058796,0 +2.013819388433135,-0.12322354775036859,0 +2.083597025712324,0.16834772265128853,0 +2.1046622748873682,0.321969070147389,0 +2.108720022072707,-0.21072346710168843,0 +2.124147293246285,-0.07516641977035582,0 +2.1433309328426424,0.4,0 +2.207412007224068,0.1144911302646231,0 +2.237584830750855,0.3595752334213297,0 From 063547fba4d20f34890aff20fce26540e3376a0e Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 13 Nov 2019 10:21:50 -0800 Subject: [PATCH 2/7] Use structured training and validation API. --- .../machine-learning/half-moons/Program.cs | 6 +-- .../machine-learning/half-moons/Training.qs | 54 ++++++++++--------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/samples/machine-learning/half-moons/Program.cs b/samples/machine-learning/half-moons/Program.cs index f35e97666551..41319f1f5cf9 100644 --- a/samples/machine-learning/half-moons/Program.cs +++ b/samples/machine-learning/half-moons/Program.cs @@ -30,7 +30,7 @@ static async Task Main() new double[] { 5.21662, 6.04363, 0.224184, 1.53913, 1.64524, 4.79508, 1.49742, 1.5455} }; using var targetMachine = new QuantumSimulator(false, 12345678); - var (optimizedParameters, optimizedBias) = await Train.Run( + var (optimizedParameters, optimizedBias) = await TrainHalfMoonModel.Run( targetMachine, new QArray>(vectors.Select(vector => new QArray(vector))), new QArray(labels), @@ -39,14 +39,14 @@ static async Task Main() //NOW DO SOME TESTING var (testVecs, testLabs) = LoadDataFromCsv("moon-test.csv"); - var testMisses = await Validate.Run( + var testMisses = await ValidateHalfMoonModel.Run( targetMachine, new QArray>(testVecs.Select(vector => new QArray(vector))), new QArray(testLabs), optimizedParameters, optimizedBias ); - System.Console.WriteLine($"Observed {testMisses} out of {testVecs.Count} validation samples."); + System.Console.WriteLine($"Observed {testMisses} misclassifications out of {testVecs.Count} validation samples."); } //HalfMoonsExample diff --git a/samples/machine-learning/half-moons/Training.qs b/samples/machine-learning/half-moons/Training.qs index 42f51408d69e..ce7dc98b9bc9 100644 --- a/samples/machine-learning/half-moons/Training.qs +++ b/samples/machine-learning/half-moons/Training.qs @@ -26,47 +26,49 @@ namespace Microsoft.Quantum.Samples { ); } - function DefaultSchedule(samples : Double[][]) : Int[][] { - return [ - [0, 1, Length(samples) - 1] - ]; + function DefaultSchedule(samples : Double[][]) : SamplingSchedule { + return SamplingSchedule([ + 0..Length(samples) - 1 + ]); } // FIXME: This needs to return a GateSequence value, but that requires adapting // TrainQcccSequential. - function ClassifierStructure() : Int[][] { - // FIXME: Change these to Pauli values, change Y to be 3. + function ClassifierStructure() : GateSequence { let (x, y, z) = (1, 2, 3); - return [ - [4, x, 0], - [5, z, 0], - [6, x, 1], - [7, z, 1], - [0, x, 0, 1], - [1, x, 1, 0], - [2, z, 1], - [3, x, 1] - ]; + return GateSequence([ + ControlledRotation(GateSpan(0, new Int[0]), PauliX, 4), + ControlledRotation(GateSpan(0, new Int[0]), PauliZ, 5), + ControlledRotation(GateSpan(1, new Int[0]), PauliX, 6), + ControlledRotation(GateSpan(1, new Int[0]), PauliZ, 7), + ControlledRotation(GateSpan(0, [1]), PauliX, 0), + ControlledRotation(GateSpan(1, [0]), PauliX, 1), + ControlledRotation(GateSpan(1, new Int[0]), PauliZ, 2), + ControlledRotation(GateSpan(1, new Int[0]), PauliX, 3) + ]); } - operation Train( + operation TrainHalfMoonModel( trainingVectors : Double[][], trainingLabels : Int[], initialParameters : Double[][] ) : (Double[], Double) { + let samples = Mapped( + LabeledSample, + Zip(Preprocessed(trainingVectors), trainingLabels) + ); let nQubits = 2; let learningRate = 0.1; let minibatchSize = 15; let tolerance = 0.005; let nMeasurements = 10000; let maxEpochs = 16; - let ppVectors = Preprocessed(trainingVectors); Message("Ready to train."); - let (optimizedParameters, optimialBias) = TrainQcccSequential( + let (optimizedParameters, optimialBias) = TrainSequentialClassifier( nQubits, ClassifierStructure(), initialParameters, - ppVectors, trainingLabels, + samples, DefaultSchedule(trainingVectors), DefaultSchedule(trainingVectors), learningRate, tolerance, minibatchSize, @@ -77,26 +79,30 @@ namespace Microsoft.Quantum.Samples { return (optimizedParameters, optimialBias); } - operation Validate( + operation ValidateHalfMoonModel( validationVectors : Double[][], validationLabels : Int[], parameters : Double[], bias : Double ) : Int { + let samples = Mapped( + LabeledSample, + Zip(Preprocessed(validationVectors), validationLabels) + ); let nQubits = 2; let tolerance = 0.005; let nMeasurements = 10000; - return CountValidationMisses( + let results = ValidateModel( tolerance, nQubits, - validationVectors, - validationLabels, + samples, DefaultSchedule(validationVectors), ClassifierStructure(), parameters, bias, nMeasurements ); + return results::NMisclassifications; } } From d04ab05408a827b738d970013346e151060c442f Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 22 Nov 2019 13:45:58 -0800 Subject: [PATCH 3/7] Switched to packagereference. --- samples/machine-learning/half-moons/HalfMoons.csproj | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/samples/machine-learning/half-moons/HalfMoons.csproj b/samples/machine-learning/half-moons/HalfMoons.csproj index cb3369a172e9..aa0593ac90b9 100644 --- a/samples/machine-learning/half-moons/HalfMoons.csproj +++ b/samples/machine-learning/half-moons/HalfMoons.csproj @@ -8,12 +8,7 @@ - - - - - - - + + From 3f3d22829572d4f442c9e7585f183c769f352e99 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 22 Nov 2019 15:39:23 -0800 Subject: [PATCH 4/7] =?UTF-8?q?Add=20=E2=93=92=20headers.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- samples/machine-learning/half-moons/Program.cs | 4 ++++ samples/machine-learning/half-moons/Training.qs | 3 +++ 2 files changed, 7 insertions(+) diff --git a/samples/machine-learning/half-moons/Program.cs b/samples/machine-learning/half-moons/Program.cs index 41319f1f5cf9..dbea1b383708 100644 --- a/samples/machine-learning/half-moons/Program.cs +++ b/samples/machine-learning/half-moons/Program.cs @@ -1,3 +1,7 @@ + +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + using Microsoft.Quantum.Simulation.Core; using Microsoft.Quantum.Simulation.Simulators; using System; diff --git a/samples/machine-learning/half-moons/Training.qs b/samples/machine-learning/half-moons/Training.qs index ce7dc98b9bc9..5c7839a95038 100644 --- a/samples/machine-learning/half-moons/Training.qs +++ b/samples/machine-learning/half-moons/Training.qs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + namespace Microsoft.Quantum.Samples { open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Canon; From 88eadfe6edd943309ddf2a5d2b567356dc0118f1 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 22 Nov 2019 16:34:54 -0800 Subject: [PATCH 5/7] Remove out-dated API comment. --- samples/machine-learning/half-moons/Program.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/samples/machine-learning/half-moons/Program.cs b/samples/machine-learning/half-moons/Program.cs index dbea1b383708..509dd2504e25 100644 --- a/samples/machine-learning/half-moons/Program.cs +++ b/samples/machine-learning/half-moons/Program.cs @@ -19,10 +19,6 @@ namespace Microsoft.Quantum.Samples class Program { - /// - /// Simple 2D data classes that are, however, not linearly separable - /// - /// true iff fewer that 3 misclassifications are achieved on test data static async Task Main() { var (vectors, labels) = LoadDataFromCsv("sorted-data.csv"); From 239dcd75a53c43db8af44a347063042f4a5d2b05 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 22 Nov 2019 17:18:04 -0800 Subject: [PATCH 6/7] Convert half moon data to json --- .../half-moons/HalfMoons.csproj | 1 + .../machine-learning/half-moons/Program.cs | 51 +++--- samples/machine-learning/half-moons/data.json | 167 ++++++++++++++++++ .../machine-learning/half-moons/moon-test.csv | 15 -- .../half-moons/sorted-data.csv | 137 -------------- 5 files changed, 196 insertions(+), 175 deletions(-) create mode 100644 samples/machine-learning/half-moons/data.json delete mode 100644 samples/machine-learning/half-moons/moon-test.csv delete mode 100644 samples/machine-learning/half-moons/sorted-data.csv diff --git a/samples/machine-learning/half-moons/HalfMoons.csproj b/samples/machine-learning/half-moons/HalfMoons.csproj index aa0593ac90b9..1337adc30d47 100644 --- a/samples/machine-learning/half-moons/HalfMoons.csproj +++ b/samples/machine-learning/half-moons/HalfMoons.csproj @@ -10,5 +10,6 @@ + diff --git a/samples/machine-learning/half-moons/Program.cs b/samples/machine-learning/half-moons/Program.cs index 509dd2504e25..0e3227672906 100644 --- a/samples/machine-learning/half-moons/Program.cs +++ b/samples/machine-learning/half-moons/Program.cs @@ -7,6 +7,7 @@ using System; using System.IO; using System.Linq; +using System.Text.Json; using System.Runtime.InteropServices; using System.Collections.Generic; using System.Threading.Tasks; @@ -21,7 +22,7 @@ class Program { static async Task Main() { - var (vectors, labels) = LoadDataFromCsv("sorted-data.csv"); + var data = await LoadData("data.json"); var paramSource = new double[][] { new double[] {0.060057, 3.00522, 2.03083, 0.63527, 1.03771, 1.27881, 4.10186, 5.34396}, @@ -32,40 +33,44 @@ static async Task Main() using var targetMachine = new QuantumSimulator(false, 12345678); var (optimizedParameters, optimizedBias) = await TrainHalfMoonModel.Run( targetMachine, - new QArray>(vectors.Select(vector => new QArray(vector))), - new QArray(labels), + new QArray>(data.TrainingData.Features.Select(vector => new QArray(vector))), + new QArray(data.TrainingData.Labels), new QArray>(paramSource.Select(parameterSet => new QArray(parameterSet))) ); //NOW DO SOME TESTING - var (testVecs, testLabs) = LoadDataFromCsv("moon-test.csv"); var testMisses = await ValidateHalfMoonModel.Run( targetMachine, - new QArray>(testVecs.Select(vector => new QArray(vector))), - new QArray(testLabs), + new QArray>(data.ValidationData.Features.Select(vector => new QArray(vector))), + new QArray(data.ValidationData.Labels), optimizedParameters, optimizedBias ); - System.Console.WriteLine($"Observed {testMisses} misclassifications out of {testVecs.Count} validation samples."); - } //HalfMoonsExample + System.Console.WriteLine($"Observed {testMisses} misclassifications out of {data.ValidationData.Labels.Count} validation samples."); + } + class LabeledData + { + public List Features { get; set; } + public List Labels { get; set; } + } - static (List, List) LoadDataFromCsv(string dataPath, double offset = 0.0, double filler = 1.0) + class DataSet { - var vectors = new List(); - var labels = new List(); - using var dataReader = new StreamReader(dataPath); - while (dataReader.ReadLine() is string line) - { - var tokens = line.Split(','); - var x = double.Parse(tokens[0]) + offset; - var y = double.Parse(tokens[1]) + offset; - //pre-applying "product state" kernel - var vec = new double[] { x, y }; - vectors.Add(vec); - labels.Add(long.Parse(tokens[2])); - } - return (vectors, labels); + public LabeledData TrainingData { get; set; } + public LabeledData ValidationData { get; set; } + } + + static async Task LoadData(string dataPath, double offset = 0.0, double filler = 1.0) + { + using var dataReader = File.OpenRead(dataPath); + return await JsonSerializer.DeserializeAsync( + dataReader, + new JsonSerializerOptions + { + ReadCommentHandling = JsonCommentHandling.Skip + } + ); } } diff --git a/samples/machine-learning/half-moons/data.json b/samples/machine-learning/half-moons/data.json new file mode 100644 index 000000000000..8ab42ad57891 --- /dev/null +++ b/samples/machine-learning/half-moons/data.json @@ -0,0 +1,167 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +{ + "TrainingData": { + "Features": [ + [ + 0.883898709935946, + 0.0 + ], + [ + 1.1793893456320759, + 0.3748347849076317 + ], + [ + 0.5231831310352743, + 0.900818803609586 + ], + [ + 0.30081607582696224, + 0.9615554053041235 + ], + [ + -0.06340157706002579, + 1.224735863277014 + ], + [ + -0.5382643095868677, + 1.0133143141607128 + ], + [ + -0.5975208094029268, + 0.561438878658366 + ], + [ + -0.766231190604878, + 0.19526118857958627 + ], + [ + 0.14060021668138722, + 0.4 + ], + [ + 0.05239183271831849, + -0.008592101868396151 + ], + [ + 0.36087228857768316, + -0.3470962748964499 + ], + [ + 0.7371834528946137, + -0.3046817236779634 + ], + [ + 1.0706889634601606, + -0.7207038198913537 + ], + [ + 1.487876633223481, + -0.37571084836184543 + ], + [ + 1.8726657414770358, + -0.16558447370672003 + ] + ], + "Labels": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "ValidationData": { + "Features": [ + [ + 0.883898709935946, + 0.0 + ], + [ + 1.1793893456320759, + 0.3748347849076317 + ], + [ + 0.5231831310352743, + 0.900818803609586 + ], + [ + 0.30081607582696224, + 0.9615554053041235 + ], + [ + -0.06340157706002579, + 1.224735863277014 + ], + [ + -0.5382643095868677, + 1.0133143141607128 + ], + [ + -0.5975208094029268, + 0.561438878658366 + ], + [ + -0.766231190604878, + 0.19526118857958627 + ], + [ + 0.14060021668138722, + 0.4 + ], + [ + 0.05239183271831849, + -0.008592101868396151 + ], + [ + 0.36087228857768316, + -0.3470962748964499 + ], + [ + 0.7371834528946137, + -0.3046817236779634 + ], + [ + 1.0706889634601606, + -0.7207038198913537 + ], + [ + 1.487876633223481, + -0.37571084836184543 + ], + [ + 1.8726657414770358, + -0.16558447370672003 + ] + ], + "Labels": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } +} diff --git a/samples/machine-learning/half-moons/moon-test.csv b/samples/machine-learning/half-moons/moon-test.csv deleted file mode 100644 index b846b4e34875..000000000000 --- a/samples/machine-learning/half-moons/moon-test.csv +++ /dev/null @@ -1,15 +0,0 @@ -0.883898709935946,0.,1 -1.1793893456320759,0.3748347849076317,1 -0.5231831310352743,0.900818803609586,1 -0.30081607582696224,0.9615554053041235,1 --0.06340157706002579,1.224735863277014,1 --0.5382643095868677,1.0133143141607128,1 --0.5975208094029268,0.561438878658366,1 --0.766231190604878,0.19526118857958627,1 -0.14060021668138722,0.4,0 -0.05239183271831849,-0.008592101868396151,0 -0.36087228857768316,-0.3470962748964499,0 -0.7371834528946137,-0.3046817236779634,0 -1.0706889634601606,-0.7207038198913537,0 -1.487876633223481,-0.37571084836184543,0 -1.8726657414770358,-0.16558447370672003,0 diff --git a/samples/machine-learning/half-moons/sorted-data.csv b/samples/machine-learning/half-moons/sorted-data.csv deleted file mode 100644 index e8ff8575ec3b..000000000000 --- a/samples/machine-learning/half-moons/sorted-data.csv +++ /dev/null @@ -1,137 +0,0 @@ --0.00035731158553797826,-0.06346656877546791,0 --0.0012062337869831463,-0.15157022343854742,0 --0.014980621149421162,0.7452612548840972,1 --0.03536657731228199,0.36450905608465584,0 --0.08658898925520085,0.8549594407803911,1 --0.08780040610147566,0.3158448974605273,0 --0.11041961535964329,0.029508550947450807,0 --0.1236937998311684,0.8915912980454145,1 --0.1381620621317352,0.100136328149671,0 --0.14962800792227093,0.03490175212127222,0 --0.16703979749984005,1.1061592722104854,1 --0.18702040402999198,0.6909521716931064,1 --0.274906632066767,0.94407037626692,1 --0.40035386722930877,0.9640718547110079,1 --0.42645222935272076,0.8084904468062676,1 --0.44580392648704686,0.8279493796060237,1 --0.4565691026559081,1.026935374542866,1 --0.47115221818532443,1.1627266622606667,1 --0.48113754393867386,1.0177743873407035,1 --0.5573460215796026,0.9347902465129836,1 --0.5629032983072818,0.7552388504286991,1 --0.6349597854601028,0.43957861193628395,1 --0.6559537333860002,0.5512056376068405,1 --0.675859772306459,0.8831917431313464,1 --0.6789437666097666,0.33724531848285233,1 --0.7184386804472017,0.1970015971182835,1 --0.7265600758299311,0.312525805601502,1 --0.7471807053856604,0.6879169346941071,1 --0.7501513130996611,0.5868387512254272,1 --0.7675714408206668,0.3111027708930208,1 --0.8211557055524259,0.7060386061700794,1 --0.8523667503036682,0.8760469456594606,1 --0.9318185748767674,0.5922375073085167,1 --0.9360478798593356,0.7217802547976218,1 --0.9458822433124261,0.5463806510445365,1 --0.9927882574787499,0.37272854954816614,1 --1.0794720450455788,0.,1 --1.0903971011972062,0.15043830790243995,1 --1.1240595085750649,0.06868659592655377,1 --1.214345522322524,0.0522205845910377,1 --1.2478207683344034,0.09971541915389676,1 -0.015790851198098987,0.8176667797938731,1 -0.024025073005429665,0.19498421190371337,0 -0.04070325327489788,0.249948540045528,0 -0.05330457430838108,1.0564351286097744,1 -0.08150549868348289,1.0466409152302647,1 -0.13545436353822082,-0.28735571909099844,0 -0.13790002655139869,0.8079245980111084,1 -0.14330248971296777,0.16878957858332952,0 -0.15111162653375743,-0.48726422061762564,0 -0.15241120217118012,0.7882780938447811,1 -0.1684510563335908,-0.16516768291416295,0 -0.1889645905680306,0.04426699518384147,0 -0.19707578589348906,-0.2380232166101135,0 -0.21923185570294207,1.0258464978767086,1 -0.2272375409453048,-0.2660358584515484,0 -0.23414554456624714,-0.1821040168632353,0 -0.23872423712311908,-0.5521479642401027,0 -0.28398615786926007,-0.5053038255570522,0 -0.2913326625188073,0.9961989575986329,1 -0.3492829018038269,0.814349058873698,1 -0.35875569081458425,-0.07308833776422552,0 -0.362865905625692,0.8093526658754205,1 -0.3745589417707047,-0.06441622857939078,0 -0.3862048923032335,0.897812088282051,1 -0.44463324389734504,0.8059192934499005,1 -0.45996051267747096,1.0931047101235087,1 -0.47441840271450164,-0.5671490088420339,0 -0.4792391502435683,0.8766676237020283,1 -0.49674365935819675,0.7262766499720068,1 -0.5254035987296022,-0.5304074709596346,0 -0.5515696762477782,0.7047403349020965,1 -0.5583796023696284,-0.3479717584215746,0 -0.5637841185957758,0.7379114816809925,1 -0.6077488386907419,-0.6479590594758237,0 -0.6336773725676798,0.4013212953811713,1 -0.6417404109261109,-0.2616928728716996,0 -0.6468024469374531,0.5723741631150826,1 -0.6519740444333493,-0.39192657875894454,0 -0.6671288712714325,0.7610985060640911,1 -0.6932965033438983,-0.5691093818942972,0 -0.7169235943848092,0.8787011825169279,1 -0.735662886386677,-0.5139463255333367,0 -0.7372698027976039,0.5213352096575902,1 -0.7418878900815039,0.7002467277813453,1 -0.7664851841222006,-0.6514816641294779,0 -0.7725057509267337,0.8420004414490583,1 -0.7826795986676983,0.18277102726722777,1 -0.7940103483510714,0.4372365151467599,1 -0.7979464168249012,0.34798699949141526,1 -0.8260330228824426,-0.49820898981569917,0 -0.842288240480912,0.36875379048411394,1 -0.851971206551066,0.39348082552085084,1 -0.86205044244621,0.19841586681120152,1 -0.8649902905009432,-0.8610121773585954,0 -0.8918712515887249,0.04342395954912626,1 -0.9330218289777374,-0.3206460583629134,0 -0.9415223350819799,0.09922080120808434,1 -0.9803048280161961,-0.4510040235742361,0 -1.0208043681386143,-0.8751310593605329,0 -1.052488336309264,0.4328256302831184,1 -1.0985310687439107,0.14973497839506208,1 -1.1339205799760226,-0.43403293167637014,0 -1.1565732261285677,-0.6595940690524519,0 -1.1602020363874843,-0.2934418893827161,0 -1.2682099135173655,-0.6278842301450488,0 -1.2728317781228748,0.09730915590736164,1 -1.2811702965638943,-0.3447002832792715,0 -1.314987405783858,-0.3575003637607095,0 -1.385688958936755,-0.40535754675580093,0 -1.3971199048085738,-0.5457951846994613,0 -1.5012513595709254,-0.5463014889465386,0 -1.5172077595677511,-0.6206057874342353,0 -1.5231911523171273,-0.34631140825430407,0 -1.580210458744003,-0.15260672753941906,0 -1.6079210210735444,-0.19380515481338,0 -1.6104405670902222,-0.11669112572858897,0 -1.6183753843243038,-0.503965099128002,0 -1.6201999823810802,-0.33683064921830785,0 -1.6576017564472596,-0.4885701807109335,0 -1.6845310670806912,-0.2311093840793329,0 -1.7410140105531124,-0.3425370707868646,0 -1.8363547966325138,0.14677633121227235,0 -1.8486093722400083,-0.2787461884436434,0 -1.951337189006637,0.30510300479138863,0 -1.9714210183447758,0.012927048499541016,0 -1.9870163765527555,0.1911013992299178,0 -1.9932458483843853,-0.1645193522473022,0 -2.0030979227790873,0.2522312038058796,0 -2.013819388433135,-0.12322354775036859,0 -2.083597025712324,0.16834772265128853,0 -2.1046622748873682,0.321969070147389,0 -2.108720022072707,-0.21072346710168843,0 -2.124147293246285,-0.07516641977035582,0 -2.1433309328426424,0.4,0 -2.207412007224068,0.1144911302646231,0 -2.237584830750855,0.3595752334213297,0 From 2441f2f317b71d956bc64deb16e58d7522c88d39 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Tue, 3 Dec 2019 10:52:55 -0800 Subject: [PATCH 7/7] Add better comments and simplify code some. --- .../machine-learning/half-moons/Program.cs | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/samples/machine-learning/half-moons/Program.cs b/samples/machine-learning/half-moons/Program.cs index 0e3227672906..ffc3b254597c 100644 --- a/samples/machine-learning/half-moons/Program.cs +++ b/samples/machine-learning/half-moons/Program.cs @@ -22,23 +22,36 @@ class Program { static async Task Main() { + // We start by loading the training and validation data from our JSON + // data file. var data = await LoadData("data.json"); - var paramSource = new double[][] + + // We then define the classifier parameters where we want to start our + // training iterations from. Since gradient descent is good at finding + // local optima, it's helpful to have a variety of different starting + // points. + var parameterStartingPoints = new [] { - new double[] {0.060057, 3.00522, 2.03083, 0.63527, 1.03771, 1.27881, 4.10186, 5.34396}, - new double[] {0.586514, 3.371623, 0.860791, 2.92517, 1.14616, 2.99776, 2.26505, 5.62137}, - new double[] {1.69704, 1.13912, 2.3595, 4.037552, 1.63698, 1.27549, 0.328671, 0.302282}, - new double[] { 5.21662, 6.04363, 0.224184, 1.53913, 1.64524, 4.79508, 1.49742, 1.5455} + new [] {0.060057, 3.00522, 2.03083, 0.63527, 1.03771, 1.27881, 4.10186, 5.34396}, + new [] {0.586514, 3.371623, 0.860791, 2.92517, 1.14616, 2.99776, 2.26505, 5.62137}, + new [] {1.69704, 1.13912, 2.3595, 4.037552, 1.63698, 1.27549, 0.328671, 0.302282}, + new [] {5.21662, 6.04363, 0.224184, 1.53913, 1.64524, 4.79508, 1.49742, 1.5455} }; - using var targetMachine = new QuantumSimulator(false, 12345678); + + // Next, we initialize a full state-vector simulator as our target machine. + using var targetMachine = new QuantumSimulator(); + + // Once we have the data loaded and have initialized our target machine, + // we can then use that target machine to train a QCC classifier. var (optimizedParameters, optimizedBias) = await TrainHalfMoonModel.Run( targetMachine, new QArray>(data.TrainingData.Features.Select(vector => new QArray(vector))), new QArray(data.TrainingData.Labels), - new QArray>(paramSource.Select(parameterSet => new QArray(parameterSet))) + new QArray>(parameterStartingPoints.Select(parameterSet => new QArray(parameterSet))) ); - //NOW DO SOME TESTING + // After training, we can use the validation data to test the accuracy + // of our new classifier. var testMisses = await ValidateHalfMoonModel.Run( targetMachine, new QArray>(data.ValidationData.Features.Select(vector => new QArray(vector))),