Python scipy.optimize.minimize牛顿重心停止,即使二阶导数为负

Python scipy.optimize.minimize牛顿重心停止,即使二阶导数为负,python,scipy,minimization,Python,Scipy,Minimization,尝试最小化S形曲线f(x)=1/(1+exp(-x))(在负无穷远处收敛到零,在无穷远处收敛到一) 我得到以下输出: 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

尝试最小化S形曲线
f(x)=1/(1+exp(-x))
(在负无穷远处收敛到零,在无穷远处收敛到一)

我得到以下输出:

     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.])
这意味着,当algorihtm实际为
f(-infinity)=0时,它只是停在它所在的位置并声称最小值为
f(100)=1
。这个答案是合理的,只看
x=100
处的微小导数(并考虑到最小值只能在一定的误差容限内找到),但负二阶导数(hessian)意味着
x=100
甚至不接近局部最小值


如何避免警告消息,以及如何强制算法继续,直到它找到至少一个
hess(x)>0
的点?注意,雅可比矩阵和黑森矩阵实际上都没有遇到数值稳定性问题;实际上
jac(100)>0
hess(100)该算法没有声称最小值为100,它明确表示未找到最小值(成功:错误),并指出原因:精度损失。当以双精度执行计算时,请注意
1+np.exp(-100)
,甚至
1+np.exp(-50)
,都正好是1.0。你给了优化器一个函数,这个函数在它看来等于1,难怪它找不到更小的值


解决方法是回顾你真正问题的情况。如果你在优化两个大小相差如此之大的事物的总和,那么这些术语的比例似乎很糟糕。数值优化方法处理此类问题的能力有限;需要人为干预才能使问题易于处理。

该算法没有声称最小值为100,它明确表示未找到最小值(成功:错误),并指出原因:精度损失。当以双精度执行计算时,请注意
1+np.exp(-100)
,甚至
1+np.exp(-50)
,都正好是1.0。你给了优化器一个函数,这个函数在它看来等于1,难怪它找不到更小的值


解决方法是回顾你真正问题的情况。如果你在优化两个大小相差如此之大的事物的总和,那么这些术语的比例似乎很糟糕。数值优化方法处理此类问题的能力有限;需要人为干预,使问题易于处理。

x=100时的黑森指数为-3.7e-44。虽然这是负数,但它太小,实际上无法与0区分开来。换句话说,该区域的曲线太平坦,对优化器来说没有意义。我倾向于在这种情况下使用。如果你想确保你有一个合理的最小值,你可以进一步将结果作为起点传递给一个基于梯度的优化例程。“…并声称最小值为f(100)=1…”它没有这样说。看看输出!上面写着:“警告:由于精度损失,不一定会出现期望的错误。”和
success:False
。这意味着它在没有找到最小值的情况下停止了。x=100时的黑森曲线为-3.7e-44。虽然这是负数,但它太小,实际上无法与0区分开来。换句话说,该区域的曲线太平坦,对优化器来说没有意义。我倾向于在这种情况下使用。如果你想确保你有一个合理的最小值,你可以进一步将结果作为起点传递给一个基于梯度的优化例程。“…并声称最小值为f(100)=1…”它没有这样说。看看输出!上面写着:“警告:由于精度损失,不一定会出现期望的错误。”和
success:False
。这意味着它没有找到最小值就停止了。对不起,我误传了算法。尽管我的措辞很糟糕,但我意识到这一警告信息,但我的问题仍然是我想避免它。我不相信在我的问题中我能做多少来修正尺度,以及由此产生的函数的恒定性。我确实检查过,简单地跟随梯度直到Hessian变得正定,确实会导致最优,因此我的问题是,我可以告诉算法这样做,你不能告诉算法忽略它应该最小化的函数,而只是通过梯度。作为一种可能的解决方法,尝试通过向函数中添加一个小倍数的
|x |**2
(一些变量平方)来修改该函数,刚好足以使其从初始位置松开。如果运气好的话,它将收敛到离最小值不远的某个地方,您可以使用实际函数从那里继续。尽管我的措辞很糟糕,但我意识到这一警告信息,但我的问题仍然是我想避免它。我不相信在我的问题中我能做多少来修正尺度,以及由此产生的函数的恒定性。我确实检查过,简单地跟随梯度直到Hessian变得正定,确实会导致最优,因此我的问题是,我可以告诉算法这样做,你不能告诉算法忽略它应该最小化的函数,而只是通过梯度。作为一种可能的解决方法,尝试通过向函数中添加一个小倍数的
|x |**2
(一些变量平方)来修改该函数,刚好足以使其从初始位置松开。如果运气好的话,它将收敛到离最小值不远的某个地方,您可以使用实际函数从那里继续。
     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.])