解释 scipy 的 line_search 中的 amax 参数
Interpreting the amax parameter in scipy's line_search
在SciPy 1.0.0中,根据its documentation,scipy.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_new
和 x0
之间的距离,但事实并非如此。
我是否误解了文档,或者这是 SciPy 中的错误?而且,如果它按预期工作,amax
的正确解释是什么,还有其他方法可以限制执行线搜索的 alpha 范围吗?
正如 sascha 所说,line_search
(SciPy 1.0.0)的当前实现没有正确处理 amax
。具体来说,如果找到合适的 alpha,函数 scalar_search_wolfe2
就会跳出循环 for i in xrange(maxiter)
,而对 amax
的检查出现在循环的后面并且没有到达。
解决方法:
- 使用旧例程
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 条件。
- 将步骤的要求作为
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)
又是正确的:没有合适的步长。
- 也许你不是真的想强加沃尔夫的条件?毕竟,将 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
。
在SciPy 1.0.0中,根据its documentation,scipy.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_new
和 x0
之间的距离,但事实并非如此。
我是否误解了文档,或者这是 SciPy 中的错误?而且,如果它按预期工作,amax
的正确解释是什么,还有其他方法可以限制执行线搜索的 alpha 范围吗?
正如 sascha 所说,line_search
(SciPy 1.0.0)的当前实现没有正确处理 amax
。具体来说,如果找到合适的 alpha,函数 scalar_search_wolfe2
就会跳出循环 for i in xrange(maxiter)
,而对 amax
的检查出现在循环的后面并且没有到达。
解决方法:
- 使用旧例程
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 条件。
- 将步骤的要求作为
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)
又是正确的:没有合适的步长。
- 也许你不是真的想强加沃尔夫的条件?毕竟,将 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
。