Пример #1
0
        public void MemoryLayerTest()
        {
#if DEBUG
            using var context = BrightWireGpuProvider.CreateLinearAlgebra();
            var matrix = context.CreateZeroMatrix(10, 10);
            context.PushLayer();
            var matrix2 = context.CreateZeroMatrix(10, 10);
            context.PopLayer();
            Assert.IsFalse(matrix2.IsValid);
            Assert.IsTrue(matrix.IsValid);
            matrix.Dispose();
            Assert.IsFalse(matrix.IsValid);
#endif
        }
Пример #2
0
        static void MNISTConvolutional(string dataFilesPath)
        {
            using (var lap = BrightWireGpuProvider.CreateLinearAlgebra()) {
                var graph = new GraphFactory(lap);

                Console.Write("Loading training data...");
                var trainingData = _BuildTensors(graph, null, Mnist.Load(dataFilesPath + "train-labels.idx1-ubyte", dataFilesPath + "train-images.idx3-ubyte"));
                var testData     = _BuildTensors(graph, trainingData, Mnist.Load(dataFilesPath + "t10k-labels.idx1-ubyte", dataFilesPath + "t10k-images.idx3-ubyte"));
                Console.WriteLine($"done - {trainingData.RowCount} training images and {testData.RowCount} test images loaded");

                var errorMetric = graph.ErrorMetric.OneHotEncoding;
                var propertySet = graph.CurrentPropertySet
                                  .Use(graph.GradientDescent.RmsProp)
                                  .Use(graph.WeightInitialisation.Xavier)
                ;

                // create the network
                const int   HIDDEN_LAYER_SIZE = 1024;
                const float LEARNING_RATE     = 0.05f;
                var         engine            = graph.CreateTrainingEngine(trainingData, LEARNING_RATE, 32);
                engine.LearningContext.ScheduleLearningRate(15, LEARNING_RATE / 3);
                graph.Connect(engine)
                .AddConvolutional(8, 2, 5, 5, 1, false)
                .Add(graph.ReluActivation())
                .AddDropOut(0.5f)
                .AddMaxPooling(2, 2, 2)
                .AddConvolutional(16, 2, 5, 5, 1)
                .Add(graph.ReluActivation())
                .AddMaxPooling(2, 2, 2)
                .Transpose()
                .AddFeedForward(HIDDEN_LAYER_SIZE)
                .Add(graph.ReluActivation())
                .AddDropOut(0.5f)
                .AddFeedForward(trainingData.OutputSize)
                .Add(graph.SoftMaxActivation())
                .AddBackpropagation(errorMetric)
                ;

                engine.Train(20, testData, errorMetric);

                // export the graph and verify that the error is the same
                var networkGraph    = engine.Graph;
                var executionEngine = graph.CreateEngine(networkGraph);
                var output          = executionEngine.Execute(testData);
                Console.WriteLine(output.Average(o => o.CalculateError(errorMetric)));
            }
        }
