Пример #1
0
        private static ITransformer TrainModel(IDataView trainSet, IDataView validationSet, string workspaceRelativePath, MLContext mlContext)
        {
            var classifierOptions = new ImageClassificationTrainer.Options()
            {
                FeatureColumnName = "Image",
                LabelColumnName   = "LabelAsKey",
                ValidationSet     = validationSet,
                Arch            = ImageClassificationTrainer.Architecture.ResnetV2101,
                MetricsCallback = Console.WriteLine,
                TestOnTrainSet  = false,
                ReuseTrainSetBottleneckCachedValues      = true,
                ReuseValidationSetBottleneckCachedValues = true,
                WorkspacePath = workspaceRelativePath
            };

            var trainingPipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(classifierOptions)
                                   .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));

            // takes approx. ~ 31min for 10 classes, 18300 images
            ITransformer trainedModel;

            using (new PerformanceTimer("DNN Image classifier training"))
                trainedModel = trainingPipeline.Fit(trainSet);

            return(trainedModel);
        }
Пример #2
0
        public void BuildAndSave()
        {
            MLContext mlContext = new MLContext();

            var traindData       = PrepareData();
            var trainingDataView = mlContext.Data.LoadFromEnumerable <ModelInput>(traindData);

            var dataProcessPipeline = mlContext.Transforms.Conversion.MapValueToKey("Label", "Label")
                                      .Append(mlContext.Transforms.LoadRawImageBytes("ImageSource_featurized", null, "ImageSource"))
                                      .Append(mlContext.Transforms.CopyColumns("Features", "ImageSource_featurized"));

            ImageClassificationTrainer.Options options = new ImageClassificationTrainer.Options()
            {
                LabelColumnName   = "Label",
                FeatureColumnName = "Features",
                WorkspacePath     = "TrainedModelOut",
                Arch             = ImageClassificationTrainer.Architecture.ResnetV2101,
                MetricsCallback  = (metrics) => Console.WriteLine(metrics),
                FinalModelPrefix = "knives_mdl"
            };

            var trainer = mlContext.MulticlassClassification.Trainers.ImageClassification(options)
                          .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel", "PredictedLabel"));

            var trainingPipeline = dataProcessPipeline.Append(trainer);

            var model = trainingPipeline.Fit(trainingDataView);

            mlContext.Model.Save(model, trainingDataView.Schema, "./TrainedModelOut/MLModel.zip");
        }
        /// <summary>
        /// 5.1. (Optional) Define the model's training pipeline by using explicit hyper-parameters
        /// </summary>
        /// <param name="validationSet"></param>
        /// <returns></returns>
        private EstimatorChain <KeyToValueMappingTransformer> CreateCustomPipeline()
        {
            ImageClassificationTrainer.Options options = new ImageClassificationTrainer.Options()
            {
                LabelColumnName = KeyColumn,
                // The feature column name should has same name in ImageDataInMemory
                FeatureColumnName = FeatureColumn,
                // Change the architecture to different DNN architecture
                Arch = (ImageClassificationTrainer.Architecture)arch,
                // Number of training iterations
                Epoch = 200,
                // Number of samples to use for mini-batch training
                BatchSize       = 10,
                LearningRate    = 0.01f,
                MetricsCallback = (metrics) => Console.WriteLine(metrics),
            };
            if (useValidationSet)
            {
                options.ValidationSet = validationDataset;
            }
            else
            {
                options.ValidationSet = testDataset;
            }
            EstimatorChain <KeyToValueMappingTransformer> pipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(options).
                                                                     Append(mlContext.Transforms.Conversion.MapKeyToValue(PredictedLabelColumn, PredictedLabelColumn));

            return(pipeline);
        }
        public static IEstimator <ITransformer> BuildTrainingPipeline(MLContext mlContext)
        {
            // Data process configuration with pipeline data transformations
            var dataProcessPipeline = mlContext.Transforms.Conversion.MapValueToKey("Label", "Label")
                                      .Append(mlContext.Transforms.LoadRawImageBytes("ImageSource_featurized", null, "ImageSource"))
                                      .Append(mlContext.Transforms.CopyColumns("Features", "ImageSource_featurized"));

            var classifierOptions = new ImageClassificationTrainer.Options()
            {
                LabelColumnName       = "Label",
                FeatureColumnName     = "Features",
                Epoch                 = 200,
                WorkspacePath         = WORKSPACE_RELATIVE_PATH,
                MetricsCallback       = (metrics) => Console.WriteLine(metrics),
                EarlyStoppingCriteria = null,
                TestOnTrainSet        = false
            };

            // Set the training algorithm
            var trainer = mlContext.MulticlassClassification.Trainers.ImageClassification(classifierOptions)
                          .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel", "PredictedLabel"));
            var trainingPipeline = dataProcessPipeline.Append(trainer);

            return(trainingPipeline);
        }
Пример #5
0
        public IEstimator <ITransformer> CreateCustomPipelineTF()
        {
            ImageClassificationTrainer.Options options = new ImageClassificationTrainer.Options()
            {
                LabelColumnName   = "LabelAsKey",
                FeatureColumnName = "softmax2_pre_activation",
                // Change the architecture to different DNN architecture
                Arch = ImageClassificationTrainer.Architecture.InceptionV3,
                // Number of training iterations
                Epoch = 200,
                // Number of samples to use for mini-batch training
                BatchSize       = 10,
                LearningRate    = 0.01f,
                MetricsCallback = (metrics) => Console.WriteLine(metrics),
                ValidationSet   = validationDataset
            };
            string outputCol = "ImageBytes", inputCol = "ImagePath";
            IEstimator <ITransformer> pipeline = mlContext.Transforms.
                                                 LoadRawImageBytes(outputCol, InputFolderPathForTraining, inputCol).
                                                 Append(mlContext.Transforms.ResizeImages(outputCol, imageWidth: InceptionSettings.ImageWidth, imageHeight: InceptionSettings.ImageHeight, inputCol)).
                                                 Append(mlContext.Transforms.ExtractPixels(outputCol, interleavePixelColors: InceptionSettings.ChannelsLast, offsetImage: InceptionSettings.Mean)).
                                                 Append(mlContext.Model.LoadTensorFlowModel(InceptionTFModelPath).
                                                        ScoreTensorFlowModel(outputColumnNames: new[] { "softmax2_pre_activation" }, inputColumnNames: new[] { inputCol }, addBatchDimensionInput: true)).
                                                 Append(mlContext.Transforms.Conversion.MapValueToKey("LabelAsKey", "Label", keyOrdinality: KeyOrdinality.ByValue)).
                                                 ////////////////////////////////////////////////////////////////////////////////
                                                 Append(mlContext.MulticlassClassification.Trainers.ImageClassification(options)).
                                                 //Append(mlContext.MulticlassClassification.Trainers.LbfgsMaximumEntropy(labelColumnName: "LabelAsKey", featureColumnName: "softmax2_pre_activation")).
                                                 Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel", "Predicted")).
                                                 AppendCacheCheckpoint(mlContext);

            return(pipeline);
        }
Пример #6
0
        private static ITransformer TrainModel(MLContext mlContext, IDataView dataView, string dataSetDir, ImageClassificationTrainer.Architecture architecture, int epochs, double testFraction)
        {
            IDataView shuffledData          = mlContext.Data.ShuffleRows(dataView);
            var       preprocessingPipeline = mlContext.Transforms.Conversion.MapValueToKey(inputColumnName: "Label",
                                                                                            outputColumnName: "LabelKey")
                                              .Append(mlContext.Transforms.LoadRawImageBytes(outputColumnName: "Img",
                                                                                             imageFolder: dataSetDir,
                                                                                             inputColumnName: "ImgPath"));    // > InputData.cs
            IDataView preProcData = preprocessingPipeline.Fit(shuffledData).Transform(shuffledData);

            DataOperationsCatalog.TrainTestData trainSplit          = mlContext.Data.TrainTestSplit(data: preProcData, testFraction: testFraction);
            DataOperationsCatalog.TrainTestData validationTestSplit = mlContext.Data.TrainTestSplit(trainSplit.TestSet);

            IDataView trainSet      = trainSplit.TrainSet;
            IDataView validationSet = validationTestSplit.TrainSet;
            IDataView testSet       = validationTestSplit.TestSet;

            var classifierOptions = new ImageClassificationTrainer.Options
            {
                FeatureColumnName = "Img",
                LabelColumnName   = "LabelKey",
                ValidationSet     = validationSet,
                Arch            = architecture,
                MetricsCallback = metrics => Console.WriteLine(metrics),
                TestOnTrainSet  = false,
                ReuseTrainSetBottleneckCachedValues      = true,
                ReuseValidationSetBottleneckCachedValues = true,
                Epoch = epochs,
            };

            var trainingPipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(classifierOptions)
                                   .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));

            return(trainingPipeline.Fit(trainSet));
        }
        public ImageRecognizerTrainer(string imagesFolder, string modelFolder)
        {
            Console.WriteLine("Loading images...");

            var images = ImageData.GetImageData(imagesFolder);

            Console.WriteLine($"Done. Loaded {images.Count()} images.");
            Console.WriteLine("MLContext initialization...");

            MLContext context = new();
            //var model = context.Model.Load(modelFolder, out var inputSchema);

            var fullImagesDataset     = context.Data.LoadFromEnumerable(images);
            var shuffledImagesDataset = context.Data.ShuffleRows(fullImagesDataset);

            Console.WriteLine("Done.");
            Console.WriteLine("Pipeline definition...");

            var preProcessPipeline = context.Transforms.Conversion.MapValueToKey("LabelAsKey", "Label")
                                     .Append(context.Transforms.LoadRawImageBytes("Image", imagesFolder, "ImagePath"));

            var preProcessData = preProcessPipeline.Fit(shuffledImagesDataset).Transform(shuffledImagesDataset);

            var trainTestData = context.Data.TrainTestSplit(preProcessData, 0.1);
            var trainData     = trainTestData.TrainSet;
            var testData      = trainTestData.TestSet;

            var classifierOptions = new ImageClassificationTrainer.Options()
            {
                FeatureColumnName = "Image",
                LabelColumnName   = "LabelAsKey",
                ValidationSet     = testData,
                Arch            = ImageClassificationTrainer.Architecture.MobilenetV2,
                MetricsCallback = (metrics) => Console.WriteLine(metrics),
                ReuseTrainSetBottleneckCachedValues      = true,
                ReuseValidationSetBottleneckCachedValues = true
            };

            var pipeline = context.MulticlassClassification.Trainers
                           .ImageClassification(classifierOptions)
                           .Append(context.Transforms.Conversion.MapValueToKey("PredictedLabel", "PredictedLabel"));

            Console.WriteLine("Done.");
            Console.WriteLine("Starting training...");

            var trainedModel = pipeline.Fit(trainData);

            context.Model.Save(trainedModel, trainData.Schema, modelFolder);

            Console.WriteLine("Done. Model Saved.");
            Console.WriteLine("Calculating model metrics...");

            var predictionsData = trainedModel.Transform(testData);
            var metrics         = context.MulticlassClassification.Evaluate(predictionsData, "LabelAsKey", predictedLabelColumnName: "PredictedLabel");

            PrintMultiClassClassificationMetrics("TensorFlow DNN Transfer Learning", metrics);

            Console.ReadLine();
        }
