ハイパーパラメータ調整の使用

このページでは、モデルをトレーニングする際に AI Platform Training のハイパーパラメータ調整を使用する方法を示します。ハイパーパラメータ調整は、デベロッパーが指定するターゲット変数を最適化します。ターゲット変数は、ハイパーパラメータ指標と呼ばれます。ハイパーパラメータ調整ありのジョブを開始するときに、ハイパーパラメータ指標の名前を設定します。これは、トレーナーに追加するスカラー サマリーに割り当てる名前です。

ハイパーパラメータの調整の手順

トレーニング ジョブでハイパーパラメータ調整を使用するには、次の操作を行います。

  1. TrainingInput オブジェクトに HyperparameterSpec を含めることで、トレーニング ジョブ用のハイパーパラメータ調整の構成を指定します。

  2. トレーニング アプリケーションに次のコードを追加します。

    • 調整するハイパーパラメータを表すコマンドライン引数を解析し、その値を使用してトレーニング トライアルのハイパーパラメータを設定します。
    • ハイパーパラメータ指標をグラフのサマリーに追加します。

以下は各手順の詳細です。

トレーニング ジョブ用のハイパーパラメータ調整の構成の指定

トレーニング ジョブのハイパーパラメータ調整の構成を格納する HyperparameterSpec オブジェクトを作成し、HyperparameterSpechyperparameters オブジェクトとして TrainingInput オブジェクトに追加します。

ハイパーパラメータ調整ジョブにより、トライアル ジョブが作成されます。トレーニング トライアル ジョブのプロセスを加速する場合は、TrainingInput オブジェクトにカスタム マシンタイプを指定します。たとえば、n1-standard-8 VM を使用して各トライアル ジョブを作成するには、masterTypen1-standard-8 に指定し、ワーカー構成を空のままにします。

HyperparameterSpec で、選択した指標を表す値を hyperparameterMetricTag に設定します。hyperparameterMetricTag を指定しない場合、AI Platform Training は training/hptuning/metric という名前の指標を探します。次の例は、metric1 という名前の指標の構成を作成する方法を示しています。

gcloud

ハイパーパラメータ構成の情報を、構成 YAML ファイルに追加します。下記の例をご覧ください。作業用構成ファイルについては、Estimator の国勢調査サンプルの hptuning_config.yaml をご覧ください。

trainingInput:
  scaleTier: CUSTOM
  masterType: complex_model_m
  workerType: complex_model_m
  parameterServerType: large_model
  workerCount: 9
  parameterServerCount: 3
  hyperparameters:
    goal: MAXIMIZE
    hyperparameterMetricTag: metric1
    maxTrials: 30
    maxParallelTrials: 1
    enableTrialEarlyStopping: True
    params:
    - parameterName: hidden1
      type: INTEGER
      minValue: 40
      maxValue: 400
      scaleType: UNIT_LINEAR_SCALE
    - parameterName: numRnnCells
      type: DISCRETE
      discreteValues:
      - 1
      - 2
      - 3
      - 4
    - parameterName: rnnCellType
      type: CATEGORICAL
      categoricalValues:
      - BasicLSTMCell
      - BasicRNNCell
      - GRUCell
      - LSTMCell
      - LayerNormBasicLSTMCell

Python

HyperparameterSpec を表すディクショナリを作成し、トレーニング入力に追加します。次の例は、トレーニング ジョブ構成ガイドの説明に従って、TrainingInput ディクショナリ(ここでの名前は training_inputs)が作成されていることを前提としています。

# Add hyperparameter tuning to the job config.
hyperparams = {
    'goal': 'MAXIMIZE',
    'hyperparameterMetricTag': 'metric1',
    'maxTrials': 30,
    'maxParallelTrials': 1,
    'enableTrialEarlyStopping': True,
    'params': []}

hyperparams['params'].append({
    'parameterName':'hidden1',
    'type':'INTEGER',
    'minValue': 40,
    'maxValue': 400,
    'scaleType': 'UNIT_LINEAR_SCALE'})

hyperparams['params'].append({
    'parameterName':'numRnnCells',
    'type':'DISCRETE',
    'discreteValues': [1, 2, 3, 4]})

hyperparams['params'].append({
    'parameterName':'rnnCellType',
    'type': 'CATEGORICAL',
    'categoricalValues': [
        'BasicLSTMCell',
        'BasicRNNCell',
        'GRUCell',
        'LSTMCell',
        'LayerNormBasicLSTMCell'
    ]
})

