Python Tensorflow 读取带有标签的图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34340489/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 14:50:47  来源:igfitidea点击:

Tensorflow read images with labels

pythontensorflow

提问by MarvMind

I am building a standard image classification model with Tensorflow. For this I have input images, each assigned with a label (number in {0,1}). The Data can hence be stored in a list using the following format:

我正在用 Tensorflow 构建一个标准的图像分类模型。为此,我有输入图像,每个图像都分配有一个标签({0,1} 中的数字)。因此,可以使用以下格式将数据存储在列表中:

/path/to/image_0 label_0
/path/to/image_1 label_1
/path/to/image_2 label_2
...

I want to use TensorFlow's queuing system to read my data and feed it to my model. Ignoring the labels, one can easily achieve this by using string_input_producerand wholeFileReader. Here the code:

我想使用 TensorFlow 的排队系统来读取我的数据并将其提供给我的模型。忽略标签,可以通过使用string_input_producer和轻松实现这一点wholeFileReader。这里的代码:

def read_my_file_format(filename_queue):
  reader = tf.WholeFileReader()
  key, value = reader.read(filename_queue)
  example = tf.image.decode_png(value)
  return example

#removing label, obtaining list containing /path/to/image_x
image_list = [line[:-2] for line in image_label_list]

input_queue = tf.train.string_input_producer(image_list)                                                     
input_images = read_my_file_format(input_queue)

However, the labels are lost in that process as the image data is purposely shuffled as part of the input pipeline. What is the easiest way of pushing the labels together with the image data through the input queues?

然而,由于图像数据作为输入管道的一部分被故意打乱,因此标签在该过程中丢失了。通过输入队列将标签与图像数据一起推送的最简单方法是什么?

采纳答案by MarvMind

Using slice_input_producerprovides a solution which is much cleaner. Slice Input Producer allows us to create an Input Queue containing arbitrarily many separable values. This snippet of the question would look like this:

使用slice_input_producer提供了一个更干净的解决方案。Slice Input Producer 允许我们创建一个包含任意多个可分离值的输入队列。这个问题的片段看起来像这样:

def read_labeled_image_list(image_list_file):
    """Reads a .txt file containing pathes and labeles
    Args:
       image_list_file: a .txt file with one /path/to/image per line
       label: optionally, if set label will be pasted after each line
    Returns:
       List with all filenames in file image_list_file
    """
    f = open(image_list_file, 'r')
    filenames = []
    labels = []
    for line in f:
        filename, label = line[:-1].split(' ')
        filenames.append(filename)
        labels.append(int(label))
    return filenames, labels

def read_images_from_disk(input_queue):
    """Consumes a single filename and label as a ' '-delimited string.
    Args:
      filename_and_label_tensor: A scalar string tensor.
    Returns:
      Two tensors: the decoded image, and the string label.
    """
    label = input_queue[1]
    file_contents = tf.read_file(input_queue[0])
    example = tf.image.decode_png(file_contents, channels=3)
    return example, label

# Reads pfathes of images together with their labels
image_list, label_list = read_labeled_image_list(filename)

images = ops.convert_to_tensor(image_list, dtype=dtypes.string)
labels = ops.convert_to_tensor(label_list, dtype=dtypes.int32)

# Makes an input queue
input_queue = tf.train.slice_input_producer([images, labels],
                                            num_epochs=num_epochs,
                                            shuffle=True)

image, label = read_images_from_disk(input_queue)

# Optional Preprocessing or Data Augmentation
# tf.image implements most of the standard image augmentation
image = preprocess_image(image)
label = preprocess_label(label)

# Optional Image and Label Batching
image_batch, label_batch = tf.train.batch([image, label],
                                          batch_size=batch_size)

See also the generic_input_producerfrom the TensorVisionexamples for full input-pipeline.

另请参阅TensorVision示例中的generic_input_producer以了解完整的输入管道。

回答by mrry

There are three main steps to solving this problem:

解决这个问题主要有以下三个步骤:

  1. Populate the tf.train.string_input_producer()with a list of strings containing the original, space-delimited string containing the filename and the label.

  2. Use tf.read_file(filename)rather than tf.WholeFileReader()to read your image files. tf.read_file()is a stateless op that consumes a single filename and produces a single string containing the contents of the file. It has the advantage that it's a pure function, so it's easy to associate data with the input and the output. For example, your read_my_file_formatfunction would become:

    def read_my_file_format(filename_and_label_tensor):
      """Consumes a single filename and label as a ' '-delimited string.
    
      Args:
        filename_and_label_tensor: A scalar string tensor.
    
      Returns:
        Two tensors: the decoded image, and the string label.
      """
      filename, label = tf.decode_csv(filename_and_label_tensor, [[""], [""]], " ")
      file_contents = tf.read_file(filename)
      example = tf.image.decode_png(file_contents)
      return example, label
    
  3. Invoke the new version of read_my_file_formatby passing a single dequeued element from the input_queue:

    image, label = read_my_file_format(input_queue.dequeue())         
    
  1. tf.train.string_input_producer()使用包含原始、空格分隔的字符串的字符串列表填充 ,其中包含文件名和标签。

  2. 使用tf.read_file(filename)而不是tf.WholeFileReader()读取您的图像文件。tf.read_file()是一个无状态操作,它使用单个文件名并生成一个包含文件内容的字符串。它的优点是它是一个纯函数,因此很容易将数据与输入和输出关联起来。例如,您的read_my_file_format函数将变为:

    def read_my_file_format(filename_and_label_tensor):
      """Consumes a single filename and label as a ' '-delimited string.
    
      Args:
        filename_and_label_tensor: A scalar string tensor.
    
      Returns:
        Two tensors: the decoded image, and the string label.
      """
      filename, label = tf.decode_csv(filename_and_label_tensor, [[""], [""]], " ")
      file_contents = tf.read_file(filename)
      example = tf.image.decode_png(file_contents)
      return example, label
    
  3. read_my_file_format通过从 传递单个出队元素来调用新版本input_queue

    image, label = read_my_file_format(input_queue.dequeue())         
    

You can then use the imageand labeltensors in the remainder of your model.

然后,您可以在模型的其余部分使用imagelabel张量。

回答by Salvador Dali

In addition to the answers provided there are few other things you can do:

除了提供的答案之外,您还可以做其他一些事情:

Encode your label into the filename.If you have N different categories you can rename your files to something like: 0_file001, 5_file002, N_file003. Afterwards when you read the data from a readerkey, value = reader.read(filename_queue)your key/value are:

将您的标签编码到文件名中。如果你有N个不同的类别,你可以将文件重命名为类似:0_file001, 5_file002, N_file003。之后,当您从阅读器读取数据时,key, value = reader.read(filename_queue)您的键/值是:

The output of Read will be a filename (key) and the contents of that file (value)

Read 的输出将是文件名(键)和该文件的内容(值)

Then parse your filename, extract the label and convert it to int. This will require a little bit of preprocessing of the data.

然后解析您的文件名,提取标签并将其转换为 int。这将需要对数据进行一些预处理。

Use TFRecordswhich will allow you to store the data and labels at the same file.

使用TFRecords,它将允许您将数据和标签存储在同一文件中。