ML モデルのモニタリング: AI Platform Prediction を使用したサービング リクエストのロギング

このドキュメントは、データ スキューとデータ ドリフトを検知するために、AI Platform Prediction にデプロイされた機械学習(ML)モデルをモニタリングする方法について説明するシリーズの最初のパートです。このガイドでは、以下の方法について説明します。

  • AI Platform Prediction を使用して TensorFlow 2.3 で Keras モデルを提供する方法。
  • オンライン リクエスト(インスタンス)とレスポンス(予測)のログを BigQuery に記録するように Keras モデルを構成する方法。

このシリーズは、サービング データが時間の経過とともにどのように変化するかをモニタリングすることにより、本番環境で ML モデルのパフォーマンスを維持したいデータ サイエンティストと MLOps エンジニアを対象としています。また、Google Cloud、TensorFlow、Jupyter ノートブックの使用経験があることを前提としています。

このシリーズは、次のガイドで構成されています。

ML モデルのモニタリングの概要

ビジネス ユースケースに対応するために、ML モデルを本番環境にデプロイする際、モデルのパフォーマンスが低下しないことを定期的かつ積極的に確認することが重要です。正確なパフォーマンスを確保するため、MLOps の最も重要な要素のひとつとして、モデルの品質と本番環境でのパフォーマンスをモニタリングするタスクが登場しました。

モデルは静的環境で稼働しているわけではないため、ML モデルのパフォーマンスは時間の経過とともに低下することがあります。時間の経過とともに入力データのプロパティが変化すると、データは、モデルのトレーニングと評価に使用されるデータからずれ始めます。

たとえば、アップストリームのデータ処理パイプラインに変更を加えると、モデルが想定する特徴量表現と特徴量ドメインが変化する可能性があります。入力が以下のうち 1 つ以上を含む場合があります。

  • 測定単位の m から km への変更。
  • カテゴリ特徴量への新しい語彙の導入。
  • 一部の特徴量のデータタイプの変更。

このようなトレーニング データとサービング データのスキューは、モデルの予測パフォーマンスの低下につながる可能性があります。

本番環境でモデルのパフォーマンスを維持するには、サービング データをキャプチャし、モデルが提供する予測でモデルがどう反応するかを判断する必要があります。データをキャプチャすると、次のことを行うのに役立ちます。

  • 時間の経過とともにデータがどのように変化したかを分析する。
  • データ内に取り込まれたすべてのスキューを検知する。
  • 新しく発生したパターンをキャプチャするために、新しいデータでモデルを更新または再トレーニングする必要がることを通知する。

ML モニタリング用の AI Platform Prediction

AI Platform Prediction は、オンライン予測を提供する ML モデルをデプロイするためのスケーラブルなフルマネージド サービスです。このシリーズ中のこのドキュメントでは、AI Platform Prediction を使用してリクエスト / レスポンス ロギング(ベータ版)を有効にする方法を説明します。このプロセスでは、BigQuery テーブルに対するオンライン予測のリクエストとレスポンスのサンプルが、未加工の(JSON)形式で記録されます。

次の図は、作成するアーキテクチャを示したものです。

このチュートリアル シリーズで作成されるフローのアーキテクチャ。

このアーキテクチャでは、未加工のインスタンスと予測データは BigQuery に保存されます。その後、このデータを解析し、記述統計を計算して、データスキューとデータのブレを可視化できます。これらのタスクの詳細については、このシリーズの次のパートで詳しく説明します。

このシリーズのデータセット

このシリーズで説明するシナリオでは、UCI Machine Learning Repository の Covertype データセットを使用します。このデータセットには、コロラド州のいくつかの自然保護区域における森林被覆の種類に関する情報が含まれています。これは分類データセットであり、地図に関する変数のみから森林被覆の種類を予測することがタスクです。このデータセットには、次の特徴があります。

  • データセットには 581,012 のインスタンスがあり、トレーニングの分割には 431,010 インスタンスが含まれます。
  • このデータセットには 12 個の入力特徴量があります。10 個は数値で、2 個はカテゴリです。
  • ターゲット クラスには 7 つのラベルがあります。範囲は 0~6 です。

