Cloud ML Engine と Cloud Datalab での分散 TensorFlow の使用

このチュートリアルでは、Google Cloud Machine Learning Engine で MNIST データセットを使用した畳み込みニューラル ネットワーク モデルのトレーニングに、Python の TensorFlow コードの分散構成を使用する方法を説明します。TensorBoard を使用してトレーニング プロセスを可視化し、Google Cloud Datalab で予測をテストします。

TensorFlow は、Google が機械学習用に提供しているオープンソース ライブラリで、Google の研究機関である Machine Intelligence 部門の研究者とエンジニアが開発しました。TensorFlow は複数のマシンで実行され、学習のワークロードを負荷分散します。Cloud Machine Learning Engine が提供するマネージド サービスにより、サービス API を使用して TensorFlow コードを分散環境で実行できます。

このチュートリアルでは、ノードという用語はトレーニング中に並列計算を実行するアプリケーション コンテナを指します。

データについて

MNIST データセットは手書き数字の認識に対応しているため、画像認識の学習セットとして機械学習で広く利用されています。

データセットには、0〜9 の手書き数字の画像が大量に含まれ、各画像には数字を表すラベルが付いています。

このチュートリアルでは、MNIST データセットに基づいて画像を分類する機械学習モデルをトレーニングします。トレーニング後、このモデルは MNIST データセットの手書き画像から学習した内容に基づいて、受信画像を 10 個のカテゴリ(0〜9)のいずれかに分類します。まだ学習していない画像をモデルに送信した場合、モデルはトレーニングで学習した内容に基づいて画像内の数字を識別します。

MNIST データセットは次の 3 つの部分から構成されます。

  • 55,000 例のトレーニング データ
  • 10,000 例のテストデータ
  • 5,000 例の検証データ

データセットの詳細については、MNIST データベース サイトをご覧ください。

ニューラル ネットワークの理解

コンピュータ プログラミングでは、人間が多くの行のコードを使用して各ステップを指定することによって、コンピュータに問題を解決するよう指示します。機械学習とニューラル ネットワークでは、代わりにコンピュータに例を使って問題を解決するように指示します。

ニューラル ネットワークは、トレーニング データセットの特定の入力に対して期待される出力を知ることができる数学的関数です。次の図は、ネコの画像から「cat」を出力するようにトレーニングされたニューラル ネットワークを示しています。

ニューラル ネットワーク モデルは、例を使用してトレーニングすることができる関数です。

ニューラル ネットワーク モデルは、各層に設定可能なパラメータがある計算ユニットの複数の層で構成されていることがわかります。モデルのトレーニングの目標は、最高の精度で結果を得るためにパラメータを最適化することです。トレーニング アルゴリズムでは、モデルを通じてトレーニング データセットのバッチを処理するときに調整を行います。トレーニング プロセスを複数の計算ノードに分散する場合は、すべてのノードが共有する変更パラメータを追跡する方法が必要です。

分散トレーニングのアーキテクチャ

複数のノードを持つモデルをトレーニングするための基本的な戦略は 3 つあります。

  • 同期更新によるデータの並列トレーニング。
  • 非同期更新によるデータの並列トレーニング。
  • モデルの並行トレーニング。

このチュートリアルのサンプルコードでは、Cloud ML Engine で非同期更新を使用するデータの並列トレーニングを使用しています。この場合、次のタイプのノードを使用してトレーニング ジョブが実行されます。

  • パラメータ サーバーノード。ワーカーノードおよびチーフ ワーカーノードの勾配ベクトルでパラメータを更新します。
  • ワーカーノード。トレーニング データセットから勾配ベクトルを計算します。
  • チーフ ワーカーノード。ワーカーノードの 1 つとしての役目を果たすだけでなく、複数のワーカーのオペレーションを調整します。

モデル構造に関係なく、データの並列化戦略を使用できるため、カスタムモデルに分散型トレーニング メソッドを適用するのは良い出発点です。データ並列トレーニングでは、モデル全体がすべてのワーカーノードで共有されます。各ノードで、ミニバッチ処理と同様にトレーニング データセットの一部とは独立して勾配ベクトルを計算します。計算された勾配ベクトルはパラメータ サーバーノードに集められ、モデル パラメータは勾配ベクトルの総和で更新されます。10 個のワーカーノードに 10,000 個のバッチを分散すると、各ノードは約 1,000 個のバッチで動作します。

データの並列トレーニングは、同期更新または非同期更新のいずれかで行うことができます。非同期更新を使用する場合、パラメータ サーバーは次の図に示すように各勾配ベクトルをワーカーノードの 1 つから受信した直後に、個別に適用します。

非同期更新によるデータの並列トレーニング。

一般的なデプロイでは、いくつかのパラメータ サーバーノード、単一のチーフ ワーカーノード、および複数のワーカーノードがあります。サービス API を使用してトレーニング ジョブを送信すると、これらのノードがプロジェクトに自動的にデプロイされます。

次の図は、Cloud ML Engine で分散トレーニング ジョブを実行し、Cloud Datalab を使用してトレーニングされたモデルで予測を実行するためのアーキテクチャを示しています。

チュートリアルで使用されるアーキテクチャ。

目標

  • Cloud ML Engine で分散 TensorFlow サンプルコードを実行します。
  • トレーニングされたモデルを Cloud ML Engine にデプロイして、予測用のカスタム API を作成します。
  • TensorBoard でトレーニング プロセスを可視化します。
  • Cloud Datalab を使用して予測をテストします。

料金

このチュートリアルでは、以下を含む、Cloud Platform の課金対象となるコンポーネントを使用しています。

  • Cloud ML Engine
  • Google Cloud Storage
  • Google Compute Engine
  • Compute Engine の永続ディスク

料金計算ツールでこのチュートリアルで発生する費用を計算すると、すべてのリソースを 1 日中使用した場合の費用はおおよそ $1.20 になります。

始める前に

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

  2. GCP プロジェクトを選択または作成します。

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

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

    課金を有効にする方法について

  4. Google Compute Engine と Cloud Machine Learning API を有効にします。

    APIを有効にする

Google Cloud SDK のコンポーネントの確認

  1. Cloud Shell に移動します。

    Cloud Shell を開く

  2. モデルのリストを表示します。このコマンドから空のリストが返されることを確認します。

    gcloud ml-engine models list
    

    このコマンドから空のリストが返されることを確認します。

    Listed 0 items.

Cloud ML Engine ですでに作業している場合は、アカウントに関連付けられているすべてのモデルのリストが表示されます。

サンプル ファイルのダウンロード

サンプル ファイルをダウンロードし、現在のディレクトリを設定します。

git clone https://github.com/GoogleCloudPlatform/cloudml-dist-mnist-example
cd cloudml-dist-mnist-example

MNIST ファイルの Cloud Storage バケットの作成

  1. モデルのトレーニングに使用される MNIST データファイルを格納する regional Cloud Storage バケットを作成します。

    PROJECT_ID=$(gcloud config list project --format "value(core.project)")
    BUCKET="${PROJECT_ID}-ml"
    gsutil mb -c regional -l us-central1 gs://${BUCKET}
    
  2. 次のスクリプトを使用して MNIST データファイルをダウンロードし、バケットにコピーします。

    ./scripts/create_records.py
    gsutil cp /tmp/data/train.tfrecords gs://${BUCKET}/data/
    gsutil cp /tmp/data/test.tfrecords gs://${BUCKET}/data/
    

