Итератор с поддержкой Tensorflow, проблемы с производительностью - PullRequest
0 голосов
/ 22 февраля 2019

Я использую TF для обучения ГАН с использованием изображений.До сих пор я строил свою модель и использовал только свой тренировочный набор (который собран из файла tfrecord) и одну эталонную партию для визуализации тензорной доски, и получал приличные постоянные характеристики на Titan V (0,38 ~ 0,40 с / партия) в течение длительного временитак как я использовал инициализируемый итератор и переключался между набором обучающих данных и образцом визуализации (после каждой эпохи обучения).

Поскольку все работало хорошо, мне приходилось добавлять набор тестов и шаг теста после каждого шага поезда.Так как я получил различное количество выборок в двух наборах данных, я решил использовать итератор с возможностью подачи для переключения между тремя наборами данных, потому что мне нужно отобразить обе потери на каждой итерации (мой global_step - это итерация, а не эпоха)и мне нужно было возобновить итерацию после переключения набора данных.

После этого мои выступления ужасно снизились и стали нестабильными.Теперь каждый шаг тренировки занимает от 0,35 до 1,95 с, но все останавливается каждые 16, 32 или 42 итерации на случайную пару секунд (30+).Проблема в том, что это происходит не по фиксированной инструкции, а часто после того же количества итераций).

Это функция, которую я использую для построения конвейера набора данных:

def load_dataset(name, batch_size=32, prefetch_buffer=1, interleave=1, n_threads=os.cpu_count())
    # parse sample is a lambda (omitted)
    parsed_dataset = dataset.map(parse_sample, num_parallel_calls=n_threads)
    # Here there's a series of filter() that I omitted
    parsed_dataset = parsed_dataset.cache()
    parsed_dataset = parsed_dataset.shuffle(shuffle_buffer, reshuffle_each_iteration=True)
    parsed_dataset = parsed_dataset.repeat()
    parsed_dataset = parsed_dataset.batch(batch_size)
    if interleave > 1:
        parsed_dataset = parsed_dataset.interleave(lambda x: tf.data.Dataset.from_tensors(x).repeat(interleave), cycle_length=n_threads, block_length=interleave, num_parallel_calls=n_threads)
    parsed_dataset = parsed_dataset.prefetch(prefetch_buffer)
    return parsed_dataset

Мне нужно чередование, чтобы обучающий набор данных возвращал 3 идентичных пакета при последующих вызовах.

Я ничего не менял в конвейере набора данных, тем не менее я пробовал много разных значений для prefetch_buffer, shuffle_buffer и n_threads.Также попытался удалить repeat() или cache() без существенной разницы.Единственное отличие, которое я получил, заключается в частоте длительного замораживания, но я не мог понять, с каким параметром это связано.

Мой цикл обучения с использованием итерируемого кода:

train_dataset = dh.load_dataset('train',prefetch_buffer=1,shuffle_buffer=32,interleave=3)
validation_dataset = dh.load_dataset('valid',prefetch_buffer=1,shuffle_buffer=32)
tensorboard_datasets = dh.load_dataset('tboard', prefetch_buffer=1, shuffle_buffer=1)

use_dataset=tf.placeholder(tf.string, shape=[])
iterator = tf.data.Iterator.from_string_handle(use_dataset, train_dataset.output_types, train_dataset.output_shapes)
next_batch = iterator.get_next()

train_iterator = train_dataset.make_initializable_iterator()
valid_iterator = validation_dataset.make_initializable_iterator()
tboard_iterator = tensorboard_datasets.make_initializable_iterator()
# Initializers for the datasets
reset_train_iter = train_iterator.initializer
reset_validation_iter = valid_iterator.initializer
reset_tboard_iter = tboard_iterator.initializer

with tf.Session() as sess:
   # Handles to switch between datasets
   use_train_dataset = sess.run(train_iterator.string_handle())
   use_valid_dataset = sess.run(valid_iterator.string_handle())
   use_tboard_dataset = sess.run(tboard_iterator.string_handle())
    while self.layers['train']['global_step'] <= self.params['max_iterations']:
        # Initialize iterators
        sess.run([reset_train_iter, reset_validation_iter, reset_tboard_iter])
        print("Training...")
        for i in range(self.params['save_every_itn']):
            # Training of C and S
            _ = sess.run(self.layers['train']['step_C'], feed_dict={use_dataset: use_train_dataset, is_training: True})
            _ = sess.run(self.layers['train']['step_S'], feed_dict={use_dataset: use_train_dataset, is_training: True})
            # Visualizing losses for each iteration
            self.visualizer.log(sess, show='train_loss', feed_dict={use_dataset: use_train_dataset, is_training: True})
            self.visualizer.log(sess, show='test_loss',  feed_dict={use_dataset: use_valid_dataset, is_training: False})
            self.layers['train']['global_step'] += 1
        print("Checkpoint...")
        self.save(sess)
        # Show a prediction made with a reference sample:
        # Show the differences by using trained and current BatchNorm weights.
        self.visualizer.log(sess, show='train', feed_dict={use_dataset: use_tboard_dataset, is_training: True})
        self.visualizer.log(sess, show='test', feed_dict={use_dataset: use_tboard_dataset, is_training: False})

где «визуализатор» - это класс, в котором я храню весь код для управления Tensorboard.Он просто запускает правильное резюме ('*_loss' - это операция, которая регистрирует только тренировки и тестовые потери, в то время как два других также печатают изображения и другие материалы).Проблема не должна возникать, потому что я пытался удалить вызовы, но проблема с итераторами остается.

Наборы данных Train и Validation на самом деле представляют собой разные фильтры, применяемые к одному и тому же файлу .tfrecords, если это имеет значение.

Я не мог понять, почему вычисления так нестабильны. За ночь было выполнено 14 000 итераций, тогда как в предыдущей версии это было около 90 000.Топ говорит, что процесс Python использует 200% -300% нашего Xeon E5-2609 и 22 из 64 ГБ оперативной памяти при обработке данных.

Есть ли кто-нибудь, кто имеет опыт работы с такого рода итераторами?

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