# Add hyperparameter specification to the training inputs dictionary.
training_inputs['hyperparameters'] = hyperparams

# Build the job spec.
job_spec = {'jobId': my_job_name, 'trainingInput': training_inputs}

トレーニング アプリケーションのコードの確認

アプリケーションで、ハイパーパラメータのコマンドライン引数を処理し、ハイパーパラメータ指標を AI Platform Training に報告します。

調整するハイパーパラメータのコマンドライン引数の処理

AI Platform Training は、トレーニング アプリケーションを呼び出すときにコマンドライン引数を設定します。次のようにコードでコマンドライン引数を使用します。

  1. 各ハイパーパラメータ引数の名前を定義し、任意の引数パーザー(通常は argparse)を使用して解析します。引数名は、前述のように、ジョブ構成で指定したパラメータ名と一致させる必要があります。

  2. コマンドライン引数の値をトレーニング コードのハイパーパラメータに割り当てます。

AI Platform Training へのハイパーパラメータ指標の報告

ハイパーパラメータ指標を AI Platform Training サービスに報告する方法は、トレーニングに TensorFlow を使用するかどうかによって異なります。また、トレーニングにランタイム バージョンを使用するのか、カスタム コンテナを使用するのかによっても異なります。

早期停止を活用するために、トレーニング コードでハイパーパラメータ指標を AI Platform Training に頻繁に報告することをおすすめします。

TensorFlow とランタイム バージョン

AI Platform Training ランタイム バージョンを使用し、TensorFlow でトレーニングする場合に、ハイパーパラメータ指標を AI Platform Training に報告するには、その指標を TensorFlow サマリーに書き込みます。次のいずれかの関数を使用します。

次の Estimator の例のように、上記の関数のいずれかを別の TensorFlow API で呼び出した場合にも、ハイパーパラメータ指標が AI Platform Training に報告されます。

ハイパーパラメータの指標をサマリーに書き込むには 2 つの方法があり、次の例にそれぞれの基本的な考え方を示します。どちらの例でも、回帰モデルのトレーニングを前提とし、正解ラベルと評価予測の間の二乗平均平方根誤差を metric1 という名前のハイパーパラメータ指標として書き込みます。

Keras

次の例では、カスタムの Keras コールバックを使用して、各トレーニング エポックの最後にスカラー サマリーを書き込んでいます。

class MyMetricCallback(tf.keras.callbacks.Callback):

    def on_epoch_end(self, epoch, logs=None):
        tf.summary.scalar('metric1', logs['RootMeanSquaredError'], epoch)

logdir = "logs/scalars/" + datetime.now().strftime("%Y%m%d-%H%M%S")
file_writer = tf.summary.create_file_writer(logdir + "/metrics")
file_writer.set_as_default()

model = tf.keras.Sequential(
    tf.keras.layers.Dense(1, activation='linear', input_dim=784))
model.compile(
    optimizer='rmsprop',
    loss='mean_squared_error',
    metrics=['RootMeanSquaredError'])

model.fit(
    x_train,
    y_train,
    batch_size=64,
    epochs=10,
    steps_per_epoch=5,
    verbose=0,
    callbacks=[MyMetricCallback()])

Estimator

次の例では、tf.estimator.add_metrics を使用してグラフのサマリーにハイパーパラメータ指標を追加しています。

Estimator は、evaluate メソッドを実行するたびにグラフのサマリーを書き込むことに注意してください。この例では、tf.estimator.EvalSpectf.estimator.train_and_evaluate を使用して、トレーニングの間 300 秒ごとにサマリーを評価して書き込むように Estimator を構成しています。

# Create metric for hyperparameter tuning
def my_metric(labels, predictions):
    # Note that different types of estimator provide different different
    # keys on the predictions Tensor. predictions['predictions'] is for
    # regression output.
    pred_values = predictions['predictions']
    return {'metric1': tf.compat.v1.metrics.root_mean_squared_error(labels, pred_values)}

# Create estimator to train and evaluate
def train_and_evaluate(output_dir):

    estimator = tf.estimator.DNNLinearCombinedRegressor(...)

    estimator = tf.estimator.add_metrics(estimator, my_metric)

    train_spec = ...
    eval_spec = tf.estimator.EvalSpec(
        start_delay_secs = 60, # start evaluating after 60 seconds
        throttle_secs = 300,  # evaluate every 300 seconds
        ...)
    tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)

