scipy.optimize.fmin_bfgs单个函数计算f和fprime

时间:2012-05-23 02:44:24

标签: python optimization scipy gradient

我正在使用scipy.optimize.fmin_bfgs(f, init_theta, fprime)来最小化f,它具有渐变fprime。我在一个函数中计算ffprime,因为大多数计算是相同的,所以不需要两次。

有没有办法调用fmin_bfgs()指定一个同时返回ffprime的函数?

3 个答案:

答案 0 :(得分:4)

如果您试图节省计算时间而不是仅仅为了代码方便而将ff'的计算结合起来,那么您的函数似乎需要额外的包装来缓存值,因为fmin_bfgs似乎不允许你传递这样的函数(与其他一些优化函数不同)。

这是一种方法,在一个小缓存中维护最近评估的10个点。 (我不确定对这个函数的调用是否需要是线程安全的:可能不是,但如果是这样,你可能需要在这里添加一些锁定,我想。)

def func_wrapper(f, cache_size=10):
    evals = {}
    last_points = collections.deque()

    def get(pt, which):
        s = pt.tostring() # get binary string of numpy array, to make it hashable
        if s not in evals:
            evals[s] = f(pt)
            last_points.append(s)
            if len(last_points) >= cache_size:
                del evals[last_points.popleft()]
        return evals[s][which]

    return functools.partial(get, which=0), functools.partial(get, which=1)

如果我们那么做

>>> def f(x):
...    print "evaluating", x
...    return (x-3)**2, 2*(x-3)

>>> f_, fprime = func_wrapper(f)

>>> optimize.fmin_bfgs(f_, 1000, fprime)
evaluating [ 994.93480441]
evaluating [ 974.67402207]
evaluating [ 893.63089268]
evaluating [ 665.93446894]
evaluating [ 126.99931561]
evaluating [ 3.]
Optimization terminated successfully.
         Current function value: 0.000000
         Iterations: 4
         Function evaluations: 7
         Gradient evaluations: 7
array([ 3.])

我们可以看到我们不重复任何评估。

答案 1 :(得分:1)

假设您有一个Python函数f(x),它返回函数值和渐变:

In [20]: def f(x):
   ....:     return (x-3)**2, 2*(x-3)

然后像这样单独传递输出:

In [21]: optimize.fmin_bfgs(lambda x: f(x)[0], 1000, lambda x: f(x)[1])
Optimization terminated successfully.
         Current function value: 0.000000
         Iterations: 4
         Function evaluations: 7
         Gradient evaluations: 7
Out[21]: array([ 3.])

答案 2 :(得分:0)

似乎没有办法直接这样做。但scipy.optimize.minimize确实允许你这样做。您可以为fprime而不是函数传递值True。这表示f返回函数值和梯度的元组。您可以使用method ='BFGS'调用minimize以获得所需的效果。

the source code for minimize是很有启发性的。它和fmin_bfgs最终都调用_minimize_bfgs,它将f和fprime作为单独的函数参数。当fprime是一个布尔值时,minimize巧妙地将fprime构造为一个对象,它记住f返回的最后一个值,并缓存渐变信息。