私はScipyを使用して最適化問題を実行しています。ここでは、サイズNNxNN
の頂点と結合のフラットネットワークを取得し、その2つの側面を接続し(つまり、周期的にし)、エネルギー関数を最小化します。それは丸まって円柱を形成します。 (以下のリンクを参照してください。)
私は関数energy(xyz-position)
を持っていて、それはグラデーションなので、Scipyマニュアルで推奨されている3つの方法を使用することにしました-Newton-CG
、BFGS
、L-BFGS-B
-そして、彼らがどのように実行したかを比較します。
最適化関数を次のように呼び出し、場合に応じて'Newton-CG'
を'BFGS'
と'L-BFGS-B'
に置き換えるだけです。
from scipy.optimize import minimize
res = minimize(energy, xyzInit, method='Newton-CG', jac = energy_der, options={'disp': True})
次の一般的な動作が見つかりました(NN=9
の場合の出力データを提供しています。これは、3*9^2=243
次元のパラメーター空間に対応します)-
BFGSは体系的に正しい最小値を見つけることができず(低いNN
の場合)、大きいNN
の場合はまったく収束しませんでした。最終結果については、 https://plot.ly/~apal90/162/ を参照してください。
NN=9
Method: BFGS
Warning: Desired error not necessarily achieved due to precision loss.
Current function value: 204.465912
Iterations: 1239
Function evaluations: 1520
Gradient evaluations: 1508
Time taken for minimisation: 340.728140116
Newton-CGは、小さいNN
(<= 8)の正しい最小値を見つけましたが、NN = 9から開始して、誤った最小値を返し(つまり、シリンダーの一端が押しつぶされました)、より高い値の場合でも停止しました収束。注:この動作は、何らかの理由で奇数のNN
によって悪化しました。 https://plot.ly/~apal90/164/ を参照してください
NN=9
Method: Newton-CG
Optimization terminated successfully.
Current function value: 7.954412
Iterations: 49
Function evaluations: 58
Gradient evaluations: 1654
Hessian evaluations: 0
Time taken for minimisation: 294.203114033
L-BFGS-Bは、私がテストしたすべてのNN
(NN=14
まで)について、正しい最小値を見つけましたが、それは非常に高速でした。 https://plot.ly/~apal90/160/ を参照してください
NN=9
Method: L-BFGS-B
Time taken for minimisation: 36.3749790192
質問:この場合、L-BFGS-B
が他の2つの方法よりも優れているのはなぜですか?特に、両方が(私の理解では)まったく同じように機能する準ニュートン法であると想定されているのに、なぜそれがBFGS
よりもはるかに優れているのですか。
状況についての私の考え:3つの方法はすべて、すべての点xで2次近似を行います。このためには、グラデーションとヘシアンが必要です。ヘッセ行列が指定されていない場合は、アルゴリズムで計算する必要があります。勾配のみが明示的に指定されているこの場合、これはアルゴリズムによってすべてのステップで数値的に計算されます。より具体的には、必要なのはヘッセ行列の逆行列であり、これは特に高次元では非常にコストのかかるステップです。現在、Newton-CGはこの逆ヘッセ行列を明示的に計算するため、より長い時間要件があります。 BFGSやL-BFGSのような準ニュートン法は、勾配に基づいてヘッセ行列(つまり、曲率)の近似を計算します。これは、時間的に安価であり、ポイントの周りの曲率のより良い推定値でもあると考えられます。したがって、2次関数の場合、ニュートンCGはより速く収束しますが、非2次関数の場合、準ニュートン関数はよりよく収束します。 L-BFGSはBFGSの低メモリバージョンであり、完全なNxN行列よりもすべてのステップではるかに少ないメモリを格納するため、BFGSよりも高速です。
この説明は、ニュートン-CG法と準ニュートン法の相違を示しています。それが説明していないのは、アルゴリズムが真の最小値を見つけることができないこと、特にBFGSとL-BFGSの間の不一致であり、どちらも同じように機能するはずです。
長い収束時間に関する私の一般的な予感は、システムが最小値について非二次(つまりフラット)であり、したがってアルゴリズムが収束とともに振動することです。それを超えて、BFGSとL-BFGSが本当に同じように機能する場合、Scipyアルゴリズムの収束許容レベルには多少の違いがあるはずだと思います。そうでなければ、BFGSとL-BFGSは実際には同じようには機能せず、後者はおそらくヘッセ行列をはるかに正確に計算します。
参照-
http://www.scipy-lectures.org/advanced/mathematical_optimization/#newton-and-quasi-newton-methods
https://en.wikipedia.org/wiki/Newton%27s_method_in_optimization
https://en.wikipedia.org/wiki/Quasi-Newton_method
https://docs.scipy.org/doc/scipy-0.18.1/reference/optimize.minimize-bfgs.html#optimize-minimize-bfgs
あなたの質問には、エネルギー関数と初期推定という2つの重要な情報が欠けています。エネルギー関数は、凸/非凸、滑らか/区分的に滑らか/不連続にすることができます。このため、あなたの文脈であなたの質問に完全に答えることは困難になります。ただし、BFGSとL-BFGS-Bの主な違いについては説明できます。
どちらの方法も、非線形最適化問題を解くための反復法です。これらは両方とも、反復ごとに関数のヘッセ行列の近似を使用してニュートン法を近似します。ニュートン法との主な違いは、特定のポイントで完全なヘッセ行列を計算する代わりに、前のポイントで勾配を累積し、BFGS式を使用してヘッセ行列の近似としてそれらをまとめることです。ニュートン法とBFGS法は、関数が最適に近い2次テイラー展開を持たない限り収束することが保証されていません。
元のBFGS法は、与えられた初期推定以降のすべての勾配を累積します。この方法には2つの問題があります。まず、メモリが無期限に増加する可能性があります。第二に、非線形問題の場合、最初の推測でのヘッセ行列は、解でのヘッセ行列を表していないことがよくあります。したがって、近似されたヘッセ行列は、解の近くに十分な勾配が蓄積されるまでバイアスされます。これは収束を遅くする可能性がありますが、私の経験では、単一の極小値を持つエネルギー関数の優れたライン探索アルゴリズムで収束するはずです。
L-BFGSはBFGSと同じですが、メモリが制限されています。つまり、しばらくすると、古いグラデーションが破棄され、新しく計算されたグラデーション用のスペースが残ります。これにより、メモリの問題が解決され、初期勾配の偏りが回避されます。ただし、メモリに保持されている勾配の数によっては、ヘッセ行列が正確に推定されない場合があり、バイアスのもう1つの原因となる可能性があります。これも収束を遅くする可能性がありますが、ここでも、単一の極小値を持つエネルギー関数の優れたライン探索アルゴリズムで収束する必要があります。
L-BFGS-BはL-BFGSと同じですが、入力変数に制約があります。 L-BFGS-Bは、ドメインの境界にある変数の最適化を停止します。制約を指定しなかったため、アルゴリズムのこの側面は問題に適用されません。
私の仮説は、解からはほど遠い初期推定を使用して、滑らかであるが凸ではない問題を解こうとしていること、そして最終的には極小値になるというものです。フラットな構成から始めるとおっしゃっていたので、ヘッセ行列の縮退につながる特異点から始めることは驚くことではありません。これは、残りの最適化で問題を引き起こす可能性があります。あなたの場合のBFGSとL-BFGSの唯一の違いは、すべての反復でわずかに異なる勾配が計算されることと、L-BFGS法がグローバル最小値につながるパスをたどることになるということです。