/// <summary>
        /// Enables the usage of SQLite and local storage
        /// </summary>
        /// <param name="builder">MLOpsBuilder to add Azure Storage providers to</param>
        /// <param name="destinationFolder">Destination folder, default location is .mlops under the current user</param>
        /// <returns>Provided MLOpsBuilder for chaining</returns>
        public static MLOpsBuilder UseSQLite(this MLOpsBuilder builder, string destinationFolder = null)
        {
            builder.UseMetaDataStore(new SQLiteMetaDataStore());
            builder.UseModelRepository(new LocalFileModelRepository(new FileSystem(), destinationFolder));

            return(builder);
        }
Exemple #2
0
        public async Task LogConfusionMatrixAsync_SavesConfusionMatrixOnRun()
        {
            //Arrange
            var unitUnderTest = new MLOpsBuilder()
                                .UseSQLite()
                                .UseModelRepository(new Mock <IModelRepository>().Object)
                                .Build();
            var runId = await unitUnderTest.LifeCycle.CreateRunAsync("Test");

            var mlContext            = new MLContext(seed: 2);
            List <DataPoint> samples = GetSampleDataForTraining();

            var data    = mlContext.Data.LoadFromEnumerable(samples);
            var trainer = mlContext.BinaryClassification.Trainers.LbfgsLogisticRegression(labelColumnName: "Label", featureColumnName: "Features");

            var model = trainer.Fit(data);

            var predicitions = model.Transform(data);
            var metrics      = mlContext.BinaryClassification.Evaluate(predicitions, labelColumnName: "Label");

            //Act
            await unitUnderTest.Evaluation.LogConfusionMatrixAsync(runId, metrics.ConfusionMatrix);

            //Assert
            var confusionMatrix = unitUnderTest.Evaluation.GetConfusionMatrix(runId);

            confusionMatrix.Should().NotBeNull();
        }
        /// <summary>
        /// Enables the usage of Azure Blobstorage and TableStorage as a storage provider
        /// </summary>
        /// <param name="builder">MLOpsBuilder to add Azure Storage providers to</param>
        /// <param name="connectionString">The connection string for the azure storage account</param>
        /// <returns>Provided MLOpsBuilder for chaining</returns>
        public static MLOpsBuilder UseAzureStorage(this MLOpsBuilder builder, string connectionString)
        {
            builder.UseMetaDataStore(new StorageAccountMetaDataStore(connectionString));
            builder.UseModelRepository(new StorageAccountModelRepository(connectionString));

            return(builder);
        }
