A API tfds.features.FeatureConnector
:
- Define a estrutura, formas e tipos do
tf.data.Dataset
final - Abstraia a serialização de/para o disco.
- Expor metadados adicionais (por exemplo, nomes de rótulos, taxa de amostragem de áudio,...)
Visão geral
tfds.features.FeatureConnector
define a estrutura de recursos do conjunto de dados (em 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,
},
}),
)
Os recursos podem ser documentados usando apenas uma descrição textual ( doc='description'
) ou usando tfds.features.Documentation
diretamente para fornecer uma descrição mais detalhada do recurso.
Os recursos podem ser:
- Valores escalares:
tf.bool
,tf.string
,tf.float32
,... Quando quiser documentar o recurso, você também pode usartfds.features.Scalar(tf.int64, doc='description')
. -
tfds.features.Audio
,tfds.features.Video
,... (veja a lista de recursos disponíveis) -
dict
aninhado de recursos:{'metadata': {'image': Image(), 'description': tf.string} }
,... -
tfds.features.Sequence
aninhados:Sequence({'image': ..., 'id': ...})
,Sequence(Sequence(tf.int64))
,...
Durante a geração, os exemplos serão serializados automaticamente por FeatureConnector.encode_example
em um formato adequado ao disco (atualmente buffers de protocolo 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',
},
}
Ao ler o conjunto de dados (por exemplo, com tfds.load
), os dados são decodificados automaticamente com FeatureConnector.decode_example
. O tf.data.Dataset
retornado corresponderá à estrutura dict
definida em 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),
},
}
Serializar/desserializar para proto
O TFDS expõe uma API de baixo nível para serializar/desserializar exemplos para o proto tf.train.Example
.
Para serializar dict[np.ndarray | Path | str | ...]
para proto bytes
, use 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)
Para desserializar para proto bytes
para tf.Tensor
, use features.deserialize_example
:
ds = tf.data.TFRecordDataset('path/to/file.tfrecord')
ds = ds.map(features.deserialize_example)
Acessar metadados
Consulte o documento de introdução para acessar os metadados dos recursos (nomes dos rótulos, forma, dtype,...). Exemplo:
ds, info = tfds.load(..., with_info=True)
info.features['label'].names # ['cat', 'dog', ...]
info.features['label'].str2int('cat') # 0
Crie seu próprio tfds.features.FeatureConnector
Se você acredita que um recurso está faltando entre os recursos disponíveis , abra um novo problema .
Para criar seu próprio conector de recursos, você precisa herdar de tfds.features.FeatureConnector
e implementar os métodos abstratos.
- Se o seu recurso for um valor de tensor único, é melhor herdar de
tfds.features.Tensor
e usarsuper()
quando necessário. Consulte o código-fontetfds.features.BBoxFeature
para obter um exemplo. - Se o seu recurso for um contêiner de vários tensores, é melhor herdar de
tfds.features.FeaturesDict
e usarsuper()
para codificar automaticamente os subconectores.
O objeto tfds.features.FeatureConnector
abstrai como o recurso é codificado no disco e como ele é apresentado ao usuário. Abaixo está um diagrama que mostra as camadas de abstração do conjunto de dados e a transformação dos arquivos brutos do conjunto de dados para o objeto tf.data.Dataset
.
Para criar seu próprio conector de recursos, subclasse tfds.features.FeatureConnector
e implemente os métodos abstratos:
-
encode_example(data)
: Define como codificar os dados fornecidos no gerador_generate_examples()
em dados compatíveis comtf.train.Example
. Pode retornar um único valor ou umdict
de valores. -
decode_example(data)
: Define como decodificar os dados do tensor lido detf.train.Example
no tensor do usuário retornado portf.data.Dataset
. -
get_tensor_info()
: Indica a forma/tipo do(s) tensor(es) retornado(s) portf.data.Dataset
. Pode ser opcional se herdar de outrotfds.features
. - (opcionalmente)
get_serialized_info()
: Se as informações retornadas porget_tensor_info()
forem diferentes de como os dados são realmente gravados no disco, então você precisa sobrescreverget_serialized_info()
para corresponder às especificações dotf.train.Example
-
to_json_content
/from_json_content
: Isso é necessário para permitir que seu conjunto de dados seja carregado sem o código-fonte original. Consulte Recurso de áudio para ver um exemplo.
Para obter mais informações, dê uma olhada na documentação tfds.features.FeatureConnector
. Também é melhor observar exemplos reais .