这是我对以下问题的解决方案的后续问题:
如果函数How to apply a function in parallel to multiple images in a numpy array?
process_image()
必须返回结果,那么My suggested solution可以正常工作,然后我们可以将其缓存到某个列表中以供以后处理。
由于我想对超过100K的图像(数组形状(100000, 32, 32, 3)
)进行这种类型的预处理,我希望我的解决方案非常有效。但是,我基于列表的方法会占用大量内存,因此效率也很低(进一步处理)。因此,我希望在使用joblib
多次调用此函数时,在process_image()
函数内更新数组就地。
但是,我在更新原始批量映像数组就地时遇到问题。我尝试了suggestion by Eric
,但无法更新原始数组就地。我通过在process_image
函数内打印数组的 flags 来验证数组内存是否确实在工作进程之间共享。这是我的代码:
import numpy as np
from skimage import exposure
from joblib import Parallel, delayed
# number of processes
nprocs = 10
# batched image array
img_arr = np.random.randint(0, 255, (1000, 32, 32, 3)).astype(np.float32)
# for verification
img_arr_copy = img_arr.copy()
# function to be applied on all images (in parallel)
# note: this function fails to update the original array in-place
# but, I want in-place updation of original array with the result of `equalize_hist`
def process_image(img, idx):
"""
update original array in-place since all worker processes share
original memory! i.e. they don't make copy while processing it.
"""
print("\n processing image: ", idx)
img[...] = exposure.equalize_hist(img)
print("array metadata: \n", img.flags)
print("======================= \n")
# run `process_image()` in parallel
Parallel(n_jobs=nprocs)(delayed(process_image)(img_arr[idx], idx) for idx in range(img_arr.shape[0]))
我甚至尝试使用与原始批处理图像阵列相同形状的np.empty()
初始化一个空数组,并尝试更新它但是也失败了。我不知道哪里出错了。
为了检查更新是否发生在数组中,我使用了:
np.all(result_arr == img_arr)
其中result_arr
初始化为:
result_arr = np.empty(img_arr.shape, dtype=np.float32)
我哪里出错了,我的代码中的错误是什么?所有建议都非常感谢!!
从上面的代码打印统计数据以检查内存是否共享:
processing image: 914
array metadata:
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : False #<=========== so memory is shared
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
=======================
processing image: 614
array metadata:
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : False #<=========== so memory is shared
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
=======================