はじめに
前回Optunaを使ってハイパーパラメータの最適化を行っていた時に遭遇した問題についてoptunaしくじり備忘録でまとめましたが、またOptunaを使用していてやってしまったことが増えてきましたので、再度まとめてみたいと思います。
dropoutの最適化について
Optunaを使って、畳み込み層の数、全結合層のユニット数、ドロップアウト率の最適化を行ってみました。
これを実行すると以下のエラーが発生しました。
def objective(trial):
#セッションのクリア
clear_session()
num_layer = trial.suggest_int("num_layer", 2, 8)
mid_units = int(trial.suggest_float("mid_units", 128, 512, step=128))
for i in range(num_layer)]
dropout_rate = trial.suggest_float('dropout_rate', 0.0, 1.0, step=0.1)
model = create_model(num_layer, mid_units, dropout_rate)
model.compile(optimizer="adam",
loss="categorical_crossentropy",
metrics=["accuracy"])
Trial 4 failed with parameters: {'num_layer': 8, 'mid_units': 256.0, 'dropout_rate': 1.0} because of the following error: ValueError('Exception encountered when calling Dropout.call().\n\n\x1b[1m`rate` must be a scalar tensor or a float in the range [0, 1). Received: rate=1.0\x1b[0m\n\nArguments received by Dropout.call():\n inputs=tf.Tensor(shape=(None, 50, 50, 16), dtype=float32)\n • training=True').
最初は何が問題なのかよくわからなかったのですが、よくよく考えてみるとドロップアウト率が1.0ということは、すべてのノードを不活性化することになるので学習できなくなりますね。以下のように修正しました。
def objective(trial):
#セッションのクリア
clear_session()
num_layer = trial.suggest_int("num_layer", 2, 8)
mid_units = int(trial.suggest_float("mid_units", 128, 512, step=128))
for i in range(num_layer)]
dropout_rate = trial.suggest_float('dropout_rate', 0.0, 0.9, step=0.1)
model = create_model(num_layer, mid_units, dropout_rate)
model.compile(optimizer="adam",
loss="categorical_crossentropy",
metrics=["accuracy"])
repeat関数って?
Optunaを使ってハイパーパラメータの最適化を行っていると、以下のようなWarningが出ることがあります。
/usr/local/lib/python3.11/dist-packages/keras/src/trainers/epoch_iterator.py:107: UserWarning: Your input ran out of data; interrupting training. Make sure that your dataset or generator can generate at least steps_per_epoch * epochs
batches. You may need to use the .repeat()
function when building your dataset.
Warningなのでそのまま続行することができるのですが、そうすると以下のような結果になることがあります。
Trial 0 finished with value: 0.0 and parameters: {'num_layer': 2, 'mid_units': 512.0, 'dropout_rate': 0.1}. Best is trial 0 with value: 0.0.
最適化の結果が0.0?なんかおかしい。先ほどのWarningも入力データを使い果たしている?repeat()関数を使う?とよくわからないアドバイスが。
最初見たときはさっぱり原因がわからなかったけど、どうもこれらのWarningは入力データ数(Trainingデータ数やValidationデータ数)にばらつきがある場合に出ることがあるようです。
Trainingデータ数、Validationデータ数を一定にすることにより上記のWarningは出なくなりました!