Estaba tratando de guardar imágenes de diferentes tamaños en tf-records. Descubrí que aunque las imágenes tienen diferentes tamaños, todavía puedo cargarlas con FixedLenFeature
.
Al revisar los documentos en FixedLenFeature
y VarLenFeature
, encontré que la diferencia parece ser que VarLenFeauture
devuelve un tensor disperso.
¿Alguien podría ilustrar algunas situaciones que deberían usar FixedLenFeature
o VarLenFeature
?
Puede cargar imágenes probablemente porque las guardó con el tipo de función tf.train.BytesList()
y los datos de la imagen completa son un valor de un byte grande dentro de una lista.
Si estoy en lo cierto, está usando tf.decode_raw
para obtener los datos de la imagen que carga desde TFRecord.
Con respecto a ejemplos de casos de uso: uso VarLenFeature
para guardar conjuntos de datos para la tarea de detección de objetos: hay una cantidad variable de cuadros delimitadores por imagen (igual a un objeto en la imagen), por lo tanto, necesito otra función objects_number
para realizar un seguimiento de la cantidad de objetos (y bboxes). Cada cuadro delimitador en sí es una lista de 4 coordenadas flotantes
Estoy usando el siguiente código para cargarlo:
features = tf.parse_single_example( serialized_example, features={ # We know the length of both fields. If not the # tf.VarLenFeature could be used 'height': tf.FixedLenFeature([], tf.int64), 'width': tf.FixedLenFeature([], tf.int64), 'depth': tf.FixedLenFeature([], tf.int64), # Label part 'objects_number': tf.FixedLenFeature([], tf.int64), 'bboxes': tf.VarLenFeature(tf.float32), 'labels': tf.VarLenFeature(tf.int64), # Dense data 'image_raw': tf.FixedLenFeature([],tf.string) }) # Get metadata objects_number = tf.cast(features['objects_number'], tf.int32) height = tf.cast(features['height'], tf.int32) width = tf.cast(features['width'], tf.int32) depth = tf.cast(features['depth'], tf.int32) # Actual data image_shape = tf.parallel_stack([height, width, depth]) bboxes_shape = tf.parallel_stack([objects_number, 4]) # BBOX data is actually dense convert it to dense tensor bboxes = tf.sparse_tensor_to_dense(features['bboxes'], default_value=0) # Since information about shape is lost reshape it bboxes = tf.reshape(bboxes, bboxes_shape) image = tf.decode_raw(features['image_raw'], tf.uint8) image = tf.reshape(image, image_shape)
Observe que “image_raw” es una Característica de longitud fija (tiene un elemento) y contiene valores del tipo “bytes”, sin embargo, un valor del tipo “bytes” puede tener un tamaño variable (es una cadena de bytes y puede tener muchos símbolos) ). Así que “image_raw” es una lista con UN elemento de tipo “bytes”, que puede ser muy grande.
Para más detalles sobre cómo funciona: Las características son listas de valores, esos valores tienen un “tipo” específico.
Los tipos de datos para características son un subconjunto de tipos de datos para tensores, usted tiene:
Puede consultar aquí los tipos de datos de los tensores .
Por lo tanto, puede almacenar datos de longitud variable sin VarLenFeatures
(en realidad, sí lo hace), pero primero tendría que convertirlos en la función de bytes / cadena y luego decodificarlos. Y este es el método más común.