Пример #8
0
        static void Main(string[] args)
        {
            // Define Paths
            var projectDirectory      = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "../../../"));
            var workspaceRelativePath = Path.Combine(projectDirectory, "workspace");
            var data = Path.Combine(projectDirectory, "data");

            // Initialize instances
            MLContext mlContext = new MLContext();

            // Load data
            IEnumerable <ImageData> images = LoadImagesFromDirectory(folder: data, useFolderNameAsLabel: true);

            IDataView imageData = mlContext.Data.LoadFromEnumerable(images);

            IDataView shuffledData = mlContext.Data.ShuffleRows(imageData);

            // Build Model
            var preprocessingPipeline = mlContext.Transforms.Conversion.MapValueToKey(inputColumnName: "Label", outputColumnName: "LabelAsKey")
                                        .Append(mlContext.Transforms.LoadRawImageBytes(outputColumnName: "Image", imageFolder: data, inputColumnName: "ImagePath"));

            IDataView preProcessedData = preprocessingPipeline
                                         .Fit(shuffledData)
                                         .Transform(shuffledData);

            // Train test data
            TrainTestData trainSplit          = mlContext.Data.TrainTestSplit(data: preProcessedData, testFraction: 0.25);
            TrainTestData validationTestSplit = mlContext.Data.TrainTestSplit(trainSplit.TestSet);

            IDataView trainSet      = trainSplit.TrainSet;
            IDataView validationSet = validationTestSplit.TrainSet;
            IDataView testSet       = validationTestSplit.TestSet;

            // Train Model
            var classifierOptions = new ImageClassificationTrainer.Options()
            {
                FeatureColumnName = "Image",
                LabelColumnName   = "LabelAsKey",
                ValidationSet     = validationSet,
                Arch            = ImageClassificationTrainer.Architecture.ResnetV2101,
                MetricsCallback = (metrics) => Console.WriteLine(metrics),
                TestOnTrainSet  = false,
                ReuseTrainSetBottleneckCachedValues      = true,
                ReuseValidationSetBottleneckCachedValues = true,
                WorkspacePath = workspaceRelativePath
            };

            var trainingPipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(classifierOptions)
                                   .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));

            ITransformer trainedModel = trainingPipeline.Fit(trainSet);

            // Save model
            mlContext.Model.Save(trainedModel, imageData.Schema, "animal-classifier-model.zip");

            ClassifyImages(mlContext, testSet, trainedModel);

            Console.ReadLine();
        }
Пример #9
0
        static void Main(string[] args)
        {
            //get full path for th relative folder
            var relativeFolderPath = "../../../../image_set";

            var      loc                = System.Reflection.Assembly.GetExecutingAssembly().Location;
            FileInfo _dataRoot          = new FileInfo(loc);
            string   assemblyFolderPath = _dataRoot.Directory.FullName;

            string fullPath = Path.Combine(assemblyFolderPath, relativeFolderPath);

            //begin building model process
            var mlContext = new MLContext(seed: 20200525);

            //we need to crate logger of ML.NET context in order to know what is heppening in it.
            mlContext.Log += MlContext_Log;


            ModelBuilder model = new ModelBuilder(mlContext, fullPath);

            var imageSet = LoadImageSet(fullPath + "/train");


            //
            //Definition of the hype-parameters
            var opt = new ImageClassificationTrainer.Options()
            {
                //Feature and Label name
                FeatureColumnName = "Image",
                LabelColumnName   = "LabelAsKey",
                ValidationSet     = null,
                // Just by changing/selecting InceptionV3/MobilenetV2/ResnetV250
                // you can try a different DNN architecture (TensorFlow pre-trained model).
                Arch = ImageClassificationTrainer.Architecture.InceptionV3,

                //epoch
                Epoch        = 500,
                LearningRate = 0.01f,

                //logging training progress
                MetricsCallback = (m) =>
                {
                    if (m.Train != null && m.Train.Epoch != 0 && m.Train.Epoch % 10 == 0)
                    {
                        Console.WriteLine(m.ToString());
                    }
                    //Console.WriteLine($"Epoch: {m.Train.Epoch}; Accuracy {m.Train.Accuracy}");
                    else if (m.Train == null && m.Bottleneck.Index % 100 == 0)
                    {
                        Console.WriteLine($"{m.Bottleneck.DatasetUsed} set, preprocessed {m.Bottleneck.Index} images so far......");
                    }
                },
            };

            //
            model.BuildAndTrain(imageSet, opt);
        }
Пример #10
0
        public ResNetv2()
        {
            var projectDirectory      = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "../../../"));
            var workspaceRelativePath = Path.Combine(projectDirectory, "workspace");
            var assetsRelativePath    = Path.Combine(projectDirectory, "assetsforResNet");

            MLContext mlContext = new MLContext();

            IEnumerable <ImageData> images = LoadImagesFromDirectory(folder: assetsRelativePath, useFolderNameAsLabel: true);

            IDataView imageData = mlContext.Data.LoadFromEnumerable(images);

            IDataView shuffledData = mlContext.Data.ShuffleRows(imageData);

            var preprocessingPipeline = mlContext.Transforms.Conversion.MapValueToKey(
                inputColumnName: "Label",
                outputColumnName: "LabelAsKey")
                                        .Append(mlContext.Transforms.LoadRawImageBytes(
                                                    outputColumnName: "Image",
                                                    imageFolder: assetsRelativePath,
                                                    inputColumnName: "ImagePath"));

            IDataView preProcessedData = preprocessingPipeline
                                         .Fit(shuffledData)
                                         .Transform(shuffledData);

            TrainTestData trainSplit          = mlContext.Data.TrainTestSplit(data: preProcessedData, testFraction: 0.3);
            TrainTestData validationTestSplit = mlContext.Data.TrainTestSplit(trainSplit.TestSet);

            IDataView trainSet      = trainSplit.TrainSet;
            IDataView validationSet = validationTestSplit.TrainSet;
            IDataView testSet       = validationTestSplit.TestSet;

            var classifierOptions = new ImageClassificationTrainer.Options()
            {
                FeatureColumnName = "Image",
                LabelColumnName   = "LabelAsKey",
                ValidationSet     = validationSet,
                Arch            = ImageClassificationTrainer.Architecture.ResnetV2101,
                MetricsCallback = (metrics) => Console.WriteLine(metrics),
                TestOnTrainSet  = false,
                ReuseTrainSetBottleneckCachedValues      = true,
                ReuseValidationSetBottleneckCachedValues = true,
                WorkspacePath = workspaceRelativePath
            };

            var trainingPipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(classifierOptions)
                                   .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));

            ITransformer trainedModel = trainingPipeline.Fit(trainSet);

            ClassifySingleImage(mlContext, testSet, trainedModel);

            ClassifyImages(mlContext, testSet, trainedModel);

            Console.ReadKey();
        }
        static void Main(string[] args)
        {
            var mlContext = new MLContext();

            var projectDirectory      = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "../../../"));
            var trainRelativePath     = Path.Combine(projectDirectory, "Data\\train");
            var workspaceRelativePath = Path.Combine(projectDirectory, "Workspace");

            var trainImages = LoadImagesFromDirectory(trainRelativePath);

            var trainData = mlContext.Data.LoadFromEnumerable(trainImages);

            var shuffledData = mlContext.Data.ShuffleRows(trainData);

            var preprocessingPipeline = mlContext.Transforms.Conversion.MapValueToKey(
                inputColumnName: "Label",
                outputColumnName: "LabelAsKey")
                                        .Append(mlContext.Transforms.LoadRawImageBytes(
                                                    outputColumnName: "Image",
                                                    imageFolder: trainRelativePath,
                                                    inputColumnName: "ImagePath"));

            var preProcessedData = preprocessingPipeline
                                   .Fit(shuffledData)
                                   .Transform(shuffledData);

            var trainTestSplit = mlContext.Data.TrainTestSplit(preProcessedData, testFraction: 0.3);
            var trainSet       = trainTestSplit.TrainSet;

            var validationTestSplit = mlContext.Data.TrainTestSplit(trainTestSplit.TestSet);
            var validationSet       = validationTestSplit.TrainSet;
            var testSet             = validationTestSplit.TestSet;

            var classifierOptions = new ImageClassificationTrainer.Options()
            {
                FeatureColumnName = "Image",
                LabelColumnName   = "LabelAsKey",
                ValidationSet     = validationSet,
                Arch            = ImageClassificationTrainer.Architecture.ResnetV2101,
                MetricsCallback = Console.WriteLine,
                TestOnTrainSet  = false,
                ReuseTrainSetBottleneckCachedValues      = true,
                ReuseValidationSetBottleneckCachedValues = true,
                WorkspacePath = workspaceRelativePath,
                Epoch         = 100
            };

            var trainingPipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(classifierOptions)
                                   .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));

            var trainedModel = trainingPipeline.Fit(trainSet);

            mlContext.Model.Save(trainedModel, trainData.Schema, "model.zip");

            Console.ReadLine();
        }
