Tensorflow VarLenFeature与FixedLenFeature

Zij*_*ost 25 python tensorflow

我试图将不同大小的图像保存到tf记录中.我发现即使图像大小不同,我仍然可以加载它们FixedLenFeature.

通过检查文档FixedLenFeatureVarLenFeature,我发现差异似乎是VarLenFeauture返回稀疏张量.

任何人都可以说明一些应该使用的情况FixedLenFeatureVarLenFeature

Xyz*_*Xyz 41

您可以加载图像,因为您使用要素类型保存它们,tf.train.BytesList()并且整个图像数据是列表中的一个大字节值.

如果我是对的,你正在使用tf.decode_raw从TFRecord加载的图像中获取数据.

关于示例用例:我VarLenFeature用于保存对象检测任务的数据集:每个图像的边界框数量可变(等于图像中的对象)因此我需要另一个功能objects_number来跟踪对象(和bbox)的数量.每个边界框本身都是4个浮点坐标的列表

我正在使用以下代码加载它:

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)
Run Code Online (Sandbox Code Playgroud)

请注意,"image_raw"是固定长度的Feature(有一个元素)并保存"bytes"类型的值,但是"bytes"类型的值本身可以具有可变大小(它是一个字节串,并且其中可以包含许多符号) ).所以"image_raw"是一个列表,其中包含一个"bytes"类型的元素,它可以超大.

进一步详细说明它的工作原理: 功能是值列表,这些值具有特定的"类型".

对于数据类型功能的子集的数据类型为张量,你必须:

  • int64(内存中64位空间)
  • bytes(在内存中占用尽可能多的字节)
  • float(在内存中占用32-64位idk多少)

您可以在此处查看 张量数据类型.

所以你可以VarLenFeatures根本不存储可变长度的数据(实际上你做得很好),但首先你需要将它转换成字节/字符串功能,然后解码它.这是最常用的方法.