FeatureConnecteur

L'API tfds.features.FeatureConnector :

  • Définit la structure, les formes et les types du tf.data.Dataset final
  • Sérialisation abstraite vers/depuis le disque.
  • Exposer des métadonnées supplémentaires (par exemple, noms d'étiquettes, fréquence d'échantillonnage audio,...)

Aperçu

tfds.features.FeatureConnector définit la structure des fonctionnalités de l'ensemble de données (dans 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,
       
},
   
}),
)

Les fonctionnalités peuvent être documentées soit en utilisant simplement une description textuelle ( doc='description' ), soit en utilisant directement tfds.features.Documentation pour fournir une description plus détaillée des fonctionnalités.

Les fonctionnalités peuvent être :

  • Valeurs scalaires : tf.bool , tf.string , tf.float32 ,... Lorsque vous souhaitez documenter la fonctionnalité, vous pouvez également utiliser tfds.features.Scalar(tf.int64, doc='description') .
  • tfds.features.Audio , tfds.features.Video ,... (voir la liste des fonctionnalités disponibles)
  • dict imbriqué de fonctionnalités : {'metadata': {'image': Image(), 'description': tf.string} } ,...
  • tfds.features.Sequence imbriqué : Sequence({'image': ..., 'id': ...}) , Sequence(Sequence(tf.int64)) ,...

Lors de la génération, les exemples seront automatiquement sérialisés par FeatureConnector.encode_example dans un format adapté au disque (actuellement les tampons de protocole 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',
   
},
}

Lors de la lecture de l'ensemble de données (par exemple avec tfds.load ), les données sont automatiquement décodées avec FeatureConnector.decode_example . Le tf.data.Dataset renvoyé correspondra à la structure dict définie dans 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),
   
},
}

Sérialiser/désérialiser en prototype

TFDS expose une API de bas niveau pour sérialiser/désérialiser les exemples dans le proto tf.train.Example .

Pour sérialiser dict[np.ndarray | Path | str | ...] en proto bytes , utilisez 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)

Pour désérialiser en proto bytes vers tf.Tensor , utilisez features.deserialize_example :

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

Accéder aux métadonnées

Voir la documentation d'introduction pour accéder aux métadonnées des fonctionnalités (noms d'étiquettes, forme, type,...). Exemple:

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

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

Créez votre propre tfds.features.FeatureConnector

Si vous pensez qu'une fonctionnalité manque parmi les fonctionnalités disponibles , veuillez ouvrir un nouveau numéro .

Pour créer votre propre connecteur de fonctionnalités, vous devez hériter de tfds.features.FeatureConnector et implémenter les méthodes abstraites.

  • Si votre fonctionnalité est une valeur de tenseur unique, il est préférable d'hériter de tfds.features.Tensor et d'utiliser super() si nécessaire. Voir le code source tfds.features.BBoxFeature pour un exemple.
  • Si votre fonctionnalité est un conteneur de plusieurs tenseurs, il est préférable d'hériter de tfds.features.FeaturesDict et d'utiliser le super() pour encoder automatiquement les sous-connecteurs.

L'objet tfds.features.FeatureConnector fait abstraction de la façon dont la fonctionnalité est codée sur le disque de la façon dont elle est présentée à l'utilisateur. Vous trouverez ci-dessous un diagramme montrant les couches d'abstraction de l'ensemble de données et la transformation des fichiers de l'ensemble de données bruts en l'objet tf.data.Dataset .

Couches d'abstraction DatasetBuilder

Pour créer votre propre connecteur de fonctionnalités, sous-classez tfds.features.FeatureConnector et implémentez les méthodes abstraites :

  • encode_example(data) : Définit comment encoder les données fournies dans le générateur _generate_examples() en données compatibles tf.train.Example . Peut renvoyer une valeur unique ou un dict de valeurs.
  • decode_example(data) : Définit comment décoder les données du tenseur lu depuis tf.train.Example en tenseur utilisateur renvoyé par tf.data.Dataset .
  • get_tensor_info() : Indique la forme/le type du ou des tenseurs renvoyés par tf.data.Dataset . Peut être facultatif en cas d'héritage d'un autre tfds.features .
  • (facultatif) get_serialized_info() : Si les informations renvoyées par get_tensor_info() sont différentes de la façon dont les données sont réellement écrites sur le disque, vous devez alors écraser get_serialized_info() pour correspondre aux spécifications de tf.train.Example
  • to_json_content / from_json_content : Ceci est requis pour permettre à votre ensemble de données d'être chargé sans le code source d'origine. Voir Fonctionnalité audio pour un exemple.

Pour plus d'informations, consultez la documentation tfds.features.FeatureConnector . Il est également préférable de regarder des exemples réels .