¿Cómo convierto un directorio de imágenes jpeg a un archivo TFRecords en tensorflow?


Tengo datos de entrenamiento que son un directorio de imágenes jpeg y un archivo de texto correspondiente que contiene el nombre del archivo y la etiqueta de categoría asociada. Estoy tratando de convertir estos datos de entrenamiento en un archivo tfrecords como se describe en la documentación de tensorflow. He pasado bastante tiempo tratando de que esto funcione, pero no hay ejemplos en tensorflow que demuestren cómo usar cualquiera de los lectores para leer en archivos jpeg y agregarlos a un tfrecord usando tfrecordwriter

 42
Author: Nadav Ben-Haim, 2015-11-22

4 answers

Espero que esto ayude:

filename_queue = tf.train.string_input_producer(['/Users/HANEL/Desktop/tf.png']) #  list of files to read

reader = tf.WholeFileReader()
key, value = reader.read(filename_queue)

my_img = tf.image.decode_png(value) # use decode_png or decode_jpeg decoder based on your files.

init_op = tf.initialize_all_variables()
with tf.Session() as sess:
  sess.run(init_op)

# Start populating the filename queue.

coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)

for i in range(1): #length of your filename list
  image = my_img.eval() #here is your image Tensor :) 

print(image.shape)
Image.show(Image.fromarray(np.asarray(image)))

coord.request_stop()
coord.join(threads)

Para obtener todas las imágenes como una matriz de tensores use el siguiente ejemplo de código.

Repositorio de Github de ImageFlow


Actualización:

En la respuesta anterior acabo de decir cómo leer una imagen en formato TF, pero no guardarla en TFRecords. Para eso debes usar:

def _int64_feature(value):
  return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))


def _bytes_feature(value):
  return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))

# images and labels array as input
def convert_to(images, labels, name):
  num_examples = labels.shape[0]
  if images.shape[0] != num_examples:
    raise ValueError("Images size %d does not match label size %d." %
                     (images.shape[0], num_examples))
  rows = images.shape[1]
  cols = images.shape[2]
  depth = images.shape[3]

  filename = os.path.join(FLAGS.directory, name + '.tfrecords')
  print('Writing', filename)
  writer = tf.python_io.TFRecordWriter(filename)
  for index in range(num_examples):
    image_raw = images[index].tostring()
    example = tf.train.Example(features=tf.train.Features(feature={
        'height': _int64_feature(rows),
        'width': _int64_feature(cols),
        'depth': _int64_feature(depth),
        'label': _int64_feature(int(labels[index])),
        'image_raw': _bytes_feature(image_raw)}))
    writer.write(example.SerializeToString())

Más información aquí

Y lees los datos así:

# Remember to generate a file name queue of you 'train.TFRecord' file path
def read_and_decode(filename_queue):
  reader = tf.TFRecordReader()
  _, serialized_example = reader.read(filename_queue)
  features = tf.parse_single_example(
    serialized_example,
    dense_keys=['image_raw', 'label'],
    # Defaults are not specified since both keys are required.
    dense_types=[tf.string, tf.int64])

  # Convert from a scalar string tensor (whose single string has
  image = tf.decode_raw(features['image_raw'], tf.uint8)

  image = tf.reshape(image, [my_cifar.n_input])
  image.set_shape([my_cifar.n_input])

  # OPTIONAL: Could reshape into a 28x28 image and apply distortions
  # here.  Since we are not applying any distortions in this
  # example, and the next step expects the image to be flattened
  # into a vector, we don't bother.

  # Convert from [0, 255] -> [-0.5, 0.5] floats.
  image = tf.cast(image, tf.float32)
  image = tf.cast(image, tf.float32) * (1. / 255) - 0.5

  # Convert label from a scalar uint8 tensor to an int32 scalar.
  label = tf.cast(features['label'], tf.int32)

  return image, label
 33
Author: Hamed MP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-04 16:37:00

El modelo de inicio de Tensorflow tiene un archivo build_image_data.py eso puede lograr lo mismo con la suposición de que cada subdirectorio representa una etiqueta.

 17
