Fentes et tranches

Tous les ensembles de données TFDS exposent diverses divisions de données (par exemple 'train' , 'test' ) qui peuvent être explorées dans le catalogue . N'importe quelle chaîne alphabétique peut être utilisée comme nom de split, sauf all (qui est un terme réservé qui correspond à l'union de tous les splits, voir ci-dessous).

En plus des divisions « officielles » des ensembles de données, TFDS permet de sélectionner des tranches de divisions et diverses combinaisons.

API de découpage

Les instructions de découpage sont spécifiées dans tfds.load ou tfds.DatasetBuilder.as_dataset via split= kwarg.

ds = tfds.load('my_dataset', split='train[:75%]')
builder = tfds.builder('my_dataset')
ds = builder.as_dataset(split='test+train[:75%]')

Le fractionnement peut être :

  • Noms de division simples (une chaîne telle que 'train' , 'test' , ...) : tous les exemples dans la division sélectionnée.
  • Tranches : Les tranches ont la même sémantique que la notation de tranche Python . Les tranches peuvent être :
    • Absolute ( 'train[123:450]' , train[:4000] ) : (voir la note ci-dessous pour la mise en garde concernant l'ordre de lecture)
    • Pourcentage ( 'train[:75%]' , 'train[25%:75%]' ) : divisez les données complètes en tranches paires. Si les données ne sont pas divisibles de manière égale, certains pourcentages peuvent contenir des exemples supplémentaires. Les pourcentages fractionnaires sont pris en charge.
    • Shard ( train[:4shard] , train[4shard] ) : sélectionnez tous les exemples dans le fragment demandé. (voir info.splits['train'].num_shards pour obtenir le nombre de fragments du fractionnement)
  • Union des fractionnements ( 'train+test' , 'train[:25%]+test' ) : les fractionnements seront entrelacés.
  • Ensemble de données complet ( 'all' ) : 'all' est un nom de division spécial correspondant à l'union de toutes les divisions (équivalent à 'train+test+...' ).
  • Liste des fractionnements ( ['train', 'test'] ) : plusieurs tf.data.Dataset sont renvoyés séparément :
# Returns both train and test split separately
train_ds, test_ds = tfds.load('mnist', split=['train', 'test[:50%]'])

tfds.even_splits et formation multi-hôtes

tfds.even_splits génère une liste de sous-splits qui ne se chevauchent pas et de même taille.

# Divide the dataset into 3 even parts, each containing 1/3 of the data
split0, split1, split2 = tfds.even_splits('train', n=3)

ds = tfds.load('my_dataset', split=split2)

Cela peut être particulièrement utile lors d'une formation dans un environnement distribué, où chaque hôte doit recevoir une tranche des données d'origine.

Avec Jax , cela peut être encore simplifié en utilisant tfds.split_for_jax_process :

split = tfds.split_for_jax_process('train', drop_remainder=True)
ds = tfds.load('my_dataset', split=split)

tfds.split_for_jax_process est un simple alias pour :

# The current `process_index` loads only `1 / process_count` of the data.
splits = tfds.even_splits('train', n=jax.process_count(), drop_remainder=True)
split = splits[jax.process_index()]

tfds.even_splits , tfds.split_for_jax_process accepte n'importe quelle valeur divisée en entrée (par exemple 'train[75%:]+test' )

Découpage et métadonnées

Il est possible d'obtenir des informations supplémentaires sur les splits/subsplits ( num_examples , file_instructions ,...) en utilisant les informations du jeu de données :

builder = tfds.builder('my_dataset')
builder.info.splits['train'].num_examples  # 10_000
builder.info.splits['train[:75%]'].num_examples  # 7_500 (also works with slices)
builder.info.splits.keys()  # ['train', 'test']

Validation croisée

Exemples de validation croisée 10 fois à l'aide de l'API de chaîne :

vals_ds = tfds.load('mnist', split=[
    f'train[{k}%:{k+10}%]' for k in range(0, 100, 10)
])
trains_ds = tfds.load('mnist', split=[
    f'train[:{k}%]+train[{k+10}%:]' for k in range(0, 100, 10)
])

Les ensembles de données de validation seront chacun de 10 % : [0%:10%] , [10%:20%] , ..., [90%:100%] . Et les ensembles de données de formation seront chacun complémentaires à 90 % : [10%:100%] (pour un ensemble de validation correspondant de [0%:10%] ), `[0% : 10 %]

  • [20%:100%] (for a validation set of [10%:20%]`),...

tfds.core.ReadInstruction et arrondi

Plutôt que str , il est possible de transmettre des fractionnements sous la forme tfds.core.ReadInstruction :

Par exemple, split = 'train[50%:75%] + test' équivaut à :

split = (
    tfds.core.ReadInstruction(
        'train',
        from_=50,
        to=75,
        unit='%',
    )
    + tfds.core.ReadInstruction('test')
)
ds = tfds.load('my_dataset', split=split)

unit peut être :

  • abs : Tranchage absolu
  • % : Pourcentage de découpage
  • shard : tranchage de fragment

tfds.ReadInstruction a également un argument d'arrondi. Si le nombre d'exemples dans l'ensemble de données n'est pas divisé également :

  • rounding='closest' (par défaut) : les exemples restants sont répartis entre les pourcentages, donc certains pourcentages peuvent contenir des exemples supplémentaires.
  • rounding='pct1_dropremainder' : Les exemples restants sont supprimés, mais cette garantie que tous les pourcentages contiennent exactement le même nombre d'exemples (par exemple : len(5%) == 5 * len(1%) ).

Reproductibilité et déterminisme

Lors de la génération, pour une version donnée de l'ensemble de données, TFDS garantit que les exemples sont mélangés de manière déterministe sur le disque. Ainsi, générer l'ensemble de données deux fois (sur 2 ordinateurs différents) ne modifiera pas l'ordre des exemples.

De même, l'API subsplit sélectionnera toujours le même set d'exemples, quelle que soit la plate-forme, l'architecture, etc. Cela signifie set('train[:20%]') == set('train[:10%]') + set('train[10%:20%]') .

Cependant, l’ordre dans lequel les exemples sont lus n’est peut-être pas déterministe. Cela dépend d'autres paramètres (par exemple si shuffle_files=True ).