在尝试使用Scipy的优化算法来最小化在子过程中计算其值的函数时,我发现基于梯度的算法(到目前为止流域购物和L-BFGS-B)在optimize.py的第562行遇到以下错误:
grad [k] =(f(*((xk d,)args)) - f0)/ d [k]
TypeError:不支持的操作数类型 - :'NoneType'和'NoneType'
以下是生成此错误的代码的简单示例:
import multiprocessing as mp
from scipy.optimize import basinhopping
def runEnvironment(x):
return x**2
def func(x):
if __name__ == '__main__':
print "x:",x
pool = mp.Pool(processes=1)
results=pool.apply(runEnvironment,(x,))
pool.close()
return results
x0=5
ret=basinhopping(func, x0, niter=100, T=1.0, stepsize=0.1, minimizer_kwargs=None, take_step=None, accept_test=None, callback=None, interval=50, disp=False, niter_success=None)
请注意,如果删除了多处理组件,或者使用了基于非梯度的算法(如COBYLA),则此代码可以正常运行 . 任何人都可以想到这种情况发生的原因吗?
2 回答
你的
if __name__ == '__main__':
成语位置不正确 - 以这种方式重新排列:仅使用一个工作进程创建许多小
mp.Pool
是低效的 . 每次调用func
创建一个池也是低效的,因为多次调用func
.而是在程序开始时创建一个
Pool
,并将池传递给每次调用func
:minimizer_kwargs=dict(args=pool)
告诉optimize.basinhopping
将pool
作为func
的附加参数传递 .你也可以使用
获取日志语句,显示调用函数的过程 . 例如,
版画
这表明
func
总是由主进程调用,而runEnvironment
由工作进程运行 .请注意,对
func
的调用是按顺序进行的 . 要从pool
中获得任何好处,每次调用func
时都需要运行更多处理器 .