static Model CreateModel(Function inputVariable, Variable targetVariable, int targetCount,
                                 DataType dataType, DeviceDescriptor device)
        {
            var random = new Random(232);
            Func <CNTKDictionary> weightInit = () => Initializers.GlorotNormal(random.Next());
            var biasInit = Initializers.Zero();

            // Create the architecture.
            var network = inputVariable

                          .Dense(32, weightInit(), biasInit, device, dataType)
                          .ReLU()
                          .Dense(32, weightInit(), biasInit, device, dataType)
                          .ReLU()
                          .Dense(targetCount, weightInit(), biasInit, device, dataType);

            // loss
            var lossFunc   = Losses.MeanSquaredError(network.Output, targetVariable);
            var metricFunc = Losses.MeanAbsoluteError(network.Output, targetVariable);

            // setup trainer.
            var learner = CntkCatalyst.Learners.Adam(network.Parameters());
            var trainer = CNTKLib.CreateTrainer(network, lossFunc, metricFunc, new LearnerVector {
                learner
            });

            var model = new Model(trainer, network, dataType, device);

            Trace.WriteLine(model.Summary());
            return(model);
        }
Exemplo n.º 2
0
        public void Model_Use_Case()
        {
            var inputShape      = new int[] { 28, 28, 1 };
            var numberOfClasses = 10;
            var outputShape     = new int[] { numberOfClasses };

            (var observations, var targets) = CreateArtificialData(inputShape, outputShape, observationCount: 100);

            var dataType = DataType.Float;
            var device   = DeviceDescriptor.UseDefaultDevice();

            var random = new Random(232);
            Func <CNTKDictionary> weightInit = () => Initializers.GlorotNormal(random.Next());
            var biasInit = Initializers.Zero();

            // Create the architecture.
            var network = Layers.Input(inputShape, dataType)
                          .Dense(512, weightInit(), biasInit, device, dataType)
                          .ReLU()
                          .Dense(numberOfClasses, weightInit(), biasInit, device, dataType)
                          .Softmax();

            // setup input and target variables.
            var inputVariable  = network.Arguments[0];
            var targetVariable = Variable.InputVariable(network.Output.Shape, dataType);

            // loss
            var lossFunc   = Losses.CategoricalCrossEntropy(network.Output, targetVariable);
            var metricFunc = Metrics.Accuracy(network.Output, targetVariable);

            // setup trainer.
            var learner = Learners.MomentumSGD(network.Parameters());
            var trainer = CNTKLib.CreateTrainer(network, lossFunc, metricFunc, new LearnerVector {
                learner
            });

            var model = new Model(trainer, network, dataType, device);

            // setup name to data.
            var nameToData = new Dictionary <string, MemoryMinibatchData>
            {
                { "observations", observations },
                { "targets", targets }
            };

            // setup name to variable
            var nameToVariable = new Dictionary <string, Variable>
            {
                { "observations", inputVariable },
                { "targets", targetVariable },
            };

            var trainSource = new MemoryMinibatchSource(nameToVariable, nameToData, seed: 232, randomize: true);

            model.Fit(trainSource, batchSize: 8, epochs: 2);

            (var loss, var metric) = model.Evaluate(trainSource);

            Trace.WriteLine($"Final evaluation - Loss: {loss}, Metric: {metric}");
        }
