このチュートリアルを Colab のノートブックとして実行 | GitHub のノートブックを表示 |
概要
このチュートリアルでは、トレーニング済みの scikit-learn モデルを AI Platform Prediction にデプロイし、カスタム予測ルーティンを使用して予測を提供します。これにより、予測リクエストに対する AI Platform Prediction のレスポンスをカスタマイズできます。
この例では、カスタム予測ルーチンを使用して、前処理として予測入力をスケーリングし、後処理として予測出力のクラス番号をラベル文字列に変換します。
このチュートリアルでは次の操作を行います。
- ローカル(このノートブック)で簡単な scikit-learn モデルをトレーニングする
- カスタム予測ルーチンを作成して AI Platform Prediction にデプロイする
- そのデプロイメントからの予測リクエストを処理する
データセット
このチュートリアルでは R.A. Fisher の Iris データセットを使用します。これは、機械学習技術を試す際によく利用される小さなデータセットです。各インスタンスには 4 つの数値特徴があり、花のさまざまな測定値を表します。ターゲット ラベルは Iris(アヤメ)の種類で、Iris setosa、Iris versicolour、Iris virginica のいずれかになります。
このチュートリアルでは、scikit-learn ライブラリに含まれている Iris データセットのコピーを使用します。
目的
ここでは、花の測定値を入力として、それがどのアヤメの種類かを予測するモデルをトレーニングすることを目的とします。
このチュートリアルでは、モデル自体の設計よりも、AI Platform Prediction でこのモデルを使用することに重点を置きます。
費用
このチュートリアルでは、Google Cloud の課金対象となるコンポーネントを使用します。
- AI Platform Prediction
- Cloud Storage
詳しくは、AI Platform Training の料金と Cloud Storage の料金をご覧ください。また、料金計算ツールを使用すると、予想される使用量に基づいて費用の見積もりを作成できます。
始める前に
AI Platform Prediction でモデルをトレーニングしてデプロイする前に、次の準備作業が必要です。
- ローカル開発環境を設定します。
- 課金と必要な API が有効になっている Google Cloud プロジェクトを設定します。
- トレーニング パッケージとトレーニングしたモデルを保存する Cloud Storage バケットを作成します。
ローカル開発環境の設定
このチュートリアルを完了するには、以下のリソースが必要です。
- Python 3
- virtualenv
- Google Cloud SDK
Python 開発環境を設定するための Google Cloud ガイドでは、上記の要件を満たすための詳しい手順を説明しています。要約した手順を次に示します。
virtualenv をインストールして、Python 3 を使用する仮想環境を作成します。
その環境をアクティブにします。
次のセクションにある手順に沿って、Google Cloud SDK をインストールします。
Google Cloud プロジェクトの設定
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the AI Platform Training & Prediction and Compute Engine APIs.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the AI Platform Training & Prediction and Compute Engine APIs.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
GCP アカウントの認証
認証を設定するには、サービス アカウント キーを作成し、そのサービス アカウント キーへのファイルパスの環境変数を設定する必要があります。
-
サービス アカウントを作成します。
-
Google Cloud コンソールで [サービス アカウントの作成] ページに移動します。
- [サービス アカウント名] フィールドに名前を入力します。
- 省略可: [サービス アカウントの説明] フィールドに説明を入力します。
- [作成] をクリックします。
- [ロールを選択] フィールドをクリックします。[すべてのロール] で、[AI Platform] > [AI Platform 管理者] の順に選択します。
- [別の役割を追加] をクリックします。
-
[ロールを選択] フィールドをクリックします。[すべてのロール] で、[Cloud Storage] > [ストレージ オブジェクト管理者] を選択します。
-
[完了] をクリックして、サービス アカウントを作成します。
ブラウザ ウィンドウは閉じないでください。次のステップでこれを使用します。
-
-
認証に使用するサービス アカウント キーを作成します。
- Google Cloud コンソールで、作成したサービス アカウントのメールアドレスをクリックします。
- [キー] をクリックします。
- [鍵を追加]、[新しい鍵を作成] の順にクリックします。
- [作成] をクリックします。JSON キーファイルがパソコンにダウンロードされます。
- [閉じる] をクリックします。
-
環境変数 GOOGLE_APPLICATION_CREDENTIALS をサービス アカウント キーが格納された JSON ファイルのファイルパスに設定します。この変数は現在の shell セッションにのみ適用されるため、新しいセッションを開く場合は、変数を再度設定します。
Cloud Storage バケットを作成
カスタム予測ルーチンをデプロイするには、トレーニング済みモデルのアーティファクトとカスタムコードを Cloud Storage にアップロードする必要があります。
Cloud Storage バケットの名前を環境変数として設定します。この名前は、すべての Cloud Storage バケットにわたって一意なものにする必要があります。
BUCKET_NAME="your-bucket-name"
AI Platform Prediction を利用できるリージョンを選択して、別の環境変数を作成します。
REGION="us-central1"
このリージョンに Cloud Storage バケットを作成し、後のトレーニングと予測で同じリージョンを使用します。そのバケットが存在しない場合は、次のコマンドを実行して作成します。
gcloud storage buckets create gs://$BUCKET_NAME --location=$REGION
scikit-learn モデルの構築とトレーニング
多くの場合、機械学習モデルをトレーニングするときに、データをそのままの形式で使用することはできません。そのまま使用できる場合でも、トレーニングの前にデータの前処理を行うと、モデルが改善されることがあります。
予測入力がトレーニング データと同じ形式になると予想される場合、モデルが一貫した予測を行うように、トレーニングと予測で同じ前処理を行う必要があります。
このセクションでは、前処理モジュールを作成し、そのモジュールをトレーニングで使用します。さらに、トレーニング中に学習した特徴を持つプリプロセッサをエクスポートし、後でカスタム予測ルーチンで使用します。
ローカル トレーニング用の依存関係をインストールする
ローカル トレーニングでは、いくつかの依存関係が必要です。
pip install numpy>=1.16.0 scikit-learn==0.20.2
プリプロセッサを作成する
各数値特徴列の平均値が 0、標準偏差が 1 になるようにトレーニング データをスケーリングすると、モデルを改善できます。
このスケーリングを行うクラスを含む preprocess.py
を作成します。
import numpy as np
class MySimpleScaler(object):
def __init__(self):
self._means = None
self._stds = None
def preprocess(self, data):
if self._means is None: # during training only
self._means = np.mean(data, axis=0)
if self._stds is None: # during training only
self._stds = np.std(data, axis=0)
if not self._stds.all():
raise ValueError('At least one column has standard deviation of 0.')
return (data - self._means) / self._stds
MySimpleScaler
のインスタンスは、最初の使用時に各特徴列の平均と標準偏差を保存します。その後、これらの要約統計を使用して、発生したデータをスケーリングします。
これにより、トレーニング分布の特徴を保存し、予測時に同じ前処理を行うことができます。
モデルのトレーニング
次に、preprocess.MySimpleScaler
を使用して Iris データを前処理し、scikit-learn でモデルをトレーニングします。
最後に、トレーニング済みのモデルを joblib(.joblib
)ファイルとしてエクスポートし、MySimpleScaler
インスタンスを pickle(.pkl
)ファイルとしてエクスポートします。
import pickle
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.externals import joblib
from preprocess import MySimpleScaler
iris = load_iris()
scaler = MySimpleScaler()
X = scaler.preprocess(iris.data)
y = iris.target
model = RandomForestClassifier()
model.fit(X, y)
joblib.dump(model, 'model.joblib')
with open ('preprocessor.pkl', 'wb') as f:
pickle.dump(scaler, f)
カスタム予測ルーチンのデプロイ
カスタム予測ルーチンをデプロイして、トレーニング済みモデルから予測を提供するには、次の作業を行います。
- リクエストを処理するカスタム予測器を作成する
- 予測器と前処理モジュールをパッケージ化する
- モデル アーティファクトとカスタムコードを Cloud Storage にアップロードする
- カスタム予測ルーチンを AI Platform Prediction にデプロイする
カスタム予測器を作成する
カスタム予測ルーチンをデプロイするには、予測器インターフェースを実装するクラスを作成する必要があります。これにより、AI Platform Prediction にモデルの読み込み方法と予測リクエストの処理方法を指示します。
次のコードを predictor.py
に記述します。
import os
import pickle
import numpy as np
from sklearn.datasets import load_iris
from sklearn.externals import joblib
class MyPredictor(object):
def __init__(self, model, preprocessor):
self._model = model
self._preprocessor = preprocessor
self._class_names = load_iris().target_names
def predict(self, instances, **kwargs):
inputs = np.asarray(instances)
preprocessed_inputs = self._preprocessor.preprocess(inputs)
if kwargs.get('probabilities'):
probabilities = self._model.predict_proba(preprocessed_inputs)
return probabilities.tolist()
else:
outputs = self._model.predict(preprocessed_inputs)
return [self._class_names[class_num] for class_num in outputs]
@classmethod
def from_path(cls, model_dir):
model_path = os.path.join(model_dir, 'model.joblib')
model = joblib.load(model_path)
preprocessor_path = os.path.join(model_dir, 'preprocessor.pkl')
with open(preprocessor_path, 'rb') as f:
preprocessor = pickle.load(f)
return cls(model, preprocessor)
この予測器は、トレーニング中に定義したプリプロセッサを使用するだけでなく、予測出力をクラス インデックス(0
、1
または 2
)からラベル文字列(花の種類の名前)に変換する後処理も行います。
ただし、予測器が値 True
を含む probabilities
キーワード引数を受け取った場合、代わりに確率配列を返し、3 つのクラスが正しいラベルに変換される確率を示します(確率はモデルによって異なります)。このチュートリアルの最後の部分で、予測中にキーワード引数を指定する方法を説明します。
カスタムコードのパッケージ化
カスタムコードを使用して予測を提供できるように、predictor.py
と preprocess.py
を .tar.gz
ソース配布パッケージとしてパッケージ化して AI Platform Prediction に提供する必要があります。
以下の setup.py
を記述してパッケージを定義します。
from setuptools import setup
setup(
name='my_custom_code',
version='0.1',
scripts=['predictor.py', 'preprocess.py'])
次のコマンドを実行して dist/my_custom_code-0.1.tar.gz
を作成します。
python setup.py sdist --formats=gztar
モデル アーティファクトとカスタムコードを Cloud Storage にアップロードする
提供するモデルをデプロイする前に、Cloud Storage 内の次のファイルを AI Platform Prediction からアクセスできるようにする必要があります。
model.joblib
(モデル アーティファクト)preprocessor.pkl
(モデル アーティファクト)my_custom_code-0.1.tar.gz
(カスタムコード)
モデル アーティファクトは、モデル ディレクトリにまとめて保存する必要があります。予測器は、from_path
クラスメソッドの model_dir
引数を使用してこのディレクトリにアクセスできます。カスタムコードは同じディレクトリに保存する必要はありません。次のコマンドを実行して、ファイルをアップロードします。
gcloud storage cp ./dist/my_custom_code-0.1.tar.gz gs://$BUCKET_NAME/custom_prediction_routine_tutorial/my_custom_code-0.1.tar.gz
gcloud storage cp model.joblib preprocessor.pkl gs://$BUCKET_NAME/custom_prediction_routine_tutorial/model/
カスタム予測ルーチンをデプロイする
モデルリソースとバージョン リソースを作成して、カスタム予測ルーチンをデプロイします。最初に自分のリソース名で環境変数を定義します。
MODEL_NAME='IrisPredictor'
VERSION_NAME='v1'
次にモデルを作成します。
gcloud ai-platform models create $MODEL_NAME \
--regions $REGION
バージョンを作成します。Cloud Storage にアップロードしたアーティファクトとカスタムコードへのパスを指定します。
gcloud components install beta
gcloud beta ai-platform versions create $VERSION_NAME \
--model $MODEL_NAME \
--runtime-version 1.13 \
--python-version 3.5 \
--origin gs://$BUCKET_NAME/custom_prediction_routine_tutorial/model/ \
--package-uris gs://$BUCKET_NAME/custom_prediction_routine_tutorial/my_custom_code-0.1.tar.gz \
--prediction-class predictor.MyPredictor
カスタム予測ルーチンのデプロイで使用できるオプションについては、指定する必要があるオプションをご覧ください。
オンライン予測を提供する
オンライン予測リクエストを送信してデプロイメントを試してみましょう。まず、Python 用の Google API クライアント ライブラリをインストールします。
pip install --upgrade google-api-python-client
次に、デプロイしたバージョンに Iris データの 2 つのインスタンスを送信します。
import googleapiclient.discovery
instances = [
[6.7, 3.1, 4.7, 1.5],
[4.6, 3.1, 1.5, 0.2],
]
service = googleapiclient.discovery.build('ml', 'v1')
name = 'projects/{}/models/{}/versions/{}'.format(PROJECT_ID, MODEL_NAME, VERSION_NAME)
response = service.projects().predict(
name=name,
body={'instances': instances}
).execute()
if 'error' in response:
raise RuntimeError(response['error'])
else:
print(response['predictions'])
['versicolor', 'setosa']
キーワード引数の送信
カスタム予測ルーチンに予測リクエストを送信するときに、リクエスト本文に追加のフィールドを指定できます。予測器の predict
メソッドが、これらを **kwargs
ディクショナリのフィールドとして受け取ります。
次のコードは、以前と同じリクエストを送信しますが、今回はリクエスト本文に probabilities
フィールドが追加されています。
response = service.projects().predict(
name=name,
body={'instances': instances, 'probabilities': True}
).execute()
if 'error' in response:
raise RuntimeError(response['error'])
else:
print(response['predictions'])
[[0.0, 1.0, 0.0], [1.0, 0.0, 0.0]]
クリーンアップ
このプロジェクトで使用しているすべての GCP リソースをクリーンアップするには、チュートリアルで使用した GCP プロジェクトを削除します。
また、以下のコマンドを実行して、個々のリソースを別々にクリーンアップすることもできます。
# Delete version resource
gcloud ai-platform versions delete $VERSION_NAME --quiet --model $MODEL_NAME
# Delete model resource
gcloud ai-platform models delete $MODEL_NAME --quiet
# Delete Cloud Storage objects that were created
gcloud storage rm gs://$BUCKET_NAME/custom_prediction_routine_tutorial --recursive
次のステップ
- カスタム予測ルーチンについて学習する。
- モデルをエクスポートしてカスタム予測ルーチンなしで予測を提供する方法を学習する。