Сохранение и загрузка обученных моделей

Узнайте, как сохранять и загружать в приложение обученные модели.

В процессе создания модель находится в памяти и доступна на протяжении всего жизненного цикла приложения. Однако, если приложение прекращает работу, а модель не сохранена ни на локальном компьютере, ни на удаленном ресурсе, она станет недоступна. Обычно модели используются после обучения в других приложениях для вывода либо для переобучения. В связи с этим модель необходимо сохранять. Сохраняйте и загружайте модели, выполняя действия, описанные в последующих разделах этого документа, при использовании конвейеров подготовки данных и обучения модели, подобных описанному ниже. Несмотря на то что в этом примере используется модель линейной регрессии, такая же процедура подходит и для других алгоритмов 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");

Поскольку большинство моделей и конвейеров подготовки наследуется из одного и того же набора классов, подписи методов сохранения и загрузки для этих компонентов будут одинаковы. В зависимости от варианта использования можно либо объединить конвейер подготовки данных и модель в единый объект EstimatorChain, который выдаст один ITransformer, или разделить их и создать таким образом для каждого отдельный ITransformer.

Сохранение модели на локальном компьютере

При сохранении модели нужны две вещи:

  1. ITransformer модели;
  2. DataViewSchema ожидаемых входных данных ITransformer.

После обучения модели вызовите метод Save, чтобы сохранить обученную модель в файл с именем model.zip, используя DataViewSchema входных данных.

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

Локальное сохранение модели ONNX

Чтобы сохранить версию ONNX модели локально, установите пакет NuGet Microsoft.ML.OnnxConverter.

После установки пакета OnnxConverter с его помощью можно сохранить модель в формате ONNX. Для этого требуется объект Stream, который можно указать в качестве FileStream с помощью метода File.Create. Метод File.Create принимает строку в качестве параметра, который будет путем к модели ONNX.

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

После создания потока можно вызвать метод ConvertToOnnx и предоставить ему обученную модель, данные для обучения модели и поток. Однако не все обучающие службы и преобразователи можно экспортировать в ONNX. Полный список см. в руководствах по преобразованию и выбору алгоритма ML.NET.

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

Загрузка модели, сохраненной на локальном компьютере

Модели, сохраненные на локальном компьютере, можно использовать в других процессах или приложениях, таких как ASP.NET Core и Serverless Web Applications. Дополнительные сведения см. в статьях Использование ML.NET в веб-API и Развертывание бессерверного веб-приложения ML.NET.

В отдельном приложении или процессе вызовите метод Load с указанием пути к файлу, чтобы загрузить в приложение обученную модель.

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

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

Локальная загрузка модели ONNX

Чтобы загрузить модель ONNX для прогнозирования, потребуется пакет NuGet Microsoft.ML.OnnxTransformer.

После установки пакета OnnxTransformer можно загрузить существующую модель ONNX с помощью метода ApplyOnnxModel. Для этого необходима строка, которая является путем к локальной модели ONNX.

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

Метод ApplyOnnxModel возвращает объект OnnxScoringEstimator. Сначала необходимо загрузить новые данные.

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

С новыми данными мы можем выполнить загрузку в IDataView с помощью метода LoadFromEnumerable.

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

Теперь мы можем использовать новый интерфейс IDataView для размещения новых данных.

estimator.Fit(newHousingDataView);

После использования метода Fit в оценщике из ApplyOnnxModel можно сохранить его как новую модель с помощью метода Save, описанного в разделе Сохранение модели на локальном компьютере.

Загрузка модели, сохраненной на удаленном ресурсе

Чтобы загрузить в приложение конвейеры подготовки данных и модели, сохраненные на удаленном ресурсе, вместо пути к файлу укажите Stream в методе 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);
}

Работа с отдельными конвейерами подготовки данных и модели

Примечание.

Работать с отдельными конвейерами подготовки данных и обучения модели необязательно. Отделение конвейеров упрощает проверку параметров обученной модели. Для создания прогнозов проще сохранять и загружать единый конвейер, который включает операции подготовки данных и обучения модели.

При работе с отдельными конвейерами подготовки данных и моделей применяется тот же порядок действий, что и при работе с единым конвейером за тем исключением, что оба конвейера должны сохраняться и загружаться одновременно.

Допустим, у нас есть отдельные конвейеры подготовки данных и обучения модели:

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

Сохранение конвейера подготовки данных и обученной модели

Чтобы сохранить и конвейер подготовки данных, и обученную модель, используйте следующие команды:

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

Загрузка конвейера подготовки данных и обученной модели

Для одновременной загрузки конвейера подготовки данных и обученной модели в отдельный процесс или приложение используйте следующие команды:

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