Exemplo n.º 3
0
        static void Main(string[] args)
        {
            Console.WriteLine("MNIST Test");

            int seed;

            using (var rng = new RNGCryptoServiceProvider())
            {
                var buffer = new byte[sizeof(int)];

                rng.GetBytes(buffer);
                seed = BitConverter.ToInt32(buffer, 0);
            }

            RandomProvider.SetSeed(seed);

            var   assembly            = Assembly.GetExecutingAssembly();
            var   filename            = "CNN.xml";
            var   serializer          = new DataContractSerializer(typeof(IEnumerable <Layer>), new Type[] { typeof(Convolution), typeof(BatchNormalization), typeof(Activation), typeof(ReLU), typeof(MaxPooling), typeof(FullyConnected), typeof(Softmax) });
            var   random              = RandomProvider.GetRandom();
            var   trainingList        = new List <Tuple <double[], double[]> >();
            var   testList            = new List <Tuple <double[], double[]> >();
            var   accuracyList        = new List <double>();
            var   lossList            = new List <double>();
            var   logPath             = "Log.csv";
            var   channels            = 1;
            var   imageWidth          = 28;
            var   imageHeight         = 28;
            var   filters             = 30;
            var   filterWidth         = 5;
            var   filterHeight        = 5;
            var   poolWidth           = 2;
            var   poolHeight          = 2;
            var   activationMapWidth  = Convolution.GetActivationMapLength(imageWidth, filterWidth);
            var   activationMapHeight = Convolution.GetActivationMapLength(imageHeight, filterHeight);
            var   outputWidth         = MaxPooling.GetOutputLength(activationMapWidth, poolWidth);
            var   outputHeight        = MaxPooling.GetOutputLength(activationMapHeight, poolHeight);
            Model model;

            using (Stream
                   imagesStream = assembly.GetManifestResourceStream("MNISTTest.train-images.idx3-ubyte"),
                   labelsStream = assembly.GetManifestResourceStream("MNISTTest.train-labels.idx1-ubyte"))
            {
                foreach (var image in MnistImage.Load(imagesStream, labelsStream).Take(1000))
                {
                    var t = new double[10];

                    for (int i = 0; i < 10; i++)
                    {
                        if (i == image.Label)
                        {
                            t[i] = 1.0;
                        }
                        else
                        {
                            t[i] = 0.0;
                        }
                    }

                    trainingList.Add(Tuple.Create <double[], double[]>(image.Normalize(), t));
                }
            }

            using (Stream
                   imagesStream = assembly.GetManifestResourceStream("MNISTTest.t10k-images.idx3-ubyte"),
                   labelsStream = assembly.GetManifestResourceStream("MNISTTest.t10k-labels.idx1-ubyte"))
            {
                foreach (var image in MnistImage.Load(imagesStream, labelsStream).Take(1000))
                {
                    var t = new double[10];

                    for (int i = 0; i < 10; i++)
                    {
                        if (i == image.Label)
                        {
                            t[i] = 1.0;
                        }
                        else
                        {
                            t[i] = 0.0;
                        }
                    }

                    testList.Add(Tuple.Create <double[], double[]>(image.Normalize(), t));
                }
            }

            if (File.Exists(filename))
            {
                using (XmlReader xmlReader = XmlReader.Create(filename))
                {
                    model = new Model((IEnumerable <Layer>)serializer.ReadObject(xmlReader), new Adam(), new SoftmaxCrossEntropy());
                }
            }
            else
            {
                /*model = new Model(new Layer[] {
                 *  new Convolutional(channels, imageWidth, imageHeight, filters, filterWidth, filterHeight, (fanIn, fanOut) => Initializers.HeNormal(fanIn)),
                 *  new Activation(filters * activationMapWidth * activationMapHeight, new ReLU()),
                 *  new MaxPooling(filters, activationMapWidth, activationMapHeight, poolWidth, poolHeight),
                 *  new FullyConnected(filters * outputWidth * outputHeight, 100, (fanIn, fanOut) => Initializers.HeNormal(fanIn)),
                 *  new Activation(100, new ReLU()),
                 * new Softmax(100, 10, (fanIn, fanOut) => Initializers.GlorotNormal(fanIn, fanOut))
                 * }, new Adam(), new SoftmaxCrossEntropy());*/
                /*var inputLayer = new Convolutional(channels, imageWidth, imageHeight, filters, filterWidth, filterHeight, (fanIn, fanOut) => Initializers.HeNormal(fanIn));
                 *
                 * new Softmax(
                 *  new Activation(
                 *      new FullyConnected(
                 *          new MaxPooling(
                 *              new Activation(inputLayer, new ReLU()),
                 *              filters, inputLayer.ActivationMapWidth, inputLayer.ActivationMapHeight, poolWidth, poolHeight),
                 *          100, (fanIn, fanOut) => Initializers.HeNormal(fanIn)),
                 *      new ReLU()),
                 *  10, (fanIn, fanOut) => Initializers.GlorotNormal(fanIn, fanOut));
                 *
                 * model = new Model(inputLayer, new Adam(), new SoftmaxCrossEntropy());*/
                model = new Model(
                    new Convolution(channels, imageWidth, imageHeight, filters, filterWidth, filterHeight, (fanIn, fanOut) => Initializers.HeNormal(fanIn),
                                    new Activation(new ReLU(),
                                                   new MaxPooling(filters, activationMapWidth, activationMapHeight, poolWidth, poolHeight,
                                                                  new FullyConnected(filters * outputWidth * outputHeight, (fanIn, fanOut) => Initializers.HeNormal(fanIn),
                                                                                     new Activation(new ReLU(),
                                                                                                    new Softmax(100, 10, (fanIn, fanOut) => Initializers.GlorotNormal(fanIn, fanOut))))))),
                    new Adam(), new SoftmaxCrossEntropy());
                int epochs     = 50;
                int iterations = 1;

                model.Stepped += (sender, e) =>
                {
                    double tptn = 0.0;

                    trainingList.ForEach(x =>
                    {
                        var vector = model.Predicate(x.Item1);
                        var i      = ArgMax(vector);
                        var j      = ArgMax(x.Item2);

                        if (i == j && Math.Round(vector[i]) == x.Item2[j])
                        {
                            tptn += 1.0;
                        }
                    });

                    var accuracy = tptn / trainingList.Count;

                    accuracyList.Add(accuracy);
                    lossList.Add(model.Loss);

                    Console.WriteLine("Epoch {0}/{1}", iterations, epochs);
                    Console.WriteLine("Accuracy: {0}, Loss: {1}", accuracy, model.Loss);

                    iterations++;
                };

                Console.WriteLine("Training...");

                var stopwatch = Stopwatch.StartNew();

                model.Fit(trainingList, epochs, 100);

                stopwatch.Stop();

                Console.WriteLine("Done ({0}).", stopwatch.Elapsed.ToString());
            }

            double testTptn = 0.0;

            testList.ForEach(x =>
            {
                var vector = model.Predicate(x.Item1);
                var i      = ArgMax(vector);
                var j      = ArgMax(x.Item2);

                if (i == j && Math.Round(vector[i]) == x.Item2[j])
                {
                    testTptn += 1.0;
                }
            });

            Console.WriteLine("Accuracy: {0}", testTptn / testList.Count);

            if (accuracyList.Count > 0)
            {
                var logDictionary = new Dictionary <string, IEnumerable <double> >();

                logDictionary.Add("Accuracy", accuracyList);
                logDictionary.Add("Loss", lossList);

                ToCsv(logPath, logDictionary);

                Console.WriteLine("Saved log to {0}...", logPath);
            }

            XmlWriterSettings settings = new XmlWriterSettings();

            settings.Indent   = true;
            settings.Encoding = new System.Text.UTF8Encoding(false);

            using (XmlWriter xmlWriter = XmlWriter.Create(filename, settings))
            {
                serializer.WriteObject(xmlWriter, model.Layers);
                xmlWriter.Flush();
            }
        }