Exemple #4
0
        static async Task Main(string[] args)
        {
            var stopwatch = new Stopwatch();

            // MLOps: Create experiment and run
            var mlOpsContext = new MLOpsBuilder()
                               .UseSQLite()
                               .Build();

            Console.WriteLine("Creating an MLOps Run");
            var runId = await mlOpsContext.LifeCycle.CreateRunAsync("Taxi Fare Predictor");

            Console.WriteLine($"Run created with Id {runId}");

            var mlContext = new MLContext(seed: 1);

            Console.WriteLine("Loading the data");
            var data          = mlContext.Data.LoadFromTextFile <ModelInput>("Data/taxi-fare.csv", hasHeader: true, separatorChar: ',');
            var testTrainTest = mlContext.Data.TrainTestSplit(data);

            Console.WriteLine("Creating a data processing pipeline");
            var dataProcessingPipeline = mlContext.Transforms.CopyColumns(outputColumnName: "Label", inputColumnName: "FareAmount")
                                         .Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "VendorIdEncoded", inputColumnName: "VendorId"))
                                         .Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "RateCodeEncoded", inputColumnName: "RateCode"))
                                         .Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "PaymentTypeEncoded", inputColumnName: "PaymentType"))
                                         .Append(mlContext.Transforms.Concatenate("Features", "VendorIdEncoded", "RateCodeEncoded", "PassengerCount", "TripDistance", "PaymentTypeEncoded"));

            Console.WriteLine("Training the model, please stand-by...");
            stopwatch.Start();
            var trainer          = mlContext.Regression.Trainers.FastTree();
            var trainingPipeline = dataProcessingPipeline
                                   .Append(trainer);

            var trainedModel = trainingPipeline.Fit(testTrainTest.TrainSet);

            await mlOpsContext.Training.LogHyperParametersAsync <FastTreeRegressionTrainer>(runId, trainer);

            stopwatch.Stop();

            //MLOps: Training time
            await mlOpsContext.LifeCycle.SetTrainingTimeAsync(runId, stopwatch.Elapsed);

            Console.WriteLine($"Training time:{mlOpsContext.LifeCycle.GetRun(runId).TrainingTime}");

            Console.WriteLine("Evaluating the model");
            var predictions = trainedModel.Transform(testTrainTest.TestSet);
            var metrics     = mlContext.Regression.Evaluate(predictions);

            //MLOps: Log Metrics
            Console.WriteLine("Logging metrics");
            await mlOpsContext.Evaluation.LogMetricsAsync(runId, metrics);

            //Save the model
            mlContext.Model.Save(trainedModel, testTrainTest.TrainSet.Schema, "RegressionClassificationModel.zip");

            //MLOps: Upload artifact/model
            Console.WriteLine("Uploading artifact");
            await mlOpsContext.Model.UploadAsync(runId, "RegressionClassificationModel.zip");
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="awsAccessKeyId"></param>
        /// <param name="awsSecretAccessKey"></param>
        /// <param name="regionName"></param>
        /// <returns></returns>
        public static MLOpsBuilder UseAWSS3ModelRepository(this MLOpsBuilder builder, string awsAccessKeyId, string awsSecretAccessKey, string regionName)
        {
            var region         = RegionEndpoint.GetBySystemName(regionName);
            var amazonS3Client = new AmazonS3Client(awsAccessKeyId, awsSecretAccessKey, region);

            builder.UseModelRepository(new S3BucketModelRepository(amazonS3Client, new ModelPathGenerator()));

            return(builder);
        }
        public void UseAzureStorage_ConfiguresManager()
        {
            IMLOpsContext lcManager = new MLOpsBuilder().UseAzureStorage("UseDevelopmentStorage=true").Build();

            lcManager.Should().BeOfType <MLOpsContext>("Because the default IMLLifeCycleManager is MLLifeCycleManager");
            var metaDataField   = typeof(MLOpsContext).GetField("metaDataStore", BindingFlags.Instance | BindingFlags.NonPublic);
            var repositoryField = typeof(MLOpsContext).GetField("modelRepository", BindingFlags.Instance | BindingFlags.NonPublic);

            metaDataField.GetValue(lcManager).Should().BeOfType <StorageAccountMetaDataStore>();
            repositoryField.GetValue(lcManager).Should().BeOfType <StorageAccountModelRepository>();
        }
Exemple #7
0
        private static async Task <(IMLOpsContext, Run)> CreateRun(string experimentName)
        {
            var mlOpsContext = new MLOpsBuilder()
                               .UseSQLite()
                               .UseLocalFileModelRepository()
                               .Build();

            var run = await mlOpsContext.LifeCycle.CreateRunAsync(experimentName);

            return(mlOpsContext, run);
        }
Exemple #8
0
        /// <summary>
        /// Enables the usage of Azure Blobstorage as a storage provider for the models
        /// </summary>
        /// <param name="builder">MLOpsBuilder to add Azure Storage providers to</param>
        /// <param name="connectionString">The connection string for the azure storage account</param>
        /// <returns>Provided MLOpsBuilder for chaining</returns>
        public static MLOpsBuilder UseAzureBlobModelRepository(this MLOpsBuilder builder, string connectionString)
        {
            var modelRepositoryClient = new BlobContainerClient(connectionString, "model-repository");
            var deploymentClient      = new BlobContainerClient(connectionString, "deployment");

            modelRepositoryClient.CreateIfNotExists(PublicAccessType.None);
            deploymentClient.CreateIfNotExists(PublicAccessType.Blob);

            builder.UseModelRepository(new StorageAccountModelRepository(modelRepositoryClient, deploymentClient, new ModelPathGenerator()));

            return(builder);
        }
        public void UseAzureStorage_ConfiguresManager()
        {
            var           sqlitePath = $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}{Path.DirectorySeparatorChar}.mlops";
            IMLOpsContext lcManager  = new MLOpsBuilder().UseSQLite(sqlitePath).Build();

            lcManager.Should().BeOfType <MLOpsContext>("Because the default IMLLifeCycleManager is MLLifeCycleManager");
            var metaDataField   = typeof(MLOpsContext).GetField("metaDataStore", BindingFlags.Instance | BindingFlags.NonPublic);
            var repositoryField = typeof(MLOpsContext).GetField("modelRepository", BindingFlags.Instance | BindingFlags.NonPublic);

            metaDataField.GetValue(lcManager).Should().BeOfType <SQLiteMetaDataStore>();
            repositoryField.GetValue(lcManager).Should().BeOfType <LocalFileModelRepository>();
        }
