В наборе данных TensorFlow не записан файл кеша

Я пытаюсь управлять большим набором данных изображений, который не помещается в памяти, но требует определенных вычислений. В настоящее время мой код выглядит так:

  files  = [str(f) for f in self.files]
  labels = self.categories
  batch_size= 32


  dataset = tf.data.Dataset.from_generator(
        lambda: zip(files, labels),
        output_types=(tf.string, tf.uint8),
        output_shapes=(tf.TensorShape([]), tf.TensorShape([]))
  )

  dataset = dataset.map(
        lambda x, y: tf.py_function(_parser, [x, y, category_count], [tf.float32, tf.uint8]),
        num_parallel_calls=tf.data.experimental.AUTOTUNE,
        deterministic=False)

  dataset.cache(filename='/tmp/dataset.tmp')

  if mode == tf.estimator.ModeKeys.TRAIN:
        dataset = dataset.shuffle(buffer_size=10*batch_size, reshuffle_each_iteration=True)

  dataset = dataset.batch(batch_size=batch_size, drop_remainder=False)

  if mode == tf.estimator.ModeKeys.TRAIN:
        dataset.repeat(None)
  else:
        dataset.repeat(1)

  dataset = dataset.prefetch(tf.data.experimental.AUTOTUNE)

Функция _parser() открывает файл изображения, выполняет кучу преобразований и возвращает тензор и вектор с горячим кодированием. Однако шаг кеширования не работает должным образом:

  • Значительного улучшения времени вычислений между 1-й эпохой и последующими не наблюдается.
  • Во время процесса не создается файл кеша, хотя раздел подкачки почти заполнен (~ 90%)

Создает ли функция cache() файл только тогда, когда и память, и раздел подкачки заполнены? Более того, я ожидаю, что буду читать только batch_size файла за раз. Однако кажется, что все файлы читаются сразу на этапе сопоставления. Стоит ли вместо этого использовать interleave() в сочетании с from_generator()? Или, может быть, мне сначала нужно сгруппировать файлы, а затем сопоставить их?


person beardybear    schedule 17.07.2020    source источник


Ответы (1)


Обратите внимание, что cache () следует использовать, когда набор данных небольшой. Если набор данных большой (что в вашем случае), ОЗУ будет недостаточно для кэширования его содержимого, поэтому он не помещается в память. Либо вам следует увеличить объем оперативной памяти, либо адаптировать какой-либо другой метод для ускорения обучения.

Другой причиной замедления обучения является этап предварительной обработки, когда вы используете функцию map().
Метод map() применяет преобразование к каждому элементу, в отличие от метода apply(), применяющего преобразование ко всему набору данных.

Вы можете использовать interleave() и сохранить тот же порядок map(), а затем batch().
Вы уже используете многопоточность, сделав num_parallel_calls и установив для него tf.data.experimental.AUTOTUNE наилучшим образом использовать все, что доступно.

Вы также можете нормализовать свои входные данные, а затем cache, если они снова не помещаются в память, тогда лучше не cache на большом наборе данных.

Вы можете следовать этим советам по производительности от TensorFlow.

Если у вас несколько рабочих / устройств, это поможет вам ускорить обучение.

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

введите описание изображения здесь

person Tfer3    schedule 09.10.2020