Exemplo n.º 4
0
        //[TestMethod]
        public void Fitter_Loop()
        {
            var inputShape      = new int[] { 28, 28, 1 };
            var numberOfClasses = 10;
            var outputShape     = new int[] { numberOfClasses };

            (var observations, var targets) = CreateArtificialData(inputShape, outputShape, observationCount: 10000);

            var dataType = DataType.Float;
            var device   = DeviceDescriptor.UseDefaultDevice();

            var random = new Random(232);
            Func <CNTKDictionary> weightInit = () => Initializers.GlorotNormal(random.Next());
            var biasInit = Initializers.Zero();

            // Create the architecture.
            var network = Layers.Input(inputShape, dataType)
                          .Dense(512, weightInit(), biasInit, device, dataType)
                          .ReLU()
                          .Dense(numberOfClasses, weightInit(), biasInit, device, dataType)
                          .Softmax();

            // setup input and target variables.
            var inputVariable  = network.Arguments[0];
            var targetVariable = Variable.InputVariable(network.Output.Shape, dataType);

            // loss
            var loss   = Losses.CategoricalCrossEntropy(network.Output, targetVariable);
            var metric = Metrics.Accuracy(network.Output, targetVariable);

            // setup trainer.
            var learner = Learners.MomentumSGD(network.Parameters());
            var trainer = CNTKLib.CreateTrainer(network, loss, metric, new LearnerVector {
                learner
            });

            // data names
            var observationsName = "observations";
            var targetsName      = "targets";

            // setup name to variable map.
            var nameToVariable = new Dictionary <string, Variable>
            {
                { observationsName, inputVariable },
                { targetsName, targetVariable },
            };

            // setup name to data map.
            var nameToData = new Dictionary <string, MemoryMinibatchData>
            {
                { observationsName, observations },
                { targetsName, targets }
            };

            var minibatchSource = new MemoryMinibatchSource(nameToVariable, nameToData, seed: 232, randomize: true);

            // setup Fitter
            var fitter = new Fitter(trainer, device);

            // variables for training loop.
            var inputMap = new Dictionary <Variable, Value>();

            var epochs    = 10;
            int batchSize = 32;

            for (int epoch = 0; epoch < epochs;)
            {
                var(minibatch, isSweepEnd) = minibatchSource.GetNextMinibatch(batchSize, device);
                fitter.FitNextStep(minibatch, batchSize);

                if (isSweepEnd)
                {
                    var currentLoss   = fitter.CurrentLoss;
                    var currentMetric = fitter.CurrentMetric;
                    fitter.ResetLossAndMetricAccumulators();

                    var traceOutput = $"Epoch: {epoch + 1:000} Loss = {currentLoss:F8}, Metric = {currentMetric:F8}";

                    ++epoch;

                    Trace.WriteLine(traceOutput);
                }
            }
        }