Пример #12
0
    public void FaceModelTraining()
    {
        Console.WriteLine("STARTING TRAINING");

        string sCurrentDirectory = AppDomain.CurrentDomain.BaseDirectory;
        string sFile             = System.IO.Path.Combine(sCurrentDirectory, @"..\..\..\assets");
        string faceImagePath     = Path.GetFullPath(sFile);

        MLContext mlContext = new MLContext();

        IEnumerable <ImageData> images = LoadImagesFromDirectory(folder: faceImagePath, useFolderNameAsLabel: true);
        IDataView imageData            = mlContext.Data.LoadFromEnumerable(images);
        IDataView shuffledData         = mlContext.Data.ShuffleRows(imageData);

        var preprocessingPipeline = mlContext.Transforms.Conversion.MapValueToKey(
            inputColumnName: "Label",
            outputColumnName: "LabelAsKey")
                                    .Append(mlContext.Transforms.LoadRawImageBytes(
                                                outputColumnName: "Image",
                                                imageFolder: faceImagePath,
                                                inputColumnName: "ImagePath"));

        IDataView preProcessedData = preprocessingPipeline
                                     .Fit(shuffledData)
                                     .Transform(shuffledData);

        TrainTestData trainSplit          = mlContext.Data.TrainTestSplit(data: preProcessedData, testFraction: 0.3);
        TrainTestData validationTestSplit = mlContext.Data.TrainTestSplit(trainSplit.TestSet);

        IDataView trainSet      = trainSplit.TrainSet;
        IDataView validationSet = validationTestSplit.TrainSet;
        IDataView testSet       = validationTestSplit.TestSet;

        var classifierOptions = new ImageClassificationTrainer.Options()
        {
            FeatureColumnName = "Image",
            LabelColumnName   = "LabelAsKey",
            ValidationSet     = validationSet,
            Arch            = ImageClassificationTrainer.Architecture.ResnetV2101,
            MetricsCallback = (metrics) => Console.WriteLine(metrics),
            TestOnTrainSet  = false,
            ReuseTrainSetBottleneckCachedValues      = true,
            ReuseValidationSetBottleneckCachedValues = true
        };

        var trainingPipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(classifierOptions)
                               .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));

        ITransformer trainedModel = trainingPipeline.Fit(trainSet);

        ClassifySingleImage(mlContext, testSet, trainedModel);
        ClassifyImages(mlContext, testSet, trainedModel);

        mlContext.Model.Save(trainedModel, trainSet.Schema, "facemodel.zip");
    }
Пример #13
0
        /// <summary>
        /// Обучение модели
        /// </summary>
        /// <returns></returns>
        public ITransformer Learning()
        {
            LogInfo("Чтение данных из директории");

            var images       = LoadImagesFromDefaultDirectory();
            var imageData    = _context.Data.LoadFromEnumerable(images);
            var shuffledData = _context.Data.ShuffleRows(imageData);

            var preprocessingPipeline = _context.Transforms.Conversion
                                        .MapValueToKey(inputColumnName: "Label",
                                                       outputColumnName: "LabelAsKey")
                                        .Append(_context.Transforms.LoadRawImageBytes("Image",
                                                                                      _resourses.AssetsRelativePath,
                                                                                      "Path"));

            LogInfo("Подготовка данных к обучению");

            var preProcessedData = preprocessingPipeline
                                   .Fit(shuffledData)
                                   .Transform(shuffledData);

            var trainSplit          = _context.Data.TrainTestSplit(preProcessedData, 0.3);
            var validationTestSplit = _context.Data.TrainTestSplit(trainSplit.TestSet);

            var trainSet      = trainSplit.TrainSet;
            var validationSet = validationTestSplit.TrainSet;

            var classifierOptions = new ImageClassificationTrainer.Options()
            {
                FeatureColumnName = "Image",
                LabelColumnName   = "LabelAsKey",
                ValidationSet     = validationSet,
                Arch            = ImageClassificationTrainer.Architecture.ResnetV2101,
                MetricsCallback = Console.WriteLine,
                TestOnTrainSet  = false,
                ReuseTrainSetBottleneckCachedValues      = true,
                ReuseValidationSetBottleneckCachedValues = true,
                WorkspacePath = _resourses.WorkspaceRelativePath
            };

            LogInfo("Обучение модели");

            var trainingPipeline = _context.MulticlassClassification.Trainers
                                   .ImageClassification(classifierOptions)
                                   .Append(_context.Transforms.Conversion.MapKeyToValue("PredictedLabel"));

            var result = trainingPipeline.Fit(trainSet);

            LogInfo("Обучение завершено");

            return(result);
        }
Пример #14
0
        static void Main(string[] args)
        {
            var context = new MLContext(seed: 0);

            // Create a DataView containing the image paths and labels
            var input = LoadLabeledImagesFromPath(_imagePath);
            var data  = context.Data.LoadFromEnumerable(input);

            data = context.Data.ShuffleRows(data);

            // Load the images and convert the labels to keys to serve as categorical values
            var images = context.Transforms.Conversion.MapValueToKey(inputColumnName: nameof(Input.Label), outputColumnName: _keyColumnName)
                         .Append(context.Transforms.LoadRawImageBytes(inputColumnName: nameof(Input.ImagePath), outputColumnName: nameof(Input.Image), imageFolder: _imagePath))
                         .Fit(data).Transform(data);

            // Split the dataset for training and testing
            var trainTestData = context.Data.TrainTestSplit(images, testFraction: 0.2, seed: 1);
            var trainData     = trainTestData.TrainSet;
            var testData      = trainTestData.TestSet;

            // Create an image-classification pipeline and train the model
            var options = new ImageClassificationTrainer.Options()
            {
                FeatureColumnName = nameof(Input.Image),
                LabelColumnName   = _keyColumnName,
                ValidationSet     = testData,
                Arch            = ImageClassificationTrainer.Architecture.ResnetV2101, // Pretrained DNN
                MetricsCallback = (metrics) => Console.WriteLine(metrics),
                TestOnTrainSet  = false
            };

            var pipeline = context.MulticlassClassification.Trainers.ImageClassification(options)
                           .Append(context.Transforms.Conversion.MapKeyToValue(_predictedLabelColumnName));

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

            // Evaluate the model and show the results
            var predictions = model.Transform(testData);
            var metrics     = context.MulticlassClassification.Evaluate(predictions, labelColumnName: _keyColumnName, predictedLabelColumnName: _predictedLabelColumnName);

            Console.WriteLine();
            Console.WriteLine($"Macro accuracy = {metrics.MacroAccuracy:P2}");
            Console.WriteLine($"Micro accuracy = {metrics.MicroAccuracy:P2}");
            Console.WriteLine(metrics.ConfusionMatrix.GetFormattedConfusionTable());
            Console.WriteLine();

            // Save the model
            Console.WriteLine();
            Console.WriteLine("Saving the model...");
            context.Model.Save(model, trainData.Schema, _savePath);
        }