Пример #3
0
        /// <summary>
        /// Trains a feed forward neural net on the MNIST data set (handwritten digit recognition)
        /// The data files can be downloaded from http://yann.lecun.com/exdb/mnist/
        /// </summary>
        /// <param name="dataFilesPath">The path to a directory with the four extracted data files</param>
        public static void MNIST(string dataFilesPath)
        {
            using (var lap = BrightWireGpuProvider.CreateLinearAlgebra()) {
                var graph = new GraphFactory(lap);

                Console.Write("Loading training data...");
                var trainingData = _BuildVectors(null, graph, Mnist.Load(dataFilesPath + "train-labels.idx1-ubyte", dataFilesPath + "train-images.idx3-ubyte"));
                var testData     = _BuildVectors(trainingData, graph, Mnist.Load(dataFilesPath + "t10k-labels.idx1-ubyte", dataFilesPath + "t10k-images.idx3-ubyte"));
                Console.WriteLine($"done - {trainingData.RowCount} training images and {testData.RowCount} test images loaded");

                // one hot encoding uses the index of the output vector's maximum value as the classification label
                var errorMetric = graph.ErrorMetric.OneHotEncoding;

                // configure the network properties
                graph.CurrentPropertySet
                .Use(graph.GradientDescent.RmsProp)
                .Use(graph.WeightInitialisation.Xavier)
                ;

                // create the training engine and schedule a training rate change
                const float TRAINING_RATE = 0.1f;
                var         engine        = graph.CreateTrainingEngine(trainingData, TRAINING_RATE, 128);
                engine.LearningContext.ScheduleLearningRate(15, TRAINING_RATE / 3);

                // create the network
                graph.Connect(engine)
                .AddFeedForward(outputSize: 1024)
                .Add(graph.LeakyReluActivation())
                .AddDropOut(dropOutPercentage: 0.5f)
                .AddFeedForward(outputSize: trainingData.OutputSize)
                .Add(graph.SigmoidActivation())
                .AddBackpropagation(errorMetric)
                ;

                // train the network for twenty iterations, saving the model on each improvement
                Models.ExecutionGraph bestGraph = null;
                engine.Train(20, testData, errorMetric, model => bestGraph = model.Graph);

                // export the final model and execute it on the training set
                var executionEngine = graph.CreateEngine(bestGraph ?? engine.Graph);
                var output          = executionEngine.Execute(testData);
                Console.WriteLine($"Final accuracy: {output.Average(o => o.CalculateError(errorMetric)):P2}");
            }
        }
Пример #4
0
        /// <summary>
        /// Trains a neural net on the MNIST database (digit recognition)
        /// The data files can be downloaded from http://yann.lecun.com/exdb/mnist/
        /// </summary>
        /// <param name="dataFilesPath">The path to a directory with the four extracted data files</param>
        public static void MNIST(string dataFilesPath)
        {
            using (var lap = BrightWireGpuProvider.CreateLinearAlgebra()) {
                var graph = new GraphFactory(lap);

                Console.Write("Loading training data...");
                var trainingData = _BuildVectors(null, graph, Mnist.Load(dataFilesPath + "train-labels.idx1-ubyte", dataFilesPath + "train-images.idx3-ubyte"));
                var testData     = _BuildVectors(trainingData, graph, Mnist.Load(dataFilesPath + "t10k-labels.idx1-ubyte", dataFilesPath + "t10k-images.idx3-ubyte"));
                Console.WriteLine($"done - {trainingData.RowCount} training images and {testData.RowCount} test images loaded");

                // use a one hot encoding error metric, rmsprop gradient descent and xavier weight initialisation
                var errorMetric = graph.ErrorMetric.OneHotEncoding;
                var propertySet = graph.CurrentPropertySet
                                  //.Use(graph.Regularisation.L2)
                                  .Use(graph.GradientDescent.RmsProp)
                                  .Use(graph.WeightInitialisation.Xavier)
                ;

                // create the training engine and schedule a training rate change
                const float TRAINING_RATE = 0.1f;
                var         engine        = graph.CreateTrainingEngine(trainingData, TRAINING_RATE, 128);
                engine.LearningContext.ScheduleLearningRate(15, TRAINING_RATE / 3);

                // create the network
                graph.Connect(engine)
                .AddFeedForward(1024)
                .Add(graph.LeakyReluActivation())
                .AddDropOut(0.5f)
                .AddFeedForward(trainingData.OutputSize)
                .Add(graph.SigmoidActivation())
                .AddBackpropagation(errorMetric)
                ;

                // train the network
                engine.Train(20, testData, errorMetric);

                // export the graph and verify that the error is the same
                var networkGraph    = engine.Graph;
                var executionEngine = graph.CreateEngine(networkGraph);
                var output          = executionEngine.Execute(testData);
                Console.WriteLine(output.Average(o => o.CalculateError(errorMetric)));
            }
        }
