Tensorflow asyn c / одновременный для цикла - PullRequest
0 голосов
/ 20 января 2020

Мне любопытно, есть ли способ асинхронной обработки элементов в течение l oop, если я использую тот же экземпляр модели.

Сейчас я просто перебираю каждый элемент, обрабатываю его синхронно и перехожу к следующему (но каждый занимает некоторое время):

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 голосов
/ 20 января 2020

Почти каждая модель будет работать быстрее, если вы упаковываете свои изображения и упаковываете кучу в каждый вызов. Это самый чистый способ добиться некоторой производительности в этом случае. По какой-либо причине?

Я не уверен, что в вашей модели тензорного потока, но AFAIK современный TensorFlow выполняет асинхронную диспетчеризацию по умолчанию, возвращаемые нетерпеливые тензоры являются ручками для будущих результатов. Он блокирует и ждет результата, когда вы извлекаете значение в части #do something with the result.

Конечно, вы можете сделать что-то вроде: поместить загрузочную, выводящую и do smething части каждая в свой собственный поток (или процесс) с многопоточными (многопроцессорными) очередями между ними. Таким образом, ваша загрузка и Do something выполняются параллельно с логическим выводом. Но кажется, что мы заново изобретаем устаревшие «входные очереди тензорного потока». Эти потоки все еще сражаются за 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 l oop.

Если есть вещи, которые вы не можете или не можете использовать Вы не можете выразить в чисто тензорном потоке, вы можете обернуть их tf.data.Dataset.from_generator или tf.py_function

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...