scipy.optimize.minimize 即使二阶导数为负,Newton-CG 也会停止
scipy.optimize.minimize Newton-CG stops even when second derivative is negative
尝试使用
最小化 S 形曲线 f(x)=1/(1+exp(-x))
(在负无穷大收敛到零,在无穷大收敛到一)
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
处的微小导数是合理的(并考虑到最小值只能在一定的误差容限内找到),但负二阶导数(hessian)意味着 x=100
甚至不接近局部最小值。
如何避免警告消息,以及如何强制算法继续,直到它至少找到 hess(x)>0
所在的点?请注意,Jacobian 矩阵和 Hessian 矩阵实际上 运行 都没有进入数值稳定性问题;实际上 jac(100)>0
和 hess(100)<0
,从中最小化器应该能够得出尚未达到最佳值的结论。
PS:这当然只是一个玩具问题,但我相信它抓住了我的实际应用程序失败的要点。另外,我不打算使用 Newton-CG,但是当雅可比像上面的例子一样小时,任何不使用二阶导数的方法都不能期望继续,所以我确实想使用一种利用的方法二阶导数信息
我正在使用 Python3.6.3 和 scipy0.19.1
该算法并未声明最小值为 100,它明确表示未找到最小值(成功:False),并说明原因:精度损失。当以双精度执行计算时,请注意 1 + np.exp(-100)
,甚至 1 + np.exp(-50)
正好是 1.0。你给了优化器一个函数,就它所知,它等于 1,难怪它无处可去寻找更小的值。
解决的方法是在你的真实问题中查看情况。如果您正在优化两个如此大相径庭的事物的总和,那么这些术语似乎很难缩放。数值优化方法处理此类问题的能力有限;需要人工干预才能使问题易于处理。
尝试使用
最小化 S 形曲线f(x)=1/(1+exp(-x))
(在负无穷大收敛到零,在无穷大收敛到一)
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
处的微小导数是合理的(并考虑到最小值只能在一定的误差容限内找到),但负二阶导数(hessian)意味着 x=100
甚至不接近局部最小值。
如何避免警告消息,以及如何强制算法继续,直到它至少找到 hess(x)>0
所在的点?请注意,Jacobian 矩阵和 Hessian 矩阵实际上 运行 都没有进入数值稳定性问题;实际上 jac(100)>0
和 hess(100)<0
,从中最小化器应该能够得出尚未达到最佳值的结论。
PS:这当然只是一个玩具问题,但我相信它抓住了我的实际应用程序失败的要点。另外,我不打算使用 Newton-CG,但是当雅可比像上面的例子一样小时,任何不使用二阶导数的方法都不能期望继续,所以我确实想使用一种利用的方法二阶导数信息
我正在使用 Python3.6.3 和 scipy0.19.1
该算法并未声明最小值为 100,它明确表示未找到最小值(成功:False),并说明原因:精度损失。当以双精度执行计算时,请注意 1 + np.exp(-100)
,甚至 1 + np.exp(-50)
正好是 1.0。你给了优化器一个函数,就它所知,它等于 1,难怪它无处可去寻找更小的值。
解决的方法是在你的真实问题中查看情况。如果您正在优化两个如此大相径庭的事物的总和,那么这些术语似乎很难缩放。数值优化方法处理此类问题的能力有限;需要人工干预才能使问题易于处理。