Cloud TPU(TF 2.x)での EfficientNet のトレーニング

このチュートリアルでは、tf.distribute.TPUStrategy を使用して Cloud TPU で Keras EfficientNet モデルをトレーニングする方法を説明します。

Cloud TPU に精通していない場合は、クイックスタートで Cloud TPU と Compute Engine VM の作成方法を確認することを強くおすすめします。

目標

  • データセットとモデルの出力を格納する Cloud Storage バケットを作成します。
  • ImageNet データセットに類似したフェイク ImageNet データセットを準備します。
  • トレーニング ジョブを実行します。
  • 出力結果を確認します。

費用

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

  • Compute Engine
  • Cloud TPU
  • クラウド ストレージ

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

始める前に

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

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

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

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

    [プロジェクトの選択] ページに移動

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

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

リソースを設定する

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

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

    Cloud Shell を開く

  2. プロジェクト ID の変数を作成します。

    export PROJECT_ID=project-id
    
  3. Cloud TPU を作成するプロジェクトを使用するように gcloud コマンドライン ツールを構成します。

    gcloud config set project ${PROJECT_ID}
    

    このコマンドを新しい Cloud Shell VM で初めて実行すると、Authorize Cloud Shell ページが表示されます。ページの下部にある [Authorize] をクリックして、gcloud に認証情報を使用した GCP API の呼び出しを許可します。

  4. Cloud TPU プロジェクトのサービス アカウントを作成します。

    gcloud beta services identity create --service tpu.googleapis.com --project $PROJECT_ID
    

    このコマンドでは、Cloud TPU サービス アカウントを次の形式で返します。

    service-PROJECT_NUMBER@cloud-tpu.iam.gserviceaccount.com
    

  5. 次のコマンドを使用して Cloud Storage バケットを作成します。

    gsutil mb -p ${PROJECT_ID} -c standard -l europe-west4 -b on gs://bucket-name/
    

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

    バケットのロケーションは、Compute Engine(VM)および Cloud TPU ノードと同じリージョンにする必要があります。

  6. Cloud Shell から、ctpu up コマンドを使用して Compute Engine VM リソースを起動します。

    $ ctpu up --project=${PROJECT_ID}} \
     --vm-only \
     --name=efficientnet-tutorial \
     --zone=europe-west4-a \
     --disk-size-gb=300 \
     --machine-type=n1-standard-16 \
     --tf-version=2.3.1
    

    コマンドフラグの説明

    project
    GCP プロジェクト ID
    name
    作成する Cloud TPU の名前。
    zone
    Cloud TPU を作成するゾーン
    disk-size-gb
    ctpu up コマンドで作成された VM のハードディスクのサイズ(GB)。
    machine-type
    作成する Compute Engine VM のマシンタイプ
    tf-version
    Tensorflow ctpu のバージョンが VM にインストールされます。

    ctpu ユーティリティの詳細については、CTPU リファレンスをご覧ください。

  7. プロンプトが表示されたら、y キーを押して Cloud TPU リソースを作成します。

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

    gcloud compute ssh efficientnet-tutorial --zone=europe-west4-a
    

Cloud Storage バケットの変数を設定する

次の環境変数を設定します。bucket-name を Cloud Storage バケットの名前に置き換えます。

(vm)$ export STORAGE_BUCKET=gs://bucket-name
(vm)$ export MODEL_DIR=${STORAGE_BUCKET}/efficientnet-2x
(vm)$ export DATA_DIR=gs://cloud-tpu-test-datasets/fake_imagenet

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

fake_imagenet を使用した EfficientNet モデルのトレーニングと評価

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

このチュートリアルでは、ImageNet の完全版のデータセットの fake_imagenet と呼ばれるデモバージョンを使用しています。このデモバージョンを使用すると、ストレージ容量と所要時間を ImageNet の完全版のデータセットに対してモデルを実行する際に通常必要となるものより抑えながらチュートリアルを試すことができます。

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

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

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

