5

我正在尝试对生化过程进行建模,并将我的问题构建为一个优化问题,我使用 differential_evolutionscipy 解决了这个问题。
到目前为止,一切都很好,我对使用 15-19 个参数的简化模型的实现感到非常满意。
我扩展了模型,现在有 32 个参数,花费的时间太长了。并非完全出乎意料,但仍然是一个问题,因此是这个问题。

我已经看到: - R并行差分进化
的几乎相同的问题 - 以及关于该主题 的 github 问题https://github.com/scipy/scipy/issues/4864

但它想留在 python 中(模型在 python 管道中),尽管已经提出了一些选项,但拉取请求还没有导致并正式接受的解决方案。

此外,我无法并行化要优化的函数内的代码,因为这是一系列顺序计算,每个计算都需要上一步的结果。理想的选择是有一些东西可以并行评估一些个体并将它们返回给总体。

总结:
- scipy 中是否有任何选项允许我愚蠢地忽略的差分进化并行化?(理想的解决方案)
- 是否有关于 scipy 中的替代算法的建议,该算法要么(方式)串行速度更快,要么可以并行化?
- 有没有其他提供并行差分进化功能的好包?还是其他适用的优化方法?
- 健全性检查:我是否用 32 个参数重载了 DE,我需要彻底改变方法吗?

PS
我是一名生物学家,正式的数学/统计学并不是我的强项,任何公式到英文的翻译都将不胜感激:)

PPS
作为一个极端的选择,我可以尝试迁移到 R,但我无法编写 C/C++ 或其他语言。

4

4 回答 4

6

通过指定工人, Scipydifferential_evolution现在可以非常容易地并行使用:

工人int 或类似地图的可调用,可选

如果workers是一个int,则人口被细分为workers部分并并行评估(使用multiprocessing.Pool)。提供 -1 以使用所有可用的 CPU 内核。或者提供一个类似地图的可调用对象,例如 multiprocessing.Pool.map 用于并行评估总体。这个评估是作为工人(func,iterable)进行的。如果workers != 1,此选项将更新关键字覆盖为updated='deferred'。要求func 是可腌制的。

版本 1.2.0 中的新功能。

scipy.optimize.differential_evolution 文档

于 2019-09-10T15:37:04.180 回答
4

感谢@jp2011 指向pygmo

首先,值得注意的是与 pygmo 1 的区别,因为 google 上的第一个链接仍然指向旧版本。

二、Multiprocessing island 仅适用于 python 3.4+

第三,它有效。当我第一次提出这个问题时,我开始的进程在我写作时仍在运行,pygmo 群岛在不到 3 小时的时间内对 saDE 中存在的所有 18 种可能的 DE 变体进行了广泛的测试。此处建议使用 Numba 的编译版本https://esa.github.io/pagmo2/docs/python/tutorials/coding_udp_simple.html可能会更早完成。起首。

我个人觉得它比 scipy 版本不太直观,因为需要构建一个新类(与 scipy 中的一个 signle 函数相比)来定义问题,但这可能只是个人喜好。此外,突变/交叉参数的定义不太清楚,因为第一次接近 DE 的人可能有点模糊。
但是,由于 scipy 中的串行 DE 并没有削减它,欢迎使用 pygmo(2)。

此外,我还发现了其他几个声称可以并行化 DE 的选项。我自己没有测试它们,但可能对偶然发现这个问题的人有用。

Platypus,专注于多目标进化算法 https://github.com/Project-Platypus/Platypus

雅盒
https://github.com/pablormier/yabox

来自 Yabox 创建者对 DE https://pablormier.github.io/2017/09/05/a-tutorial-on-differential-evolution-with-python/的详细但恕我直言清晰的解释

于 2018-06-23T16:40:06.320 回答
2

我一直有完全相同的问题。也许,您可以尝试pygmo,它确实支持不同的优化算法(包括 DE)并具有并行计算模型。但是,我发现社区并不像 scipy 那样大。他们的教程、文档和示例质量很好,可以从中得到一些东西。

于 2018-06-15T09:08:40.670 回答
0

我建议使用 PyFDE 的批处理模式。 https://pythonhosted.org/PyFDE/tutorial.html#batch-mode 在批处理模式下,每次迭代只调用一次适应度函数来评估所有种群的适应度。

不带批处理模式的示例:

import pyfde
from math import cos, pi
import time
import numpy

t1=time.time()
def fitness(p):
    x, y = p[0], p[1]
    val = 20 + (x**2 - 10*cos(2*pi*x)) + (y**2 - 10*cos(2*pi*y))
    return -val
    
solver = pyfde.ClassicDE(fitness, n_dim=2, n_pop=40, limits=(-5.12, 5.12))
solver.cr, solver.f = 0.9, 0.45
best, fit = solver.run(n_it=150)
t2=time.time()
print("Estimates: ",best)
print("Normal mode elapsed time (s): ",t2-t1)

批处理模式示例:

t1=time.time()
def vec_fitness(p,fit):
    x, y = numpy.array(p[:,0]), numpy.array(p[:,1])
    val = 20 + (x**2 - 10*numpy.cos(2*pi*x)) + (y**2 - 10*numpy.cos(2*pi*y))
    fit[:] = -val
    
solver = pyfde.ClassicDE(vec_fitness, n_dim=2, n_pop=40, limits=(-5.12, 5.12), batch=True)
solver.cr, solver.f = 0.9, 0.45
best, fit = solver.run(n_it=150)
t2=time.time()
print("Estimates: ",best)
print("Batch mode elapsed time (s): ",t2-t1)

输出是:

估计:[1.31380987e-09 1.12832169e-09]
正常模式经过时间(秒):0.015959978103637695

估计:[2.01733383e-10 1.23826873e-10]
批处理模式经过时间(秒):0.006017446517944336

################################################# ##########

它快 1.5 倍,但仅适用于一个简单的问题。对于一个复杂的问题,您可以看到 > 10 倍的速度。代码运行在单个 CPU 内核上(无多处理),性能提升来自矢量化和 MIMD(多指令,多数据)的使用。结合矢量化和并行/多处理将导致双重改进。

于 2021-05-03T22:26:20.017 回答