【问题标题】:scipy.optimize.fmin_l_bfgs_b returns 'ABNORMAL_TERMINATION_IN_LNSRCH'scipy.optimize.fmin_l_bfgs_b 返回 'ABNORMAL_TERMINATION_IN_LNSRCH'
【发布时间】:2016-04-12 08:07:37
【问题描述】:

我正在使用 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_

我知道这意味着在此迭代中可以达到最小值。我用谷歌搜索了这个问题。有人说经常出现是因为目标函数和梯度函数不匹配。但是这里我不提供渐变功能,因为我使用的是 'approx_grad'。

我应该调查哪些可能的原因? “舍入误差主导计算”是什么意思?

======

我还发现对数似然不是单调增加的:

########## Convergence !!! ##########
log_likelihood_history: [-28659.725891322563, 220.49993177669558, 291.3513633060345, 267.47745327823907, 265.31567762171181, 265.07311121000367, 265.04217683341682]

它通常在第二次或第三次迭代时开始减少,即使没有发生“ABNORMAL_TERMINATION_IN_LNSRCH”。不知道这个问题是不是和上一个有关。

【问题讨论】:

  • 我也遇到了类似的问题。它们似乎都集中在我给优化器的梯度函数上。您是否 100% 确定您的梯度完全正确?
  • 在尝试最大化函数的对数似然时,我遇到了与 L-BFGS 类似的问题。我必须补充一点,我没有传递函数的梯度,而是让 L-BFGS 近似它。有时我可以通过使用 Nelder–Mead 优化器来解决这个问题……你能解决这个问题吗?
  • @muammar,根据我使用 L-BFGS 的经验,它只有在提供显式导数函数时才能正常工作。否则很容易丢失。

标签: optimization machine-learning statistics normal-distribution gradient-descent


【解决方案1】:

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,因为这已经足够了。机器epsilon是10E-16,我觉得20其实有点太多了。因此,对于大多数遇到此问题的人来说,我的钱是您的渐变与您的功能不匹配

现在,也可能是“2. 舍入误差主导计算”。通过这个,他的意思是你的函数是一个非常平坦的表面,其中增加是机器 epsilon 的数量级(在这种情况下你可以重新调整函数), 现在,我想也许应该有第三种选择,当你的功能太奇怪时。振荡?我可以看到类似 $\sin({\frac{1}{x}})$ 的东西导致了这种问题。但我不是一个聪明人,所以不要假设有第三种情况。

所以我认为OP的解决方案应该是你的功能太平了。或者看一下fortran代码。

https://github.com/scipy/scipy/blob/master/scipy/optimize/lbfgsb/lbfgsb.f

想看的可以在线搜索。 https://en.wikipedia.org/wiki/Line_search

注意。这已经晚了7个月。为了将来,我把它放在这里。

【讨论】:

  • 如果目标函数(或可能的梯度)变为nan,也会打印此错误消息。
  • “代码在你提供的下降方向上尝试了总共 20 次称为线搜索的东西,并意识到你不是在告诉它下坡,而是上坡。” ——这不意味着它已经找到了一个局部最优值并且应该完成而不是抛出一个错误?
  • Nocedal 的代码在代码的另一个地方捕捉到了收敛。
【解决方案2】:

正如 Wilmer E. Henao 在回答中指出的那样,问题可能出在梯度上。由于您使用的是approx_grad=True,因此梯度是用数值计算的。在这种情况下,减小epsilon 的值(用于数值计算梯度的步长)会有所帮助。

【讨论】:

  • 将 epsilon 减少 4 个数量级对我有帮助!
  • scipy 在哪里调用这个函数?我想知道在哪里可以编辑 L-BFGS-B 的参数
  • @learningthemachine, scipy.optimize.fmin_l_bfgs_b 可能在很多地方都被调用过。它在那里,因此您可以随时调用它。
【解决方案3】:

使用 L-BFGS-B 优化器时,我也收到错误“ABNORMAL_TERMINATION_IN_LNSRCH”。

虽然我的梯度函数指向正确的方向,但我通过其 L2 范数重新调整了函数的 实际 梯度。删除它或添加另一种适当类型的重新缩放有效。之前,我猜是梯度太大了,马上就出界了。

如果我没看错的话,来自 OP 的问题是无限的,所以这肯定不会帮助解决这个问题。但是,谷歌搜索错误“ABNORMAL_TERMINATION_IN_LNSRCH”会将此页面作为第一个结果之一,因此它可能对其他人有所帮助...

【讨论】:

    猜你喜欢
    • 2016-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-23
    相关资源
    最近更新 更多