Пример #15
0
        private ITransformer CreateModel(MLContext mlContext)
        {
            var workspacePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            Directory.CreateDirectory(workspacePath);


            IEnumerable <ImageData> images = LoadImagesFromDirectory(_options.TrainingPath, useFolderNameAsLabel: true);

            IDataView imageData    = mlContext.Data.LoadFromEnumerable(images);
            IDataView shuffledData = mlContext.Data.ShuffleRows(imageData);

            IDataView preProcessedData = GetPreprocessingPipeline(mlContext)
                                         .Fit(shuffledData)
                                         .Transform(shuffledData);

            DataOperationsCatalog.TrainTestData trainSplit =
                mlContext.Data.TrainTestSplit(data: preProcessedData, testFraction: 0.3);
            DataOperationsCatalog.TrainTestData validationTestSplit = mlContext.Data.TrainTestSplit(trainSplit.TestSet);

            IDataView trainSet      = trainSplit.TrainSet;
            IDataView validationSet = validationTestSplit.TrainSet;
            IDataView testSet       = validationTestSplit.TestSet;

            var classifierOptions = new ImageClassificationTrainer.Options()
            {
                Epoch             = 600,
                FeatureColumnName = "Image",
                LabelColumnName   = "LabelAsKey",
                ValidationSet     = validationSet,
                Arch           = ImageClassificationTrainer.Architecture.ResnetV2101,
                TestOnTrainSet = true,
                ReuseTrainSetBottleneckCachedValues      = true,
                ReuseValidationSetBottleneckCachedValues = true,
                WorkspacePath = workspacePath
            };

            classifierOptions.MetricsCallback = metrics => Serilog.Log.Information(metrics.ToString());

            var trainingPipeline = mlContext.MulticlassClassification.Trainers
                                   .ImageClassification(classifierOptions)
                                   .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));

            var trainedModel = trainingPipeline.Fit(trainSet);

            mlContext.Model.Save(trainedModel, imageData.Schema, _options.ModelPath);

            Directory.Delete(workspacePath, true);

            return(trainedModel);
        }
        static void Main(string[] args)
        {
            MLContext _mLContext = new MLContext();

            IEnumerable <ImageData> trainingimages = LoadImagesFromDirectory(folder: _trainDataPath, useFolderNameAslabel: true);

            IEnumerable <ImageData> validationimages = LoadImagesFromDirectory(folder: _validationDataPath, useFolderNameAslabel: true);

            IDataView trainingimageData = _mLContext.Data.LoadFromEnumerable(trainingimages);

            IDataView validationimageData = _mLContext.Data.LoadFromEnumerable(validationimages);

            IDataView shuffledtrainingImageData = _mLContext.Data.ShuffleRows(trainingimageData);

            IDataView shuffledvalidationImageData = _mLContext.Data.ShuffleRows(validationimageData);

            IDataView trainDataView = _mLContext.Transforms.Conversion.MapValueToKey(outputColumnName: "LabelAsKey", inputColumnName: "Label", keyOrdinality: KeyOrdinality.ByValue)
                                      .Append(_mLContext.Transforms.LoadRawImageBytes(outputColumnName: "Image", imageFolder: _trainDataPath, inputColumnName: "ImagePath"))
                                      .Fit(shuffledtrainingImageData)
                                      .Transform(shuffledtrainingImageData);

            IDataView testDataView = _mLContext.Transforms.Conversion.MapValueToKey(outputColumnName: "LabelAsKey", inputColumnName: "Label", keyOrdinality: KeyOrdinality.ByValue)
                                     .Append(_mLContext.Transforms.LoadRawImageBytes(outputColumnName: "Image", imageFolder: _validationDataPath, inputColumnName: "ImagePath"))
                                     .Fit(shuffledvalidationImageData)
                                     .Transform(shuffledvalidationImageData);

            var options = new ImageClassificationTrainer.Options()
            {
                FeatureColumnName = "Image",
                LabelColumnName   = "LabelAsKey",
                Arch            = ImageClassificationTrainer.Architecture.ResnetV2101,
                Epoch           = 50,
                BatchSize       = 10,
                LearningRate    = 0.01f,
                MetricsCallback = (metrics) => Console.WriteLine(metrics),
                ValidationSet   = testDataView
            };

            IEstimator <ITransformer> trainingpipeLine = _mLContext.MulticlassClassification.Trainers.ImageClassification(options)
                                                         .Append(_mLContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));

            ITransformer trainedModel = trainingpipeLine.Fit(trainDataView);

            EvaluateModel(_mLContext, testDataView, trainedModel);

            _mLContext.Model.Save(trainedModel, trainDataView.Schema, _modelPath);
        }
        public TransformerChain <KeyToValueMappingTransformer> TrainResnetV250()
        {
            var options = new ImageClassificationTrainer.Options()
            {
                FeatureColumnName = "Image",
                LabelColumnName   = "Label",
                Arch                  = ImageClassificationTrainer.Architecture.ResnetV250,
                Epoch                 = 50,
                BatchSize             = 10,
                LearningRate          = 0.01f,
                EarlyStoppingCriteria = new ImageClassificationTrainer.EarlyStopping(minDelta: 0.001f, patience: 20, metric: ImageClassificationTrainer.EarlyStoppingMetric.Loss),
                ValidationSet         = _testDataset
            };
            var pipeline = _mlContext.MulticlassClassification.Trainers.ImageClassification(options)
                           .Append(_mlContext.Transforms.Conversion.MapKeyToValue(
                                       outputColumnName: "PredictedLabel",
                                       inputColumnName: "PredictedLabel"));

            return(pipeline.Fit(_trainDataset));
        }
        private static IEstimator <ITransformer> BuildPipeLine(MLContext context)
        {
            var dataPipeLine = context.Transforms.Conversion.MapValueToKey("Label", "Label")
                               .Append(context.Transforms.LoadRawImageBytes("Image", DATA_PATH, "ImagePath"));
            var trainerOptions = new ImageClassificationTrainer.Options()
            {
                LabelColumnName   = "Label",
                FeatureColumnName = "Image",
                Arch            = ImageClassificationTrainer.Architecture.ResnetV250,
                BatchSize       = 20,
                MetricsCallback = Console.WriteLine
            };

            var trainer = context.MulticlassClassification.Trainers.ImageClassification(trainerOptions);

            var trainingPipeLine = dataPipeLine.Append(trainer)
                                   .Append(context.Transforms.Conversion.MapKeyToValue("PredictedLabel"));

            return(trainingPipeLine);
        }
Пример #19
0
        public ITransformer Train(IDataView data)
        {
            var options = new ImageClassificationTrainer.Options()
            {
                BatchSize         = _options.BatchSize,
                FeatureColumnName = "Image",
                LabelColumnName   = "LabelAsKey",
                LearningRate      = _options.LearningRate,
                Epoch             = _options.Epoch,
                Arch          = ImageClassificationTrainer.Architecture.InceptionV3,
                WorkspacePath = _options.Output
            };

            var pipeline = Context.MulticlassClassification.Trainers.ImageClassification(options)
                           .Append(Context.Transforms.Conversion.MapKeyToValue(
                                       outputColumnName: "PredictedLabel",
                                       inputColumnName: "PredictedLabel"));
            var model = pipeline.Fit(data);

            return(model);
        }
Пример #20
0
        /// <summary>
        /// Training model by splitting image set to Train and Validation part manually.
        /// </summary>
        /// <param name="trainValidSet"></param>
        /// <returns></returns>
        public void BuildAndTrain(IEnumerable <ImageData> imageSet, ImageClassificationTrainer.Options hyperParams)
        {
            // 1. Load image information (filenames and labels) in IDataView
            //Load the initial single full Image-Set
            IDataView fullImagesDataset = mlContext.Data.LoadFromEnumerable(imageSet);
            //make image set more random to perform shuffling
            IDataView shuffledFullImageFilePathsDataset = mlContext.Data.ShuffleRows(fullImagesDataset);


            // 2. Load images in-memory while applying image transformations
            IDataView imageDataSet = mlContext.Transforms.Conversion.
                                     MapValueToKey(outputColumnName: "LabelAsKey", inputColumnName: "Label", keyOrdinality: KeyOrdinality.ByValue)
                                     .Append(mlContext.Transforms.LoadRawImageBytes(
                                                 outputColumnName: nameof(ImageData.Image),
                                                 imageFolder: fullImagesetFolderPath,
                                                 inputColumnName: nameof(ImageData.ImageFileName)))
                                     .Fit(shuffledFullImageFilePathsDataset)
                                     .Transform(shuffledFullImageFilePathsDataset);


            // 3. Define the model's training pipeline using Transfer Learning using pre-trained Tensor-flow model InceptionV3
            var pipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(hyperParams)
                           .Append(mlContext.Transforms.Conversion.MapKeyToValue(outputColumnName: "PredictedLabel",
                                                                                 inputColumnName: "PredictedLabel"));

            // 4. Train/create the ML model
            ITransformer trainedModel = pipeline.Fit(imageDataSet);

            // 5. Get the quality metrics (accuracy, etc.)
            IDataView predictionsDataView = trainedModel.Transform(imageDataSet);

            var metrics = mlContext.MulticlassClassification.Evaluate(predictionsDataView, labelColumnName: "LabelAsKey", predictedLabelColumnName: "PredictedLabel");

            ConsoleHelper.PrintMultiClassClassificationMetrics("TensorFlow DNN Transfer Learning", metrics);
            ConsoleHelper.ConsolePrintConfusionMatrix(metrics.ConfusionMatrix);

            //// 6. Save the model to assets/outputs
            var retVal = saveTrainedModel(predictionsDataView, trainedModel);
        }