このデータセットは前処理されて、分割され、Cloud Storage 一般公開バケット(gs://workshop-datasets/covertype)にアップロードされています。このシリーズでは、タスク用に、この前処理済みデータセットを使用します。このデータセットの詳細については、GitHub の Covertype Data Set の README ファイルをご覧ください。

目標

  • Notebooks を開き、Jupyter ノートブックを含む GitHub リポジトリのクローンを作成する。
  • ノートブックを実行して次のタスクを実行する。
    • モデルをトレーニングする。
    • モデルをエクスポートする。
    • モデルをデプロイする。
    • BigQuery へのロギングを有効にする。
    • モデルをテストする。

料金

このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

始める前に

  1. Google Cloud アカウントにログインします。Google Cloud を初めて使用する場合は、アカウントを作成して、実際のシナリオでの Google プロダクトのパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
  2. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  3. Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する

  4. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  5. Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する

このシナリオ用の Jupyter ノートブック

このシリーズの ML モニタリングのタスクは、GitHub リポジトリにある Jupyter ノートブックに組み込まれています。タスクを実施するには、ノートブックを開き、ノートブック内のコードセルを順番に実行します。

この最初のガイドでは、Jupyter ノートブックを使用して次のタスクを行います。

  • Keras 分類モデルをトレーニングして評価します。
  • Keras モデルを SavedModel としてエクスポートし、Cloud Storage にアップロードします。
  • エクスポートしたモデルを AI Platform Prediction にデプロイします。
  • AI Platform Prediction でモデル バージョンに対するリクエスト / レスポンス ロギングを有効にします。
  • オンライン予測のためにモデル API をテストします。
  • ログに記録されたインスタンスと予測を検証します。

JupyterLab とノートブックを開く

このシナリオのタスクに取り組むには、JupyterLab 環境を開いてノートブックを開く必要があります。

  1. Cloud Console で、[Notebooks] ページに移動します。

    [Notebooks] ページに移動

  2. AI Platform Notebook のリストでノートブックを選択し、[Open Jupyterlab] をクリックします。ブラウザで JupyterLab 環境が開きます。

  3. ターミナル タブを起動するには、[ランチャー] タブの [ターミナル] アイコンをクリックします。

  4. ターミナルで、mlops-on-gcp GitHub リポジトリのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/mlops-on-gcp.git
    

    コマンドが終了すると、ファイル ブラウザに mlops-on-gcp フォルダが表示されます。

ノートブック設定の構成

このセクションでは、コンテキストに固有の値でノートブックに変数を設定し、このシナリオ用のコードを実行する Python 環境を準備します。

  1. ファイル ブラウザで mlops-on-gcp ファイルを開き、skew-detection ディレクトリに移動します。
  2. 01-covertype-training-serving.ipynb ノートブックを開きます。
  3. ノートブックの [設定] で、[パッケージと依存関係のインストール] セルを実行して、必要な Python パッケージをインストールし、環境変数を構成します。
  4. [Google Cloud 環境設定の構成] の最初のセルで、次の変数を設定してセルを実行します。

    • PROJECT: AI Platform Prediction モデルがデプロイされ、リクエスト / レスポンス データ用に BigQuery データセットのログが記録される Cloud プロジェクトの ID。
    • BUCKET: SavedModel をアップロードして AI Platform Prediction にデプロイする Cloud Storage バケットの名前。名前がグローバルに一意であることを確認してください。
    • REGION: AI Platform Prediction モデルがデプロイされるリージョン。地理的に近いリージョンを選択してください。
  5. [設定] の残りのセルを実行して、環境の構成を完了します。

    • Google Cloud アカウントを認証する
    • ライブラリのインポート
    • 定数を定義する
    • ローカル ワークスペースを作成する

以上の手順が完了したら、データを準備して、モデルのトレーニングと評価を行い、サービング用にモデルをエクスポートして、AI Platform にモデルをデプロイする準備が整います。これらのタスクを行った後、BigQuery ロギング用のデータセットを準備します。

これらのタスクはすべてノートブックでコーディングされます。タスクを行うには、Jupyter ノートブックで行うのと同様に、ノートブック内のセルのシーケンスを実行します。

以下のセクションでは、プロセスの重要な部分に焦点を当てて、設計とコードの特徴について説明します。

モデルのトレーニング

ノートブックのセクション 2 のタスクを実行してモデルを作成し、トレーニングします。ノートブックのコードは、feature columns リストを使用して入力特徴を表します。このコードでは、次の変数を使用します。

  • numeric_column は、数値特徴量の場合に使用します。
  • categorical_column_with_vocabulary_list は、カテゴリ特徴量の場合に使用します。
  • embedding_column は、カテゴリ特徴量の各列をラップするために使用します。ここでは、埋め込み列の dimension は、1 にカテゴリ特徴量の語彙サイズの平方根を加えた値に設定されます。

次のスニペットは、作成された特徴量の列を示しています。

EmbeddingColumn(categorical_column=VocabularyListCategoricalColumn(key='Soil_Type', vocabulary_list=('2702', '2703', '2704', ...), dtype=tf.string, default_value=-1, num_oov_buckets=0), dimension=7, combiner='mean', max_norm=None, trainable=True)
EmbeddingColumn(categorical_column=VocabularyListCategoricalColumn(key='Wilderness_Area', vocabulary_list=('Cache', 'Commanche', 'Neota', 'Rawah'), dtype=tf.string, default_value=-1, num_oov_buckets=0), dimension=3, combiner='mean', max_norm=None, trainable=True)
NumericColumn(key='Aspect', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None)
NumericColumn(key='Elevation', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None)
NumericColumn(key='Hillshade_3pm', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None)
NumericColumn(key='Hillshade_9am', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None)
NumericColumn(key='Hillshade_Noon', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None)
NumericColumn(key='Horizontal_Distance_To_Fire_Points', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None)
NumericColumn(key='Horizontal_Distance_To_Hydrology', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None)
NumericColumn(key='Horizontal_Distance_To_Roadways', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None)
NumericColumn(key='Slope', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None)
NumericColumn(key='Vertical_Distance_To_Hydrology', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None)

次のコード スニペットに示すように、ノートブックでは、Keras 分類モデルは、tf.keras.Sequential メソッドを使用して作成されます。

def create_model(params):

 feature_columns = create_feature_columns()
  layers = []
 layers.append(tf.keras.layers.DenseFeatures(feature_columns))
 for units in params.hidden_units:
   layers.append(tf.keras.layers.Dense(units=units, activation='relu'))
   layers.append(tf.keras.layers.BatchNormalization())
   layers.append(tf.keras.layers.Dropout(rate=params.dropout))
  layers.append(tf.keras.layers.Dense(units=NUM_CLASSES, activation='softmax'))
  model = tf.keras.Sequential(layers=layers, name='classifier')

 adam_optimzer = tf.keras.optimizers.Adam(learning_rate=params.learning_rate)

 model.compile(
       optimizer=adam_optimzer,
       loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
       metrics=[tf.keras.metrics.SparseCategoricalAccuracy()],
       loss_weights=None,
       sample_weight_mode=None,
       weighted_metrics=None,
   )

 return model

ノートブックでデフォルトのパラメータ設定を使用してモデルをトレーニングすると、モデルでは次のグラフに示されるような正解率と損失関数の値が得られます。X 軸はエポック数を示し、Y 軸は正解率と損失関数を示します。

モデルの正解率グラフ。

モデルの損失関数グラフ。

モデルのエクスポート

ノートブックのセクション 3 のタスクを実行して、モデルをエクスポートして提供します。SavedModel をエクスポートして検査したら、Cloud Storage バケットにアップロードします。

サービング用に未加工の特徴量を受け入れるように構成されたモデルを SavedModel としてエクスポートする前に、feature_spec 辞書を作成する必要があります。この辞書では、サービング関数のためのインターフェース(入力)を定義します。ノートブックの次のスニペットは、辞書を示したものです。

feature_spec = {}
for feature_name in FEATURE_NAMES:
   if feature_name in CATEGORICAL_FEATURES_WITH_VOCABULARY:
       feature_spec[feature_name] = tf.io.FixedLenFeature(
           shape=[None], dtype=tf.string)
   else:
       feature_spec[feature_name] = tf.io.FixedLenFeature(
           shape=[None], dtype=tf.float32)

次のスニペットは、作成された feature_spec 辞書を示したものです。

Soil_Type: FixedLenFeature(shape=[None], dtype=tf.string, default_value=None)
Wilderness_Area: FixedLenFeature(shape=[None], dtype=tf.string, default_value=None)
Aspect: FixedLenFeature(shape=[None], dtype=tf.float32, default_value=None)
Elevation: FixedLenFeature(shape=[None], dtype=tf.float32, default_value=None)
Hillshade_3pm: FixedLenFeature(shape=[None], dtype=tf.float32, default_value=None)
Hillshade_9am: FixedLenFeature(shape=[None], dtype=tf.float32, default_value=None)
Hillshade_Noon: FixedLenFeature(shape=[None], dtype=tf.float32, default_value=None)
Horizontal_Distance_To_Fire_Points: FixedLenFeature(shape=[None], dtype=tf.float32, default_value=None)
Horizontal_Distance_To_Hydrology: FixedLenFeature(shape=[None], dtype=tf.float32, default_value=None)
Horizontal_Distance_To_Roadways: FixedLenFeature(shape=[None], dtype=tf.float32, default_value=None)
Slope: FixedLenFeature(shape=[None], dtype=tf.float32, default_value=None)
Vertical_Distance_To_Hydrology: FixedLenFeature(shape=[None], dtype=tf.float32, default_value=None)

次に、ノートブック コードが make_features_serving_fn 関数を定義します。この関数は、model オブジェクトを受け取り、serve_features_fn 関数を返します。serve_features_fn 関数はモデル提供レシーバ関数として使用するもので、features 辞書を受け取り、次の項目を持つ辞書を返します。

  • predicted_label(モデルにより予測されたクラスラベルを含む)。
  • confidence(予測されたクラスラベルの確率を含む)。
  • probabilities(すべてのクラスラベルの確率を含む)。

この出力形式は、AI Platform の継続評価と互換性があります。一般的な分類タスクについては、入力例と出力予測のフォーマット方法をご覧ください。

次のスニペットは、ノートブックで定義されている make_features_serving_fn 関数を示したものです。

LABEL_KEY = 'predicted_label'
SCORE_KEY = 'confidence'
PROBABILITIES_KEY = 'probabilities'
SIGNATURE_NAME = 'serving_default'
...

def make_features_serving_fn(model):

 @tf.function
 def serve_features_fn(features):
   probabilities = model(features)
   labels = tf.constant(TARGET_FEATURE_LABELS, dtype=tf.string)
   predicted_class_indices = tf.argmax(probabilities, axis=1)
   predicted_class_label = tf.gather(
       params=labels, indices=predicted_class_indices)
   prediction_confidence = tf.reduce_max(probabilities, axis=1)

   return {
       LABEL_KEY: predicted_class_label,
       SCORE_KEY:prediction_confidence,
       PROBABILITIES_KEY: probabilities}

 return serve_features_fn

モデルをトレーニングするためのセルを実行したら、モデルを SavedModel 形式にエクスポートする必要があります。そのためには、make_features_serving_fn 関数を使用する signatures 辞書と feature_spec 辞書が必要です。次のリストは、これら両方のタスクのコードを示しています。

SIGNATURE_NAME = 'serving_default'

features_input_signature = {
   feature: tf.TensorSpec(shape=spec.shape, dtype=spec.dtype, name=feature)
   for feature, spec in feature_spec.items()}

...

signatures = {
   SIGNATURE_NAME: make_features_serving_fn(model).get_concrete_function(
       features_input_signature)}

model.save(MODEL_DIR, save_format='tf', signatures=signatures)

モデルをエクスポートするときは、次の出力を生成する saved_model_cli コマンドライン ツールを使用して SavedModel の署名(入力と出力)を検査できます。

The given SavedModel SignatureDef contains the following input(s):
  inputs['Aspect'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1)
      name: serving_default_Aspect:0
  inputs['Elevation'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1)
      name: serving_default_Elevation:0
  inputs['Hillshade_3pm'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1)
      name: serving_default_Hillshade_3pm:0
  inputs['Hillshade_9am'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1)
      name: serving_default_Hillshade_9am:0
  inputs['Hillshade_Noon'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1)
      name: serving_default_Hillshade_Noon:0
  inputs['Horizontal_Distance_To_Fire_Points'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1)
      name: serving_default_Horizontal_Distance_To_Fire_Points:0
  inputs['Horizontal_Distance_To_Hydrology'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1)
      name: serving_default_Horizontal_Distance_To_Hydrology:0
  inputs['Horizontal_Distance_To_Roadways'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1)
      name: serving_default_Horizontal_Distance_To_Roadways:0
  inputs['Slope'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1)
      name: serving_default_Slope:0
  inputs['Soil_Type'] tensor_info:
      dtype: DT_STRING
      shape: (-1)
      name: serving_default_Soil_Type:0
  inputs['Vertical_Distance_To_Hydrology'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1)
      name: serving_default_Vertical_Distance_To_Hydrology:0
  inputs['Wilderness_Area'] tensor_info:
      dtype: DT_STRING
      shape: (-1)
      name: serving_default_Wilderness_Area:0
The given SavedModel SignatureDef contains the following output(s):
  outputs['confidence'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1)
      name: StatefulPartitionedCall_24:0
  outputs['predicted_label'] tensor_info:
      dtype: DT_STRING
      shape: (-1)
      name: StatefulPartitionedCall_24:1
  outputs['probabilities'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 7)
      name: StatefulPartitionedCall_24:2
Method name is: tensorflow/serving/predict

AI Platform Prediction へのモデルのデプロイ

ノートブックのセクション 4 のセルを実行してモデルをデプロイします。SavedModel を Cloud Storage のロケーションにアップロードしたら、REST API として AI Platform Prediction にモデルをデプロイします。次のコード スニペットに示すように、コードを実行してモデルを作成します。

!gcloud ai-platform models create {MODEL_NAME} \
    --project {PROJECT} \
    --regions {REGION}

次のコマンドを使用して、モデル バージョンを作成します。

!gcloud ai-platform versions create {VERSION_NAME} \
    --model={MODEL_NAME} \
    --origin=gs://{BUCKET}/models/{MODEL_NAME} \
    --runtime-version=2.1 \
    --framework=TENSORFLOW \
    --python-version=3.7 \
    --project={PROJECT}

モデル バージョンが作成されると、Cloud Console の [AI Platform] > [Models] で確認できます。コンソールでモデルを選択すると、作成したモデル バージョンが表示されます。バージョンの詳細を表示するには、モデルのバージョンをクリックします。

次の画像は、コンソールに表示されるバージョンの詳細を示したものです。

AI Platform Prediction コンソールのモデルの詳細。

BigQuery へのリクエスト / レスポンス ロギングを有効にする

ノートブックのセクション 5 のセルを実行して、BigQuery へのロギングを有効にします。これには、BigQuery テーブルの設定が含まれます。

ログには費用が発生するため、AI Platform Prediction 予測サービスのデフォルトではリクエストに関するログ情報を提供しません。秒間クエリ数(QPS)が多いオンライン予測の場合、かなりの数のログが生成される可能性があります。これらのログには BigQuery の料金が適用されます。そのため、ロギングを明示的に有効にする必要があります。

BigQuery へのリクエスト / レスポンス ロギングを有効にする前に、リクエスト / レスポンス ロギング サービスに受け入れられる形式を持つ BigQuery テーブルを作成する必要があります。

次のスニペットは、ログを保存する BigQuery テーブルのスキーマを作成するために実行するノートブックのコードを示したものです。

import json

table_schema_json = [
 {"name":"model", "type": "STRING", "mode": "REQUIRED"},
 {"name":"model_version", "type": "STRING", "mode":"REQUIRED"},
 {"name":"time", "type": "TIMESTAMP", "mode": "REQUIRED"},
 {"name":"raw_data", "type": "STRING", "mode": "REQUIRED"},
 {"name":"raw_prediction", "type": "STRING", "mode": "NULLABLE"},
 {"name":"groundtruth", "type": "STRING", "mode": "NULLABLE"}]

json.dump(table_schema_json, open('table_schema.json', 'w'))

次のスニペットは、テーブルを作成するために実行する BigQuery コマンドを示したものです。

TIME_PARTITION_EXPERIATION = int(60 * 60 * 24 * 7)

!bq mk --table \
 --project_id={PROJECT_ID} \
 --time_partitioning_field=time \
 --time_partitioning_type=DAY \
 --time_partitioning_expiration={TIME_PARTITION_EXPERIATION} \
 {PROJECT}:{BQ_DATASET_NAME}.{BQ_TABLE_NAME} \
 'table_schema.json'

リクエスト / レスポンス ロギングを有効にするには、既存のモデル バージョンの projects.models.versions.patch メソッドを使用します。次のコード スニペットに示すように、requestLoggingConfig 辞書で samplingPercentagebigqueryTableName の値を設定する必要があります。

sampling_percentage = 1.0
bq_full_table_name = '{}.{}.{}'.format(PROJECT, BQ_DATASET_NAME, BQ_TABLE_NAME)

service = googleapiclient.discovery.build('ml', 'v1')
name = 'projects/{}/models/{}/versions/{}'.format(PROJECT, MODEL_NAME, VERSION_NAME)

logging_config = {
   "requestLoggingConfig":{
       "samplingPercentage": sampling_percentage,
       "bigqueryTableName": bq_full_table_name
       }
   }

service.projects().models().versions().patch(
   name=name,
   body=logging_config,
   updateMask="requestLoggingConfig"
   ).execute()

このコードを実行すると、次のような出力が表示されます。

{'metadata': {'@type': 'type.googleapis.com/google.cloud.ml.v1.OperationMetadata',
  'createTime': '2020-04-24T23:59:38Z',
  'modelName': 'projects/[YOUR_GOOGLE_PROJECT]/models/covertype_classifier',
  'operationType': 'UPDATE_VERSION',
  'version': {'createTime': '2020-04-14T21:21:09Z',
   'deploymentUri': 'gs://<[YOUR_CLOUD_STORAGE_BUCKET]/models/covertype_classifier',
   'etag': 'TnlXt8cIbVs=',
   'framework': 'TENSORFLOW',
   'machineType': 'mls1-c1-m2',
   'name': 'projects/[YOUR_GOOGLE_PROJECT]/models/covertype_classifier/versions/v2',
   'pythonVersion': '3.7',
   'requestLoggingConfig': {'bigqueryTableName': '[YOUR_GOOGLE_PROJECT].data_validation.covertype_classifier_logs',
    'samplingPercentage': 1},
   'runtimeVersion': '2.1',
   'state': 'READY'}},
 'name': 'projects/[YOUR_GOOGLE_PROJECT]/operations/update_covertype_classifier_v2_1587772778240'}

モデル API とログに記録されたインスタンスと予測をテストする

モデル API をテストできるように、ノートブックには caip_predict メソッドを実装するコードが含まれています。このメソッドは、API として AI Platform Prediction にデプロイされているモデルを呼び出して、特定のデータ インスタンスを渡します。次のスニペットは、このタスクを行うノートブックのコードを示しています。

import googleapiclient.discovery

service = googleapiclient.discovery.build('ml', 'v1')
name = 'projects/{}/models/{}/versions/{}'.format(PROJECT, MODEL_NAME, VERSION_NAME)
print("Service name: {}".format(name))

def caip_predict(instances):

 request_body={
     'signature_name': SIGNATURE_NAME,
     'instances': instances}

 response = service.projects().predict(
     name=name,
     body=request_body).execute()

 if 'error' in response:
   raise RuntimeError(response['error'])

 probability_list = [output[MODEL_OUTPUT_KEY] for output in response['predictions']]
 classes = [FEATURE_LABELS[int(np.argmax(probabilities))] for probabilities in probability_list]
 return classes

サンプル インスタンスを使用して API を呼び出すには、次のコードを実行します。このコードは API を 10 回呼び出して、毎回 instances 辞書を渡します。

instances = [
     {
       'Soil_Type': ['7202'],
       'Wilderness_Area': ['Commanche'],
       'Aspect': [61],
       'Elevation': [3091],
       'Hillshade_3pm': [129],
       'Hillshade_9am': [227],
       'Hillshade_Noon': [223],
       'Horizontal_Distance_To_Fire_Points': [2868],
       'Horizontal_Distance_To_Hydrology': [134],
       'Horizontal_Distance_To_Roadways': [0],
       'Slope': [8],
       'Vertical_Distance_To_Hydrology': [10],
   }
]

...

import time

for i in range(10):
 caip_predict(instances)
 print('.', end='')
 time.sleep(0.1)

次のスクリーンショットで示すとおり、ログに記録されたリクエストとレスポンスをコンソールからクエリするには、BigQuery コンソールを使用します。

SQL ステートメントと結果が表示されたクエリエディタ。

このように、インスタンス(リクエスト)とその予測(レスポンス)は BigQuery テーブルに取り込まれますが、未加工の形式(JSON 形式)でキャプチャされます。したがって、特徴と予測確率は、スキューで分析する前に解析する必要があります。このシリーズの次のガイドでは、その方法について説明します。

クリーンアップ

このシリーズの残りも継続する予定の場合は、作成済みのリソースはそのままにしておいてください。継続する予定でない場合は、リソースを含むプロジェクトを削除するか、プロジェクトは残して個々のリソースを削除します。

プロジェクトの削除

  1. Cloud Console で [リソースの管理] ページに移動します。

    [リソースの管理] に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

次のステップ