ImageNet データセット全体をダウンロードして処理する方法については、ImageNet データセットのダウンロード、前処理、アップロードをご覧ください。

  1. ctpu ユーティリティを使用して Cloud TPU リソースを起動します。

    (vm)$ ctpu up --project=${PROJECT_ID} \
     -tpu-only \
     --name=efficientnet-tutorial \
     --tpu-size=v3-8  \
     --zone=europe-west4-a \
     --tf-version=2.3.1
    

    コマンドフラグの説明

    project
    GCP プロジェクト ID
    tpu-only
    Cloud TPU のみを作成します。デフォルトでは、ctpu up コマンドは VM と Cloud TPU を作成します。
    name
    作成する Cloud TPU の名前。
    tpu-size
    作成する Cloud TPU のタイプ
    zone
    Cloud TPU を作成するゾーン
    tf-version
    Tensorflow ctpu のバージョンが VM にインストールされます。
  2. Cloud TPU 名の変数を設定します。これは、--name パラメータで ctpu up に指定した名前か、デフォルトのユーザー名になります。

    (vm)$ export TPU_NAME=efficientnet-tutorial
    
  3. EfficientNet トレーニング スクリプトには、追加のパッケージが必要です。この時点で、これらのパッケージをインストールしておきます。

    (vm)$ sudo pip3 install tensorflow-addons
    (vm)$ sudo pip3 install tensorflow-model-optimization>=0.1.3
    
  4. 次のコマンドを使用して、Python パスに最上位の /models フォルダを追加します。

    (vm)$ export PYTHONPATH="${PYTHONPATH}:/usr/share/models/"
    

    EfficientNet モデルは、Compute Engine VM にプリインストールされています。

  5. ディレクトリに移動します。

    (vm)$ cd /usr/share/models/official/vision/image_classification/
    
  6. トレーニング スクリプトを実行します。これは fake_imagenet データセットを使用し、EfficientNet を 1 エポック、トレーニングします。

    (vm)$ python3 classifier_trainer.py \
    --mode=train_and_eval \
    --model_type=efficientnet \
    --dataset=imagenet \
    --tpu=${TPU_NAME} \
    --data_dir=${DATA_DIR} \
    --model_dir=${MODEL_DIR} \
    --config_file=configs/examples/efficientnet/imagenet/efficientnet-b0-tpu.yaml \
    --params_override="train.epochs=1, train_dataset.builder=records, validation_dataset.builder=records"
    

    コマンドフラグの説明

    mode
    train_and_eval に設定すると、このスクリプトはモデルをトレーニングして評価します。export_only に設定すると、このスクリプトは保存されたモデルをエクスポートします。
    model_type
    モデルのタイプ(efficientnet など)。
    dataset
    データセットの名前。例: imagenet
    tpu
    TPU_NAME 環境変数で指定された名前を使用します。
    data_dir
    トレーニング入力用の Cloud Storage のパスを指定します。この例では、fake_imagenet データセットに設定されています。
    model_dir
    モデルのトレーニング中にチェックポイントとサマリーが保存されるディレクトリを指定します。該当するフォルダがない場合は、プログラムによって作成されます。Cloud TPU を使用する場合、model_dir を Cloud Storage パスにする必要があります(`gs://...`)。以前のチェックポイントが、同じサイズの Cloud TPU と TensorFlow バージョンを使用して作成されていれば、既存のフォルダを再利用して現在のチェックポイント データを読み込んで追加のチェックポイントを保存できます。
    config_file
    事前トレーニング済みの EfficientNet モデルを含む JSON ファイルへのパス。このファイルにはモデル アーキテクチャが含まれています。
    params_override
    デフォルトのスクリプト パラメータをオーバーライドする JSON 文字列。スクリプト パラメータの詳細については、/usr/share/models/official/vision/detection/main.py をご覧ください。

これにより、EfficientNet を 1 エポック トレーニングし、v3-8 Cloud TPU ノードでは 10 分未満で完了します。トレーニングが終了すると、次のような出力が表示されます。