Cloud Machine Learning Engine のモデルのトレーニング

  1. Cloud ML Engine にトレーニング ジョブを送信します。

    JOB_NAME="job_$(date +%Y%m%d_%H%M%S)"
    gcloud ml-engine jobs submit training ${JOB_NAME} \
        --package-path trainer \
        --module-name trainer.task \
        --staging-bucket gs://${BUCKET} \
        --job-dir gs://${BUCKET}/${JOB_NAME} \
        --runtime-version 1.2 \
        --region us-central1 \
        --config config/config.yaml \
        -- \
        --data_dir gs://${BUCKET}/data \
        --output_dir gs://${BUCKET}/${JOB_NAME} \
        --train_steps 10000
    

    --train_steps オプションはトレーニング バッチの総数を指定します。

    構成ファイル config/config.yamlスケール階層を指定することにより、トレーニング ジョブに割り当てられるリソースの量を制御できます。ジョブが複数のノードで実行されると、--package-path パラメータで指定されたトレーナー ディレクトリ内の同じ Python コードがすべてのノードにデプロイされます。トレーナー ディレクトリ内のファイルとその機能は、下の表に一覧表示されています。

    ファイル 説明
    setup.py 追加のモジュールをノードにインストールするためのセットアップ スクリプト。
    model.py 畳み込みニューラル ネットワーク モデルを定義する TensorFlow コード。
    task.py トレーニング タスクを実行する TensorFlow コード。この例では、Experiment API を使用してトレーニング グループを分散して実行しています。
  2. Google Cloud Platform Console で [ML Engine] ページを開き、実行中のジョブを見つけます。

    Cloud ML Engine を開く

  3. ジョブ ID をクリックすると、ログビューアへのリンクが表示されます。このコード例は、トレーニング中のログの進捗状況を示しています。たとえば、各ワーカーノードには、トレーニングの損失値が表示されます。これは、1 回のトレーニング バッチでのデータセットの損失総額を一定の間隔で表します。さらに、チーフ ワーカーノードは、テストセットの損失と精度を示します。トレーニングの最後に、テストセットに対する最終評価が表示されます。この例では、トレーニングはテストセットに対して 99.3% の精度を達成しました。

    Saving dict for global step 10008: accuracy = 0.9931, global_step = 10008, loss = 0.0315906
  4. トレーニング後、トレーニングされたモデルはストレージ バケットにエクスポートされます。次のコマンドを使用すると、モデルバイナリが含まれるディレクトリの格納パスを見つけることができます。

    gsutil ls gs://${BUCKET}/${JOB_NAME}/export/Servo | tail -1

    出力は次のようになります。

    gs://${BUCKET}/job_[TIMESTAMP]/export/Servo/[JOB_ID]/

TensorBoard によるトレーニング プロセスの可視化

トレーニング後、サマリーデータが gs://${BUCKET}/${JOB_NAME} に保存され、TensorBoard で可視化することができます。

  1. Cloud Shell で次のコマンドを実行し、TensorBoard を起動します。

    tensorboard --port 8080 --logdir gs://${BUCKET}/${JOB_NAME}
  2. 新しいブラウザ ウィンドウを開くには、Cloud Shell ツールバーの右上隅にある [ウェブでプレビュー] メニューから [ポート 8080 でプレビュー] を選択します。

  3. 新しいウィンドウでは、TensorBoard を使用して、トレーニングの概要と可視化されたネットワーク グラフを表示できます。Ctrl+C キーを押して、クラウドシェル内の TensorBoard を停止します。

    TensorBoard はトレーニングの概要とネットワーク グラフを表示します。

予測のためのトレーニングされたモデルのデプロイ

