为scipy.optimize.fmin(和其他人)设置收敛标准

时间:2015-05-21 02:22:33

标签: python numpy optimization scipy

我正在开展一项优化任务,其中成本函数评估非常昂贵,并且可以容忍一些错误。我正在使用scipy.optimize中的一些预先打包的scipy方法来开始。我正在使用的第一个是fmin,它实现了nelder mead单纯形算法。

此函数有两个收敛相关参数xtol和ftol,其中(as I understand it)指定收敛标准,其中如果x或f(参数集和成本分别)变化小于xtol或ftol迭代,函数返回。

但是,由于成本函数对我来说太贵了,我还希望能够指定一个成本阈值,如果它找到一个成本低于阈值的点,它将立即返回。

是否可以为scipy.optimize.fmin指定此阈值?

奖金问题:我没有详细介绍过许多其他方法,但看起来这个阈值选项看起来并不存在。这是典型的scipy优化方法吗?尝试提供此功能对我来说是否有价值?

1 个答案:

答案 0 :(得分:1)

可以停止任何可以表示为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