Pythonでトレーニング済みモデルを保存する方法
Pythonでトレーニング済みモデルを保存する方法
実世界の機械学習(ML)のユースケースを取り組む際に、最適なアルゴリズム/モデルを見つけることは責任の終わりではありません。これらのモデルを将来の使用と本番環境への展開のために保存、保管、パッケージ化することが重要です。
これらの手法は以下の理由で必要です:
- バックアップ:トレーニングされたモデルは、元のデータが損傷または破壊された場合のバックアップとして保存できます。
- 再利用性と再現性:MLモデルの構築は本来時間がかかります。コストと時間を節約するために、モデルを実行するたびに同じ結果を得ることが重要です。モデルを正しく保存し、保管することでこれが実現されます。
- 展開:トレーニングされたモデルを実世界の設定に展開する際には、簡単に展開できるようにパッケージ化する必要があります。これにより、他のシステムやアプリケーションが手間をかけずに同じモデルを使用できるようになります。
繰り返しになりますが、MLモデルの保存と保管は共有、再利用性、再現性を容易にし、モデルのパッケージ化は迅速かつ簡単な展開を可能にします。これらの3つの操作は、モデル管理プロセスを簡素化するために調和して機能します。
この記事では、トレーニングされた機械学習モデルの保存、保管、パッケージ化の異なる方法、および各方法の利点と欠点について学びます。しかし、その前に、これらの3つの用語の違いを理解する必要があります。
モデルの保存、パッケージ化、保管
これらの用語は似ているように見えますが、同じではありません。
保存は、モデルのパラメータ、重みなどをファイルに保存するプロセスを指します。通常、すべてのMLおよびDLモデルは、モデルを保存するためのいくつかの方法(例:model.save())を提供しています。ただし、保存は単一のアクションであり、モデルのバイナリファイルのみを提供するため、MLアプリケーションを本番環境に適用するためには引き続きコードが必要です。
パッケージ化は、モデルファイル、依存関係、設定ファイルなどのモデルの必要なコンポーネントを1つの展開可能なパッケージにまとめるプロセスを指します。パッケージの目的は、MLモデルを本番環境で簡単に配布および展開できるようにすることです。
パッケージ化されたモデルは、ウェブアプリケーション、モバイルアプリケーションなどのさまざまな本番環境で展開できるため、異なる環境に展開することができます。Dockerは、これを実現するためのツールの1つです。
保管は、トレーニングされたモデルファイルをいつでも必要な時にアクセスできるように、中央集中型のストレージに保存するプロセスを指します。モデルを保管する際には、通常、モデルを取得していつでも使用できるストレージの種類を選択します。モデルレジストリは、この問題を解決するツールのカテゴリです。
それでは、モデルの保存方法を見てみましょう。
Pythonでトレーニング済みモデルを保存する方法
このセクションでは、機械学習(ML)およびディープラーニング(DL)モデルを保存するさまざまな方法を見ていきます。まず、最も有名なアヤメデータセットを使用して単純な分類モデルを作成しましょう。
注意:この記事の焦点は最も優れたMLモデルを作成する方法を示すことではなく、トレーニング済みモデルを効果的に保存する方法を説明することです。
まず、次のように必要な依存関係とアヤメデータセットを読み込む必要があります:
# 必要な依存関係を読み込む import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import classification_report, confusion_matrix # データセットを読み込む url = "iris.data" # 使用する列名 names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'Class'] # URLからデータセットを読み込む dataset = pd.read_csv(url, names=names) # iris分類データの最初の数行を確認する dataset.head()次に、データをトレーニングセットとテストセットに分割し、特徴量の標準化などの必要な前処理ステージを適用する必要があります。
# 独立変数と従属変数を分離する X = dataset.iloc[:, :-1].values y = dataset.iloc[:, 4].values # データセットをランダムにトレーニングセットとテストセットに分割する X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20) # 特徴量の標準化 scaler = StandardScaler() scaler.fit(X_train) X_train = scaler.transform(X_train) X_test = scaler.transform(X_test)最後に、トレーニングデータで分類モデル(任意のモデルを選択してください)を学習し、テストデータでその性能を確認する必要があります。
# KNN分類器のトレーニング model = KNeighborsClassifier(n_neighbors=5) model.fit(X_train, y_train) # テストデータに対して予測を行う y_predict = model.predict(X_test) # 結果を確認する print(confusion_matrix(y_test, y_predict)) print(classification_report(y_test, y_predict))これで将来の利用のために保存したいMLモデルがあります。MLモデルを保存する最初の方法はpickleファイルを使用することです。
pickleを使用してトレーニング済みモデルを保存する
pickleモジュールは、Pythonオブジェクトを直列化(シリアライズ)および非直列化(デシリアライズ)するために使用できます。ピックリング(Pickling)は、Pythonオブジェクトの階層をバイトストリームに変換するプロセスであり、アンピックリング(Unpickling)は、バイトストリーム(バイナリファイルまたはバイトで構成された他のオブジェクトから)をオブジェクト階層に変換するプロセスです。
MLモデルをpickleファイルとして保存するには、デフォルトのPythonインストールにすでに含まれているpickleモジュールを使用する必要があります。
アヤメの分類モデルをpickleファイルとして保存するには、単にファイル名を決定し、モデルをpickleファイルにダンプするだけです。
import pickle # アヤメの分類モデルをpickleファイルとして保存する model_pkl_file = "iris_classifier_model.pkl" with open(model_pkl_file, 'wb') as file: pickle.dump(model, file)ファイルはバイトとして保存するためにwb(バイナリ書き込み)モードで開かれることに注意してください。また、dump()メソッドはモデルを指定したpickleファイルに保存します。
また、pickleモジュールのload()メソッドを使用してこのモデルを読み込むこともできます。保存されたモデルを読み込むには、pickleファイルをrb(バイナリ読み込み)モードで開く必要があります。
# pickleファイルからモデルを読み込む with open(model_pkl_file, 'rb') as file: model = pickle.load(file) # モデルを評価する y_predict = model.predict(X_test) # 結果を確認する print(classification_report(y_test, y_predict))読み込んだ後は、このモデルを使用して予測を行うことができます。
Pythonのpickleアプローチの利点
-
1
PickleはPythonの標準モジュールとして提供されており、MLモデルの保存と復元に簡単に使用できます。 -
2
Pickleファイルはカスタムオブジェクトを含むほとんどのPythonオブジェクトを処理できるため、モデルを保存する多目的な方法です。 -
3
小規模なモデルでは、pickleアプローチは非常に高速で効率的です。 -
4
MLモデルがアンピックルされると、以前の状態(変数や設定を含む)に復元されます。これにより、PythonのpickleファイルはMLモデルを保存するための最良の代替手段の1つとなります。
Pythonのpickleアプローチのデメリット
-
1
信頼性のないデータをアンピックルすると、pickleはセキュリティの脅威になる可能性があります。オブジェクトをアンピックルすると、悪意のあるコードが実行されることがありますので、信頼できるソースからの情報のみをアンピックルすることが重要です。 -
2
Pickle化されたオブジェクトの使用は、異なるPythonバージョンやオペレーティングシステム間で転送することができない場合があります。 -
3
メモリの使用量が大きいモデルの場合、pickle化すると巨大なファイルが作成されることがあり、問題が発生する可能性があります。 -
4
モデルの変更を時間の経過とともに追跡するのが困難になる場合があります。特にモデルが頻繁に更新され、さまざまなバージョンのモデルに対して複数のpickleファイルを作成することが実現不可能な場合です。
ピクルは小規模なモデルに最適であり、いくつかのセキュリティ上の問題もあります。これらの理由があるため、MLモデルを保存する別の代替手段を探すのに十分な理由です。次に、MLモデルを保存および読み込むためのJoblibについて説明します。
注:次のセクションでは、異なるテクニックを使用して同じアヤメ分類モデルを保存する方法を見ていきます。
Joblibでトレーニング済みモデルを保存する
JoblibはPythonで軽量なパイプラインを提供する一連のツールです(通常はScipyエコシステムの一部です)。主にディスクキャッシング、メモ化、並列計算に重点を置いており、Pythonオブジェクトの保存と読み込みに使用されます。Joblibは、パラメータが多いMLモデルに対して高速かつ信頼性のある処理を実現するために、NumPy配列に特化して最適化されています。
Joblibを使用して大きなモデルを保存するには、Pythonに事前にインストールされているJoblibモジュールを使用する必要があります。
import joblib # joblibを使用してモデルを保存する filename = 'joblib_model.sav' joblib.dump(model, filename)モデルを保存するには、拡張子が「.sav」または「.pkl」のファイル名を定義し、Joblibのdump()メソッドを呼び出す必要があります。
pickleと同様に、Joblibは保存されたMLモデルを読み込むためのload()メソッドを提供しています。
# joblibでモデルを読み込む loaded_model = joblib.load(filename) # モデルを評価する y_predict = model.predict(X_test) # 結果を確認する print(classification_report(y_test, y_predict))Joblibでモデルを読み込んだ後は、データに適用して予測に使用することができます。
Joblibを使用してMLモデルを保存する利点
-
1
Joblibは、メモリ要件が大きいモデルに特に重要な性能と効果的なパフォーマンスを提供します。 -
2
Joblibを介して直列化および逆直列化プロセスを並列化することで、マルチコアマシン上でのパフォーマンスを向上させることができます。 -
3
大量のメモリを要求するモデルに対して、Joblibはメモリマップドファイル形式を使用してメモリ使用量を削減します。 -
4
Joblibは、信頼性のないデータに対する保護を支援するための安全な関数のホワイトリストなど、さまざまなセキュリティ機能を提供しています。
Joblibを使用してMLモデルを保存する欠点
-
1
JoblibはNumPy配列に最適化されており、他のオブジェクトタイプとの互換性があまり良くありません。 -
2
JoblibはPickleよりも柔軟性が低く、直列化プロセスの設定オプションが少ないため、オプションの選択肢が少なくなります。 -
3
Pickleと比較して、Joblibはあまり知られていないため、ヘルプやドキュメントを見つけるのがより難しい場合があります。
Joblibはpickleが抱える主な問題を解決していますが、独自の問題も抱えています。次に、JSONを使用してモデルを手動で保存および復元する方法を見ていきます。
JSONを使用してトレーニング済みモデルを保存する
MLモデルの保存と復元手順を完全に制御したい場合は、JSONを使用します。他の2つの方法とは異なり、この方法ではMLモデルを直接ファイルにダンプするのではなく、保存するためにモデルの異なるパラメータを明示的に定義する必要があります。
この方法を使用するには、デフォルトのPythonインストールに含まれているPythonのjsonモジュールを使用する必要があります。JSONメソッドを使用するには、MLモデルに含まれるすべてのパラメータを書き込むための追加の作業が必要です。JSONを使用してモデルを保存するために、次のような関数を作成しましょう:
import json # json保存関数を作成する def save_json(model, filepath, X_train, y_train): saved_model = {} saved_model["algorithm"] = model.get_params()['algorithm'], saved_model["max_iter"] = model.get_params()['leaf_size'], saved_model["solver"] = model.get_params()['metric'], saved_model["metric_params"] = model.get_params()['metric_params'], saved_model["n_jobs"] = model.get_params()['n_jobs'], saved_model["n_neighbors"] = model.get_params()['n_neighbors'], saved_model["p"] = model.get_params()['p'], saved_model["weights"] = model.get_params()['weights'], saved_model["X_train"] = X_train.tolist() if X_train is not None else "None", saved_model["y_train"] = y_train.tolist() if y_train is not None else "None" json_txt = json.dumps(saved_model, indent=4) with open(filepath, "w") as file: file.write(json_txt) # アヤメ分類モデルをjsonファイルに保存する file_path = 'json_model.json' save_json(model, file_path, X_train, y_train)各モデルパラメータとそのデータをJSONで定義する必要があることがわかります。異なるモデルにはパラメータの詳細をチェックするための異なる方法があります。例えば、KNeighboursClassifierのget_params()はモデルのすべてのハイパーパラメータのリストを返します。これらのハイパーパラメータとデータ値を辞書に保存し、その辞書を「.json」という拡張子のファイルにダンプする必要があります。
このJSONファイルを読み込むには、単に開いて以下のようにパラメータにアクセスするだけです。
# JSONファイルを読み込む関数を作成する def load_json(filepath): with open(filepath, "r") as file: saved_model = json.load(file) return saved_model # モデルの設定をロードする saved_model = load_json('json_model.json') saved_model上記のコードでは、load_json()という関数が作成され、JSONファイルを読み込んでパラメータとデータを辞書として返します。
残念ながら、保存したモデルを直接JSONで使用することはできません。これらのパラメータとデータを読み込み、モデルを自分自身で再学習する必要があります。
JSONでMLモデルを保存する利点
-
1
異なるシステム間で交換する必要があるモデルを、プログラミング言語やプラットフォームで読み込むことができる移植可能な形式であるJSONを使用して行うことができます。 -
2
JSONは読みやすく理解しやすいテキストベースの形式であり、人間による検査や編集が必要なモデルに適しています。 -
3
PickleやJoblibと比較して、JSONはより軽量な形式であり、インターネットを介して転送する必要があるモデルにとって重要な要素となる小さいファイルを作成します。 -
4
デシリアライズ時にコードを実行するPickleとは異なり、JSONはセキュリティの脅威を最小限に抑えるセキュアな形式です。
JSONでMLモデルを保存する欠点
-
1
JSONはサポートされているデータ型が少ないため、固有のデータ型を使用する高度な機械学習モデルと互換性がない可能性があります。 -
2
特に大きなモデルの場合、JSONのシリアライズとデシリアライズは他の形式よりも遅くなる可能性があります。 -
3
代替形式と比較して、JSONは柔軟性が低く、シリアライズ手順を調整するためにより多くの努力が必要となる場合があります。 -
4
JSONは損失yな形式であり、元のモデルのすべての情報を保持しない場合があり、正確な複製が必要なモデルにとって問題となる可能性があります。
セキュリティとJSON/pickleの利点を確保するために、モデルを専用のデータベースに保存することができます。次に、データベースにMLモデルを保存する方法を見ていきます。
TensorFlow Kerasで深層学習モデルを保存する
TensorFlowはDLベースのモデルをトレーニングするための人気のあるフレームワークであり、KerasはTensorFlowのラッパーです。多層のニューラルネットワーク設計とラベル付きデータを使用して、深層学習モデルをトレーニングします。これらのモデルには、重みとネットワークアーキテクチャという2つの主要なコンポーネントがあり、将来の使用のためにこれらを保存して復元する必要があります。通常、深層学習モデルを保存する方法は2つあります:
- モデルのアーキテクチャをJSONまたはYAMLファイルに保存し、重みをHDF5ファイルに保存する。
- モデルとアーキテクチャの両方をHDF5、protobuf、またはtfliteファイルに保存する。
これらのうちいずれかの方法を参照することができますが、一般的にはモデルの重みとアーキテクチャを一緒にHDF5ファイルに保存する方法がよく使われます。
TensorFlow Kerasで深層学習モデルを保存するには、KerasのModelオブジェクトのsave()メソッドを使用します。このメソッドは、モデルのアーキテクチャ、オプティマイザ、および重みを含む、後で予測を行うためにロードできる形式でモデル全体を保存します。
以下は、TensorFlow KerasベースのDLモデルを保存する方法を示す例のコードスニペットです。
# TensorFlowの依存関係をインポートする from tensorflow.keras.models import Sequential, model_from_json from tensorflow.keras.layers import Dense # モデルのアーキテクチャを定義する model = Sequential() model.add(Dense(12, input_dim=4, activation='relu')) model.add(Dense(8, activation='relu')) model.add(Dense(1, activation='sigmoid')) # モデルをコンパイルする model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) # モデルをフィットさせる model.fit(X_train, y_train, epochs=150, batch_size=10, verbose=0) # モデルとそのアーキテクチャを保存する model.save('model.h5')これで、モデルのアーキテクチャを定義し、適切な設定でモデルをトレーニングし、最後にsave()メソッドを使用して保存するだけです。
Kerasで保存されたモデルをロードするのは、Pythonでファイルを読み込むのと同じくらい簡単です。モデルファイルのパスを指定してload_model()メソッドを呼び出すだけで、モデルがロードされます。
# 必要な依存関係を定義 from tensorflow.keras.models import load_model # モデルをロード model = load_model('model.h5') # モデルの情報を確認 model.summary()モデルがロードされました。
TensorFlow Kerasでモデルを保存する利点
-
1
TensorFlow Kerasでモデルを保存してロードすることは、save()
およびload_model()
関数を使用することで非常に簡単です。これにより、他の人とモデルを共有したり、本番環境に展開したりすることが容易になります。 -
2
Kerasモデルを保存すると、モデルのアーキテクチャ、オプティマイザ、および重みが1つのファイルに保存されます。アーキテクチャと重みを別々にロードする必要がないため、モデルを簡単にロードして予測を生成することができます。 -
3
TensorFlow Kerasは、モデルを保存するためのさまざまなファイル形式(HDF5形式(.h5)、TensorFlow SavedModel形式(.pb)、TensorFlow Lite形式(.tflite))をサポートしています。これにより、ニーズに最適な形式を選択することができます。
TensorFlow Kerasでモデルを保存する際のデメリット
-
1
Kerasモデルを保存すると、特に多数のレイヤーやパラメータがある場合、保存されるファイルのサイズがかなり大きくなる場合があります。これは、帯域幅やストレージスペースが制限されている状況でモデルを共有または展開する際に問題となる可能性があります。 -
2
TensorFlow Kerasの異なるバージョンで保存されたモデルは、別のバージョンのKerasまたはTensorFlowでロードしようとすると問題が発生する可能性があります。 -
3
Kerasモデルを保存することは簡単ですが、モデルの保存やロード方法に関してより柔軟性が必要な場合は、異なるフレームワークや戦略が必要になる場合があります。
DLベースのモデルをトレーニングするために広く使用されているもう1つのフレームワークであるPyTorchという名前のフレームワークもあります。Pythonを使用してPyTorchベースの深層学習モデルを保存する方法を確認しましょう。
PyTorchで深層学習モデルを保存する
Facebookによって開発されたPyTorchは、DLベースのソリューションを開発するために非常によく使用されるフレームワークの1つです。動的な計算グラフを提供するため、モデルをリアルタイムで変更することができ、研究や実験に最適です。モデルのアーキテクチャと重みを保存するために、”.pt”および”.pth”のファイル形式を使用します。
PyTorchで深層学習モデルを保存するには、PyTorchのtorch.nn.Module
オブジェクトのsave()
メソッドを使用します。このメソッドは、モデルのアーキテクチャと重みを含むモデル全体を保存し、後でロードして予測を行うための形式で保存します。
以下は、PyTorchモデルを保存する方法を示すコードの例です:
# 依存関係をインポート import torch import torch.nn as nn import numpy as np # データのnumpy配列をテンソルに変換 X_train = torch.FloatTensor(X_train) X_test = torch.FloatTensor(X_test) y_train = torch.LongTensor(y_train) y_test = torch.LongTensor(y_test) # モデルのアーキテクチャを定義 class NeuralNetworkClassificationModel(nn.Module): def __init__(self,input_dim,output_dim): super(NeuralNetworkClassificationModel,self).__init__() self.input_layer = nn.Linear(input_dim,128) self.hidden_layer1 = nn.Linear(128,64) self.output_layer = nn.Linear(64,output_dim) self.relu = nn.ReLU() def forward(self,x): out = self.relu(self.input_layer(x)) out = self.relu(self.hidden_layer1(out)) out = self.output_layer(out) return out # 入力および出力の次元を定義 input_dim = 4 output_dim = 3 model = NeuralNetworkClassificationModel(input_dim,output_dim) # オプティマイザと損失関数オブジェクトを作成 learning_rate = 0.01 criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(),lr=learning_rate) # トレーニングステップを定義 def train_network(model,optimizer,criterion,X_train,y_train,X_test,y_test,num_epochs,train_losses,test_losses): for epoch in range(num_epochs): # 前のステップの勾配をクリアする optimizer.zero_grad() # フォワードフィード output_train = model(X_train) # 損失を計算 loss_train = criterion(output_train, y_train) # 逆伝播:勾配を計算 loss_train.backward() # 重みを更新 optimizer.step() output_test = model(X_test) loss_test = criterion(output_test,y_test) train_losses[epoch] = loss_train.item() test_losses[epoch] = loss_test.item() if (epoch + 1) % 50 == 0: print(f"エポック { epoch+1 }/{ num_epochs }、トレーニング損失: { loss_train.item():.4f }、テスト損失: {loss_test.item():.4f}") # モデルをトレーニング num_epochs = 1000 train_losses = np.zeros(num_epochs) test_losses = np.zeros(num_epochs) train_network(model,optimizer,criterion,X_train,y_train,X_test,y_test,num_epochs,train_losses,test_losses) # モデルを保存 torch.save(model, 'model_pytorch.pt')Tensorflowとは異なり、Pytorchではモデルのトレーニングにより多くの制御が可能です。上記のコードで示されているように、モデルのトレーニング後、save()メソッドを使用して重みとアーキテクチャを保存することができます。
Pytorchで保存されたモデルをロードするには、load()メソッドを使用する必要があります。
# モデルのロード model = torch.load('model_pytorch.pt') # モデルのサマリーを確認 model.eval()Pytorchでモデルを保存する利点
-
1
PyTorchが使用する計算グラフは動的であり、プログラムが実行されると構築されます。これにより、トレーニング中や推論中にモデルをより柔軟に変更することができます。 -
2
可変長の入力や出力を持つような動的なモデル(自然言語処理(NLP)やコンピュータビジョンで頻繁に使用される)に対して、PyTorchは改善されたサポートを提供しています。 -
3
PyTorchはPythonで記述されており、NumPyやpandasなどの他のPythonライブラリともうまく機能するため、トレーニング前後のデータの操作が簡単です。
Pytorchでモデルを保存するデメリット
-
1
PyTorchは使いやすいAPIを提供しているものの、深層学習やPythonプログラミングの初心者にとっては学習曲線が急かもしれません。 -
2
PyTorchは基本的には研究用のフレームワークであるため、TensorFlowやKerasのような他の深層学習フレームワークと比較して、本番展開に必要なツールが少ないかもしれません。
これだけではありません。モデル登録プラットフォームを使用すると、大きなサイズのDLベースのモデルも保存できます。これにより、開発者に追加の労力を必要とせずにデプロイおよびメンテナンスが容易になります。
この記事で使用されたデータセットとコードはこちらで見つけることができます。
MLモデルのパッケージ化方法
MLモデルは通常、トレーニングデータセットとトレーニングされた特定の環境に最適化されています。しかし、本番環境など、異なる環境でモデルを展開する場合にはさまざまな課題が発生する可能性があります。
これらの課題は、ハードウェア、ソフトウェア、およびデータ入力の違いなどに限定されません。モデルをパッケージ化することで、異なる環境でモデルをロードして使用するための標準的な形式にエクスポートまたはシリアライズすることが容易になります。
現在はさまざまなパッケージングオプションが利用可能です。PMML(Predictive Model Markup Language)、ONNX、TensorFlow SavedModel形式などのような標準的な形式でモデルをパッケージ化することで、異なるチームが異なるライブラリやツールを使用してモデルを共有および協力することが容易になります。さて、Pythonでさまざまなフレームワークを使用してMLモデルをパッケージ化するいくつかの例を見てみましょう。
注意: このセクションでも、同じアヤメ分類の例が表示されます。
PMMLを使用したモデルのパッケージ化
PythonでPMMLライブラリを使用すると、機械学習モデルをPMML形式にエクスポートし、ウェブサービス、バッチ処理システム、データ統合プラットフォームなどとして展開することができます。これにより、機械学習モデルを共有し、協力することが容易になり、さまざまな本番環境で展開することも容易になります。
PMMLを使用してMLモデルをパッケージ化するには、sklearn2pmml、jpmml-sklearn、jpmml-tensorflowなどのモジュールを使用することができます。
注意: PMMLを使用するには、システムにJava Runtimeがインストールされている必要があります。
以下は、PMMLを使用してトレーニングされたアヤメの分類器モデルをパッケージ化する例のコードスニペットです。
from sklearn2pmml import PMMLPipeline, sklearn2pmml # アヤメの分類器モデルをPMMLでパッケージ化 sklearn2pmml(PMMLPipeline([("estimator", model)]), "iris_model.pmml", with_repr=True)上記のコードでは、モデルオブジェクトを渡すことでPMMLパイプラインオブジェクトを作成するだけです。その後、sklearn2pmml()メソッドを使用してPMMLオブジェクトを保存する必要があります。以上です。これで、この“iris_model.pmml”ファイルをさまざまな環境で使用することができます。
PMMLの利点
-
1
PMMLはプラットフォームに依存しない形式であるため、PMMLモデルは多くのデータ処理プラットフォームと統合し、さまざまな製品環境で使用することができます。 -
2
PMMLはベンダーロックインを削減できるため、異なる機械学習プラットフォーム間でモデルをエクスポートおよびインポートすることができます。 -
3
PMMLモデルは、さまざまなデータ処理プラットフォームとシステムと統合できるため、製品環境で簡単に展開することができます。
PMMLのデメリット
-
1
一部の機械学習モデルとアルゴリズムは、限られたサポートのためにPMML形式でエクスポートできない場合があります。 -
2
PMMLはXMLベースの形式であり、冗長で柔軟性に欠けるため、PMML形式でエクスポートした後のモデルの変更や更新が困難になる場合があります。 -
3
複雑な特徴や相互作用を持つ複雑なモデルの場合、PMMLモデルの作成が困難になる場合があります。
ONNXを使用したモデルのパッケージング
MicrosoftとFacebookによって開発されたONNX(Open Neural Network Exchange)は、機械学習モデルを表現するためのオープンな形式です。これにより、異なるディープラーニングフレームワークとツール間での相互運用性が可能になります。
ONNXモデルは、モバイルデバイス、エッジデバイス、クラウドなど、さまざまなプラットフォームで効率的に展開することができます。また、Caffe2、TensorFlow、PyTorch、MXNetなど、さまざまなランタイムをサポートしているため、最小限の努力でモデルを異なるデバイスとプラットフォームに展開することができます。
ONNXでモデルを保存するには、システムにonnxとonnxruntimeパッケージをダウンロードする必要があります。
ここに、既存のMLモデルをONNX形式に変換する方法の例があります。
# 依存関係を読み込む import onnxmltools import onnxruntime # KNeighborsClassifierモデルをONNX形式に変換する onnx_model = onnxmltools.convert_sklearn(model) # ONNXモデルをファイルに保存する onnx_file = "iris_knn.onnx" onnxmltools.utils.save_model(onnx_model, onnx_file)必要なモジュールをインポートし、convert_sklearn()メソッドを使用してsklearnモデルをONNXモデルに変換するだけです。変換が完了したら、save_model()メソッドを使用してONNXモデルを「.onnx」拡張子のファイルに保存できます。ここではMLモデルの例を示していますが、ONNXは主にDLモデルに使用されます。
また、ONNX Runtimeモジュールを使用してこのモデルを読み込むこともできます。
# ONNXモデルをONNX Runtimeに読み込む sess = onnxruntime.InferenceSession(onnx_file) # テストデータにモデルを評価する input_data = {"X": X_test[:10].astype('float32')} output = sess.run(None, input_data)InferenceSession()メソッドを使用してセッションを作成し、ファイルからONNXモデルを読み込み、sess.run()メソッドを使用してモデルから予測を行います。
ONNXの利点
-
1
ほんの少しの努力で、ONNXモデルをモバイルデバイスやクラウドなど、さまざまなプラットフォームに簡単に展開することができます。ONNXはさまざまなハードウェアとソフトウェアプラットフォームのサポートを提供するため、さまざまなプラットフォームでモデルを展開することが簡単です。 -
2
ONNXモデルはパフォーマンスが最適化されているため、他の形式のモデルよりも高速に実行され、リソースを少なく消費します。
ONNXのデメリット
-
1
ONNXは主にディープラーニングモデルに適しており、他のタイプの機械学習モデルには適していない場合があります。 -
2
ONNXモデルは異なるディープラーニングフレームワークのすべてのバージョンと互換性があるわけではないため、互換性を確保するために追加の努力が必要になる場合があります。
Tensorflow SavedModelでモデルをパッケージ化する
TensorflowのSavedModel形式を使用すると、ディープラーニングモデルを簡単に保存および読み込むことができ、他のTensorflowツールやプラットフォームとの互換性が保証されます。さらに、本格的な環境でモデルを展開するための効率的な方法を提供します。
SavedModelは、Tensorflow Servingを使用してモデルを提供したり、Tensorflow Liteを使用してモバイルデバイスにモデルを展開したり、ONNXなどの他のMLライブラリにモデルをエクスポートしたりするなど、さまざまな展開シナリオをサポートしています。
これは、Tensorflowモデルを保存および読み込むためのシンプルで効率的な方法を提供します。APIは使いやすく、ドキュメントも充実しており、フォーマットは効率的かつスケーラブルに設計されています。
注意:上記のセクションで訓練した同じTensorFlowモデルを使用することができます。
SavedModel形式でモデルを保存するには、次のコードを使用できます:
import tensorflow as tf # SavedModel形式でモデルを保存 tf.saved_model.save(model, "my_model")load()メソッドを使用してモデルを読み込むこともできます。
# モデルを読み込む loaded_model = tf.saved_model.load("my_model")Tensorflow SavedModelの利点
-
1
SavedModelはプラットフォーム非依存でバージョン互換性があり、異なるプラットフォームやTensorFlowのバージョン間でモデルを共有および展開するのが簡単です。 -
2
SavedModelは、ONNXなどの他のMLライブラリにモデルをエクスポートしたり、TensorFlow Servingを使用してモデルを提供したり、TensorFlow Liteを使用してモバイルデバイスにモデルを配布したりするなど、さまざまな展開シナリオをサポートしています。 -
3
SavedModelはトレーニングと推論に最適化されており、分散トレーニングのサポートやGPUやTPUを使用したトレーニングの高速化が可能です。
Tensorflow SavedModelのデメリット
-
1
SavedModelファイルは大きくなる場合があります。特に複雑なモデルの場合、保存および転送が困難になる可能性があります。 -
2
SavedModelはTensorFlow専用であるため、他のMLライブラリやツールとの互換性が制約される場合があります。 -
3
保存されたモデルはバイナリファイルであり、詳細なモデルのアーキテクチャや動作の詳細を理解するのが難しい場合があります。
MLおよびDLモデルをパッケージングするための複数の方法を見てきたので、これらのモデルをパッケージ化、展開、提供するためのインフラストラクチャを提供するさまざまなツールが存在することも認識しておく必要があります。人気のあるツールのうち2つはBentoMLとMLFlowです。
BentoML
BentoMLは、本番で使用できる機械学習サービスを構築して展開するための柔軟なフレームワークです。データサイエンティストは、トレーニング済みモデル、その依存関係、およびモデルを提供するために必要なインフラストラクチャコードを再利用可能なパッケージである「Bento」にパッケージ化することができます。
BentoMLはさまざまな機械学習フレームワークと展開プラットフォームをサポートし、モデルのライフサイクルを管理するための統一されたAPIを提供します。モデルがBentoとしてパッケージ化されると、AWS Lambda、Kubernetes、またはDockerなどのさまざまな提供プラットフォームに展開することができます。BentoMLは、REST APIを介してモデルを提供するために使用できるAPIサーバーも提供します。詳細については、こちらをご覧ください。
MLFlow
MLFlowは、エンドツーエンドの機械学習ライフサイクルを管理するためのオープンソースプラットフォームです。実験の追跡、コードと依存関係のパッケージ化、モデルの展開に必要な包括的なツールセットを提供します。
MLFlowは、データサイエンティストが、AWS SageMaker、Azure ML、Google Cloud AI Platformなどのさまざまなプラットフォームに展開できる標準形式でモデルを簡単にパッケージ化することができます。また、モデルのバージョン管理とパフォーマンスの追跡を管理するためのモデルレジストリも提供します。さらに、MLFlowは、REST APIを介してモデルを提供するためのAPIを提供しており、ウェブアプリケーションや他のサービスに簡単に統合することができます。
MLモデルの保存方法
モデルの保存について知ったので、そのモデルを迅速かつ簡単に取得できるように保存する方法を見てみましょう。
データベースにMLモデルを保存する
MLモデルをリレーショナルデータベース(PostgreSQL、MySQL、Oracle SQLなど)やNoSQLデータベース(MongoDB、Cassandraなど)に保存することもできます。データベースの選択は、保存されるデータの種類とボリューム、パフォーマンスとスケーラビリティの要件、およびアプリケーションの具体的なニーズによって異なります。
PostgreSQLは、構造化データの保存と操作をサポートするMLモデルでの人気のある選択肢です。PostgreSQLにMLモデルを保存することで、異なるバージョンのモデルを追跡し、中央集権的な場所で管理することが簡単になります。
また、チームや組織全体でモデルを簡単に共有することも可能です。ただし、大きなモデルをデータベースに保存すると、データベースのサイズとクエリの時間が増加する可能性があるため、PostgreSQLでモデルを保存する際には、データベースのストレージ容量とパフォーマンスを考慮することが重要です。
MLモデルをPostgreSQLなどのデータベースに保存するには、まずトレーニング済みモデルをバイトストリーム(pickleオブジェクト)やJSONなどのシリアライズされた形式に変換する必要があります。
import pickle # モデルのシリアライズ model_bytes = pickle.dumps(model)次に、データベースに接続し、シリアライズされたモデルを格納するためのテーブルまたはコレクションを作成します。これには、Pythonのpsycopg2ライブラリを使用する必要があります。このライブラリはPostgreSQLデータベースに接続するためのものです。Pythonパッケージインストーラを使用してこのライブラリをダウンロードすることができます。
$ pip install psycopg2-binaryその後、次のようにデータベースに接続してMLモデルを保存するための接続を確立する必要があります。
import psycopg2 # データベースへの接続の確立 conn = psycopg2.connect( database="データベース名", user="ユーザー名", password="パスワード", host="127.0.0.1", port="5432" )データベース上で操作を行うためには、Pythonプログラムでクエリを実行するのに役立つカーソルオブジェクトを作成する必要があります。
# カーソルの作成 cur = conn.cursor()このカーソルを使用して、CREATE TABLEクエリを実行して新しいテーブルを作成することができます。
cur.execute("CREATE TABLE models (id INT PRIMARY KEY NOT NULL, name CHAR(50), model BYTEA)")注意: モデルオブジェクトの型がBYTEAであることを確認してください。
最後に、INSERT INTOコマンドを使用してモデルとその他のメタデータ情報を保存することができます。
# シリアライズされたモデルをデータベースに挿入 cur.execute("INSERT INTO models (id, name, model) VALUES (%s, %s, %s)", (1, 'iris-classifier', model_bytes)) conn.commit() # データベース接続を閉じる cur.close() conn.close()すべての操作が完了したら、カーソルとデータベースへの接続を閉じます。
最後に、データベースからモデルを読み込むには、名前またはIDでモデルをフィルタリングしてSELECTコマンドを使用することができます。
import psycopg2 import pickle # データベースへの接続 conn = psycopg2.connect( database="データベース名", user="ユーザー名", password="パスワード", host="127.0.0.1", port="5432" ) # データベースからシリアライズされたモデルを取得 cur = conn.cursor() cur.execute("SELECT model FROM models WHERE name = %s", ('iris-classifier',)) model_bytes = cur.fetchone()[0] # モデルのデシリアライズ model = pickle.loads(model_bytes) # データベース接続を閉じる cur.close() conn.close()データベースからモデルが読み込まれたら、以下のように予測に使用することができます:
# 読み込まれたモデルのテスト y_predict = model.predict(X_test) # 結果の確認 print(classification_report(y_test, y_predict))以上で、モデルがデータベースに保存され、読み込まれました。
MLモデルをデータベースに保存する利点
-
1
データベースにMLモデルを保存することで、複数のアプリケーションやユーザーが簡単にアクセスできる集中したストレージ場所が提供されます。 -
2
ほとんどの組織は既にデータベースを使用しているため、MLモデルを既存のインフラストラクチャに統合することが容易になります。 -
3
データベースはデータの取得に最適化されているため、MLモデルの取得がより高速かつ効率的に行えます。 -
4
データベースは認証、認可、暗号化などの堅牢なセキュリティ機能を提供するよう設計されています。これにより、保存されたMLモデルが安全であることが保証されます。
MLモデルをデータベースに保存するデメリット
-
1
データベースは構造化データの保存に設計されており、MLモデルなどの非構造化データの保存には最適化されていません。そのため、モデルのサイズ、ファイル形式などの制約や、データベースが対応できないMLモデルの他の側面に制限があるかもしれません。 -
2
データベースにMLモデルを保存することは複雑であり、データベース管理と機械学習の両方の専門知識が必要です。 -
3
MLモデルが大きい場合、データベースに保存することで拡張性の問題が発生する可能性があります。また、大きなモデルの取得はデータベースのパフォーマンスに影響を与える可能性があります。
機械学習モデルを保存する一般的な方法として、pickle、joblib、およびJSONがありますが、バージョニング、共有、および機械学習モデルの管理には制限があります。こうした制約に対処するために、MLモデルレジストリが登場し、代替手段に直面するすべての問題を解決します。
次に、モデルレジストリにMLモデルを保存することで、再現性と再利用性を実現する方法をご紹介します。
モデルレジストリにMLモデルを保存する
- モデルレジストリは、機械学習モデルを保存、バージョン管理、および管理するための中央リポジトリです。
- 通常、モデルのバージョニング、メタデータの制御、モデルの実行の比較などの機能が含まれます。
- MLまたはDLプロジェクトで作業している場合、モデルとそのメタデータをいつでもモデルレジストリから保存および取得できます。
- 何よりも、モデルレジストリはチームメンバー間の高いコラボレーションを可能にします。
モデルレジストリについての詳細は、この記事をご覧ください。
モデルレジストリのオプションはさまざまです。例えば、neptune.ai、Mlflow、Kubeflowなどがあります。これらのプラットフォームはそれぞれ独自の特徴を持っていますが、幅広い機能を提供できるレジストリを選ぶことが賢明です。
この例では、Neptuneを使用します。Neptuneには、機械学習モデルの組織化、保存、および管理のために開発されたモデルレジストリの機能があります。データサイエンティストやMLエンジニアがトレーニング済みモデルを管理する必要がある場合には、コラボレーション機能、ユーザーフレンドリーなインターフェース、およびモデルバージョニング機能を提供するため、非常に優れた選択肢となります。
ここで無料アカウントを設定するか、ツールについて詳しく学ぶことができます。
Neptuneレジストリにモデルを登録する
無料アカウントを作成した後、新しいプロジェクトボタンをクリックして新しいプロジェクトを開始できます。
プロジェクトの作成が完了すると、モデルを保存するためのさまざまな設定が表示されます。Neptuneでは、Scikit-Learn、Keras、Tensorflow、PyTorchなどのさまざまなフレームワークで作業できます。
モデルをNeptuneモデルレジストリに保存するには、次のライブラリをインストールする必要があります:
$ pip install neptune注意:pickleまたはjoblibモジュールを使用してトレーニング済みモデルをファイルに保存してから、モデルレジストリに保存する必要があります。
依存関係がインストールされたら、プログラムにインポートし、名前、一意のキー(大文字)、およびNeptuneの認証情報を提供してNeptuneモデルを初期化する必要があります。これらの情報は、Neptuneプロジェクトのモデルメタデータタブで確認できます。
import neptune # モデルを初期化 model = neptune.init_model( name="予測モデル", key="IRMOD", # プロジェクトごとに異なる必要があります project="ユーザー名/プロジェクト名", api_token="APIキー", # 認証情報 )上記のコードでは、Neptuneの依存関係がインポートされ、Neptuneの認証情報で保存および追跡したいモデル(モデルレジストリ)が初期化されます。次に、分類モデルのメタデータをNeptuneモデルオブジェクトに割り当てる必要があります。
# 分類モデルのメタデータをモデルオブジェクトに割り当てる model_info = {"size_limit": 7.09, "size_units": "KB"} model["model"] = model_info最後に、次のようにupload()メソッドを使用してモデルをNeptuneモデルレジストリにアップロードできます:
# モデルをレジストリにアップロード model["model/signature"].upload("iris_classifier_model.pkl")さらに、neptuneが提供するtrack_files()メソッドを使用して、データセットのバージョンを追跡できます。
# データセットのバージョンを追跡 model["data/train_and_test"].track_files("iris.data") # セッションを終了する model.stop()以上で、モデルとデータセットがレジストリに保存されました。また、stop()メソッドでセッションを閉じることを忘れないでください。
モデルのバージョン化
実世界の機械学習プロジェクトでは、さまざまなモデルとパラメータおよびハイパーパラメータの組み合わせを試すことがよくあります。このデータを追跡しないと、試したすべてのことを把握せず、再作業が必要になる可能性があります。
そこで、Neptuneモデルレジストリが役立ちます。数行のコードでモデルの異なるバージョンを登録することができます。まず、以下のようにModelVersionオブジェクトを初期化する必要があります:
# ModelVersionの初期化 import neptune model_version = neptune.init_model_version( model="IR-IRMOD", # プロジェクトごとに異なる必要があります project="ユーザー名/プロジェクト名", api_token="あなたのAPIキー", # あなたの認証情報 )その後、Neptuneレジストリに登録する各モデルバージョンにモデルとその他のメタデータの詳細をオプションで保存することもできます。
# モデルのパラメータ parameters = { "algorithm": clf_model.get_params()['algorithm'], "max_iter": clf_model.get_params()['leaf_size'], "solver": clf_model.get_params()['metric'], "metric_params": clf_model.get_params()['metric_params'], "n_jobs": clf_model.get_params()['n_jobs'], "n_neighbors": clf_model.get_params()['n_neighbors'], "p": clf_model.get_params()['p'], "weights": clf_model.get_params()['weights'], } # モデルのパラメータとその他のメタデータをログに記録 model_version["model/binary"].upload("iris_classifier_model.pkl") model_version["model/parameters"] = parameters model_version["data/dataset"].track_files("iris.data") model_version["validation/acc"] = 0.93 # セッションを終了 model_version.stop()完了したら、stop()メソッドを使用してセッションを終了できます。
レジストリからモデルとメタデータを取得する
最後に、必要なときに保存されたモデルとメタデータにアクセスする必要があります。レジストリに保存した特定のモデルバージョンをロードすることができます。モデルバージョンIDを指定して、ModelVersionオブジェクトを初期化する必要があります。
import neptune import pickle # モデルバージョンIDを指定 version_id = 'IR-IRMOD-1' # プロジェクトごとに異なる必要があります # 実行の初期化 model_version = neptune.init_model_version( with_id=version_id, project="ユーザー名/プロジェクト名", api_token="あなたのAPIキー", # あなたの認証情報 )完了したら、登録したモデル、メタデータ、データセットなど、異なるモデルオブジェクトにアクセスできます。まず、レジストリからモデルをダウンロードしてローカルに保存し、テストデータでのパフォーマンスをテストしてみましょう。
# モデルをレジストリからローカルに保存 if model_version.exists("model/binary"): model_version["model/binary"].download(f"model/{version_id}_model.pkl") # 保存したpickleファイルからモデルを読み込む with open(f"model/{version_id}_model.pkl", 'rb') as file: clf_model_2 = pickle.load(file) # モデルを評価 y_predict = clf_model_2.predict(X_test)また、Neptuneに保存したモデルのメタデータ情報も確認できます。
このメタデータをローカルにダウンロードするには、次のコードを使用できます:
<p以上です。Neptuneモデルレジストリから特定のモデルを保存およびロードする方法についての情報がわかりました。
# メタデータの確認 model_version["model/parameters"].fetch()Neptuneモデルレジストリについては、こちらをご覧ください。
モデルレジストリを使用したモデルの保存の利点
-
1
機械学習モデルの管理、保存、バージョン管理を一元化するための場所が提供される。 -
2
モデルレジストリには、バージョンやパフォーマンスメトリクスなどのモデルに関するメタデータが頻繁に含まれており、変更履歴を追跡したり、モデルの過去を理解したりするのが簡単になる。 -
3
モデルレジストリを使用すると、チームメンバーがモデルに共同作業し、簡単に作業を共有できる。 -
4
一部のモデルレジストリには、自動デプロイメントオプションが提供されており、モデルを本番環境に展開するプロセスを簡素化することができる。 -
5
モデルレジストリは、アクセス制御、暗号化、認証などのセキュリティ機能を提供することが多く、モデルを安全に保ち、承認されたユーザーのみがアクセスできるようにする。
モデルレジストリを使用したモデルの保存のデメリット
-
1
一部のモデルレジストリは有料の購読が必要であり、機械学習プログラムのコストが増える。 -
2
モデルレジストリには学習曲線があり、その機能や特徴に慣れるまで時間がかかる場合がある。 -
3
モデルレジストリの使用には他のツールやシステムとの統合が必要な場合があり、追加の依存関係が生じる可能性がある。
これまでさまざまなMLモデルの保存方法を見てきました(モデルレジストリが最適な方法です)。次に、Deep Learning(DL)ベースのモデルの保存方法をいくつか確認しましょう。
ベストプラクティス
このセクションでは、MLおよびDLモデルの保存のためのベストプラクティスのいくつかをご紹介します。
- ライブラリのバージョンを確認する: モデルの保存と読み込みに異なるライブラリのバージョンを使用すると、ライブラリの更新で構造的な変更が発生する可能性があるため、互換性の問題が発生することがあります。機械学習モデルを読み込む際に使用するライブラリのバージョンを保存したモデルと同じにする必要があります。
- Pythonのバージョンを確認する: MLパイプライン開発のすべての段階で同じPythonバージョンを使用することは良い習慣です。Pythonバージョンの変更によって実行の問題が発生することがあります。たとえば、TensorflowV1はPython 3.7までサポートされており、それ以降のバージョンで使用しようとするとエラーが発生します。
- モデルのアーキテクチャと重みを保存する: DLベースのモデルの場合、モデルの重みだけを保存してアーキテクチャを保存しない場合、モデルを再構築することはできません。トレーニング済みの重みとともにモデルのアーキテクチャを保存することで、モデルを完全に再構築して後で使用することができます。
- モデルのドキュメント化: モデルの目標、入力、出力、および予測パフォーマンスを文書化する必要があります。これにより、他の人がモデルの能力と制約を理解するのに役立ちます。
- モデルレジストリを使用する: neptune.aiのようなモデルレジストリを使用してモデルとそのバージョン、メタデータを追跡し、チームメンバーと共同作業する。
- 保存したモデルを安全に保つ: 機密データが含まれている場合、保存したモデルを暗号化したり、安全な場所に保存することで、保存したモデルを安全に保つ。
結論
まとめると、機械学習モデルの保存は開発プロセスで重要なステップであり、他の人とモデルを再利用および共有できるようにします。機械学習モデルを保存するためにはいくつかの方法があり、それぞれに利点と欠点があります。一部の主流な方法には、pickle、Joblib、JSON、TensorFlowの保存、およびPyTorchの保存があります。
特定のユースケースに適したファイル形式を選択し、バージョン管理、言語およびライブラリのバージョンの確保、保存したモデルのテストなど、モデルの保存とドキュメント化のためのベストプラクティスに従うことが重要です。本記事で議論されたプラクティスに従うことで、機械学習モデルを正しく保存し、簡単に再利用および展開でき、他の人と効果的に共有できることが保証されます。
参考文献
- https://machinelearningmastery.com/save-load-machine-learning-models-python-scikit-learn/
- https://www.tensorflow.org/tutorials/keras/save_and_load
- https://pytorch.org/tutorials/beginner/saving_loading_models.html
- https://www.kaggle.com/code/prmohanty/python-how-to-save-and-load-ml-models
We will continue to update VoAGI; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles