diff --git a/docs/code/experimental/MlNetCookBookStaticApi.md b/docs/code/experimental/MlNetCookBookStaticApi.md index 086e3b8e3b..99ce4a8d3c 100644 --- a/docs/code/experimental/MlNetCookBookStaticApi.md +++ b/docs/code/experimental/MlNetCookBookStaticApi.md @@ -397,7 +397,7 @@ Here's what you do to save the model to a file, and reload it (potentially in a ```csharp // Saving and loading happens to 'dynamic' models, so the static typing is lost in the process. -mlContext.Model.Save(model.AsDynamic, trainData.AsDynamic.Schema, modelPath); +mlContext.Model.Save(model, trainData, modelPath); // Potentially, the lines below can be in a different process altogether. diff --git a/src/Microsoft.ML.StaticPipe/ModelOperationsCatalogExtensions.cs b/src/Microsoft.ML.StaticPipe/ModelOperationsCatalogExtensions.cs new file mode 100644 index 0000000000..c42b983edc --- /dev/null +++ b/src/Microsoft.ML.StaticPipe/ModelOperationsCatalogExtensions.cs @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.IO; +using Microsoft.ML.Data; + +namespace Microsoft.ML.StaticPipe +{ + public static class ModelOperationsCatalogExtensions + { + /// + /// Save statically typed model to the stream. + /// + /// The model explainability operations catalog. + /// The trained model to be saved. Note that this can be , as a shorthand + /// for an empty transformer chain. Upon loading with the returned value will + /// be an empty . + /// The data view with the schema of the input to the transformer. This can be . + /// A writeable, seekable stream to save to. + public static void Save(this ML.ModelOperationsCatalog catalog, Transformer model, DataView dataView, Stream stream) + where TTransformer : class, ITransformer + { + catalog.Save(model?.AsDynamic, dataView?.AsDynamic.Schema, stream); + } + + /// + /// Save statically typed model to the stream. + /// + /// The model explainability operations catalog. + /// The trained model to be saved. Note that this can be , as a shorthand + /// for an empty transformer chain. Upon loading with the returned value will + /// be an empty . + /// The data view with the schema of the input to the transformer. This can be . + /// Path where model should be saved. + public static void Save(this ML.ModelOperationsCatalog catalog, Transformer model, DataView dataView, string filePath) + where TTransformer : class, ITransformer + { + catalog.Save(model?.AsDynamic, dataView?.AsDynamic.Schema, filePath); + } + } +} diff --git a/test/Microsoft.ML.Tests/Scenarios/Api/CookbookSamples/CookbookSamples.cs b/test/Microsoft.ML.Tests/Scenarios/Api/CookbookSamples/CookbookSamples.cs index cce1de27b5..dc66dd570d 100644 --- a/test/Microsoft.ML.Tests/Scenarios/Api/CookbookSamples/CookbookSamples.cs +++ b/test/Microsoft.ML.Tests/Scenarios/Api/CookbookSamples/CookbookSamples.cs @@ -147,7 +147,7 @@ private void TrainRegression(string trainDataPath, string testDataPath, string m var metrics = mlContext.Regression.Evaluate(model.Transform(testData), label: r => r.Target, score: r => r.Prediction); // Saving and loading happens to 'dynamic' models, so the static typing is lost in the process. - mlContext.Model.Save(model.AsDynamic, trainData.AsDynamic.Schema, modelPath); + mlContext.Model.Save(model, trainData, modelPath); // Potentially, the lines below can be in a different process altogether.