Salvar e carregar modelos treinados
Saiba como salvar e carregar modelos treinados em seu aplicativo.
Em todo o processo de criação de modelo, um modelo reside na memória e é acessível em todo o ciclo de vida do aplicativo. No entanto, depois que o aplicativo terminar a execução, se o modelo não for salvo em algum lugar local ou remotamente, ele não ficará mais acessível. Normalmente, os modelos são usados em algum momento após o treinamento em outros aplicativos para inferência de tipos ou novo treinamento. Assim, é importante armazenar o modelo. Salve e carregue modelos usando as etapas descritas nas seções subsequentes deste documento ao usar pipelines de treinamento de modelo e preparação de dados como os detalhados abaixo. Embora este exemplo use um modelo de regressão linear, o mesmo processo se aplica a outros algoritmos do ML.NET.
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");
Porque a maioria dos pipelines de preparação de dados e modelos herda o mesmo conjunto de classes, as assinaturas do método salvar e carregar para esses componentes são iguais. Dependendo do seu caso de uso, você pode tanto combinar o pipeline de preparação de dados e o modelo em um único EstimatorChain
que geraria um único ITransformer
quanto separá-los, criando um ITransformer
separado para cada um.
Salvar um modelo localmente
Ao salvar um modelo, você precisa de dois itens:
- O
ITransformer
do modelo. - O
DataViewSchema
da entrada esperada deITransformer
.
Depois de treinar o modelo, use o método Save
para salvar o modelo treinado em um arquivo chamado model.zip
usando o DataViewSchema
dos dados de entrada.
// Save Trained Model
mlContext.Model.Save(trainedModel, data.Schema, "model.zip");
Salvar um modelo ONNX localmente
Para salvar uma versão ONNX do seu modelo localmente, você precisará ter instalado o pacote NuGet Microsoft.ML.OnnxConverter.
Com o pacote OnnxConverter
instalado, podemos usá-lo para salvar nosso modelo no formato ONNX. Isso requer um objeto Stream
que podemos fornecer como um FileStream
usando o método File.Create
. O método File.Create
usa uma cadeia de caracteres como um parâmetro que será o caminho do modelo ONNX.
using FileStream stream = File.Create("./onnx_model.onnx");
Com o fluxo criado, podemos chamar o método ConvertToOnnx
e fornecer o modelo treinado, os dados usados para treinar o modelo e o fluxo. No entanto, nem todos os treinadores e transformadores são exportáveis para o ONNX. Para obter uma lista completa, visite os guias Transformações e Como escolher um algoritmo de ML.NET.
mlContext.Model.ConvertToOnnx(trainedModel, data, stream);
Carregar um modelo armazenado localmente
Os modelos armazenados localmente podem ser usados em outros processos ou aplicativos, como ASP.NET Core
e Serverless Web Applications
. Veja os artigos de instruções Usar ML.NET na API Web e Implantar aplicativo Web sem servidor do ML.NET para saber mais.
Em um aplicativo ou processo separado, use o método Load
juntamente com o caminho do arquivo para obter o modelo treinado em seu aplicativo.
//Define DataViewSchema for data preparation pipeline and trained model
DataViewSchema modelSchema;
// Load trained model
ITransformer trainedModel = mlContext.Model.Load("model.zip", out modelSchema);
Carregar um modelo ONNX localmente
Para carregar um modelo ONNX para previsões, você precisará do pacote NuGet Microsoft.ML.OnnxTransformer.
Com o pacote OnnxTransformer
instalado, você pode carregar um modelo ONNX existente usando o método ApplyOnnxModel
. O parâmetro necessário é uma cadeia de caracteres que é o caminho do modelo ONNX local.
OnnxScoringEstimator estimator = mlContext.Transforms.ApplyOnnxModel("./onnx_model.onnx");
O método ApplyOnnxModel
retorna um objeto OnnxScoringEstimator
. Primeiro, precisamos carregar os novos dados.
HousingData[] newHousingData = new HousingData[]
{
new()
{
Size = 1000f,
HistoricalPrices = new[] { 300_000f, 350_000f, 450_000f },
CurrentPrice = 550_00f
}
};
Com os novos dados, podemos carregá-los em um IDataView
usando o método LoadFromEnumerable
.
IDataView newHousingDataView = mlContext.Data.LoadFromEnumerable(newHousingData);
Agora, podemos usar o novo IDataView
para se ajustar aos novos dados.
estimator.Fit(newHousingDataView);
Depois de usar o método Fit em um avaliador de ApplyOnnxModel
, ele poderá ser salvo como um novo modelo usando o método Save mencionado na seção Salvar um modelo localmente.
Carregar um modelo armazenado remotamente
Para carregar os pipelines de preparação de dados e modelos armazenados em um local remoto em seu aplicativo, use Stream
em vez de um caminho de arquivo no método Load
.
// 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);
}
Trabalhando com pipelines de modelo e preparação de dados separados
Observação
Trabalhar com pipelines de treinamento de modelo e preparação de dados separados é opcional. A separação de pipelines facilita a inspeção dos parâmetros do modelo aprendido. Para obter previsões, é mais fácil de salvar e carregar um único pipeline que inclua as operações de treinamento de modelo e preparação de dados.
Ao trabalhar com modelos e pipelines de preparação de dados separados, aplica-se o mesmo processo que o para pipelines únicos, exceto que agora os dois pipelines precisam ser salvos e carregados simultaneamente.
Dados pipelines de treinamento de modelo e preparação de dados separados:
// 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);
Salve o pipeline de preparação de dados e o modelo treinado
Para salvar o pipeline de preparação de dados e o modelo treinado, use os seguintes comandos:
// 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");
Carregar o pipeline de preparação de dados e o modelo treinado
Em um processo ou aplicativo separado, carregue o modelo treinado e o pipeline de preparação de dados simultaneamente da seguinte maneira:
// 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);