Пример #5
0
        public static void TrainWithSelu(string dataFilesPath)
        {
            using (var lap = BrightWireGpuProvider.CreateLinearAlgebra()) {
                var graph = new GraphFactory(lap);

                // parse the iris CSV into a data table and normalise
                var dataTable = new StreamReader(new MemoryStream(File.ReadAllBytes(dataFilesPath))).ParseCSV(',').Normalise(NormalisationType.Standard);

                // split the data table into training and test tables
                var split        = dataTable.Split(0);
                var trainingData = graph.CreateDataSource(split.Training);
                var testData     = graph.CreateDataSource(split.Test);

                // one hot encoding uses the index of the output vector's maximum value as the classification label
                var errorMetric = graph.ErrorMetric.OneHotEncoding;

                // configure the network properties
                graph.CurrentPropertySet
                .Use(graph.GradientDescent.RmsProp)
                .Use(graph.GaussianWeightInitialisation(true, 0.1f, GaussianVarianceCalibration.SquareRoot2N, GaussianVarianceCount.FanInFanOut))
                ;

                // create the training engine and schedule a training rate change
                const float TRAINING_RATE = 0.01f;
                var         engine        = graph.CreateTrainingEngine(trainingData, TRAINING_RATE, batchSize: 128);

                // create the network with the custom activation function
                graph.Connect(engine)
                .AddFeedForward(outputSize: 32)
                .Add(new SeluActivation())
                .AddFeedForward(trainingData.OutputSize)
                .Add(graph.SigmoidActivation())
                .AddBackpropagation(errorMetric)
                ;

                // train the network, but only run the test set every 50 iterations
                const int TRAINING_ITERATIONS = 1000;
                engine.Train(TRAINING_ITERATIONS, testData, errorMetric, null, testCadence: 50);
            }
        }
Пример #6
0
        public static void TrainWithSelu(string dataFilesPath)
        {
            using (var lap = BrightWireGpuProvider.CreateLinearAlgebra()) {
                var graph = new GraphFactory(lap);

                // parse the iris CSV into a data table and normalise
                var dataTable = new StreamReader(new MemoryStream(File.ReadAllBytes(dataFilesPath))).ParseCSV(',').Normalise(NormalisationType.Standard);

                // split the data table into training and test tables
                var split        = dataTable.Split(0);
                var trainingData = graph.CreateDataSource(split.Training);
                var testData     = graph.CreateDataSource(split.Test);

                // use a one hot encoding error metric, rmsprop gradient descent and xavier weight initialisation
                var errorMetric = graph.ErrorMetric.OneHotEncoding;
                var propertySet = graph.CurrentPropertySet
                                  .Use(graph.GradientDescent.RmsProp)
                                  .Use(graph.GaussianWeightInitialisation(true, 0.1f, GaussianVarianceCalibration.SquareRoot2N, GaussianVarianceCount.FanInFanOut))
                ;

                // create the training engine and schedule a training rate change
                const float TRAINING_RATE = 0.01f;
                var         engine        = graph.CreateTrainingEngine(trainingData, TRAINING_RATE, 128);

                // create the network
                graph.Connect(engine)
                .AddFeedForward(32)
                .Add(new SeluActivation())
                .AddFeedForward(trainingData.OutputSize)
                .Add(graph.SigmoidActivation())
                .AddBackpropagation(errorMetric)
                ;

                // train the network
                engine.Train(1000, testData, errorMetric, null, 50);
            }
        }
Пример #7
0
 public static void Load(TestContext context)
 {
     _cuda = BrightWireGpuProvider.CreateLinearAlgebra(false);
     _cpu  = BrightWireProvider.CreateLinearAlgebra(false);
 }
Пример #8
0
 private static void Load()
 {
     _cuda = BrightWireGpuProvider.CreateLinearAlgebra(false);
     _cpu  = BrightWireProvider.CreateLinearAlgebra(false);
 }
