この記事は、IBM Cloudで機械学習/深層学習モデル(AIモデル)を開発・運用するためのPythonプログラムについて記載しています。
概要
IBM CloudでAIモデルを開発・運用するためのステップの一例として、以下が挙げられます。
- AIモデルの開発はIBM CloudのWatson Studioサービスで行い、AIモデルの管理はIBM CloudのWatson Machine Learningサービスで行うため、これらのサービスを作成します
- AIモデルを開発するためにプロジェクトを作成します
- 作成したプロジェクトで、Jupyterノートブック・エディターを使用してAIモデルの開発を行います
- AIモデルの学習に必要なデータはデータベースやオブジェクト・ストレージなどから取得します。それらのデータ・ソースへの接続情報は、プロジェクトに定義します
- 作成したAIモデルをプロジェクトに保存します
- AIモデルを管理するために、デプロイメント・スペースを作成します
- プロジェクトに保存されたAIモデルをデプロイメント・スペースに取り込みます(プロモート)
- デプロイメント・スペースにプロモートされたAIモデルを同じデプロイメント・スペース上にデプロイします。デプロイすると、そのAIモデルに対してREST APIを使って推論できるようになります
- REST APIで、デプロイされたAIモデルを使って推論します
この記事では、上記、4, 5, 7, 8, 9 について、Pythonでどのように実装するのかについて述べます。7と8はIBM CloudのWeb画面を使って実現可能ですが、Pythonのプログラムでできるようにしておくと自動化に利用できて便利です。
Pythonのライブラリは、ibm-watson-machine-learing を使用します。
AIモデルの例として、scikit-learnを使った機械学習モデル(住宅ローンの許可/却下の分類)、Kerasを使った深層学習モデル(画像の分類)、PyTorchを使った深層学習モデル(画像の分類)を取り上げます。
1. ベースとなるAPIClientオブジェクトの作成
Pythonのライブラリ ibm-watson-machine-learning
で各種処理を行うためには、ベースとなるAPIClientオブジェクトを作成する必要があります。
この作成時に認証も行いますが、IBM CloudのSaaS環境 (Cloud Pak for Data as a Service) か、オンプレ環境 (Cloud Pak for Data) かで、やり方が異なります。
1.1. SaaS環境 (Cloud Pak for Data as a Service)
オブジェクトを作成する際の認証情報として、APIキーとSaaS環境のURLが必要となります。APIキーは、IBM CloudのWeb画面を使用して作成することができます。
IBM Cloudにログインし、管理 > アクセス(IAM) を選択
画面左メニューの APIキー を選択し、画面右にある作成ボタンを選択してAPIキーを作成
SaaS環境のURLは、https://[ロケーション].ml.cloud.ibm.com で、ロケーション情報は、IBM Cloud の Jupyter ノートブック・エディターを使用する場合、RUNTIME_ENV_REGION
環境変数から得られます。
APIClientオブジェクトを作成するプログラムは以下になります。
import os
from ibm_watson_machine_learning import APIClient
location = os.environ['RUNTIME_ENV_REGION']
apikey = "[APIキー]"
wml_credentials = {
"apikey": apikey,
"url": 'https://' + location + '.ml.cloud.ibm.com'
}
wml_client = APIClient(wml_credentials)
1.2. オンプレ環境 (Cloud Pak for Data)
オンプレでAPIClientオブジェクトを作成するためには、url, username, apikey, instance_id, version が必要となります。
- URLは、https://[Cloud Pak for Data のホスト名]
- usernameは、Cloud Pak for Data のユーザー名
- apikeyは、上記ユーザーのAPIキー。上記ユーザーでCloud Pak for Data にログインしたWeb画面で、上部のメニュー右から2つ目のアイコンをクリックし、「プロファイルと設定」を選択。切り替わった画面右にある「API鍵」をクリックして「新規鍵の生成」を選択するとAPIキーを作成することができます
- instance_idは、openshift
- versionは、Cloud Pak for Dataのバージョン(例: "5.0")
APIClientオブジェクトを作成するプログラムは以下になります。
cp4d_url = "https://[Cloud Pak for Data のホスト名]"
cp4d_user = "[ユーザー名]"
cp4d_apikey = "[APIキー]"
cp4d_version = "Cloud Pak for Data のバージョン(例: 5.0)"
wml_credentials = {
"url": cp4d_url,
"username": cp4d_user,
"apikey": cp4d_apikey,
"instance_id": "openshift",
"version": cp4d_version
}
wml_client = APIClient(wml_credentials)
以降、生成したAPIClientオブジェクトの変数名をwml_client
として説明します。
2. 作業する対象環境(特定のプロジェクトまたはデプロイメント・スペース)を指定
プロジェクトにAIモデルを保存したり、プロジェクトのAIモデルをデプロイメント・スペースにプロモートする場合、プロジェクトIDを以下のようにセットします。
project_id = "[プロジェクトID]"
wml_client.set.default_project(project_id)
プロジェクトIDは、プロジェクトの「管理」タブの「一般」に表示されています。
デプロイメント・スペースにプロモートされたAIモデルをデプロイする場合、デプロイメント・スペースのID(スペースID)を以下のようにセットします。
space_id="[スペースID]"
wml_client.set.default_space(space_id)
スペースIDは、以下のプログラムで、デプロイメント・スペース名から特定することができます。
space_name = "[デプロイメント・スペース名]"
space_id = None
for space in wml_client.spaces.get_details()['resources']:
# print(space['metadata']['id'], space['entity']['name'], space['metadata']['created_at'])
if space['entity']['name'] == space_name:
space_id = space['metadata']['id']
break
if space_id:
print(f'Deployment space name: "{space_name}", Deployment space ID: "{space_id}"')
else:
emsg = f'Deployment space name "{space_name}" not found.'
raise Exception(emsg)
IBM CloudのWeb画面からも得ることができ、デプロイメント・スペースの「管理」タブの「一般」に表示されています(スペースGUID
)。
3. AIモデル開発に使用するデータ・アクセス
3.1. Db2データベースに保存されたデータ取得
プロジェクトに保存したDb2接続情報の取得とSELECT文の結果をPandasのデータフレームに保存するプログラム例を以下に述べます。
import ibm_db_dbi
import pandas as pd
wml_client.set.default_project(project_id)
db2_name = "Db2 Mortgage Approval Data" # Db2接続情報名
db2_info = None
for detail in wml_client.connections.get_details()["resources"]:
if detail["entity"]["name"] == db2_name:
db2_info = wml_client.connections.get_details(detail["metadata"]["id"])["entity"]["properties"]
print(f"db2_info={db2_info}")
con_url = f'DATABASE={db2_info["database"]};HOSTNAME={db2_info["host"]};PORT={db2_info["port"]};PROTOCOL=TCPIP;UID={db2_info["username"]};PWD={db2_info["password"]}'
if db2_info["ssl"] == "true":
con_url = con_url + ";Security=SSL"
print(f"con_url={con_url}")
con = ibm_db_dbi.connect(con_url,'','')
sql_query = "select * from AI_MORTGAGE.MORTGAGE_APPROVAL_VIEW"
df_mortgage = pd.read_sql_query(sql_query, con)
df_mortgage.head()
画面出力例
db2_info={'database': 'BLUDB', 'auth_method': 'username_password', 'password': 'xxx', 'port': '50001', 'host': 'xxx.us-south.db2w.cloud.ibm.com', 'ssl': 'true', 'username': 'xxx'}
ID NAME STREET_ADDRESS CITY STATE STATE_CODE ZIP_CODE EMAIL_ADDRESS PHONE_NUMBER GENDER ... NUMBER_OF_CARDS CREDITCARD_DEBT LOANS LOAN_AMOUNT CREDIT_SCORE COMMERCIAL_CLIENT COMM_FRAUD_INV PROPERTY_VALUE AREA_AVG_PRICE MORTGAGE_APPROVAL
0 110424 Adah Marks 4355-5 Pelham South Park Ridge Illinois IL 41227 Adah.Marks@donny.ca 206-220-3128 Male ... 2 1168.0 1 7478.0 547 FALSE FALSE 548618.0 NaN 0
1 110425 Jerrell Eichmann 5642-1 Hwy 78 East Reston Virginia VA 41198 Jerrell.Eichmann@trycia.biz 972-510-7295 Male ... 2 1167.0 1 7476.0 547 TRUE FALSE 548638.0 NaN 0
2 110426 Glennie Barrows 6736-1 Whitfield Ave Houston Texas TX 41169 Glennie.Barrows@elwin.us 609-564-9894 Female ... 2 1166.0 1 7474.0 547 FALSE FALSE 548658.0 NaN 0
3 110427 Susanna Schaefer 4529-0 Madison Blvd Woodridge Illinois IL 41140 Susanna.Schaefer@elta.ca 484-261-6798 Female ... 2 1165.0 1 7471.0 547 FALSE FALSE 548678.0 NaN 0
4 110428 Jettie Waters 3698-Kelley Blvd Truckee California CA 41110 Jettie.Waters@kacie.co.uk 253-973-4793 Male ... 2 1164.0 1 7469.0 546 TRUE FALSE 548698.0 721244.0 0
5 rows × 29 columns
3.2. IBM Cloud Object Storage (ICOS) に保存されたデータ取得
認証方法を「リソース・インスタンスIDとAPIキー」として登録した場合のプログラム例を以下に示します。
import ibm_boto3
from ibm_botocore.client import Config
wml_client.set.default_project(project_id)
icos_name = "icos1" # ICOS接続情報名
bucket_name = "cloud-object-storage-mortgage-2021-jp"
file_name = "mortgage_approval_view.csv"
icos_info = None
for detail in wml_client.connections.get_details()["resources"]:
if detail["entity"]["name"] == icos_name:
icos_info = wml_client.connections.get_details(detail["metadata"]["id"])["entity"]["properties"]
print(f"icos_info={icos_info}")
if not icos_info["url"].startswith("http"):
icos_info["url"] = "https://" + icos_info["url"]
cos = ibm_boto3.client(service_name="s3",
ibm_api_key_id=icos_info["api_key"],
ibm_service_instance_id=icos_info["resource_instance_id"],
ibm_auth_endpoint='https://iam.bluemix.net/oidc/token',
config=Config(signature_version='oauth'),
endpoint_url=icos_info["url"])
cos.download_file(Bucket=bucket_name, Key=file_name, Filename=file_name)
!ls -l $file_name
画面出力例
icos_info={'trust_all_ssl_cert': 'false', 'auth_method': 'instanceid_apikey', 'iam_url': 'https://iam.cloud.ibm.com/identity/token', 'api_key': 'xxx', 'resource_instance_id': 'crn:v1:bluemix:public:cloud-object-storage:global:xxx', 'url': 's3.us-south.cloud-object-storage.appdomain.cloud'}
-rw-rw---- 1 wsuser wscommon 1281702 Jan 25 05:42 mortgage_approval_view.csv
Jupyter ノートブックのファイルシステムにあるファイルをICOSにアップロードするには、upload_file
メソッドをコールします。引数は、上記の例で使用している download_file
メソッドと同じです。
4. AIモデルの保存
4.1. scikit-learnを使った機械学習モデルの保存
scikit-leanのpiplelineを使った機械学習モデルを例として述べます。
機械学習モデルを開発するプログラムの詳細は省略しますが、その中で、モデルの保存に必要な情報は以下になります。
target_col='MORTGAGE_APPROVAL' # 推論結果を表す列
X = df_mortgage.drop([target_col], axis=1)
model = Pipeline(steps=[('preprocessor', preprocessor),
('model', RandomForestClassifier(n_estimators=top_ne, max_depth=top_md, max_features=top_mf, random_state=0))])
AIモデルを新規保存またはバージョンアップするプログラムの例は以下になります。AIモデルの保存は wml_client.repository.store_model
メソッドを利用します。このメソッドでAIモデルを保存すると、同じ名前でもIDの異なる新規のAIモデルが作成されてしまいます。同じ名前の場合は、wml_client.repository.update_model
メソッドを使ってバージョンアップするのがお勧めです。
model_name = "Mortgage Approval Model"
# AIモデルが既に保存されているか確認
models = wml_client.repository.get_model_details()['resources']
model_ids = [m['metadata']['id'] for m in models if m['metadata']['name'] == model_name]
model_id = None
if len(model_ids) > 1:
emsg = 'Multiple models with the same model name "{}" exist: {}'.format(model_name, model_ids)
raise KeyError(emsg)
elif len(model_ids) == 1:
model_id = model_ids[0]
print(f"existing model_id: {model_id}")
# AIモデルが保存されていなかったら新規作成、保存されていたらバージョンアップ
if model_id == None:
# 実行環境情報のセット
software_spec_uid = wml_client.software_specifications.get_id_by_name("runtime-24.1-py3.11")
print(software_spec_uid)
# training_data_references情報のセット
db2_name = "Db2 Mortgage Approval Data" # Db2接続情報名
connection_id = None
for detail in wml_client.connections.get_details()["resources"]:
if detail["entity"]["name"] == db2_name:
connection_id = detail["metadata"]["id"]
sql_query = "select * from AI_MORTGAGE.MORTGAGE_APPROVAL_VIEW"
training_data_references = [{
"id": "Mortgage_data",
"type": "connection_asset",
"connection": {
"id": connection_id,
},
"location": {
"select_statement": sql_query,
"table_name": "Mortgage_Approval_view"
}
}]
# モデル・プロパティ値のセット
model_props = {
wml_client._models.ConfigurationMetaNames.NAME:model_name,
wml_client._models.ConfigurationMetaNames.TYPE: "scikit-learn_1.3",
wml_client._models.ConfigurationMetaNames.SOFTWARE_SPEC_UID: software_spec_uid,
wml_client._models.ConfigurationMetaNames.LABEL_FIELD:target_col,
wml_client._models.ConfigurationMetaNames.INPUT_DATA_SCHEMA:[{'id': '1', 'type': 'struct', 'fields': [{"name":column_name,"type":str(column_type[0])} for column_name,column_type in pd.DataFrame(X.dtypes).T.to_dict('list').items()]}],
wml_client.repository.ModelMetaNames.TRAINING_DATA_REFERENCES: training_data_references
}
# モデルをプロジェクトに保存
model_detail = wml_client.repository.store_model(model=model, meta_props=model_props,
training_data=X_train, training_target=y_train)
print(f'The model "{model_name}" successfully stored in the project.')
else:
model_props = {
wml_client._models.ConfigurationMetaNames.NAME:model_name
}
# モデルの更新(バージョン・アップ)
model_detail = wml_client.repository.update_model(
model_uid=model_id,
updated_meta_props=model_props,
update_model=model
)
print(f'The model "{model_name}" successfully updated in the project.')
model_id = wml_client.repository.get_model_id(model_detail)
new_model_revision = wml_client.repository.create_model_revision(model_id)
rev_id = new_model_revision["metadata"].get("rev")
print(f"Model ID: {model_id}")
print(f"Revison ID: {rev_id}")
4.2. Keras を使った深層学習モデルの保存
AIモデルのバージョンアップについては 4.1. scikit-learnを使った機械学習モデルの保存 と同じようにできるので、ここでは、新規保存についてのみ述べます。
以下のモデルを例に述べます。
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense, Activation
def cnn_model(x_train, class_labels_count):
model = Sequential()
model.add(Conv2D(32, (3, 3), padding="same", input_shape=x_train.shape[1:]))
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(class_labels_count))
model.add(Activation('softmax'))
model.compile(
loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy']
)
return model
モデルの保存は以下のようになります。
h5file = 'mnist-keras.h5'
gzfile = 'mnist-keras.tar.gz'
model.save(h5file)
import tarfile
with tarfile.open(gzfile, 'w:gz') as tf:
tf.add(h5file)
model_name = "mnist-keras"
software_spec_uid = wml_client.software_specifications.get_uid_by_name("runtime-24.1-py3.11")
model_props = {
wml_client._models.ConfigurationMetaNames.NAME:model_name,
wml_client._models.ConfigurationMetaNames.TYPE: "tensorflow_2.14",
wml_client._models.ConfigurationMetaNames.SOFTWARE_SPEC_UID: software_spec_uid,
}
model_detail = wml_client.repository.store_model(model=gzfile, meta_props=model_props)
model_id = wml_client.repository.get_model_id(model_detail)
new_model_revision = wml_client.repository.create_model_revision(model_id)
rev_id = new_model_revision["metadata"].get("rev")
print(f"Model ID: {model_id}")
print(f"Revison ID: {rev_id}")
4.3. PyTorch を使った深層学習モデルの保存
こちらも、AIモデルのバージョンアップについては 4.1. scikit-learnを使った機械学習モデルの保存 と同じようにできるので、ここでは、新規保存についてのみ述べます。
以下のモデルを例に述べます。
import torch
import torchvision
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import torchvision.transforms as transforms
class cifar10_cnn(nn.Module):
def __init__(self, num_classes):
super(cifar10_cnn,self).__init__()
self.conv1 = nn.Conv2d(3, 32, 3, padding=(1,1), padding_mode='replicate')
self.conv2 = nn.Conv2d(32, 32, 3)
self.conv3 = nn.Conv2d(32, 64, 3, padding=(1,1), padding_mode='replicate')
self.conv4 = nn.Conv2d(64, 64, 3)
self.relu = nn.ReLU(inplace=True)
self.dropout1 = nn.Dropout(0.25)
self.dropout2 = nn.Dropout(0.5)
self.maxpool = nn.MaxPool2d((2,2))
self.classifier1 = nn.Linear(2304, 512)
self.classifier2 = nn.Linear(512, num_classes)
self.features = nn.Sequential(
self.conv1,
self.relu,
self.conv2,
self.relu,
self.maxpool,
self.dropout1,
self.conv3,
self.relu,
self.conv4,
self.relu,
self.dropout1,
self.maxpool)
self.classifier = nn.Sequential(
self.classifier1,
self.relu,
self.dropout2,
self.classifier2)
def forward(self, x):
x = self.features(x)
x = x.view(x.size(0), -1)
x = self.classifier(x)
return x
モデルの保存は以下のようになります。
# ダミーデータの作成
dummy_input = torch.randn((1, 3, 32, 32)).to(device)
# onyx形式でexport
torch.onnx.export(net, dummy_input, "mnist-pytorch.onnx",
keep_initializers_as_inputs=True, verbose=True, opset_version=9)
# gz形式に圧縮
!tar czvf mnist-pytorch.gz mnist-pytorch.onnx
gzfile = "mnist-pytorch.gz"
model_name = "mnist-pytorch"
software_spec_uid = wml_client.software_specifications.get_uid_by_name("runtime-24.1-py3.11")
model_props = {
wml_client._models.ConfigurationMetaNames.NAME:model_name,
wml_client._models.ConfigurationMetaNames.TYPE: "pytorch-onnx_2.1",
wml_client._models.ConfigurationMetaNames.SOFTWARE_SPEC_UID: software_spec_uid,
}
model_detail = wml_client.repository.store_model(model=gzfile, meta_props=model_props)
model_id = wml_client.repository.get_model_id(model_detail)
new_model_revision = wml_client.repository.create_model_revision(model_id)
rev_id = new_model_revision["metadata"].get("rev")
print(f"Model ID: {model_id}")
print(f"Revison ID: {rev_id}")
torch.onnx.exportメソッドの引数 opset_version
を指定しないと、モデルのデプロイでエラーとなるようです。
5. AIモデルのプロモート
以下のように行います。
# wml_clientにプロジェクトIDのセット
project_id = "[プロジェクトID]"
wml_client.set.default_project(project_id)
# 以下に記載の [モデル名] を、以下に記載の [デプロイメント・スペース名] にプロモート
model_name = "[モデル名]"
space_name = "[デプロイメント・スペース名]"
# プロジェクトに保存されているモデルIDの取得
entities = wml_client.repository.get_details()['models']['resources']
model_id = None
for entity in entities:
name = entity['metadata']['name']
if name == model_name:
model_id = entity['metadata']['id']
break
if model_id:
print(f'Model name: "{model_name}", Model ID: "{model_id}"')
else:
emsg = f'Model name "{model_name}" not found.'
raise Exception(emsg)
# プロモート先となるデプロイメントスペースIDの取得
space_id = None
for space in wml_client.spaces.get_details()['resources']:
# print(space['metadata']['id'], space['entity']['name'], space['metadata']['created_at'])
if space['entity']['name'] == space_name:
space_id = space['metadata']['id']
break
if space_id:
print(f'Deployment space name: "{space_name}", Deployment space ID: "{space_id}"')
else:
emsg = f'Deployment space name "{space_name}" not found.'
raise Exception(emsg)
# モデルのプロモート
if model_id and space_id:
space_model_id = wml_client.spaces.promote(asset_id=model_id, source_project_id=project_id, target_space_id=space_id)
print(f'Model asset ID in deployment space "{space_name}": "{space_model_id}"')
6. モデルのデプロイ
以下のように行います。
# 以下に記載の [デプロイメント・スペース名] にプロモートされている [モデル名] をデプロイ
space_name = "[デプロイメント・スペース名]"
space_model_name = "[モデル名]"
# デプロイメントスペースIDの取得
space_id = None
for space in wml_client.spaces.get_details()['resources']:
# print(space['metadata']['id'], space['entity']['name'], space['metadata']['created_at'])
if space['entity']['name'] == space_name:
space_id = space['metadata']['id']
break
if space_id:
print(f'Deployment space name: "{space_name}", Deployment space ID: "{space_id}"')
else:
emsg = f'Deployment space name "{space_name}" not found.'
raise Exception(emsg)
# wml_clientにスペースIDのセット
wml_client.set.default_space(space_id)
# モデルIDの取得
entities = wml_client.repository.get_details()["models"]["resources"]
space_model_id = None
for entity in entities:
name = entity['metadata']['name']
if name == space_model_name:
space_model_id = entity['metadata']['id']
break
if space_model_id:
print(f'Space Model name: "{space_model_name}", Space Model ID: "{space_model_id}"')
else:
emsg = f'Space Model name "{space_model_name}" not found.'
raise Exception(emsg)
# モデルのデプロイ
meta_props={
wml_client.deployments.ConfigurationMetaNames.NAME: space_model_deployment_name,
wml_client.deployments.ConfigurationMetaNames.ONLINE: {}
}
if space_id and space_model_id:
deployment_id = wml_client.deployments.create(artifact_uid=space_model_id, meta_props=meta_props, target_space_id=space_id)
space_model_deployment_id = deployment_id['entity']['asset']['id']
print(f'Deployment name: "{space_model_deployment_name}", Deployment ID: "{space_model_deployment_id}"')
7. デプロイされたAIモデルの利用
SaaS環境 (Cloud Pak for Data as a Service) も、オンプレ環境 (Cloud Pak for Data) も、デプロイされたモデルをWeb画面で開くと、APIリファレンス
タブがあり、REST APIで推論要求するためのプログラムの断片(コード・スニペット)が記載されています。
SaaS環境の例
オンプレ環境の例
SaaS環境とオンプレ環境の違いは認証方法のみで、それ以外は呼び出し先のURLが異なるだけで、プログラムは同じです。
7.1. 認証方法
7.1.1. SaaS環境 (Cloud Pak for Data as a Service) の認証方法
コード・スニペットに記載の通り、以下のようにプログラムします。
API_KEY = "[APIキー]"
token_response = requests.post('https://iam.cloud.ibm.com/identity/token', data={"apikey":
API_KEY, "grant_type": 'urn:ibm:params:oauth:grant-type:apikey'})
mltoken = token_response.json()["access_token"]
header = {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + mltoken}
7.1.2. オンプレ環境 (Cloud Pak for Data)
認証情報として、ログインしているユーザー名とそのAPIキーを利用して以下を実行します。
$ echo "[ユーザー名]:[APIキー]" | base64
ユーザー名を cpadmin
、APIキーを ABCDE12345
とすると、以下のようになります。
$ echo "cpadmin:ABCDE12345" | base64
Y3BhZG1pbjpBQkNERTEyMzQ1Cg==
上記の値をmltokenにセットして、headerを以下のようにします。
mltoken = "Y3BhZG1pbjpBQkNERTEyMzQ1Cg=="
header = {'Content-Type': 'application/json', 'Authorization': 'ZenApiKey ' + mltoken}
7.2. モデルの推論
headerは、上記で述べたようにSaaS環境とオンプレ環境で異なります。ここでは、headerがセットされた前提で、それ以降のプログラムを、SaaSのURLを用いて説明します。
SaaSのURLは、プライベート・エンドポイントとパブリック・エンドポイントがあり、スニペットはプライベート・エンドポイントが記載されています。Watson Studio の Jupyter ノードブック等、IBM Cloud内からのコールの場合、プライベート・エンドポイントを利用します。IBM Cloud外からのアクセスの場合は、パブリック・エンドポイントに変更します。
以下の3つのモデル(scikit-learn機械学習モデル、Keras深層学習モデル、PyTorch深層学習モデル)の例では、IBM Cloud外からパブリック・エンドポイントに変更して実行しています。
7.2.1. scikit-learn機械学習モデル
プログラム
payload_scoring = {
"input_data": [
{
"fields": [
"INCOME",
"YRS_AT_CURRENT_ADDRESS",
"YRS_WITH_CURRENT_EMPLOYER",
"NUMBER_OF_CARDS",
"CREDITCARD_DEBT",
"LOAN_AMOUNT",
"CREDIT_SCORE",
"PROPERTY_VALUE",
"AREA_AVG_PRICE",
"LOANS",
"GENDER",
"EDUCATION",
"EMPLOYMENT_STATUS",
"MARITAL_STATUS",
"APPLIEDONLINE",
"RESIDENCE",
"COMMERCIAL_CLIENT",
"COMM_FRAUD_INV"
],
"values": [
[
53115,
12,
1,
2,
674,
10455,
539,
538588,
528267,
0,
"Female",
"High School or Below",
"Employed",
"Married",
"NO",
"Owner Occupier",
"TRUE",
"FALSE"
]
]
}
]
}
response_scoring = requests.post('https://us-south.ml.cloud.ibm.com/ml/v4/deployments/a40b45aa-c8b6-4f9d-b43b-8c4ef46c109d/predictions?version=2021-05-01', json=payload_scoring,
headers={'Authorization': 'Bearer ' + mltoken})
print("Scoring response")
print(response_scoring.json())
実行結果
Scoring response
{'predictions': [{'fields': ['prediction', 'probability'], 'values': [[0, [0.8599447513812154, 0.14005524861878452]]]}]}
7.2.2. Keras深層学習モデル
以下の画像を分類します。
img_car = np.load("img_car.npy")
print(f"ndim: {img_car.ndim}")
print(f"shape: {img_car.shape}")
ndim: 3
spape: (32, 32, 3)
import matplotlib.pyplot as plt
plt.imshow(img_car)
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F507588%2Ff1aafe80-751b-86b7-a19a-8a63b7c3685b.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=b54aa74037a88b419ddca7f1fa87020b)
Kerasの場合、payload_scoring
に fields
は不要で、以下のフォーマットになります。
{"input_data": [{"values": [イメージの配列]}]}
プログラム
payload_scoring = {"input_data": [{"values": [img_car.tolist()]}]}
response_scoring = requests.post('https://us-south.ml.cloud.ibm.com/ml/v4/deployments/912ac537-d1d9-4009-8dbb-0df9e0015d76/predictions?version=2021-05-01', json=payload_scoring,
headers={'Authorization': 'Bearer ' + mltoken})
print("Scoring response")
print(response_scoring.json())
実行結果
Scoring response
{'predictions': [{'fields': ['prediction'], 'id': 'activation_5', 'values': [[0.0017128867330029607, 0.7528261542320251, 9.030097135109827e-05, 0.00012985964713152498, 0.00011039885430363938, 0.0002107438340317458, 0.00011447971337474883, 0.0006360796396620572, 0.004830101504921913, 0.23933905363082886]]}]}
7.2.3. PyTorch深層学習モデル
こちらもKerasと同じ画像を使用します。
次元は、Kerasで使った画像の3次元目のchannelが最初になるので、以下のように変換しています。
np.transpose(img_car, (2,0,1))
PyTorchの場合、payload_scoring
に fields
が必要となり、以下の値となります。
import onnxruntime
sess = onnxruntime.InferenceSession('mnist-pytorch.onnx')
print(f"input_name: {sess.get_inputs()[0].name}")
input_name: input.1
payload_scoring
は、以下のフォーマットとなります。
{"input_data": [{"fields": "input.1", "values": [イメージの配列]}]}
プログラム
payload_scoring = {"input_data": [{"fields": "input.1", "values": [np.transpose(img_car, (2,0,1)).tolist()]}]}
response_scoring = requests.post('https://us-south.ml.cloud.ibm.com/ml/v4/deployments/bd2a7a2b-3440-434b-83c6-944cba26aba3/predictions?version=2021-05-01', json=payload_scoring,
headers={'Authorization': 'Bearer ' + mltoken})
print("Scoring response")
print(response_scoring.json())
実行結果
Scoring response
{'predictions': [{'values': [[90.16368865966797, 132.31080627441406, -152.7025146484375, -148.4767608642578, -170.6203155517578, -235.80233764648438, -228.36398315429688, -156.88336181640625, 35.36519241333008, 105.59580993652344]]}]}
参考文献
- scikit-learn機械学習モデルは以下のtutorialで作成しているモデルを利用しました
AI governance tutorial: Build and deploy a model