Guardar e carregar modelos treinados

Aprenda a guardar e carregar modelos treinados na sua aplicação.

Ao longo de todo o processo de construção do modelo, um modelo vive na memória e está acessível ao longo de todo o ciclo de vida da aplicação. No entanto, uma vez que a aplicação deixa de funcionar, se o modelo não for guardado localmente ou remotamente, deixa de estar acessível. Normalmente, os modelos são usados em algum momento após o treino noutras aplicações, seja para inferência ou retreinamento. Por isso, é importante guardar o modelo. Guarde e carregue modelos seguindo os passos descritos nas secções seguintes deste artigo ao utilizar processos de preparação de dados e de treino de modelos, como o aqui apresentado. Embora esta amostra utilize um modelo de regressão linear, o mesmo processo aplica-se a outros algoritmos 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");

Como a maioria dos modelos e cadeias de preparação de dados herda do mesmo conjunto de classes, as assinaturas dos métodos de guardar e carregar destes componentes são as mesmas. Dependendo do seu caso de uso, pode combinar o pipeline de preparação de dados e o modelo num único EstimatorChain que geraria um ITransformer único ou separá-los, criando assim um separado ITransformer para cada um.

Guardar um modelo localmente

Ao guardar um modelo, precisas de duas coisas:

  1. O ITransformer do modelo.
  2. O DataViewSchema da entrada esperada de ITransformer.

Após treinar o modelo, use o Save método para guardar o modelo treinado num ficheiro chamado model.zip usando o DataViewSchema dos dados de entrada.

// Save Trained Model
mlContext.Model.Save(trainedModel, data.Schema, "model.zip");

Guardar um modelo ONNX localmente

Para guardar localmente uma versão Open Neural Network Exchange (ONNX) do seu modelo, deve instalar o pacote NuGet Microsoft.ML.OnnxConverter.

Com o OnnxConverter pacote instalado, podes usá-lo para guardar o teu modelo no formato ONNX. Isto requer um Stream objeto, que pode fornecer como um FileStream usando o File.Create método. O File.Create método assume um parâmetro de cadeia que representa o caminho do modelo ONNX.

using FileStream stream = File.Create("./onnx_model.onnx");

Com o fluxo criado, pode chamar o ConvertToOnnx método e dar-lhe 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 ONNX. Para uma lista completa, consulte os guias Transforms e How to Choose an ML.NET Algorithm.

mlContext.Model.ConvertToOnnx(trainedModel, data, stream);

Carregar um modelo armazenado localmente

Importante

Carregue apenas modelos de fontes confiáveis. Carregar modelos a partir de fontes não confiáveis é um risco de segurança.

Modelos armazenados localmente podem ser usados noutros processos ou aplicações como ASP.NET Core e aplicações web serverless. Para mais informações, consulte Use ML.NET na Web API e Deploy ML.NET Serverless Web App.

Numa aplicação ou processo separado, use o Load método juntamente com o caminho do ficheiro para integrar o modelo treinado na sua aplicação.

//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, instale o pacote NuGet Microsoft.ML.OnnxTransformer.

Com o OnnxTransformer pacote instalado, pode carregar um modelo ONNX existente usando o ApplyOnnxModel método. O parâmetro necessário é uma string que é o caminho do modelo local ONNX.

OnnxScoringEstimator estimator = mlContext.Transforms.ApplyOnnxModel("./onnx_model.onnx");

O ApplyOnnxModel método devolve um OnnxScoringEstimator objeto. Primeiro, tens de carregar os novos dados.

HousingData[] newHousingData = new HousingData[]
{
    new()
    {
        Size = 1000f,
        HistoricalPrices = new[] { 300_000f, 350_000f, 450_000f },
        CurrentPrice = 550_00f
    }
};

Carregue os novos dados num IDataView usando o LoadFromEnumerable método.

IDataView newHousingDataView = mlContext.Data.LoadFromEnumerable(newHousingData);

Agora podes usar o novo IDataView para se ajustar aos novos dados.

estimator.Fit(newHousingDataView);

Depois de utilizar o método Fit num estimador de ApplyOnnxModel, este pode depois ser guardado como um novo modelo utilizando o método Save descrito na secção guardar um modelo localmente.

Carregar um modelo armazenado remotamente

Para carregar para a sua aplicação pipelines de preparação de dados e modelos armazenados numa localização remota, utilize um Stream em vez de um caminho de ficheiro 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);
}

Trabalhar com fluxos separados de preparação de dados e de modelos

Note

Trabalhar com pipelines separados para preparação de dados e treino de modelos é opcional. A separação das cadeias de processamento facilita a inspeção dos parâmetros do modelo obtidos na aprendizagem. Para previsões, é mais fácil guardar e carregar um único pipeline que inclua a preparação de dados e as operações de treino do modelo.

Ao trabalhar com pipelines e modelos separados para preparação de dados, aplica-se o mesmo processo que para pipelines únicos. A diferença é que ambos os pipelines precisam de ser guardados e carregados simultaneamente.

Dados pipelines separados para a preparação de dados e para o treino de modelos:

// 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);

Guardar pipeline de preparação de dados e o modelo treinado

Para guardar tanto o pipeline de preparação de dados como o modelo treinado, utilize 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 fluxo de preparação de dados e o modelo treinado

Num processo ou aplicação separado, carregue simultaneamente o pipeline de preparação de dados e o modelo treinado da seguinte forma:

// 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);