ベイズ最適化の可視化をやってみました
こんにちは、医mportです。
最近理論の勉強ばかりに時間投資をしていたんですが、実装欲と言いますか、もともと工学畑でもあったせいか手を動かしたくなってました。
そこで、計算論的精神医学でも多用されているベイズ(特に統合失調症のモデル)周りでなにか応用しようかなと考えた時に最適化過程を見れる
ものなら見てみたいという思いで今回やってみました。
ベイズ最適化はハイパラ探索で主に使われます。
いつも通り、どうせ適するライブラリがあるんだろ?と期待してたら、やはりありました。GPyOptというライブラリですね。
まずはテキトーにx,y,z座標における非線形関数を定義してx,y座標でスライスしたグラフを見て見ます、等高図っぽいやつですね。
import matplotlib.pyplot as plt import numpy as np x = np.linspace(-3, 3, 100) y = np.linspace(-3, 3, 100) X, Y = np.meshgrid(x, y) Z = 0.05*(X**2+Y**2-20)**2 + 10*np.sin(2*X) plt.figure() cont = plt.contour(X, Y, Z, cmap="Greys") cont.clabel(fmt='%1.1f', fontsize=14) plt.xlabel("X") plt.ylabel("Y") plt.show()
見た感じ、右側の山の25あたりが最高値であることが検討できますが、客観的にどこが頂点なのかベイズ最適化をしていきます。
ここでの注意点はGpyOptは最低値探索であるので今回の最高値探索に適応するためにz値に画一的にマイナスをかけたところです。
import GPy import GPyOpt import numpy as np def f(x): xx,y = x[:,0],x[:,1] z = -(0.05*(xx**2+y**2-20)**2 + 10*np.sin(2*xx)) print(-z) return z bounds = [{'name': 'xx', 'type': 'continuous', 'domain': (-3,3)}, {'name': 'y', 'type': 'continuous', 'domain': (-3,3)}] #ベイズ最適化myBopt = GPyOpt.methods.BayesianOptimization(f=f, domain=bounds)myBopt.run_optimization(max_iter=30) result_x = myBopt.X result_z = -myBopt.Y plt.figure() cont = plt.contour(X, Y, Z, cmap="Greys") cont.clabel(fmt='%1.1f', fontsize=14) plt.xlabel("X") plt.ylabel("Y") sc = plt.scatter(result_x[:,0], result_x[:,1],s=50, c=range(len(result_x)),cmap="autumn") plt.colorbar(sc) plt.plot(result_x[:,0], result_x[:,1], linestyle="dashed") plt.show()
結果がこちらです。
黄色くなるほど最新の探索結果となりますが、だんだん25付近に近づいてるのがわかります。
とはいえ、一旦山を降りてたりするのですがこれは見落としを防ぐための措置なのかな?と考えます。