python 中的多线程优化

multithreading optimization in python

我正在使用 lmfit 进行一些优化,但速度非常慢。我有一个大图像,我基本上是每个像素的 运行 最小二乘最小化。在我看来,它可能是多线程或其他类型优化的理想选择,因为它目前速度非常慢。

所以,我的优化代码如下:

我将 objective 函数定义为:

def objective(params, x, data):
    s0 = params['S0']
    t1 = params['T1']
    m = s0 * (1.0 - np.exp(-x / t1))
    return m - data

所以,我正在尝试最小化模型和观察之间的差异。我认为 lmfit 确保绝对值最小化,但我不确定,需要检查。

主循环如下:

我需要估计的参数初始化如下,有一些初始值:

p = Parameters()
p.add('S0', value=1.0)
p.add('T1', value=3.0)

final_data = <numpy image>
tis = np.asarray([1.0, 2.0, 3.0])

for i in range(final_data.shape[0]):
    print "Processing pixel: ", i
    minner = Minimizer(objective, params=p, fcn_args=np.asarray(tis),
                       final_data[i, :]),
                       nan_policy='propagate')
    result = minner.minimize(method='least_squares')
    s0_data[i] = result.params['S0']
    t1_data[i] = result.params['T1']

这工作正常,但速度很慢。我试图弄清楚如何在 python 中进行多线程处理,并且对有关 GIL 锁定的帖子感到非常困惑,并且 python 中的多线程处理并不真正存在。

我的问题是: 1:这可以通过 python 中的多线程轻松扩展吗? 2: 还有其他优化可以尝试吗?

正如评论所暗示的那样,这里的多线程不会很有成果。基本上,任何与 lmfit 或 scipy 匹配的结果都以单线程 Fortran 例程结束,该例程重复调用您的 python objective 函数,并使用这些结果生成下一步。尝试使用多线程意味着 python objective 函数和参数必须在线程之间进行管理——fortran 代码不适合这种情况,并且计算并不是真正的 I/O 绑定无论如何。

使用多核的多处理是更好的方法。但是尝试对单个拟合使用多处理并不像听起来那么简单,因为 objective 函数和参数必须是 pickle-able 的。对于您的简单示例,这应该可行,但随着问题使用更复杂的对象,该方法可能会中断。 dill 包可以帮助解决这个问题。

而且:对于您的问题有一个更简单的解决方案,因为它是自然并行化的。只是对每个像素进行单独的拟合,每个像素都在自己的过程中。您可以为此使用多处理,或者您甚至可以将问题分解为 N 个单独的实际进程 运行 N 个不同的脚本,每个脚本适合 1/N 的像素。