Exemplo n.º 5
0
        static void Main(string[] args)
        {
            Console.WriteLine("MNIST Test");

            int seed;

            using (var rng = new RNGCryptoServiceProvider())
            {
                var buffer = new byte[sizeof(int)];

                rng.GetBytes(buffer);
                seed = BitConverter.ToInt32(buffer, 0);
            }

            RandomProvider.SetSeed(seed);

            var assembly      = Assembly.GetExecutingAssembly();
            var random        = RandomProvider.GetRandom();
            var trainingList  = new List <Tuple <double[], double[]> >();
            var testList      = new List <Tuple <double[], double[]> >();
            var accuracyList  = new List <double>();
            var lossList      = new List <double>();
            var logDictionary = new Dictionary <string, IEnumerable <double> >();
            var logPath       = "Log.csv";
            var channels      = 1;
            var imageWidth    = 28;
            var imageHeight   = 28;
            var filters       = 30;
            var filterWidth   = 5;
            var filterHeight  = 5;
            var poolWidth     = 2;
            var poolHeight    = 2;

            using (Stream
                   imagesStream = assembly.GetManifestResourceStream("MNISTTest.train-images.idx3-ubyte"),
                   labelsStream = assembly.GetManifestResourceStream("MNISTTest.train-labels.idx1-ubyte"))
            {
                foreach (var image in MnistImage.Load(imagesStream, labelsStream).Take(1000))
                {
                    var t = new double[10];

                    for (int i = 0; i < 10; i++)
                    {
                        if (i == image.Label)
                        {
                            t[i] = 1.0;
                        }
                        else
                        {
                            t[i] = 0.0;
                        }
                    }

                    trainingList.Add(Tuple.Create <double[], double[]>(image.Normalize(), t));
                }
            }

            using (Stream
                   imagesStream = assembly.GetManifestResourceStream("MNISTTest.t10k-images.idx3-ubyte"),
                   labelsStream = assembly.GetManifestResourceStream("MNISTTest.t10k-labels.idx1-ubyte"))
            {
                foreach (var image in MnistImage.Load(imagesStream, labelsStream).Take(1000))
                {
                    var t = new double[10];

                    for (int i = 0; i < 10; i++)
                    {
                        if (i == image.Label)
                        {
                            t[i] = 1.0;
                        }
                        else
                        {
                            t[i] = 0.0;
                        }
                    }

                    testList.Add(Tuple.Create <double[], double[]>(image.Normalize(), t));
                }
            }

            var inputLayer  = new ConvolutionalPoolingLayer(channels, imageWidth, imageHeight, filters, filterWidth, filterHeight, poolWidth, poolHeight, new ReLU(), (index, fanIn, fanOut) => Initializers.HeNormal(fanIn));
            var hiddenLayer = new FullyConnectedLayer(inputLayer, 100, new ReLU(), (index, fanIn, fanOut) => Initializers.HeNormal(fanIn));
            var outputLayer = new SoftmaxLayer(hiddenLayer, 10, (index, fanIn, fanOut) => Initializers.GlorotNormal(fanIn, fanOut));
            var network     = new Network(inputLayer, outputLayer, new Adam(), new SoftmaxCrossEntropy());
            int epochs      = 50;
            int iterations  = 1;

            network.Stepped += (sender, e) =>
            {
                double tptn = 0;

                trainingList.ForEach(x =>
                {
                    var vector = network.Predicate(x.Item1);
                    var i      = ArgMax(vector);
                    var j      = ArgMax(x.Item2);

                    if (i == j && Math.Round(vector[i]) == x.Item2[j])
                    {
                        tptn += 1.0;
                    }
                });

                var accuracy = tptn / trainingList.Count;

                accuracyList.Add(accuracy);
                lossList.Add(network.Loss);

                Console.WriteLine("Epoch {0}/{1}", iterations, epochs);
                Console.WriteLine("Accuracy: {0}, Loss: {1}", accuracy, network.Loss);

                iterations++;
            };

            Console.WriteLine("Training...");

            var stopwatch = Stopwatch.StartNew();

            network.Train(trainingList, epochs, 100);

            stopwatch.Stop();

            Console.WriteLine("Done ({0}).", stopwatch.Elapsed.ToString());

            double testTptn = 0;

            testList.ForEach(x =>
            {
                var vector = network.Predicate(x.Item1);
                var i      = ArgMax(vector);
                var j      = ArgMax(x.Item2);

                if (i == j && Math.Round(vector[i]) == x.Item2[j])
                {
                    testTptn += 1.0;
                }
            });

            Console.WriteLine("Accuracy: {0}", testTptn / testList.Count);

            logDictionary.Add("Accuracy", accuracyList);
            logDictionary.Add("Loss", lossList);

            ToCsv(logPath, logDictionary);

            Console.Write("Saved log to {0}...", logPath);
        }
        public void Run()
        {
            // Prepare data
            var baseDataDirectoryPath = @"E:\DataSets\Imdb";
            var trainFilePath         = Path.Combine(baseDataDirectoryPath, "imdb_sparse_train_50w.txt");
            var testFilePath          = Path.Combine(baseDataDirectoryPath, "imdb_sparse_test_50w.txt");

            // Define the input and output shape.
            var inputShape      = new int[] { 129888 + 4 }; // Number distinct input words + offset for one-hot, sparse
            var numberOfClasses = 2;
            var outputShape     = new int[] { numberOfClasses };

            // Define data type and device for the model.
            var dataType = DataType.Float;
            var device   = DeviceDescriptor.UseDefaultDevice();

            // Setup initializers
            var random = new Random(232);
            Func <CNTKDictionary> weightInit = () => Initializers.GlorotNormal(random.Next());
            var biasInit = Initializers.Zero();

            // Ensure reproducible results with CNTK.
            CNTKLib.SetFixedRandomSeed((uint)random.Next());
            CNTKLib.ForceDeterministicAlgorithms();

            // Create the architecture.
            var network = Layers.Input(inputShape, dataType, isSparse: true)
                          .Embedding(32, weightInit(), dataType, device)
                          .LSTMStack(32, 1, weightInit(), false, device, dataType)
                          .Dense(numberOfClasses, weightInit(), biasInit, device, dataType)
                          .Softmax();

            // Since we are processing sequence data,
            // wrap network in sequenceLast.
            network = CNTKLib.SequenceLast(network);

            // Get input and target variables from network.
            var inputVariable  = network.Arguments[0];
            var targetVariable = Variable.InputVariable(outputShape, dataType,
                                                        dynamicAxes: new List <Axis>()
            {
                Axis.DefaultBatchAxis()
            },
                                                        isSparse: false);

            // setup loss and learner.
            var lossFunc   = Losses.CategoricalCrossEntropy(network.Output, targetVariable);
            var metricFunc = Metrics.Accuracy(network.Output, targetVariable);

            // setup trainer.
            var learner = Learners.Adam(network.Parameters());
            var trainer = Trainer.CreateTrainer(network, lossFunc, metricFunc, new List <Learner> {
                learner
            });

            // Create the network.
            var model = new Model(trainer, network, dataType, device);

            // Write model summary.
            Trace.WriteLine(model.Summary());

            // Setup minibatch sources.
            // Network will be trained using the training set,
            // and tested using the test set.
            var featuresName = "x";
            var targetsName  = "y";

            // setup name to variable map.
            var nameToVariable = new Dictionary <string, Variable>
            {
                { featuresName, inputVariable },
                { targetsName, targetVariable },
            };

            // The order of the training data is randomize.
            var train = CreateMinibatchSource(trainFilePath, featuresName, targetsName,
                                              numberOfClasses, inputShape, randomize: true);
            var trainingSource = new CntkMinibatchSource(train, nameToVariable);

            // Notice randomization is switched off for test data.
            var test = CreateMinibatchSource(testFilePath, featuresName, targetsName,
                                             numberOfClasses, inputShape, randomize: false);
            var testSource = new CntkMinibatchSource(test, nameToVariable);

            // Train the model using the training set.
            var history = model.Fit(trainingSource, epochs: 100, batchSize: 512,
                                    validationMinibatchSource: testSource);

            // Trace loss and validation history
            TraceLossValidationHistory(history);

            // Evaluate the model using the test set.
            var(loss, metric) = model.Evaluate(testSource);

            // Write the test set loss and metric to debug output.
            Trace.WriteLine($"Test set - Loss: {loss}, Metric: {metric}");

            // Write first ten predictions
            var predictions = model.Predict(testSource)
                              .Take(10);

            // Use tensor data directly, since only 1 element pr. sample.
            Trace.WriteLine($"Predictions: [{string.Join(", ", predictions.Select(p => p.First()))}]");
        }
