L'API tfds.features.FeatureConnector :
- Definisce la struttura, le forme, i dtype del
tf.data.Datasetfinale - Serializzazione astratta su/da disco.
- Esporre metadati aggiuntivi (ad esempio nomi di etichette, frequenza di campionamento audio,...)
Panoramica
tfds.features.FeatureConnector definisce la struttura delle caratteristiche del set di dati (in 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,
},
}),
)
Le funzionalità possono essere documentate utilizzando solo una descrizione testuale ( doc='description' ) o utilizzando direttamente tfds.features.Documentation per fornire una descrizione più dettagliata della funzionalità.
Le caratteristiche possono essere:
- Valori scalari:
tf.bool,tf.string,tf.float32,... Quando si desidera documentare la funzionalità, è anche possibile utilizzaretfds.features.Scalar(tf.int64, doc='description'). -
tfds.features.Audio,tfds.features.Video,... (vedi l'elenco delle funzionalità disponibili) -
dictdi funzionalità nidificate:{'metadata': {'image': Image(), 'description': tf.string} },... -
tfds.features.Sequencenidificate :Sequence({'image': ..., 'id': ...}),Sequence(Sequence(tf.int64)),...
Durante la generazione, gli esempi verranno automaticamente serializzati da FeatureConnector.encode_example in un formato adatto al disco (attualmente buffer del protocollo 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',
},
}
Durante la lettura del set di dati (ad esempio con tfds.load ), i dati vengono decodificati automaticamente con FeatureConnector.decode_example . Il tf.data.Dataset restituito corrisponderà alla struttura dict definita in 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),
},
}
Serializza/deserializza in proto
TFDS espone un'API di basso livello per serializzare/deserializzare gli esempi nel proto tf.train.Example .
Per serializzare dict[np.ndarray | Path | str | ...] in proto bytes , utilizzare 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)
Per deserializzare in proto bytes su tf.Tensor , utilizzare features.deserialize_example :
ds = tf.data.TFRecordDataset('path/to/file.tfrecord')
ds = ds.map(features.deserialize_example)
Accedi ai metadati
Consulta il documento introduttivo per accedere ai metadati delle funzionalità (nomi delle etichette, forma, dtype,...). Esempio:
ds, info = tfds.load(..., with_info=True)
info.features['label'].names # ['cat', 'dog', ...]
info.features['label'].str2int('cat') # 0
Crea il tuo tfds.features.FeatureConnector
Se ritieni che manchi una funzionalità tra quelle disponibili , apri un nuovo problema .
Per creare il tuo connettore di funzionalità, devi ereditare da tfds.features.FeatureConnector e implementare i metodi astratti.
- Se la tua funzionalità è un singolo valore tensore, è meglio ereditare da
tfds.features.Tensore utilizzaresuper()quando necessario. Vedi il codice sorgentetfds.features.BBoxFeatureper un esempio. - Se la tua funzionalità è un contenitore di più tensori, è meglio ereditare da
tfds.features.FeaturesDicte utilizzaresuper()per codificare automaticamente i sottoconnettori.
L'oggetto tfds.features.FeatureConnector astrae il modo in cui la funzionalità è codificata sul disco da come viene presentata all'utente. Di seguito è riportato un diagramma che mostra i livelli di astrazione del set di dati e la trasformazione dai file del set di dati grezzi all'oggetto tf.data.Dataset .

Per creare il tuo connettore di funzionalità, crea la sottoclasse tfds.features.FeatureConnector e implementa i metodi astratti:
-
encode_example(data): Definisce come codificare i dati forniti nel generatore_generate_examples()in dati compatibili contf.train.Example. Può restituire un singolo valore o undictdi valori. -
decode_example(data): definisce come decodificare i dati dal tensore letto datf.train.Examplenel tensore utente restituito datf.data.Dataset. -
get_tensor_info(): indica la forma/dtype dei tensori restituiti datf.data.Dataset. Può essere facoltativo se si eredita da un altrotfds.features. - (facoltativo)
get_serialized_info(): se le informazioni restituite daget_tensor_info()sono diverse da come i dati vengono effettivamente scritti su disco, è necessario sovrascrivereget_serialized_info()per corrispondere alle specifiche ditf.train.Example -
to_json_content/from_json_content: è necessario per consentire il caricamento del set di dati senza il codice sorgente originale. Vedi la funzione Audio per un esempio.
Per ulteriori informazioni, dai un'occhiata alla documentazione di tfds.features.FeatureConnector . È anche meglio guardare esempi reali .