Beispiel #1
0
        static void Main(string[] args)
        {
            var context = new MLContext();

            Console.WriteLine("Loading Data...");

            var colDef = new TextLoader.Column[] {
                new TextLoader.Column(nameof(Digit.PixelValues), DataKind.Single, 1, 784),
                new TextLoader.Column("Number", DataKind.Single, 0)
            };

            var trainDataView = context.Data.LoadFromTextFile(trainDataPath, colDef, hasHeader: true, separatorChar: ',');
            var testDataView  = context.Data.LoadFromTextFile(testDataPath, colDef, hasHeader: true, separatorChar: ',');

            var pipeline = context.Transforms.Conversion.MapValueToKey(outputColumnName: "Label", inputColumnName: "Number", keyOrdinality: ValueToKeyMappingEstimator.KeyOrdinality.ByValue)
                           .Append(context.Transforms.Concatenate("Features", nameof(Digit.PixelValues)))
                           .AppendCacheCheckpoint(context)
                           .Append(context.MulticlassClassification.Trainers.OneVersusAll(context.BinaryClassification.Trainers.FastForest(), "Label"))
                           .Append(context.Transforms.Conversion.MapKeyToValue(outputColumnName: "Number", inputColumnName: "Label"));

            Console.WriteLine("Training the model...");
            var model = pipeline.Fit(trainDataView);

            Console.WriteLine("Evaluating model...");
            var predictions = model.Transform(testDataView);

            var metrics = context.MulticlassClassification.Evaluate(predictions, labelColumnName: "Number", scoreColumnName: "Score");

            // show evaluation metrics
            Console.WriteLine($"Evaluation metrics");
            Console.WriteLine($"    MicroAccuracy:    {metrics.MicroAccuracy:0.###}");
            Console.WriteLine($"    MacroAccuracy:    {metrics.MacroAccuracy:0.###}");
            Console.WriteLine($"    LogLoss:          {metrics.LogLoss:#.###}");
            Console.WriteLine($"    LogLossReduction: {metrics.LogLossReduction:#.###}");
            Console.WriteLine();

            var digits = context.Data.CreateEnumerable <Digit>(testDataView, false).ToArray();

            var testDigits = new Digit[] {
                digits[215], // 0
                digits[202], // 1
                digits[199], // 2
                digits[200], // 3
                digits[198], // 4
                digits[207], // 5
                digits[201], // 6
                digits[220], // 7
                digits[226], // 8
                digits[235]  // 9
            };

            var engine = context.Model.CreatePredictionEngine <Digit, DigitPrediction>(model);

            var table = new BetterConsoleTables.Table(TableConfiguration.Unicode());

            table.AddColumn("Digits");
            for (var i = 0; i < 10; i++)
            {
                table.AddColumn($"P{i}");
            }

            for (var i = 0; i < testDigits.Length; i++)
            {
                var prediction = engine.Predict(testDigits[i]);
                table.AddRow(
                    testDigits[i].Number,
                    prediction.Score[0].ToString("P2"),
                    prediction.Score[1].ToString("P2"),
                    prediction.Score[2].ToString("P2"),
                    prediction.Score[3].ToString("P2"),
                    prediction.Score[4].ToString("P2"),
                    prediction.Score[5].ToString("P2"),
                    prediction.Score[6].ToString("P2"),
                    prediction.Score[7].ToString("P2"),
                    prediction.Score[8].ToString("P2"),
                    prediction.Score[9].ToString("P2"));
            }

            // show results
            Console.WriteLine(table.ToString());
        }
Beispiel #2
0
        static void Main(string[] args)
        {
            // Create machine learning context.
            var context = new MLContext();

            // Let's load model if it already exists, otherwise let's create it.
            var modelPath = @"Assets\model.zip";

            if (File.Exists(modelPath))
            {
                // Load existing model.
                _model = context.Model.Load(modelPath, out DataViewSchema modelSchema);
            }
            else
            {
                // Upload training data set.
                LoadTrainingDigits();

                // Load training data set to ML context.
                var trainingData = context.Data.LoadFromEnumerable(_trainingDigits.OrderBy(d => d.Number));
                trainingData = context.Data.Cache(trainingData);

                // Define the trainer.
                // Different trainers give different accuracy of prediction, e.g.:
                //  - LbfgsMaximumEntropy gives better accuracy but lasts longer (92%, > 10 min);
                //  - SdcaMaximumEntropy gives worse accuracy, but lasts shorter (87%, < 1 min).
                var pipeline = context.Transforms.Conversion.MapValueToKey(inputColumnName: "Number", outputColumnName: "Label")
                               .Append(context.Transforms.Concatenate("Features", "Pixels"))
                               .Append(context.MulticlassClassification.Trainers.SdcaMaximumEntropy(labelColumnName: "Label", featureColumnName: "Features"))
                               .Append(context.Transforms.Conversion.MapKeyToValue(inputColumnName: "PredictedLabel", outputColumnName: "PredictedNumber"));

                // Train the model.
                _model = pipeline.Fit(trainingData);

                // Save the model.
                context.Model.Save(_model, trainingData.Schema, modelPath);
            }

            #region Evaluate model uging test data set
            // Upload test data set.
            LoadTestDigits();

            // Load test data set to ML context.
            var testData = context.Data.LoadFromEnumerable(_testDigits);
            testData = context.Data.Cache(testData);

            // Perform prediction on test data.
            var predictions = _model.Transform(testData);

            // Evaluate the model using prediction on test data.
            var metrics = context.MulticlassClassification.Evaluate(predictions);
            Console.WriteLine("Model's evaluation metrics:");
            Console.WriteLine($"    MicroAccuracy:    {metrics.MicroAccuracy:0.###}");
            Console.WriteLine($"    MacroAccuracy:    {metrics.MacroAccuracy:0.###}");
            Console.WriteLine($"    LogLoss:          {metrics.LogLoss:#.###}");
            Console.WriteLine($"    LogLossReduction: {metrics.LogLossReduction:#.###}");
            Console.WriteLine();
            #endregion

            // Use predict engine to predict single values.
            var predictionEngine = context.Model.CreatePredictionEngine <Digit, DigitPrediction>(_model);

            Digit           digit;
            DigitPrediction prediction;

            // Recognize image from img.bmp file.
            Console.WriteLine("Recognizing image from img.bmp file...");
            digit = new Digit(_recognizeFile);
            digit.Draw();

            prediction = predictionEngine.Predict(digit);
            Console.WriteLine($"Predicted number: {prediction.PredictedNumber}");
            for (var i = 0; i < prediction.Score.Length; i++)
            {
                Console.WriteLine($"[{i}]: {prediction.Score[i].ToString("P2")}");
            }
            Console.WriteLine("");

            // Recognize random digit from test data set.
            Console.WriteLine("Recognizing random image from test data set...");
            var rand = new Random();
            digit = _testDigits.Skip(rand.Next(_testDigits.Length)).First();
            digit.Draw();

            prediction = predictionEngine.Predict(digit);

            Console.WriteLine($"Original number: {digit.Number}, predicted number: {prediction.PredictedNumber}");
            for (var i = 0; i < prediction.Score.Length; i++)
            {
                Console.WriteLine($"[{i}]: {prediction.Score[i].ToString("P2")}");
            }
            Console.WriteLine("");
        }