Керас подходит генератор медленный

Keras fit_generator очень медленный. Графический процессор не используется постоянно в обучении, иногда его использование падает до 0%. Даже на 4 рабочих и multiproceesing=True.

Кроме того, процессы сценария запрашивают слишком много виртуальной памяти и имеют статус D, непрерывный сон (обычно IO).

Я уже пробовал разные комбинации max_queue_size, но ничего не вышло.

Скриншот Использование графического процессора

Скриншот процессов виртуальной памяти и состояния

Информация об оборудовании GPU = Titan XP 12 ГБ

Код класса генератора данных

import numpy as np
import keras
import conf


class DataGenerator(keras.utils.Sequence):
    'Generates data for Keras'
    def __init__(self, list_IDs, labels, batch_size=32, dim=(conf.max_file, 128),
                 n_classes=10, shuffle=True):
        'Initialization'
        self.dim = dim
        self.batch_size = batch_size
        self.labels = labels
        self.list_IDs = list_IDs
        self.n_classes = n_classes
        self.shuffle = shuffle
        self.on_epoch_end()

    def __len__(self):
        'Denotes the number of batches per epoch'
        return int(np.floor(len(self.list_IDs) / self.batch_size))

    def __getitem__(self, index):
        'Generate one batch of data'
        # Generate indexes of the batch
        indexes = self.indexes[index*self.batch_size:(index+1)*self.batch_size]

        # Find list of IDs
        list_IDs_temp = [self.list_IDs[k] for k in indexes]

        # Generate data
        X, y = self.__data_generation(list_IDs_temp)

        return X, y

    def on_epoch_end(self):
        'Updates indexes after each epoch'
        self.indexes = np.arange(len(self.list_IDs))
        if self.shuffle == True:
            np.random.shuffle(self.indexes)

    def __data_generation(self, list_IDs_temp):
        'Generates data containing batch_size samples' # X : (n_samples, *dim, n_channels)
        # Initialization
        X = np.empty((self.batch_size, *self.dim))
        y = np.empty((self.batch_size, conf.max_file, self.n_classes))
        # Generate data
        for i, ID in enumerate(list_IDs_temp):
            # Store sample
            X[i, ] = np.load(conf.dir_out_data+"data_by_file/" + ID)

            # Store class
            y[i, ] = np.load(conf.dir_out_data +
                            'data_by_file/' + self.labels[ID])

        return X, y

Код скрипта Python

training_generator = DataGenerator(partition['train'], labels, **params)

validation_generator = DataGenerator(partition['validation'], labels, **params)

model.fit_generator(generator = training_generator,
                    validation_data = validation_generator,
                    epochs=steps,
                    callbacks=[tensorboard, checkpoint],
                    workers=4,
                    use_multiprocessing=True,
                    max_queue_size=50)

Сказать «очень медленно» - это субъективно, сколько времени занимает эпоха? Вы считали, что графический процессор - это не узкое место, а чтение файлов из файловой системы?

Dr. Snoopy 31.10.2018 18:29

Это может быть из-за времени чтения файловой системы. Это «очень медленно» по сравнению с использованием только fit. Графический процессор используется не полностью, поэтому я думаю, что проблема, скорее всего, не в нем.

Renan Cunha 31.10.2018 19:05

fit и fit_generator не делают одно и то же, так что это нечестное сравнение. Вы должны найти способ уменьшить количество операций ввода-вывода для решения вашей проблемы, например, наличие большого количества небольших файлов для чтения всегда будет проблемой.

Dr. Snoopy 31.10.2018 19:08

Так как же минимизировать эту проблему для fit_generator? Я не могу использовать fit из-за большого количества данных.

Renan Cunha 31.10.2018 19:23

Оптимизируйте функцию генератора, чтобы она работала быстро и использовала минимальное количество операций ввода-вывода.

Dr. Snoopy 31.10.2018 19:24

@RenanCunha +1 У меня такая же проблема ... ты нашел какое-нибудь решение?

AaronDT 11.12.2018 16:50

Что мне немного помогло, так это загрузка всех значений классов сразу и использование генератора только для входных данных. Но даже это не привело к хорошей производительности, возможно, потому, что я использую жесткий диск вместо SSD. Поэтому я преобразовал свои данные в float16, чтобы они соответствовали оперативной памяти ПК.

Renan Cunha 11.12.2018 19:05

В этом помогло medium.com/@moritzkrger/…keras.io/examples/mnist_tfrecord

Renan Cunha 16.03.2019 22:33

Использование fit_generator() без многопроцессорной обработки намного быстрее

DollarAkshay 11.08.2019 15:51
5
9
4 592
1

Ответы 1

Если вы используете Tensorflow 2.0, вы можете столкнуться с этой ошибкой: https://github.com/tensorflow/tensorflow/issues/33024

Возможные решения:

  • Позвоните в tf.compat.v1.disable_eager_execution() в начале кода
  • Используйте model.fit, а не model.fit_generator. Первый в любом случае поддерживает генераторы.
  • Переход на TF 1.14

Независимо от версии Tensorflow действуют следующие принципы:

  • Ограничьте доступ к диску, который вы делаете, это часто является узким местом.
  • Проверяйте размер партии как при обучении, так и при проверке. Размер партии 1 при проверке будет очень медленным.

Кажется, есть проблема с медленными генераторами в 1.13.2 и 2.0.1 (по крайней мере). https://github.com/keras-team/keras/issues/12683

попробуйте использовать больший размер партии

Gerry P 17.04.2020 07:37

Другие вопросы по теме