Загрузка папок с изображениями в тензор потока

Я новичок в tenorflow, но я уже следовал и выполнил учебники, которые они продвигают, и многие другие по всей сети. Я сделал небольшую сверточную нейронную сеть поверх изображений MNIST. Ничего особенного, но я хотел бы проверить свои собственные изображения. Теперь у меня проблема: я создал несколько папок; имя каждой папки - это класс (метка), к которой принадлежат изображения.

Изображения имеют разные формы; я имею в виду, что они не имеют фиксированного размера.

Как я могу загрузить их для использования с Tensorflow?

Я следовал многим учебникам и ответам как здесь, на Stackru, так и на других сайтах Q/A. Но все же я так и не понял, как это сделать.

4 ответа

tf.data API (в версии tenorflow 1.4 и выше) отлично подходит для подобных вещей. Конвейер будет выглядеть примерно так:

  • Создать начальный tf.data.Dataset объект, который перебирает все примеры
  • (если обучение) shuffle / repeat набор данных;
  • map это через некоторую функцию, которая делает все изображения одинакового размера;
  • batch;
  • (Optionall) prefetch попросить вашу программу собрать предварительную обработку последующих пакетов данных, пока сеть обрабатывает текущий пакет; а также
  • и получить входные данные.

Существует несколько способов создания исходного набора данных (более подробный ответ см. Здесь), но я бы предложил преобразовать ваши изображения в tfrecords формат или загрузка для каждого примера на основе строковых имен файлов (приведенных ниже).

image_paths, labels = load_base_data(...)
epoch_size = len(image_paths)
image_paths = tf.convert_to_tensor(image_paths, dtype=tf.string)
labels = tf.convert_to_tensor(labels)

dataset = tf.data.Dataset.from_tensor_slices((image_paths, labels))

if mode == 'train':
    dataset = dataset.repeat().shuffle(epoch_size)


def map_fn(path, label):
    # path/label represent values for a single example
    image = tf.image.decode_jpeg(tf.read_file(path))

    # some mapping to constant size - be careful with distorting aspec ratios
    image = tf.image.resize_images(out_shape)
    # color normalization - just an example
    image = tf.to_float(image) * (2. / 255) - 1
    return image, label


# num_parallel_calls > 1 induces intra-batch shuffling
dataset = dataset.map(map_fn, num_parallel_calls=8)
dataset = dataset.batch(batch_size)
# try one of the following
dataset = dataset.prefetch(1)
# dataset = dataset.apply(
#            tf.contrib.data.prefetch_to_device('/gpu:0'))

images, labels = dataset.make_one_shot_iterator().get_next()

Я никогда не работал в распределенной среде, но я никогда не замечал снижения производительности при использовании этого подхода tfrecords, Если вам нужно больше пользовательских функций загрузки, также проверьте tf.py_func,

Более общая информация здесь и заметки о производительности здесь

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

import tensorflow as tf
filename_queue = tf.train.string_input_producer(
tf.train.match_filenames_once("/home/xxx/Desktop/stackru/images/*/*.png"))

image_reader = tf.WholeFileReader()
key, image_file = image_reader.read(filename_queue)
S = tf.string_split([key],'/')
length = tf.cast(S.dense_shape[1],tf.int32)
# adjust constant value corresponding to your paths if you face issues. It should work for above format.
label = S.values[length-tf.constant(2,dtype=tf.int32)]
label = tf.string_to_number(label,out_type=tf.int32)
image = tf.image.decode_png(image_file)

# Start a new session to show example output.
with tf.Session() as sess:
    # Required to get the filename matching to run.
    tf.initialize_all_variables().run()

    # Coordinate the loading of image files.
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(coord=coord)

    for i in xrange(6):
        # Get an image tensor and print its value.
        key_val,label_val,image_tensor = sess.run([key,label,image])
        print(image_tensor.shape)
        print(key_val)
        print(label_val)


    # Finish off the filename queue coordinator.
    coord.request_stop()
    coord.join(threads)

Каталог файлов

./images/1/1.png
./images/1/2.png
./images/3/1.png
./images/3/2.png
./images/2/1.png
./images/2/2.png

Выход:

 (881, 2079, 3)
 /home/xxxx/Desktop/stackru/images/3/1.png
 3
 (155, 2552, 3)
 /home/xxxx/Desktop/stackru/images/2/1.png
 2
 (562, 1978, 3)
 /home/xxxx/Desktop/stackru/images/3/2.png
 3
 (291, 2558, 3)
 /home/xxxx/Desktop/stackru/images/1/1.png
 1
 (157, 2554, 3)
 /home/xxxx/Desktop/stackru/images/1/2.png
 1
 (866, 936, 3)
 /home/xxxx/Desktop/stackru/images/2/2.png
 2

Для загрузки изображений одинакового размера просто используйте это:

      tf.keras.preprocessing.image_dataset_from_directory(dir)

документы: https://www.tensorflow.org/api_docs/python/tf/keras/preprocessing/image_dataset_from_directory

Для загрузки изображений разной формы tf предоставляет реализацию конвейера (ImageGenerator):

      from tensorflow.keras.preprocessing.image import ImageDataGenerator

TARGET_SHAPE = (500,500)
BATCH_SIZE = 32
train_dir = "train_images_directory" #ex: images/train/
test_dir = "train_images_directory" #ex: images/test/

train_images_generator = ImageDataGenerator(rescale=1.0/255,)
train_data_gen = 
               image_train_gen.flow_from_directory(batch_size=BATCH_SIZE,
                                           directory=train_dir,
                                           target_size=TARGET_SHAPE,
                                           shuffle=True,
                                           class_mode='sparse')

# do the same for validation and test dataset
# 1- image_generator 2- load images from directory with target shape
Другие вопросы по тегам