I1107 20:28:57.561836 140033625347520 efficientnet_ctl_imagenet_main.py:222] Training 1 epochs, each epoch has 1251 steps, total steps: 1251; Eval 48 steps
I1107 20:34:09.638025 140033625347520 efficientnet_ctl_imagenet_main.py:358] Training loss: 0.6292637, accuracy: 0.99680257 at epoch 1
I1107 20:34:21.682796 140033625347520 efficientnet_ctl_imagenet_main.py:372] Test loss: 3.8977659, accuracy: 0.0% at epoch: 1
I1107 20:34:22.028973 140033625347520 efficientnet_ctl_imagenet_main.py:392]
Run stats:
{'train_loss': 0.6292637, 'train_acc': 0.99680257, 'eval_acc': 0.0, 'step_timestamp_log':
['BatchTimestamp < batch_index: 1, timestamp: 1573158554.11 >'],
'train_finish_time': 1573158861.683073, 'eval_loss': 3.8977659>}

収束するように EfficientNet をトレーニングするには、次のスクリプトに示すように 90 エポックで実行します。トレーニングと評価は一緒に行われます。合計 112,590 ステップ中、各エポックには、1,251 のトレーニング ステップと 48 の評価ステップがあります。

   (vm)$ python3 classifier_trainer.py \
     --mode=train_and_eval \
     --model_type=efficientnet \
     --dataset=imagenet \
     --tpu=${TPU_NAME} \
     --data_dir=${DATA_DIR} \
     --model_dir=${MODEL_DIR} \
     --config_file=configs/examples/efficientnet/imagenet/efficientnet-b0-tpu.yaml \
     --params_override="train_dataset.builder=records, validation_dataset.builder=records"

コマンドフラグの説明

mode
「train_and_eval」に設定すると、このスクリプトはモデルをトレーニングして評価します。「export_only」に設定すると、このスクリプトは保存されたモデルをエクスポートします。
model_type
モデルのタイプ(efficientnet など)。
dataset
データセットの名前。例: imagenet
tpu
TPU_NAME 変数で指定された名前を使用します。
data_dir
トレーニング入力用の Cloud Storage のパスを指定します。この例では、fake_imagenet データセットに設定されています。
model_dir
モデルのトレーニング中にチェックポイントとサマリーが保存されるディレクトリを指定します。フォルダが見つからない場合は、スクリプトによって作成されます。Cloud TPU を使用する場合、model_dir を Cloud Storage パスにする必要があります(`gs://...`)。以前のチェックポイントが、同じサイズの Cloud TPU と TensorFlow バージョンを使用して作成されていれば、既存のフォルダを再利用して現在のチェックポイント データを読み込んで追加のチェックポイントを保存できます。
config_file
事前トレーニング済みの EfficientNet モデルを含む JSON ファイルへのパス。このファイルにはモデル アーキテクチャが含まれています。
params_override
デフォルトのスクリプト パラメータをオーバーライドする JSON 文字列。スクリプト パラメータの詳細については、/usr/share/models/official/vision/detection/main.py をご覧ください。

トレーニングと評価は fake_imagenet データセットに対して行われているため、出力結果には、実際のデータセットでトレーニングと評価を行った場合の出力は反映されません。

この時点で、このチュートリアルを終了して、GCP リソースをクリーンアップすることも、Cloud TPU Pod でのモデルの実行をさらに詳しく調べることもできます。

Cloud TPU Pod を使用してモデルをスケーリングする

Cloud TPU Pod を使用してモデルをスケーリングすると、より迅速に結果を得ることができます。完全にサポートされている EfficientNet モデルは、次の Pod スライスを使用できます。

  • v2-32
  • v3-32

Cloud TPU Pod では、トレーニングと評価が同時に行われます。

