尽管设置了worker参数,但Scipy的differential_evolution未在多个内核中运行

8yparm6h  于 2022-11-09  发布在  其他
关注(0)|答案(1)|浏览(140)

我想在多核环境下运行scipy的differential_evolution函数,参数为workers
我已经按照documentation的说明,开发了以下脚本来检查函数在使用和不使用workers参数时的运行时间:

import time

if __name__ == '__main__':
    from scipy.optimize import differential_evolution, rosen
    bounds = [( 0, 2 ), ( 0, 2 ), ( 0, 2 ), ( 0, 2 ), ( 0, 2 )]

    print( 'Beginning optimisation without parallelisation' )
    start = time.time()
    result = differential_evolution( rosen, bounds,
                                     workers=1,
                                     popsize=200,
                                     maxiter=1000,
                                     tol=0.001,
                                     seed=1 )
    end = time.time()
    print( 'Optimisation finished after {} seconds'.format( round( end - start, 2 ) ) )

    print( '\nBeginning optimisation with workers parameter set to 10' )
    start = time.time()
    result = differential_evolution( rosen, bounds,
                                     updating='deferred',
                                     workers=10,
                                     popsize=200,
                                     maxiter=1000,
                                     tol=0.001,
                                     seed=1 )
    end = time.time()
    print( 'Optimisation finished after {} seconds'.format( round( end - start, 2 ) ) )

运行脚本后,为每个调用返回的运行时间如下:

Beginning optimisation without parallelisation
Optimisation finished after 59.0 seconds

Beginning optimisation with workers parameter set to 10
Optimisation finished after 60.43 seconds

正如您所看到的,将worker参数设置为10时的执行速度甚至比第一个慢。您能帮我完成这个吗?为了在differential_evolution函数中实现并行化,我还需要做什么吗?
我目前使用的是Python 3.8,而我的scipy版本是1.8.1。

ux6nzvsh

ux6nzvsh1#

@9769953是正确的。multiprocessing会产生额外负荷:创建进程、将计算分配给子进程等。只有当计算是CPU密集型的时,才能克服这种开销,而rosen不是。
如果scipy〉1.9,并且目标函数可以矢量化,那么矢量化可以提供速度增益。如果可以消除矢量化过程中的中间计算,那么增益会更大:

import time
import numpy as np
from scipy.optimize import differential_evolution, rosen

bounds = [( 0, 2 ), ( 0, 2 ), ( 0, 2 ), ( 0, 2 ), ( 0, 2 )]

print( 'Beginning optimisation without parallelisation' )
start = time.time()
result = differential_evolution( rosen, bounds,
                                 workers=1,
                                 popsize=200,
                                 updating='deferred',
                                 seed=1 )
end = time.time()
print( f'Optimisation finished after {end - start} seconds')

print( '\nBeginning optimisation with vectorisation' )
start = time.time()
result = differential_evolution( rosen, bounds,
                                 updating='deferred',
                                 popsize=200,
                                 seed=1,
                                 vectorized=True
                               )
end = time.time()
print( f'Optimisation finished after {end-start} seconds')

给出:

Beginning optimisation without parallelisation
Optimisation finished after 46.94838500022888 seconds

Beginning optimisation with vectorisation
Optimisation finished after 40.34918713569641 seconds

相关问题