【问题标题】:python scipy differential evolution optimization fails with workers not 1python scipy差分进化优化失败,工人不是1
【发布时间】:2020-05-01 19:37:22
【问题描述】:

我正在尝试使用the scipy differential evolution algoworkers 参数。

当我把它设置为 1 时,我的脚本运行没有问题。 如果我放了一些不同的东西,它会失败并出现以下回溯:

Traceback (most recent call last):
  File "/home/ubuntu/.local/lib/python3.6/site-packages/scipy/_lib/_util.py", line 419, in __call__
    return self._mapfunc(func, iterable)
  File "/usr/lib/python3.6/multiprocessing/pool.py", line 266, in map
    return self._map_async(func, iterable, mapstar, chunksize).get()
  File "/usr/lib/python3.6/multiprocessing/pool.py", line 644, in get
    raise self._value
  File "/usr/lib/python3.6/multiprocessing/pool.py", line 424, in _handle_tasks
    put(task)
  File "/usr/lib/python3.6/multiprocessing/connection.py", line 206, in send
    self._send_bytes(_ForkingPickler.dumps(obj))
  File "/usr/lib/python3.6/multiprocessing/reduction.py", line 51, in dumps
    cls(buf, protocol).dump(obj)
TypeError: cannot serialize '_io.TextIOWrapper' object

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ubuntu/.local/lib/python3.6/site-packages/scipy/optimize/_differentialevolution.py", line 878, in _calculate_population_energies
    parameters_pop[0:nfevs]))
  File "/home/ubuntu/.local/lib/python3.6/site-packages/scipy/_lib/_util.py", line 422, in __call__
    raise TypeError("The map-like callable must be of the"
TypeError: The map-like callable must be of the form f(func, iterable)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "main_parallel.py", line 323, in <module>
    optimizer(args.asset_class, udl, tenor, args.criteria, params_decay, params, couch_server, args.num_workers)
  File "main_parallel.py", line 269, in optimizer
    maxiter=5, workers=num_workers, mutation=(0.5, 1.5), recombination=0.8)
  File "/home/ubuntu/.local/lib/python3.6/site-packages/scipy/optimize/_differentialevolution.py", line 306, in differential_evolution
    ret = solver.solve()
  File "/home/ubuntu/.local/lib/python3.6/site-packages/scipy/optimize/_differentialevolution.py", line 745, in solve
    self.population[self.feasible]))
  File "/home/ubuntu/.local/lib/python3.6/site-packages/scipy/optimize/_differentialevolution.py", line 883, in _calculate_population_energies
    raise RuntimeError("The map-like callable must be of the"
RuntimeError: The map-like callable must be of the form f(func, iterable), returning a sequence of numbers the same length as 'iterable'

有人可以帮忙解释如何使用这个参数(具体目标函数?其他约束?)?

还有一个使用多核的简单 python 差异进化优化示例,我们将不胜感激。

【问题讨论】:

    标签: python python-3.x parallel-processing scipy differential-evolution


    【解决方案1】:

    differential evolution documentation 关于工人使用的关键部分是警告,当worker != 1 时,它

    [...] 要求 func 是可腌制的

    出现的错误中有几个提示表明func 不可腌制,即

        self._mapfunc(func, iterable)
        ...
        self._send_bytes(_ForkingPickler.dumps(obj))
        ...
    TypeError: cannot serialize '_io.TextIOWrapper' object
    

    显然,有人尝试酸洗func,但失败了,大概是因为func 不可酸洗。正如文档中的另一个签名所表明的那样,workers 似乎试图被解释为 类似地图或可调用。可以预见的是,这也会失败,因为workers 实际上是int

    文档包含一个complete example,其中workers != 1 工作正常,

    from scipy.optimize import differential_evolution, rosen
    bounds = [(0,2), (0, 2), (0, 2), (0, 2), (0, 2)]
    result = differential_evolution(rosen, bounds, updating='deferred',
                                    workers=-1)
    result.x, result.fun
    

    如果您将scipy.optimize.differential_evolution 中使用的func 重构为可通过pickling 序列化,您应该能够成功使用workers != 1

    【讨论】:

    • 感谢您的帮助。你怎么知道罪魁祸首是 args.asset_class ?它只是一个字符串,所以我假设它的处理是内置的。
    • @Chapo 那是一个错误,我误读了错误声明。我需要看看你如何调用 scipy.optimize.differential_evolution 来告诉你需要重构哪些内容以进行酸洗
    • result_diff_evo = differential_evolution(func=optimizer_function, bounds=bounds, args=( init_params_names, df, criteria, params_decay[udl][tenor]["first_date"], params_decay[udl][tenor]["busdays"], params_decay[udl][tenor]["coeff"], params_decay[udl][tenor]["spot_start"], params_decay[udl][tenor]["iv_start"], params["verbose"], folder, tested_params,), init=pop_denorm, maxiter=5, workers=num_workers, mutation=(0.5, 1.5), recombination=0.8, print=True) 是实际行
    • @Chapo 解决您的问题的方法是将optimizer_function 重构为可通过酸洗进行序列化
    • 所有参数都相当简单,除了tested_params 是通过tested_params = open(f"tested_params.csv", "w") 获得的。会不会是问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-24
    • 2019-12-07
    • 2014-09-05
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多