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
.
Чтобы создать собственный соединитель функций, создайте подкласс 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
. Также лучше всего посмотреть на реальные примеры .