Exemple #10
0
        static async Task Main(string[] args)
        {
            // MLOps: Create experiment and run
            var mlOpsContext = new MLOpsBuilder()
                               .UseSQLite()
                               .Build();

            Console.WriteLine("Creating an MLOps Run");
            var runId = await mlOpsContext.LifeCycle.CreateRunAsync("Iris Predictor");

            Console.WriteLine($"Run created with Id {runId}");

            var mlContext = new MLContext(seed: 1);

            Console.WriteLine("Loading the data");
            var data          = mlContext.Data.LoadFromTextFile <ModelInput>("Data/iris-dataset.csv", hasHeader: true, separatorChar: ',');
            var testTrainTest = mlContext.Data.TrainTestSplit(data);
            var features      = new[] { nameof(ModelInput.SepalLengthCm), nameof(ModelInput.SepalWidthCm), nameof(ModelInput.PetalLengthCm), nameof(ModelInput.PetalWidthCm) };

            Console.WriteLine("Creating a data processing pipeline");
            var dataProcessingPipeline = mlContext.Transforms.Concatenate("Features", features)
                                         .Append(mlContext.Transforms.NormalizeMinMax("Features"));

            Console.WriteLine("Training the model, please stand-by...");
            var trainer          = mlContext.Clustering.Trainers.KMeans(featureColumnName: "Features", numberOfClusters: 3);
            var trainingPipeline = dataProcessingPipeline
                                   .Append(trainer);

            var trainedModel = trainingPipeline.Fit(testTrainTest.TrainSet);

            await mlOpsContext.Training.LogHyperParametersAsync <KMeansTrainer>(runId, trainer);

            //MLOps: Training time
            await mlOpsContext.LifeCycle.SetTrainingTimeAsync(runId);

            Console.WriteLine($"Training time:{mlOpsContext.LifeCycle.GetRun(runId).TrainingTime}");

            Console.WriteLine("Evaluating the model");
            var predictions = trainedModel.Transform(testTrainTest.TestSet);
            var metrics     = mlContext.Clustering.Evaluate(predictions);

            //MLOps: Log Metrics
            Console.WriteLine("Logging metrics");
            await mlOpsContext.Evaluation.LogMetricsAsync(runId, metrics);

            //Save the model
            mlContext.Model.Save(trainedModel, testTrainTest.TrainSet.Schema, "IrisModel.zip");

            //MLOps: Upload artifact/model
            Console.WriteLine("Uploading artifact");
            await mlOpsContext.Model.UploadAsync(runId, "IrisModel.zip");
        }
        public void UseSqlLite_ConfiguresLifeCycleCatalog()
        {
            //Act
            IMLOpsContext unitUnderTest = new MLOpsBuilder()
                                          .UseSQLite()
                                          .UseModelRepository(new Mock <IModelRepository>().Object)
                                          .Build();

            unitUnderTest.Should().BeOfType <MLOpsContext>("Because the default IMLLifeCycleManager is MLLifeCycleManager");

            //Assert
            unitUnderTest.LifeCycle.Should().NotBeNull();
        }
Exemple #12
0
        public void UseSQLServer_ConfiguresLifeCycleCatalog()
        {
            //Act
            IMLOpsContext unitUnderTest = new MLOpsBuilder()
                                          .UseSQLServer(this.configuration[ConfigurationKeys.ConnectionString])
                                          .UseModelRepository(new Mock <IModelRepository>().Object)
                                          .Build();

            unitUnderTest.Should().BeOfType <MLOpsContext>("Because the default IMLLifeCycleManager is MLLifeCycleManager");

            //Assert
            unitUnderTest.LifeCycle.Should().NotBeNull();
        }
