Scipy.Optimize - 在 Python 中的最后一次迭代中进行多处理和恢复



Scipy.Optimize可以选择通过将"workers"参数更改为>1(或-1(来启用多处理。但是,如果我希望能够从上次迭代中恢复优化,同时仍然使用多处理功能,这似乎是不可能的。

我可以通过使用 DiffialEvolutionSolver (按照 https://github.com/scipy/scipy/issues/6517>恢复操作(,但是在 Differential EvolutionSolver 中 1 的"worker"使我无法为了保持会话之间的持久性而挑选对象。

import pickle
from scipy.optimize._differentialevolution import DifferentialEvolutionSolver  
bounds = [(-1, 1)]
bounds = bounds * 66
if __name__ == '__main__':
solver = DifferentialEvolutionSolver(converter, bounds, disp=True, seed=9, workers=-1, 
maxiter=1)
for i in range(100):
best_x, best_cost = next(solver)
print(solver.population_energies.min())
with open('solver_%d.pkl' % i, 'wb') as f:
pickle.dump(solver, f)

此代码在尝试首次运行时立即生成以下错误:

未实现错误:池对象无法在进程之间传递 或腌制

但是,如果我使用"workers=1",代码工作正常,但显然要慢得多。

有没有办法同时获得多处理和保存每个迭代的能力?

请记住,DifferentialEvolutionSolver不是 SciPy 公共 API 的一部分,它可能会发生变化。需要更改能力才能提高性能或重新设计。具有向后兼容性的面向公众的功能是differential_evolution。 如果您准备好应对这种情况,那么您可以使用以下内容:

import pickle
from multiprocessing import Pool
from scipy.optimize import rosen
from scipy.optimize._differentialevolution import DifferentialEvolutionSolver  
bounds = [(-2, 2), (-2, 2)]
with Pool(2) as p:
# make sure that `updating='deferred'`, as this is required for
# parallelisation
solver = DifferentialEvolutionSolver(
rosen,
bounds,
seed=9,
workers=1,
updating='deferred',
)
for i in range(100):
# the _mapwrapper attribute needs to be a map-like
solver._mapwrapper = p.map
best_x, best_cost = next(solver)
print(solver.population_energies.min())
solver._mapwrapper = map
with open(f"solver_{i}.pkl", 'wb') as f:
pickle.dump(solver, f)

最新更新