我有一个简单的函数
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可以轻易做到的事情吗?或者任何其他第三方工具?
下面是另一个尝试,基于 我的原话 以及随后的讨论。
据我所知 scipy.optimization 模块适用于具有标量或矢量输入和标量输出(或称 "成本")的函数。
由于你把每个方程都看作是独立于其他方程的,我最好的想法是使用多处理模块来并行完成工作。 如果你要最小化的函数和你的问题中的函数一样简单,我想说这是不值得的。
如果函数比较复杂,而你又想分工合作,可以尝试一下这样的方法。
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)
我来得有点晚了 但对于想通过并行计算来减少最小化时间的人来说,这可能会很有趣。
我们实现了一个并行版本的 scipy.optimize.minimize(method='L-BFGS-B')
包装内 最佳平行 可在PyPI上使用,它可以通过并行评估目标函数和(近似)梯度来加速优化。它可以通过并行评估目标函数和(近似)梯度来加快优化速度。下面是一个例子。
from optimparallel import minimize_parallel
def my_square(x, a=1):
return (x - a)**2
minimize_parallel(fun=my_square, x0=1, args=11)
如果我理解你的意图,你可以为两个目标函数传递numpy数组。x
和 a
因此,您可以优化您的所有 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