Exemple #13
0
        public async Task CreateExperimentAsync_Always_ReturnsNonEmptyGuidAsync()
        {
            //Arrange
            var           destinationFolder = @"C:\MLOps";
            IMLOpsContext mlm = new MLOpsBuilder().UseSQLite(destinationFolder).Build();

            //Act
            var guid = await mlm.CreateExperimentAsync("first experiment");

            //Assert
            Guid.TryParse(guid.ToString(), out var parsedGuid);
            parsedGuid.Should().NotBeEmpty();
        }
        /// <summary>
        /// Enables the usage of SQL Server
        /// </summary>
        /// <param name="builder">MLOpsBuilder for using SQL Server</param>
        /// <param name="connectionString"></param>
        /// <returns>Provided MLOpsBuilder for chaining</returns>
        public static MLOpsBuilder UseSQLServer(this MLOpsBuilder builder, string connectionString)
        {
            var options = new DbContextOptionsBuilder()
                          .UseSqlServer(connectionString)
                          .Options;

            var contextFactory = new DbContextFactory(() => new MLOpsSQLDbContext(options));

            contextFactory.CreateDbContext().EnsureCreated();

            builder.UseMetaDataRepositories(contextFactory);

            return(builder);
        }
        /// <summary>
        /// Enables the usage of SQLite
        /// </summary>
        /// <param name="builder">MLOpsBuilder for using SQLite</param>
        /// <returns>Provided MLOpsBuilder for chaining</returns>
        public static MLOpsBuilder UseSQLite(this MLOpsBuilder builder)
        {
            var options = new DbContextOptionsBuilder()
                          .UseSqlite("Data Source=local.db")
                          .Options;

            var contextFactory = new DbContextFactory(options, RelationalEntityConfigurator.OnModelCreating);

            contextFactory.CreateDbContext().EnsureCreated();

            builder.UseMetaDataRepositories(contextFactory);

            return(builder);
        }
Exemple #16
0
        public void UseAzureStorage_ConfiguresLifeCycleCatalog()
        {
            //Act
            IMLOpsContext unitUnderTest = new MLOpsBuilder().UseAzureStorage("UseDevelopmentStorage=true").Build();

            unitUnderTest.Should().BeOfType <MLOpsContext>("Because the default IMLLifeCycleManager is MLLifeCycleManager");

            //Assert
            unitUnderTest.LifeCycle.Should().NotBeNull();

            var metaDataField = typeof(LifeCycleCatalog).GetField("metaDataStore", BindingFlags.Instance | BindingFlags.NonPublic);

            metaDataField.GetValue(unitUnderTest.LifeCycle).Should().BeOfType <StorageAccountMetaDataStore>();
        }
Exemple #17
0
        public void UseAzureStorage_ConfiguresModelCatalog()
        {
            //Act
            IMLOpsContext unitUnderTest = new MLOpsBuilder().UseAzureStorage("UseDevelopmentStorage=true").Build();

            unitUnderTest.Should().BeOfType <MLOpsContext>("Because the default IMLLifeCycleManager is MLLifeCycleManager");

            //Assert
            unitUnderTest.Model.Should().NotBeNull();

            var repositoryField = typeof(ModelCatalog).GetField("modelRepository", BindingFlags.Instance | BindingFlags.NonPublic);

            repositoryField.GetValue(unitUnderTest.Model).Should().BeOfType <StorageAccountModelRepository>();
        }