Пример #21
0
        public static IEstimator <ITransformer> BuildTrainingPipeline(MLContext mlContext)
        {
            // Data process configuration with pipeline data transformations
            var dataProcessPipeline = mlContext.Transforms.Conversion.MapValueToKey("Label", "Label")
                                      .Append(mlContext.Transforms.LoadRawImageBytes("ImageSource_featurized", null, "ImageSource"))
                                      .Append(mlContext.Transforms.CopyColumns("Features", "ImageSource_featurized"));

            // Set the training algorithm
            var options = new ImageClassificationTrainer.Options
            {
                WorkspacePath     = Constants.WorkspaceRelativePath,
                LabelColumnName   = "Label",
                FeatureColumnName = "Features",
                Arch            = ImageClassificationTrainer.Architecture.InceptionV3,
                MetricsCallback = Console.WriteLine,
            };

            var trainer = mlContext.MulticlassClassification.Trainers.ImageClassification(options)
                          .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel", "PredictedLabel"));

            var trainingPipeline = dataProcessPipeline.Append(trainer);

            return(trainingPipeline);
        }
Пример #22
0
        /// <summary>
        /// 学習開始
        /// </summary>
        /// <param name="batchSize"></param>
        /// <param name="epoch"></param>
        /// <param name="architecture"></param>
        /// <returns></returns>
        public Task Run(string batchSize, string epoch, string architecture)
        {
            var task = Task.Factory.StartNew(() =>
            {
                ImageClassificationTrainer.Architecture arch = GetArchitecture(architecture);
                var classifierOptions = new ImageClassificationTrainer.Options()
                {
                    FeatureColumnName = "Image",
                    LabelColumnName   = "LabelAsKey",
                    ValidationSet     = validationSet,
                    Arch            = arch,
                    MetricsCallback = (metrics) => LearningCallBack(metrics),
                    TestOnTrainSet  = false,
                    WorkspacePath   = workspaceRelativePath
                };

                var trainingPipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(classifierOptions)
                                       .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));

                ITransformer trainedModel = trainingPipeline.Fit(trainSet);
            });

            return(task);
        }
Пример #23
0
        static void Main()
        {
            const string assetsRelativePath = @"../../../assets";
            string       assetsPath         = GetAbsolutePath(assetsRelativePath);

            string outputMlNetModelFilePath       = Path.Combine(assetsPath, "outputs", "imageClassifier.zip");
            string imagesFolderPathForPredictions = Path.Combine(assetsPath, "inputs", "images-for-predictions", "FlowersForPredictions");

            string imagesDownloadFolderPath = Path.Combine(assetsPath, "inputs", "images");

            // 1. Download the image set and unzip
            //string finalImagesFolderName = DownloadImageSet(imagesDownloadFolderPath);
            string fullImagesetFolderPath = Path.Combine(imagesDownloadFolderPath, imagesDownloadFolderPath); // For dataset already dowloaded

            var mlContext = new MLContext(seed: 1);

            // Specify MLContext Filter to only show feedback log/traces about ImageClassification
            // This is not needed for feedback output if using the explicit MetricsCallback parameter
            mlContext.Log += FilterMLContextLog;

            // 2. Load the initial full image-set into an IDataView and shuffle so it'll be better balanced
            IEnumerable <ImageData> images = LoadImagesFromDirectory(folder: fullImagesetFolderPath, useFolderNameAsLabel: true);
            IDataView fullImagesDataset    = mlContext.Data.LoadFromEnumerable(images);
            IDataView shuffledFullImageFilePathsDataset = mlContext.Data.ShuffleRows(fullImagesDataset);

            // 3. Load Images with in-memory type within the IDataView and Transform Labels to Keys (Categorical)
            IDataView shuffledFullImagesDataset = mlContext.Transforms.Conversion.
                                                  MapValueToKey(outputColumnName: "LabelAsKey", inputColumnName: "Label", keyOrdinality: KeyOrdinality.ByValue)
                                                  .Append(mlContext.Transforms.LoadRawImageBytes(
                                                              outputColumnName: "Image",
                                                              imageFolder: fullImagesetFolderPath,
                                                              inputColumnName: "ImagePath"))
                                                  .Fit(shuffledFullImageFilePathsDataset)
                                                  .Transform(shuffledFullImageFilePathsDataset);

            // 4. Split the data 80:20 into train and test sets, train and evaluate.
            var       trainTestData = mlContext.Data.TrainTestSplit(shuffledFullImagesDataset, testFraction: 0.2);
            IDataView trainDataView = trainTestData.TrainSet;
            IDataView testDataView  = trainTestData.TestSet;

            // 5. Define the model's training pipeline using DNN default values
            //
            //var pipeline = mlContext.MulticlassClassification.Trainers
            //        .ImageClassification(featureColumnName: "Image",
            //                             labelColumnName: "LabelAsKey",
            //                             validationSet: testDataView)
            //    .Append(mlContext.Transforms.Conversion.MapKeyToValue(outputColumnName: "PredictedLabel",
            //                                                          inputColumnName: "PredictedLabel"));

            //5.1(OPTIONAL) Define the model's training pipeline by using explicit hyper-parameters


            var options = new ImageClassificationTrainer.Options()
            {
                FeatureColumnName = "Image",
                LabelColumnName   = "LabelAsKey",
                // Just by changing/selecting InceptionV3/MobilenetV2/ResnetV250
                // you can try a different DNN architecture (TensorFlow pre-trained model).
                Arch            = ImageClassificationTrainer.Architecture.ResnetV2101,
                Epoch           = 50, //100
                BatchSize       = 10,
                LearningRate    = 0.01f,
                MetricsCallback = (metrics) => Console.WriteLine(metrics),
                ValidationSet   = testDataView
            };

            var pipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(options)
                           .Append(mlContext.Transforms.Conversion.MapKeyToValue(
                                       outputColumnName: "PredictedLabel",
                                       inputColumnName: "PredictedLabel"));

            // 6. Train/create the ML model
            Console.WriteLine("*** Training the image classification model with DNN Transfer Learning on top of the selected pre-trained model/architecture ***");

            // Measuring training time
            var watch = Stopwatch.StartNew();

            //Train
            ITransformer trainedModel = pipeline.Fit(trainDataView);

            watch.Stop();
            var elapsedMs = watch.ElapsedMilliseconds;

            Console.WriteLine($"Training with transfer learning took: {elapsedMs / 1000} seconds");

            // 7. Get the quality metrics (accuracy, etc.)
            EvaluateModel(mlContext, testDataView, trainedModel);

            // 8. Save the model to assets/outputs (You get ML.NET .zip model file and TensorFlow .pb model file)
            mlContext.Model.Save(trainedModel, trainDataView.Schema, outputMlNetModelFilePath);
            Console.WriteLine($"Model saved to: {outputMlNetModelFilePath}");

            // 9. Try a single prediction simulating an end-user app
            TrySinglePrediction(imagesFolderPathForPredictions, mlContext, trainedModel);

            Console.WriteLine("Press any key to finish");
            Console.ReadKey();
        }
Пример #24
0
        static void Main(string[] args)
        {
            Console.WriteLine("Meerkat image classification trainer");
            Console.WriteLine();

            // We don't want to copy the images to the bin folder, so we need to
            // specify the full path to the folders in the project
            var imagesPath = Path.Combine(AppContext.BaseDirectory,
                                          @"..\..\..\images");

            // A folder that will contain intermediate results
            var workspacePath = Path.Combine(AppContext.BaseDirectory,
                                             @"..\..\..\workspace");

            Directory.CreateDirectory(workspacePath);


            var mlContext = new MLContext(0);

            // Set up the data pre processing pipeline
            var preprocessingPipeline =
                mlContext
                .Transforms
                .LoadRawImageBytes(
                    outputColumnName: "ImageBytes",
                    imageFolder: imagesPath,
                    inputColumnName: "ImagePath")
                .Append(
                    mlContext
                    .Transforms
                    .Conversion
                    .MapValueToKey(
                        inputColumnName: "Label",
                        outputColumnName: "LabelAsKey"
                        )
                    );

            //Load the training data
            var imageFilePaths = Directory.GetFiles(imagesPath,
                                                    "*.jpg",
                                                    searchOption: SearchOption.AllDirectories);

            // Create the ModelInput DataView instead of loading from csv
            var labeledImagesPaths = imageFilePaths
                                     .Select(i => new ModelInput()
            {
                Label     = Directory.GetParent(i).Name,
                ImagePath = i
            });

            IDataView allImagesDataView = mlContext
                                          .Data
                                          .LoadFromEnumerable(labeledImagesPaths);

            IDataView shuffledImageDataView = mlContext
                                              .Data
                                              .ShuffleRows(allImagesDataView, 0);

            Console.WriteLine("Pre processing images....");
            var timestamp = DateTime.Now;

            // Pre Process images and split into train/test/validation
            IDataView preProcessedImageDataView = preprocessingPipeline
                                                  .Fit(shuffledImageDataView)
                                                  .Transform(shuffledImageDataView);

            Console.WriteLine($"Image preprocessing done in {(DateTime.Now - timestamp).TotalSeconds} seconds");
            Console.WriteLine();

            var firstSplit = mlContext
                             .Data
                             .TrainTestSplit(data: preProcessedImageDataView,
                                             testFraction: 0.3,
                                             seed: 0);
            var trainSet = firstSplit.TrainSet;

            var secondSplit = mlContext
                              .Data
                              .TrainTestSplit(data: firstSplit.TestSet,
                                              testFraction: 0.5, seed: 0);

            var validationSet = secondSplit.TrainSet;
            var testSet       = secondSplit.TestSet;

            // Set up trainer
            var classifierOptions = new ImageClassificationTrainer.Options()
            {
                FeatureColumnName = "ImageBytes",
                LabelColumnName   = "LabelAsKey",
                Arch = ImageClassificationTrainer.Architecture.InceptionV3,

                TestOnTrainSet = false,
                ValidationSet  = validationSet,

                ReuseTrainSetBottleneckCachedValues      = true,
                ReuseValidationSetBottleneckCachedValues = true,
                WorkspacePath = workspacePath,

                MetricsCallback = Console.WriteLine
            };

            var trainingPipeline = mlContext
                                   .MulticlassClassification
                                   .Trainers
                                   .ImageClassification(classifierOptions)
                                   .Append(mlContext
                                           .Transforms
                                           .Conversion
                                           .MapKeyToValue("PredictedLabel"));

            Console.WriteLine("Training model....");
            timestamp = DateTime.Now;

            var trainedModel = trainingPipeline.Fit(trainSet);

            Console.WriteLine($"Model training done in {(DateTime.Now - timestamp).TotalSeconds} seconds");
            Console.WriteLine();

            Console.WriteLine("Calculating metrics...");

            IDataView evaluationData = trainedModel.Transform(testSet);
            var       metrics        = mlContext
                                       .MulticlassClassification
                                       .Evaluate(evaluationData, "LabelAsKey");

            Console.WriteLine($"LogLoss: {metrics.LogLoss}");
            Console.WriteLine($"LogLossReduction: {metrics.LogLossReduction}");
            Console.WriteLine($"MicroAccuracy: {metrics.MicroAccuracy}");
            Console.WriteLine($"MacroAccuracy: {metrics.MacroAccuracy}");
            Console.WriteLine();
            Console.WriteLine($"{metrics.ConfusionMatrix.GetFormattedConfusionTable()}");

            Console.WriteLine();
            Console.WriteLine("Saving model");

            Directory.CreateDirectory("Model");
            mlContext.Model.Save(trainedModel, preProcessedImageDataView.Schema, "Model\\trainedModel.zip");

            Console.WriteLine();
        }
