我正在尝试对生化过程进行建模,并将我的问题构建为优化问题,我使用scipy中的differential_evolution
来解决。
到目前为止,非常好,我很满意15-19参数的简化模型的实现
我扩展了模型,现在有32个参数,花了太长时间。并非完全出乎意料,但仍然是一个问题,因此这个问题。
我见过:
- 对于R Parallel differential evolution来说几乎完全相同的问题
- 以及关于主题的github问题https://github.com/scipy/scipy/issues/4864
但是它希望保留在python中(模型在python管道中),并且pull请求还没有导致并正式接受解决方案,尽管已经提出了一些选项。
另外,我无法并行化要优化的函数中的代码,因为它是一系列顺序计算,每个都需要上一步的结果。理想的选择是拥有能够并行评估某些人并将其返回给人群的东西。
总结:
- 在scipy中是否有任何选项允许我笨拙地忽略了差分进化的并行化? (理想的解决方案)
- 是否有关于scipy中替代算法的建议,要么(方式)串行更快或可以并行化?
- 是否还有其他提供并行差分进化功能的优质软件包?或其他适用的优化方法?
- 完整性检查:我是否用32参数重载DE,我需要从根本上改变方法吗?
PS
我是一名生物学家,正式的数学/统计学并不是我的实力,任何公式对英语的翻译都会非常感激:)
PPS
作为一个极端的选择,我可以尝试迁移到R,但我无法编写C / C ++或其他语言。
答案 0 :(得分:3)
感谢@ jp2011指向pygmo
首先,值得注意的是与pygmo 1的区别,因为google上的拳头链接仍然指向较旧的版本。
第二个多处理岛仅适用于python 3.4 +
第三,有效。当我第一次提出问题时,我开始的过程仍在运行,而pygmo群岛在不到3小时的时间内对saDE中存在的所有18种可能的DE变异进行了广泛的测试。 https://esa.github.io/pagmo2/docs/python/tutorials/coding_udp_simple.html中建议的使用Numba的编译版本可能甚至会更早完成。开头语。
鉴于需要建立一个新类(相对于scipy中的signle函数)来定义问题,我个人认为它不如scipy版本直观,但可能只是个人喜好。同样,对突变/交叉参数的定义也不太清楚,因为第一次接触DE的人可能会有些晦涩。
但是,由于scipy中的串行DE不能满足要求,因此欢迎pygmo(2)。
此外,我还发现了其他一些声称可以并行化DE的选项。我自己没有对它们进行测试,但是对于在这个问题上绊脚石的人可能有用。
鸭嘴兽,专注于多目标进化算法 https://github.com/Project-Platypus/Platypus
Yabox
https://github.com/pablormier/yabox
关于DE的详细但恕我直言的清晰解释 https://pablormier.github.io/2017/09/05/a-tutorial-on-differential-evolution-with-python/
答案 1 :(得分:2)
我一直有同样的问题。也许,您可以尝试pygmo,它支持不同的优化算法(包括DE)并且具有并行计算模型。但是,我发现社区并不像scipy那么大。他们的教程,文档和示例质量很好,可以从中获得成功。
答案 2 :(得分:1)
Scipy differential_evolution
现在可以通过指定工作线程非常容易地并行使用:
工人 int或类似地图的可调用,可选
如果工人是一个int型,则将人口细分为工人 部分并进行并行评估(使用multiprocessing.Pool)。供应 -1以使用所有可用的CPU内核。或者提供类似地图的可调用项,例如multiprocessing.Pool.map来评估 人口并行。该评估是按照 工人(功能,可迭代)。此选项将覆盖更新 如果worker!=,则要更新='deferred'的关键字。1.要求func是 可腌的。
1.2.0版中的新功能。
答案 3 :(得分: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]
普通模式运行时间(s):0.015959978103637695
估计:[2.01733383e-10 1.23826873e-10]
批处理模式运行时间(s):0.006017446517944336
############################################ #############
速度提高了 1.5 倍,但仅适用于一个简单的问题。对于复杂的问题,您可以将查看速度提高 10 倍以上。 代码运行在单个 CPU 内核上(无多处理),性能提升来自使用矢量化和 MIMD(多指令,多数据)。结合矢量化和并行/多处理将带来双重改进。