AI Platform Prediction での AI Explanations の使用

ここでは、AI Explanations で AI Platform Prediction にモデルをデプロイして使用する方法を説明します。

始める前に

AI Platform でモデルをトレーニングしてデプロイする前に、次の準備作業が必要です。

  • ローカル開発環境を設定します。
  • 課金と必要な API を有効にして GCP プロジェクトを設定します。
  • トレーニング パッケージとトレーニングしたモデルを保存する Cloud Storage バケットを作成します。

GCP プロジェクトを設定するには、サンプル ノートブックの手順に従ってください。

モデルを保存する

TensorFlow 1.15、2.1、2.2 がサポートされています。TensorFlow 2.2 でモデルを保存するには tf.saved_model.save を使用しますが、TensorFlow 1.15 ではこれを使用しないでください。

AI Explanations で使用するモデルを保存する方法と、Explainable AI SDK の使用方法をご覧ください。

説明メタデータ ファイル

入力、出力、ベースラインに関する情報を含むメタデータ ファイルを送信する必要があります。これにより、AI Explanations がモデルの正しい部分についての説明を提供します。Explainable AI SDK を使用して、入力と出力を生成できます。

  • 説明を付ける入力テンソルと出力テンソルの名前を指定します。入力テンソルと出力のテンソルの識別方法の詳細をご覧ください。
  • input_baselines にベースラインを渡します。
  • framework の「テンソルフロー」を指定します。
  • ファイルに explanation_metadata.json という名前を付けます。
  • SavedModel が格納されている同じ Cloud Storage バケットに explanation_metadata.json ファイルをアップロードします。

explanation_metadata.json ファイルは次の例のようになります。

{
    "inputs": {
      "data": {
        "input_tensor_name": "YOUR_INPUT_TENSOR_NAME"
        "input_baselines": [0]
      }
    },
    "outputs": {
      "duration": {
        "output_tensor_name": "YOUR_OUTPUT_TENSOR_NAME"
      }
    },
    "framework": "tensorflow"
}

この例では、モデルの作成とトレーニングのプロセスで割り当てることができる入力テンソルと出力テンソルの意味のある名前は「data」と「duration」です。実際の入力テンソルと出力テンソルの名前は name:index という形式になります。たとえば、x:0Placeholder:0 です。

input_baselines の場合、まず 1 つのベースラインを指定します。この例では、[0] はすべて黒の画像を表します。詳しくは、ベースラインの調整をご覧ください。

入力テンソルと出力テンソルの名前を手動で検索する

ほとんどの場合、Explainable AI SDK を使用してモデルの入力と出力を生成できます。事前トレーニング済みの TensorFlow 1.15 モデルを使用している場合のみ、入力テンソルと出力テンソルの名前を手動で検索できます。

入力テンソルと出力テンソルの名前を調べる最適な方法は、入力データと出力データの型のほか、モデルの作成方法によっても異なります。各ケースの詳細な説明と例については、[入力と出力について][understanding-inputs-outputs] に関するガイドをご覧ください。

入力データ型 出力データ型 その他の条件 推奨されるアプローチ
数値または文字列 数値 入力はシリアル化された形式ではありません。出力は、カテゴリデータとして扱われる数値データではありません(たとえば、数値クラス ID など)。 SavedModel CLI を使用して、入力テンソルと出力のテンソルの名前を検索します。または、モデルのトレーニング中や保存中に説明メタデータ ファイルを作成します。その場合、プログラムや環境はトレーニング コードに引き続きアクセスできます。
シリアル化されたデータ 任意 モデルをエクスポートするときに、TensorFlow 解析オペレーションをサービング入力関数に追加します。解析オペレーションの出力を使用して、入力テンソルを識別します。
任意 任意 モデルに前処理オペレーションが含まれます 前処理ステップの後に入力テンソルの名前を取得するには、tf.Tensorname プロパティを使用して、入力テンソルの名前を取得します。
任意 確率、ロジット、その他のタイプの浮動小数点数テンソルではありません 確率、ロジット、その他の浮動小数点数テンソルではない出力についての説明を取得します。 TensorBoard を使用してグラフを調べ、正しい出力テンソルを見つけます。
微分不可能なデータ 任意 微分可能な入力が必要な統合勾配を使用します。 微分可能なテンソルとして微分不可能な入力をエンコードします。元の入力テンソルとエンコードされた入力テンソルの両方の名前を説明メタデータ ファイルに追加します。