Author: ksindi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-17 22:30:01

Yo también tengo el mismo problema.

Así que aquí es cómo obtengo los archivos tfrecords de mis propios archivos jpeg

Edit: add sol 1-a better & faster way

(Recomendado) Solución 1:

De github oficial de tensorflow: Cómo construir un Nuevo Conjunto de datos para el Reciclaje, utilice el script oficial de python build_image_data.py directamente y bazel es una idea mejor.

Aquí está la instrucción:

Para ejecutar build_image_data.py, puede ejecutar la siguiente línea de comandos:

# location to where to save the TFRecord data.        
OUTPUT_DIRECTORY=$HOME/my-custom-data/

# build the preprocessing script.
bazel build inception/build_image_data

# convert the data.
bazel-bin/inception/build_image_data \
  --train_directory="${TRAIN_DIR}" \
  --validation_directory="${VALIDATION_DIR}" \
  --output_directory="${OUTPUT_DIRECTORY}" \
  --labels_file="${LABELS_FILE}" \
  --train_shards=128 \
  --validation_shards=24 \
  --num_threads=8

Donde el $OUTPUT_DIRECTORY es la ubicación de la TFRecords. El $LABELS_FILE será un archivo de texto que es leído por el script que proporciona una lista de todas las etiquetas.

Entonces, debería hacer el truco.

Ps. bazel, que está hecho por Google, convierte el código en makefile.

Solución 2:

Primero, hago referencia a la instrucción de @ capitalistpug y comprobar el archivo de script de shell

(shell archivo de script proporcionado por Google: download_and_preprocess_flowers.sh )

En segundo lugar, también me entero de un mini inception - v3 tutorial de formación por NVIDIA

(NVIDIA official ACELERA EL ENTRENAMIENTO CON TENSORFLOW ACELERADO POR GPU )

Tenga cuidado, los siguientes pasos deben ejecutarse en el entorno de Bazel WORKSAPCE

Para que el archivo de compilación de Bazel pueda ejecutarse correctamente


First step, I comment out la parte de descargar el conjunto de datos imagenet que ya he descargado

Y el resto de la parte que no necesito de download_and_preprocess_flowers.sh

Segundo paso , cambiar el directorio a tensorflow/models / inception

Donde está el entorno Bazel y está construido por Bazel antes de

$ cd tensorflow/models/inception 

Opcional: Si no está construido antes, escriba el siguiente código en cmd

$ bazel build inception/download_and_preprocess_flowers 

Necesitas averiguar el contenido en lo siguiente imagen

introduzca la descripción de la imagen aquí

Y el último paso, escriba el siguiente código:

$ bazel-bin/inception/download_and_preprocess_flowers $Your/own/image/data/path

Entonces, comenzará a llamar a build_image_data.py y creando el archivo tfrecords

 3
Author: Wei Yuang Hsu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-21 08:47:30

Tenga en cuenta que las imágenes se guardarán en TFRecord como tensores sin comprimir, posiblemente aumentando el tamaño por un factor de aproximadamente 5. Eso es desperdiciar espacio de almacenamiento, y es probable que sea bastante lento debido a la cantidad de datos que deben leerse.

Es mucho mejor simplemente guardar el nombre del archivo en el TFRecord, y leer el archivo a petición. La nueva API Dataset funciona bien, y la documentación tiene este ejemplo:

# Reads an image from a file, decodes it into a dense tensor, and resizes it
# to a fixed shape.
def _parse_function(filename, label):
  image_string = tf.read_file(filename)
  image_decoded = tf.image.decode_jpeg(image_string)
  image_resized = tf.image.resize_images(image_decoded, [28, 28])
  return image_resized, label

# A vector of filenames.
filenames = tf.constant(["/var/data/image1.jpg", "/var/data/image2.jpg", ...])

# `labels[i]` is the label for the image in `filenames[i].
labels = tf.constant([0, 37, ...])

dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))
dataset = dataset.map(_parse_function)
 1
Author: MattW.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-13 05:15:07