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 po zatrzymaniu działania aplikacji, jeśli model nie zostanie zapisany lokalnie lub zdalnie, nie będzie 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 artykułu podczas korzystania z potoków przygotowywania danych i trenowania modelu, takich jak pokazane tutaj. 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 generowałby jeden element ITransformer, albo rozdzielić je, tworząc osobny ITransformer dla każdego z nich.

Lokalne zapisywanie modelu

Podczas zapisywania modelu potrzebne są dwie rzeczy:

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

Po wytrenowaniu modelu użyj metody Save, aby zapisać wytrenowany model do pliku o nazwie model.zip, używając DataViewSchema danych wejściowych.

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

Lokalne zapisywanie modelu ONNX

Aby lokalnie zapisać wersję swojego modelu w formacie Open Neural Network Exchange (ONNX), należy zainstalować pakiet NuGet Microsoft.ML.OnnxConverter.

Po zainstalowaniu OnnxConverter pakietu można go użyć do zapisania modelu w formacie ONNX. To wymaga obiektu Stream, który można przekazać jako FileStream za pomocą metody File.Create. Metoda File.Create przyjmuje parametr ciągu reprezentujący ścieżkę modelu ONNX.

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

Po utworzeniu strumienia możesz wywołać metodę ConvertToOnnx i przekazać do niej wytrenowany model, dane użyte do wytrenowania modelu oraz strumień. Jednak nie wszystkie trenery i transformatory można eksportować do ONNX. Aby uzyskać pełną listę, zobacz przewodniki Transforms i Jak wybrać algorytm ML.NET.

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

Ładowanie modelu przechowywanego lokalnie

Ważna

Ładuj tylko modele z zaufanych źródeł. Ładowanie modeli z niezaufanych źródeł jest zagrożeniem bezpieczeństwa.

Modele przechowywane lokalnie mogą być używane w innych procesach lub aplikacjach, takich jak ASP.NET Core i bezserwerowe aplikacje internetowe. Aby uzyskać więcej informacji, zobacz Use ML.NET in Web API and Deploy ML.NET Serverless Web App.

W oddzielnej aplikacji lub procesie użyj metody Load, podając ścieżkę do pliku, aby załadować 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);

Załaduj model ONNX lokalnie

Aby załadować model ONNX na potrzeby prognoz, zainstaluj pakiet NuGet Microsoft.ML.OnnxTransformer.

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

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

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

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

Załaduj nowe dane do IDataView obiektu przy użyciu LoadFromEnumerable metody .

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

Teraz możesz użyć nowego IDataView, aby dopasować się do nowych danych.

estimator.Fit(newHousingDataView);

Po użyciu metody Fit na estymatorze z ApplyOnnxModel można go zapisać jako nowy model przy użyciu metody Save, opisanej w sekcji zapisywanie modelu lokalnie.

Ładowanie modelu przechowywanego zdalnie

Aby załadować do aplikacji potoki przygotowania danych i modele przechowywane w lokalizacji zdalnej, użyj elementu Stream 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

Note

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 przygotowywania danych i modelami obowiązuje ten sam proces, co w przypadku pojedynczych potoków. Różnica polega na tym, że oba potoki muszą być zapisywane i ładowane jednocześnie.

Zakładając oddzielne procesy 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 przygotowania 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);