Salvar e carregar modelos treinados

Saiba como salvar e carregar modelos treinados em seu aplicativo.

Durante todo o processo de criação do modelo, um modelo vive na memória e é acessível durante todo o ciclo de vida do aplicativo. No entanto, uma vez que o aplicativo para de ser executado, se o modelo não for salvo em algum lugar local ou remotamente, ele não estará mais acessível. Normalmente, os modelos são usados em algum momento após o treinamento em outros aplicativos, seja para inferência ou retreinamento. Por isso, é importante armazenar o modelo. Salve e carregue modelos usando as etapas descritas nas seções subsequentes deste documento ao usar pipelines de preparação de dados e treinamento de modelos, como o detalhado abaixo. Embora este exemplo use um modelo de regressão linear, o mesmo processo se aplica 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 pipelines de preparação de dados herdam do mesmo conjunto de classes, as assinaturas do método de salvamento e carregamento para esses componentes são as mesmas. Dependendo do seu caso de uso, você pode combinar o pipeline de preparação de dados e o modelo em um único EstimatorChain que resultaria em um único ITransformer ou separá-los, criando assim um separado ITransformer para cada um.

Guardar um modelo localmente

Ao salvar um modelo, você precisa de duas coisas:

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

Depois de treinar o modelo, use o Save método 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á do pacote NuGet Microsoft.ML.OnnxConverter instalado.

Com o OnnxConverter pacote instalado, podemos usá-lo para salvar nosso modelo no formato ONNX. Isso requer um Stream objeto que podemos fornecer como um FileStream usando o File.Create método. O File.Create método 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 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 obter uma lista completa, visite os guias Transformações e Como escolher um algoritmo 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. Consulte os artigos de instruções Usar ML.NET na API Web e Implantar ML.NET aplicativo Web sem servidor para saber mais.

Em um aplicativo ou processo separado, use o Load método junto 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 em um modelo ONNX para previsões, você precisará do pacote NuGet Microsoft.ML.OnnxTransformer .

Com o OnnxTransformer pacote instalado, você pode carregar um modelo ONNX existente usando o ApplyOnnxModel método. 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 ApplyOnnxModel método retorna um OnnxScoringEstimator objeto. 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 método de uso LoadFromEnumerable .

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

Agora, podemos usar o novo IDataView para ajustar os novos dados.

estimator.Fit(newHousingDataView);

Depois de usar o método Fit em um estimador do ApplyOnnxModel, ele pode ser salvo como um novo modelo usando o método Save mencionado salvar um modelo localmente seção.

Carregar um modelo armazenado remotamente

Para carregar pipelines de preparação de dados e modelos armazenados em um local remoto em seu aplicativo, use um Stream caminho em vez de um caminho de arquivo no Load método.

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

Nota

Trabalhar com pipelines de treinamento de modelo e preparação de dados separados é opcional. A separação de dutos facilita a inspeção dos parâmetros do modelo aprendido. Para previsões, é mais fácil salvar e carregar um único pipeline que inclui a preparação de dados e operações de treinamento de modelos.

Ao trabalhar com pipelines e modelos de preparação de dados separados, aplica-se o mesmo processo que pipelines únicos; Só que agora ambos os pipelines precisam ser salvos e carregados simultaneamente.

Dada a preparação de dados separada e pipelines de treinamento de modelo:

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

Salvar pipeline de preparação de dados e 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");

Pipeline de preparação de dados de carga e modelo treinado

Em um processo ou aplicativo separado, carregue o pipeline de preparação de dados e o modelo treinado 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);