【问题标题】:Interpreting the amax parameter in scipy's line_search解释 scipy 的 line_search 中的 amax 参数
【发布时间】:2018-05-21 17:38:40
【问题描述】:

在 SciPy 1.0.0 中,根据 its documentationscipy.optimize.line_search 有一个可选参数 amax,它决定了“最大步长”。

因此,我希望第一个返回值 alpha 始终小于给定的 amax,但事实并非如此,如下例所示:

from scipy.optimize import line_search

def f(x):
    return x[0]**2 + x[1]**2

def df(x):
    return 2*x

x = np.array([4, 5])
line_search(f, df, x, -df(x), amax=0.001)
# Returns (0.5, 3, 1, 0.0, 41.0, array([ 0.,  0.]))

其中alpha的值为0.5,而amax的值为0.001,小于0.5。

另一种解释可能是amax 限制了输出值x_newx0 之间的距离,但事实并非如此。

我是否误解了文档,或者这是 SciPy 中的错误?而且,如果它按预期工作,amax 的正确解释是什么,还有其他方法来限制执行线搜索的 alpha 范围吗?

【问题讨论】:

  • 哦,line_search 模块。碰过一次,失败了。似乎 alpha 增加了(从 1 开始),因此第一个 pick=1 用于您。您是否需要基于 wolfe 条件的行搜索。如果没有,我会尝试 armijo-ls,它可以从 1 到 0 工作。但当然它是另外一回事。如果您需要坚持这一点,您可能会在 github 上的问题跟踪器中找到一些讨论,当然还有 Nocedal 的数值优化中的伪代码。
  • Armijo 按预期做了(尝试过)(但仍未回答您的问题)。
  • 阅读代码感觉就像一个错误。如果初始猜测成功,则永远不会触及 amax。与 Nocedal 的区别也令人费解:amax 是 init 阶段的一部分。

标签: python scipy mathematical-optimization


【解决方案1】:

正如 sascha 所说,line_search (SciPy 1.0.0) 的当前实现不能正确处理 amax。具体来说,如果找到合适的 alpha,函数scalar_search_wolfe2 会跳出循环for i in xrange(maxiter),而对amax 的检查会出现在循环的后面并且没有到达。

解决方法:

  1. 使用旧例程line_search_wolfe1,它是MINPACK 行搜索的包装器。它不仅强制执行amax,还强制执行amin,最小步长。
from scipy.optimize.linesearch import line_search_wolfe1
line_search_wolfe1(f, df, x, -df(x), amax=0.001)

这将返回 (None, 1, 0, 41.0, 41.0, array([ 8, 10])) 其中 None 表示未找到合适的步骤。这是正确的答案:最多 0.001 的步长不满足 Wolfe 条件。

  1. 将步骤上的要求作为extra_condition 参数传递给line_search 例程。
line_search(f, df, x, -df(x), extra_condition=lambda a, x, f, g: a <= 0.001)

这会返回(None, 13, 1, None, 41.0, None),这又是正确的:没有合适的步长。

  1. 也许你并不是真的要强加沃尔夫的条件?毕竟,将“无”作为(正确)答案并不是很有帮助。如果是这样,请使用 Armijo 回溯。参数不同:它不要求df 函数,但它确实要求搜索初始点的梯度和值。参数alpha0 是初始步长和最大步长,算法只会在必要时减小它。
from scipy.optimize.linesearch import line_search_armijo
line_search_armijo(f, x, -df(x), df(x), f(x), alpha0=0.001)

返回(0.001, 1, 40.836164000000004),表示步长为0.001,有1次函数求值,步长后的函数值为40.8……当然比最初的41小了。

我在 SciPy 网站上没有看到 line_search_armijo 的文档,但我们可以阅读它的 docstring on Github

【讨论】:

  • 尝试了更多,确实line_search_armijo 表现更好,但它仍然有一些惊喜。例如,通过使用 $\phi'(0) > 0$ 的(可以说是损坏的)输入方向,它可能会返回负值 alpha(鉴于 @987654345 中的 amin=0,您不会期望@)。
  • 是的,源码说alpha&gt;0被假定为下降方向,也就是说derphi0被假定为负数。这个假设是涉及 alpha 和 amin 的不等式的基础。我不知道为什么在 derphi0>0 的情况下线搜索不会简单地出错。但是您可以自己添加此保护措施:在调用 line_search_armijo(f, xk, pk, gfk, old_fval) 之前,请确保 np.dot(gfk, pk) 是否定的。
  • 我的猜测是,当一些依赖 line_search 的多变量优化例程没有按预期执行时,会调整 line_search 以便它更有可能继续运行,而不是引发错误并终止过程。
【解决方案2】:

this pull request 将在 SciPy 1.3.0 中修复该错误,这会将行为更改为预期的行为:结果步长为None

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 1970-01-01
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    相关资源
    最近更新 更多