scipy.optimize.minimize即使二阶导数为负,Newton-CG也会停止

时间:2018-01-30 10:38:43

标签: python scipy minimization

尝试使用

最小化sigmoid曲线f(x)=1/(1+exp(-x))(在负无穷大处收敛为零,在无穷远处收敛为1)
scipy.optimize.minimize(lambda x: 1/(1+np.exp(-x)),100,hess=lambda x:-(np.exp(x)*(np.exp(x)-1))/(np.exp(x)+1)**3,jac = lambda x:1/(np.exp(-x/2)+np.exp(x/2))**2,method = 'Newton-CG')

我得到以下输出:

     fun: array([ 1.])
     jac: array([  3.72007598e-44])
 message: 'Warning: Desired error not necessarily achieved due to precision loss.'
    nfev: 19
    nhev: 1
     nit: 0
    njev: 7
  status: 2
 success: False
       x: array([ 100.])

这意味着,算法只会停在原来的位置,并声称最小值是f(100)=1,当它真的是f(-infinity)=0时。这个答案在x=100只看到微小的导数时是合理的(考虑到最小值只能达到一定的误差容限),但负二阶导数(粗体)意味着x=100甚至没有接近当地的最低标准。

如何避免出现警告消息,如何强制算法继续运行,直至找到hess(x)>0的某个点为止?请注意,Jacobian和Hessian实际上都没有遇到数值稳定性问题;确实是jac(100)>0hess(100)<0,最小化者应该能够从中得出尚未达到最佳值的结论。

PS:这当然只是一个玩具问题,但我相信它捕获了我的真实应用程序失败的基本要素。另外,我没有开始使用Newton-CG,但是当jacobian与上面的例子一样小时,任何不使用二阶导数的方法都不能继续,所以我确实想要使用一个利用的方法二阶导数信息

我正在使用Python3.6.3和scipy0.19.1

1 个答案:

答案 0 :(得分:2)

算法没有声称最小值是100,它明确表示找不到最小值(成功:False),并指出原因:精度损失。当以双精度执行计算时,观察1 + np.exp(-50),甚至//animate menu icons $('.nav-link').hover(function() { console.log('entered'); $(this).find('.menu-image').toggleClass('animated swing'); });正好是1.0。你为优化器提供了一个同样等于1的函数,毫无疑问它无处寻找更小的值。

解决方案是检查您真实问题中的情况。如果你正在优化两个如此大小不同的事物的总和,那么这些术语似乎是严重缩放的。数值优化方法处理这些问题的能力有限;需要人为干预才能使问题易于解决。