并行化Python循环

问题描述 投票:1回答: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)

它获取了我的图像补丁,然后通过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)

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

python performance parallel-processing processing-efficiency parallelism-amdahl
1个回答
0
投票

您的图像似乎是简单的二维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])

请参见multiprocessing documentation中的第一个基本示例。

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


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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.