lmfit.Model.fit()无法在multiprocessing.Pool中工作

时间:2018-04-18 19:58:50

标签: python python-multiprocessing lmfit

我正在使用lmfit来拟合一系列光谱。我的模型是几个谱线和一个常数项的总和。我想使用multiprocessing.Pool同时适应多个光谱。当在for循环中使用时,拟合非常有效,但在使用multiprocessing.Pool时似乎失败了。

我的模型相当复杂,所以我为此道歉,但希望这很清楚。我知道在函数中有一个函数很奇怪,但我发现这是让lmfit.Model()正确运行的唯一方法。

import numpy as np
from lmfit import Model
from lmfit.models import ConstantModel

def fit_spectrum(spectrum):
    xdata, ydata = spectrum
    def line_profile(x, amp1, amp2, a, center, wave1, wave2, sig1, sig2, N):
        gauss1 = amp1*np.exp(-(x-wave1)**2/(2*sig1**2.))
        gauss2 = amp2*np.exp(-(x-wave2)**2/(2*sig2**2.))
        core = gauss1 + gauss2

        w = center/N_eff * (1/(np.sqrt(2)*np.pi))
        t = w**2.
        b = ((x-center)**2+w**2)
        scatter = a*t/b

        return core + scatt

    mod = None
    spectral_lines = [ 391.44,  404.71,  435.92,  546.15,  557.89,  589.15,  589.75, 630.2 ]
    for i, line in enumerate(spectral_lines):
        pref = 'f%s_' % str(i).zfill(4)
        line_model = Model(line_profile, prefix=pref)
        line_model.set_param_hint(pref+'amp1', value=10, min=0)
        line_model.set_param_hint(pref+'amp2', value=10, min=0)
        line_model.set_param_hint(pref+'center', value=line, min=line-.1, max=line + .1, vary=True)
        line_model.set_param_hint(pref+'delta1', value=0.06, min=0, max=0.1, vary=True)
        line_model.set_param_hint(pref+'delta2', value=0.09, min=0, max=0.1, vary=True)
        line_model.set_param_hint(pref+'wave1', expr=pref+'center + '+pref+'delta1')
        line_model.set_param_hint(pref+'wave2', expr=pref+'center - '+pref+'delta2')

        line_model.set_param_hint(pref+'a', value=10, min=0)
        line_model.set_param_hint(pref+'sig1', value=0.1, min=0, max=1)
        line_model.set_param_hint(pref+'sig2', value=0.1, min=0, max=1)
        line_model.set_param_hint(pref+'N', value=83200, min=0)

        if mod is None:
            mod = line_model
        else:
            mod = mod + line_model

    offset = ConstantModel()
    offset.set_param_hint('c', value=1)

    model = mod + offset
    params = model.make_params()

    results = model.fit(ydata, params, x=xdata)
    return results

现在,我列出了许多我希望通过多处理适合的光谱。如果我在for循环中运行fit_spectrum()函数,则拟合成功。下面是一个有效的代码示例,其中spectrum是波长和数据的numpy数组的列表,spectrum = [np.array(波长),np.array(数据)],list_of_spectra是这些的列表:

FitResults = []
for spectrum in list_of_spectra:
    result = fit_spectrum(spectrum)
    FitResults.append(result)

当我尝试在多处理中实现它时,代码只是停留在Model.fit()。没有错误消息也没有代码崩溃。它只是移动到下一个光谱而不会缩小拟合结果。没有返回任何内容,当程序到达list_of_spectra的末尾时,代码挂起。

import multiprocessing

pool = multiprocessing.Pool(processes=4)
FitResults = pool.map(fit_spectrum, list_of_spectra)
pool.terminate()

我想也许这与需要多处理来解决问题有关,但我不知道如何解决这个问题。我还发现这个问题实现了lmfit.minimize()函数而不是Model.fit(),并对上面的代码进行了一些更改。

0 个答案:

没有答案