Пример #25
0
        public void TrainModel(string testImagePath = null)
        {
            #region Notes: Fundamental components

            /*  Main components:
             *      IDataView,
             *      ITransformer,
             *      IEstimator
             */

            //IDataView demoDataView;
            //ITransformer demoITransformer;
            //IEstimator<ITransformer> demoIEstimator;
            #endregion Notes: Fundamental components
            #region Notes: Conventional column names

            /*  Conventional column names:
             *      Input:
             *          Label
             *          Features
             *      Output:
             *          PredictedLabel
             *          Score
             */
            #endregion Notes: Conventional column names
            #region Notes: Usual training process

            /*  Usual training process:
             *      1. Load training/test datasets (IDataView)
             *      2. Build training pipeline (IEstimator)
             *          2.1   Construct preProcessing pipeline (IEstimator) (optional)
             *          2.2   Configure trainer (IEstimator)
             *          2.3   Construct postProcessing pipeline (optional)
             *          2.4   Construct training pipeline (preProcessing pipelin + trainer + postProcessing pipline
             *      3. Train model using training dataset (ITransformer)
             *      4. Evaluate model perfomance
             *          4.1 Make predictions on test data using trained model (IDataView)
             *          4.2 Compute evaluation metrics (Metrics staticsitcs)
             *      (optional) Retrain on full dataset (Itransformer)
             *      5. Save model to filesystem
             *      6. Make single prediction
             */
            #endregion Notes: Usual training process

            // Load data
            IDataView imagesInfo = LoadData(_dataFolder);
            imagesInfo = mlContext.Data.ShuffleRows(imagesInfo);
            DataOperationsCatalog.TrainTestData dataSplit = mlContext.Data.TrainTestSplit(imagesInfo, testFraction: 0.2);

            // Pre processing
            IEstimator <ITransformer> e_preProcessing_readImageBytes = mlContext.Transforms.LoadRawImageBytes(
                inputColumnName: nameof(ImageFileInputModel.ImagePath),
                outputColumnName: nameof(ImageInputModel.Image),
                imageFolder: _dataFolder);

            IEstimator <ITransformer> e_preProcessing_labelKeyMapping = mlContext.Transforms.Conversion.MapValueToKey(
                inputColumnName: nameof(BaseInputModel.Label),
                outputColumnName: "LabelAsKey",
                keyOrdinality: Microsoft.ML.Transforms.ValueToKeyMappingEstimator.KeyOrdinality.ByValue);


            ITransformer t_preProcessing_labelKeyMapping = e_preProcessing_labelKeyMapping.Fit(imagesInfo);
            ITransformer t_preProcessing_readImageBytes  = e_preProcessing_readImageBytes.Fit(imagesInfo);
            ITransformer t_preProcessingPipeline         = t_preProcessing_labelKeyMapping.Append(t_preProcessing_readImageBytes);


            // Core Model training pipeline
            IDataView testSetTransformed = t_preProcessingPipeline.Transform(dataSplit.TestSet);
            ImageClassificationTrainer.Options trainerSettings = new ImageClassificationTrainer.Options
            {
                FeatureColumnName = nameof(ImageInputModel.Image),
                LabelColumnName   = "LabelAsKey",
                Arch            = ImageClassificationTrainer.Architecture.ResnetV2101,
                Epoch           = 100,
                BatchSize       = 200,
                LearningRate    = 0.05f,
                MetricsCallback = (m) => Console.WriteLine(m),
                ValidationSet   = testSetTransformed,
                WorkspacePath   = _workspaceFolder
            };

            IEstimator <ITransformer> e_trainer = mlContext.MulticlassClassification.Trainers.ImageClassification(trainerSettings);
            IEstimator <ITransformer> e_postProcessing_labelKeyMapping = mlContext.Transforms.Conversion.MapKeyToValue(
                inputColumnName: "PredictedLabel",
                outputColumnName: nameof(PredictionModel.PredictedLabel));

            IEstimator <ITransformer> trainingPipeline = e_trainer.Append(e_postProcessing_labelKeyMapping);

            // Train
            #region Notes: On metadata

            /*
             * Metadata source: https://aka.ms/mlnet-resources/resnet_v2_101_299.meta
             * System.IO.Path.GetTempPath() -  C:\Users\User\AppData\Local\Temp\
             */
            #endregion
            ITransformer trainedModel = Train(trainingPipeline, t_preProcessingPipeline.Transform(dataSplit.TrainSet));

            #region Notes: Model composition
            //var extractPixelsEst = mlContext.Transforms.ExtractPixels();
            //var resizeEst = mlContext.Transforms.ResizeImages();
            //IEstimator<ITransformer> est = mlContext.Model.LoadTensorFlowModel("MODEL_PATH")
            //.ScoreTensorFlowModel(
            //outputColumnNames: new[] { "some-name" },
            //inputColumnNames: new[] { "Features" }, addBatchDimensionInput: true);
            #endregion Model composition

            // Evaluate/Save FileSystemModel
            ITransformer fileSystemModel = t_preProcessingPipeline.Append(trainedModel);
            Evaluate(fileSystemModel, dataSplit.TestSet);
            SaveModel(fileSystemModel,
                      new DataViewSchema.Column[] {
                imagesInfo.Schema.First(x => x.Name == nameof(ImageFileInputModel.ImagePath)),
                imagesInfo.Schema.First(x => x.Name == nameof(BaseInputModel.Label))
            },
                      ResolveModelFileName("fromFile"));

            // Evaluate/Save InMemoryModel
            IDataView testSetImageExtracted = t_preProcessing_readImageBytes.Transform(dataSplit.TrainSet);

            ITransformer inMemoryModel = t_preProcessing_labelKeyMapping.Append(trainedModel);
            Evaluate(inMemoryModel, testSetImageExtracted);
            SaveModel(inMemoryModel,
                      new DataViewSchema.Column[] {
                testSetImageExtracted.Schema.First(x => x.Name == nameof(ImageFileInputModel.ImagePath)),
                testSetImageExtracted.Schema.First(x => x.Name == nameof(BaseInputModel.Label))
            },
                      ResolveModelFileName("inMemory"));

            //Try a single prediction
            if (!string.IsNullOrWhiteSpace(testImagePath))
            {
                MakeSinglePrediction(testImagePath);
            }
        }
