📚

Keras Tunerでハイパーパラメータチューニング

2021/03/05に公開

kaggleでKerasによるニューラルネットワークモデルのハイパーパラメータチューニンがしたく、Keras Tunerを使ってみました。

今回は、Titanicコンペで実際に使ってみながら紹介していきます。

対象読者

  • Kerasのモデルでハイパーパラメータチューニングしたい
  • Keras Tunerを使ってみたい

ゴール

  • Keras Tunerでハイパーパラメータチューニングができる

Keras Tunerとは

Kerasでハイパーパラメータチューニングができるライブラリです。
層やユニットの数、どの層を使うかなど、モデルを構築する上で様々なパラメータをチューニングすることができます。

Titanicコンペでやってみる

実際にTitanicコンペのデータを使ってKeras Tunerを使っていきます。
https://www.kaggle.com/c/titanic

データの前処理の詳しい説明については、割愛しています。

インストール

まずはKeras Tunerをインストールします。

pip install keras-tuner

インポート

チューニングするRandomSearchをインポートします。

from kerastuner.tuners import RandomSearch

モデルの定義

Keras Tunerでパラメータチューニングできるようにモデルを定義していきます。

今回設定しているパラメータは以下の4つになります。

  • 層の数 (2~20)
    • hp.Int('num_layers', 2, 20)
  • ユニットの数 (32~512の32ごと値)
    • hp.Int('units_' + str(i), min_value=32, max_value=512, step=32)
  • BatchNormalizationかDropoutかどちらもか
    • hp.Choice('batchnorm_and_dropout', ['batch', 'dropout', 'both'])
  • 学習率 (1e-2, 1e-3, 1e-4)
    • hp.Choice('learning_rate', [1e-2, 1e-3, 1e-4])
def build_model(hp):
    model = keras.Sequential()
    for i in range(hp.Int('num_layers', 2, 20)):
        model.add(layers.Dense(units=hp.Int('units_' + str(i),
                                            min_value=32,
                                            max_value=512,
                                            step=32),
                               activation='relu'))
        if hp.Choice('batchnorm_and_dropout', ['batch', 'dropout', 'both']) == 'batch':
            model.add(layers.BatchNormalization())
        elif hp.Choice('batchnorm_and_dropout', ['batch', 'dropout', 'both']) == 'dropout':
            model.add(layers.Dropout(0.2))
        else:
            model.add(layers.BatchNormalization())
            model.add(layers.Dropout(0.2))
    model.add(layers.Dense(1, activation="sigmoid"))
    model.compile(
        optimizer=keras.optimizers.Adam(
            hp.Choice('learning_rate', [1e-2, 1e-3, 1e-4])),
        loss=keras.losses.BinaryCrossentropy(from_logits=True),
        metrics=[keras.metrics.BinaryAccuracy(name='acc')])
    return model

今回はhp.Inthp.Choiceを使いましたが、他にも種類があります。

https://keras-team.github.io/keras-tuner/documentation/hyperparameters/

チューニング

定義したモデルを使ってインスタンス化します。
今回はRandomSearchを利用してチューニングをします。

tuner = RandomSearch(
    build_model,
    objective='val_acc',
    max_trials=100,
    overwrite=True)

https://keras-team.github.io/keras-tuner/documentation/tuners/

チューニング実行中のコールバックを定義できます。EarlyStoppingを利用するとチューニングの実行を短縮できます。

callbacks=[keras.callbacks.EarlyStopping(monitor='val_acc', mode='max', patience=3)]

チューニング実行していきます。
与えられた学習データ(X, y)を、学習データと検証データに分けて利用します。

X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.3)
tuner.search(X_train, y_train, validation_data=(X_val, y_val), callbacks=callbacks, epochs=100)

チューニングしたパラメータを使う

最も良かったパラメータでモデルを構築して、学習します。

best_hp = tuner.get_best_hyperparameters()[0]
model = build_model(best_hp)
model.fit(X, y, epochs=1000)

今回は以下のようなモデルになりました。

Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
dense_4 (Dense)              (None, 256)               2560
_________________________________________________________________
batch_normalization_3 (Batch (None, 256)               1024
_________________________________________________________________
dense_5 (Dense)              (None, 128)               32896
_________________________________________________________________
batch_normalization_4 (Batch (None, 128)               512
_________________________________________________________________
dense_6 (Dense)              (None, 256)               33024
_________________________________________________________________
batch_normalization_5 (Batch (None, 256)               1024
_________________________________________________________________
dense_7 (Dense)              (None, 256)               65792
_________________________________________________________________
batch_normalization_6 (Batch (None, 256)               1024
_________________________________________________________________
dense_8 (Dense)              (None, 1)                 257
=================================================================
Total params: 138,113
Trainable params: 136,321
Non-trainable params: 1,792
_________________________________________________________________

学習したモデルでの予測を提出したらスコアは0.73684でした。

まとめ

  • Keras Tunerでハイパーパラメータチューニングが簡単にできる

kaggleのKernelも作成したので、良かったら見てください。

https://www.kaggle.com/masaonda/titanic-hyperparameter-tuning-with-keras-tuner

参考

Discussion