在张量流中加载图像文件夹

时间:2017-06-07 15:21:21

标签: tensorflow neural-network directory loadimage

我是tensorflow的新手,但我已经关注并执行了他们推广的教程以及网络上的许多其他内容。 我在MNIST图像上做了一个小卷积神经网络。没什么特别的,但我想测试我自己的图像。 现在我的问题来了:我创建了几个文件夹;每个文件夹的名称是里面图像所属的类(标签)。

图像有不同的形状;我的意思是他们没有固定的尺寸。

如何加载它们以便与Tensorflow一起使用?

我在StackOverflow和其他Q / A网站上都遵循了许多教程和答案。但是,我还是没弄明白怎么做。

3 个答案:

答案 0 :(得分:2)

示例输入管道脚本,用于从目录加载图像和标签。在此之后,您可以进行预处理(调整图像大小等)。

import ast
print ( 10 + int(ast.literal_eval(  animal)))

档案目录

import tensorflow as tf
filename_queue = tf.train.string_input_producer(
tf.train.match_filenames_once("/home/xxx/Desktop/stackoverflow/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

答案 1 :(得分:1)

tf.data API(从Tensorflow 1.4开始)非常适合此类情况。管道如下所示:

  • 创建迭代所有示例的初始tf.data.Dataset对象
  • (如果接受培训)shuffle / repeat数据集;
  • map通过某种功能使所有图像具有相同大小;
  • batch;
  • (可选)prefetch,告诉您的程序在网络处理当前批次时收集预处理的后续批次数据;和
  • 并获取输入。

有多种创建初始数据集的方法(有关更深入的答案,请参见here

带有Tensorflow数据集的TFRecords

Tensorflow datasets支持tensorflow版本1.12及更高版本,提供了一个相对简单的API,用于创建tfrecord数据集,并且还可以自动处理数据下载,分片,统计信息生成和其他功能。

例如参见this image classification dataset implementation。那里有很多bookeeper内容(下载url,引文等),但是技术部分归结为指定features并编写_generate_examples函数

features = tfds.features.FeaturesDict({
            "image": tfds.features.Image(shape=(_TILES_SIZE,) * 2 + (3,)),
            "label": tfds.features.ClassLabel(
                names=_CLASS_NAMES),
            "filename": tfds.features.Text(),
        })

...

def _generate_examples(self, root_dir):
  root_dir = os.path.join(root_dir, _TILES_SUBDIR)
  for i, class_name in enumerate(_CLASS_NAMES):
    class_dir = os.path.join(root_dir, _class_subdir(i, class_name))
    fns = tf.io.gfile.listdir(class_dir)

    for fn in sorted(fns):
      image = _load_tif(os.path.join(class_dir, fn))
      yield {
          "image": image,
          "label": class_name,
          "filename": fn,
      }

您还可以使用较低级别的操作来生成tfrecords

通过tf.data.Dataset.maptf.py_func(tion)加载图像

或者,您可以按照以下方式从tf.data.Dataset.map内部的文件名中加载图像文件。

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

更多一般信息here和性能说明here

答案 2 :(得分:0)

要加载相同大小的图像,只需使用:

tf.keras.preprocessing.image_dataset_from_directory(dir)

文档:https://www.tensorflow.org/api_docs/python/tf/keras/preprocessing/image_dataset_from_directory