モデルとバージョンのデプロイ

AI Platform Prediction は、モデルリソースとバージョン リソースを使用してトレーニング済みモデルを整理します。AI Platform Prediction モデルは、機械学習モデルの複数のバージョンを格納するコンテナに相当します。

モデルをデプロイするには、AI Platform Prediction でモデルリソースを作成し、そのモデルのバージョンを作成して Cloud Storage に格納されたモデルファイルにリンクします。

モデルリソースを作成する

AI Platform Prediction はモデルリソースを使用して、さまざまなバージョンのモデルを整理します。

モデル バージョンのモデルリソースを作成します。次の gcloud コマンドライン ツール コマンドで、MODEL_NAME をモデルの名前に置き換えます。モデル名の先頭は英字にしてください。その後には、英字、数字、アンダースコアのみを使用できます。

AI Explanations を使用するには、モデルをリージョン エンドポイントに作成する必要があります。

gcloud ai-platform models create MODEL_NAME \
  --region us-central1

詳細については、AI Platform Prediction モデル API をご覧ください。

モデル バージョンを作成する

これで、Cloud Storage にアップロードされたトレーニング済みのモデルでモデル バージョンを作成する準備が整いました。バージョンを作成するには、次のパラメータを指定します。

  • name: AI Platform Prediction モデル内で一意にする必要があります。
  • deploymentUri: Cloud Storage の SavedModel ディレクトリのパス。
  • framework(必須): tensorflow のみ
  • runtimeVersion: AI Explanations の 1.15、2.1、2.2 をサポートする次のランタイム バージョンのいずれかを使用します。
  • pythonVersion: ランタイム バージョン 1.14 を使用している場合は、「3.5」に設定する必要があります。ランタイム バージョンが 1.15 の場合は、「3.7」を使用します。
  • machineType(必須): AI Platform Prediction が予測と説明を提供するノードに使用する仮想マシンのタイプ。AI Explanations でサポートされるマシンタイプを選択します。
  • explanation-method: 使用する特徴アトリビューション方式のタイプ(「sampled-sappley」、「integrating-gradients」、「xrai」)。
  • 経路またはステップ: サンプリングされた Shapley には --num-paths を使用し、統合勾配または XRAI には --num-integral-steps を使用します。

上記の各パラメータの詳細については、バージョン リソースの AI Platform トレーニングと Prediction API をご覧ください。

  1. SavedModel が配置されている Cloud Storage ディレクトリへのパス、モデル名、バージョン名、使用するフレームワークを格納する環境変数を設定します。

    MODEL=your_model_name
    MODEL_DIR="gs://your_bucket_name/"
    VERSION=your_version_name
    FRAMEWORK=tensorflow
    
  2. バージョンを作成します。

    EXPLAIN_METHOD="integrated-gradients"
    gcloud beta ai-platform versions create $VERSION \
    --model $MODEL \
    --origin $MODEL_DIR \
    --runtime-version 1.15 \
    --framework $FRAMEWORK \
    --python-version 3.5 \
    --machine-type n1-standard-4 \
    --explanation-method $EXPLAIN_METHOD \
    --num-integral-steps 25 \
    --region us-central1
    

    バージョンの作成には数分かかります。完了すると次の出力が表示されます。

    Creating version (this might take a few minutes)......done.
  3. モデルのデプロイのステータスを確認し、モデルが正しくデプロイされていることを確認します。

    gcloud ai-platform versions describe $VERSION_NAME \
      --model $MODEL_NAME \
      --region us-central1
    

    状態が READY であることを確認します。次のような出力が表示されます。

    createTime: '2018-02-28T16:30:45Z'
    deploymentUri: gs://your_bucket_name
    framework: TENSORFLOW
    machineType: mls1-c1-m2
    name: projects/your_project_id/models/your_model_name/versions/your_version_name
    pythonVersion: '3.5'
    runtimeVersion: '1.15'
    state: READY

Explanations でサポートされているマシンタイプ

AI Explanations リクエストでは、次のいずれかのマシンタイプのモデル バージョンをデプロイする必要があります。マシンタイプを指定しなければ、デプロイは失敗します。

次の表は、使用可能なマシンタイプを比較したものです。

名前 vCPU メモリ(GB)
n1-standard-2 2 7.5
n1-standard-4 4 15
n1-standard-8 8 30
n1-standard-16 16 60
n1-standard-32 32 120

