在scipy中使用L-BFGS-B时出错

use*_*603 3 python optimization scipy

在scipy.optimize.minimize中使用'L-BFGS-B'方法时,我得到了一些令人费解的结果:

import scipy.optimize as optimize
import numpy as np

def testFun():
    prec = 1e3

    func0 = lambda x: (float(x[0]*prec)/prec+0.5)**2+(float(x[1]*prec)/prec-0.3)**2
    func1 = lambda x: (float(round(x[0]*prec))/prec+0.5)**2+(float(round(x[1]*prec))/prec-0.3)**2

    result0 = optimize.minimize(func0, np.array([0,0]), method = 'L-BFGS-B', bounds=((-1,1),(-1,1)))
    print result0
    print 'func0 at [0,0]:',func0([0,0]),'; func0 at [-0.5,0.3]:',func0([-0.5,0.3]),'\n'

    result1 = optimize.minimize(func1, np.array([0,0]), method = 'L-BFGS-B', bounds=((-1,1),(-1,1)))
    print result1
    print 'func1 at [0,0]:',func1([0,0]),'; func1 at [-0.5,0.3]:',func1([-0.5,0.3])

def main():
    testFun()
Run Code Online (Sandbox Code Playgroud)

func0()和func1()几乎是相同的二次函数,输入值的精度差异仅为0.001.'L-BFGS-B'方法适用于func0.但是,通过在func1()中添加round()函数,'L-BFGS-B'在第一步后停止搜索最佳值,并直接使用初始值[0,0]作为最佳点.

这不仅限于round().替换func1()中的round()为int()也会导致相同的错误.

有谁知道这个的原因?

非常感谢.

CT *_*Zhu 10

BFGS方法是不仅依赖于函数值,而且依赖于梯度和Hessian的方法之一(如果您愿意,可以将其视为一阶和二阶导数).在你func1(),一旦你拥有了round()它,梯度不再是连续的.因此,BFGS方法在第一次迭代后立即失败(想象如下:BFGS在起始参数周围搜索并发现梯度没有改变,因此它停止了).同样,我希望其他需要梯度的方法失败为BGFS.

您可以通过前置条件或重新调整X来使其工作.但更好的是,您应该尝试无梯度方法,例如'Nelder-Mead'或'Powell'

  • 这不是局部最小值与全局最小值的关系.一旦您将行为引入您的约束或目标,这会破坏衍生信息,基于梯度的求解器就不再保证可以工作,也可能不会.正如朱所说,如果必须在模型中使用round,int或abs等函数,请使用不依赖于派生信息的优化器.我所知道的优化方法无法在有限时间内保证全局最优. (3认同)

War*_*ser 5

roundint创建不可区分的步骤函数.l-bfgs-b方法用于解决平滑优化问题.它使用近似渐变(如果你没有给它一个明确的渐变),如果函数有步骤,那将是垃圾.