【问题标题】:BFGS optimization is much slower in Python compared to Octave与 Octave 相比,Python 中的 BFGS 优化要慢得多
【发布时间】:2014-04-30 09:15:15
【问题描述】:

我在 Octave/Matlab 中有一些执行 L-BFGS 优化的代码,调用签名如下:

[optTheta, cost] = fminlbfgs(objFunc, theta);

objFunc 是我的目标函数,theta 是我对参数的初始猜测。我认为fminlbfgs 是一个库,但它的调用签名和行为类似于 Matlab 中的minFuncobjFunc 返回[cost, gradient]。此代码最多执行 400 次迭代,并在 5 分钟内完成。

我已将我的代码移植到 Python 并尝试使用 Scipy 的 minimize 进行相同的优化:

res = minimize(obj_func, theta, 
               method='BFGS', jac=True, 
               options={'maxiter': 400, 'disp':True})

但由于某种原因,这段代码运行得非常慢(我等了大约 15 分钟才杀死它)。 obj_func 的返回签名与 Octave 中的相同。

我想知道我是否没有正确调用minimize 函数?分析显示包含minimize 的模块占用了最多的运行时间。

【问题讨论】:

  • 也许你应该和 scipy 的 lbfgsb 比较一下。如果没有更多信息,就不可能说出原因可能是什么。跨 scipy 版本更改的 linesearch 可能存在一些问题。
  • 基于 scipy 源,我相信 minimizemethod='BFGS' 应该调用与 fmin_bfgs 相同的函数。似乎minimize 是 scipy 基于文档实现的所有算法的首选接口。
  • 我的意思是method=‘L-BFGS-B’'BFGS'不同,我不知道哪个优化器相当于Octave的L-BFGS
  • 啊,我认为 BFGS 是正确的。我认为 L-BFGS 是一种低内存变体,只要数据具有一定大小或其他东西,Scipy 就会使用它。 L-BFGS-B 是 L-BFGS 的受限版本。
  • 你试过了吗? bfgs 在 Python 中,在 scipy 中的 lbfgsb 在 Fortran 中,并且可能基于与 octave 中的相同的原始 Fortran 包。不需要在 lbfgsb 中使用最后一个 b。但正如我之前评论的那样,如果您的优化没有在 15 分钟内完成,那么您的情况就有些“奇怪”了。

标签: matlab scipy octave


【解决方案1】:

我无法准确指出您的问题是什么,但您可以看到 BFGS 最小化是否收敛,

def print_resnorm(x):
    print "residual norm = ", obj_func(x)[0]

res = minimize(obj_func, theta, 
               method='BFGS', jac=True, 
               options={'maxiter': 400, 'disp':True},
               callback=print_resnorm)

【讨论】:

  • 这似乎不是一个收敛问题。我添加了一个类似的打印语句来查看obj_func 被调用了多少次,它真的很慢(即每次调用花费的时间都比它应该的长得多)。不过我会试一试。
  • 你也可以试试full newton方法或者用MATLAB/octave看看是不是收敛问题。
猜你喜欢
  • 2014-03-29
  • 2017-07-22
  • 1970-01-01
  • 1970-01-01
  • 2017-07-14
  • 2020-02-12
  • 1970-01-01
  • 1970-01-01
  • 2015-07-22
相关资源
最近更新 更多