Cloud TPU Pod を使用したトレーニング

  1. 単一のデバイスでモデルをトレーニングするために作成した Cloud TPU リソースを削除します。

    (vm)$ ctpu delete --project=${PROJECT_ID} \
     --tpu-only \
     --name=efficientnet-tutorial \
     --zone=europe-west4-a
  2. 使用する Pod スライスを指定するための tpu-sizeパラメータを使用して、ctpu up コマンドを実行します。たとえば、次のコマンドは v3-32 の Pod スライスを使用します。

    (vm)$ ctpu up --project=${PROJECT_ID} \
      --tpu-only \
      --name=efficientnet-tutorial \
      --zone=europe-west4-a \
      --tpu-size=v3-32 \
      --tf-version=2.3.1
    

    コマンドフラグの説明

    project
    GCP プロジェクト ID
    tpu-only
    Cloud TPU のみを作成します。デフォルトでは、ctpu up コマンドは VM と Cloud TPU を作成します。
    name
    作成する Cloud TPU の名前。
    zone
    Cloud TPU を作成するゾーン
    tpu-size
    作成する Cloud TPU のタイプ
    tf-version
    Tensorflow ctpu のバージョンが VM にインストールされます。
    gcloud compute ssh efficientnet-tutorial --zone=europe-west4-a
    
  3. MODEL_DIR ディレクトリを更新して、Cloud TPU Pod のトレーニング データを保存します。

    (vm)$ export MODEL_DIR=${STORAGE_BUCKET}/efficientnet-2x-pod
    
  4. Cloud TPU 名を定義します。

    (vm)$ export TPU_NAME=efficientnet-tutorial
    
  5. ディレクトリに移動します。

    (vm)$ cd /usr/share/models/official/vision/image_classification/
    
  6. モデルをトレーニングします。

    (vm)$ python3 classifier_trainer.py \
    --mode=train_and_eval \
    --model_type=efficientnet \
    --dataset=imagenet \
    --tpu=${TPU_NAME} \
    --data_dir=${DATA_DIR} \
    --model_dir=${MODEL_DIR} \
    --config_file=configs/examples/efficientnet/imagenet/efficientnet-b0-tpu.yaml \
    --params_override="train.epochs=1, train_dataset.builder=records, validation_dataset.builder=records"
    

    コマンドフラグの説明

    mode
    train_and_eval に設定すると、このスクリプトはモデルをトレーニングして評価します。export_only に設定すると、このスクリプトは保存されたモデルをエクスポートします。
    model_type
    モデルのタイプ(efficientnet など)。
    dataset
    データセットの名前。例: imagenet
    tpu
    TPU_NAME 変数で指定された名前を使用します。
    data_dir
    トレーニング入力用の Cloud Storage のパスを指定します。この例では、fake_imagenet データセットに設定されています。
    model_dir
    モデルのトレーニングの際にチェックポイントとサマリーが保存されるディレクトリを指定します。フォルダが見つからない場合は、スクリプトによって作成されます。Cloud TPU を使用する場合、model_dir を Cloud Storage パスにする必要があります(`gs://...`)。以前のチェックポイントが、同じサイズの Cloud TPU と TensorFlow バージョンを使用して作成されていれば、既存のフォルダを再利用して現在のチェックポイント データを読み込んで追加のチェックポイントを保存できます。
    config_file
    事前トレーニング済みの EfficientNet モデルを含む JSON ファイルへのパス。このファイルにはモデル アーキテクチャが含まれています。
    params_override
    デフォルトのスクリプト パラメータをオーバーライドする JSON 文字列。スクリプト パラメータの詳細については、/usr/share/models/official/vision/detection/main.py をご覧ください。

この手順は、fake_imagnet データセットに対してモデルを 1 エポックまでトレーニング(合計 312 トレーニング ステップ、12 評価ステップ)します。このトレーニングは、v3-32 Cloud TPU 上で約 2 分かかります。トレーニングと評価が完了すると、次のようなメッセージが表示されます。