その他の機械学習フレームワークまたはカスタム コンテナ

トレーニングにカスタム コンテナを使用する場合や、TensorFlow 以外のフレームワークでハイパーパラメータ調整を行う場合は、cloudml-hypertune Python パッケージを使用してハイパーパラメータ指標を AI Platform Training に報告します。

cloudml-hypertune の使用例をご覧ください。

実行中のハイパーパラメータ調整ジョブの詳細の取得

実行中のトレーニング ジョブの詳細なステータスを取得することで、ハイパーパラメータ調整をモニタリングできます。

レスポンスのジョブリソース内の TrainingOutput オブジェクトには、ハイパーパラメータ調整を使用したトレーニング ジョブ中に次の値が設定されます。

  • isHyperparameterTuningJobTrue に設定します。

  • trials が生成され、トライアルごとに 1 つの HyperparameterOutput オブジェクトのリストが組み込まれています。

TF_CONFIG 環境変数からトライアル ID を取得することもできます。TF_CONFIG からの詳細の取得に関するガイドをご覧ください。

ハイパーパラメータ調整結果の取得

トレーニングの実行が完了したら、Google Cloud コンソールで各トライアルの結果を表示できます。または、projects.jobs.get を呼び出して結果を取得できます。ジョブリソース内の TrainingOutput オブジェクトには、すべての実行の指標が含まれ、識別されて最適に調整された実行の指標があります。

処理中のジョブをモニタリングするために使用するのと同じ詳細なステータス リクエストを使用して、この情報を取得します。

ジョブの説明の各トライアルから結果を確認できます。Google Cloud コンソールで、トライアルを rmselearning_ratetraining steps でフィルタできます。ハイパーパラメータ指標に最適な値をもたらしたトライアルを探します。トライアルがモデルの成功の基準を満たしている場合、そのトライアルに対して示されているハイパーパラメータ値を、モデルの以後の実行で使用できます。

場合によっては、複数のトライアルが調整指標に対して同じ結果をもたらすことがあります。そのような場合は、他の手段で最も効果的なハイパーパラメータ値を決定する必要があります。たとえば、隠れ層のノード数を調整して値を 8 に設定したときと 20 に設定したときで結果が変わらなかった場合、ノードの数を多くしてもモデルは改善されず、処理とコストがかさむだけです。この場合は、8 を使用することをおすすめします。

HyperparameterOutputFAILED トライアルの状態は、そのトライアルのトレーニングが失敗したか、ハイパーパラメータ調整指標を報告できなかったことを意味します。後者の場合、トライアルが失敗しても親ジョブは成功することがあります。トライアルのトレーニングが失敗したかどうかは、トライアルのログで確認できます。

トライアル数の上限の設定

サービスに実行を許可するトライアルの数を決めて、HyperparameterSpec オブジェクトの maxTrials 値を設定する必要があります。

許可するトライアル数を決定する際には、次の 2 つの競合する事項について考慮する必要があります。

  • 時間(結果として、費用)
  • 精度

トライアル数を増やすと一般には結果が向上しますが、常に向上するとは限りません。ほとんどの場合、収穫逓減点があり、それより後はトライアルを追加しても精度に影響がないか、ほとんど影響しません。最初はトライアル数を少なくして、選択したハイパーパラメータがモデルの精度に与える効果を測定してから、ジョブのトライアル数を増やすことをおすすめします。

ハイパーパラメータ調整を最大限に活用するには、設定する最大値がハイパーパラメータの数の 10 倍を下回らないようにしてください。

失敗したトライアルの処理

ハイパーパラメータ調整トライアルがエラーで終了する場合は、トレーニング ジョブを早期に終了できます。HyperparameterSpecmaxFailedTrials フィールドに、許可するトライアルの失敗回数を設定します。トライアルの失敗回数がこの数を超えると、AI Platform Training はトレーニング ジョブを終了します。maxFailedTrials 値は、maxTrials 以下にする必要があります。

