解释 scipy 的 line_search 中的 amax 参数

Interpreting the amax parameter in scipy's line_search

在SciPy 1.0.0中,根据its documentationscipy.optimize.line_search有一个可选参数amax决定了"Maximum step size".

因此,我希望第一个 return 值 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 范围吗?

正如 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)

This returns (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)

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

  1. 也许你不是真的想强加沃尔夫的条件?毕竟,将 None 作为(正确的)答案并不是很有帮助。如果是这样,请使用 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)

returns (0.001, 1, 40.836164000000004)表示步长为0.001,有1次函数求值,步后函数值为40.8...当然比最初的41小.

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

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