为 scipy.optimize.fmin(及其他)设置收敛标准
Setting convergence criteria for scipy.optimize.fmin (and others)
我正在进行一项优化任务,其中成本函数评估非常昂贵,并且可以容忍一些错误。我正在使用 scipy.optimize 中的一些预先打包的 scipy 方法来开始。我正在使用的第一个是 fmin,它实现了 nelder mead 单纯形算法。
此函数有两个收敛相关参数 xtol 和 ftol,其中 (as I understand it) 指定收敛标准,其中如果 x 或 f(分别为参数集和成本)变化小于 xtol 或 ftol在一次迭代中,函数 returns.
但是,由于成本函数对我来说太昂贵了,我还希望能够指定一个成本阈值,如果它找到一个成本低于阈值的点,它将立即 return。
是否可以为 scipy.optimize.fmin 指定此阈值?
奖金问题:我没有详细研究许多其他方法,但看起来这些方法也不存在此阈值选项。这对 scipy 优化方法来说是典型的吗?尝试贡献此功能对我来说有价值吗?
对于任何可以表示为 x
函数的标准,都可以停止迭代。这里的思路是劫持callback
方法,利用异常进行流量控制。这里有两个利用这个想法的解决方案:
from scipy.optimize import fmin_bfgs
import numpy as np
f = lambda x: np.linalg.norm(x**2)
x0 = np.random.rand(100)
解决方案 1:
global result
class SmallEnoughException(Exception):
pass
def check_conv_criteria(xk):
global result
if np.linalg.norm(xk) < 0.1:
result = xk
raise SmallEnoughException()
try:
x, _, _ = fmin_bfgs(f, x0, callback=check_conv_criteria)
except SmallEnoughException:
x = result
解决方案 2:
class StopOptimizingException(Exception):
pass
class CallbackCollector:
def __init__(self, f, thresh):
self._f = f
self._thresh = thresh
def __call__(self, xk):
if self._f(xk) < self._thresh:
self.x_opt = xk
raise StopOptimizingException()
try:
cb = CallbackCollector(f, thresh=0.2)
x, _, _ = fmin_bfgs(f, x0, callback=cb)
except StopOptimizingException:
x = cb.x_opt
我正在进行一项优化任务,其中成本函数评估非常昂贵,并且可以容忍一些错误。我正在使用 scipy.optimize 中的一些预先打包的 scipy 方法来开始。我正在使用的第一个是 fmin,它实现了 nelder mead 单纯形算法。
此函数有两个收敛相关参数 xtol 和 ftol,其中 (as I understand it) 指定收敛标准,其中如果 x 或 f(分别为参数集和成本)变化小于 xtol 或 ftol在一次迭代中,函数 returns.
但是,由于成本函数对我来说太昂贵了,我还希望能够指定一个成本阈值,如果它找到一个成本低于阈值的点,它将立即 return。
是否可以为 scipy.optimize.fmin 指定此阈值?
奖金问题:我没有详细研究许多其他方法,但看起来这些方法也不存在此阈值选项。这对 scipy 优化方法来说是典型的吗?尝试贡献此功能对我来说有价值吗?
对于任何可以表示为 x
函数的标准,都可以停止迭代。这里的思路是劫持callback
方法,利用异常进行流量控制。这里有两个利用这个想法的解决方案:
from scipy.optimize import fmin_bfgs
import numpy as np
f = lambda x: np.linalg.norm(x**2)
x0 = np.random.rand(100)
解决方案 1:
global result
class SmallEnoughException(Exception):
pass
def check_conv_criteria(xk):
global result
if np.linalg.norm(xk) < 0.1:
result = xk
raise SmallEnoughException()
try:
x, _, _ = fmin_bfgs(f, x0, callback=check_conv_criteria)
except SmallEnoughException:
x = result
解决方案 2:
class StopOptimizingException(Exception):
pass
class CallbackCollector:
def __init__(self, f, thresh):
self._f = f
self._thresh = thresh
def __call__(self, xk):
if self._f(xk) < self._thresh:
self.x_opt = xk
raise StopOptimizingException()
try:
cb = CallbackCollector(f, thresh=0.2)
x, _, _ = fmin_bfgs(f, x0, callback=cb)
except StopOptimizingException:
x = cb.x_opt