我有一个简单的功能
def square(x, a=1):
return [x**2 + a, 2*x]
对于多个参数x
,我希望将其最小化a
。我目前有循环,在精神上,做这样的事情:
In [89]: from scipy import optimize
In [90]: res = optimize.minimize(square, 25, method='BFGS', jac=True)
In [91]: [res.x, res.fun]
Out[91]: [array([ 0.]), 1.0]
In [92]: l = lambda x: square(x, 2)
In [93]: res = optimize.minimize(l, 25, method='BFGS', jac=True)
In [94]: [res.x, res.fun]
Out[94]: [array([ 0.]), 2.0]
现在,该功能已经过矢量化
In [98]: square(array([2,3]))
Out[98]: [array([ 5, 10]), array([4, 6])]
In [99]: square(array([2,3]), array([2,3]))
Out[99]: [array([ 6, 12]), array([4, 6])]
这意味着并行运行所有优化而不是循环可能要快得多。这是SciPy可以轻松实现的吗?或任何其他第三方工具?
答案 0 :(得分:14)
这是另一次尝试,基于my original answer以及随后的讨论。
据我所知,scipy.optimize模块用于带标量或矢量输入和标量输出或“成本”的函数。
由于您将每个等式视为独立于其他等式,我最好的想法是使用多处理模块并行完成工作。如果您最小化的功能与问题中的功能一样简单,我会说这不值得付出努力。
如果功能更复杂,并且您想分工,请尝试以下方法:
import numpy as np
from scipy import optimize
from multiprocessing import Pool
def square(x, a=1):
return [np.sum(x**2 + a), 2*x]
def minimize(args):
f,x,a = args
res = optimize.minimize(f, x, method = 'BFGS', jac = True, args = [a])
return res.x
# your a values
a = np.arange(1,11)
# initial guess for all the x values
x = np.empty(len(a))
x[:] = 25
args = [(square,a[i],x[i]) for i in range(10)]
p = Pool(4)
print p.map(minimize,args)
答案 1 :(得分:4)
我参加聚会有点晚了。但这对于希望通过并行计算减少最小化时间的人可能很有趣:
我们在PyPI上可用的软件包 optimparallel 中实现了scipy.optimize.minimize(method='L-BFGS-B')
的并行版本。通过并行评估目标函数和(近似)梯度,可以加快优化速度。这是一个示例:
from optimparallel import minimize_parallel
def my_square(x, a=1):
return (x - a)**2
minimize_parallel(fun=my_square, x0=1, args=11)
答案 2 :(得分:1)
如果我了解您的意图,您可以为x
和a
传递numpy数组,这样您就可以同时优化所有a
参数。
尝试类似:
def square(x, a=1):
return [np.sum(x**2 + a), 2*x]
# your a values
a = np.arange(1,11)
# initial guess for all the x values
x = np.empty(len(a))
x[:] = 25
# extra arguments to pass to the objective function, in this case, your a values
args = [a]
res = optimize.minimize(square, x, method = 'BFGS', jac = True, args = args)
这似乎得到了正确的结果。
>>> res.x
[ -8.88178420e-16 -8.88178420e-16 -8.88178420e-16 -8.88178420e-16
-8.88178420e-16 -8.88178420e-16 -8.88178420e-16 -8.88178420e-16
-8.88178420e-16 -8.88178420e-16]
>>> res.fun
55.0