本記事の目的
本記事では、IBM Cloud上で提供される Cloud Pak for Data as a Service(以降、CP4DaaSと表記) を対象に、Watson Studio および Watson Machine learning サービスでトレーニングしたモデルをローカルにダウンロードして利用する例を紹介します。
1. モデルのトレーニングおよびプロジェクトへの保存
まず、Watson Studio および Watson Machine learning サービスでモデルをトレーニングし、プロジェクトへ保存します。
本記事ではモデルのトレーニングおよびプロジェクトへの保存手順については取り扱いません。製品資料や別Qiita記事をご参照ください。
- モデルのトレーニングおよびプロジェクトへの保存方法
2. プロジェクトへ保存されたモデルのダウンロード
モデルのフレームワークに応じ、ダウンロードされるモデルファイルの形式は異なります。
本節では、以下のQiita記事の手順にてトレーニングおよび保存したPytorchのモデルを例として利用します。
-
事前準備
- API keys のページでAPIキーを生成し、取得します。
- モデルが保存されているプロジェクトへアクセスし、 プロジェクトのID を取得します。
- Watson Machine Learning サービスインスタンスのロケーション名を確認します。
WMLサービス・インスタンスの作成リージョン ロケーション名 米国(ダラス) us-south 英国(ロンドン) eu-gb アジア太平洋(東京) jp-tok ヨーロッパ(フランクフルト) eu-de - インターネットに接続可能な任意のPython環境へNoteobookを作成します。
- 以降の手順は、Notebookにセルを追加して実行します。
-
手順
- Noteobookのセルへ変数として事前準備した値をセットします。
セル内の必須TBDPROJECT_ID = '控えておいたPROJECT_ID' IAM_APIKEY = '控えておいたAPIキー' WML_SERVICES_LOCATION = '控えておいたロケーション' # WMLインスタンスのロケーション. us-south, eu-gb, eu-de, jp-tok のいずれか WML_SERVICES_URL = 'https://' + WML_SERVICES_LOCATION + '.ml.cloud.ibm.com'
- WMLクライアントのパッケージをインストールします。
pip install 'ibm_watson_machine_learning'
- WMLクライアントをセットアップします。
# WMLクライアントのセットアップ from ibm_watson_machine_learning import APIClient wml_credentials = { "url": WML_SERVICES_URL, "apikey": IAM_APIKEY } wml_client = APIClient(wml_credentials) wml_client.set.default_project(PROJECT_ID) # モデルが保存されているプロジェクト
- プロジェクトへ保存されているモデルを確認し、ダウンロードしたいモデルのIDを控えます。
プロジェクトへ保存されたモデルの一覧# モデル一覧 wml_client.repository.list_models()
- 本例では、NAMEが
pytorch_bba9a5de-0f8d-4364-88fe-f62b54cea62f
のPytorchのモデルをダウンロードできるように、IDb3cfb015-5c34-4320-aa0c-4280092bbfa1
を控えます。
実行例:プロジェクトへ保存されたモデルの一覧------------------------------------ --------------------------------------------------------------- ------------------------ ----------------- ---------- ---------------- ID NAME CREATED TYPE SPEC_STATE SPEC_REPLACEMENT 4813469b-7f00-46fe-b9d6-5307e8b67e0d pt_mnist_init_model 2023-06-16T11:13:04.002Z pytorch-onnx_1.12 supported b3cfb015-5c34-4320-aa0c-4280092bbfa1 pytorch_bba9a5de-0f8d-4364-88fe-f62b54cea62f 2023-06-08T11:49:22.002Z pytorch-onnx_1.12 supported
- 控えておいたダウンロードしたいモデルのIDを変数にセットします。
モデルのIDmodel_id = '控えておいたダウンロードしたいモデルのID' # model_id = 'b3cfb015-5c34-4320-aa0c-4280092bbfa1' 一つ前の手順で控えた値を設定した例
- プロジェクトからローカルへモデルファイルをダウンロードし、解凍します。
- ダウンロードされるモデルは圧縮されているので、解凍することが必要です。
モデルファイルのダウンロード・解凍# モデルファイルをダウンロード wml_client.repository.download(model_id, "model.tar.gz") # ダウンロードしたモデルファイルを解凍 import subprocess command = ["unzip", "-o", "model.tar.gz"] subprocess.call(command)
- 解凍されたモデルファイルを確認します。
- 本例ではPytorchのモデルをダウンロードしたため、
PyTorch_1686224194.6340466.onnx
となっています。ファイル形式はONNX形式が使用されています。 - モデルのフレームワークに応じ、ダウンロードしたモデルのファイル形式は異なります。
- 本例ではPytorchのモデルをダウンロードしたため、
!ls -l
確認例total 1752 -rw-r--r-- 1 wsluser1 wsluser1 930016 Jul 23 11:36 PyTorch_1686224194.6340466.onnx -rw-r--r-- 1 wsluser1 wsluser1 857735 Jul 23 17:03 model.tar.gz
3. ダウンロードしたモデルファイルによる予測の実行例(ONNX形式のPytorchモデルを使用)
モデルのフレームワークやデータセットの構造に応じ、モデルのスコアリング方法は異なります。
本節では、以下のQiita記事の手順にてトレーニングおよび保存したPytorchのモデルを例として利用します。
Qiita記事:IBM Cloud の Watson Studio と Watson Machine learningサービスで、Federated Learningを動かす(API編, 準同型暗号オプション有効化)このモデルではMNISTデータセットを利用しています。
-
手順
- onnxのパッケージをインストール
- 前節で例としてダウンロードしたPytorchモデルのファイルはONNX形式でした。ONNX形式のファイルを利用するために本パッケージをインストールします。
pip install onnx onnxruntime
- モデルファイルのパス指定
- 前節で解凍したモデルファイルのパスを指定します。
model_path = "<解凍したモデルファイルのパス>" # model_path = "./PyTorch_1686224194.6340466.onnx" 前節で解凍したモデルのパスを指定した例
- onnxパッケージを利用したモデルファイルの読込
import onnx model = onnx.load(model_path) onnx.checker.check_model(model)
- モデルの構造確認
# モデルの構造が表示可能 print(onnx.helper.printable_graph(model.graph))
モデルの構造の確認例graph torch_jit ( %onnx::Flatten_0[FLOAT, 1x1x28x28] ) optional inputs with matching initializers ( %1.weight[FLOAT, 256x784] %1.bias[FLOAT, 256] %3.weight[FLOAT, 100x256] %3.bias[FLOAT, 100] %5.weight[FLOAT, 50x100] %5.bias[FLOAT, 50] %7.weight[FLOAT, 10x50] %7.bias[FLOAT, 10] ) { %onnx::Gemm_9 = Flatten[axis = 1](%onnx::Flatten_0) %input = Gemm[alpha = 1, beta = 1, transB = 1](%onnx::Gemm_9, %1.weight, %1.bias) %onnx::Gemm_11 = Relu(%input) %input.3 = Gemm[alpha = 1, beta = 1, transB = 1](%onnx::Gemm_11, %3.weight, %3.bias) %onnx::Gemm_13 = Relu(%input.3) %input.7 = Gemm[alpha = 1, beta = 1, transB = 1](%onnx::Gemm_13, %5.weight, %5.bias) %onnx::Gemm_15 = Relu(%input.7) %input.11 = Gemm[alpha = 1, beta = 1, transB = 1](%onnx::Gemm_15, %7.weight, %7.bias) %17 = LogSoftmax[axis = 1](%input.11) return %17 }
- スコアリング用のデータセット読込
- MNISTデータセットをダウンロード後、読込して前処理を実行
import os import requests import numpy as np import shutil # ファイルのダウンロード DATASET_URL = 'https://api.dataplatform.cloud.ibm.com/v2/gallery-assets/entries/85ae67d0cf85df6cf114d0664194dc3b/data' DATASET_FILE_NAME = 'mnist.npz' local_file = os.path.join("./", DATASET_FILE_NAME) with requests.get(DATASET_URL, stream=True) as r: with open(local_file, 'wb') as f: shutil.copyfileobj(r.raw, f) # ローカルファイルの読込 with np.load(local_file, allow_pickle=True) as mnist: x_train, y_train = mnist['x_train'], mnist['y_train'] x_test, y_test = mnist['x_test'], mnist['y_test'] # 画像データ前処理用の関数 def preprocess(x, y): """ Preprocesses the training and testing dataset, \ e.g., reshape the images according to self.channels_first; \ convert the labels to binary class matrices. :return: None """ img_rows, img_cols = 28, 28 x = x.astype('float32').reshape(x.shape[0], 1, img_rows, img_cols) y = y.astype('int64') return (x, y) # スコアリングの動作確認用に、テストデータセットの先頭10枚の画像のみを取り出して前処理を実行 x_input, y_true = preprocess(x_test[:10], y_test[:10])
- スコアリングの実行
import onnxruntime # スコアリング用にモデル読込 sess = onnxruntime.InferenceSession(model_path, providers=['CUDAExecutionProvider', 'CPUExecutionProvider']) # モデルの入出力定義の確認 input_name = sess.get_inputs()[0].name print("Input name :", input_name) input_shape= sess.get_inputs()[0].shape print("Input shape :", input_shape) # 今回のモデルは一枚の画像を入力にとるため、複数の画像を同時に入力することはできない。for文で1枚ずつのスコアリングを繰り返し実行する。 output_name = sess.get_outputs()[0].name print("Output name :", output_name) output_shape = sess.get_outputs()[0].shape print("Output shape :", output_shape) output_type = sess.get_outputs()[0].type print("Output type :", output_type) y_pred=[] # 予測結果の格納 for i in range(0, x_input.shape[0]): #print(i) x = np.expand_dims(x_input[i], 0) # [1, 1, 28, 28] になるよう次数を増やす inputs = {input_name: x} outputs = sess.run(None, inputs) y_pred.append(np.argmax(outputs[0], axis=1)[0])
- Accuracyの計算
- (補足)例として使用したモデルは、正解率が0.2と低い精度でした。動作確認用のチュートリアルで作成したモデルのため、トレーニングのitteration数が小さく設定されており、学習が十分に行われていなかったことが原因と考えられます。
from sklearn.metrics import accuracy_score # 精度計算用の入力データ print(f"y_true: {y_true}") #正解ラベル print(f"y_pred: {np.array(y_pred)}") #予測結果のラベル # 精度計算 accuracy=accuracy_score(y_true, y_pred) print(f"accuracy: {accuracy}")
精度計算の結果例y_true: [7 2 1 0 4 1 4 9 5 9] y_pred: [1 1 1 9 1 1 1 1 1 1] accuracy: 0.2
- onnxのパッケージをインストール
4. 参考資料
プロジェクトに保存したモデルのダウンロード方法は以下を参照しました。
IBM Watson Machine Learning documentation > Core > Repositry
https://ibm.github.io/watson-machine-learning-sdk/core_api.html#repository
ONNXの利用方法について以下の記事を参考にさせていただきました。ありがとうございました。
ONNXの使い方メモ
https://qiita.com/studio_haneya/items/be9bc7c56af44b7c1e0a