Keras Tuner の基礎

TensorFlow.org で表示 Google Colab で実行 GitHub でソースを表示 ノートブックをダウンロード

概要

Keras Tuner は、TensorFlow プログラム向けに最適なハイパーパラメータを選択するためのライブラリです。ユーザーの機械学習(ML)アプリケーションに適切なハイパーパラメータを選択するためのプロセスは、ハイパーパラメータチューニングまたはハイパーチューニングと呼ばれます。

ハイパーパラメータは、ML のトレーニングプロセスとトポロジーを管理する変数です。これらの変数はトレーニングプロセス中、一貫して定数を維持し、ML プログラムのパフォーマンスに直接影響を与えます。ハイパーパラメータには、以下の 2 種類があります。

  1. モデルハイパーパラメータ: 非表示レイヤーの数と幅などのモデルの選択に影響します。
  2. アルゴリズムハイパーパラメータ: 確率的勾配降下法(SGD)の学習速度や k 最近傍(KNN)分類器の最近傍の数など、学習アルゴリズムの速度と質に影響します。

このチュートリアルでは、Keras Tuner を使用して、画像分類アプリケーションのハイパーチューニングを実施します。

セットアップ

import tensorflow as tf
from tensorflow import keras

import IPython

Keras Tuner をインストールしてインポートします。

!pip install -U keras-tuner
import kerastuner as kt

データセットをダウンロードして準備する

このチュートリアルでは、Keras Tuner を使用して、Fashion MNIST データセットの服飾の画像を分類する学習モデル向けに最適なハイパーパラメータを見つけます。

データを読み込みます。

