Tensorflow lee imágenes con tags.

Estoy construyendo un modelo de clasificación de imagen estándar con Tensorflow. Para esto tengo imágenes de entrada, cada una asignada con una etiqueta (número en {0,1}). Por lo tanto, los datos se pueden almacenar en una lista utilizando el siguiente formato:

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

Quiero usar el sistema de colas de TensorFlow para leer mis datos y enviarlos a mi modelo. Ignorando las tags, uno puede lograrlo fácilmente usando string_input_producer y wholeFileReader . Aquí el código:

 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) 

Sin embargo, las tags se pierden en ese proceso a medida que los datos de la imagen se mezclan deliberadamente como parte de la canalización de entrada. ¿Cuál es la forma más fácil de empujar las tags junto con los datos de imagen a través de las colas de entrada?

El uso de slice_input_producer proporciona una solución que es mucho más limpia. Slice Input Producer nos permite crear una cola de entrada que contiene arbitrariamente muchos valores separables. Este fragmento de la pregunta se vería así:

 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) 

Vea también el generic_input_producer de los ejemplos de TensorVision para la canalización de entrada completa.

Hay tres pasos principales para resolver este problema:

  1. tf.train.string_input_producer() con una lista de cadenas que contienen la cadena original, delimitada por espacios, que contiene el nombre del archivo y la etiqueta.

  2. Utilice tf.read_file(filename) lugar de tf.WholeFileReader() para leer sus archivos de imagen. tf.read_file() es una tf.read_file() sin estado que consume un solo nombre de archivo y produce una sola cadena que contiene el contenido del archivo. Tiene la ventaja de que es una función pura, por lo que es fácil asociar los datos con la entrada y la salida. Por ejemplo, su función read_my_file_format se convertiría en:

     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. Invoque la nueva versión de read_my_file_format pasando un solo elemento en cola de la input_queue :

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

Luego, puede usar la image y label tensores en el rest de su modelo.

Además de las respuestas proporcionadas, hay algunas otras cosas que puede hacer:

Codifique su etiqueta en el nombre del archivo. Si tiene N categorías diferentes, puede cambiar el nombre de sus archivos a algo como: 0_file001, 5_file002, N_file003 . Luego, cuando lea los datos de una key, value = reader.read(filename_queue) lector key, value = reader.read(filename_queue) su clave / valor son:

La salida de Lectura será un nombre de archivo (clave) y el contenido de ese archivo (valor)

Luego analice su nombre de archivo, extraiga la etiqueta y conviértalo a int. Esto requerirá un poco de preprocesamiento de los datos.

Use TFRecords que le permitirá almacenar los datos y las tags en el mismo archivo.