AI・機械学習 python 技術関連

[optuna]パラメータ探索について解説してみる

更新日:

概要

作成したモデルの精度を上げるためのハイパーパラメータの調整について解説します。

はじめに

作成したモデルの精度を上げるために、モデルのハイパーパラメータの調整を機械的にする作業になります。
パラメータ変更→学習→精度検証を繰り返し、精度が高かったパラメータを採用します。

モデルのハイパーパラメータの例として

  • DeepLeraning
    • ノード数、層の数、dropoutの割合、バッチサイズなど
  • アンサンブル系
    • 決定機の本数、層数、サブサンプルの抽出割合、子ノードの最小重み制限など

などがあり、これらのパラメータを調整することで、精度を上げていくことが出来ます。

パラメータの調整方法としては、大きく2種類あります。

  • グリッドサーチ
    • 指定された範囲を全探索し、一番精度の高いパラメータを探索する。
  • ベイズ最適化(Optuna)
    • ベイズ統計に基づき、ベストに近いパラメータを探索する。

【グリッドサーチの図】

【ベイズ最適化の図】

使い分けの用途としては、

時間をかけて精度を上げる:グリッドサーチ
クイックにある程度の精度まで上げる:ベイズ最適化

で良いと思います。

実装

Optuna

Kerasを用いたCNN画像判別モデルに対して、
畳み込み層と活性化関数のパラメータの最適化をします。

from keras.backend import clear_session
from keras.datasets import mnist
from keras.layers import Conv2D
from keras.layers import Dense
from keras.layers import Flatten
from keras.models import Sequential
from keras.optimizers import RMSprop

import optuna


N_TRAIN_EXAMPLES = 3000
N_VALID_EXAMPLES = 1000
BATCHSIZE = 128
CLASSES = 10
EPOCHS = 10


def objective(trial):
    # Clear clutter from previous Keras session graphs.
    clear_session()

    (x_train, y_train), (x_valid, y_valid) = mnist.load_data()
    img_x, img_y = x_train.shape[1], x_train.shape[2]
    x_train = x_train.reshape(-1, img_x, img_y, 1)[:N_TRAIN_EXAMPLES].astype("float32") / 255
    x_valid = x_valid.reshape(-1, img_x, img_y, 1)[:N_VALID_EXAMPLES].astype("float32") / 255
    y_train = y_train[:N_TRAIN_EXAMPLES]
    y_valid = y_valid[:N_VALID_EXAMPLES]
    input_shape = (img_x, img_y, 1)

    model = Sequential()
    model.add(
        Conv2D(
            filters=trial.suggest_categorical("filters", [32, 64]),
            kernel_size=trial.suggest_categorical("kernel_size", [3, 5]),
            strides=trial.suggest_categorical("strides", [1, 2]),
            activation=trial.suggest_categorical("activation", ["relu", "linear"]),
            input_shape=input_shape,
        )
    )
    model.add(Flatten())
    model.add(Dense(CLASSES, activation="softmax"))

    # We compile our model with a sampled learning rate.
    lr = trial.suggest_loguniform("lr", 1e-5, 1e-1)
    model.compile(
        loss="sparse_categorical_crossentropy", optimizer=RMSprop(lr=lr), metrics=["accuracy"]
    )

    model.fit(
        x_train,
        y_train,
        validation_data=(x_valid, y_valid),
        shuffle=True,
        batch_size=BATCHSIZE,
        epochs=EPOCHS,
        verbose=False,
    )

    # Evaluate the model accuracy on the validation set.
    score = model.evaluate(x_valid, y_valid, verbose=0)
    return score[1]


if __name__ == "__main__":
    study = optuna.create_study(direction="maximize")
    study.optimize(objective, n_trials=100, timeout=600)

    print("Number of finished trials: {}".format(len(study.trials)))

    print("Best trial:")
    trial = study.best_trial

    print("  Value: {}".format(trial.value))

    print("  Params: ")
    for key, value in trial.params.items():
        print("    {}: {}".format(key, value))

おわりに

モデルの学習に時間がかかる場合は、
パラメータの最適化作業も時間がかかるので、
場合によっては、省略することもあります。

転職での面接で、
パラメータの調整方法について質問されたことがあるので、
知っておいて損はないと思います。

-AI・機械学習, python, 技術関連

Copyright© AIなんて気合いダッ! , 2020 All Rights Reserved Powered by AFFINGER5.