Tensorflow VarLenFeature vs FixedLenFeature

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:

  • int64 (espacio de 64 bits en la memoria)
  • bytes (ocupa tantos bytes en memoria como quieras)
  • float (ocupa 32-64 bits en la memoria idk cuánto)

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.