我很好奇,如果我使用相同的模型实例,是否可以在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()
任何见解都值得赞赏。谢谢!
答案 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_generator
或tf.py_function
包裹它们