maxFailedTrials を設定しない場合や、0 に設定した場合、AI Platform Training は次のルールに従って失敗したトライアルを処理します。

  • ジョブの最初のトライアルが失敗した場合、AI Platform Training はジョブを直ちに終了します。最初のトライアルの失敗は、トレーニング コードに問題があることを示唆します。つまり、後続のトライアルも失敗する可能性があります。ジョブを直ちに終了すれば、後続のトライアルを待たずに問題の診断を行うことができ、不要なコストもかかりません。
  • 最初のトライアルが成功した場合、AI Platform Training は、次のいずれかの基準に基づいて、後続のトライアルで失敗した後にジョブを終了します。
    • 失敗したトライアルの数が非常に多い。
    • 成功したトライアルに対する失敗したトライアルの比率が非常に高い。

これらの内部しきい値は変更されることがあります。特定の動作を保証するには、maxFailedTrials フィールドを設定してください。

トライアルの並列実行

HyperparameterSpec オブジェクトで maxParallelTrials を設定することで、並列実行されるトライアルの数を指定できます。

トライアルの並列実行には、トレーニング ジョブの所要時間を短縮できるというメリットがあります(リアルタイムの時間という意味であり、所要処理時間の合計は特に変わりません)。ただし、並列で実行すると、調整ジョブ全体の効果が減じることがあります。なぜなら、ハイパーパラメータ調整は、前のトライアルの結果を使用して、後続のトライアルのハイパーパラメータに割り当てる値を通知するからです。並列実行の場合、まだ実行中のトライアルの結果を利用できないままに開始するトライアルもでてくることになります。

トライアルを並列実行する場合、トレーニング サービスは複数のトレーニング処理クラスタ(または、単一プロセス トレーナーの場合は複数の個々のマシン)をプロビジョニングします。ジョブに対して設定するスケール階層は、個々のトレーニング クラスタに使用されます。

トライアルの早期停止

成功の見込みがないトライアルを自動的に停止するように AI Platform Training を設定できます。これにより、有効ではないトライアルの継続でかかるコストを節約できます。

トライアルの早期停止を有効にするには、HyperparameterSpecenableTrialEarlyStopping 値を TRUE に設定します。

完了したハイパーパラメータ調整ジョブの再開

完了したハイパーパラメータ調整ジョブを、部分的に最適化された状態から再開できます。これにより、以前のハイパーパラメータ調整ジョブで得られた知識を再利用できます。

ハイパーパラメータ調整ジョブを再開するには、次の構成を使用して新しいハイパーパラメータ調整ジョブを送信します。

  • HyperparameterSpecresumePreviousJobId 値を前のトライアルのジョブ ID に設定します。
  • maxTrialsmaxParallelTrials の値を指定します。

AI Platform Training は、以前のジョブ ID を使用して同じ goalparamshyperparameterMetricTag 値を取得し、ハイパーパラメータ調整ジョブを継続します。

ジョブで異なるパラメータが使用される場合でも、類似するジョブに対して一定の hyperparameterMetricTag 名と params を使用します。これにより、AI Platform Training の処理性能を改善できます。

次の例は、resumePreviousJobId 構成の使用方法を示しています。

gcloud

trainingInput:
  scaleTier: CUSTOM
  masterType: complex_model_m
  workerType: complex_model_m
  parameterServerType: large_model
  workerCount: 9
  parameterServerCount: 3
  hyperparameters:
    enableTrialEarlyStopping: TRUE
    maxTrials: 30
    maxParallelTrials: 1
    resumePreviousJobId: [PREVIOUS_JOB_IDENTIFIER]

Python

# Add hyperparameter tuning to the job config.
hyperparams = {
    'enableTrialEarlyStopping': True,
    'maxTrials': 30,
    'maxParallelTrials': 1,
    'resumePreviousJobId': [PREVIOUS_JOB_IDENTIFIER]}

# Add the hyperparameter specification to the training inputs dictionary.
training_inputs['hyperparameters'] = hyperparams

# Build the job spec.
job_spec = {'jobId': my_job_name, 'trainingInput': training_inputs}

Cloud TPU によるハイパーパラメータ調整

AI Platform Training の Cloud TPU でハイパーパラメータ調整ジョブを実行する場合は、TPUEstimatorSpeceval_metrics プロパティを使用することがベスト プラクティスとなります。

Cloud TPU でハイパーパラメータ調整を行うサンプルについては、ResNet-50 TPU ハイパーパラメータ調整のサンプルをご覧ください。

eval_metrics プロパティでハイパーパラメータ調整サービスを使用するのではなく、host_calltf.summary を呼び出すこともできます。詳細については、TPUEstimatorSpec をご覧ください。

次のステップ