CloudTuner を使用した Google Cloud での HP チューニング

TensorFlow.org で見る GitHub で見るノートブックをダウンロードKaggleのロゴKaggle で実行する

この例は、 Keras-Tuner CIFAR10 サンプルに基づいており、 TensorFlow Cloudと Google Cloud Platform を使用して HP チューニング ジョブを大規模に実行する方法を示しています。

必要なモジュールをインポートする

import datetime
import uuid

import numpy as np
import pandas as pd
import tensorflow as tf
import os
import sys
import subprocess

from tensorflow.keras import datasets, layers, models
from sklearn.model_selection import train_test_split


! pip install -q tensorflow-cloud
import tensorflow_cloud as tfc
tf.version.VERSION
'2.6.0'

プロジェクト構成

プロジェクト パラメータの設定 Google Cloud 固有のパラメータについては、「Google Cloud プロジェクトのセットアップ手順」を参照してください。

# Set Google Cloud Specific parameters

# TODO: Please set GCP_PROJECT_ID to your own Google Cloud project ID.
GCP_PROJECT_ID = 'YOUR_PROJECT_ID' 

# TODO: Change the Service Account Name to your own Service Account
SERVICE_ACCOUNT_NAME = 'YOUR_SERVICE_ACCOUNT_NAME'
SERVICE_ACCOUNT = f'{SERVICE_ACCOUNT_NAME}@{GCP_PROJECT_ID}.iam.gserviceaccount.com'

# TODO: set GCS_BUCKET to your own Google Cloud Storage (GCS) bucket.
GCS_BUCKET = 'YOUR_GCS_BUCKET_NAME'

# DO NOT CHANGE: Currently only the 'us-central1' region is supported.
REGION = 'us-central1'
# Set Tuning Specific parameters

# OPTIONAL: You can change the job name to any string.
JOB_NAME = 'cifar10'

# OPTIONAL:  Set Number of concurrent tuning jobs that you would like to run.
NUM_JOBS = 5

# TODO: Set the study ID for this run. Study_ID can be any unique string.
# Reusing the same Study_ID will cause the Tuner to continue tuning the
# Same Study parameters. This can be used to continue on a terminated job,
# or load stats from a previous study.
STUDY_NUMBER = '00001'
STUDY_ID = f'{GCP_PROJECT_ID}_{JOB_NAME}_{STUDY_NUMBER}'

# Setting location were training logs and checkpoints will be stored
GCS_BASE_PATH = f'gs://{GCS_BUCKET}/{JOB_NAME}/{STUDY_ID}'
TENSORBOARD_LOGS_DIR = os.path.join(GCS_BASE_PATH,"logs")

Google Cloud プロジェクトを使用するためのノートブックの認証

Kaggle ノートブックの場合は、下のセルを実行する前に、[アドオン] -> [Google Cloud SDK] をクリックします。

# Using tfc.remote() to ensure this code only runs in notebook
if not tfc.remote():

    # Authentication for Kaggle Notebooks
    if "kaggle_secrets" in sys.modules:
        from kaggle_secrets import UserSecretsClient
        UserSecretsClient().set_gcloud_credentials(project=GCP_PROJECT_ID)

    # Authentication for Colab Notebooks
    if "google.colab" in sys.modules:
        from google.colab import auth
        auth.authenticate_user()
        os.environ["GOOGLE_CLOUD_PROJECT"] = GCP_PROJECT_ID

データをロードして準備する

生データを読み取り、データセットをトレーニングおよびテストするために分割します。

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()

# Setting input specific parameters
# The model expects input of dimensions (INPUT_IMG_SIZE, INPUT_IMG_SIZE, 3)
INPUT_IMG_SIZE = 32
NUM_CLASSES = 10

モデルのアーキテクチャとハイパーパラメータを定義する

このセクションでは、 Keras Tuner Hyper Parametersとモデル構築関数を使用して調整パラメーターを定義します。モデル構築関数は引数 hp を受け取り、そこから hp.Int('units', min_value=32, max_value=512, step=32) (特定の範囲の整数) などのハイパーパラメーターをサンプリングできます。

import kerastuner
from tensorflow.keras import layers

# Configure the search space
HPS = kerastuner.engine.hyperparameters.HyperParameters()

HPS.Int('conv_blocks', 3, 5, default=3)
for i in range(5):
    HPS.Int('filters_' + str(i), 32, 256, step=32)
    HPS.Choice('pooling_' + str(i), ['avg', 'max'])
HPS.Int('hidden_size', 30, 100, step=10, default=50)
HPS.Float('dropout', 0, 0.5, step=0.1, default=0.5)
HPS.Float('learning_rate', 1e-4, 1e-2, sampling='log')