Пример #26
0
        public static void Example()
        {
            string assetsRelativePath = @"../../../assets";
            string assetsPath         = GetAbsolutePath(assetsRelativePath);

            var outputMlNetModelFilePath = Path.Combine(assetsPath, "outputs",
                                                        "imageClassifier.zip");

            string imagesDownloadFolderPath = Path.Combine(assetsPath, "inputs",
                                                           "images");

            // Download Cifar Dataset.
            string finalImagesFolderName = DownloadImageSet(
                imagesDownloadFolderPath);
            string finalImagesFolderNameTrain  = "cifar\\train";
            string fullImagesetFolderPathTrain = Path.Combine(
                imagesDownloadFolderPath, finalImagesFolderNameTrain);

            string finalImagesFolderNameTest  = "cifar\\test";
            string fullImagesetFolderPathTest = Path.Combine(
                imagesDownloadFolderPath, finalImagesFolderNameTest);

            try
            {
                MLContext mlContext = new MLContext(seed: 1);

                //Load all the original train images info
                IEnumerable <ImageData> train_images = LoadImagesFromDirectory(
                    folder: fullImagesetFolderPathTrain, useFolderNameAsLabel: true);
                IDataView trainDataset = mlContext.Data.LoadFromEnumerable(train_images);
                trainDataset = mlContext.Transforms.Conversion
                               .MapValueToKey("Label")
                               .Append(mlContext.Transforms.LoadRawImageBytes("Image",
                                                                              fullImagesetFolderPathTrain, "ImagePath"))
                               .Fit(trainDataset)
                               .Transform(trainDataset);

                //Load all the original test images info
                IEnumerable <ImageData> test_images = LoadImagesFromDirectory(
                    folder: fullImagesetFolderPathTest, useFolderNameAsLabel: true);
                IDataView testDataset = mlContext.Data.LoadFromEnumerable(test_images);
                testDataset = mlContext.Transforms.Conversion
                              .MapValueToKey("Label")
                              .Append(mlContext.Transforms.LoadRawImageBytes("Image",
                                                                             fullImagesetFolderPathTest, "ImagePath"))
                              .Fit(testDataset)
                              .Transform(testDataset);

                var options = new ImageClassificationTrainer.Options()
                {
                    FeatureColumnName = "Image",
                    LabelColumnName   = "Label",
                    // Just by changing/selecting InceptionV3/MobilenetV2 here instead of
                    // ResnetV2101 you can try a different architecture/
                    // pre-trained model.
                    Arch            = ImageClassificationTrainer.Architecture.ResnetV2101,
                    Epoch           = 182,
                    BatchSize       = 128,
                    LearningRate    = 0.01f,
                    MetricsCallback = (metrics) => Console.WriteLine(metrics),
                    ValidationSet   = testDataset,
                    ReuseValidationSetBottleneckCachedValues = false,
                    ReuseTrainSetBottleneckCachedValues      = false,
                    // Use linear scaling rule and Learning rate decay as an option
                    // This is known to do well for Cifar dataset and Resnet models
                    // You can also try other types of Learning rate scheduling methods
                    // available in LearningRateScheduler.cs
                    LearningRateScheduler = new LsrDecay()
                };

                var pipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(options)
                               .Append(mlContext.Transforms.Conversion.MapKeyToValue(
                                           outputColumnName: "PredictedLabel",
                                           inputColumnName: "PredictedLabel"));


                Console.WriteLine("*** Training the image classification model " +
                                  "with DNN Transfer Learning on top of the selected " +
                                  "pre-trained model/architecture ***");

                // Measuring training time
                var watch = System.Diagnostics.Stopwatch.StartNew();

                var trainedModel = pipeline.Fit(trainDataset);

                watch.Stop();
                long elapsedMs = watch.ElapsedMilliseconds;

                Console.WriteLine("Training with transfer learning took: " +
                                  (elapsedMs / 1000).ToString() + " seconds");

                mlContext.Model.Save(trainedModel, testDataset.Schema,
                                     "model.zip");

                ITransformer   loadedModel;
                DataViewSchema schema;
                using (var file = File.OpenRead("model.zip"))
                    loadedModel = mlContext.Model.Load(file, out schema);

                EvaluateModel(mlContext, testDataset, loadedModel);

                watch = System.Diagnostics.Stopwatch.StartNew();

                // Predict image class using an in-memory image.
                TrySinglePrediction(fullImagesetFolderPathTest, mlContext, loadedModel);

                watch.Stop();
                elapsedMs = watch.ElapsedMilliseconds;

                Console.WriteLine("Prediction engine took: " +
                                  (elapsedMs / 1000).ToString() + " seconds");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

            Console.WriteLine("Press any key to finish");
            Console.ReadKey();
        }
        static void Main(string[] args)
        {
            var imagesFolder = Path.Combine(Environment.CurrentDirectory, "..", "..", "..", "images");
            var files        = Directory.GetFiles(imagesFolder, "*", SearchOption.AllDirectories);

            var images = files.Select(file => new ImageData
            {
                Image = File.ReadAllBytes(file),
                Label = Directory.GetParent(file).Name
            });

            var context = new MLContext();

            var imageData         = context.Data.LoadFromEnumerable(images);
            var imageDataShuffled = context.Data.ShuffleRows(imageData);

            imageDataShuffled = context.Transforms.Conversion
                                .MapValueToKey("Label", keyOrdinality: Microsoft.ML.Transforms
                                               .ValueToKeyMappingEstimator.KeyOrdinality.ByValue)
                                .Fit(imageDataShuffled)
                                .Transform(imageDataShuffled);

            var testTrainData = context.Data.TrainTestSplit(imageDataShuffled, testFraction: 0.2);

            var options = new ImageClassificationTrainer.Options()
            {
                FeatureColumnName = "Image",
                LabelColumnName   = "Label",
                Arch                  = ImageClassificationTrainer.Architecture.ResnetV2101,
                Epoch                 = 100,
                BatchSize             = 10,
                MetricsCallback       = (metrics) => Console.WriteLine(metrics),
                ValidationSetFraction = 0.2f,
            };

            var pipeline = context.MulticlassClassification.Trainers.
                           ImageClassification(options)
                           .Append(context.Transforms.Conversion.MapKeyToValue(
                                       outputColumnName: "PredictedLabel",
                                       inputColumnName: "PredictedLabel"));

            var model = pipeline.Fit(testTrainData.TrainSet);

            //Console.WriteLine("Training with transfer learning finished.");

            var predicions = model.Transform(testTrainData.TestSet);

            var metrics = context.MulticlassClassification.Evaluate(predicions);

            Console.WriteLine(Environment.NewLine);
            Console.WriteLine($"Log loss - {metrics.LogLoss}");

            var predictionEngine = context.Model.CreatePredictionEngine <ImageData, ImagePrediction>(model);

            var testImagesFolder = Path.Combine(Environment.CurrentDirectory, "..", "..", "..", "test");

            var testFiles = Directory.GetFiles(testImagesFolder, "*", SearchOption.AllDirectories);

            var testImages = testFiles.Select(file => new ImageData
            {
                Image = File.ReadAllBytes(file),
                Label = Directory.GetParent(file).Name
            });

            Console.WriteLine(Environment.NewLine);

            foreach (var image in testImages)
            {
                var prediction = predictionEngine.Predict(image);

                Console.WriteLine($"Image : {image.Label}, Score : {prediction.Score.Max()}, Predicted Label : {prediction.PredictedLabel}");
            }

            context.Model.Save(model, imageData.Schema, "./dnn_model.zip");

            Console.ReadLine();
        }
        static void Main()
        {
            //Dataset taken from https://www.kaggle.com/paultimothymooney/chest-xray-pneumonia/
            const string datasetUrl      = "https://storage.googleapis.com/kaggle-data-sets/17810/23812/bundle/archive.zip?GoogleAccessId=web-data@kaggle-161607.iam.gserviceaccount.com&Expires=1587921765&Signature=HxSUJTlJVYahLDVTXsjq0q15M0RdUlhVeAAAcHHDgfO15r9T9vNrDbVQdac%2BZ7vn5FAJJLxRaOlWUVRQIcf5P2fwF0D6vM3mMdB76x6aukiFu6kSRYL8XWbM2Kw8aPjazhmvSnVJpRTFAlycpfh7kqU2g%2F8kEEgo9De4lU7hDZ85RtjQfajPxpLmgdrOlxTbGmm8fQaZ4DJgqDpU00cLKQAJSTFsBraM3xZcZMFu4tf6GKyUXSq%2FFR08h%2BOkQuUOL5xFI2aLweFSgKGMxfDawjXqNK5O3yqaLtDVapEMbT%2BzopDQeC0XabTysK6J4aktdrMhnSLh0E2MKSpzpCBBmg%3D%3D&response-content-disposition=attachment%3B+filename%3Dchest-xray-pneumonia.zip";
            const string datasetFullName = "chest-xray-pneumonia.zip";

            var projectDirectory = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "../../../../"));

            var datasetFolder = Path.Combine(projectDirectory, "dataset");

            // 1. Download the image set and unzip
            Utility.DownloadImageSet(datasetFolder, datasetUrl, datasetFullName);

            // Measuring training time
            var watch = Stopwatch.StartNew();

            var workspaceRelativePath = Path.Combine(projectDirectory, "workspace");

            datasetFolder = Path.Combine(projectDirectory, "chest_xray");
            var trainImageFolderPath      = Path.Combine(datasetFolder, "train");
            var testImageFolderPath       = Path.Combine(datasetFolder, "test");
            var validationImageFolderPath = Path.Combine(datasetFolder, "val");

            var context = new MLContext(seed: 1);

            // 2. Load the initial full image-set into an IDataView and shuffle so it'll be better balanced
            var trainImageDataShuffle = Utility.GetTrainImageData(trainImageFolderPath, context);

            // 3. Load Images with in-memory type within the IDataView and Transform Labels to Keys (Categorical)
            trainImageDataShuffle = Utility.TransformDataView(context, trainImageDataShuffle, trainImageFolderPath);

            // Load test images from files to memory
            var testImages        = Utility.LoadImagesFromDirectory(testImageFolderPath, true);
            var testImageDataView = context.Data.LoadFromEnumerable(testImages);

            testImageDataView = Utility.TransformDataView(context, testImageDataView, testImageFolderPath);

            var classifierOptions = new ImageClassificationTrainer.Options()
            {
                FeatureColumnName = "Image",
                LabelColumnName   = "Label",
                // Just by changing/selecting InceptionV3/MobilenetV2/ResnetV250
                // here instead of ResnetV2101 you can try a different
                // architecture/ pre-trained model.
                Arch = ImageClassificationTrainer.Architecture.ResnetV2101,
                //Epoch = 50,
                //BatchSize = 10,
                LearningRate    = 0.01f,
                MetricsCallback = (metrics) => Console.WriteLine(metrics),
                ValidationSet   = testImageDataView,
                // Disable EarlyStopping to run to specified number of epochs.
                //EarlyStoppingCriteria = null,
                ReuseTrainSetBottleneckCachedValues = true,
                WorkspacePath = workspaceRelativePath
            };


            //4. Define the model's training pipeline using DNN default values
            var pipeline = context.MulticlassClassification.Trainers
                           .ImageClassification(classifierOptions)
                           .Append(context.Transforms.Conversion.MapKeyToValue(
                                       outputColumnName: "PredictedLabel",
                                       inputColumnName: "PredictedLabel"));

            Console.WriteLine("*** Training the image classification model " +
                              "with DNN Transfer Learning on top of the selected " +
                              "pre-trained model/architecture ***");

            //5. Train
            var model = pipeline.Fit(trainImageDataShuffle);

            Console.WriteLine("Training with transfer learning finished.");
            watch.Stop();
            var elapsedMs = watch.ElapsedMilliseconds;

            Console.WriteLine($"Training with transfer learning took: {(elapsedMs / 1000) / 60} minutes.");

            //6. Evaluate the trained model on the passed test dataset.
            Console.WriteLine("Evaluate model with validation data.\n");
            var valImages        = Utility.LoadImagesFromDirectory(validationImageFolderPath, true);
            var valImageDataView = context.Data.LoadFromEnumerable(valImages);

            valImageDataView = Utility.TransformDataView(context, valImageDataView, validationImageFolderPath);

            var metric = context.MulticlassClassification.Evaluate(model.Transform(valImageDataView));

            Console.WriteLine($"LogLoss : " + metric.LogLoss + "\n" +
                              $"MacroAccuracy : " + metric.MacroAccuracy + "\n" +
                              $"MicroAccuracy : " + metric.MicroAccuracy + "\n");

            context.Model.Save(model, trainImageDataShuffle.Schema, "model.zip");

            Console.ReadLine();
        }
