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]。本最適化パッケージがどの程度の確からしさを持っているかを確認した。
image{"#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}}
      
  • 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}}
      
  • 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など)では闇雲な初期値による膨大になりがちな計算時間の短縮などに資すると思われる。