これらのマシンタイプは、リージョン エンドポイントでのみ使用できます。詳しくは、他の AI Platform Prediction 機能のサポートをご覧ください。

マシンタイプごとの料金をご覧ください。Compute Engine(N1)マシンタイプの仕様の詳細については、Compute Engine のドキュメントをご覧ください。

入力データを整形する

オンライン予測の基本形式は、データ インスタンスをリスト化したものです。これらは、トレーニング アプリケーションで入力を構成した方法に応じて、値のプレーンリストまたは JSON オブジェクトのメンバーのいずれかになります。予測のために複雑な入力とバイナリデータをフォーマットする方法について学習します。

次の例は、TensorFlow モデルの入力テンソルとインスタンス キーを示しています。

{"values": [1, 2, 3, 4], "key": 1}

次の規則に従う限り、JSON 文字列の構成は複雑になってもかまいません。

  • インスタンス データの最上位レベルは、Key-Value ペアの辞書である JSON オブジェクトでなければなりません。

  • インスタンス オブジェクト内の個々の値には、文字列、数字、またはリストを使用できます。JSON オブジェクトを埋め込むことはできません。

  • リストには、同じ型(他のリストも含む)のアイテムのみが含まれている必要があります。文字列と数値を混在させることはできません。

オンライン予測の入力インスタンスを、projects.explain 呼び出しのメッセージ本文として渡します。詳細については、予測リクエスト本文のフォーマット要件をご覧ください。

  1. gcloud を使用してリクエストを送信するには、入力ファイルが改行区切りの JSON ファイルであり、各行に 1 つのインスタンスが JSON オブジェクトとして記述されていることを確認します。

    {"values": [1, 2, 3, 4], "key": 1}
    {"values": [5, 6, 7, 8], "key": 2}
    

予測と説明をリクエストする

予測と説明をリクエストします。

gcloud beta ai-platform explain \
  --model $MODEL \
  --version $VERSION \
  --json-instances='your-data.txt' \
  --region us-central1

説明のレスポンスを理解する

モデルをデプロイしたら、Explainable AI SDK を使用して、表形式データと画像データの両方の説明をリクエストし、特徴アトリビューションの結果を可視化できます。

import explainable_ai_sdk

m = explainable_ai_sdk.load_model_from_ai_platform(PROJECT_ID, MODEL_NAME, VERSION)
explanations = m.explain([instance_dict])
explanations[0].visualize_attributions()

表形式のモデルでは、アトリビューションが棒グラフでプロットされます。画像モデルでは、モデルのデプロイ時に指定した可視化設定を使用して、入力画像にアトリビューションが表示されます。

説明レスポンスの各フィールドの詳細については、API リファレンスの完全なレスポンスの例をご覧ください。

サンプル ノートブックを参照して、説明レスポンスを解析する方法を学習します。

説明を確認する

次のコード例は、一連の説明を確認し、ベースラインを調整する必要があるかどうかを確認するのに役立ちます。

コードでは、explanation_metadata.json ファイルに指定した内容に従って、入力キー値を更新するだけで済みます。

