Help us understand the problem. What is going on with this article?

ベイズ最適化シリーズ(5) -リアルな実験で使ってみたい-

More than 1 year has passed since last update.

ベイズ最適化シリーズ5回目。
今回は、リアルな実験でベイズ最適化を使う方法をご紹介します。

ベイズ最適化シリーズ(1) -ベイズ最適化の可視化-
ベイズ最適化シリーズ(2) -アンサンブル学習(Voting)の最適化-
ベイズ最適化シリーズ(3) -XGBoostのハイパーパラメータ探索-
ベイズ最適化シリーズ(4) -ゲームの攻略-

scince_jikken.png

リアルな実験でベイズ最適化

ベイズ最適化は、機械学習のパラメータ設定のみならず、化学実験や物理実験などのリアルな実験でも威力を発揮します。

今回はGPyOptを使い、リアルな実験を想定したコードを書いてみました。

実験のながれ

今回想定している実験の流れを下記に示します。

  • 予備実験のデータを2つ持っている。(予備実験のデータを持っていない場合でも対応できます。)
  • 予備実験のデータをGPyOptに投げ、最初の実験条件を提示してもらう。
  • ①提示された条件で実験を行い、実験結果を入力する。
  • ②実験結果をGPyOptに投げ、次の実験条件を提示してもらう。
  • ①と②を繰り返し、規定回数まで行うと実験終了。
  • 最後に、最適な実験条件を提示してもらう。

とりあえず、コードをコピペして動かしていただければ、何をやっているかは分かるかと思います。

問題設定

本当は、ピタゴラスイッチ的な実験装置を用意したかったのですが、時間の都合上、数値計算で代替しました。

以下のyの最小値を求める問題を考えます。

y = x^2

GPyOptからxが提示されますので、yを計算後、入力するものです。

皆さんが実験する際、上記の式は未知だと思いますので、xを実験条件、yを実験結果に置き換えて使ってみてください。

コード

import GPy
import GPyOpt
import numpy as np

#予備実験のデータ
initial_x = np.array([-1, 0.5])
initial_y = np.array([1, 0.25])

initial_x = initial_x.reshape((-1,1))
initial_y = initial_y.reshape((-1,1))

#実験回数
exp_num = 5

try_ = 1

def f(x):
    global try_

    print("Try : " , try_ , " / {0} , next x is ".format(exp_num) , x)
    score = float(input("Input y : "))

    try_ += 1

    return score

bounds = [{'name': 'a', 'type': 'continuous', 'domain': (-2,2)}]#実験条件の範囲

print("Bayesian Optimization")

#予備実験のデータを持っていない場合はinitial_design_numdataの値を変更
myBopt = GPyOpt.methods.BayesianOptimization(f=f,
                                             domain=bounds,
                                             X = initial_x,
                                             Y = initial_y,
                                             initial_design_numdata=0)
myBopt.run_optimization(max_iter=exp_num)

#最適なパラメータ
print("Best x is ",myBopt.x_opt)

ベイズ最適化の際に、渡す変数はこちらを見ていただければ分かります。

結果

上記のコードを走らせると以下のような結果になります。
なお、Input yの部分は私が手計算して、入力しています。

Bayesian Optimization
Try :  1  / 5 , next x is  [[0.60906033]]
Input y : 0.36
Try :  2  / 5 , next x is  [[0.21945366]]
Input y : 0.0479
Try :  3  / 5 , next x is  [[2.]]
Input y : 4
Try :  4  / 5 , next x is  [[-0.087055]]
Input y : 0.0064
Try :  5  / 5 , next x is  [[0.01745743]]
Input y : 0.000289
Best x is  [0.01745743]

ということで、最適なxは「0.01745」と求められました。
解析的には「0」が最適値ですので、ほぼ到達できたかと思います。

一応、アニメーションにしてみました。

movie (2).gif

青い点は予備実験のデータで、赤い点はベイズ最適化で実験したものです。

shinmura0
自己紹介はツイッターをご覧ください。 https://twitter.com/shinmura0
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away