Cloud TPU で Inception を実行する

このチュートリアルでは、Cloud TPU で Inception モデルをトレーニングする方法について説明します。

免責

このチュートリアルでは、サードパーティのデータセットを使用します。Google は、このデータセットの有効性またはその他の側面について、いかなる表明、保証もいたしません。

モデルの説明

Inception v3 は、広く使用されている画像認識モデルで、高い精度を達成できます。このモデルは、長年にわたって複数の研究者によって開発された多くのアイデアが結実したもので、Szegedy 氏他の『Rethinking the Inception Architecture for Computer Vision』という論文をベースにしています。

このモデルには、次のようなさまざまなビルディング ブロックが含まれています。これらには対称のものもあれば、非対称のものもあります。

  • 畳み込み
  • 平均プーリング
  • 最大プーリング
  • 連結
  • ドロップアウト
  • 全結合層

損失は Softmax によって計算されます。

次の図は、モデルの概要を示しています。

画像

このモデルの詳細については、GitHub をご覧ください。

このモデルは、高レベルな Estimator API を使用して作成されています。

この API は、低レベルの関数のほとんどをカプセル化することでモデル作成を大幅に簡素化します。これにより、ユーザーは、操作を実行する基礎となるハードウェアの内部構造ではなく、モデル開発に集中できます。

始める前に

このチュートリアルを開始する前に、Google Cloud Platform プロジェクトが正しく設定されていることを確認してください。

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

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

  2. GCP Console のプロジェクト セレクタのページで、GCP プロジェクトを選択または作成します。

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

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

  4. このチュートリアルでは、Google Cloud Platform の課金対象となるコンポーネントを使用します。費用を見積もるには、Cloud TPU の料金ページを確認してください。不要な課金を回避できるよう、このチュートリアルを完了したら、作成したリソースを必ずクリーンアップしてください。

リソースを設定する

このセクションでは、チュートリアルで使用する Cloud Storage のストレージ、VM、Cloud TPU の各リソースを設定する方法を説明します。

Cloud Storage バケットを作成する

モデルのトレーニングに使用するデータとトレーニング結果を格納するには、Cloud Storage バケットが必要です。このチュートリアルで使用する ctpu up ツールは、Cloud TPU サービス アカウントのデフォルトの権限を設定します。権限の詳細な設定が必要な場合は、アクセスレベル権限をご覧ください。

バケットのロケーションは、仮想マシン(VM)および TPU ノードと同じリージョンにする必要があります。VM と TPU ノードは、リージョン内のサブディビジョンである特定のゾーンに配置されます。

  1. GCP Console の Cloud Storage ページに移動します。

    Cloud Storage ページに移動

  2. 次のオプションを指定して新しいバケットを作成します。

    • 任意の一意な名前
    • デフォルトのストレージ クラス: Standard
    • ロケーション: TPU ノードを作成する予定のリージョンと同じリージョンにバケットのロケーションを指定します。各種の TPU タイプをどこで使用できるかについては、TPU タイプとゾーンをご覧ください。

ctpu ツールを使用する

このセクションでは、Cloud TPU プロビジョニング ツールctpu)を使用して Cloud TPU プロジェクトのリソースを作成、管理する方法を説明します。リソースは、同じ名前が付けられた仮想マシン(VM)と Cloud TPU リソースで構成されます。これらのリソースは、作成したバケットと同じリージョン / ゾーンに存在する必要があります。

VM リソースと TPU リソースを設定するには、gcloud コマンドまたは Cloud Console を使用することもできます。Compute Engine VM と Cloud TPU リソースの設定から管理までのすべての手順については、TPU の作成と削除ページをご覧ください。

ctpu up を実行してリソースを作成する

  1. Cloud Shell ウィンドウを開きます。

    Cloud Shell を開く

  2. gcloud config set project <Your-Project> を実行して Cloud TPU を作成するプロジェクトを使用するよう設定します。

  3. Cloud TPU デバイスまたは Pod スライスのいずれかを示すフラグを指定して ctpu up を実行します。フラグのオプションと説明については、CTPU リファレンスをご覧ください。

  4. Cloud TPU デバイスを設定します。

    $ ctpu up 

    構成に関する次のメッセージが表示されます。

    ctpu will use the following configuration:
    
    Name: [your TPU's name]
    Zone: [your project's zone]
    GCP Project: [your project's name]
    TensorFlow Version: 1.14
    VM:
     Machine Type: [your machine type]
     Disk Size: [your disk size]
     Preemptible: [true or false]
    Cloud TPU:
     Size: [your TPU size]
     Preemptible: [true or false]
    
    OK to create your Cloud TPU resources with the above configuration? [Yn]:
    

    y キーを押して、Cloud TPU リソースを作成します。

ctpu up コマンドにより、仮想マシン(VM)と Cloud TPU サービスが作成されます。

これ以降、接頭辞 (vm)$ は Compute Engine VM インスタンスでコマンドを実行する必要があることを意味します。

Compute Engine VM を確認する

ctpu up コマンドの実行が終了したら、shell プロンプトが username@project から username@tpuname に変更されたことを確認します。変更されていれば、Compute Engine VM にログインしていることになります。

データを取得する

次の環境変数を設定します。YOUR-BUCKET-NAME は、Cloud Storage バケットの名前に置き換えます。

(vm)$ export STORAGE_BUCKET=gs://YOUR-BUCKET-NAME

トレーニング アプリケーションでは、Cloud Storage でトレーニング データにアクセスできる必要があります。また、トレーニング アプリケーションは、Cloud Storage バケットを使用してトレーニング中にチェックポイントを保存します。

トレーニング データセット

ImageNet は画像データベースです。このデータベース内では画像が階層に編成されていて、階層の各ノードを数百、数千もの画像で表しています。

このチュートリアルでは、「fake_imagenet」データセットと呼ばれる、ImageNet の完全版のデータセットのデモバージョンを使用します。このデモバージョンを使用すると、完全版の ImageNet のデータベースをダウンロードしてモデルを実行するために必要となるストレージと時間を確保しなくても、チュートリアルを試すことができます。ランダムに生成された fake_imagenet データセットを使用してモデルをテストする手順を以下に示します。または、完全版の ImageNet のデータセットを使用することもできます。

トレーニング対象のデータセットを指定するには、以下で説明する DATA_DIR 環境変数を使用します。

fake_imagenet データセットは、Cloud TPU の使用方法を理解し、エンドツーエンドのパフォーマンスを検証する場合にのみ役立ちます。精度の数値と保存されたモデルは意味がありません。

fake_imagenet データセットは Cloud Storage の次のロケーションにあります。

gs://cloud-tpu-test-datasets/fake_imagenet

(省略可)TensorBoard をセットアップする

TensorBoard には、TensorFlow データを視覚的に表示するための一連のツールが用意されています。モニタリングに使用することで、処理のボトルネックを特定し、パフォーマンスの改善方法を探る際に役立ちます。

この時点でモデルの出力をモニタリングする必要がない場合は、TensorBoard の設定手順をスキップできます。

モデルの出力とパフォーマンスをモニタリングする場合は、TensorBoard の設定に関するガイドをご覧ください。

モデルを実行する

これで、ImageNet データを使用して Inception v3 モデルをトレーニングおよび評価する準備ができました。

Inception v3 モデルは、Compute Engine VM の /usr/share/tpu/models/experimental/inception/ ディレクトリにプリインストールされています。

次の手順で、コマンドに接頭辞 (vm)$ が含まれている場合、そのコマンドは Compute Engine VM で実行する必要があります。

  1. 次のいずれかの値を格納する環境変数 DATA_DIR を設定します。

    • fake_imagenet データセットを使用している場合:

      (vm)$ export DATA_DIR=gs://cloud-tpu-test-datasets/fake_imagenet
      
    • Cloud Storage バケットに一連のトレーニング データをアップロードした場合:

      (vm)$ export DATA_DIR=${STORAGE_BUCKET}/data
      
  2. Inception v3 モデルを実行します。

    (vm)$ python /usr/share/tpu/models/experimental/inception/inception_v3.py \
        --tpu=$TPU_NAME \
        --learning_rate=0.165 \
        --train_steps=250000 \
        --iterations=500 \
        --use_tpu=True \
        --use_data=real \
        --mode=train_and_eval \
        --train_steps_per_eval=2000 \
        --data_dir=${DATA_DIR} \
        --model_dir=${STORAGE_BUCKET}/inception
    • --tpu は、Cloud TPU の名前を指定します。ctpu は、この名前を環境変数(TPU_NAME)として Compute Engine VM に渡します。
    • --use_data は、トレーニング中に使用する必要があるデータの種類(fake または real)を指定します。デフォルト値は fake です。
    • --data_dir は、トレーニング入力用の Cloud Storage のパスを指定します。fake_imagenet データを使用している場合、このパラメータは無視されます。
    • --model_dir は、モデルのトレーニングの際にチェックポイントとサマリーが保存されるディレクトリを指定します。フォルダがない場合は、プログラムによって作成されます。Cloud TPU を使用する場合、model_dir は Cloud Storage のパスである必要があります(gs://...)。以前に作成されたチェックポイントの TPU のサイズと TensorFlow のバージョンが同じであれば、既存のフォルダを再利用して現在のチェックポイント データを読み込み、追加のチェックポイントを保存できます。

期待される動作

Inception v3 は 299x299 の画像で動作します。デフォルトのトレーニングのバッチサイズは 1,024 です。つまり、各イテレーションはこれらの画像 1,024 枚に対して行われます。

--mode フラグを使用して、3 つのオペレーション モード(train、eval、train_and_eval)のいずれかを選択できます。

  • --mode=train または --mode=eval は、トレーニングのみ、または評価のみのジョブを指定します。
  • --mode=train_and_eval は、トレーニングと評価の両方を行うハイブリッド ジョブを指定します。

トレーニングのみのジョブは、train_steps で定義された指定のステップ数に対して実行され、必要に応じてトレーニング セット全体を処理できます。

train_and_eval のジョブは、トレーニングと評価のセグメントを繰り返し処理します。各トレーニング サイクルは train_steps_per_eval に対して実行され、その後に評価ジョブ(そのポイントまでトレーニングされた重みを使用)が続きます。

トレーニング サイクル数は、floor 関数(train_stepstrain_steps_per_eval で除算)で定義されます。

floor(train_steps / train_steps_per_eval)

デフォルトでは、Estimator API ベースモデルは一定のステップ数ごとに損失値をレポートします。レポート形式は、次のようになります。

step = 15440, loss = 12.6237

説明: このモデルに対する TPU 固有の変更

TPU 用の Estimator API ベースモデルを取得するために必要な固有の変更は、ごくわずかです。次のライブラリが自動的にインポートされます。

from google.third_party.tensorflow.contrib.tpu.python.tpu import tpu_config
from google.third_party.tensorflow.contrib.tpu.python.tpu import tpu_estimator
from google.third_party.tensorflow.contrib.tpu.python.tpu import tpu_optimizer

CrossShardOptimizer 関数は、次のようにオプティマイザーをラップします。

if FLAGS.use_tpu:
  optimizer = tpu_optimizer.CrossShardOptimizer(optimizer)

モデルを定義する関数は、以下を使用して Estimator の仕様を返します。

return tpu_estimator.TPUEstimatorSpec(
    mode=mode, loss=loss, train_op=train_op, eval_metrics=eval_metrics)

main 関数は、以下を使用して Estimator と互換性のある構成を定義します。

run_config = tpu_config.RunConfig(
    master=tpu_grpc_url,
    evaluation_master=tpu_grpc_url,
    model_dir=FLAGS.model_dir,
    save_checkpoints_secs=FLAGS.save_checkpoints_secs,
    save_summary_steps=FLAGS.save_summary_steps,
    session_config=tf.ConfigProto(
        allow_soft_placement=True,
        log_device_placement=FLAGS.log_device_placement),
    tpu_config=tpu_config.TPUConfig(
        iterations_per_loop=iterations,
        num_shards=FLAGS.num_shards,
        per_host_input_for_training=per_host_input_for_training))

プログラムは、この定義された構成とモデル定義関数を使用して Estimator オブジェクトを作成します。

inception_classifier = tpu_estimator.TPUEstimator(
    model_fn=inception_model_fn,
    use_tpu=FLAGS.use_tpu,
    config=run_config,
    params=params,
    train_batch_size=FLAGS.train_batch_size,
    eval_batch_size=eval_batch_size,
    batch_axis=(batch_axis, 0))

トレーニングのみのジョブは、train 関数の呼び出しのみを行います。

inception_classifier.train(
    input_fn=imagenet_train.input_fn, steps=FLAGS.train_steps)

評価のみのジョブは、使用可能なチェックポイントからデータを取得して、新しいチェックポイントが使用可能になるまで待機します。

for checkpoint in get_next_checkpoint():
  eval_results = inception_classifier.evaluate(
      input_fn=imagenet_eval.input_fn,
      steps=eval_steps,
      hooks=eval_hooks,
      checkpoint_path=checkpoint)

オプション train_and_eval を選択すると、トレーニング ジョブと評価ジョブが並列処理されます。評価の際は、利用可能な最新のチェックポイントからトレーニング可能な変数が読み込まれます。トレーニングと評価のサイクルは、フラグでの指定に従って反復されます。

for cycle in range(FLAGS.train_steps // FLAGS.train_steps_per_eval):
  inception_classifier.train(
      input_fn=imagenet_train.input_fn, steps=FLAGS.train_steps_per_eval)

  eval_results = inception_classifier.evaluate(
      input_fn=imagenet_eval.input_fn, steps=eval_steps, hooks=eval_hooks)

fake_imagenet を使用してモデルをトレーニングした場合は、クリーンアップに進みます。

完全版の ImageNet データセットの使用

容量の要件を確認する

ImageNet の完全版のデータセットを使用するには、ローカルマシンまたは VM に約 300 GB の空き容量が必要です。

VM ディスクのサイズは、次のいずれかの方法で増やすことができます。

  • ctpu up コマンドラインで、割り当てるサイズ(GB 単位)を設定した --disk-size-gb フラグを指定します。
  • Compute Engine ガイドに従って、VM にディスクを追加します。
    • VM を削除する際にディスクが削除されるように、[インスタンスを削除したときの動作] を [ディスクを削除] に設定します。
    • 新しいディスクのパスをメモします。例: /mnt/disks/mnt-dir

ImageNet データをダウンロードして変換する

  1. ImageNet アカウントに登録します。アカウントの作成に使用したユーザー名とパスワードを覚えておいてください。

  2. Cloud Storage バケットのパスを指す DATA_DIR 環境変数を設定します。

    (vm)$ export DATA_DIR=gs://storage-bucket
    
  3. GitHub から imagenet_to_gcs.py スクリプトをダウンロードします。

    $ wget https://raw.githubusercontent.com/tensorflow/tpu/master/tools/datasets/imagenet_to_gcs.py
    
  4. スクリプトの作業ファイルを含むように SCRATCH_DIR 変数を設定します。この変数で、ローカルマシン上または Compute Engine VM 上の場所を指定する必要があります。たとえば、ローカルマシン上の場所は次のように指定します。

    $ SCRATCH_DIR=./imagenet_tmp_files
    

    また、VM でデータを処理している場合は次のようにします。

    (vm)$ SCRATCH_DIR=/mnt/disks/mnt-dir/imagenet_tmp_files
    
  5. imagenet_to_gcs.py スクリプトを実行して ImageNet データをダウンロードし、フォーマットしてバケットにアップロードします。[USERNAME][PASSWORD] は、ImageNet アカウントの作成に使用したユーザー名とパスワードに置き換えます。

    $ pip install google-cloud-storage
    $ python imagenet_to_gcs.py \
      --project=$PROJECT \
      --gcs_output_path=$DATA_DIR \
      --local_scratch_dir=$SCRATCH_DIR \
      --imagenet_username=[USERNAME] \
      --imagenet_access_key=[PASSWORD]
    

JPEG 形式の元データがすでにダウンロードされている場合は、必要に応じて、直接 raw_data_directory パスを指定できます。トレーニング用または検証データ用の元データのディレクトリが提供されている場合は、次の形式になります。

トレーニング サブディレクトリ名(例: n03062245)は「WordNet ID」(wnid)です。ImageNet API は、synset_labels.txt ファイル内の WordNet ID とそれに関連する検証ラベルとのマッピングを示します。このコンテキストの synset は、視覚的に似たグループの画像です。

: ネットワークとパソコンの速度によっては、データのダウンロードと前処理に 10 時間以上かかることがあります。スクリプトを中断しないでください。

スクリプトの処理が終了すると、次のようなメッセージが表示されます。

2018-02-17 14:30:17.287989: Finished writing all 1281167 images in data set.

このスクリプトにより、以下の形式の一連のディレクトリ(トレーニング用と検証用の両方)が生成されます。

${DATA_DIR}/train-00000-of-01024
${DATA_DIR}/train-00001-of-01024
 ...
${DATA_DIR}/train-01023-of-01024

および

${DATA_DIR}/validation-00000-of-00128
S{DATA_DIR}/validation-00001-of-00128
 ...
${DATA_DIR}/validation-00127-of-00128

Cloud バケットにデータがアップロードされたら、モデルを実行して --data_dir=${DATA_DIR} を設定します。

クリーンアップ

このトピックで使用したリソースについて GCP アカウントに課金されないようにする手順は次のとおりです。

  1. Compute Engine VM との接続を解除します。

    (vm)$ exit
    

    プロンプトが user@projectname に変わります。これは、現在、Cloud Shell 内にいることを示しています。

  2. Cloud Shell で、Cloud TPU の設定時に使用した --zone フラグを指定して ctpu delete を実行し、Compute Engine VM と Cloud TPU を削除します。

    $ ctpu delete [optional: --zone]
    
  3. TPU の使用に対して不要な料金が発生しないように、ctpu status を実行してインスタンスが割り当てられていないことを確認します。削除には数分かかることがあります。 次のようなレスポンスは、割り当てられたインスタンスがないことを示します。

    2018/04/28 16:16:23 WARNING: Setting zone to "us-central1-b"
    No instances currently exist.
            Compute Engine VM:     --
            Cloud TPU:             --
    
  4. 次に示すように gsutil を実行します。YOUR-BUCKET-NAME の部分は、このチュートリアルで作成した Cloud Storage バケット名に置き換えてください。

    $ gsutil rm -r gs://YOUR-BUCKET-NAME
    

Inception v4

Inception v4 モデルは、Inception v3 のビルディング ブロックを使用するディープ ニューラル ネットワーク モデルで、Inception v3 よりも高い精度を実現します。これは、Szegedy 氏他の論文『Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning』で説明されています。

Inception v4 モデルは、Compute Engine VM の /usr/share/tpu/models/experimental/inception/ ディレクトリにプリインストールされています。

次の手順で、コマンドに接頭辞 (vm)$ が含まれている場合、そのコマンドは Compute Engine VM で実行する必要があります。

  1. Cloud Shell のタブで TensorBoard を実行している場合は、作業する別のタブが必要です。Cloud Shell で別のタブを開き、新しい Shell で ctpu を使用して Compute Engine VM に接続します。

    $ ctpu up
  2. 次のいずれかの値を格納する環境変数 DATA_DIR を設定します。

    • fake_imagenet データセットを使用している場合:

      (vm)$ export DATA_DIR=gs://cloud-tpu-test-datasets/fake_imagenet
      
    • Cloud Storage バケットに一連のトレーニング データをアップロードした場合:

      (vm)$ export DATA_DIR=${STORAGE_BUCKET}/data
      
  3. Inception v4 モデルを実行します。

    (vm)$ python /usr/share/tpu/models/experimental/inception/inception_v4.py \
        --tpu=$TPU_NAME \
        --learning_rate=0.36 \
        --train_steps=1000000 \
        --iterations=500 \
        --use_tpu=True \
        --use_data=real \
        --train_batch_size=256 \
        --mode=train_and_eval \
        --train_steps_per_eval=2000 \
        --data_dir=${DATA_DIR} \
        --model_dir=${STORAGE_BUCKET}/inception
    • --tpu は、Cloud TPU の名前を指定します。ctpu は、この名前を環境変数(TPU_NAME)として Compute Engine VM に渡します。
    • --use_data は、トレーニング中に使用する必要があるデータの種類(fake または real)を指定します。デフォルト値は fake です。
    • --train_batch_size は、トレーニングのバッチサイズを 256 に指定します。Inception v4 モデルは Inception v3 よりも大きいため、TPU コアごとのバッチサイズを小さくして実行する必要があります。
    • --data_dir は、トレーニング入力用の Cloud Storage のパスを指定します。fake_imagenet データを使用している場合、このパラメータは無視されます。
    • --model_dir は、モデルのトレーニングの際にチェックポイントとサマリーが保存されるディレクトリを指定します。フォルダがない場合は、プログラムによって作成されます。Cloud TPU を使用する場合、model_dir は Cloud Storage のパスである必要があります(gs://...)。以前に作成されたチェックポイントの TPU のサイズと TensorFlow のバージョンが同じであれば、既存のフォルダを再利用して現在のチェックポイント データを読み込み、追加のチェックポイントを保存できます。

次のステップ

  • Cloud TPU における Inception v3 の詳細を学習する。
  • ローカルマシンへのインストール方法など、ctpu の詳細を学習する。
  • TensorBoard の TPU ツールを確認する。