Пример #9
0
        /// <summary>
        /// Classifies text into either positive or negative sentiment
        /// The data files can be downloaded from https://archive.ics.uci.edu/ml/datasets/Sentiment+Labelled+Sentences
        /// </summary>
        /// <param name="dataFilesPath">Path to extracted data files</param>
        public static void SentimentClassification(string dataFilesPath)
        {
            var files = new[] {
                "amazon_cells_labelled.txt",
                "imdb_labelled.txt",
                "yelp_labelled.txt"
            };
            var LINE_SEPARATOR = "\n".ToCharArray();
            var SEPARATOR      = "\t".ToCharArray();
            var stringTable    = new StringTableBuilder();
            var sentimentData  = files.SelectMany(f => File.ReadAllText(dataFilesPath + f)
                                                  .Split(LINE_SEPARATOR)
                                                  .Where(l => !String.IsNullOrWhiteSpace(l))
                                                  .Select(l => l.Split(SEPARATOR))
                                                  .Select(s => Tuple.Create(_Tokenise(s[0]), s[1][0] == '1' ? "positive" : "negative"))
                                                  .Where(d => d.Item1.Any())
                                                  ).Shuffle(0).ToList();
            var splitSentimentData = sentimentData.Split();

            // build training and test classification bag
            var trainingClassificationBag = _BuildIndexedClassifications(splitSentimentData.Training, stringTable);
            var testClassificationBag     = _BuildIndexedClassifications(splitSentimentData.Test, stringTable);

            // train a bernoulli naive bayes classifier
            var bernoulli = trainingClassificationBag.TrainBernoulliNaiveBayes();

            Console.WriteLine("Bernoulli accuracy: {0:P}", testClassificationBag
                              .Classify(bernoulli.CreateClassifier())
                              .Average(r => r.Score)
                              );

            // train a multinomial naive bayes classifier
            var multinomial = trainingClassificationBag.TrainMultinomialNaiveBayes();

            Console.WriteLine("Multinomial accuracy: {0:P}", testClassificationBag
                              .Classify(multinomial.CreateClassifier())
                              .Average(r => r.Score)
                              );

            // convert the index lists to vectors and normalise along the way
            var sentimentDataBag    = _BuildIndexedClassifications(sentimentData, stringTable);
            var sentimentDataTable  = sentimentDataBag.ConvertToTable();
            var normalisedDataTable = sentimentDataTable.Normalise(NormalisationType.Standard);
            var vectoriser          = normalisedDataTable.GetVectoriser();
            var sentimentDataSet    = normalisedDataTable.Split(0);
            var dataTableAnalysis   = normalisedDataTable.GetAnalysis();

            using (var lap = BrightWireGpuProvider.CreateLinearAlgebra()) {
                var graph            = new GraphFactory(lap);
                var trainingData     = graph.CreateDataSource(sentimentDataSet.Training, vectoriser);
                var testData         = graph.CreateDataSource(sentimentDataSet.Test, vectoriser);
                var indexListEncoder = (IIndexListEncoder)trainingData;

                // use a one hot encoding error metric, rmsprop gradient descent and xavier weight initialisation
                var errorMetric = graph.ErrorMetric.OneHotEncoding;
                var propertySet = graph.CurrentPropertySet
                                  .Use(graph.GradientDescent.RmsProp)
                                  .Use(graph.WeightInitialisation.Xavier)
                ;

                var engine = graph.CreateTrainingEngine(trainingData, 0.3f, 128);
                engine.LearningContext.ScheduleLearningRate(5, 0.1f);
                engine.LearningContext.ScheduleLearningRate(11, 1f);
                engine.LearningContext.ScheduleLearningRate(15, 0.3f);

                // train a neural network classifier
                var neuralNetworkWire = graph.Connect(engine)
                                        .AddFeedForward(512, "layer1")
                                        //.AddBatchNormalisation()
                                        .Add(graph.ReluActivation())
                                        .AddDropOut(0.5f)
                                        .AddFeedForward(trainingData.OutputSize, "layer2")
                                        .Add(graph.ReluActivation())
                                        .AddBackpropagation(errorMetric, "first-network")
                ;

                // train the network
                Console.WriteLine("Training neural network classifier...");
                const int  TRAINING_ITERATIONS = 10;
                GraphModel bestNetwork         = null;
                engine.Train(TRAINING_ITERATIONS, testData, errorMetric, network => bestNetwork = network);
                if (bestNetwork != null)
                {
                    engine.LoadParametersFrom(bestNetwork.Graph);
                }
                var firstClassifier = graph.CreateEngine(engine.Graph);

                // stop the backpropagation to the first neural network
                engine.LearningContext.EnableNodeUpdates(neuralNetworkWire.Find("layer1"), false);
                engine.LearningContext.EnableNodeUpdates(neuralNetworkWire.Find("layer2"), false);

                // create the bernoulli classifier wire
                var bernoulliClassifier = bernoulli.CreateClassifier();
                var bernoulliWire       = graph.Connect(engine)
                                          .AddClassifier(bernoulliClassifier, sentimentDataSet.Training, dataTableAnalysis)
                ;

                // create the multinomial classifier wire
                var multinomialClassifier = multinomial.CreateClassifier();
                var multinomialWire       = graph.Connect(engine)
                                            .AddClassifier(multinomialClassifier, sentimentDataSet.Training, dataTableAnalysis)
                ;

                // join the bernoulli, multinomial and neural network classification outputs
                var firstNetwork = neuralNetworkWire.Find("first-network");
                var joined       = graph.Join(multinomialWire, graph.Join(bernoulliWire, graph.Connect(trainingData.OutputSize, firstNetwork)));

                // train an additional classifier on the output of the previous three classifiers
                joined
                .AddFeedForward(outputSize: 64)
                //.AddBatchNormalisation()
                .Add(graph.ReluActivation())
                .AddDropOut(dropOutPercentage: 0.5f)
                .AddFeedForward(trainingData.OutputSize)
                //.AddBatchNormalisation()
                .Add(graph.ReluActivation())
                .AddBackpropagation(errorMetric)
                ;

                // train the network again
                Console.WriteLine("Training stacked neural network classifier...");
                GraphModel bestStackedNetwork = null;
                engine.Train(10, testData, errorMetric, network => bestStackedNetwork = network);
                if (bestStackedNetwork != null)
                {
                    engine.LoadParametersFrom(bestStackedNetwork.Graph);
                }

                Console.WriteLine("Enter some text to test the classifiers...");
                while (true)
                {
                    Console.Write(">");
                    var line = Console.ReadLine();
                    if (String.IsNullOrWhiteSpace(line))
                    {
                        break;
                    }

                    var tokens    = _Tokenise(line);
                    var indexList = new List <uint>();
                    foreach (var token in tokens)
                    {
                        if (stringTable.TryGetIndex(token, out uint stringIndex))
                        {
                            indexList.Add(stringIndex);
                        }
                    }
                    if (indexList.Any())
                    {
                        var queryTokens = indexList.GroupBy(d => d).Select(g => Tuple.Create(g.Key, (float)g.Count())).ToList();
                        var vector      = new float[trainingData.InputSize];
                        foreach (var token in queryTokens)
                        {
                            vector[token.Item1] = token.Item2;
                        }
                        var indexList2   = IndexList.Create(indexList.ToArray());
                        var encodedInput = indexListEncoder.Encode(indexList2);

                        Console.WriteLine("Bernoulli classification: " + bernoulliClassifier.Classify(indexList2).First().Label);
                        Console.WriteLine("Multinomial classification: " + multinomialClassifier.Classify(indexList2).First().Label);
                        var result         = firstClassifier.Execute(encodedInput);
                        var classification = vectoriser.GetOutputLabel(1, (result.Output[0].Data[0] > result.Output[0].Data[1]) ? 0 : 1);
                        Console.WriteLine("Neural network classification: " + classification);

                        var stackedResult         = engine.Execute(encodedInput);
                        var stackedClassification = vectoriser.GetOutputLabel(1, (stackedResult.Output[0].Data[0] > stackedResult.Output[0].Data[1]) ? 0 : 1);
                        Console.WriteLine("Stack classification: " + stackedClassification);
                    }
                    else
                    {
                        Console.WriteLine("Sorry, none of those words have been seen before.");
                    }
                    Console.WriteLine();
                }
            }
            Console.WriteLine();
        }
