Как перевести устаревший подход tf.train.QueueRunners к импорту данных в новый подход tf.data.Dataset - PullRequest
0 голосов
/ 04 февраля 2019

Несмотря на то, что тензор потока очень рекомендует не использовать устаревшие функции, которые будут заменены объектами tf.data, кажется, нет хорошей документации для чистой замены устаревшей для современного подхода.Более того, учебники Tensorflow по-прежнему используют устаревшую функциональность для обработки файлов (Учебное пособие по чтению данных: https://www.tensorflow.org/api_guides/python/reading_data).

С другой стороны, хотя есть хорошая документация для использования «современного» подхода (Импорт данных)учебное пособие: https://www.tensorflow.org/guide/datasets), все еще существуют старые учебные пособия, которые, вероятно, приведут многих, как и меня, к тому, чтобы сначала использовать устаревший учебник, поэтому хотелось бы аккуратно перевести устаревший на «современный» подход ипример для этого перевода, вероятно, будет очень полезен.

#!/usr/bin/env python3
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import shutil
import os

if not os.path.exists('example'):
    shutil.rmTree('example');
    os.mkdir('example');

batch_sz = 10; epochs = 2; buffer_size = 30; samples = 0;
for i in range(50):
    _x = np.random.randint(0, 256, (10, 10, 3), np.uint8);
    plt.imsave("example/image_{}.jpg".format(i), _x)
images = tf.train.match_filenames_once('example/*.jpg')
fname_q = tf.train.string_input_producer(images,epochs, True);
reader = tf.WholeFileReader()
_, value = reader.read(fname_q)
img = tf.image.decode_image(value)
img_batch = tf.train.batch([img], batch_sz, shapes=([10, 10, 3]));
with tf.Session() as sess:
    sess.run([tf.global_variables_initializer(),
        tf.local_variables_initializer()])
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(coord=coord)
    for _ in range(epochs):
        try:
            while not coord.should_stop():
                sess.run(img_batch)
                samples += batch_sz;
                print(samples, "samples have been seen")
        except tf.errors.OutOfRangeError:
            print('Done training -- epoch limit reached')
        finally:
            coord.request_stop();
    coord.join(threads)

Этот код отлично работает для меня, вывод на консоль:

10 samples have been seen
20 samples have been seen
30 samples have been seen
40 samples have been seen
50 samples have been seen
60 samples have been seen
70 samples have been seen
80 samples have been seen
90 samples have been seen
100 samples have been seen
110 samples have been seen
120 samples have been seen
130 samples have been seen
140 samples have been seen
150 samples have been seen
160 samples have been seen
170 samples have been seen
180 samples have been seen
190 samples have been seen
200 samples have been seen
Done training -- epoch limit reached

Как видно, он использует устаревшие функции иобъекты как tf.train.string_input_producer () и tf.WholeFileReader (). Требуется эквивалентная реализация с использованием «современного» tf.data.Dataset.

РЕДАКТИРОВАТЬ:

Найден уже приведенный пример импорта данных CSV: Замена входных конвейеров на основе очереди tf.data . Я хотел бы bКак можно полнее здесь, и предположим, что больше примеров лучше, поэтому я не считаю это повторным вопросом.

1 Ответ

0 голосов
/ 04 февраля 2019

Вот перевод, который печатает точно так же для стандартного вывода.

#!/usr/bin/env python3
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import os
import shutil

if not os.path.exists('example'):
    shutil.rmTree('example');
    os.mkdir('example');

batch_sz = 10; epochs = 2; buffer_sz = 30; samples = 0;
for i in range(50):
    _x = np.random.randint(0, 256, (10, 10, 3), np.uint8);
    plt.imsave("example/image_{}.jpg".format(i), _x);
fname_data = tf.data.Dataset.list_files('example/*.jpg')\
        .shuffle(buffer_sz).repeat(epochs);
img_batch = fname_data.map(lambda fname: \
        tf.image.decode_image(tf.read_file(fname),3))\
        .batch(batch_sz).make_initializable_iterator();

with tf.Session() as sess:
    sess.run([img_batch.initializer,
        tf.global_variables_initializer(),
        tf.local_variables_initializer()]);
    next_element = img_batch.get_next();
    try:
        while True:
            sess.run(next_element);
            samples += batch_sz
            print(samples, "samples have been seen");
    except tf.errors.OutOfRangeError:
        pass;
    print('Done training -- epoch limit reached');

Основные проблемы:

  1. Использование tf.data.Dataset.list_files() для загрузки имен файлов какнабор данных вместо генерации очереди с устаревшим tf.tran.string_input_producer() для использования имен файлов.
  2. Использование итераторов для обработки наборов данных, которые также требуют инициализации, вместо последовательных чтений с устаревшим tf.WholeFileReader, с пакетами устаревших tf.train.batch() функция.
  3. Координатор не нужен, так как потоки для очередей (tf.train.QueueRunners созданные tf.train.string_input_producer()) больше не используются, но его следует проверять после завершения итератора набора данных.

Я надеюсь, что это будет полезно для многих, как и для меня после его достижения.

Ссылка:


БОНУС: Набор данных + оценщик

#!/usr/bin/env python3
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import os
import shutil

if not os.path.exists('example'):
    shutil.rmTree('example');
    os.mkdir('example');

batch_sz = 10; epochs = 2; buffer_sz = 10000; samples = 0;
for i in range(50):
    _x = np.random.randint(0, 256, (10, 10, 3), np.uint8);
    plt.imsave("example/image_{}.jpg".format(i), _x);
def model(features,labels,mode,params):
    return tf.estimator.EstimatorSpec(
            tf.estimator.ModeKeys.PREDICT,{'images': features});
estimator = tf.estimator.Estimator(model,'model_dir',params={});
def input_dataset():
    return tf.data.Dataset.list_files('example/*.jpg')\
        .shuffle(buffer_sz).repeat(epochs).map(lambda fname: \
            tf.image.decode_image(tf.read_file(fname),3))\
        .batch(batch_sz);

predictions = estimator.predict(input_dataset,
        yield_single_examples=False);
for p_dict in predictions:
    samples += batch_sz;
    print(samples, "samples have been seen");
print('Done training -- epoch limit reached');

Основные проблемы:

  1. Определение функции model для пользовательской estimator для обработкиизображения, которые в этом случае ничего не делают, потому что мы просто передаем их.
  2. Определение input_dataset функции для извлечения набора данных, который будет использоваться (для прогнозирования в этом случае) оценщиком.
  3. Использование tf.estimator.Estimator.predict() в оценщике вместо использования tf.Session() напрямую, плюс yield_single_example=False для получения пакета элементов вместо единственного в списке предсказаний словарей.

Мне кажется, чтоболее модульный и многократно используемый код.

Ссылка:

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