LoginSignup
7
7

More than 3 years have passed since last update.

Optunaで特定の初期値から最適化を開始する

Last updated at Posted at 2019-01-30

Optunaでは値の範囲を変えて追加で学習させることができる。
同様に、初期値を指定して学習を開始することも可能。
事前の手動の実験で良さそうなパラメータがわかっていてその周囲から探索してほしいとき、を想定している。

TL, DR

trial.trial_idで条件分岐させて初期値を指定する。
最適化する分布と同じ分布型(suggest_uniformとか)で指定する必要がある

ただし、カテゴリカル変数(suggest_categorical)は範囲の変更に対応していないので、カテゴリカル変数を含めて初期条件を指定したいときはリセマラしないといけないかも。

範囲を変化させる

Optunaのtutorialに載っている例から。

import optuna

def objective(trial):
    x = trial.suggest_uniform('x', -10, 10)
    return (x - 2) ** 2

study = optuna.create_study()
study.optimize(objective, n_trials=100)

study.trials_dataframe()[('params', 'x')].plot()

image.png

これは普通の最適化。

まずはtutorial通り、追加で学習する。

study.optimize(objective, n_trials=100)

study.trials_dataframe()[('params', 'x')].plot()

image.png

値の範囲を変えてみる。objectiveを再定義する。


def objective2(trial):
    x = trial.suggest_uniform('x', -40, 40)
    return (x - 2) ** 2

study.optimize(objective2, n_trials=500)
study.trials_dataframe()[('params', 'x')].plot()

image.png

初期値の設定

import optuna

def objective(trial):
    if trial.trial_id ==0:
        x = trial.suggest_uniform('x', 2, 2)
    else:
        x = trial.suggest_uniform('x', -10, 10)

    return (x - 2) ** 2

study = optuna.create_study()
study.optimize(objective, n_trials=100)

study.trials_dataframe()[('params', 'x')].plot()

image.png

study.trials_dataframe().head(5)

image.png

x=2から始めることができました。ざっとソースを眺めた限りでは、サンプリング(trial.suggest)する段階でそれ以前に試行した値とその結果を元にサンプリングしてきているようなので大きな副作用はないんじゃないかと思います。

※ ただし、suggest_categoricalで1つの値のみ指定しようとするとカテゴリ変数はdynamic range changeに対応していないといったエラーが返ってくる。

7
7
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7