{
    "inputs": {
      "YOUR_INPUT_KEY_VALUE": {
        "input_tensor_name": "YOUR_INPUT_TENSOR_NAME"
        "input_baselines": [0]
      }
    ...
}

たとえば、入力キーの値が「data」の場合、次のコード スニペットの 4 行目で同じ値が「data」になります。

def check_explanations(example, mean_tgt_value=None, variance_tgt_value=None):
  passed_test = 0
  total_test = 1
  attribution_vals = example['attributions_by_label'][0]['attributions']['YOUR-INPUT-KEY-VALUE']

  baseline_score = example['attributions_by_label'][0]['baseline_score']
  sum_with_baseline = np.sum(attribution_vals) + baseline_score
  predicted_val = example['attributions_by_label'][0]['example_score']

  # Check 1
  # The prediction at the input is equal to that at the baseline.
  #  Please use a different baseline. Some suggestions are: random input, training
  #  set mean.
  if abs(predicted_val - baseline_score) <= 0.05:
    print('Warning: example score and baseline score are too close.')
    print('You might not get attributions.')
  else:
    passed_test += 1

  # Check 2 (only for models using Integrated Gradient explanations)
  # Ideally, the sum of the integrated gradients must be equal to the difference
  # in the prediction probability at the input and baseline. Any discrepancy in
  # these two values is due to the errors in approximating the integral.
  if explain_method == 'integrated-gradients':
    total_test += 1
    want_integral = predicted_val - baseline_score
    got_integral = sum(attribution_vals)
    if abs(want_integral-got_integral)/abs(want_integral) > 0.05:
        print('Warning: Integral approximation error exceeds 5%.')
        print('Please try increasing the number of integrated gradient steps.')
    else:
        passed_test += 1

  print(passed_test, ' out of ', total_test, ' sanity checks passed.')

説明を解析する際に、受け取ったアトリビューションごとにこれらのチェックを実行できます。

for i in attributions_resp['explanations']:
  check_explanations(i)

近似誤差を使用して結果を改善する

AI Explanations の特徴アトリビューション方式(サンプリングされた Shapley、統合勾配、XRAI)はすべて、Shapley 値のバリアントに基づいています。Shapley の値は非常に計算コストが高いため、AI Explanations では正確な値ではなく近似値を使用します。AI Explanations は、特徴アトリビューションの結果とともに近似誤差も返します。近似誤差が 0.05 を超える場合は、入力を調整して誤差を減らしてください。

次の入力を変更すると、近似誤差を減らして正確な値に近づけることができます。

  • 積分ステップまたは積分経路の数を増やします。
  • 選択した入力ベースラインを変更します。
  • 入力ベースラインを追加します。統合勾配と XRAI 方式では、追加のベースラインを使用するとレイテンシが増加します。サンプリングされた Shapley 方式で追加のベースラインを使用してもレイテンシは増加しません。

ステップまたは経路を増やす

近似誤差を減らすには、次の値を大きくします。

  • サンプリングされた Shapley の経路の数
  • 統合勾配または XRAI の積分ステップ数

これらのパラメータは、モデルのデプロイ中、バージョン リソースを作成する際に設定します。

ベースラインの調整

explanation_metadata.json ファイルで input_baselines を設定できます。このセクションでは、表形式のデータと画像データの例を示します。入力ベースラインで、トレーニング データに関連した中央値、最小値、最大値、ランダム値を表すことができます。

全般:

  • 中央値を表す 1 つのベースラインから始めます。
  • このベースラインを 1 つのランダム値を表すものに変更します。
  • 最小値と最大値を表す 2 つのベースラインを試します。
  • ランダム値を表す別のベースラインを追加します。

表形式のデータの例

次の Python コードにより、表形式データの説明メタデータ ファイルの内容が作成されます。サンプリングされた Shapley または統合勾配を使用して、表形式データの特徴アトリビューションを取得できます。このコードは、表形式データのサンプル ノートブックの一部です。

input_baselines は、複数のベースラインを指定できるリストであることに注意してください。この例では、ベースラインを 1 つだけ設定しています。ベースラインはトレーニング データの中央値のリストです。この例では train_data です。

explanation_metadata = {
    "inputs": {
      "data": {
        "input_tensor_name": model.input.name,
        "input_baselines": [train_data.median().values.tolist()],
        "encoding": "bag_of_features",
        "index_feature_mapping": train_data.columns.tolist()
      }
    },
    "outputs": {
      "duration": {
        "output_tensor_name": model.output.name
      }
    },
  "framework": "tensorflow"
  }

最小値と最大値を表す 2 つのベースラインを設定するには、input_baselines を次のように設定します。[train_data.min().values.tolist(), train_data.max().values.tolist()]

画像データの例

次の Python コードにより、画像データの説明メタデータ ファイルの内容が作成されます。統合勾配を使用して、画像データの特徴アトリビューションを取得できます。このコードは、画像データのサンプル ノートブックの一部です。

input_baselines は、複数のベースラインを指定できるリストであることに注意してください。この例では、ベースラインを 1 つだけ設定しています。ベースラインはランダム値のリストです。トレーニング データセットの画像に多くの白黒が含まれている場合は、画像ベースラインにランダム値を使用すると効果的です。

それ以外の場合は、input_baselines[0, 1] に設定して黒と白の画像を表します。

random_baseline = np.random.rand(192,192,3)

explanation_metadata = {
    "inputs": {
      "data": {
        "input_tensor_name": "input_pixels:0",
        "modality": "image",
        "input_baselines": [random_baseline.tolist()]
      }
    },
    "outputs": {
      "probability": {
        "output_tensor_name": "dense/Softmax:0"
      }
    },
  "framework": "tensorflow"
  }

次のステップ