FeatureConnector

API tfds.features.FeatureConnector :

  • Определяет структуру, формы и типы конечного tf.data.Dataset
  • Абстрагируйте сериализацию на/с диска.
  • Предоставлять дополнительные метаданные (например, названия меток, частоту дискретизации звука и т. д.)

Обзор

tfds.features.FeatureConnector определяет структуру объектов набора данных (в tfds.core.DatasetInfo ):

tfds.core.DatasetInfo(
    features=tfds.features.FeaturesDict({
        'image': tfds.features.Image(shape=(28, 28, 1), doc='Grayscale image'),
        'label': tfds.features.ClassLabel(
            names=['no', 'yes'],
            doc=tfds.features.Documentation(
                desc='Whether this is a picture of a cat',
                value_range='yes or no'
            ),
        ),
        'metadata': {
            'id': tf.int64,
            'timestamp': tfds.features.Scalar(
                tf.int64,
                doc='Timestamp when this picture was taken as seconds since epoch'),
            'language': tf.string,
        },
    }),
)

Функции можно документировать, используя только текстовое описание ( doc='description' ) или напрямую используя tfds.features.Documentation для предоставления более подробного описания функции.

Особенности могут быть:

  • Скалярные значения: tf.bool , tf.string , tf.float32 ,... Если вы хотите задокументировать функцию, вы также можете использовать tfds.features.Scalar(tf.int64, doc='description') .
  • tfds.features.Audio , tfds.features.Video ,... (см. список доступных функций)
  • Вложенный dict функций: {'metadata': {'image': Image(), 'description': tf.string} } ,...
  • Вложенные tfds.features.Sequence : Sequence({'image': ..., 'id': ...}) , Sequence(Sequence(tf.int64)) ,...

Во время генерации примеры будут автоматически сериализованы FeatureConnector.encode_example в формат, подходящий для диска (в настоящее время это буферы протокола tf.train.Example ):

yield {
    'image': '/path/to/img0.png',  # `np.array`, file bytes,... also accepted
    'label': 'yes',  # int (0-num_classes) also accepted
    'metadata': {
        'id': 43,
        'language': 'en',
    },
}

При чтении набора данных (например, с помощью tfds.load ) данные автоматически декодируются с помощью FeatureConnector.decode_example . Возвращенный tf.data.Dataset будет соответствовать структуре dict , определенной в tfds.core.DatasetInfo :

ds = tfds.load(...)
ds.element_spec == {
    'image': tf.TensorSpec(shape=(28, 28, 1), tf.uint8),
    'label': tf.TensorSpec(shape=(), tf.int64),
    'metadata': {
        'id': tf.TensorSpec(shape=(), tf.int64),
        'language': tf.TensorSpec(shape=(), tf.string),
    },
}

Сериализация/десериализация в прототип

TFDS предоставляет низкоуровневый API для сериализации/десериализации примеров в прототипе tf.train.Example .

Чтобы сериализовать dict[np.ndarray | Path | str | ...] в bytes , используйте features.serialize_example :

with tf.io.TFRecordWriter('path/to/file.tfrecord') as writer:
  for ex in all_exs:
    ex_bytes = features.serialize_example(data)
    f.write(ex_bytes)

Чтобы десериализовать bytes в tf.Tensor , используйте features.deserialize_example :

ds = tf.data.TFRecordDataset('path/to/file.tfrecord')
ds = ds.map(features.deserialize_example)

Доступ к метаданным

См. вводный документ для доступа к метаданным функций (имена меток, форма, dtype и т. д.). Пример:

ds, info = tfds.load(..., with_info=True)

info.features['label'].names  # ['cat', 'dog', ...]
info.features['label'].str2int('cat')  # 0

Создайте свой собственный tfds.features.FeatureConnector

Если вы считаете, что какая-то функция отсутствует среди доступных функций , откройте новую проблему .

Чтобы создать собственный соединитель функций, вам необходимо наследовать tfds.features.FeatureConnector и реализовать абстрактные методы.

  • Если ваша функция представляет собой одно значение тензора, лучше всего наследовать от tfds.features.Tensor и при необходимости использовать super() . Пример см. в исходном коде tfds.features.BBoxFeature .
  • Если ваша функция представляет собой контейнер из нескольких тензоров, лучше всего наследовать от tfds.features.FeaturesDict и использовать super() для автоматического кодирования подконнекторов.

Объект tfds.features.FeatureConnector абстрагирует то, как функция кодируется на диске, от того, как она представляется пользователю. Ниже представлена ​​диаграмма, показывающая уровни абстракции набора данных и преобразование необработанных файлов набора данных в объект tf.data.Dataset .

Слои абстракции DatasetBuilder

Чтобы создать собственный соединитель функций, создайте подкласс tfds.features.FeatureConnector и реализуйте абстрактные методы:

  • encode_example(data) : определяет, как кодировать данные, заданные в генераторе _generate_examples() , в данные, совместимые tf.train.Example . Может возвращать одно значение или dict значений.
  • decode_example(data) : определяет, как декодировать данные из тензора, считанного из tf.train.Example , в пользовательский тензор, возвращаемый tf.data.Dataset .
  • get_tensor_info() : указывает форму/тип тензора(ов), возвращаемого tf.data.Dataset . Может быть необязательным при наследовании от другого tfds.features .
  • (необязательно) get_serialized_info() : если информация, возвращаемая get_tensor_info() отличается от того, как данные фактически записываются на диск, вам необходимо перезаписать get_serialized_info() , чтобы он соответствовал спецификациям tf.train.Example
  • to_json_content / from_json_content : это необходимо для загрузки вашего набора данных без исходного исходного кода. Пример см. в разделе «Функция аудио» .

Для получения дополнительной информации ознакомьтесь с документацией tfds.features.FeatureConnector . Также лучше всего посмотреть на реальные примеры .