Пример #29
0
        static void Main(string[] args)
        {
            var imagesFolder = Path.Combine(Environment.CurrentDirectory, "flowers");

            var files  = Directory.GetFiles(imagesFolder, "*", SearchOption.AllDirectories);
            var images = files.Select(file => new ImageData
            {
                ImagePath = file,
                Label     = Directory.GetParent(file).Name
            });

            var context          = new MLContext();
            var imageData        = context.Data.LoadFromEnumerable(images);
            var imageDataSuffled = context.Data.ShuffleRows(imageData);
            var testTrainData    = context.Data.TrainTestSplit(imageDataSuffled, testFraction: 0.2);
            var validationData   = context.Transforms.Conversion.MapValueToKey("LabelKey", "Label",
                                                                               keyOrdinality: Microsoft.ML.Transforms.ValueToKeyMappingEstimator.KeyOrdinality.ByValue)
                                   .Append(context.Transforms.LoadRawImageBytes("Image", imagesFolder, "ImagePath"))
                                   .Fit(testTrainData.TestSet)
                                   .Transform(testTrainData.TestSet);

            var imagesPipeline = context.Transforms.Conversion
                                 .MapValueToKey("LabelKey", "Label", keyOrdinality: Microsoft.ML.Transforms.ValueToKeyMappingEstimator.KeyOrdinality.ByValue)
                                 .Append(context.Transforms.LoadRawImageBytes("Image", imagesFolder, "ImagePath"));

            var imagesDataModel = imagesPipeline.Fit(testTrainData.TrainSet);
            var imageDataView   = imagesDataModel.Transform(testTrainData.TestSet);

            var options = new ImageClassificationTrainer.Options()

            {
                Arch              = ImageClassificationTrainer.Architecture.ResnetV250,
                Epoch             = 100,
                BatchSize         = 20,
                LearningRate      = 0.01f,
                LabelColumnName   = "LabelKey",
                FeatureColumnName = "Image",
                ValidationSet     = validationData
            };

            var pipeline = context.MulticlassClassification.Trainers.ImageClassification(options)
                           .Append(context.Transforms.Conversion.MapKeyToValue("PredictedLabel"));

            var model            = pipeline.Fit(imageDataView);
            var predictionEngine = context.Model.CreatePredictionEngine <ImageModelInput, ImagePrediction>(model);

            var testImagesFolder = Path.Combine(Environment.CurrentDirectory, "test");
            var testFiles        = Directory.GetFiles(testImagesFolder, "*", SearchOption.AllDirectories);
            var testImages       = testFiles.Select(file => new ImageModelInput
            {
                ImagePath = file
            });

            Console.WriteLine(Environment.NewLine);

            var testImagesData = context.Data.LoadFromEnumerable(testImages);

            var testImagesDataView = imagesPipeline.Fit(testImagesData).Transform(testImagesData);

            var predictions = model.Transform(testImagesDataView);

            var testPredictions = context.Data.CreateEnumerable <ImagePrediction>(predictions, reuseRowObject: false);

            foreach (var prediction in testPredictions)
            {
                Console.WriteLine($"Image: { Path.GetFileName(prediction.ImagePath)}, Predicted label: {prediction.PredictedLabel}");
            }
        }
Пример #30
0
        /// <summary>
        /// Main method used for training the prediction model
        /// </summary>
        /// <returns>True if successful otherwise false if some error occures</returns>
        public bool TrainModel()
        {
            try
            {
                ProjectDirectory      = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "../../../")); //set main directory path
                WorkspaceRelativePath = Path.Combine(ProjectDirectory, "workspace");                           // set workspace path
                AssetsRelativePath    = Path.Combine(ProjectDirectory, "assets");                              //set assets path
                ClearWorkspace();

                MLContext context = new MLContext();                                                                                          // Machine Learning Context
                IEnumerable <ImageData> images = ImageLoader.LoadImagesFromDirectory(folder: AssetsRelativePath, useFolderNameAsLabel: true); // Load images from assets dir

                IDataView imageData    = context.Data.LoadFromEnumerable(images);                                                             //fundamental pipeline
                IDataView shuffledData = context.Data.ShuffleRows(imageData);                                                                 // shuffle rows od the pipeline

                //Creates a Estimator which converts categorical values into numerical keys from InputModel class
                var preprocessingPipeline = context.Transforms.Conversion.MapValueToKey(
                    inputColumnName: "Label",
                    outputColumnName: "LabelAsKey")
                                            .Append(context.Transforms.LoadRawImageBytes(
                                                        outputColumnName: "Image",
                                                        imageFolder: AssetsRelativePath,
                                                        inputColumnName: "ImagePath"));

                //Pre processsed data used for training/testing/validating the model
                IDataView preProcessedData = preprocessingPipeline
                                             .Fit(shuffledData)
                                             .Transform(shuffledData);

                //Declare to split into 3 categories train / test / validate
                TrainTestData trainSplit          = context.Data.TrainTestSplit(data: preProcessedData, testFraction: 0.3);
                TrainTestData validationTestSplit = context.Data.TrainTestSplit(trainSplit.TestSet);

                IDataView trainSet      = trainSplit.TrainSet;          // get the training set
                IDataView validationSet = validationTestSplit.TrainSet; // get the validation set
                IDataView testSet       = validationTestSplit.TestSet;  // get the test set

                //Image trainer options used for training the image classification model
                var classifierOptions = new ImageClassificationTrainer.Options()
                {
                    FeatureColumnName = "Image",
                    LabelColumnName   = "LabelAsKey",
                    ValidationSet     = validationSet,
                    Arch            = ImageClassificationTrainer.Architecture.ResnetV2101,
                    MetricsCallback = (metrics) => Console.WriteLine(metrics),
                    TestOnTrainSet  = false,
                    Epoch           = 100,
                    BatchSize       = 10,
                    ReuseTrainSetBottleneckCachedValues      = true,
                    ReuseValidationSetBottleneckCachedValues = true,
                    WorkspacePath = WorkspaceRelativePath
                };

                //create a training pipeline and append output of prediction as PredictedLabel from OutputModel class
                var trainingPipeline = context.MulticlassClassification.Trainers.ImageClassification(classifierOptions)
                                       .Append(context.Transforms.Conversion.MapKeyToValue("PredictedLabel"));

                //Main trained model used for making image predictions
                ITransformer trainedModel = trainingPipeline.Fit(trainSet);

                //Prediction engine used for prediction. Created from the trained model
                PredictionEngine = context.Model.CreatePredictionEngine <InputModel, OutputModel>(trainedModel);

                return(true);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return(false);
            }
        }