Tensorflow VarLenFeature vs FixedLenFeature

Я пытался сохранять изображения разных размеров в tf-записи. Я обнаружил, что, хотя изображения имеют разные размеры, я все равно могу загрузить их с помощью FixedLenFeature.

Проверяя документы на FixedLenFeature и VarLenFeature, я обнаружил, что разница в том, что VarLenFeauture возвращает разреженный тензор.

Может ли кто-нибудь проиллюстрировать некоторые ситуации, которые следует использовать FixedLenFeature или VarLenFeature?

Ответ 1

Вы можете загружать изображения, вероятно, потому что вы сохранили их, используя тип функции tf.train.BytesList() и данные всего изображения представляют собой одно большое значение байта внутри списка.

Если я прав, вы используете tf.decode_raw чтобы получить данные из изображения, которое вы загружаете из TFRecord.

Что касается примеров использования: я использую VarLenFeature для сохранения наборов данных для задачи обнаружения объектов: там переменное количество ограничивающих рамок на изображение (равное объекту на изображении), поэтому мне нужен другой объект objects_number для отслеживания количества объектов (и bboxes). Каждый ограничивающий прямоугольник представляет собой список из 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)

Обратите внимание, что "image_raw" имеет фиксированную длину Feature (имеет один элемент) и содержит значения типа "bytes", однако значение типа "bytes" само по себе может иметь переменный размер (это строка байтов и может содержать много символов внутри него).). Таким образом, "image_raw" - это список с ОДНЫМ элементом типа "байты", который может быть очень большим.

Для дальнейшего уточнения того, как это работает: объекты представляют собой списки значений, эти значения имеют определенный "тип".

Типы данных для объектов являются подмножеством типов данных для тензоров, у вас есть:

  • int64 (64-битное пространство в памяти)
  • байт (занимает столько байтов в памяти, сколько вы хотите)
  • float (занимает 32-64 бита в idk памяти)

Вы можете проверить здесь типы данных тензоров.

Таким образом, вы можете хранить данные переменной длины VarLenFeatures без VarLenFeatures (на самом деле вы хорошо это делаете), но сначала вам нужно будет преобразовать их в байты/строковую функцию, а затем декодировать их. И это самый распространенный метод.

Ответ 2

@Xyz

import tensorflow as tf

def __format(record):
    features = tf.parse_single_example(
        record,
        features={
            'image/height': tf.FixedLenFeature([], tf.int64),
            'image/width': tf.FixedLenFeature([], tf.int64),
            'image/depth': tf.FixedLenFeature([], tf.int64),
            'image/source': tf.FixedLenFeature([], tf.string)
        })

    height = tf.cast(features['image/height'], tf.int32)
    width = tf.cast(features['image/width'], tf.int32)
    depth = tf.cast(features['image/depth'], tf.int32)
    # Actual data
    image_shape = tf.parallel_stack([height, width, depth])

    image = tf.decode_raw(features['image/source'], tf.uint8)
    image = tf.reshape(image, image_shape)

    return image


dataset = tf.data.TFRecordDataset("train.tfrecord")
dataset = dataset.repeat()

dataset = dataset.map(__format)

dataset = dataset.batch(1)  # From the paper

iterator = dataset.make_one_shot_iterator()

image = iterator.get_next()

print(image.get_shape())

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    pass

этот результат (?,?,?,?) изображение не имеет формы..... и не может CNN

Что я делаю?