Exemple #18
0
        /// <summary>
        /// Enables the usage of CosmosDb as a storage provider for model meta data
        /// </summary>
        /// <param name="builder">MLOpsBuilder to add Azure Storage providers to</param>
        /// <param name="accountEndpoint"></param>
        /// <param name="accountKey"></param>
        /// <returns>Provided MLOpsBuilder for chaining</returns>
        public static MLOpsBuilder UseCosmosDb(this MLOpsBuilder builder, string accountEndpoint, string accountKey)
        {
            var options = new DbContextOptionsBuilder()
                          .UseCosmos(accountEndpoint, accountKey, databaseName: "MLOpsNET")
                          .Options;

            var contextFactory = new DbContextFactory(() => new MLOpsCosmosDbContext(options));

            contextFactory.CreateDbContext().EnsureCreated();

            builder.UseMetaDataRepositories(contextFactory);

            return(builder);
        }
        /// <summary>
        /// Enables the usage of SQL Server
        /// </summary>
        /// <param name="builder">MLOpsBuilder for using SQL Server</param>
        /// <param name="connectionString"></param>
        /// <returns>Provided MLOpsBuilder for chaining</returns>
        public static MLOpsBuilder UseSQLServer(this MLOpsBuilder builder, string connectionString)
        {
            var options = new DbContextOptionsBuilder()
                          .UseSqlServer(connectionString)
                          .Options;

            var contextFactory = new DbContextFactory(options, RelationalEntityConfigurator.OnModelCreating);

            contextFactory.CreateDbContext().EnsureCreated();

            builder.UseMetaDataRepositories(contextFactory);

            return(builder);
        }
        /// <summary>
        /// Enables the usage of SQLite
        /// </summary>
        /// <param name="builder">MLOpsBuilder for using SQLite</param>
        /// <returns>Provided MLOpsBuilder for chaining</returns>
        public static MLOpsBuilder UseSQLite(this MLOpsBuilder builder)
        {
            var options = new DbContextOptionsBuilder()
                          .UseSqlite("Data Source=local.db")
                          .Options;

            var contextFactory = new DbContextFactory(() => new MLOpsSQLiteDbContext(options));

            contextFactory.CreateDbContext().EnsureCreated();

            builder.UseMetaDataRepositories(contextFactory);

            return(builder);
        }
Exemple #21
0
        static async System.Threading.Tasks.Task Main(string[] args)
        {
            // MLOps: Create experiment and run
            var mlOpsContext = new MLOpsBuilder()
                               .UseSQLite(@"C:/MLOps")
                               .Build();

            Console.WriteLine("Creating an MLOps Run");
            var runId = await mlOpsContext.CreateRunAsync("Product Category Predictor");

            Console.WriteLine($"Run created with Id {runId}");

            var mlContext = new MLContext(seed: 1);

            Console.WriteLine("Loading the data");
            var data          = mlContext.Data.LoadFromTextFile <ModelInput>("Data/titanic.csv", hasHeader: true, separatorChar: ',');
            var testTrainTest = mlContext.Data.TrainTestSplit(data);

            var features = new[] { nameof(ModelInput.Pclass), nameof(ModelInput.Sex), nameof(ModelInput.Age), nameof(ModelInput.SibSp), nameof(ModelInput.Parch), nameof(ModelInput.Fare), nameof(ModelInput.Embarked) };

            Console.WriteLine("Creating a data processing pipeline");
            var dataProcessingPipeline =
                mlContext.Transforms.ReplaceMissingValues(nameof(ModelInput.Age), replacementMode: MissingValueReplacingEstimator.ReplacementMode.Mean)
                .Append(mlContext.Transforms.Categorical.OneHotEncoding(nameof(ModelInput.Sex)))
                .Append(mlContext.Transforms.Categorical.OneHotEncoding(nameof(ModelInput.Embarked)))
                .Append(mlContext.Transforms.Categorical.OneHotEncoding(nameof(ModelInput.Pclass)))
                .Append(mlContext.Transforms.Concatenate("Features", features))
                .Append(mlContext.Transforms.NormalizeMinMax("Features"));

            Console.WriteLine("Training the model, please stand-by...");
            var trainingPipeline = dataProcessingPipeline
                                   .Append(mlContext.BinaryClassification.Trainers.SdcaLogisticRegression("Label", "Features"));

            var trainedModel = trainingPipeline.Fit(testTrainTest.TrainSet);

            Console.WriteLine("Evaluating the model");
            var predictions = trainedModel.Transform(testTrainTest.TestSet);
            var metrics     = mlContext.BinaryClassification.Evaluate(predictions);

            //MLOps: Log Metrics
            Console.WriteLine("Logging metrics");
            await mlOpsContext.LogMetricsAsync(runId, metrics);

            //Save the model
            mlContext.Model.Save(trainedModel, testTrainTest.TrainSet.Schema, "BinaryClassificationModel.zip");

            //MLOps: Upload artifact/model
            Console.WriteLine("Uploading artifact");
            await mlOpsContext.UploadModelAsync(runId, "BinaryClassificationModel.zip");
        }
        public async Task CreateExperimentAsync_Always_ReturnsNonEmptyGuidAsync()
        {
            //Arrange
            IMLOpsContext mlm = new MLOpsBuilder()
                                .UseModelRepository(new Mock <IModelRepository>().Object)
                                .UseSQLite()
                                .Build();

            //Act
            var guid = await mlm.LifeCycle.CreateExperimentAsync("first experiment");

            //Assert
            Guid.TryParse(guid.ToString(), out var parsedGuid);
            parsedGuid.Should().NotBeEmpty();
        }
        public void UseAzureStorage_ConfiguresEvaluationCatalog()
        {
            //Act
            var           sqlitePath    = $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}{Path.DirectorySeparatorChar}.mlops";
            IMLOpsContext unitUnderTest = new MLOpsBuilder().UseSQLite(sqlitePath).Build();

            unitUnderTest.Should().BeOfType <MLOpsContext>("Because the default IMLLifeCycleManager is MLLifeCycleManager");

            //Assert
            unitUnderTest.Evaluation.Should().NotBeNull();

            var metaDataField = typeof(EvaluationCatalog).GetField("metaDataStore", BindingFlags.Instance | BindingFlags.NonPublic);

            metaDataField.GetValue(unitUnderTest.Evaluation).Should().BeOfType <SQLiteMetaDataStore>();
        }
        public void UseAzureStorage_ConfiguresModelCatalog()
        {
            //Act
            var           sqlitePath    = $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}{Path.DirectorySeparatorChar}.mlops";
            IMLOpsContext unitUnderTest = new MLOpsBuilder().UseSQLite(sqlitePath).Build();

            unitUnderTest.Should().BeOfType <MLOpsContext>("Because the default IMLLifeCycleManager is MLLifeCycleManager");

            //Assert
            unitUnderTest.Model.Should().NotBeNull();

            var repositoryField = typeof(ModelCatalog).GetField("modelRepository", BindingFlags.Instance | BindingFlags.NonPublic);

            repositoryField.GetValue(unitUnderTest.Model).Should().BeOfType <LocalFileModelRepository>();
        }
