Zapisywanie i ładowanie wytrenowanych modeli

Dowiedz się, jak zapisywać i ładować wytrenowane modele w aplikacji.

W całym procesie tworzenia modelu model znajduje się w pamięci i jest dostępny w całym cyklu życia aplikacji. Jednak gdy aplikacja przestanie działać, jeśli model nie jest zapisywany lokalnie lub zdalnie, nie jest już dostępny. Zazwyczaj modele są używane w pewnym momencie po trenowaniu w innych aplikacjach na potrzeby wnioskowania lub ponownego trenowania. Dlatego ważne jest przechowywanie modelu. Zapisywanie i ładowanie modeli przy użyciu kroków opisanych w kolejnych sekcjach tego dokumentu podczas korzystania z potoków przygotowywania danych i trenowania modelu, takich jak opisany poniżej. Mimo że w tym przykładzie użyto modelu regresji liniowej, ten sam proces dotyczy innych algorytmów 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");

Ponieważ większość modeli i potoków przygotowywania danych dziedziczy z tego samego zestawu klas, sygnatury metody zapisywania i ładowania dla tych składników są takie same. W zależności od przypadku użycia można połączyć potok przygotowywania danych i model w jeden EstimatorChain , który wyprowadźby pojedynczą ITransformer lub oddzielną, tworząc oddzielną ITransformer dla każdego z nich.

Lokalne zapisywanie modelu

Podczas zapisywania modelu potrzebne są dwie rzeczy:

  1. Model ITransformer .
  2. Oczekiwane DataViewSchema dane wejściowe elementu ITransformer.

Po wytrenowanym modelu użyj Save metody , aby zapisać wytrenowany model w pliku o nazwie model.zip przy użyciu DataViewSchema danych wejściowych.

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

Lokalne zapisywanie modelu ONNX

Aby zapisać lokalnie wersję ONNX modelu, musisz zainstalować pakiet NuGet Microsoft.ML.OnnxConverter .

Po zainstalowaniu OnnxConverter pakietu możemy użyć go do zapisania modelu w formacie ONNX. Stream Wymaga to obiektu, który możemy podać jako metodę FileStreamFile.Create . Metoda File.Create przyjmuje ciąg jako parametr, który będzie ścieżką modelu ONNX.

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

Po utworzeniu strumienia możemy wywołać metodę ConvertToOnnx i nadać jej wytrenowany model, dane używane do trenowania modelu i strumienia. Jednak nie wszystkie trenery i transformatory można eksportować do ONNX. Pełną listę można znaleźć w przewodnikach Transforms and How to Choose an ML.NET Algorithm (Jak wybrać algorytm ML.NET).

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

Ładowanie modelu przechowywanego lokalnie

Modele przechowywane lokalnie mogą być używane w innych procesach lub aplikacjach, takich jak ASP.NET Core i Serverless Web Applications. Aby dowiedzieć się więcej, zobacz artykuły How-to Use ML.NET in Web API and Deploy ML.NET Serverless Web App (Używanie ML.NET w internetowym interfejsie API i wdrażanie ML.NET bezserwerowej aplikacji internetowej).

W oddzielnej aplikacji lub procesie użyj Load metody wraz ze ścieżką pliku, aby pobrać wytrenowany model do aplikacji.

//Define DataViewSchema for data preparation pipeline and trained model
DataViewSchema modelSchema;

// Load trained model
ITransformer trainedModel = mlContext.Model.Load("model.zip", out modelSchema);

Lokalne ładowanie modelu ONNX

Aby załadować model ONNX na potrzeby prognoz, potrzebny będzie pakiet NuGet Microsoft.ML.OnnxTransformer .

Po zainstalowaniu OnnxTransformer pakietu można załadować istniejący model ONNX przy użyciu ApplyOnnxModel metody . Wymagany parametr jest ciągiem, który jest ścieżką lokalnego modelu ONNX.

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

Metoda ApplyOnnxModel zwraca OnnxScoringEstimator obiekt. Najpierw musimy załadować nowe dane.

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

Za pomocą nowych danych możemy załadować je do IDataView metody przy użyciu LoadFromEnumerable metody .

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

Teraz możemy użyć nowego IDataView elementu, aby zmieścić się w nowych danych.

estimator.Fit(newHousingDataView);

Po użyciu metody Fit w narzędziu do szacowania z ApplyOnnxModelprogramu można zapisać go jako nowy model przy użyciu metody Save wymienionej w sekcji Zapisywanie modelu lokalnie.

Ładowanie modelu przechowywanego zdalnie

Aby załadować potoki i modele przygotowywania danych przechowywane w lokalizacji zdalnej do aplikacji, użyj Stream ścieżki zamiast ścieżki pliku w metodzie 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);
}

Praca z oddzielnymi potokami przygotowywania danych i modelu

Uwaga

Praca z oddzielnymi potokami przygotowywania danych i trenowania modelu jest opcjonalna. Rozdzielenie potoków ułatwia sprawdzanie poznanych parametrów modelu. W przypadku przewidywań łatwiej jest zapisywać i ładować pojedynczy potok obejmujący operacje przygotowywania danych i trenowania modelu.

Podczas pracy z oddzielnymi potokami i modelami przygotowywania danych stosuje się ten sam proces co pojedyncze potoki; z wyjątkiem teraz oba potoki muszą być zapisywane i ładowane jednocześnie.

Biorąc pod uwagę oddzielne potoki przygotowywania danych i trenowania modelu:

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

Zapisywanie potoku przygotowywania danych i wytrenowanego modelu

Aby zapisać zarówno potok przygotowywania danych, jak i wytrenowany model, użyj następujących poleceń:

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

Ładowanie potoku przygotowywania danych i wytrenowanego modelu

W osobnym procesie lub aplikacji załaduj potok przygotowywania danych i wytrenowany model jednocześnie w następujący sposób:

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