Tensorflow使用标签读取图像

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

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

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

 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) 

但是,由于图像数据被有意地作为inputstream水线的一部分进行混洗,标签在该过程中丢失。 通过input队列将图像数据与标签一起推送的最简单方法是什么?

使用slice_input_producer提供了一个更清洁的解决scheme。 切片input生产者允许我们创build一个包含任意多个可分离值的input队列。 这个问题的片段将如下所示:

 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) 

另请参阅TensorVision示例中的generic_input_producer完整inputpipe道。

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

  1. 用包含原始空格分隔的string的string列表填充tf.train.string_input_producer() ,string包含文件名和标签。

  2. 使用tf.read_file(filename)而不是tf.WholeFileReader()来读取您的图像文件。 tf.read_file()是一个无状态的操作,它使用一个文件名并生成一个包含文件内容的单个string。 它的优点是它是一个纯函数,所以很容易将数据与input和输出关联起来。 例如,你的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()) 

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

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

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

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

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

使用TFRecords可以将数据和标签存储在同一个文件中。