Exemple #25
0
        static async Task Main(string[] args)
        {
            // MLOps: Create experiment and run
            var mlOpsContext = new MLOpsBuilder()
                               .UseSQLite(@"C:/MLOps")
                               .Build();

            Console.WriteLine("Creating an MLOps Run");
            var runId = await mlOpsContext.CreateRunAsync("Product Category Predictor");

            Console.WriteLine($"Run created with Id {runId}");

            var mlContext = new MLContext(seed: 1);

            Console.WriteLine("Loading the data");
            var data          = mlContext.Data.LoadFromTextFile <ProductInformation>("Data/ecommerce.csv", hasHeader: true, separatorChar: ',');
            var testTrainTest = mlContext.Data.TrainTestSplit(data);

            Console.WriteLine("Creating a data processing pipeline");
            var dataProcessingPipeline = mlContext.Transforms.Conversion.MapValueToKey(nameof(ProductInformation.Category))
                                         .Append(mlContext.Transforms.Text.FeaturizeText(nameof(ProductInformation.ProductName)))
                                         .Append(mlContext.Transforms.Text.FeaturizeText(nameof(ProductInformation.Description)))
                                         .Append(mlContext.Transforms.Categorical.OneHotHashEncoding(nameof(ProductInformation.Brand))
                                                 .Append(mlContext.Transforms.Concatenate("Features", nameof(ProductInformation.ProductName), nameof(ProductInformation.Description), nameof(ProductInformation.Brand), nameof(ProductInformation.Price))
                                                         .Append(mlContext.Transforms.NormalizeMinMax("Features"))));

            Console.WriteLine("Training the model, please stand-by...");
            var trainingPipeline = dataProcessingPipeline
                                   .Append(mlContext.MulticlassClassification.Trainers.SdcaMaximumEntropy(nameof(ProductInformation.Category), "Features")
                                           .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel")));

            var trainedModel = trainingPipeline.Fit(testTrainTest.TrainSet);

            Console.WriteLine("Evaluating the model");
            var predictions = trainedModel.Transform(testTrainTest.TestSet);
            var metrics     = mlContext.MulticlassClassification.Evaluate(predictions, nameof(ProductInformation.Category));

            //MLOps: Log Metrics
            Console.WriteLine("Logging metrics");
            await mlOpsContext.LogMetricsAsync(runId, metrics);

            //Save the model
            mlContext.Model.Save(trainedModel, testTrainTest.TrainSet.Schema, "MultiClassificationModel.zip");

            //MLOps: Upload artifact/model
            Console.WriteLine("Uploading artifact");
            await mlOpsContext.UploadModelAsync(runId, "MultiClassificationModel.zip");
        }
        public void MLOpsBuilder_BuildCreatesConfiguredLifeCycleManager()
        {
            var           metaDataStore = new Mock <IMetaDataStore>().Object;
            var           repository    = new Mock <IModelRepository>().Object;
            IMLOpsContext lcManager     = new MLOpsBuilder()
                                          .UseMetaDataStore(metaDataStore)
                                          .UseModelRepository(repository)
                                          .Build();

            lcManager.Should().BeOfType <MLOpsContext>("Because the default IMLLifeCycleManager is MLLifeCycleManager");
            var metaDataField   = typeof(MLOpsContext).GetField("metaDataStore", BindingFlags.Instance | BindingFlags.NonPublic);
            var repositoryField = typeof(MLOpsContext).GetField("modelRepository", BindingFlags.Instance | BindingFlags.NonPublic);

            metaDataStore.Should().BeSameAs(metaDataField.GetValue(lcManager), "Because UseMetaDataStore should set the IMetaDataStore instance via constructor");
            repository.Should().BeSameAs(repositoryField.GetValue(lcManager), "Because UseModelRepository should set the IModelRepository instance via constructor");
        }
Exemple #27
0
        public async Task CreateRunAsync_WithoutGitCommitHash_ShouldProvideEmptyGitCommitHash()
        {
            //Arrange
            var sut = new MLOpsBuilder()
                      .UseSQLite()
                      .UseModelRepository(new Mock <IModelRepository>().Object)
                      .Build();

            //Act
            var runId = await sut.LifeCycle.CreateRunAsync(Guid.NewGuid());

            //Assert
            var run = sut.LifeCycle.GetRun(runId);

            run.GitCommitHash.Should().Be(string.Empty);
        }
        public void UseAWSS3ModelRepository_ConfiguresModelCatalog()
        {
            //Act
            IMLOpsContext unitUnderTest = new MLOpsBuilder()
                                          .UseAWSS3ModelRepository("access-key-id", "secret-access-key", "region-name")
                                          .UseMetaDataRepositories(new Mock <IDbContextFactory>().Object)
                                          .Build();

            unitUnderTest.Should().BeOfType <MLOpsContext>("Because the default IMLOpsContext is MLOpsContext");

            //Assert
            unitUnderTest.Model.Should().NotBeNull();

            var repositoryField = typeof(ModelCatalog).GetField("modelRepository", BindingFlags.Instance | BindingFlags.NonPublic);

            repositoryField.GetValue(unitUnderTest.Model).Should().BeOfType <S3BucketModelRepository>();
        }
Exemple #29
0
        public void UseSQLServer_ConfiguresLifeCycleCatalog()
        {
            //Act
            IMLOpsContext unitUnderTest = new MLOpsBuilder()
                                          .UseSQLServer("connectionString")
                                          .UseModelRepository(new Mock <IModelRepository>().Object)
                                          .Build();

            unitUnderTest.Should().BeOfType <MLOpsContext>("Because the default IMLLifeCycleManager is MLLifeCycleManager");

            //Assert
            unitUnderTest.LifeCycle.Should().NotBeNull();

            var metaDataField = typeof(LifeCycleCatalog).GetField("metaDataStore", BindingFlags.Instance | BindingFlags.NonPublic);

            metaDataField.GetValue(unitUnderTest.LifeCycle).Should().BeOfType <SQLServerMetaDataStore>();
        }
Exemple #30
0
        public void UseSqlLiteStorage_ConfiguresTrainingCatalog()
        {
            //Act
            IMLOpsContext unitUnderTest = new MLOpsBuilder()
                                          .UseSQLite()
                                          .UseModelRepository(new Mock <IModelRepository>().Object)
                                          .Build();

            unitUnderTest.Should().BeOfType <MLOpsContext>("Because the default IMLLifeCycleManager is MLLifeCycleManager");

            //Assert
            unitUnderTest.Training.Should().NotBeNull();

            var metaDataField = typeof(TrainingCatalog).GetField("metaDataStore", BindingFlags.Instance | BindingFlags.NonPublic);

            metaDataField.GetValue(unitUnderTest.Training).Should().BeOfType <SQLiteMetaDataStore>();
        }