并行化 Python 循环



我在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)

抱歉,如果任何信息是多余的

您的图像似乎是简单的二维 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 使用情况(如果长时间没有任何反应,则可能是复制开销(。然后,尝试另一种方法。

最新更新