Python-多重处理后将切片分配给稀疏矩阵

时间:2018-06-22 17:56:10

标签: python multiprocessing slice post-processing

我目前正在研究一种用于图像去噪的非局部方法,并被要求构建一个内核,我们将其称为w,该内核由图像的每个像素索引。对于上下文,如果图像具有NxM个像素,则内核(存储为矩阵)将具有(NxM)^4个元素。幸运的是,矩阵是稀疏的,对称的,并且其对角线是已知的。所以我设计了一个函数win_largo(i,l),其中iw第i行的索引,而l是我要计算的元素数,返回CSR稀疏行及其转置。

我有一个236^2像素的图像,因此在我的情况下l=1500有足够的信息,我可以高效地计算前1500行和列。但是,还剩下54 196行。为了计算它们,我使用了如下的多处理模块:

import multiprocessing as mp
nm = N*M

pool    = mp.Pool(processes=15)
results = [pool.apply_async(win_largo, args=(i,1500,) ) for i in xrange(1500, nm) ]
pool.close()
pool.join()

我得到了一个非常快速的计算(几分钟),取而代之的是大约需要6.45个小时来进行计算。但是,现在我需要保存此结果。

为此,我编写了以下循环,其中w再次存储为CSR矩阵:

j = 0
for i in xrange(1500,nm):
    w[i,i-l:i], w[i-l:i, i] = results[j].get()
    j += 1

但是大约需要6.52小时才能完成。有更快的方法吗?如今看来,多处理循环已无用。

我正在将python 2.7与macOS High Sierra一起使用。

1 个答案:

答案 0 :(得分:0)

我找到了方法。

首先,切片不是方法。通过测试以下内容:

%%timeit -n 2
ws  = sparse.csr_matrix((nm, nm), dtype=np.float)
for i in xrange(5925,6000):                        # 75 iterations
    ws[i,i-l:i], ws[i-l:i, i] = win_largo(i,l)

我知道了

2 loops, best of 3: 2.02 s per loop

win_largo的计算需要花费几秒钟的时间。

由于切片不是分配计算对象的最佳方法,因此我决定利用win_largo返回的稀疏切片的元素。因此,我修改了该函数,使其返回非零的索引集及其对应的数据集:

%%timeit -n 5
row_ind, col_ind, datos = [], [], []

for i in xrange(5500,6000):                        # 500 iterations
    indx_w, datos_w = win_largo(i,l)
    row_ind.extend( np.repeat(i, len(indx_w)).tolist() )
    col_ind.extend( np.add(i-l, indx_w).tolist() )
    datos.extend( datos_w.tolist() )

我得到的,让我无语:

5 loops, best of 3: 2.02 s per loop

因此,整个循环耗时3分32秒完成。不到6小时的时间…大约是原始时间的0.92%。就是这样。

此后,我能够向每个列表中添加一些额外的数据,这样生成的稀疏对象将是:

ws = sparse.csr_matrix((datos, (row_ind, col_ind)), [nm, nm])

这只花了几秒钟。总共,我能够在4分钟内获得此矩阵:D