モデルバイナリを使用して、トレーニングされたモデルを予測用にデプロイします。

  1. モデルをデプロイし、デフォルトのバージョンを設定します。

    MODEL_NAME=MNIST
    gcloud ml-engine models create --regions us-central1 ${MODEL_NAME}
    VERSION_NAME=v1
    ORIGIN=$(gsutil ls gs://${BUCKET}/${JOB_NAME}/export/Servo | tail -1)
    gcloud ml-engine versions create \
        --origin ${ORIGIN} \
        --model ${MODEL_NAME} \
        ${VERSION_NAME}
    gcloud ml-engine versions set-default --model ${MODEL_NAME} ${VERSION_NAME}
    

    MODEL_NAMEVERSION_NAME は任意ですが、同じ名前を再利用することはできません。最初のバージョンが自動的にデフォルトになるため、最後のコマンドは不要です。デフォルトを明示的に設定することをおすすめします。

    デプロイされたモデルの準備が完了するまでに数分かかる場合があります。準備ができるまでは、リクエストに対して HTTP 503 エラーが返されます。

  2. サンプル リクエスト ファイルを使用して、予測 API をテストします。

    ./scripts/make_request.py

    このスクリプトは、予測用の 10 個のテスト イメージが含まれる JSON ファイル(request.json)を作成します。

  3. オンライン予測リクエストを送信します。

    gcloud ml-engine predict --model ${MODEL_NAME} --json-instances request.json

    次のようなレスポンスが得られるはずです。

    CLASSES  PROBABILITIES
    7        [3.437006127094938e-21, 5.562060376991084e-16, 2.5538862785511466e-19, 7.567420805782991e-17, 2.891652426709158e-16, 2.2750016241705544e-20, 1.837758172149778e-24, 1.0, 6.893573298530907e-19, 8.065571390565747e-15]
    2        [1.2471907477623206e-23, 2.291396136267388e-25, 1.0, 1.294716955176118e-32, 3.952643278911311e-25, 3.526924652059716e-36, 3.607279481567486e-25, 1.8093850397574458e-30, 7.008172489249426e-26, 2.6986217649454554e-29]
    ...
    9        [5.124952379488745e-22, 1.917571388490136e-20, 2.02434602684524e-21, 2.1246177460406675e-18, 1.8790316524963657e-11, 2.7904309518969085e-14, 7.973171243464317e-26, 6.233734909559877e-14, 9.224547341257772e-12, 1.0]
    

CLASSES は特定の画像の最も可能性の高い桁であり、PROBABILITIES は各桁の確率を示します。

Cloud Datalab での予測の実行

予測をテストするには、対話型の Jupyter Notebooks でコードを実行する Cloud Datalab インスタンスを作成します。

  1. Cloud Shell で次のコマンドを入力して、Cloud Datalab インスタンスを作成します。

    datalab create mnist-datalab --zone us-central1-a
  2. Cloud Shell から、[ウェブでプレビュー](右上の四角形のアイコン)をクリックして、Cloud Datalab ノートブックのリストページを起動できます。

  3. [Change port] を選択して [Port 8081] を選択し、ブラウザで新しいタブを開きます。

  4. Datalab アプリケーションでは、左上の [+Notebook] アイコンをクリックして新しいノートブックを作成します。

  5. 新しいノートブックの最初のセルに次のテキストを貼り付けます。

    %%bash
    wget https://raw.githubusercontent.com/GoogleCloudPlatform/cloudml-dist-mnist-example/master/notebooks/Online%20prediction%20example.ipynb
    cat Online\ prediction\ example.ipynb > Untitled\ Notebook.ipynb
    
  6. ページの上部にある [実行] コマンドをクリックして、Online prediction example.ipynb ノートブックをダウンロードし、その内容を現在のノートブックにコピーします。

  7. ブラウザのページを更新し、新しいノートブックのコンテンツを読み込みます。その後、JavaScript コードが含まれる最初のセルを選択し、[実行] コマンドをクリックして実行します。

  8. ページを下にスクロールして番号描画パネルを表示し、カーソルで番号を描画します。

    手描きの番号 3。

  9. 次のセルをクリックして有効にします。先頭の [Run] ボタンの横にある下矢印をクリックして、[Run from this Cell] を選択します。

  10. 予測の出力はクラスラベルと確率のリストを返します。クラスラベルは、入力した番号の予測を示します。確率のリストでは、0 から 9 までの各インデックスに数字が含まれています。値が 1 に近づくにつれ、入力した数字とインデックスが一致する可能性が高くなります。次の例では、リストにハイライト表示されている 3 番のスロットが 1 に非常に近いことがわかります。これに対応して、予測は 3 です。

    CLASSES
    3
    PROBABILITIES
    [4.181503356903704e-07,
    7.12400151314796e-07,
    0.00017898145597428083,
    0.9955494403839111,
    5.323939553103507e-11,
    0.004269002005457878,
    7.927398321116996e-11,
    1.2688398953741853e-07,
    1.0825967819982907e-06,
    2.2037748692582682e-07]
    
  11. ノートブックの最後のセルが棒グラフを描画するので、お客様の番号が予測されたことがわかります。

    棒グラフは 3 番目の棒を示しています。

クリーンアップ

このチュートリアルで使用するリソースについて、Google Cloud Platform アカウントに課金されないようにする手順は次のとおりです。

すべてのリソースを削除する最も簡単な方法は、このチュートリアルで作成したプロジェクトを削除することです。

  1. GCP Console で [プロジェクト] ページに移動します。

    プロジェクト ページに移動

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

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

TensorFlow 用 Cloud ML Engine