1. 概要
このラボでは、Vertex AI を使用して TensorFlow モデルのハイパーパラメータ調整ジョブを実行します。このラボではモデルコードに TensorFlow を使用しますが、そのコンセプトは他の ML フレームワークにも適用できます。
学習内容
次の方法を学習します。
- ハイパーパラメータ調整用のトレーニング アプリケーション コードを変更する
- Vertex AI UI からハイパーパラメータ調整ジョブを構成して起動する
- Vertex AI Python SDK を使用してハイパーパラメータ調整ジョブを構成して起動する
Google Cloud でこのラボを実行するための総費用は約 $3 米ドルです。
2. Vertex AI の概要
このラボでは、Google Cloud で利用できる最新の AI プロダクトを使用します。Vertex AI は Google Cloud 全体の ML サービスを統合してシームレスな開発エクスペリエンスを提供できるプロダクトです。これまで、AutoML でトレーニングしたモデルやカスタムモデルには、個別のサービスを介してアクセスする必要がありました。この新しいサービスは、それらを他の新しいプロダクトとともに 1 つの API へと結合します。既存のプロジェクトを Vertex AI に移行することもできます。ご意見やご質問がありましたら、サポートページからご連絡ください。
Vertex AI には、エンドツーエンドの ML ワークフローをサポートするさまざまなプロダクトが含まれています。このラボでは、以下に示す [Training] と [Workbench] の内容に重点を置きます。
3. 環境の設定
この Codelab を実行するには、課金が有効になっている Google Cloud Platform プロジェクトが必要です。プロジェクトを作成するには、こちらの手順に従ってください。
ステップ 1: Compute Engine API を有効にする
関連項目Compute Engine 、実現] をクリックします。これは、ノートブック インスタンスを作成する際に必要になります。
ステップ 2: Container Registry API を有効にする
Container Registry に移動し、[有効にする] を選択します(まだの場合)。カスタム トレーニング ジョブのコンテナを作成するために使用します。
ステップ 3: Vertex AI API を有効にする
Cloud Console の [Vertex AI] セクションに移動し、[Vertex AI API を有効にする] をクリックします。
ステップ 4: Vertex AI Workbench インスタンスを作成する
Cloud Console の Vertex AI セクションで Workbench をクリックします。
Notebooks API をまだ有効にしていない場合は、有効にします。
有効にしたら、[マネージド ノートブック] をクリックします。
[新しいノートブック] を選択します。
ノートブックに名前を付けて、[Advanced Settings] をクリックします。
[詳細設定] で、アイドル状態でのシャットダウンを有効にし、分数を 60 に設定します。つまり、使用していないときはノートブックが自動的にシャットダウンされるため、不要なコストは発生しません。
[セキュリティ] で、[ターミナルを有効にする] を選択します(有効になっていない場合)。
その他の詳細設定はすべてそのままで構いません。
次に、[作成] をクリックします。インスタンスがプロビジョニングされるまでに数分かかります。
インスタンスが作成されたら、[JupyterLab を開く] を選択します。
新しいインスタンスを初めて使用するときは、認証を求められます。これを行うには、UI の手順に従います。
4.トレーニング アプリケーション コードのコンテナ化
このラボでトレーニングおよび調整するモデルは、TensorFlow Datasets の馬または人間のデータセットでトレーニングされた画像分類モデルです。
このハイパーパラメータ調整ジョブを Vertex AI に送信するには、トレーニング アプリケーション コードを Docker コンテナに配置し、このコンテナを Google Container Registry に push します。このアプローチでは、任意のフレームワークで構築されたモデルのハイパーパラメータを調整できます。
まず、ランチャー メニューから、ノートブック インスタンスでターミナル ウィンドウを開きます。
horses_or_humans
という新しいディレクトリを作成し、そのディスクに cd します。
mkdir horses_or_humans
cd horses_or_humans
ステップ 1: Dockerfile を作成する
コードをコンテナ化する最初のステップは、Dockerfile を作成することです。Dockerfile には、イメージの実行に必要なすべてのコマンドを含めます。CloudML Hypertune ライブラリなど、必要なライブラリがすべてインストールされ、トレーニング コードのエントリ ポイントが設定されます。
ターミナルで、空の Dockerfile を作成します。
touch Dockerfile
Dockerfile を開き、次の内容をコピーします。
FROM gcr.io/deeplearning-platform-release/tf2-gpu.2-7
WORKDIR /
# Installs hypertune library
RUN pip install cloudml-hypertune
# Copies the trainer code to the docker image.
COPY trainer /trainer
# Sets up the entry point to invoke the trainer.
ENTRYPOINT ["python", "-m", "trainer.task"]
この Dockerfile は、Deep Learning Container TensorFlow Enterprise 2.7 GPU Docker イメージを使用します。Google Cloud の Deep Learning Containers には、ML やデータ サイエンスの一般的なフレームワークが多数プリインストールされています。このイメージのダウンロード後、この Dockerfile でトレーニング コードのエントリ ポイントを設定します。これらのファイルはまだ作成されていません。次のステップでは、モデルのトレーニングと調整のためのコードを追加します。
ステップ 2: モデルのトレーニング コードを追加する
ターミナルで次のコマンドを実行して、トレーニング コードのディレクトリと、コードを追加する Python ファイルを作成します。
mkdir trainer
touch trainer/task.py
horses_or_humans/
ディレクトリに、次の行が作成されます。
+ Dockerfile
+ trainer/
+ task.py
次に、作成した task.py
ファイルを開き、以下のコードをコピーします。
import tensorflow as tf
import tensorflow_datasets as tfds
import argparse
import hypertune
NUM_EPOCHS = 10
def get_args():
'''Parses args. Must include all hyperparameters you want to tune.'''
parser = argparse.ArgumentParser()
parser.add_argument(
'--learning_rate',
required=True,
type=float,
help='learning rate')
parser.add_argument(
'--momentum',
required=True,
type=float,
help='SGD momentum value')
parser.add_argument(
'--num_units',
required=True,
type=int,
help='number of units in last hidden layer')
args = parser.parse_args()
return args
def preprocess_data(image, label):
'''Resizes and scales images.'''
image = tf.image.resize(image, (150,150))
return tf.cast(image, tf.float32) / 255., label
def create_dataset():
'''Loads Horses Or Humans dataset and preprocesses data.'''
data, info = tfds.load(name='horses_or_humans', as_supervised=True, with_info=True)
# Create train dataset
train_data = data['train'].map(preprocess_data)
train_data = train_data.shuffle(1000)
train_data = train_data.batch(64)
# Create validation dataset
validation_data = data['test'].map(preprocess_data)
validation_data = validation_data.batch(64)
return train_data, validation_data
def create_model(num_units, learning_rate, momentum):
'''Defines and compiles model.'''
inputs = tf.keras.Input(shape=(150, 150, 3))
x = tf.keras.layers.Conv2D(16, (3, 3), activation='relu')(inputs)
x = tf.keras.layers.MaxPooling2D((2, 2))(x)
x = tf.keras.layers.Conv2D(32, (3, 3), activation='relu')(x)
x = tf.keras.layers.MaxPooling2D((2, 2))(x)
x = tf.keras.layers.Conv2D(64, (3, 3), activation='relu')(x)
x = tf.keras.layers.MaxPooling2D((2, 2))(x)
x = tf.keras.layers.Flatten()(x)
x = tf.keras.layers.Dense(num_units, activation='relu')(x)
outputs = tf.keras.layers.Dense(1, activation='sigmoid')(x)
model = tf.keras.Model(inputs, outputs)
model.compile(
loss='binary_crossentropy',
optimizer=tf.keras.optimizers.SGD(learning_rate=learning_rate, momentum=momentum),
metrics=['accuracy'])
return model
def main():
args = get_args()
train_data, validation_data = create_dataset()
model = create_model(args.num_units, args.learning_rate, args.momentum)
history = model.fit(train_data, epochs=NUM_EPOCHS, validation_data=validation_data)
# DEFINE METRIC
hp_metric = history.history['val_accuracy'][-1]
hpt = hypertune.HyperTune()
hpt.report_hyperparameter_tuning_metric(
hyperparameter_metric_tag='accuracy',
metric_value=hp_metric,
global_step=NUM_EPOCHS)
if __name__ == "__main__":
main()
コンテナを構築する前に、コードを詳しく見てみましょう。ハイパーパラメータ調整サービスの使用に固有のコンポーネントがいくつかあります。
- このスクリプトは、
hypertune
ライブラリをインポートします。ステップ 1 の Dockerfile には、このライブラリを pip インストールする手順が含まれていました。 - 関数
get_args()
は、調整するハイパーパラメータごとにコマンドライン引数を定義します。この例で調整されるハイパーパラメータは、学習率、オプティマイザーのモメンタム値、モデルの最後の隠れ層のユニット数ですが、他のものも自由にテストできます。これらの引数に渡された値は、コード内で対応するハイパーパラメータの設定に使用されます。 main()
関数の最後には、hypertune
ライブラリを使用して、最適化する指標を定義します。TensorFlow では、Kerasmodel.fit
メソッドがHistory
オブジェクトを返します。History.history
属性は、連続するエポックにおけるトレーニングの損失値と指標値の記録です。検証データをmodel.fit
に渡すと、History.history
属性には、検証の損失値と指標値も含まれます。たとえば、検証データを使用して 3 回のエポックでモデルをトレーニングし、指標としてaccuracy
を指定した場合、History.history
属性は次の辞書のようになります。
{
"accuracy": [
0.7795261740684509,
0.9471358060836792,
0.9870933294296265
],
"loss": [
0.6340447664260864,
0.16712145507335663,
0.04546636343002319
],
"val_accuracy": [
0.3795261740684509,
0.4471358060836792,
0.4870933294296265
],
"val_loss": [
2.044623374938965,
4.100203514099121,
3.0728273391723633
]
ハイパーパラメータ調整サービスでモデルの検証精度を最大化する値を検出するには、指標を val_accuracy
リストの最後のエントリ(NUM_EPOCS - 1
)として定義します。次に、この指標を HyperTune
のインスタンスに渡します。hyperparameter_metric_tag
には任意の文字列を選択できますが、ハイパーパラメータ調整ジョブの開始時には後でこの文字列を再度使用する必要があります。
ステップ 3: コンテナをビルドする
ターミナルで次のコマンドを実行し、プロジェクトの環境変数を定義します。your-cloud-project
は、プロジェクトの ID に置き換えてください。
PROJECT_ID='your-cloud-project'
Google Container Registry でコンテナ イメージの URI を使用して変数を定義します。
IMAGE_URI="gcr.io/$PROJECT_ID/horse-human:hypertune"
次に、horses_or_humans
ディレクトリのルートから次のコマンドを実行してコンテナをビルドします。
docker build ./ -t $IMAGE_URI
最後に、Google Container Registry に push します。
docker push $IMAGE_URI
コンテナが Container Registry に push されたら、カスタムモデルのハイパーパラメータ調整ジョブを開始する準備が整いました。
5. Vertex AI でハイパーパラメータ調整ジョブを実行する
このラボでは、Google Container Registry のカスタム コンテナを使用してカスタム トレーニングを使用しますが、Vertex AI ビルド済みコンテナでハイパーパラメータ調整ジョブを実行することもできます。
まず、Cloud Console の [Vertex] セクションの [トレーニング] セクションに移動します。
ステップ 1: トレーニング ジョブを構成する
[作成] をクリックして、ハイパーパラメータ調整ジョブのパラメータを入力します。
- [データセット] で [管理されているデータセットなし] を選択します。
- 次に、トレーニング方法として [Custom training (advanced)] を選択し、[Continue] をクリックします。
- [モデル名] に「
horses-humans-hyptertune
」(またはモデルに付ける名前)を入力します。 - [続行] をクリックする
[コンテナの設定] ステップで、[Custom container] を選択します。
最初のボックス(コンテナ イメージ)に、前のセクションの IMAGE_URI
変数の値を入力します。gcr.io/your-cloud-project/horse-human:hypertune
になっているはずです。ここでは、自分のプロジェクト名を指定します。その他のフィールドは空白のままにして、[続行] をクリックします。
ステップ 2: ハイパーパラメータ調整ジョブを構成する
[ハイパーパラメータ調整を有効にする] を選択します。
ハイパーパラメータを構成する
次に、トレーニング アプリケーション コードでコマンドライン引数として設定したハイパーパラメータを追加する必要があります。ハイパーパラメータを追加する場合は、最初に名前を指定する必要があります。これは、argparse
に渡された引数名と一致する必要があります。
次に、タイプと調整サービスが試行する値の境界を選択します。タイプに Double や Integer を選択した場合は、最小値と最大値を指定する必要があります。また、[カテゴリ] または [ディスクリート] を選択した場合は、値を入力する必要があります。
Double タイプと Integer タイプでは、Scaling の値も必要になります。
learning_rate
ハイパーパラメータを追加した後、momentum
と num_units
のパラメータを追加します。
指標の構成
ハイパーパラメータを追加したら、次に、最適化する指標と目標を指定します。これは、トレーニング アプリケーションで設定した hyperparameter_metric_tag
と同じになります。
Vertex AI ハイパーパラメータ調整サービスは、前の手順で構成した値を使用して、トレーニング アプリケーションのトライアルを複数回実行します。サービスが実行するトライアルの数に上限を設ける必要があります。トライアルの回数を増やすと一般的に良い結果が得られますが、収穫逓減のポイントがあり、それ以降はトライアルの回数を増やしても最適化しようとしている指標にほとんど影響がなくなります。少ないトライアル数から始めて、多数のトライアルにスケールアップする前に、選択したハイパーパラメータの影響を理解することをおすすめします。
また、並列トライアルの数に上限を設定する必要があります。並列トライアルの回数を増やすと、ハイパーパラメータ調整ジョブの実行時間が短縮されます。ただし、ジョブの有効性は全体で低下する可能性があります。これは、デフォルトの調整戦略で、過去のトライアルの結果を使用して後続のトライアルでの値の割り当てを通知するためです。並行して実行するトライアルの数が多すぎると、まだ実行中のトライアルの結果を利用できないままに開始するトライアルがあります。
わかりやすく説明するために、トライアル数を 15、並列トライアルの最大数を 3 に設定できます。別の数値を試すこともできますが、結果的に調整時間は長くなり、費用も高くなります。
最後に、検索アルゴリズムとして [デフォルト] を選択します。このアルゴリズムは、Google Vizier を使用してハイパーパラメータ調整のベイズ最適化を実行します。このアルゴリズムについて詳しくは、こちらをご覧ください。
[続行] をクリックします。
ステップ 3: コンピューティングの構成
[コンピューティングと料金] で、選択したリージョンをそのままにして [ワーカープール 0] を次のように構成します。
[トレーニングを開始] をクリックして、ハイパーパラメータ調整ジョブを開始します。Cloud Platform Console の [トレーニング] セクションにある [ハイパー チューニングのジョブ] タブに、次のように表示されます。
終了したら、ジョブ名をクリックして調整のトライアル結果を確認できます。
お疲れさまでした
Vertex AI を使用して以下のことを行う方法を学習しました。
- カスタム コンテナで提供されるトレーニング コードのハイパーパラメータ調整ジョブを起動します。この例では TensorFlow モデルを使用しましたが、カスタム コンテナを使用すると任意のフレームワークで構築したモデルをトレーニングできます。
Vertex のさまざまな部分について詳しくは、こちらのドキュメントをご覧ください。
6. (省略可)Vertex SDK を使用する
前のセクションでは、UI を介してハイパーパラメータ調整ジョブを起動する方法を説明しました。このセクションでは、Vertex Python API を使用してハイパーパラメータ調整ジョブを送信する別の方法について説明します。
ランチャーから、TensorFlow 2 ノートブックを作成します。
Vertex AI SDK をインポートします。
from google.cloud import aiplatform
from google.cloud.aiplatform import hyperparameter_tuning as hpt
ハイパーパラメータ調整ジョブを開始するには、まず次の仕様を定義する必要があります。image_uri
の {PROJECT_ID}
は実際のプロジェクトに置き換えてください。
# The spec of the worker pools including machine type and Docker image
# Be sure to replace PROJECT_ID in the `image_uri` with your project.
worker_pool_specs = [{
"machine_spec": {
"machine_type": "n1-standard-4",
"accelerator_type": "NVIDIA_TESLA_V100",
"accelerator_count": 1
},
"replica_count": 1,
"container_spec": {
"image_uri": "gcr.io/{PROJECT_ID}/horse-human:hypertune"
}
}]
# Dictionary representing metrics to optimize.
# The dictionary key is the metric_id, which is reported by your training job,
# And the dictionary value is the optimization goal of the metric.
metric_spec={'accuracy':'maximize'}
# Dictionary representing parameters to optimize.
# The dictionary key is the parameter_id, which is passed into your training
# job as a command line argument,
# And the dictionary value is the parameter specification of the metric.
parameter_spec = {
"learning_rate": hpt.DoubleParameterSpec(min=0.001, max=1, scale="log"),
"momentum": hpt.DoubleParameterSpec(min=0, max=1, scale="linear"),
"num_units": hpt.DiscreteParameterSpec(values=[64, 128, 512], scale=None)
}
次に、CustomJob
を作成します。ステージングするには、{YOUR_BUCKET}
をプロジェクト内のバケットに置き換える必要があります。
# Replace YOUR_BUCKET
my_custom_job = aiplatform.CustomJob(display_name='horses-humans-sdk-job',
worker_pool_specs=worker_pool_specs,
staging_bucket='gs://{YOUR_BUCKET}')
次に、HyperparameterTuningJob
を作成して実行します。
hp_job = aiplatform.HyperparameterTuningJob(
display_name='horses-humans-sdk-job',
custom_job=my_custom_job,
metric_spec=metric_spec,
parameter_spec=parameter_spec,
max_trial_count=15,
parallel_trial_count=3)
hp_job.run()
7. クリーンアップ
ノートブックは、アイドル状態の 60 分後にタイムアウトするように構成されているため、インスタンスのシャットダウンを心配する必要はありません。インスタンスを手動でシャットダウンする場合は、コンソールの Vertex AI Workbench セクションにある [停止] ボタンをクリックします。ノートブックを完全に削除する場合は、[削除] ボタンをクリックします。
ストレージ バケットを削除するには、Cloud Console のナビゲーション メニューで [ストレージ] を探してバケットを選択し、[削除] をクリックします。