Tensorflow异步/并发for循环

时间:2020-01-20 04:42:17

标签: tensorflow asynchronous keras

我很好奇,如果我使用相同的模型实例,是否可以在for循环中异步处理项目。

现在,我只是遍历每个项目,对其进行同步处理,然后移至下一个项目(但每个项目都需要一段时间):

import numpy as np
from PIL import Image

from models import Model1, Model2, Model3
from utils import utils

model1 = Model1()
model2 = Model2()
model3 = Model3()

def start():
    # some non-tensorflow stuff

    for image_path in image_paths:
        # extract images from original
        image1, image2, image3 = utils.process(image_path, model2, model3)

        # create a new image
        inference = model1.inference(image1, image2, image3)
        image4 = np.squeeze(((inference[0] + 1) * 255 / 2).astype(np.uint8))
        result_image = utils.post_process(image_path, model2, image4, image1, image2)

        # overwrite the existing image
        Image.fromarray(result_image).save(image_path)

    # do some other non-tensorflow stuff

if __name__ == '__main__':
    start()

任何见解都值得赞赏。谢谢!

1 个答案:

答案 0 :(得分:0)

几乎每个模型都可以更快地运行,因为您可以批量处理图像并在每次调用中打包一堆。在这种情况下,这是获得某些性能的最干净的方法。有没有理由吗?

我不确定您的tensorflow模型中包含什么,但是AFAIK现代TensorFlow默认情况下会进行异步分配,您返回的渴望张量是将来结果的句柄。当您在#do something with the result部分中提取值时,它将阻塞并等待结果。

当然,您可以执行以下操作:将装入,推断和do smething部分分别放在各自的线程(或进程)中,并在两者之间使用多线程(多处理)队列。这样,您的加载和Do something与推理并行运行。但这感觉就像我们在重新发明过时的“ tensorflow输入队列”。这些线程仍在争夺GIL,诸如此类。

因此,如果批处理不足以解决您的问题,那么更好的方法是使用tf.data运行此方法:

filenames = tf.data.Dataset.list_files(...)
results = filenames.map(load_and_infer_image, 
                       num_parallel_calls=tf.data.experimental.AUTOTUNE)
results = results.prefetch(tf.data.experimental.AUTOTUNE)
for result in result:
  # do something.

prefetch方法允许数据集在后台运行,并在python循环中进行处理时预取这些推断结果。

如果有些东西您无法表达或不想在纯张量流中表达,则可以用tf.data.Dataset.from_generatortf.py_function包裹它们