scipy 直线的正方向导数

5gfr0r5j  于 8个月前  发布在  其他
关注(0)|答案(6)|浏览(64)

scipy.optimize的smode 'Positive directional derivative for linesystem'是什么意思?
例如,在fmin_slsqp http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_slsqp.html

dpiehjr4

dpiehjr41#

这些优化算法通常通过选择下降方向,然后执行该方向的线搜索来工作。我认为这条消息意味着优化器进入了一个位置,它没有设法找到目标函数值减小的方向(足够快),但也无法验证当前位置是否为最小值。

iszxjhcz

iszxjhcz2#

我还不知道这意味着什么,但如何解决它。基本上,被优化的函数需要返回一个较小的值。

F(x):
    ...
    return value / 10000000
fslejnso

fslejnso3#

为了避免改变你的函数,你也可以尝试使用ftol和eps参数。将ftol更改为更高的值相当于将函数更改为更小的值。

0g0grzrc

0g0grzrc4#

您收到此错误的一种情况是,

  1. x0超出了您在bounds中定义的有效范围。
    1.并且对于bounds之外的值获得无约束最大值。
    我将设置一个假设的优化问题,用两个不同的初始值运行它,并打印scipy.optimize的输出:
import numpy as np
from scipy import optimize

H = np.array([[2., 0.],
              [0., 8.]])

c = np.array([0, -32])

x0 = np.array([0.5, 0.5])    # valid initial value
x1 = np.array([-1, 1.1])     # invalid initial value

def loss(x, sign=1.):
    return sign * (0.5 * np.dot(x.T, np.dot(H, x)) + np.dot(c, x))

def jac(x, sign=1.):
    return sign * (np.dot(x.T, H) + c)

bounds = [(0, 1), (0, 1)]

现在损失函数,梯度,x 0和边界都已经到位,我们可以解决这个问题:

def solve(start):
    res = optimize.minimize(fun=loss, 
                            x0=start, 
                            jac=jac, 
                            bounds=bounds,
                            method='SLSQP')
    return res


solve(x0)   # valid initial value
# fun: -27.999999999963507
# jac: array([ 2.90878432e-14, -2.40000000e+01])
# message: 'Optimization terminated successfully.'
# ...
#  status: 0
# success: True
# x: array([1.45439216e-14, 1.00000000e+00])

solve(x1)      # invalid initial value:
#  fun: -29.534653465326528
#  jac: array([ -1.16831683, -23.36633663])
#  message: 'Positive directional derivative for linesearch'
#  ...
#  status: 8
#  success: False
#  x: array([-0.58415842,  1.07920792])

正如@pv.在公认的答案中指出的那样,该算法无法验证这是一个最小值:
我认为这条消息意味着优化器进入了一个位置,它没有设法找到目标函数值减小的方向(足够快),但也无法验证当前位置是否为最小值。

swvgeqrz

swvgeqrz5#

这不是一个完整的答案,但你可以在这里看到生成smode的源代码:
https://github.com/scipy/scipy/blob/master/scipy/optimize/slsqp/slsqp_optmz.f
mode = 8的导数(你问的“线性导数的正方向导数”)可以在第412和486行找到。如果你能弄清楚为什么它们在代码中被分配,你就得到了答案。

n3ipq98p

n3ipq98p6#

我一直在犯同样的错误。根据我的理解,这本质上意味着迭代解已经到达了搜索空间之外的一个点(根据约束/边界),但结果却陷入了局部极小值-这里的“线性”意味着任何方向的一步,即。从当前点的任何移动都会导致“正梯度”
有几件事,你可以尝试克服这一点:
1.(这对我很有效)确保你的边界和约束都是缩放的。例如,假设您有约束:
f(x)>=0且g(x)>=0
然后确保f(x)和g(x)的上界具有相似的数量级。即使f(x)=10和g(x)=100000可能是一个正确的解决方案,优化方法也不太可能达到这一点。
1.使用公差参数。这些可以根据用于优化的方法而变化。例如,'maxcv'参数在识别每个约束被违反的程度时非常有用。
1.尝试放松约束,以了解哪一个不合理地将迭代引导到搜索空间之外。
1.根据优化问题尝试不同的优化方法。

相关问题