我需要下载图像,对其进行一些图像处理,然后将其打包到n
TFRecords中(例如,每个TFRecord 100张图像)。
使用python队列执行此操作,我将有d
个下载线程,p
个工作进程来处理图像,然后有w
个工作进程将使用TFRecordWriter写入图像当它们可用时。
我想用dask
尝试一下,所以我有类似的东西:
urls = bag.from_sequence(images_urls)
processed = urls.map(download_image).map(process)
by2 = processed.repartition(2).map_partitions(packing)
by3 = processed.repartition(3).map_partitions(packing)
bag.concat([by2, by3]).compute()
上述问题是map_partitions
似乎无法以流方式获取图像。在分区上调用packing
函数之前,整个分区似乎已在内存中。
上面的另一个烦人之处是,我在dask
中看不到如何精确控制dag的哪一部分安排在哪里。下载程序可以与线程调度程序一起发生,其中线程处理和打包程序部分需要在不同的进程中发生。这是可能的还是您坚持在整个图形上使用某种调度程序?
答案 0 :(得分:0)
如果您不希望bag
批量加载多个图像,则可以将包构造为每个分区只有一个项目(因为您事先知道URL的数量)。实际上,在给定任务可以执行给定任务之前,确实需要将所有输入都存储在该工作器中。
也许更简单的方法是退回到使用delayed
语法,例如
ims = [dask.delayed(download_image)(url) for url in images_urls]
processed = [dask.delayed(process)(im) for im in ims]
packs = [dask.delayed(packing)(processed[n:n+100]) for n in
range(0, len(processed), 100)]
dask.compute(packs)
实际上,您只能有一个调度程序来执行图形,但是Dask会尝试调度程序任务在加载数据的位置运行。