def build_model(hp):
    inputs = tf.keras.Input(shape=(INPUT_IMG_SIZE, INPUT_IMG_SIZE, 3))
    x = inputs
    for i in range(hp.get('conv_blocks')):
        filters = hp.get('filters_'+ str(i))
        for _ in range(2):
            x = layers.Conv2D(
              filters, kernel_size=(3, 3), padding='same')(x)
            x = layers.BatchNormalization()(x)
            x = layers.ReLU()(x)
        if hp.get('pooling_' + str(i)) == 'max':
            x = layers.MaxPool2D()(x)
        else:
            x = layers.AvgPool2D()(x)
    x = layers.GlobalAvgPool2D()(x)
    x = layers.Dense(hp.get('hidden_size'),
      activation='relu')(x)
    x = layers.Dropout(hp.get('dropout'))(x)
    outputs = layers.Dense(NUM_CLASSES, activation='softmax')(x)

    model = tf.keras.Model(inputs, outputs)
    model.compile(
      optimizer=tf.keras.optimizers.Adam(
        hp.get('learning_rate')),
      loss='sparse_categorical_crossentropy',
      metrics=['accuracy'])
    return model

CloudTuner を構成する

このセクションでは、クラウド チューナーをリモートとローカルの両方で実行できるように構成します。 2 つの主な違いは、配布戦略です。

from tensorflow_cloud import CloudTuner

distribution_strategy = None
if not tfc.remote():
    # Using MirroredStrategy to use a single instance with multiple GPUs
    # during remote execution while using no strategy for local.
    distribution_strategy = tf.distribute.MirroredStrategy()

tuner = CloudTuner(
    build_model,
    project_id=GCP_PROJECT_ID,
    project_name= JOB_NAME,
    region=REGION,
    objective='accuracy',
    hyperparameters=HPS,
    max_trials=100,
    directory=GCS_BASE_PATH,
    study_id=STUDY_ID,
    overwrite=True,
    distribution_strategy=distribution_strategy)
# Configure Tensorboard logs
callbacks=[
    tf.keras.callbacks.TensorBoard(log_dir=TENSORBOARD_LOGS_DIR)]

# Setting to run tuning remotely, you can run tuner locally to validate it works first.
if tfc.remote():
    tuner.search(x=x_train, y=y_train, epochs=30, validation_split=0.2, callbacks=callbacks)

# You can uncomment the code below to run the tuner.search() locally to validate
# everything works before submitting the job to Cloud. Stop the job manually
# after one epoch.

# else:
#     tuner.search(x=x_train, y=y_train, epochs=1, validation_split=0.2, callbacks=callbacks)

リモートトレーニングを開始します

このステップでは、このノートブックのコードをリモート実行用に準備し、NUM_JOBS 並列実行をリモートで開始してモデルをトレーニングします。ジョブが送信されたら、次のステップに進み、Tensorboard 経由でジョブの進行状況を監視できます。

# If you are using a custom image you can install modules via requirements txt file.
with open('requirements.txt','w') as f:
    f.write('pandas==1.1.5\n')
    f.write('numpy==1.18.5\n')
    f.write('tensorflow-cloud\n')
    f.write('keras-tuner\n')

# Optional: Some recommended base images. If you provide none the system will choose one for you.
TF_GPU_IMAGE= "tensorflow/tensorflow:latest-gpu"
TF_CPU_IMAGE= "tensorflow/tensorflow:latest"


tfc.run_cloudtuner(
    distribution_strategy='auto',
    requirements_txt='requirements.txt',
    docker_config=tfc.DockerConfig(
        parent_image=TF_GPU_IMAGE,
        image_build_bucket=GCS_BUCKET
        ),
    chief_config=tfc.COMMON_MACHINE_CONFIGS['K80_4X'],
    job_labels={'job': JOB_NAME},
    service_account=SERVICE_ACCOUNT,
    num_jobs=NUM_JOBS
)

研修結果

Colab インスタンスを再接続します

ほとんどのリモート トレーニング ジョブは長時間実行されます。Colab を使用している場合は、トレーニング結果が利用可能になる前にタイムアウトになる可能性があります。その場合は、次のセクションを再実行して再接続し、トレーニング結果にアクセスできるように Colab インスタンスを設定します。次のセクションを順番に実行します。

  1. 必要なモジュールをインポートする
  2. プロジェクト構成
  3. Google Cloud プロジェクトを使用するためのノートブックの認証

テンソルボードをロードする

トレーニングの進行中に、Tensorboard を使用して結果を表示できます。結果はトレーニングの開始後にのみ表示されることに注意してください。これには数分かかる場合があります。

%load_ext tensorboard
%tensorboard --logdir $TENSORBOARD_LOGS_DIR

トレーニング アセットには次のようにアクセスできます。結果は、チューニング ジョブが少なくとも 1 回のトライアルを完了した後にのみ表示されることに注意してください。これには数分かかる場合があります。

if not tfc.remote():
    tuner.results_summary(1)
    best_model = tuner.get_best_models(1)[0]
    best_hyperparameters = tuner.get_best_hyperparameters(1)[0]

    # References to best trial assets
    best_trial_id = tuner.oracle.get_best_trials(1)[0].trial_id
    best_trial_dir = tuner.get_trial_dir(best_trial_id)