Save and load trained models
Learn how to save and load trained models in your application.
Throughout the model building process, a model lives in memory and is accessible throughout the application's lifecycle. However, once the application stops running, if the model is not saved somewhere locally or remotely, it's no longer accessible. Typically models are used at some point after training in other applications either for inference or re-training. Therefore, it's important to store the model. Save and load models using the steps described in subsequent sections of this document when using data preparation and model training pipelines like the one detailed below. Although this sample uses a linear regression model, the same process applies to other ML.NET algorithms.
HousingData[] housingData = new HousingData[]
{
new HousingData
{
Size = 600f,
HistoricalPrices = new float[] { 100000f, 125000f, 122000f },
CurrentPrice = 170000f
},
new HousingData
{
Size = 1000f,
HistoricalPrices = new float[] { 200000f, 250000f, 230000f },
CurrentPrice = 225000f
},
new HousingData
{
Size = 1000f,
HistoricalPrices = new float[] { 126000f, 130000f, 200000f },
CurrentPrice = 195000f
}
};
// Create MLContext
MLContext mlContext = new MLContext();
// Load Data
IDataView data = mlContext.Data.LoadFromEnumerable<HousingData>(housingData);
// Define data preparation estimator
EstimatorChain<RegressionPredictionTransformer<LinearRegressionModelParameters>> pipelineEstimator =
mlContext.Transforms.Concatenate("Features", new string[] { "Size", "HistoricalPrices" })
.Append(mlContext.Transforms.NormalizeMinMax("Features"))
.Append(mlContext.Regression.Trainers.Sdca());
// Train model
ITransformer trainedModel = pipelineEstimator.Fit(data);
// Save model
mlContext.Model.Save(trainedModel, data.Schema, "model.zip");
Because most models and data preparation pipelines inherit from the same set of classes, the save and load method signatures for these components is the same. Depending on your use case, you can either combine the data preparation pipeline and model into a single EstimatorChain
which would output a single ITransformer
or separate them thus creating a separate ITransformer
for each.
Save a model locally
When saving a model you need two things:
- The
ITransformer
of the model. - The
DataViewSchema
of theITransformer
's expected input.
After training the model, use the Save
method to save the trained model to a file called model.zip
using the DataViewSchema
of the input data.
// Save Trained Model
mlContext.Model.Save(trainedModel, data.Schema, "model.zip");
Save an ONNX model locally
To save an ONNX version of your model locally you will need the Microsoft.ML.OnnxConverter NuGet package installed.
With the OnnxConverter
package installed, we can use it to save our model into the ONNX format. This requires a Stream
object which we can provide as a FileStream
using the File.Create
method. The File.Create
method takes in a string as a parameter which will be the path of the ONNX model.
using FileStream stream = File.Create("./onnx_model.onnx");
With the stream created, we can call the ConvertToOnnx
method and give it the trained model, the data used to train the model, and the stream. However, not all trainers and transformers are exportable to ONNX. For a complete list, visit the Transforms and How to Choose an ML.NET Algorithm guides.
mlContext.Model.ConvertToOnnx(trainedModel, data, stream);
Load a model stored locally
Models stored locally can be used in other processes or applications like ASP.NET Core
and Serverless Web Applications
. See Use ML.NET in Web API and Deploy ML.NET Serverless Web App how-to articles to learn more.
In a separate application or process, use the Load
method along with the file path to get the trained model into your application.
//Define DataViewSchema for data preparation pipeline and trained model
DataViewSchema modelSchema;
// Load trained model
ITransformer trainedModel = mlContext.Model.Load("model.zip", out modelSchema);
Load an ONNX model locally
To load in an ONNX model for predictions, you will need the Microsoft.ML.OnnxTransformer NuGet package.
With the OnnxTransformer
package installed, you can load an existing ONNX model by using the ApplyOnnxModel
method. The required parameter is a string which is the path of the local ONNX model.
OnnxScoringEstimator estimator = mlContext.Transforms.ApplyOnnxModel("./onnx_model.onnx");
The ApplyOnnxModel
method returns an OnnxScoringEstimator
object. First, we need to load in the new data.
HousingData[] newHousingData = new HousingData[]
{
new()
{
Size = 1000f,
HistoricalPrices = new[] { 300_000f, 350_000f, 450_000f },
CurrentPrice = 550_00f
}
};
With the new data we can load that into an IDataView
using the LoadFromEnumerable
method.
IDataView newHousingDataView = mlContext.Data.LoadFromEnumerable(newHousingData);
Now, we can use the new IDataView
to fit on the new data.
estimator.Fit(newHousingDataView);
After using the Fit method on an estimator from ApplyOnnxModel
, it can then be saved as a new model using the Save method mentioned save a model locally section.
Load a model stored remotely
To load data preparation pipelines and models stored in a remote location into your application, use a Stream
instead of a file path in the Load
method.
// Create MLContext
MLContext mlContext = new MLContext();
// Define DataViewSchema and ITransformers
DataViewSchema modelSchema;
ITransformer trainedModel;
// Load data prep pipeline and trained model
using (HttpClient client = new HttpClient())
{
Stream modelFile = await client.GetStreamAsync("<YOUR-REMOTE-FILE-LOCATION>");
trainedModel = mlContext.Model.Load(modelFile, out modelSchema);
}
Working with separate data preparation and model pipelines
Note
Working with separate data preparation and model training pipelines is optional. Separation of pipelines makes it easier to inspect the learned model parameters. For predictions, it's easier to save and load a single pipeline that includes the data preparation and model training operations.
When working with separate data preparation pipelines and models, the same process as single pipelines applies; except now both pipelines need to be saved and loaded simultaneously.
Given separate data preparation and model training pipelines:
// Define data preparation estimator
IEstimator<ITransformer> dataPrepEstimator =
mlContext.Transforms.Concatenate("Features", new string[] { "Size", "HistoricalPrices" })
.Append(mlContext.Transforms.NormalizeMinMax("Features"));
// Create data preparation transformer
ITransformer dataPrepTransformer = dataPrepEstimator.Fit(data);
// Define StochasticDualCoordinateAscent regression algorithm estimator
var sdcaEstimator = mlContext.Regression.Trainers.Sdca();
// Pre-process data using data prep operations
IDataView transformedData = dataPrepTransformer.Transform(data);
// Train regression model
RegressionPredictionTransformer<LinearRegressionModelParameters> trainedModel = sdcaEstimator.Fit(transformedData);
Save data preparation pipeline and trained model
To save both the data preparation pipeline and trained model, use the following commands:
// Save Data Prep transformer
mlContext.Model.Save(dataPrepTransformer, data.Schema, "data_preparation_pipeline.zip");
// Save Trained Model
mlContext.Model.Save(trainedModel, transformedData.Schema, "model.zip");
Load data preparation pipeline and trained model
In a separate process or application, load the data preparation pipeline and trained model simultaneously as follows:
// Create MLContext
MLContext mlContext = new MLContext();
// Define data preparation and trained model schemas
DataViewSchema dataPrepPipelineSchema, modelSchema;
// Load data preparation pipeline and trained model
ITransformer dataPrepPipeline = mlContext.Model.Load("data_preparation_pipeline.zip",out dataPrepPipelineSchema);
ITransformer trainedModel = mlContext.Model.Load("model.zip", out modelSchema);