ガウス混合問題を解決するためにscipy.optimize.fmin_l_bfgs_bを使用しています。混合分布の平均は、EMアルゴリズムを使用して重みを最適化する必要がある回帰によってモデル化されます。
sigma_sp_new, func_val, info_dict = fmin_l_bfgs_b(func_to_minimize, self.sigma_vector[si][pj],
args=(self.w_vectors[si][pj], Y, X, E_step_results[si][pj]),
approx_grad=True, bounds=[(1e-8, 0.5)], factr=1e02, pgtol=1e-05, epsilon=1e-08)
しかし、情報ディクショナリに「ABNORMAL_TERMINATION_IN_LNSRCH」という警告が表示されることがあります。
func_to_minimize value = 1.14462324063e-07
information dictionary: {'task': b'ABNORMAL_TERMINATION_IN_LNSRCH', 'funcalls': 147, 'grad': array([ 1.77635684e-05, 2.87769808e-05, 3.51718654e-05,
6.75015599e-06, -4.97379915e-06, -1.06581410e-06]), 'nit': 0, 'warnflag': 2}
RUNNING THE L-BFGS-B CODE
* * *
Machine precision = 2.220D-16
N = 6 M = 10
This problem is unconstrained.
At X0 0 variables are exactly at the bounds
At iterate 0 f= 1.14462D-07 |proj g|= 3.51719D-05
* * *
Tit = total number of iterations
Tnf = total number of function evaluations
Tnint = total number of segments explored during Cauchy searches
Skip = number of BFGS updates skipped
Nact = number of active bounds at final generalized Cauchy point
Projg = norm of the final projected gradient
F = final function value
* * *
N Tit Tnf Tnint Skip Nact Projg F
6 1 21 1 0 0 3.517D-05 1.145D-07
F = 1.144619474757747E-007
ABNORMAL_TERMINATION_IN_LNSRCH
Line search cannot locate an adequate point after 20 function
and gradient evaluations. Previous x, f and g restored.
Possible causes: 1 error in function or gradient evaluation;
2 rounding error dominate computation.
Cauchy time 0.000E+00 seconds.
Subspace minimization time 0.000E+00 seconds.
Line search time 0.000E+00 seconds.
Total User time 0.000E+00 seconds.
毎回この警告が表示されるわけではありませんが、時々表示されます。 (ほとんどの場合、「CONVERGENCE:NORM_OF_PROJECTED_GRADIENT _ <= _ PGTOL」または「CONVERGENCE:REL_REDUCTION_OF_F _ <= _ FACTR * EPSMCH」を取得します)。
これは、この反復で最小値に到達できることを意味します。私はこの問題をググった。目的関数と勾配関数が一致しないために頻繁に起こると誰かが言った。しかし、ここでは「approx_grad」を使用しているため、勾配関数は提供していません。
調査すべき理由は何ですか? 「丸め誤差が計算を支配する」とはどういう意味ですか?
======
また、対数尤度は単調に増加しないこともわかります。
########## Convergence !!! ##########
log_likelihood_history: [-28659.725891322563, 220.49993177669558, 291.3513633060345, 267.47745327823907, 265.31567762171181, 265.07311121000367, 265.04217683341682]
「ABNORMAL_TERMINATION_IN_LNSRCH」が発生しなくても、通常は2番目または3番目の反復で減少を開始します。この問題が以前の問題に関連しているかどうかはわかりません。
Scipyは元のL-BFGS-B実装を呼び出します。これはいくつかのfortran77(古くて美しく、超高速のコード)であり、下降方向が実際に上がっていることが問題です。問題は2533行目から始まります(下部のコードへのリンク)。
Gd = ddot(n,g,1,d,1)
if (ifun .eq. 0) then
gdold=Gd
if (Gd .ge. zero) then
c the directional derivative >=0.
c Line search is impossible.
if (iprint .ge. 0) then
write(0,*)' ascent direction in projection Gd = ', Gd
endif
info = -4
return
endif
endif
言い換えれば、丘を上ることによって丘を下るように言っているのです。このコードは、提供された下降方向にライン検索と呼ばれるものを合計20回試行し、下り坂ではなく上り坂に進むように指示していることを認識します。全20回。
それを書いた人(Jorge Nocedal、ちなみにとても賢い人)は20を入れました。マシンのイプシロンは10E-16ですが、20は実際には少し多すぎると思います。したがって、この問題を抱えているほとんどの人にとっての私のお金は、あなたの勾配があなたの関数と一致しないことです。
さて、それは「2.丸め誤差が計算を支配する」かもしれません。これにより、彼の関数は非常に平坦な表面であり、増加はマシンイプシロンのオーダーです(この場合、おそらく関数を再スケールできます)。さて、あなたの機能は奇妙すぎる。振動? $\sin({\ frac {1} {x}})$のようなものがこの種の問題を引き起こしているのを見ることができました。しかし、私は賢い人ではないので、3番目のケースがあると思い込まないでください。
したがって、OPの解決策は、関数が平坦すぎるということです。または、fortranコードを見てください。
https://github.com/scipy/scipy/blob/master/scipy/optimize/lbfgsb/lbfgsb.f
これを見たい人のための行検索です。 https://en.wikipedia.org/wiki/Line_search
注意。これは7か月遅すぎます。将来のためにここに置いておきます。
Wilmer E. Henaoの回答で指摘されているように、問題はおそらく勾配にあります。 approx_grad=True
を使用しているため、勾配は数値で計算されます。この場合、勾配の数値計算に使用されるステップサイズであるepsilon
の値を小さくすると効果的です。
また、L-BFGS-Bオプティマイザーを使用すると、「ABNORMAL_TERMINATION_IN_LNSRCH」エラーが発生しました。
私の勾配関数が正しい方向を指していたときに、L2-ノルムによって関数のactual勾配を再スケーリングしました。それを削除するか、別の適切な種類の再スケーリングを追加するとうまくいきました。以前は、勾配が大きすぎてすぐに範囲外になったと思います。
私が正しく読んだ場合、OPからの問題は無制限だったので、これは確かにこの問題の設定では役に立ちません。ただし、エラー「ABNORMAL_TERMINATION_IN_LNSRCH」をグーグルすると、このページが最初の結果の1つとして表示されるため、他の人を助ける可能性があります...