(img_train, label_train), (img_test, label_test) = keras.datasets.fashion_mnist.load_data()
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz
32768/29515 [=================================] - 0s 0us/step
40960/29515 [=========================================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz
26427392/26421880 [==============================] - 0s 0us/step
26435584/26421880 [==============================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz
16384/5148 [===============================================================================================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz
4423680/4422102 [==============================] - 0s 0us/step
4431872/4422102 [==============================] - 0s 0us/step
# Normalize pixel values between 0 and 1
img_train = img_train.astype('float32') / 255.0
img_test = img_test.astype('float32') / 255.0

モデルを定義する

ハイパーチューニングを行うモデルを構築する際、モデルアーキテクチャのほかにハイパーパラメータ検索空間も定義します。ハイパーチューニング用にセットアップするモデルをハイパーモデルと呼びます。

ハイパーモデルの定義は、以下の 2 つの方法で行います。

  • モデルビルダー関数を使用する
  • Keras Tuner API の HyperModel クラスをサブクラス化する

また、コンピュータビジョンアプリケーション用の HyperXceptionHyperResNet という 2 つの事前定義済みの HyperModel クラスも使用します。

このチュートリアルでは、モデルビルダー関数を使用して、画像分類モデルを定義します。モデルビルダー関数は、コンパイル済みのモデルを返し、インラインで定義するハイパーパラメータを使用してモデルをハイパーチューニングします。

def model_builder(hp):
  model = keras.Sequential()
  model.add(keras.layers.Flatten(input_shape=(28, 28)))

  # Tune the number of units in the first Dense layer
  # Choose an optimal value between 32-512
  hp_units = hp.Int('units', min_value = 32, max_value = 512, step = 32)
  model.add(keras.layers.Dense(units = hp_units, activation = 'relu'))
  model.add(keras.layers.Dense(10))

  # Tune the learning rate for the optimizer 
  # Choose an optimal value from 0.01, 0.001, or 0.0001
  hp_learning_rate = hp.Choice('learning_rate', values = [1e-2, 1e-3, 1e-4]) 

  model.compile(optimizer = keras.optimizers.Adam(learning_rate = hp_learning_rate),
                loss = keras.losses.SparseCategoricalCrossentropy(from_logits = True), 
                metrics = ['accuracy'])

  return model

チューナーをインスタンス化してハイパーチューニングを実行する

チューナーをインスタンス化して、ハイパーチューニングを実行します。Keras Tuner には、RandomSearchHyperbandBayesianOptimization、および Sklearn チューナーがあります。このチュートリアルでは、Hyperband チューナーを使用します。

Hyperband チューナーをインスタンス化するには、ハイパーモデル、最適化する objective、およびトレーニングするエポックの最大数(max_epochs)を指定する必要があります。

tuner = kt.Hyperband(model_builder,
                     objective = 'val_accuracy', 
                     max_epochs = 10,
                     factor = 3,
                     directory = 'my_dir',
                     project_name = 'intro_to_kt')
2021-08-14 06:25:49.317163: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-14 06:25:49.325033: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-14 06:25:49.326037: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-14 06:25:49.327573: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 AVX512F FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2021-08-14 06:25:49.328108: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-14 06:25:49.328985: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-14 06:25:49.329818: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-14 06:25:49.906943: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-14 06:25:49.907936: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-14 06:25:49.908817: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-14 06:25:49.909672: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1510] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 14648 MB memory:  -> device: 0, name: Tesla V100-SXM2-16GB, pci bus id: 0000:00:05.0, compute capability: 7.0

Hyperband チューニングアルゴリズムは、適応型リソース割り当てと早期停止を使用して、高パフォーマンスモデルに素早く収束させます。これは、トーナメント式のツリーを使用して行われます。アルゴリズムは、数回のエポックで大量のモデルをトレーニングし、性能の高い上位半数のモデル次のラウンドに持ち越します。Hyperband は、1 + logfactor(max_epochs) を計算し、直近の整数に繰り上げて、トーナメントでトレーニングするモデル数を決定します。

ハイパーパラメータ検索を実行する前に、トレーニングステップごとにトレーニング出力をクリアにするコールバックを定義します。

class ClearTrainingOutput(tf.keras.callbacks.Callback):
  def on_train_end(*args, **kwargs):
    IPython.display.clear_output(wait = True)

ハイパーパラメータ検索を実行します。検索メソッドの引数は、上記のコールバックのほか、tf.keras.model.fit に使用される引数と同じです。

tuner.search(img_train, label_train, epochs = 10, validation_data = (img_test, label_test), callbacks = [ClearTrainingOutput()])

# Get the optimal hyperparameters
best_hps = tuner.get_best_hyperparameters(num_trials = 1)[0]

print(f"""
The hyperparameter search is complete. The optimal number of units in the first densely-connected
layer is {best_hps.get('units')} and the optimal learning rate for the optimizer
is {best_hps.get('learning_rate')}.
""")
Trial 30 Complete [00h 00m 33s]
val_accuracy: 0.8715000152587891

Best val_accuracy So Far: 0.8849999904632568
Total elapsed time: 00h 06m 50s
INFO:tensorflow:Oracle triggered exit

The hyperparameter search is complete. The optimal number of units in the first densely-connected
layer is 448 and the optimal learning rate for the optimizer
is 0.001.

このチュートリアルの最後のステップとして、検索から得た最適なハイパーパラメータでモデルを保存します。

# Build the model with the optimal hyperparameters and train it on the data
model = tuner.hypermodel.build(best_hps)
model.fit(img_train, label_train, epochs = 10, validation_data = (img_test, label_test))
Epoch 1/10
1875/1875 [==============================] - 4s 2ms/step - loss: 0.4743 - accuracy: 0.8314 - val_loss: 0.4486 - val_accuracy: 0.8402
Epoch 2/10
1875/1875 [==============================] - 3s 2ms/step - loss: 0.3576 - accuracy: 0.8701 - val_loss: 0.3890 - val_accuracy: 0.8604
Epoch 3/10
1875/1875 [==============================] - 3s 2ms/step - loss: 0.3231 - accuracy: 0.8819 - val_loss: 0.3453 - val_accuracy: 0.8732
Epoch 4/10
1875/1875 [==============================] - 3s 2ms/step - loss: 0.2968 - accuracy: 0.8899 - val_loss: 0.3810 - val_accuracy: 0.8640
Epoch 5/10
1875/1875 [==============================] - 3s 2ms/step - loss: 0.2792 - accuracy: 0.8964 - val_loss: 0.3398 - val_accuracy: 0.8795
Epoch 6/10
1875/1875 [==============================] - 3s 2ms/step - loss: 0.2644 - accuracy: 0.9007 - val_loss: 0.3327 - val_accuracy: 0.8804
Epoch 7/10
1875/1875 [==============================] - 3s 2ms/step - loss: 0.2506 - accuracy: 0.9065 - val_loss: 0.3279 - val_accuracy: 0.8818
Epoch 8/10
1875/1875 [==============================] - 3s 2ms/step - loss: 0.2406 - accuracy: 0.9097 - val_loss: 0.3375 - val_accuracy: 0.8830
Epoch 9/10
1875/1875 [==============================] - 3s 2ms/step - loss: 0.2295 - accuracy: 0.9148 - val_loss: 0.3359 - val_accuracy: 0.8804
Epoch 10/10
1875/1875 [==============================] - 3s 2ms/step - loss: 0.2202 - accuracy: 0.9172 - val_loss: 0.3446 - val_accuracy: 0.8848
<keras.callbacks.History at 0x7fac7c360cd0>

my_dir/intro_to_kt ディレクトリには、ハイパーパラメータ検索中に実行された各トライアル(モデル構成)の詳細なログとチェックポイントが含まれます。ハイパーパラメータ検索を再実行する場合、Keras Tuner は、これらのログの既存の状態を使用して、検索を再開します。この動作を無効にするには、チューナーをインスタンス化する際に、overwrite = True 引数を追加で渡してください。

まとめ

このチュートリアルでは、Keras Tuner の使用して、モデルのハイパーパラメータを調整する方法を学習しました。Keras Tuner の調査委については、以下のその他のリソースをご覧ください。

また、モデルのハイパーパラメータを対話式で調整できる、TensorBoard の HParams Dashboard もご覧ください。