4

我正在使用scipy.optimize.minimizewithmethod='bfgs'来训练凸目标。

每次我运行最小化时,BFGS 优化器对我的目标函数所做的前两个调用总是具有相同的参数向量。这似乎没有必要,因为它浪费了好几分钟重新计算两次相同的东西。

最小工作示例(目标更简单);

from scipy.optimize import minimize

def obj_jac(x):
    """Return objective value and jacobian value wrt. x"""
    print(x)
    return 10*x**2, 20*x

minimize(obj_jac, -100, method='bfgs', jac=True, tol=1e-7)

输出;

[-100.]
[-100.]
[-98.99]
[-94.95]
[-78.79]
[-30.17904355]
[-3.55271368e-15]

有谁知道这是否是 scipy 中 BFGS 实现的预期行为?


更新:我已将此作为Scipy 项目的issue #10385提交。

4

1 回答 1

2

这不是预期的行为,或者至少存在报告错误。

通过options参数进行优化的统计输出:

minimize(obj_jac, -100, method='bfgs', jac=True, tol=1e-7, options={'disp': True})

SciPy 输出以下内容:

[-100.]
[-100.]
[-98.99]
[-94.95]
[-78.79]
[-30.17904355]
[-3.55271368e-15]
Optimization terminated successfully.
         Current function value: 0.000000
         Iterations: 3
         Function evaluations: 6
         Gradient evaluations: 6

其中报告的函数数量和梯度评估肯定相差1。因此,在 BFGS 的 SciPy 中肯定存在一个统计报告错误。

我还怀疑,SciPy 内部效率低下,这将是以下几行。在迭代循环之前,评估函数及其梯度。然后开始循环并从评估函数及其梯度开始。这将为第 0 次迭代添加额外的函数评估,当然可以通过轻微的代码重组来避免(可能,通过一些权衡 wrt 算法可读性流程)。

以下是相关的:

我不是 SciPy 的专家,我会说要么是突然出现的旧 bug(然后应该报告),要么从一开始就没有修复,尽管我从 GitHub 讨论中理解了这一点。

于 2019-07-01T07:51:46.923 回答