我在joblib
,multiprocessing
等之间有点迷路。
根据您的经验,并行化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)
对不起,如果有任何多余的信息
您的图像似乎是简单的二维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开销,特别是编写单独的功能文件)。它还具有可选的优点,即如果可能的话,它很容易以分布式方式运行。