Spacca e affetta

Tutti i set di dati TFDS espongono varie suddivisioni di dati (ad esempio 'train' , 'test' ) che possono essere esplorate nel catalogo . Come nome dello split può essere utilizzata qualsiasi stringa alfabetica, tranne all (che è un termine riservato che corrisponde all'unione di tutti gli split, vedi sotto).

Oltre alle suddivisioni "ufficiali" del set di dati, TFDS consente di selezionare porzioni di suddivisione(i) e varie combinazioni.

API di affettamento

Le istruzioni di slicing sono specificate in tfds.load o tfds.DatasetBuilder.as_dataset tramite split= kwarg.

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

La divisione può essere:

  • Nomi semplici dei gruppi (una stringa come 'train' , 'test' , ...): tutti gli esempi all'interno del gruppo selezionato.
  • Fette : le fette hanno la stessa semantica della notazione delle fette Python . Le fette possono essere:
    • Absolute ( 'train[123:450]' , train[:4000] ): (vedere la nota seguente per avvertenze sull'ordine di lettura)
    • Percentuale ( 'train[:75%]' , 'train[25%:75%]' ): divide i dati completi in sezioni pari. Se i dati non sono equamente divisibili, una percentuale potrebbe contenere ulteriori esempi. È supportata una percentuale frazionaria.
    • Shard ( train[:4shard] , train[4shard] ): seleziona tutti gli esempi nello shard richiesto. (vedi info.splits['train'].num_shards per ottenere il numero di frammenti della divisione)
  • Unione di suddivisioni ( 'train+test' , 'train[:25%]+test' ): le suddivisioni verranno interlacciate insieme.
  • Set di dati completo ( 'all' ): 'all' è un nome di split speciale corrispondente all'unione di tutti i split (equivalente a 'train+test+...' ).
  • Elenco delle suddivisioni ( ['train', 'test'] ): più tf.data.Dataset vengono restituiti separatamente:
# Returns both train and test split separately
train_ds, test_ds = tfds.load('mnist', split=['train', 'test[:50%]'])

tfds.even_splits e formazione multi-host

tfds.even_splits genera un elenco di suddivisioni secondarie non sovrapposte della stessa dimensione.

# 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)

Ciò può essere particolarmente utile durante l'addestramento in un ambiente distribuito, in cui ciascun host deve ricevere una parte dei dati originali.

Con Jax , questo può essere ulteriormente semplificato utilizzando 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 è un semplice alias per:

# 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 accetta qualsiasi valore diviso come input (ad esempio 'train[75%:]+test' )

Affettamento e metadati

È possibile ottenere informazioni aggiuntive sulle divisioni/sottodivisioni ( num_examples , file_instructions ,...) utilizzando le informazioni del set di dati :

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']

Convalida incrociata

Esempi di convalida incrociata 10 volte utilizzando l'API stringa:

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)
])

I set di dati di convalida saranno ciascuno del 10%: [0%:10%] , [10%:20%] , ..., [90%:100%] . E i set di dati di addestramento saranno ciascuno il 90% complementare: [10%:100%] (per un set di convalida corrispondente di [0%:10%] ), `[0%:10%]

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

tfds.core.ReadInstruction e arrotondamento

Invece di str , è possibile passare splits come tfds.core.ReadInstruction :

Ad esempio, split = 'train[50%:75%] + test' equivale a:

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

unit può essere:

  • abs : affettatura assoluta
  • % : affettatura percentuale
  • shard : affettatura del frammento

tfds.ReadInstruction ha anche un argomento di arrotondamento. Se il numero di esempi nel set di dati non è diviso equamente:

  • rounding='closest' (predefinito): gli esempi rimanenti sono distribuiti tra le percentuali, quindi alcune percentuali potrebbero contenere esempi aggiuntivi.
  • rounding='pct1_dropremainder' : gli esempi rimanenti vengono eliminati, ma ciò garantisce che tutte le percentuali contengano esattamente lo stesso numero di esempi (ad esempio: len(5%) == 5 * len(1%) ).

Riproducibilità e determinismo

Durante la generazione, per una determinata versione del set di dati, TFDS garantisce che gli esempi vengano mescolati in modo deterministico su disco. Pertanto, generare il set di dati due volte (in 2 computer diversi) non modificherà l'ordine dell'esempio.

Allo stesso modo, l'API subsplit selezionerà sempre lo stesso set di esempi, indipendentemente dalla piattaforma, dall'architettura, ecc. Ciò significa set('train[:20%]') == set('train[:10%]') + set('train[10%:20%]') .

Tuttavia, l’ordine in cui vengono letti gli esempi potrebbe non essere deterministico. Questo dipende da altri parametri (ad esempio se shuffle_files=True ).