Как прочитать несколько каталогов с разным количеством файлов в наборе данных tenorflow - PullRequest
0 голосов
/ 20 февраля 2020

Моя версия тензорного потока - 1.15, и мое дерево каталогов изображено ниже.

root
|
|---scene1
|     |
|     |--img1.npy
|     |--img2.npy
|     |--cam.txt
|     |--poses.txt
|
|---scene2
|     |
|     |--img1.npy
|     |--img2.npy
|     |--img3.npy
|     |--cam.txt
|     |--poses.txt

Каждая папка сцены содержит разное количество изображений (в формате npy), но ровно один cam.txt и одно из них. текст. Я пробовал это, используя numpy.genfromtxt и numpy.load для чтения файлов в каждой папке сцены в тензор, затем используя

ds = tf.data.Dataset.from_tensors, чтобы создать набор данных для каждой сцены, наконец, используя ds.concatenate для объединения этих наборов данных. Этот метод работает, но тратит много времени, когда количество папок сцены становится огромным. Есть ли лучший способ решить проблему?

1 Ответ

1 голос
/ 20 февраля 2020

Недавно я столкнулся с подобной проблемой.

При работе с очень большими наборами данных генераторы Python являются хорошим вариантом для go:

[Генераторы] написаны как обычные функции, но используют оператор yield всякий раз, когда хотят вернуть данные. Каждый раз, когда вызывается next(), генератор возобновляет работу с того места, где он остановился (он запоминает все значения данных и то, какое выражение было выполнено в последний раз).

Класс Dataset Tensorflow поддерживает их с помощью stati c from_generator метод (также доступен с TF 1.15 ):

import pathlib
import numpy as np
import tensorflow as tf

def scene_generator():
    base_dir = pathlib.Path('path/to/root/')
    scenes = tf.data.Dataset.list_files(str(base_dir / '*'))
    for s in scenes:
        scene_dir = pathlib.Path(s.numpy().decode('utf-8'))
        images = scene_dir / '*.npy'
        data = []
        for i in images:
            with np.load(i) as image:
                features = [image['x1'], image['x2']] # ...
                data.append(features)
        cam   = np.genfromtxt(scene_dir / 'cam.txt')
        poses = np.genfromtxt(scene_dir / 'poses.txt')

        yield data, [cam, poses]

types = (tf.float32, tf.float32)
shapes = (tf.TensorShape([None]), tf.TensorShape([2, None]))
train_data = tf.data.Dataset.from_generator(scene_generator,
    output_types=types,
    output_shapes=shapes)
...