1

我在 , 等之间有点迷路joblibmultiprocessing

根据您的经验,并行化 for 循环的最有效方法是什么?

例如 :

for i, p in enumerate(patches[ss_idx]):
            bar.update(i+1)
            h_features.append(calc_haralick(p)) 
def calc_haralick(roi):

    feature_vec = []

    texture_features = mt.features.haralick(roi)
    mean_ht = texture_features.mean(axis=0)

    [feature_vec.append(i) for i in mean_ht[0:9]]

    return np.array(feature_vec)

它获取 i 块图像,然后通过 haralick 提取特征

这就是我获取补丁的方式

 h_neigh = 11 # haralick neighbourhood
 size = h_neigh
 shape = (img.shape[0] - size + 1, img.shape[1] - size + 1, size, size)
 strides = 2 * img.strides
 patches = stride_tricks.as_strided(img, shape=shape, strides=strides)
 patches = patches.reshape(-1, size, size)

对不起,如果任何信息是多余的

4

1 回答 1

1

您的图像似乎是简单的二维 NumPy 数组,以及patches这些数组的列表或数组。我假设ss_idx是一个索引数组(即,不是整数),所以它patches[ss_idx]仍然是可以迭代的东西(如你的例子)。

在这种情况下,只需使用multiprocessing.Pool.map

import multiprocessing as mp

nproc = 10
with mp.Pool(nproc) as pool:
    h_features = pool.map(calc_haralick, patches[ss_idx])

请参阅多处理文档中的第一个基本示例。

如果您省略nproc或将其设置为None,则将使用所有可用的核心。


多处理的潜在问题是,它将创建nproc相同的 Python 进程,并将所有相关数据复制到这些进程。如果您的图像很大,这将导致相当大的开销。

在这种情况下,将 Python 程序拆分为单独的程序可能是值得的,其中计算单个图像的未来是一个独立的程序。该程序需要处理读取单个图像并编写功能。然后,您将所有内容包装在一个循环所有图像的bash 脚本中,注意同时只使用一定数量的核心(例如,后台进程,但wait每10 个图像)。下一步/程序需要将独立的特征文件读入一个多维数组,但是从那里,您可以继续您的旧程序。

虽然这是更多的工作,但它可以节省一些复制开销(尽管它引入了额外的 I/O 开销,特别是编写单独的功能文件)。
它还具有可选的优势,即如果可能发生,这很容易分布式运行。


尝试多处理,注意内存使用和 CPU 使用(如果长时间没有任何反应,可能是复制开销)。然后,尝试另一种方法。

于 2020-05-27T13:41:46.157 回答