[最適化問題]Optuna vs Hyperopt
はじめに
最適化フレームワークとして、OptunaとHyperoptがあります。一体どちらが優れているのか気になったので、関数最適化問題を使って比較してみようと思います。
2つのフレームワークに関しては別記事で紹介しているので、そちらを参考にしてください。
Optunaを使って関数最適化をしてみる
Hyperoptを使って関数最適化をしてみる
比較実験
今回は
x^2+y^2+z^2
の最小化問題を最適化していきます。
試行ごとに結果が異なるため, 3回試行してみようと思います。
コード
今回、実験するために使用したコードは以下になります。
# -*- coding: utf-8 -*-
import optuna
import hyperopt
from hyperopt import hp
from hyperopt import fmin
from hyperopt import tpe
from hyperopt import Trials
import matplotlib.pyplot as plt
# optuna用の目的関数を設定(今回はx^2+y^2+z^2)
def objective_optuna(trial):
# 最適化するパラメータを設定
param = {
'x': trial.suggest_uniform('x', -100, 100),
'y': trial.suggest_uniform('y', -100, 100),
'z': trial.suggest_uniform('z', -100, 100)
}
# 評価値を返す(デフォルトで最小化するようになっている)
return param['x'] ** 2 + param['y'] ** 2 + param['z'] ** 2
# optunaで最適化実行
def optuna_exe():
# studyオブジェクト生成
study = optuna.create_study()
# 最適化実行
study.optimize(objective_optuna, n_trials=500)
# ベストパラメータ表示
print(study.best_params)
# ベスト目的関数値を表示
print(study.best_value)
epoches = [] # 試行回数格納用
values = [] # ベストvalue格納用
best = 100000
# best更新
for i in study.trials:
if best > i.value:
best = i.value
epoches.append(i.number + 1)
values.append(best)
return epoches, values
# hyperopt用の目的関数を設定
def objective_hyperopt(args):
x, y, z = args
return x ** 2 + y ** 2 + z ** 2
# hyperoptで最適化実行
def hyperopt_exe():
# 探索空間の設定
space = [
hp.uniform('x', -100, 100),
hp.uniform('y', -100, 100),
hp.uniform('z', -100, 100)
]
# 探索の様子を記録するためのオブジェクト
trials = Trials()
# 探索開始
best = fmin(objective_hyperopt, space, algo=tpe.suggest, max_evals=500, trials=trials)
# 結果を出力する
print(best)
epoches = [] # 試行回数格納用
values = [] # ベストvalue格納用
best = 100000
# best更新
for i, n in zip(trials.trials, range(500)):
if best > i['result']['loss']:
best = i['result']['loss']
epoches.append(n+1)
values.append(best)
return epoches, values
def plot_graph():
result_optuna = optuna_exe()
result_hyperopt = hyperopt_exe()
epoch_optuna = result_optuna[0]
value_optuna = result_optuna[1]
epoch_hyperopt = result_hyperopt[0]
value_hyperopt = result_hyperopt[1]
# グラフの描画
fig, ax = plt.subplots()
ax.set_xlabel("trial")
ax.set_ylabel("value")
ax.set_title("Optuna vs Hyperopt")
ax.grid() # グリッド線を入れる
ax.plot(epoch_optuna, value_optuna, color="red", label="Optuna")
ax.plot(epoch_hyperopt, value_hyperopt, color="blue", label="Hyperopt")
ax.legend(loc=0) # 凡例
plt.show() # グラフ表示
if __name__ == '__main__':
plot_graph()
実験結果1回目
Optuna:
'x': 0.2690396239515218,
'y': -1.75236444646743,
'z': 0.3724308175904496,
best_value:3.2818681863901693
Hyperopt:
'x': -2.9497423868903834,
'y': 0.13662455602710644,
'z': -3.844496541052724,
best_value:23.499800072493738
最終的なbest_valueはOptunaが優れていますね。
グラフより収束速度もOptunaが優れているかなといった感じですかね。
実験結果2回目
Optuna:
'x': 0.7811129871251672,
'y': 0.4130867942356189,
'z': 0.6953642534092288,
best_value:1.2643096431468364
Hyperopt:
'x': -3.7838067947126675,
'y': -2.595648793357423,
'z': -2.683504623035553,
best_value:28.255783580024783
2回目も1回目と同様、最終的なbest_valueと収束速度の面でOptunaが優れていますかね。
実験結果3回目
Optuna:
'x': -0.19339325990518663,
'y': -0.0030977352573082623,
'z': 0.4961595538587318,
best_value:0.2835848518257752
Hyperopt:
'x': 2.810074634010315,
'y': -1.2603362587820195,
'z': -0.7356174272489406,
best_value:10.026099933181214
3回目も最終的なbest_valueの値はOptunaが優れていました。収束速度はあまり変わらない気がしますね。
結論
最終的な最良目的関数値、収束速度の面でOptunaが優れている、との結論に至りました。
最適化問題をもう少し難しくしたら、差も大きく出るのだろうか...
Author And Source
この問題について([最適化問題]Optuna vs Hyperopt), 我々は、より多くの情報をここで見つけました https://qiita.com/pontyo4/items/6ac690c5114a619f9da0著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .