public void Run() { var device = DeviceDescriptor.UseDefaultDevice(); // 1. Generate Data int sampleSize = 32; int nbDimensionsInput = 2; // 2 dimensions (age&tumorsize) int nbLabels = 2; // l'output est un vecteur de probabilités qui doit sommer à 1. Si on ne met qu'une seule dimension de sortie, l'output sera toujours de 1. // on met donc deux dimension, une dimension 'vrai' et une dimension 'faux'. L'output sera du genre 0.25 vrai et 0.75 faux => total des poids = 1; // premier label = faux, second = vrai IEnumerable <DataPoint> data = GenerateData(sampleSize); //foreach (var pt in data) // Debug.WriteLine($"{pt.Age};{pt.TumorSize};{(pt.HasCancer ? 1 : 0)}"); Variable inputVariables = Variable.InputVariable(NDShape.CreateNDShape(new[] { nbDimensionsInput }), DataType.Double, "input"); Variable expectedOutput = Variable.InputVariable(new int[] { nbLabels }, DataType.Double, "output"); int nbHiddenLayers = 1; Function lastLayer = DefineNetwork(inputVariables, nbLabels, nbHiddenLayers, CNTKLib.Sigmoid); Function lossFunction = CNTKLib.CrossEntropyWithSoftmax(lastLayer, expectedOutput); Function evalErrorFunction = CNTKLib.ClassificationError(lastLayer, expectedOutput); uint minibatchSize = 25; double learningRate = 0.5; TrainingParameterScheduleDouble learningRatePerSample = new TrainingParameterScheduleDouble(learningRate, minibatchSize); IList <Learner> parameterLearners = new List <Learner>() { Learner.SGDLearner(lastLayer.Parameters(), learningRatePerSample) }; Trainer trainer = Trainer.CreateTrainer(lastLayer, lossFunction, evalErrorFunction, parameterLearners); double nbSamplesToUseForTraining = 20000; int numMinibatchesToTrain = (int)(nbSamplesToUseForTraining / (int)minibatchSize); // train the model for (int minibatchCount = 0; minibatchCount < numMinibatchesToTrain; minibatchCount++) { IEnumerable <DataPoint> trainingData = GenerateData((int)minibatchSize); List <double> minibatchInput = new List <double>(); List <double> minibatchOutput = new List <double>(); foreach (DataPoint row in trainingData) { minibatchInput.Add(row.Age); minibatchInput.Add(row.TumorSize); minibatchOutput.Add(row.HasCancer ? 0d : 1d); minibatchOutput.Add(row.HasCancer ? 1d : 0d); } Value inputData = Value.CreateBatch <double>(NDShape.CreateNDShape(new int[] { nbDimensionsInput }), minibatchInput, device); Value outputData = Value.CreateBatch <double>(NDShape.CreateNDShape(new int[] { nbLabels }), minibatchOutput, device); trainer.TrainMinibatch(new Dictionary <Variable, Value>() { { inputVariables, inputData }, { expectedOutput, outputData } }, false, device); PrintTrainingProgress(trainer, minibatchCount); } // test { int testSize = 100; IEnumerable <DataPoint> trainingData = GenerateData(testSize); List <double> minibatchInput = new List <double>(); List <double> minibatchOutput = new List <double>(); foreach (DataPoint row in trainingData) { minibatchInput.Add(row.Age); minibatchInput.Add(row.TumorSize); minibatchOutput.Add(row.HasCancer ? 0d : 1d); minibatchOutput.Add(row.HasCancer ? 1d : 0d); } Value inputData = Value.CreateBatch <double>(NDShape.CreateNDShape(new int[] { nbDimensionsInput }), minibatchInput, device); Value outputData = Value.CreateBatch <double>(NDShape.CreateNDShape(new int[] { nbLabels }), minibatchOutput, device); IList <IList <double> > expectedOneHot = outputData.GetDenseData <double>(lastLayer.Output); IList <int> expectedLabels = expectedOneHot.Select(l => l.IndexOf(1.0d)).ToList(); var outputDataMap = new Dictionary <Variable, Value>() { { lastLayer.Output, null } }; lastLayer.Evaluate( new Dictionary <Variable, Value>() { { inputVariables, inputData } }, outputDataMap, device); Value outputValue = outputDataMap[lastLayer.Output]; IList <IList <double> > actualLabelSoftMax = outputValue.GetDenseData <double>(lastLayer.Output); var actualLabels = actualLabelSoftMax.Select((IList <double> l) => l.IndexOf(l.Max())).ToList(); int misMatches = actualLabels.Zip(expectedLabels, (a, b) => a.Equals(b) ? 0 : 1).Sum(); Debug.WriteLine($"Validating Model: Total Samples = {testSize}, Misclassify Count = {misMatches}"); } }
public void Run() { var device = DeviceDescriptor.UseDefaultDevice(); var util = new Example_103_Util(); // data string trainImagesPath = "./Example_103/train-images-idx3-ubyte.gz"; string trainLabelsPath = "./Example_103/train-labels-idx1-ubyte.gz"; List <byte[]> trainImages = util.LoadImages(trainImagesPath); List <int> trainLabels = util.LoadLabels(trainLabelsPath); List <int[]> trainLabels1Hot = trainLabels.Select(x => util.ConvertTo1Hot(x)).ToList(); string evelImagesPath = "./Example_103/t10k-images-idx3-ubyte.gz"; string evalLabelsPath = "./Example_103/t10k-labels-idx1-ubyte.gz"; List <byte[]> evalImages = util.LoadImages(evelImagesPath); List <int> evalLabels = util.LoadLabels(evalLabelsPath); List <int[]> evalLabels1Hot = evalLabels.Select(x => util.ConvertTo1Hot(x)).ToList(); // model int sampleSize = trainImages.Count; int nbLabels = 10; // de 0 à 10 Variable inputVariables = Variable.InputVariable(NDShape.CreateNDShape(new[] { 28, 28, 1 }), DataType.Double, "input"); Variable expectedOutput = Variable.InputVariable(NDShape.CreateNDShape(new int[] { nbLabels }), DataType.Double, "output"); var scaledInput = CNTKLib.ElementTimes(Constant.Scalar <double>(1.0 / 255.0, device), inputVariables); Function lastLayer = DefineModel_103D(util, nbLabels, scaledInput); Function lossFunction = CNTKLib.CrossEntropyWithSoftmax(lastLayer, expectedOutput); Function evalErrorFunction = CNTKLib.ClassificationError(lastLayer, expectedOutput); // training Trainer trainer; { // define training uint minibatchSize = 64; double learningRate = 0.2; TrainingParameterScheduleDouble learningRatePerSample = new TrainingParameterScheduleDouble(learningRate, minibatchSize); List <Learner> parameterLearners = new List <Learner>() { Learner.SGDLearner(lastLayer.Parameters(), learningRatePerSample) }; trainer = Trainer.CreateTrainer(lastLayer, lossFunction, evalErrorFunction, parameterLearners); // run training int nbSamplesToUseForTraining = trainImages.Count; int numSweepsToTrainWith = 10; // traduction de sweep ? int numMinibatchesToTrain = nbSamplesToUseForTraining * numSweepsToTrainWith / (int)minibatchSize; var minibatchSource = new Example_103_MinibatchSource(inputVariables, trainImages, expectedOutput, trainLabels1Hot, nbSamplesToUseForTraining, numSweepsToTrainWith, minibatchSize, device); for (int minibatchCount = 0; minibatchCount < numMinibatchesToTrain; minibatchCount++) { IDictionary <Variable, MinibatchData> data = minibatchSource.GetNextRandomMinibatch(); trainer.TrainMinibatch(data, device); util.PrintTrainingProgress(trainer, minibatchCount); } } // evaluate { uint testMinibatchSize = 512; int nbSamplesToTest = evalImages.Count; int numMinibatchesToTrain = nbSamplesToTest / (int)testMinibatchSize; double testResult = 0; var minibatchSource = new Example_103_MinibatchSource(inputVariables, evalImages, expectedOutput, evalLabels1Hot, nbSamplesToTest, 1, testMinibatchSize, device); for (int minibatchCount = 0; minibatchCount < numMinibatchesToTrain; minibatchCount++) { IDictionary <Variable, MinibatchData> data = minibatchSource.GetNextRandomMinibatch(); UnorderedMapVariableMinibatchData evalInput = new UnorderedMapVariableMinibatchData(); foreach (var row in data) { evalInput[row.Key] = row.Value; } double error = trainer.TestMinibatch(evalInput, device); testResult += error; //var z = CNTKLib.Softmax(lastLayer); //var tOut = new Dictionary<Variable, Value>() { { z.Output, null } }; //z.Evaluate( // new Dictionary<Variable, Value>() { { inputVariables, data[inputVariables].data } }, // tOut, // device // ); //Value outputValue = tOut[z.Output]; //IList<IList<double>> actualLabelSoftMax = outputValue.GetDenseData<double>(z.Output); //var actualLabels = actualLabelSoftMax.Select((IList<double> l) => l.IndexOf(l.Max())).ToList(); //Value expectedOutputValue = data[expectedOutput].data; //IList<IList<double>> expectedLabelsSoftmax = expectedOutputValue.GetDenseData<double>(z.Output); //var expectedLabels = expectedLabelsSoftmax.Select((IList<double> l) => l.IndexOf(l.Max())).ToList(); //for(int i = 0; i < expectedLabels.Count; i++) //{ // if (actualLabels[i] != expectedLabels[i]) // { // Debug.WriteLine($"{actualLabels[i]} {expectedLabels[i]}"); // } //} //int misMatches = actualLabels.Zip(expectedLabels, (a, b) => a.Equals(b) ? 0 : 1).Sum(); Debug.WriteLine($"Average test error: {(testResult / (minibatchCount + 1)):p2}"); } Debug.WriteLine($"Average test error: {(testResult / numMinibatchesToTrain):p2}"); } }