【问题标题】:Positive directional derivative for linesearch线搜索的正方向导数
【发布时间】:2012-06-22 11:58:23
【问题描述】:

scipy.optimize '线搜索的正方向导数'的smode是什么意思?

例如在 fmin_slsqp http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_slsqp.html

【问题讨论】:

  • 请提供文档页面的链接。

标签: scipy


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 更一般的答案是,正在优化的函数的扩展性很差。我认为理想的情况是,被优化的函数应该倾向于给出 1-5 范围内的平均值。对于我的用例,我必须乘以 1000。
    • 我知道这是一个老问题,但是如果您将要优化的功能除以 n 以哄该方法工作,您如何处理解决方案中的值 x ?
    • @Windstorm1981,如果你只缩放目标,那么解决方案值x 应该是好的。但是,如果您还缩放了输入值,那么您必须在最后反转缩放以获得实际解决方案。对于这些问题,最好将所有值(包括输入和目标)缩放到 1 阶。最后实现这种缩放和取消缩放需要一些努力,但如果优化问题很大,这应该会有所帮助收敛很多。
    • @jebob 你有最佳范围 1-5 的来源吗?
    • @scleronomic docs.mosek.com/9.2/toolbox/presolver.html 说“相同的数量级”。 gams.com/blog/2017/08/scaling 表示范围为四个数量级和大约 1。我没有
    【解决方案3】:

    为避免更改函数,您还可以尝试使用 ftol 和 eps 参数。把ftol改大就相当于把函数改小了。

    【讨论】:

    • 更适合作为评论
    • 确实如此。发帖时出错了,不知道怎么改。
    【解决方案4】:

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

    1. x0 超出了您在 bounds 中定义的有效范围。
    2. 对于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)]
    

    现在损失函数、梯度、x0 和边界已经到位,我们可以解决问题了:

    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。在接受的答案中指出,算法无法验证这是最小值:

    我认为这条消息意味着优化器进入了一个位置,它无法找到目标函数值减小的方向(足够快),但也无法验证当前位置是否为最小值。

    【讨论】:

      【解决方案5】:

      这不是一个完整的答案,但是您可以在此处查看生成 smode 的源代码:

      https://github.com/scipy/scipy/blob/master/scipy/optimize/slsqp/slsqp_optmz.f

      mode = 8(您所询问的“线搜索的正向导数”)的分配可以在第 412 和 486 行中找到。如果能弄清楚为什么它们在代码中被分配,那么您已经得到了答案。

      【讨论】:

        猜你喜欢
        • 2018-05-06
        • 1970-01-01
        • 2023-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-15
        相关资源
        最近更新 更多