1107 22:45:19.821746 140317155378624 efficientnet_ctl_imagenet_main.py:358] Training loss: 0.22576721, accuracy: 0.838141 at epoch 1
I1107 22:45:33.892045 140317155378624 efficientnet_ctl_imagenet_main.py:372] Test loss: 0.26673648, accuracy: 0.0% at epoch: 1
I1107 22:45:34.851322 140317155378624 efficientnet_ctl_imagenet_main.py:392] Run stats:
{'train_loss': 0.22576721, 'train_acc': 0.838141, 'eval_acc': 0.0, 'step_timestamp_log': ['BatchTimestamp <batch_index: 1, timestamp: 1573166574.67>'], 'train_finish_time': 1573166733.892282, 'eval_loss': 0.26673648}

クリーンアップ

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

  1. Compute Engine インスタンスとの接続を切断していない場合は切断します。

    (vm)$ exit
    

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

  2. Cloud Shell で次のコマンドを使用して、Compute Engine VM と Cloud TPU を削除します。

    $ ctpu delete --project=${PROJECT_ID} \
      --name=efficientnet-tutorial \
      --zone=europe-west4-a
    
  3. TPU の使用に対して不要な料金が発生しないように、ctpu status を実行してインスタンスが割り当てられていないことを確認します。削除には数分かかることがあります。次のようなレスポンスは、割り当てられたインスタンスがないことを示します。

    $ ctpu status --project=${PROJECT_ID} \
      --name=efficientnet-tutorial \
      --zone=europe-west4-a
    
    2018/04/28 16:16:23 WARNING: Setting zone to "europe-west4-a"
    No instances currently exist.
            Compute Engine VM:     --
            Cloud TPU:             --
    
  4. 次に示すように gsutil を実行します。bucket-name の部分は、このチュートリアルで作成した Cloud Storage バケット名に置き換えてください。

    $ gsutil rm -r gs://bucket-name
    

次のステップ

このチュートリアルでは、サンプル データセットを使用して EfficientNet モデルをトレーニングしました。このトレーニングの結果は(ほとんどの場合)推論には使用できません。推論にモデルを使用するには、一般公開されているデータセットまたは独自のデータセットでデータをトレーニングします。Cloud TPU でトレーニングされたモデルでは、データセットを TFRecord 形式にする必要があります。

データセット変換ツールのサンプルを使用して、画像分類データセットを TFRecord 形式に変換できます。画像分類モデルを使用しない場合は、自分でデータセットを TFRecord 形式に変換する必要があります。詳細については、TFRecord と tf.Example をご覧ください。

ハイパーパラメータ調整

データセットでモデルのパフォーマンスを向上させるには、モデルのハイパーパラメータを調整します。すべての TPU でサポートされているモデルに共通のハイパーパラメータに関する情報については、GitHub をご覧ください。モデルに固有のハイパーパラメータに関する情報については、各モデルのソースコードで確認できます。ハイパーパラメータ調整の詳細については、ハイパーパラメータ調整の概要ハイパーパラメータ調整サービスの使用ハイパーパラメータを調整するをご覧ください。

推論

モデルをトレーニングしたら、そのモデルを推論(予測)に使用できます。AI Platform は、機械学習モデルを開発、トレーニングデプロイするためのクラウドベースのソリューションです。モデルをデプロイすれば、AI Platform Prediction サービスを使用できるようになります。

  • データセット変換チュートリアルに従って、fake_imagenet データセットまたは ImageNet データセットの代わりに独自のデータを使用してトレーニングと評価を行う方法を学習します。 このチュートリアルでは、画像分類データ変換プログラムのサンプル スクリプトを使用して、画像分類用の生のデータセットを Cloud TPU Tensorflow モデルで使用される TFRecord に変換する方法について説明します。

  • 独自の画像データを使用して画像分類モデルを実行する方法を示す Cloud TPU colab を実行します。

  • 他の Cloud TPU チュートリアルを確認する。

  • TensorBoard の TPU モニタリング ツールの使用方法を学習する。