首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >scipy.optimize.minimize,一次计算约束及其雅可比

scipy.optimize.minimize,一次计算约束及其雅可比
EN

Stack Overflow用户
提问于 2017-03-16 23:31:35
回答 1查看 1.2K关注 0票数 4

在极小化问题上的约束和它们的雅可比之间有相当多的共享计算,到了几乎免费得到雅可比的程度。有什么方法来分享计算吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-17 13:59:00

由于约束和雅克比可能并不总是一起评估,所以您只能期望得到较小的改进。但是,如果您可以将通用计算放入单独的函数/方法中,则可以对其返回值进行缓存,以便以后不需要重新计算它们:

代码语言:javascript
复制
import scipy.optimize as opt
from functools import lru_cache

# only for the dummy example:
import scipy as sp
from time import sleep

def cost(x):
    '''dummy cost function to minimize on [1,11]'''
    return sp.log(x)

@lru_cache(maxsize=None) # careful with this choice
def heavy_stuff(x):
    '''idle computation representing common work in constraint and jacobian'''
    sleep(0.1)
    return 0

def constraint(x):
    '''constraint for [1,11], with simulated idle work'''
    # the following only works for 1d arrays, needs more work for nd
    throwaway = heavy_stuff(tuple(x))  
    return 5 - abs(6 - x)  # non-negative between 1 and 11

def jacobian(x):
    '''return the jacobiam with the same simulated idle work'''
    throwaway = heavy_stuff(tuple(x))
    return 1/x

x0 = 11
tol = 0
opts = {'disp': True}
cons = {'type': 'ineq', 'fun': constraint}
kwargs = {'method':'SLSQP', 'constraints': cons,
          'jac': jacobian, 'tol': tol, 'options': opts}
res = opt.minimize(cost,x0,**kwargs)
print(heavy_stuff.cache_info())

上面的虚拟示例尝试在间隔log(x)上最小化[1,11]。与常量界不同,我定义了一个给出区间的约束,这样我就可以表明我对你的问题的意思。

constraintjacobian都做着相同的工作,如果多个评估发生在相同的参数中,这就是您想要的。您必须将所有这些公共计算放入一个公共函数(此处名为heavy_stuff),并处理constraintjacobian中的返回值。

我的观点是,你应该使用functools.lru_cache回忆录沉重的东西。通过设置适当的缓存大小,具有相同x的多个x计算结果将同时给出先前计算的返回值,而不必重新进行计算。

如果我的怀疑是正确的,那么maxsize=1lru_cache装饰器中可能就足够了。设置maxsize=None (无上限)会造成失去太多内存的危险。你应该进行实验,看看是否需要多个回忆录的价值观,或者仅仅一个或几个就够了。

但是,请注意,lru_cache使用dict查找以前计算过的结果,其中键是修饰函数的输入参数。这意味着输入参数必须是可接受的,这实际上意味着它们应该是不可变的。Numpy数组非常类似于列表,它们也同样不可接受。这就是我们用heavy_stuff调用tuple(x)的原因:一维数组输入被转换为元组。如果x是一个多维数组,那么每个层次的嵌套都必须转换为一个元组。更糟糕的是,heavy_stuff几乎肯定必须将元组转换为numpy ndarray,这样才能完成繁重的工作。但是,如果计算jacobian/constraint确实是CPU密集型的,那么总体上您可能还是更好。

如果您想评估缓存的性能,应该仔细查看最后打印的heavy_stuff.cache_info()。它将告诉您缓存值的使用频率,以及必须计算多少次新值。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42846648

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档