RosenbrockをBayesian推定で最適化を行ったまとめ - materialsintegration/optimization_by_sipmi GitHub Wiki
Python: BayesianOptimizationパッケージを使用した最適化の試行
概要
pythonのパラメータ最適化パッケージの一つであり、最適化手法の一つである、Bayse推定による最適化の検証をまとめる。
※Bayse推定による最適化の詳細は以下の参考ページによる。
環境
- OS:CentOS7.x
- python:3.6
- py_bayesian_optimization:1.0.1
最適化の対象
Rosenbrock関数の最適化
注意点
Bayes最適化は関数の戻り値を最大にすることを行うので、評価はRosenbrock式を以下のようにした。
def rosenbrock(x, y):
'''
Rosenbrock関数
'''
return -1.0 * (100 * (y - x ** 2) ** 2 + ( 1 - x) ** 2)
試行について
試行方法について記述する。実行に係るパラメータ自体少ないので、ネット検索で頻繁に現れる数値を使用した。
-
パラメータ
- init_points*1:3と100
- n_iter*2:50、100と1000
- 以上の組み合わせ(全組み合わせではない)
-
その他
- n_iter = 50を連続して10回実行した。
※1:実行したいランダム探索のステップ数。
※2:実行するBayes最適化のステップ数。ステップが多いほど適切な最大値を見つける可能性が高くなる。
試行の結果
確からしさ
Python: BayesianOptimizationの実際の離散図である。以下に挙げる試行8回分の最適解のプロット図[@testo:test_optimize]。本最適化パッケージがどの程度の確からしさを持っているかを確認した。
{"#testo:test_optimize}
obj_funcが-3019.59938412702の場合を除いて、ほぼ望んた通りの結果となっている。
結果
以下の結果は標準出力に出力された結果表示をコピー・アンド・ペーストでログファイルとしたものを転記した。
-
注意点
- targetの指数表示が切れている。
- 2回目から最終値を取得して標準出力に出力するようにした。
-
n_iterを50とし、5回別々に実行したもの
- 1回目
| iter | target | x | y | ------------------------------------------------- | 1 | -1.616e+0 | 0.6353 | 4.424 | | 2 | -2.275e+0 | -0.2737 | 4.843 | | 3 | -624.0 | 0.134 | -2.479 | | 4 | -624.5 | 0.1341 | -2.48 | | 5 | -562.8 | 0.1242 | -2.355 | ・・・ 途中省略 ・・・ | 46 | -1.093 | -0.0438 | 0.007606 | | 47 | -1.088 | -0.04173 | 0.007294 | | 48 | -1.087 | -0.03979 | 0.009049 | | 49 | -1.069 | -0.03289 | 0.005619 | | 50 | -1.026 | -0.01311 | -0.000169 | | 51 | -0.996 | 0.00393 | -0.006164 | | 52 | -0.9336 | 0.03691 | -0.006435 | | 53 | -0.8982 | 0.06219 | -0.009828 | ================================================= - 2回目
| iter | target | x | y | ------------------------------------------------- | 1 | -2.348e+0 | 2.882 | 3.463 | | 2 | -3.139e+0 | -4.307 | 0.8412 | | 3 | -1.008e+0 | -2.28 | 2.041 | | 4 | -502.8 | 0.221 | -2.192 | | 5 | -3.952e+0 | -4.18 | -2.399 | ・・・ 途中省略 ・・・ | 47 | -6.152 | -1.478 | 2.195 | | 48 | -6.152 | -1.48 | 2.191 | | 49 | -6.141 | -1.478 | 2.188 | | 50 | -6.146 | -1.479 | 2.19 | | 51 | -6.137 | -1.477 | 2.185 | | 52 | -6.139 | -1.477 | 2.187 | | 53 | -6.139 | -1.478 | 2.185 | ================================================= {'target': -6.1364599778303788, 'params': {'x': -1.4765781657692947, 'y': 2.1857790478444765}} - 3回目
| iter | target | x | y | ------------------------------------------------- | 1 | -3.052e+0 | 3.899 | -2.268 | | 2 | -1.048e+0 | -3.177 | -0.1338 | | 3 | -4.401e+0 | 4.829 | 2.343 | | 4 | -1.053e+0 | -3.181 | -0.1346 | | 5 | -1.048e+0 | -3.177 | -0.1338 | ・・・ 途中省略 ・・・ | 47 | -3.643e+0 | -2.5 | 0.2233 | | 48 | -3.518e+0 | -2.483 | 0.2424 | | 49 | -3.473e+0 | -2.479 | 0.262 | | 50 | -3.481e+0 | -2.481 | 0.2635 | | 51 | -3.335e+0 | -2.456 | 0.2663 | | 52 | -3.148e+0 | -2.424 | 0.2761 | | 53 | -3.02e+03 | -2.402 | 0.2833 | ================================================= {'target': -3019.5993841270201, 'params': {'x': -2.4016288599121838, 'y': 0.28327169586788381}} - 4回目
| iter | target | x | y | ------------------------------------------------- | 1 | -1.386e+0 | -1.218 | -2.231 | | 2 | -2.865e+0 | -3.454 | -4.99 | | 3 | -173.8 | 2.305 | 4.003 | | 4 | -157.7 | 1.136 | 0.0358 | | 5 | -157.7 | 1.136 | 0.0358 | ・・・ 途中省略 ・・・ | 47 | -0.2733 | 0.5057 | 0.2387 | | 48 | -0.2642 | 0.5002 | 0.2382 | | 49 | -0.2925 | 0.5116 | 0.2385 | | 50 | -0.2635 | 0.5009 | 0.2389 | | 51 | -0.276 | 0.5039 | 0.2366 | | 52 | -0.2615 | 0.5008 | 0.2397 | | 53 | -0.2545 | 0.4979 | 0.243 | ================================================= {'target': -0.25448513878494755, 'params': {'x': 0.49789623371486674, 'y': 0.24302526554569737}} - 5回目
| iter | target | x | y | ------------------------------------------------- | 1 | -1.704e+0 | -3.699 | 0.6345 | | 2 | -463.6 | 1.631 | 4.811 | | 3 | -8.086e+0 | -3.013 | 0.09387 | | 4 | -1.711e+0 | 4.24 | 4.906 | | 5 | -4.574e+0 | -3.247 | 3.797 | | 6 | -554.1 | -2.378 | 3.326 | | 7 | -463.9 | 1.63 | 4.811 | | 8 | -455.6 | 1.636 | 4.811 | ・・・ 途中省略 ・・・ | 47 | -1.357 | 2.16 | 4.675 | | 48 | -1.362 | 2.159 | 4.676 | | 49 | -1.368 | 2.159 | 4.676 | | 50 | -1.36 | 2.16 | 4.678 | | 51 | -1.353 | 2.163 | 4.681 | | 52 | -1.353 | 2.159 | 4.673 | | 53 | -1.365 | 2.158 | 4.674 | ================================================= {'target': -1.3485468781465919, 'params': {'x': 2.1611062482359804, 'y': 4.6723274153171159}}
- 1回目
-
n_iterを50とし、10回連続で実行したもの
- 1回目
step 0 ------------------------------------------------- | iter | target | x | y | ------------------------------------------------- | 1 | -2.628e+0 | -3.709 | -2.447 | | 2 | -83.29 | -1.098 | 0.3181 | | 3 | -7.799e+0 | 2.114 | -4.361 | | 4 | -2.832e+0 | -4.169 | 0.5546 | | 5 | -1.661e+0 | -1.135 | -2.782 | | 6 | -423.3 | -1.401 | -0.07944 | ・・・ 途中省略 ・・・ | 524 | -0.8144 | 1.902 | 3.612 | | 525 | -0.8034 | 1.895 | 3.588 | | 526 | -0.806 | 1.896 | 3.6 | | 527 | -0.8079 | 1.899 | 3.606 | | 528 | -0.8039 | 1.896 | 3.598 | | 529 | -0.7999 | 1.894 | 3.59 | | 530 | -0.8243 | 1.891 | 3.557 | ================================================= {'target': -0.79580733024233774, 'params': {'x': 1.8884565804399678, 'y': 3.574300836686076}} - 2回目
step 0 ------------------------------------------------- | iter | target | x | y | ------------------------------------------------- | 1 | -2.628e+0 | -3.709 | -2.447 | | 2 | -83.29 | -1.098 | 0.3181 | | 3 | -7.799e+0 | 2.114 | -4.361 | | 4 | -2.832e+0 | -4.169 | 0.5546 | | 5 | -1.661e+0 | -1.135 | -2.782 | | 6 | -423.3 | -1.401 | -0.07944 | ・・・ 途中省略 ・・・ | 524 | -0.8144 | 1.902 | 3.612 | | 525 | -0.8034 | 1.895 | 3.588 | | 526 | -0.806 | 1.896 | 3.6 | | 527 | -0.8079 | 1.899 | 3.606 | | 528 | -0.8039 | 1.896 | 3.598 | | 529 | -0.7999 | 1.894 | 3.59 | | 530 | -0.8243 | 1.891 | 3.557 | ================================================= {'target': -0.79580733024233774, 'params': {'x': 1.8884565804399678, 'y': 3.574300836686076}} - 3回目
step 0 ------------------------------------------------- | iter | target | x | y | ------------------------------------------------- | 1 | -798.6 | 1.348 | -1.008 | | 2 | -1.549e+0 | 3.339 | -1.295 | | 3 | -1.477e+0 | -3.582 | 0.6874 | | 4 | -23.53 | -1.251 | 1.136 | | 5 | -2.921e+0 | 3.521 | -4.695 | | 6 | -3.555e+0 | 1.726 | -2.982 | ・・・ 途中省略 ・・・ | 324 | -0.5124 | 0.2844 | 0.08276 | | 325 | -0.5227 | 0.2792 | 0.08366 | | 326 | -0.499 | 0.2963 | 0.0816 | | 327 | -0.5024 | 0.2997 | 0.07888 | | 328 | -0.496 | 0.2973 | 0.08374 | | 329 | -0.496 | 0.2963 | 0.08506 | | 330 | -0.509 | 0.2893 | 0.07743 | ================================================= {'target': -0.49595059749752662, 'params': {'x': 0.29729168795210797, 'y': 0.083743785797047235}}
- 1回目
-
init_pointsを100、n_iterも100とした結果5つ。
[misystem@cdev11-cl python-bayesian-optimization-validation]$ head result.20191024-001.dat | iter | target | x | y | ------------------------------------------------- | 1 | -506.1 | -0.7834 | 2.856 | | 2 | -2.159e+0 | -4.145 | 2.494 | | 3 | -56.41 | 1.279 | 0.8847 | | 4 | -4.075e+0 | -4.667 | 1.598 | | 5 | -361.2 | 2.595 | 4.842 | | 6 | -575.8 | -0.4995 | 2.644 | | 7 | -3.551e+0 | 4.122 | -1.849 | | 8 | -31.99 | -1.277 | 2.149 | ・・・ 途中省略 ・・・ | 193 | -0.4093 | 1.639 | 2.689 | | 194 | -0.4364 | 1.642 | 2.68 | | 195 | -0.4098 | 1.637 | 2.686 | | 196 | -0.4164 | 1.642 | 2.703 | | 197 | -0.4097 | 1.639 | 2.689 | | 198 | -0.4155 | 1.638 | 2.692 | | 199 | -0.4676 | 1.634 | 2.697 | | 200 | -1.491 | 0.959 | 1.042 | ================================================= {'target': -0.40887210909290977, 'params': {'x': 1.6382857376069393, 'y': 2.6878056335206497}} [misystem@cdev11-cl python-bayesian-optimization-validation]$ head result.20191024-002.dat | iter | target | x | y | ------------------------------------------------- | 1 | -1.619e+0 | 2.942 | -4.069 | | 2 | -1.175e+0 | 1.725 | -0.4521 | | 3 | -2.879e+0 | -1.05 | -4.259 | | 4 | -7.153e+0 | -4.76 | -4.084 | | 5 | -5.108e+0 | 3.072 | 2.296 | | 6 | -3.875e+0 | 4.079 | -3.043 | | 7 | -182.3 | -0.04505 | 1.348 | | 8 | -1.743e+0 | -0.004642 | 4.173 | ・・・ 途中省略 ・・・ | 193 | -0.001896 | 1.043 | 1.088 | | 194 | -0.002024 | 0.9923 | 0.9891 | | 195 | -0.00221 | 0.9651 | 0.9345 | | 196 | -0.00145 | 1.037 | 1.074 | | 197 | -0.002017 | 0.9735 | 0.9513 | | 198 | -0.000648 | 0.977 | 0.9555 | | 199 | -0.001726 | 1.04 | 1.081 | | 200 | -0.001177 | 0.9724 | 0.9476 | ================================================= {'target': -9.5167408499487135e-06, 'params': {'x': 1.0029301831124195, 'y': 1.0057724758910978}} [misystem@cdev11-cl python-bayesian-optimization-validation]$ head result.20191024-003.dat | iter | target | x | y | ------------------------------------------------- | 1 | -3.313e+0 | 2.477 | 0.3832 | | 2 | -3.351e+0 | 2.6 | 0.9716 | | 3 | -1.761e+0 | 4.024 | 2.926 | | 4 | -763.5 | 0.6937 | 3.244 | | 5 | -778.0 | 0.8291 | 3.477 | | 6 | -1.3e+04 | 3.174 | -1.323 | | 7 | -2.554e+0 | -4.151 | 1.257 | | 8 | -9.021e+0 | 2.335 | -4.045 | ・・・ 途中省略 ・・・ | 193 | -0.6051 | 1.778 | 3.159 | | 194 | -0.6681 | 1.773 | 3.169 | | 195 | -0.6044 | 1.77 | 3.123 | | 196 | -0.5968 | 1.772 | 3.137 | | 197 | -0.604 | 1.776 | 3.152 | | 198 | -0.593 | 1.77 | 3.134 | | 199 | -0.5963 | 1.772 | 3.135 | | 200 | -0.6386 | 1.783 | 3.165 | ================================================= {'target': -0.59027713572641871, 'params': {'x': 1.7682274471204442, 'y': 3.1276467605283269}} [misystem@cdev11-cl python-bayesian-optimization-validation]$ head result.20191024-004.dat | iter | target | x | y | ------------------------------------------------- | 1 | -196.8 | -1.906 | 2.259 | | 2 | -8.203e+0 | -4.908 | -4.546 | | 3 | -601.1 | 0.1151 | 2.463 | | 4 | -4.018e+0 | 2.711 | 1.014 | | 5 | -2.872e+0 | -2.195 | -0.5298 | | 6 | -68.66 | -1.794 | 4.0 | | 7 | -2.641e+0 | 0.8144 | -4.476 | | 8 | -2.502e+0 | -4.516 | 4.589 | ・・・ 途中省略 ・・・ | 193 | -0.2984 | 0.4604 | 0.2035 | | 194 | -0.2968 | 0.4691 | 0.2078 | | 195 | -0.2946 | 0.4627 | 0.2064 | | 196 | -0.296 | 0.4631 | 0.2056 | | 197 | -0.2948 | 0.4639 | 0.2066 | | 198 | -0.2899 | 0.4685 | 0.2109 | | 199 | -0.2959 | 0.4675 | 0.2075 | | 200 | -0.3027 | 0.4735 | 0.2082 | ================================================= {'target': -0.28713452118238392, 'params': {'x': 0.46689019873958371, 'y': 0.21257493203241185}} [misystem@cdev11-cl python-bayesian-optimization-validation]$ head result.20191024-005.dat | iter | target | x | y | ------------------------------------------------- | 1 | -6.431e+0 | 1.926 | -4.31 | | 2 | -2.142e+0 | -1.562 | -2.183 | | 3 | -4.578e+0 | 2.706 | 0.5592 | | 4 | -40.92 | -2.3 | 4.744 | | 5 | -1.748e+0 | -3.427 | -1.471 | | 6 | -1.133e+0 | 1.49 | -1.145 | | 7 | -4.215e+0 | -1.449 | -4.388 | | 8 | -2.881e+0 | -4.653 | 4.687 | ・・・ 途中省略 ・・・ | 193 | -0.002507 | 0.9754 | 0.9557 | | 194 | -0.008733 | 0.9744 | 0.9584 | | 195 | -0.00377 | 0.9729 | 0.952 | | 196 | -0.007821 | 0.9743 | 0.9577 | | 197 | -0.001112 | 0.9778 | 0.9586 | | 198 | -0.005092 | 0.9735 | 0.9544 | | 199 | -0.006161 | 0.9772 | 0.9624 | | 200 | -0.00261 | 0.9729 | 0.951 | ================================================= {'target': -0.00060297898138711144, 'params': {'x': 0.97675188983800976, 'y': 0.95325365734233258}}
まとめ
いくつかの結果から、bayes推定のみを使った場合、想定される最適解に落ち着くことが無く、十分な精度を得られない恐れがあることが分かる。n_iterを1000くらいに設定すると良好な結果が得られやすいが、これはランダム検索とほぼ同等であるとみなされ、bayse推定を利用する必要性に疑問符がつく。 ただし、最適解を得る前処理として大局解を見つけるのは問題ないと思われるので、bayse推定により得られた大局解を用い、それを初期値とすることで、初期値を必要とする最適化手法(conminなど)では闇雲な初期値による膨大になりがちな計算時間の短縮などに資すると思われる。