// create ProgressWriterVector with attached native progress writer public static ProgressWriterVector CreateVector(string path, Function network) { var progress = new ProgressWriterVector(); var getV = typeof(ProgressWriterVector).GetMethods(BindingFlags.Static | BindingFlags.NonPublic).First(m => m.Name == "getCPtr"); HandleRef vector = (HandleRef)(getV.Invoke(null, new object[] { progress })); var getF = typeof(Function).GetMethods(BindingFlags.Static | BindingFlags.NonPublic).First(m => m.Name == "getCPtr"); HandleRef function = (HandleRef)(getF.Invoke(null, new object[] { network })); TensorBoardFileWriter.InitVec(vector.Handle, path, function.Handle); return(progress); }
static public void TrainAndEvaluate(DeviceDescriptor device) { // build a logistic regression model Variable featureVariable = Variable.InputVariable(new int[] { inputDim }, DataType.Float); Variable labelVariable = Variable.InputVariable(new int[] { numOutputClasses }, DataType.Float); var classifierOutput = CreateLinearModel(featureVariable, numOutputClasses, device); var loss = CNTKLib.CrossEntropyWithSoftmax(classifierOutput, labelVariable); var evalError = CNTKLib.ClassificationError(classifierOutput, labelVariable); // prepare for training CNTK.TrainingParameterScheduleDouble learningRatePerSample = new CNTK.TrainingParameterScheduleDouble(0.02, 1); IList <Learner> parameterLearners = new List <Learner>() { Learner.SGDLearner(classifierOutput.Parameters(), learningRatePerSample) }; var progressWriter = new TensorBoardFileWriter("log/test"); var progressWriterVector = TensorBoardFileWriter.CreateVector("log/main", classifierOutput); var trainer = Trainer.CreateTrainer(classifierOutput, loss, evalError, parameterLearners, progressWriterVector); int minibatchSize = 64; int numMinibatchesToTrain = 1000; int updatePerMinibatches = 50; // train the model Random random = new Random(0); for (int minibatchCount = 0; minibatchCount < numMinibatchesToTrain; minibatchCount++) { Value features, labels; GenerateValueData(minibatchSize, inputDim, numOutputClasses, out features, out labels, device); //TODO: sweepEnd should be set properly instead of false. #pragma warning disable 618 trainer.TrainMinibatch( new Dictionary <Variable, Value>() { { featureVariable, features }, { labelVariable, labels } }, device); #pragma warning restore 618 PrintTrainingProgress(trainer, minibatchCount, updatePerMinibatches); progressWriter.WriteValue("random1", (float)random.Next(), minibatchCount); progressWriter.WriteValue("random2", (float)random.Next(), minibatchCount); progressWriter.Flush(); } // test and validate the model int testSize = 100; Value testFeatureValue, expectedLabelValue; GenerateValueData(testSize, inputDim, numOutputClasses, out testFeatureValue, out expectedLabelValue, device); // GetDenseData just needs the variable's shape IList <IList <float> > expectedOneHot = expectedLabelValue.GetDenseData <float>(labelVariable); IList <int> expectedLabels = expectedOneHot.Select(l => l.IndexOf(1.0F)).ToList(); var inputDataMap = new Dictionary <Variable, Value>() { { featureVariable, testFeatureValue } }; var outputDataMap = new Dictionary <Variable, Value>() { { classifierOutput.Output, null } }; classifierOutput.Evaluate(inputDataMap, outputDataMap, device); var outputValue = outputDataMap[classifierOutput.Output]; IList <IList <float> > actualLabelSoftMax = outputValue.GetDenseData <float>(classifierOutput.Output); var actualLabels = actualLabelSoftMax.Select((IList <float> l) => l.IndexOf(l.Max())).ToList(); int misMatches = actualLabels.Zip(expectedLabels, (a, b) => a.Equals(b) ? 0 : 1).Sum(); Console.WriteLine($"Validating Model: Total Samples = {testSize}, Misclassify Count = {misMatches}"); }