如果我使用的是同一个模型实例,我很好奇是否有办法在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()
任何洞察力都是非常值得欣赏的。谢谢!
发布于 2020-01-21 04:19:58
几乎每个模型都会运行得更快,如果你批量处理你的图像,并在每次调用中打包一堆。在这种情况下,这是获得一些性能的最干净的方法。有什么理由不这么做吗?
我不确定tensorflow模型中包含了什么,但AFAIK现代TensorFlow默认情况下会执行异步调度,您得到的eager tensors是未来结果的句柄。当您在#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
方法允许dataset在后台运行,在您在python循环中执行操作时预取这些推理结果。
如果有一些东西你不能或者不想用纯tensorflow来表达,你可以用tf.data.Dataset.from_generator
或者tf.py_function
来包装它们
https://stackoverflow.com/questions/59817084
复制相似问题