Пример #10
0
        /// <summary>
        /// Trains a feed forward neural net on the MNIST data set (handwritten digit recognition)
        /// The data files can be downloaded from http://yann.lecun.com/exdb/mnist/
        /// </summary>
        /// <param name="dataFilesPath">The path to a directory with the four extracted data files</param>
        /// <param name="outputModelPath">Optional path to save the best model to</param>
        static void MNISTConvolutional(string dataFilesPath, string outputModelPath = null)
        {
            using var lap = BrightWireGpuProvider.CreateLinearAlgebra();
            var graph = new GraphFactory(lap);

            Console.Write("Loading training data...");
            var mnistTraining = Mnist.Load(dataFilesPath + "train-labels.idx1-ubyte",
                                           dataFilesPath + "train-images.idx3-ubyte");
            var mnistTest = Mnist.Load(dataFilesPath + "t10k-labels.idx1-ubyte",
                                       dataFilesPath + "t10k-images.idx3-ubyte");
            var trainingData =
                _BuildTensors(graph, null, mnistTraining /*.Where(d => d.Label < 2).ToList()*/);
            var testData = _BuildTensors(graph, trainingData,
                                         mnistTest /*.Where(d => d.Label < 2).ToList()*/);

            Console.WriteLine(
                $"done - {trainingData.RowCount} training images and {testData.RowCount} test images loaded");

            // one hot encoding uses the index of the output vector's maximum value as the classification label
            var errorMetric = graph.ErrorMetric.OneHotEncoding;

            // configure the network properties
            graph.CurrentPropertySet.Use(graph.GradientDescent.Adam).Use(
                graph.GaussianWeightInitialisation(false, 0.1f, GaussianVarianceCalibration.SquareRoot2N));

            // create the network
            const int   HIDDEN_LAYER_SIZE = 1024, TRAINING_ITERATIONS = 20;
            const float LEARNING_RATE = 0.05f;
            var         engine        = graph.CreateTrainingEngine(trainingData, LEARNING_RATE);

            if (!string.IsNullOrWhiteSpace(outputModelPath) && File.Exists(outputModelPath))
            {
                Console.WriteLine("Loading existing model from: " + outputModelPath);
                using var file = new FileStream(outputModelPath, FileMode.Open, FileAccess.Read);
                var model = Serializer.Deserialize <GraphModel>(file);
                engine = graph.CreateTrainingEngine(trainingData, model.Graph, LEARNING_RATE);
            }
            else
            {
                graph.Connect(engine).
                AddConvolutional(filterCount: 16, padding: 2, filterWidth: 5, filterHeight: 5, xStride: 1,
                                 yStride: 1, shouldBackpropagate: false).Add(graph.LeakyReluActivation()).
                AddMaxPooling(filterWidth: 2, filterHeight: 2, xStride: 2, yStride: 2).
                AddConvolutional(filterCount: 32, padding: 2, filterWidth: 5, filterHeight: 5, xStride: 1,
                                 yStride: 1).Add(graph.LeakyReluActivation()).
                AddMaxPooling(filterWidth: 2, filterHeight: 2, xStride: 2, yStride: 2).Transpose().
                AddFeedForward(HIDDEN_LAYER_SIZE).Add(graph.LeakyReluActivation()).
                AddDropOut(dropOutPercentage: 0.5f).AddFeedForward(trainingData.OutputSize).
                Add(graph.SoftMaxActivation()).AddBackpropagation(errorMetric);
            }

            // lower the learning rate over time
            engine.LearningContext.ScheduleLearningRate(15, LEARNING_RATE / 2);

            // train the network for twenty iterations, saving the model on each improvement
            Models.ExecutionGraph bestGraph = null;
            engine.Train(TRAINING_ITERATIONS, testData, errorMetric, model =>
            {
                bestGraph = model.Graph;
                if (!string.IsNullOrWhiteSpace(outputModelPath))
                {
                    using var file = new FileStream(outputModelPath, FileMode.Create, FileAccess.Write);
                    Serializer.Serialize(file, model);
                }
            });

            // export the final model and execute it on the training set
            var executionEngine = graph.CreateEngine(bestGraph ?? engine.Graph);
            var output          = executionEngine.Execute(testData);

            Console.WriteLine($"Final accuracy: {output.Average(o => o.CalculateError(errorMetric)):P2}");

            // execute the model with a single image
            var tensor     = mnistTest.First().AsFloatTensor.Tensor;
            var singleData = graph.CreateDataSource(new[] { tensor });
            var result     = executionEngine.Execute(singleData);
            var prediction = result.Single().Output.Single().MaximumIndex();
        }