Exemplo n.º 7
0
        public void Run()
        {
            // Prepare data
            var baseDataDirectoryPath = @"E:\DataSets\CatsAndDogs";
            var mapFiles = PrepareMapFiles(baseDataDirectoryPath);

            // Define the input and output shape.
            var inputShape      = new int[] { 150, 150, 3 };
            var numberOfClasses = 2;
            var outputShape     = new int[] { numberOfClasses };

            // Define data type and device for the model.
            var dataType = DataType.Float;
            var device   = DeviceDescriptor.UseDefaultDevice();

            // Setup initializers
            var random = new Random(232);
            Func <CNTKDictionary> weightInit = () => Initializers.GlorotNormal(random.Next());
            var biasInit = Initializers.Zero();

            // Ensure reproducible results with CNTK.
            CNTKLib.SetFixedRandomSeed((uint)random.Next());
            CNTKLib.ForceDeterministicAlgorithms();

            // Create the architecture.
            var network = Layers.Input(inputShape, dataType)
                          .Conv2D((3, 3), 32, (1, 1), Padding.None, weightInit(), biasInit, device, dataType)
                          .ReLU()
                          .MaxPool2D((2, 2), (2, 2), Padding.None)

                          .Conv2D((3, 3), 64, (1, 1), Padding.None, weightInit(), biasInit, device, dataType)
                          .ReLU()
                          .MaxPool2D((2, 2), (2, 2), Padding.None)

                          .Conv2D((3, 3), 128, (1, 1), Padding.None, weightInit(), biasInit, device, dataType)
                          .ReLU()
                          .MaxPool2D((2, 2), (2, 2), Padding.None)

                          .Conv2D((3, 3), 128, (1, 1), Padding.None, weightInit(), biasInit, device, dataType)
                          .ReLU()
                          .MaxPool2D((2, 2), (2, 2), Padding.None)

                          .Dense(512, weightInit(), biasInit, device, dataType)
                          .ReLU()
                          .Dense(numberOfClasses, weightInit(), biasInit, device, dataType)
                          .Softmax();

            // Get input and target variables from network.
            var inputVariable  = network.Arguments[0];
            var targetVariable = Variable.InputVariable(outputShape, dataType);

            // setup loss and learner.
            var lossFunc   = Losses.CategoricalCrossEntropy(network.Output, targetVariable);
            var metricFunc = Metrics.Accuracy(network.Output, targetVariable);

            // setup trainer.
            var learner = Learners.RMSProp(network.Parameters());
            var trainer = Trainer.CreateTrainer(network, lossFunc, metricFunc, new List <Learner> {
                learner
            });

            // Create the network.
            var model = new Model(trainer, network, dataType, device);

            // Write model summary.
            Trace.WriteLine(model.Summary());

            // Setup minibatch sources.
            var featuresName = "features";
            var targetsName  = "targets";

            // setup name to variable map.
            var nameToVariable = new Dictionary <string, Variable>
            {
                { featuresName, inputVariable },
                { targetsName, targetVariable },
            };
            var train = CreateMinibatchSource(mapFiles.trainFilePath, featuresName, targetsName,
                                              numberOfClasses, inputShape, augmentation: true);
            var trainingSource = new CntkMinibatchSource(train, nameToVariable);

            // Notice augmentation is switched off for validation data.
            var valid = CreateMinibatchSource(mapFiles.validFilePath, featuresName, targetsName,
                                              numberOfClasses, inputShape, augmentation: false);
            var validationSource = new CntkMinibatchSource(valid, nameToVariable);

            // Notice augmentation is switched off for test data.
            var test = CreateMinibatchSource(mapFiles.testFilePath, featuresName, targetsName,
                                             numberOfClasses, inputShape, augmentation: false);
            var testSource = new CntkMinibatchSource(test, nameToVariable);

            // Train the model using the training set.
            model.Fit(trainMinibatchSource: trainingSource,
                      epochs: 100, batchSize: 32,
                      validationMinibatchSource: validationSource);

            // Evaluate the model using the test set.
            var(loss, metric) = model.Evaluate(testSource);

            // Write the test set loss and metric to debug output.
            Trace.WriteLine($"Test set - Loss: {loss}, Metric: {metric}");

            // Save model.
            model.Network.Save("cats_and_dogs_small_2.cntk");
        }
        public void Run()
        {
            // Prepare data
            var baseDataDirectoryPath = @"E:\DataSets\Mnist";
            var trainFilePath         = Path.Combine(baseDataDirectoryPath, "Train-28x28_cntk_text.txt");
            var testFilePath          = Path.Combine(baseDataDirectoryPath, "Test-28x28_cntk_text.txt");

            // Define the input and output shape.
            var inputShape      = new int[] { 28, 28, 1 };
            var numberOfClasses = 10;
            var outputShape     = new int[] { numberOfClasses };

            // Define data type and device for the model.
            var dataType = DataType.Float;
            var device   = DeviceDescriptor.UseDefaultDevice();

            // Setup initializers
            var random = new Random(232);
            Func <CNTKDictionary> weightInit = () => Initializers.GlorotNormal(random.Next());
            var biasInit = Initializers.Zero();

            // Ensure reproducible results with CNTK.
            CNTKLib.SetFixedRandomSeed((uint)random.Next());
            CNTKLib.ForceDeterministicAlgorithms();

            // Create the architecture.
            var input = Layers.Input(inputShape, dataType);
            // scale input between 0 and 1.
            var scaledInput = CNTKLib.ElementTimes(Constant.Scalar(0.00390625f, device), input);

            var network = scaledInput
                          .Conv2D((3, 3), 32, (1, 1), Padding.None, weightInit(), biasInit, device, dataType)
                          .ReLU()
                          .MaxPool2D((2, 2), (2, 2), Padding.None)

                          .Conv2D((3, 3), 32, (1, 1), Padding.None, weightInit(), biasInit, device, dataType)
                          .ReLU()
                          .MaxPool2D((2, 2), (2, 2), Padding.None)

                          .Conv2D((3, 3), 32, (1, 1), Padding.None, weightInit(), biasInit, device, dataType)
                          .ReLU()

                          .Dense(64, weightInit(), biasInit, device, dataType)
                          .ReLU()
                          .Dense(numberOfClasses, weightInit(), biasInit, device, dataType)
                          .Softmax();

            // Get input and target variables from network.
            var inputVariable  = network.Arguments[0];
            var targetVariable = Variable.InputVariable(outputShape, dataType);

            // setup loss and learner.
            var lossFunc   = Losses.CategoricalCrossEntropy(network.Output, targetVariable);
            var metricFunc = Metrics.Accuracy(network.Output, targetVariable);

            // setup trainer.
            var learner = Learners.RMSProp(network.Parameters());
            var trainer = Trainer.CreateTrainer(network, lossFunc, metricFunc, new List <Learner> {
                learner
            });

            // Create the network.
            var model = new Model(trainer, network, dataType, device);

            // Write model summary.
            Trace.WriteLine(model.Summary());

            // Setup minibatch sources.
            // Network will be trained using the training set,
            // and tested using the test set.

            // setup name to variable map.
            var nameToVariable = new Dictionary <string, Variable>
            {
                { "features", inputVariable },
                { "labels", targetVariable },
            };

            // The order of the training data is randomize.
            var train          = CreateMinibatchSource(trainFilePath, nameToVariable, randomize: true);
            var trainingSource = new CntkMinibatchSource(train, nameToVariable);

            // Notice randomization is switched off for test data.
            var test       = CreateMinibatchSource(testFilePath, nameToVariable, randomize: false);
            var testSource = new CntkMinibatchSource(test, nameToVariable);

            // Train the model using the training set.
            model.Fit(trainingSource, epochs: 5, batchSize: 64);

            // Evaluate the model using the test set.
            var(loss, metric) = model.Evaluate(testSource);

            // Write the test set loss and metric to debug output.
            Trace.WriteLine($"Test set - Loss: {loss}, Metric: {metric}");
        }