トレーニング済みモデルの保存と読み込み

アプリケーションでのトレーニング済みモデルの保存と読み込みの方法について説明します。

モデルは、モデル構築プロセス全体を通してメモリ内に存在し、アプリケーションのライフサイクル全体を通してアクセス可能です。 ただし、アプリケーションの実行が停止した後は、モデルがローカルまたはリモートのどこかに保存されていないと、アクセスできなくなります。 通常、モデルは、トレーニング後のどこかの時点で推論または再トレーニングのために他のアプリケーションで使用されます。 そのため、モデルを保存することが重要です。 後述するようにデータ準備とモデル トレーニング パイプラインを使用する場合は、このドキュメントの以降のセクションで説明する手順を使用してモデルを保存し、読み込みます。 このサンプルでは線形回帰モデルを使用しますが、他の 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");

ほとんどのモデルとデータ準備パイプラインは同じクラスのセットから継承するため、このようなコンポーネントの save メソッドと load メソッドのシグネチャは同じです。 実際のユース ケースに応じて、データ準備パイプラインとモデルを 1 つの EstimatorChain に結合して 1 つの ITransformer を出力するか、それぞれを分けて個別の ITransformer を作成します。

モデルをローカルに保存する

モデルを保存するときには、以下の 2 つが必要です。

  1. モデルの ITransformer
  2. ITransformer の想定される入力の DataViewSchema

モデルのトレーニング後、Save メソッドを使用し、入力データの DataViewSchema を使用してトレーニング済みモデルを model.zip というファイルに保存します。

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

ONNX モデルをローカルに保存する

モデルの ONNX バージョンをローカルに保存するには、Microsoft.ML.OnnxConverter NuGet パッケージがインストールされている必要があります。

OnnxConverter パッケージがインストールされていると、それを使用してモデルを ONNX 形式に保存できます。 これには、File.Create メソッドを使用して FileStream として提供できる Stream オブジェクトが必要です。 File.Create メソッドは、ONNX モデルのパスとなる文字列をパラメーターとして受け取ります。

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

ストリームを作成したら、ConvertToOnnx メソッドを呼び出して、トレーニング済みのモデル、モデルのトレーニングに使用されるデータ、ストリームを指定できます。 ただし、すべてのトレーナーとトランスフォーマーを ONNX にエクスポートできるわけではありません。 完全な一覧については、変換に関する記事と「ML.NET アルゴリズムの選び方」ガイドを参照してください。

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

ローカルに保存されているモデルを読み込む

ローカルに保存されたモデルは、他のプロセスやアプリケーション (ASP.NET CoreServerless Web Applications など) で使用できます。 詳細については、Web API での ML.NET の使用ML.NET サーバーレス Web アプリの展開に関するハウツー記事を参照してください。

個別のアプリケーションまたはプロセスでは、ファイル パスと共に 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 モデルを読み込んで予測を行うには、Microsoft.ML.OnnxTransformer NuGet パッケージが必要です。

OnnxTransformer パッケージをインストールすると、ApplyOnnxModel メソッドを使用して既存の ONNX モデルを読み込むことができます。 必要なパラメーターは、ローカルの 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
    }
};

新しいデータがある場合は、LoadFromEnumerable メソッドを使ってそのデータを IDataView に読み込むことができます。

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

これで、新しいデータに合わせるために、新しい IDataView を使用できるようになりました。

estimator.Fit(newHousingDataView);

ApplyOnnxModel から推定器で Fit メソッドを使用すると、前述の「モデルをローカルに保存する」のセクションSave メソッドを使用して新しいモデルとして保存できるようになります。

リモートに保存されているモデルを読み込む

リモートの場所に保存されているデータ準備パイプラインとモデルをアプリケーションに読み込むには、Load メソッドでファイル パスではなく Stream を使用します。

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

個別のデータ準備パイプラインとモデル パイプラインを使用する

注意

個別のデータ準備パイプラインとモデル トレーニング パイプラインの使用は任意です。 パイプラインを分けると、学習したモデルのパラメーターを簡単に調べることができます。 予測のためには、データ準備とモデル トレーニング操作を含む 1 つのパイプラインを保存して読み込む方が簡単です。

個別のデータ準備パイプラインとモデルを使用するときは、1 つのパイプラインと同じプロセスが適用されます。ただし、この場合は両方のパイプラインを同時に保存して読み込む必要があります。

個別のデータ準備パイプラインとモデル トレーニング パイプラインの例を次に示します。

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