python - from_tensor_slices - TensorFlow-¿Lee todos los ejemplos de un TFRecords a la vez?
from_tensor_slices() (6)
Además, si no piensas ''tf.train.shuffle_batch'' es la forma que necesitas. Puede probar la combinación de tf.TFRecordReader (). Read_up_to () y tf.parse_example () también. Aquí está el ejemplo para su referencia:
def read_tfrecords(folder_name, bs):
filename_queue = tf.train.string_input_producer(tf.train.match_filenames_once(glob.glob(folder_name + "/*.tfrecords")))
reader = tf.TFRecordReader()
_, serialized = reader.read_up_to(filename_queue, bs)
features = tf.parse_example(
serialized,
features={
''label'': tf.FixedLenFeature([], tf.string),
''image'': tf.FixedLenFeature([], tf.string)
}
)
record_image = tf.decode_raw(features[''image''], tf.uint8)
image = tf.reshape(record_image, [-1, 250, 151, 1])
label = tf.cast(features[''label''], tf.string)
return image, label
¿Cómo se leen todos los ejemplos de un TFRecords a la vez?
He estado usando tf.parse_single_example
para leer ejemplos individuales usando un código similar al dado en el método read_and_decode
en el ejemplo de fully_connected_reader . Sin embargo, quiero ejecutar la red contra mi conjunto de datos de validación a la vez, y me gustaría cargarlos en su totalidad en su lugar.
No estoy del todo seguro, pero la documentación parece sugerir que puedo usar tf.parse_example
lugar de tf.parse_single_example
para cargar todo el archivo TFRecords a la vez. Parece que no puedo hacer que esto funcione. Supongo que tiene que ver con cómo especifico las características, pero no estoy seguro de cómo en la especificación de la función para indicar que hay múltiples ejemplos.
En otras palabras, mi intento de usar algo similar a:
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)
features = tf.parse_example(serialized_example, features={
''image_raw'': tf.FixedLenFeature([], tf.string),
''label'': tf.FixedLenFeature([], tf.int64),
})
no está funcionando, y supongo que es porque las características no esperan ejemplos múltiples a la vez (pero de nuevo, no estoy seguro). [Esto produce un error de ValueError: Shape () must have rank 1
]
¿Es esta la forma correcta de leer todos los registros a la vez? Y si es así, ¿qué necesito cambiar para leer realmente los registros? ¡Muchas gracias!
No sé si todavía es un tema activo. Me gustaría compartir las mejores prácticas que conozco hasta ahora, sin embargo es una pregunta hace un año.
En Tensorflow, tenemos un método muy útil para este problema: leer o repetir todo el conjunto de datos de entrada y generar entrenamiento para probar los datos de forma aleatoria. ''tf.train.shuffle_batch'' puede generar la base de datos en la secuencia de entrada (como reader.read ()) en su comportamiento. Como por ejemplo, puede generar un conjunto de datos 1000, proporcionando una lista de argumentos como esta:
reader = tf.TFRecordReader()
_, serialized = reader.read(filename_queue)
features = tf.parse_single_example(
serialized,
features={
''label'': tf.FixedLenFeature([], tf.string),
''image'': tf.FixedLenFeature([], tf.string)
}
)
record_image = tf.decode_raw(features[''image''], tf.uint8)
image = tf.reshape(record_image, [500, 500, 1])
label = tf.cast(features[''label''], tf.string)
min_after_dequeue = 10
batch_size = 1000
capacity = min_after_dequeue + 3 * batch_size
image_batch, label_batch = tf.train.shuffle_batch(
[image, label], batch_size=batch_size, capacity=capacity, min_after_dequeue=min_after_dequeue
)
Para leer todos los datos solo una vez, debe pasar num_epochs
al string_input_producer
. Cuando se leen todos los registros, el método de lectura .read
arrojará un error, que puede detectar. Ejemplo simplificado:
import tensorflow as tf
def read_and_decode(filename_queue):
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)
features = tf.parse_single_example(
serialized_example,
features={
''image_raw'': tf.FixedLenFeature([], tf.string)
})
image = tf.decode_raw(features[''image_raw''], tf.uint8)
return image
def get_all_records(FILE):
with tf.Session() as sess:
filename_queue = tf.train.string_input_producer([FILE], num_epochs=1)
image = read_and_decode(filename_queue)
init_op = tf.initialize_all_variables()
sess.run(init_op)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
try:
while True:
example = sess.run([image])
except tf.errors.OutOfRangeError, e:
coord.request_stop(e)
finally:
coord.request_stop()
coord.join(threads)
get_all_records(''/path/to/train-0.tfrecords'')
Y para usar tf.parse_example
(que es faster que tf.parse_single_example
), primero debe tf.parse_single_example
los ejemplos así:
batch = tf.train.batch([serialized_example], num_examples, capacity=num_examples)
parsed_examples = tf.parse_example(batch, feature_spec)
Desafortunadamente, de esta manera necesitarás saber el número de ejemplos de antemano.
Para mayor claridad, tengo unas miles de imágenes en un único archivo .tfrecords, son archivos png de 720 por 720 rgb. Las etiquetas son una de 0,1,2,3.
También intenté usar el parse_example y no pude hacerlo funcionar, pero esta solución funciona con parse_single_example.
La desventaja es que ahora mismo tengo que saber cuántos elementos hay en cada registro .tf, lo cual es un poco fastidioso. Si encuentro una mejor manera, actualizaré la respuesta. Además, tenga cuidado de salir de los límites del número de registros en el archivo .tfrecords, comenzará de nuevo en el primer registro si pasa el último registro
El truco consistía en hacer que el corredor de la cola utilizara un coordinador.
Dejé un código aquí para guardar las imágenes a medida que las lee, para que pueda verificar que la imagen sea correcta.
from PIL import Image
import numpy as np
import tensorflow as tf
def read_and_decode(filename_queue):
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)
features = tf.parse_single_example(
serialized_example,
# Defaults are not specified since both keys are required.
features={
''image_raw'': tf.FixedLenFeature([], tf.string),
''label'': tf.FixedLenFeature([], tf.int64),
''height'': tf.FixedLenFeature([], tf.int64),
''width'': tf.FixedLenFeature([], tf.int64),
''depth'': tf.FixedLenFeature([], tf.int64)
})
image = tf.decode_raw(features[''image_raw''], tf.uint8)
label = tf.cast(features[''label''], tf.int32)
height = tf.cast(features[''height''], tf.int32)
width = tf.cast(features[''width''], tf.int32)
depth = tf.cast(features[''depth''], tf.int32)
return image, label, height, width, depth
def get_all_records(FILE):
with tf.Session() as sess:
filename_queue = tf.train.string_input_producer([ FILE ])
image, label, height, width, depth = read_and_decode(filename_queue)
image = tf.reshape(image, tf.pack([height, width, 3]))
image.set_shape([720,720,3])
init_op = tf.initialize_all_variables()
sess.run(init_op)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
for i in range(2053):
example, l = sess.run([image, label])
img = Image.fromarray(example, ''RGB'')
img.save( "output/" + str(i) + ''-train.png'')
print (example,l)
coord.request_stop()
coord.join(threads)
get_all_records(''/path/to/train-0.tfrecords'')
Si necesita leer todos los datos de TFRecord de una vez, puede escribir una solución mucho más sencilla solo en unas pocas líneas de código usando tf_record_iterator :
Un iterador que lee los registros de un archivo TFRecords.
Para hacer esto, simplemente:
- crea un ejemplo
- iterar sobre los registros del iterador
- analizar cada registro y leer cada función según su tipo
Aquí hay un ejemplo con explicación de cómo leer cada tipo.
example = tf.train.Example()
for record in tf.python_io.tf_record_iterator(<tfrecord_file>):
example.ParseFromString(record)
f = example.features.feature
v1 = f[''int64 feature''].int64_list.value[0]
v2 = f[''float feature''].float_list.value[0]
v3 = f[''bytes feature''].bytes_list.value[0]
# for bytes you might want to represent them in a different way (based on what they were before saving)
# something like `np.fromstring(f[''img''].bytes_list.value[0], dtype=np.uint8
# Now do something with your v1/v2/v3
También puede usar tf.python_io.tf_record_iterator
para iterar manualmente todos los ejemplos en un TFRecord
.
Lo pruebo con un código de ilustración a continuación:
import tensorflow as tf
X = [[1, 2],
[3, 4],
[5, 6]]
def _int_feature(value):
return tf.train.Feature(int64_list=tf.train.Int64List(value=value))
def dump_tfrecord(data, out_file):
writer = tf.python_io.TFRecordWriter(out_file)
for x in data:
example = tf.train.Example(
features=tf.train.Features(feature={
''x'': _int_feature(x)
})
)
writer.write(example.SerializeToString())
writer.close()
def load_tfrecord(file_name):
features = {''x'': tf.FixedLenFeature([2], tf.int64)}
data = []
for s_example in tf.python_io.tf_record_iterator(file_name):
example = tf.parse_single_example(s_example, features=features)
data.append(tf.expand_dims(example[''x''], 0))
return tf.concat(0, data)
if __name__ == "__main__":
dump_tfrecord(X, ''test_tfrecord'')
print(''dump ok'')
data = load_tfrecord(''test_tfrecord'')
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
Y = sess.run([data])
print(Y)
Por supuesto, debe usar su propia especificación de feature
.
La desventaja es que no sé cómo usar multi-hilos de esta manera. Sin embargo, la mayoría de las ocasiones en que leemos todos los ejemplos es cuando evaluamos el conjunto de datos de validación, que generalmente no es muy grande. Entonces, creo que la eficiencia puede no ser un cuello de botella.
Y tengo otro problema cuando pruebo este problema, que es que debo especificar la longitud de la característica. En lugar de tf.FixedLenFeature([], tf.int64)
, tengo que escribir tf.FixedLenFeature([2], tf.int64)
, de lo contrario, se InvalidArgumentError
un InvalidArgumentError
. No tengo idea de cómo evitar esto.
Python: 3.4
Tensorflow: 0.12.0