Come posso convertire una directory di immagini jpeg nel file TFRecords in tensorflow?

Ho dati di addestramento che sono una directory di immagini jpeg e un file di testo corrispondente contenente il nome del file e l’etichetta di categoria associata. Sto cercando di convertire questi dati di addestramento in un file di tfrecords come descritto nella documentazione di tensorflow. Ho passato un po ‘di tempo a cercare di far funzionare tutto questo, ma non ci sono esempi in tensorflow che dimostrano come utilizzare uno qualsiasi dei lettori per leggere i file jpeg e aggiungerli a un tfrecord usando tfrecordwriter

Spero che aiuti:

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) 

Per ottenere tutte le immagini come una serie di tensori utilizzare il seguente esempio di codice.

Github repo di ImageFlow


Aggiornare:

Nella risposta precedente ho appena detto come leggere un’immagine in formato TF, ma non salvarla in TFRecords. Per quello dovresti usare:

 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()) 

Maggiori informazioni qui

E tu leggi i dati in questo modo:

 # 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 

Il modello iniziale di Tensorflow ha un file build_image_data.py che può compiere la stessa cosa con l’ipotesi che ciascuna sottodirectory rappresenti un’etichetta.

Ho anche lo stesso problema.

Quindi ecco come ottengo i file di tfrecords dei miei file jpeg

Modifica: aggiungi sol 1 – un modo migliore e più veloce

(Consigliato) Soluzione 1:

Dal github ufficiale di tensorflow: Come build un nuovo set di dati per la riqualificazione , utilizzare direttamente lo script python ufficiale build_image_data.py e bazel è un’idea migliore.

Ecco le istruzioni:

Per eseguire build_image_data.py , è ansible eseguire la seguente riga di comando:

 # 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 

dove $OUTPUT_DIRECTORY è la posizione dei TFRecords TFRecords . $LABELS_FILE sarà un file di testo che viene letto dallo script che fornisce un elenco di tutte le etichette.

quindi, dovrebbe fare il trucco.

ps. bazel, creato da Google, trasforma il codice in makefile.

Soluzione 2:

Innanzitutto, faccio riferimento alle istruzioni di @capitalistpug e controllo il file di script della shell

(file di script shell fornito da Google: download_and_preprocess_flowers.sh )

In secondo luogo, ho anche scoperto un tutorial di formazione mini inception-v3 di NVIDIA

(La formazione ufficiale di NVIDIA SPEED UP CON TENSORFLOW ACCELERATO CON GPU )

Fare attenzione , i seguenti passaggi devono essere eseguiti nell’ambiente di Bazel WORKSAPCE

quindi il file di build di Bazel può essere eseguito correttamente


Primo passo , commento la parte del download del set di dati imagenet che ho già scaricato

e il resto della parte che non ho bisogno di download_and_preprocess_flowers.sh

Secondo passo , cambia directory in tensorflow / modelli / inizio

dove è l’ambiente Bazel ed è stato costruito da Bazel prima

 $ cd tensorflow/models/inception 

Facoltativo: se non è stato creato in precedenza, digitare il seguente codice in cmd

 $ bazel build inception/download_and_preprocess_flowers 

Devi capire il contenuto nell’immagine seguente

inserisci la descrizione dell'immagine qui

E ultimo passaggio , digitare il seguente codice:

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

Quindi, inizierà a chiamare build_image_data.py e a creare il file tfrecords

Si noti che le immagini verranno salvate in TFRecord come tensori non compressi, aumentando possibilmente le dimensioni di un fattore di circa 5. Questo è spreco di spazio di archiviazione e probabilmente sarà piuttosto lento a causa della quantità di dati che devono essere letti.

È molto meglio semplicemente salvare il nome del file nel TFRecord e leggere il file su richiesta. La nuova API Dataset funziona bene e la documentazione ha questo esempio:

 # 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)