Keras 2 : ガイド : ハイパーパラメータ調整 – KerasTuner で始める (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 10/29/2021 (keras 2.6.0)
* 本ページは、Keras の以下のドキュメントを翻訳した上で適宜、補足説明したものです:
- Getting started with KerasTuner (Author: Luca Invernizzi, James Long, Francois Chollet, Tom O’Malley, Haifeng Jin)
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- 人工知能研究開発支援
- 人工知能研修サービス(経営者層向けオンサイト研修)
- テクニカルコンサルティングサービス
- 実証実験(プロトタイプ構築)
- アプリケーションへの実装
- 人工知能研修サービス
- PoC(概念実証)を失敗させないための支援
- テレワーク & オンライン授業を支援
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
- ウェビナー運用には弊社製品「ClassCat® Webinar」を利用しています。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション |
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/ ; Facebook |
Keras 2 : ガイド : ハイパーパラメータ調整 – KerasTuner で始める
セットアップ
!pip install keras-tuner -q
イントロダクション
ここに、単一層の dense ニューラルネットワークのためにランダム探索を使用してハイパーパラメータ調整を実行する方法があります。最初に、データセットを準備する必要があります — 例として MNIST データセットを使用しましょう。
from tensorflow import keras
import numpy as np
(x, y), (x_test, y_test) = keras.datasets.mnist.load_data()
x_train = x[:-10000]
x_val = x[-10000:]
y_train = y[:-10000]
y_val = y[-10000:]
x_train = np.expand_dims(x_train, -1).astype("float32") / 255.0
x_val = np.expand_dims(x_val, -1).astype("float32") / 255.0
x_test = np.expand_dims(x_test, -1).astype("float32") / 255.0
num_classes = 10
y_train = keras.utils.to_categorical(y_train, num_classes)
y_val = keras.utils.to_categorical(y_val, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz 11493376/11490434 [==============================] - 0s 0us/step
モデル構築関数の準備
次に、モデル構築関数を定義します。それは引数 hp を取り、それから hp.Int(‘units’, min_value=32, max_value=512, step=32) (特定の範囲からの整数) のようなハイパーパラメータをサンプリングできます。
この関数はコンパイルされたモデルを返します。
from tensorflow.keras import layers
from keras_tuner import RandomSearch
def build_model(hp):
model = keras.Sequential()
model.add(layers.Flatten())
model.add(
layers.Dense(
units=hp.Int("units", min_value=32, max_value=512, step=32),
activation="relu",
)
)
model.add(layers.Dense(10, activation="softmax"))
model.compile(
optimizer=keras.optimizers.Adam(
hp.Choice("learning_rate", values=[1e-2, 1e-3, 1e-4])
),
loss="categorical_crossentropy",
metrics=["accuracy"],
)
return model
探索の開始
次にチューナーをインスタンス化しましょう。モデル構築関数、最適化する目的 (関数) の名前 (組込みメトリクスのために最小化か最大化かは自動的に推論されます)、テストするトライアルの総数 (max_trials)、そして各トライアルのために構築されて fit されるべきモデルの数 (executions_per_trial) を指定する必要があります。
同じディレクトリの前の結果を上書きするか、代わりに前の探索を resume するかを制御するために overwrite 引数を使用します。ここでは新しい探索を始めて任意の前の結果を無視するために overwrite=True を設定します。
利用可能なチューナーは RandomSearch, BayesianOptimization と Hyperband です。
Note : トライアル毎に複数の実行を持つ目的は、結果のばらつきを削減してモデルの性能をより正確に評価できるようにすることです。結果を早く得ることを望む場合には、executions_per_trial=1 を設定できます (各モデル configuration のために訓練の単一ラウンド)。
tuner = RandomSearch(
build_model,
objective="val_accuracy",
max_trials=3,
executions_per_trial=2,
overwrite=True,
directory="my_dir",
project_name="helloworld",
)
探索空間の概要をプリントできます :
tuner.search_space_summary()
Search space summary Default search space size: 2 units (Int) {'default': None, 'conditions': [], 'min_value': 32, 'max_value': 512, 'step': 32, 'sampling': None} learning_rate (Choice) {'default': 0.01, 'conditions': [], 'values': [0.01, 0.001, 0.0001], 'ordered': True}
そして、最善のハイパーパラメータ configuration のために探索を開始します。search の呼び出しは model.fit() と同じシグネチャを持ちます。
tuner.search(x_train, y_train, epochs=2, validation_data=(x_val, y_val))
Trial 3 Complete [00h 00m 18s] val_accuracy: 0.9421000182628632 Best val_accuracy So Far: 0.9730499982833862 Total elapsed time: 00h 00m 48s INFO:tensorflow:Oracle triggered exit
ここに search で何が起きるかがあります : モデルはモデル構築関数を呼び出して繰り返し構築されます、これは hp オブジェクトにより追跡されるハイパーパラメータ空間 (探索空間) を装着 (= populate) しています。チューナーは各 configuration のメトリクスを記録し、空間を着実に探索します。
結果の照会
探索が終われば、最善なモデルを取得できます :
models = tuner.get_best_models(num_models=2)
あるいは結果の概要をプリントします :
tuner.results_summary()
Results summary Results in my_dir/helloworld Showing 10 best trials Objective(name='val_accuracy', direction='max') Trial summary Hyperparameters: units: 480 learning_rate: 0.001 Score: 0.9730499982833862 Trial summary Hyperparameters: units: 160 learning_rate: 0.001 Score: 0.9692499935626984 Trial summary Hyperparameters: units: 320 learning_rate: 0.0001 Score: 0.9421000182628632
フォルダ my_dir/helloworld, i.e. directory/project_name で詳細ログ, チェックポイント等も確認できます。
!ls -lF my_dir
total 4 drwxr-xr-x 5 root root 4096 Oct 30 17:47 helloworld/
!ls -lF my_dir/helloworld
total 20 -rw-r--r-- 1 root root 562 Oct 30 17:48 oracle.json drwxr-xr-x 3 root root 4096 Oct 30 17:47 trial_38c18dc42c8215921342967e705fb7b7/ drwxr-xr-x 3 root root 4096 Oct 30 17:47 trial_44e452393ca7b661b763d3726694260e/ drwxr-xr-x 3 root root 4096 Oct 30 17:47 trial_8190edd37fa9ab82471f11f1027fca9c/ -rw-r--r-- 1 root root 2 Oct 30 17:48 tuner0.json
!ls -lF my_dir/helloworld/trial_38c18dc42c8215921342967e705fb7b7/
total 8 drwxr-xr-x 3 root root 4096 Oct 30 17:47 checkpoints/ -rw-r--r-- 1 root root 909 Oct 30 17:47 trial.json
!ls -lF my_dir/helloworld/trial_38c18dc42c8215921342967e705fb7b7/checkpoints
total 4 drwxr-xr-x 2 root root 4096 Oct 30 17:47 epoch_0/
!ls -lF my_dir/helloworld/trial_38c18dc42c8215921342967e705fb7b7/checkpoints/epoch_0
total 2396 -rw-r--r-- 1 root root 77 Oct 30 17:47 checkpoint -rw-r--r-- 1 root root 2444433 Oct 30 17:47 checkpoint.data-00000-of-00001 -rw-r--r-- 1 root root 1215 Oct 30 17:47 checkpoint.index
探索空間は条件付きハイパーパラメータを含む場合があります
以下では、調整可能な数の層を作成する “for” ループを持ち、それら自身が調整可能な units パラメータを含みます。
これは再帰を含む、任意のレベルのパラメータに相互依存関係的に押し進められます。
総てのパラメータ名は一意である必要があることに注意してください (ここでは、i に対するループ内で、内側のパラメータに ‘units_’ + str(i) と名前を付けています)。
def build_model(hp):
model = keras.Sequential()
model.add(layers.Flatten())
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",
)
)
model.add(layers.Dense(10, activation="softmax"))
model.compile(
optimizer=keras.optimizers.Adam(hp.Choice("learning_rate", [1e-2, 1e-3, 1e-4])),
loss="categorical_crossentropy",
metrics=["accuracy"],
)
return model
モデル構築関数の代わりに HyperModel サブクラスの使用が可能
これはハイパーモデルの共有と再利用を簡単にします。
HyperModel サブクラスは build(self, hp) メソッドを実装する必要があるだけです。
from keras_tuner import HyperModel
class MyHyperModel(HyperModel):
def __init__(self, classes):
self.classes = classes
def build(self, hp):
model = keras.Sequential()
model.add(layers.Flatten())
model.add(
layers.Dense(
units=hp.Int("units", min_value=32, max_value=512, step=32),
activation="relu",
)
)
model.add(layers.Dense(self.classes, activation="softmax"))
model.compile(
optimizer=keras.optimizers.Adam(
hp.Choice("learning_rate", values=[1e-2, 1e-3, 1e-4])
),
loss="categorical_crossentropy",
metrics=["accuracy"],
)
return model
hypermodel = MyHyperModel(classes=10)
tuner = RandomSearch(
hypermodel,
objective="val_accuracy",
max_trials=3,
overwrite=True,
directory="my_dir",
project_name="helloworld",
)
tuner.search(x_train, y_train, epochs=2, validation_data=(x_val, y_val))
Trial 3 Complete [00h 00m 10s] val_accuracy: 0.9571999907493591 Best val_accuracy So Far: 0.9573000073432922 Total elapsed time: 00h 00m 28s INFO:tensorflow:Oracle triggered exit
KerasTuner は事前作成済みの調整可能なアプリケーションを含みます : HyperResNet と HyperXception
これらはコンピュータビジョンのための ready-to-use ハイパーモデルです。
これらは loss=”categorical_crossentropy” と metrics=[“accuracy”] で事前コンパイルされています。
from keras_tuner.applications import HyperResNet
hypermodel = HyperResNet(input_shape=(28, 28, 1), classes=10)
tuner = RandomSearch(
hypermodel,
objective="val_accuracy",
max_trials=3,
overwrite=True,
directory="my_dir",
project_name="helloworld",
)
tuner.search(
x_train[:100], y_train[:100], epochs=1, validation_data=(x_val[:100], y_val[:100])
)
Trial 3 Complete [00h 00m 34s] val_accuracy: 0.10000000149011612 Best val_accuracy So Far: 0.10000000149011612 Total elapsed time: 00h 01m 45s INFO:tensorflow:Oracle triggered exit
探索空間を幾つかのパラメータだけに簡単に制限できます
既存のハイパーモデルを持ち、(学習率のような) 幾つかのパラメータだけに渡り探索したい場合、hyperparameters 引数と (hyperparameters にリストされていないパラメータは調整される必要がないことを指定するために) tune_new_entries=False をチューナー・コンストラクタに渡すことによりそれを行なうことができます。これらのパラメータについては、デフォルト値が使用されます。
from keras_tuner import HyperParameters
from keras_tuner.applications import HyperXception
hypermodel = HyperXception(input_shape=(28, 28, 1), classes=10)
hp = HyperParameters()
# This will override the `learning_rate` parameter with your
# own selection of choices
hp.Choice("learning_rate", values=[1e-2, 1e-3, 1e-4])
tuner = RandomSearch(
hypermodel,
hyperparameters=hp,
# `tune_new_entries=False` prevents unlisted parameters from being tuned
tune_new_entries=False,
objective="val_accuracy",
max_trials=3,
overwrite=True,
directory="my_dir",
project_name="helloworld",
)
tuner.search(
x_train[:100], y_train[:100], epochs=1, validation_data=(x_val[:100], y_val[:100])
)
Trial 3 Complete [00h 00m 02s] val_accuracy: 0.10999999940395355 Best val_accuracy So Far: 0.10999999940395355 Total elapsed time: 00h 00m 08s INFO:tensorflow:Oracle triggered exit
パラメータのデフォルト値について
モデル構築関数やハイパーモデルの build メソッド内でハイパーパラメータを登録するときはいつでも、デフォルト値を指定できます :
hp.Int("units", min_value=32, max_value=512, step=32, default=128)
そうでない場合には、ハイパーパラメータは常にデフォルトを持ちます (Int については、それは min_value に等しいです)。
ハイパーモデルの値を固定する
反対のことを行ないたい場合 – ハイパーパラメータの総ての利用可能なパラメータを、1 つ (学習率) を除いて調整したい場合はどうでしょう?
(一つの) Fixed エントリ (あるいは任意の数の Fixed エントリ) を持つ hyperparameters 引数を渡して、tune_new_entries=True を指定します。
hypermodel = HyperXception(input_shape=(28, 28, 1), classes=10)
hp = HyperParameters()
hp.Fixed("learning_rate", value=1e-4)
tuner = RandomSearch(
hypermodel,
hyperparameters=hp,
tune_new_entries=True,
objective="val_accuracy",
max_trials=3,
overwrite=True,
directory="my_dir",
project_name="helloworld",
)
tuner.search(
x_train[:100], y_train[:100], epochs=1, validation_data=(x_val[:100], y_val[:100])
)
Trial 3 Complete [00h 00m 07s] val_accuracy: 0.10000000149011612 Best val_accuracy So Far: 0.11999999731779099 Total elapsed time: 00h 00m 17s INFO:tensorflow:Oracle triggered exit
コンパイル引数を override する
既存の optimizer, 損失やメトリクスを変更したいハイパーモデルを持つ場合、これらの引数をチューナーのコンストラクタに渡すことによりそれを行なうことができます :
hypermodel = HyperXception(input_shape=(28, 28, 1), classes=10)
tuner = RandomSearch(
hypermodel,
optimizer=keras.optimizers.Adam(1e-3),
loss="mse",
metrics=[
keras.metrics.Precision(name="precision"),
keras.metrics.Recall(name="recall"),
],
objective="val_loss",
max_trials=3,
overwrite=True,
directory="my_dir",
project_name="helloworld",
)
tuner.search(
x_train[:100], y_train[:100], epochs=1, validation_data=(x_val[:100], y_val[:100])
)
Trial 3 Complete [00h 00m 07s] val_loss: 0.09853753447532654 Best val_loss So Far: 0.08992436528205872 Total elapsed time: 00h 00m 23s INFO:tensorflow:Oracle triggered exit
以上