【发布时间】:2019-09-24 19:54:10
【问题描述】:
我正在使用 scipy.optimize (differential evolution) 进行优化。整体效果很好。我已经开始使用 worker 功能(它允许您告诉优化将群体中的个体分拆到其他进程中,从而非常容易地有效地并行化优化过程)。
我发现如果我指定workers=-1,我的所有核心都将投入工作,正如它们应该的那样。
模拟在一个结构中管理:
""" Sandbox stuff """
from scipy.optimize import *
class Simulation:
def __init__(self):
self.data = None
def optim_manager(self):
optimized_results = differential_evolution(self.optim_loop,
bounds=self.bounds, callback=self.optim_callback, workers=-1)
def optim_loop(self, parameters):
self.data = run_model(parameters)
optim_value = self.calc_optim_value(self.data)
# at this point self.data exist & is not None
return optim_value
def optim_callback(self,*args):
# *args contains the parameters value for that optimal run
optim_value = self.calc_optim_value(self.data) # error
write_optimisation_run_to_dictionnary(args, optim_value)
但是,当我尝试在回调中计算 optim_value 时,我得到:
Traceback (most recent call last):
File "lancer_modele.py", line 512, in <module>
mp.launch()
File "lancer_modele.py", line 234, in launch
self.do_optim_ghosts()
File "lancer_modele.py", line 296, in do_optim_ghosts
opt.opti_manager_ghosts(**merged_kwargs)
File "/home/atari/PycharmProjects/RT/managers/optimisation.py", line 41, in opti_manager_ghosts
simul_params = simul.fctopti_ghosts(nbrite=1, free_params_ordereddict=free_init_params[-1], **kwargs) # it returns other stuff we don't need, a,b,c
File "/home/atari/PycharmProjects/RT/managers/Simulation.py", line 225, in fctopti_ghosts
popsize=5, callback=self.optim_callback, workers=2)
File "/home/atari/.local/lib/python3.6/site-packages/scipy/optimize/_differentialevolution.py", line 272, in differential_evolution
ret = solver.solve()
File "/home/atari/.local/lib/python3.6/site-packages/scipy/optimize/_differentialevolution.py", line 701, in solve
convergence=self.tol / convergence) is True):
File "/home/atari/PycharmProjects/RT/managers/Simulation.py", line 433, in optim_callback
optim_value = self.calc_ghost_optimized_value()
File "/home/atari/PycharmProjects/RT/managers/Simulation.py", line 509, in calc_ghost_optimized_value
optim_value = np.sum(cubedata[:,:,self.gstart_tick:self.gstop_tick])
TypeError: 'NoneType' object is not subscriptable
因为 self.data 在 optim_callback 的上下文中是 None 。但是,如果我只使用 1 个核心,这可以正常工作。我猜想当使用多个内核时,该类被序列化并传递,并且在每个运行的进程中更新属性。然后它返回到主进程,在该进程中,Simulation 仍然保持原样,因为调用了 worker 分拆(因此它仍然具有 self.data = None)。这意味着我不能轻易计算出最佳值,而且似乎虽然 scipy 的回调给了我所有的参数值,但它并没有传递我告诉它的值,这些值在我的模型中是值得的。
有什么想法吗?我想我可以在 optim_callback 中单独重新创建一个完整的模型,使用提供的参数对其进行更新,再次运行它以获得优化值。但是,运行模型的时间适中,我不想每次获得(中间)最优值时都减慢优化速度。
【问题讨论】:
标签: python-3.x scipy multiprocessing