【发布时间】:2017-07-14 10:44:32
【问题描述】:
我正在使用 Scipy 做一个优化问题,我正在使用大小为 NNxNN 的顶点和键的平面网络,连接它的两侧(即,使其周期性),并最小化能量函数,这样它卷曲形成一个圆柱体。 (请参阅下面的链接。)
由于我有函数 energy(xyz-position) 并且它是渐变的,因此我决定使用 Scipy 手册中推荐的三种方法——Newton-CG、BFGS、L-BFGS-B——并比较它们的执行情况。
我调用优化函数如下,我只是根据大小写将'Newton-CG'替换为'BFGS'和'L-BFGS-B':
from scipy.optimize import minimize
res = minimize(energy, xyzInit, method='Newton-CG', jac = energy_der, options={'disp': True})
我发现了以下一般行为(我给出了NN=9情况的输出数据,对应于3*9^2=243维参数空间)-
-
BFGS 系统性地无法找到正确的最小值(对于低
NN),并且对于大NN根本无法收敛。最终结果见https://plot.ly/~apal90/162/。NN=9 Method: BFGS Warning: Desired error not necessarily achieved due to precision loss. Current function value: 204.465912 Iterations: 1239 Function evaluations: 1520 Gradient evaluations: 1508 Time taken for minimisation: 340.728140116 -
Newton-CG 为小的
NN(NN 会加剧这种行为。见https://plot.ly/~apal90/164/NN=9 Method: Newton-CG Optimization terminated successfully. Current function value: 7.954412 Iterations: 49 Function evaluations: 58 Gradient evaluations: 1654 Hessian evaluations: 0 Time taken for minimisation: 294.203114033 -
对于我测试的所有
NN(最多NN=14),L-BFGS-B 找到了正确的最小值,而且速度非常快。见https://plot.ly/~apal90/160/NN=9 Method: L-BFGS-B Time taken for minimisation: 36.3749790192
问题:为什么L-BFGS-B 在这种情况下优于其他两种方法?特别是,为什么它比BFGS 优越得多,因为两者都应该是准牛顿方法(据我理解),以完全相同的方式工作。
我对这种情况的看法:所有三种方法都在每个点 x 处进行二次逼近。为此,它需要一个梯度和一个 Hessian。如果没有给出Hessian,则必须通过算法计算。在我们的例子中,只有梯度是明确给出的,这是由算法在每一步数值计算的。更具体地说,我们需要的是 Hessian 的倒数,这是一个非常昂贵的步骤,尤其是在更高维度上。现在,Newton-CG 显式地计算了这个逆 Hessian,因此需要更长的时间。像 BFGS 和 L-BFGS 这样的准牛顿方法基于梯度计算 Hessian 的近似值(即曲率),这在时间上更便宜,并且也被认为是对一个点的曲率的更好估计。因此,对于二次函数,Newton-CG 收敛得更快,而对于非二次函数,拟牛顿函数收敛得更好。 L-BFGS 是 BFGS 的低内存版本,每一步存储的内存远少于完整的 NxN 矩阵,因此它比 BFGS 快。
这个解释显示了 Newton-CG 和准牛顿方法之间的分歧。它没有解释的是算法无法找到真正的最小值,尤其是 BFGS 和 L-BFGS 之间的差异,它们都应该以相同的方式运行。
我对长收敛时间的一般预感是系统在最小值附近是非二次的(即平坦的),因此算法会随着收敛而振荡。除此之外,如果 BFGS 和 L-BFGS 真的以相同的方式工作,我相信 Scipy 算法的收敛容差水平之间肯定存在一些差异。否则,BFGS 和 L-BFGS 的工作方式并不相同,后者可能更准确地计算 Hessian。
参考--
http://www.scipy-lectures.org/advanced/mathematical_optimization/#newton-and-quasi-newton-methods
https://en.wikipedia.org/wiki/Newton%27s_method_in_optimization
https://en.wikipedia.org/wiki/Quasi-Newton_method
https://docs.scipy.org/doc/scipy-0.18.1/reference/optimize.minimize-bfgs.html#optimize-minimize-bfgs
【问题讨论】:
-
您能展示一下您是如何调用算法的吗?从接口的角度来看,L-BFGS-B 与其他两种算法的主要区别在于它支持有界约束。你有指定吗?这些可能对收敛产生了积极影响。
-
@kazemakase 不,我根本没有为 L-BFGS-B 提供任何约束。我已更新帖子以显示我的代码行。所有算法都是一样的。
-
交叉发布:stackoverflow.com/q/42424444/781723,cs.stackexchange.com/q/70780/755。请do not post the same question on multiple sites。每个社区都应该诚实地回答问题,而不会浪费任何人的时间。
-
energy()是否足够小/足够独立,可以在 gist.github 上发布? (可扩展的测试用例对于测试其他优化器也很有用。) -
@denis 不,不幸的是,它还不够独立。涉及的输入变量太多。
标签: python optimization scipy newtons-method