Guarda i keynote, le sessioni sui prodotti, i workshop e altro ancora da Google I / O Visualizza la playlist

Suggerimenti per le prestazioni

Questo documento fornisce suggerimenti sulle prestazioni specifici per TFDS. Si noti che TFDS fornisce set di dati cometf.data.Dataset s, quindi si applicano ancora i consigli della guida tf.data .

Set di dati di benchmark

Utilizzare tfds.benchmark(ds) per eseguire il benchmark di qualsiasi oggettotf.data.Dataset .

Assicurati di indicare batch_size= per normalizzare i risultati (es. 100 iter / sec -> 3200 ex / sec). Funziona con qualsiasi iterabile (ad esempio tfds.benchmark(tfds.as_numpy(ds)) ).

ds = tfds.load('mnist', split='train').batch(32).prefetch()
# Display some benchmark statistics
tfds.benchmark(ds, batch_size=32)
# Second iteration is much faster, due to auto-caching
tfds.benchmark(ds, batch_size=32)

Set di dati piccoli (<GB)

Tutti i dataset TFDS memorizzano i dati su disco nel formato TFRecord . Per piccoli set di dati (ad esempio Mnist, Cifar, ...), la lettura da .tfrecord può aggiungere un overhead significativo.

Poiché questi set di dati si adattano alla memoria, è possibile migliorare significativamente le prestazioni memorizzando nella cache o precaricando il set di dati. Si noti che TFDS memorizza automaticamente nella cache piccoli set di dati (vedere la sezione successiva per i dettagli).

Memorizzazione nella cache del set di dati

Di seguito è riportato un esempio di una pipeline di dati che memorizza esplicitamente nella cache il set di dati dopo la normalizzazione delle immagini.

def normalize_img(image, label):
  """Normalizes images: `uint8` -> `float32`."""
  return tf.cast(image, tf.float32) / 255., label


ds, ds_info = tfds.load(
    'mnist',
    split='train',
    as_supervised=True,  # returns `(img, label)` instead of dict(image=, ...)
    with_info=True,
)
# Applying normalization before `ds.cache()` to re-use it.
# Note: Random transformations (e.g. images augmentations) should be applied
# after both `ds.cache()` (to avoid caching randomness) and `ds.batch()` (for
# vectorization [1]).
ds = ds.map(normalize_img, num_parallel_calls=tf.data.experimental.AUTOTUNE)
ds = ds.cache()
# For true randomness, we set the shuffle buffer to the full dataset size.
ds = ds.shuffle(ds_info.splits['train'].num_examples)
# Batch after shuffling to get unique batches at each epoch.
ds = ds.batch(128)
ds = ds.prefetch(tf.data.experimental.AUTOTUNE)

Durante l'iterazione su questo set di dati, la seconda iterazione sarà molto più veloce della prima grazie alla memorizzazione nella cache.

Caching automatico

Per impostazione predefinita, TFDS memorizza automaticamente nella cache i set di dati che soddisfano i seguenti vincoli:

  • La dimensione totale del set di dati (tutte le suddivisioni) è definita e <250 MiB
  • shuffle_files è disabilitato o viene letto solo un singolo frammento

È possibile disattivare la memorizzazione nella cache automatica passando try_autocaching=False a tfds.ReadConfig in tfds.load . Dai un'occhiata alla documentazione del catalogo del set di dati per vedere se un set di dati specifico utilizzerà la cache automatica.

Caricamento dei dati completi come un singolo tensore

Se il tuo set di dati si adatta alla memoria, puoi anche caricare il set di dati completo come un singolo array Tensor o NumPy. È possibile farlo impostando batch_size=-1 per batch_size=-1 tutti gli esempi in un singolo tf.Tensor . Quindi utilizzare tfds.as_numpy per la conversione da tf.Tensor a np.array .

(img_train, label_train), (img_test, label_test) = tfds.as_numpy(tfds.load(
    'mnist',
    split=['train', 'test'],
    batch_size=-1,
    as_supervised=True,
))

Set di dati di grandi dimensioni

I set di dati di grandi dimensioni sono frammentati (suddivisi in più file) e in genere non si adattano alla memoria, quindi non devono essere memorizzati nella cache.

Shuffle e formazione

Durante l'addestramento, è importante mescolare bene i dati; dati scarsamente mescolati possono comportare una minore precisione dell'addestramento.

Oltre a usare ds.shuffle per mescolare i record, dovresti anche impostare shuffle_files=True per ottenere un buon comportamento di mescolamento per set di dati più grandi che sono suddivisi in più file. Altrimenti, le epoche leggeranno i frammenti nello stesso ordine, quindi i dati non saranno veramente randomizzati.

ds = tfds.load('imagenet2012', split='train', shuffle_files=True)

Inoltre, quando shuffle_files=True , TFDS disabilita options.experimental_deterministic , che può aumentare leggermente le prestazioni. Per ottenere un mescolamento deterministico, è possibile disattivare questa funzione con tfds.ReadConfig : impostando read_config.shuffle_seed o sovrascrivendo read_config.options.experimental_deterministic .

Suddividi automaticamente i tuoi dati tra i lavoratori

Quando si input_context l'addestramento su più worker, è possibile utilizzare l'argomento tfds.ReadConfig di tfds.ReadConfig , in modo che ogni worker legga un sottoinsieme dei dati.

input_context = tf.distribute.InputContext(
    input_pipeline_id=1,  # Worker id
    num_input_pipelines=4,  # Total number of workers
)
read_config = tfds.ReadConfig(
    input_context=input_context,
)
ds = tfds.load('dataset', split='train', read_config=read_config)

Questo è complementare all'API subsplit. Prima viene applicata l'API subplit ( train[:50%] viene convertito in un elenco di file da leggere), quindi viene applicata un'operazione ds.shard() su quei file. Esempio: quando si utilizza train[:50%] con num_input_pipelines=2 , ciascuno dei 2 worker leggerà 1/4 dei dati.

Quando shuffle_files=True , i file vengono mescolati all'interno di un worker, ma non tra i worker. Ogni lavoratore leggerà lo stesso sottoinsieme di file tra le epoche.

Decodifica delle immagini più veloce

Per impostazione predefinita, TFDS decodifica automaticamente le immagini. Tuttavia, ci sono casi in cui può essere più performante saltare la decodifica dell'immagine con tfds.decode.SkipDecoding e applicare manualmente l'op tf.io.decode_image :

  • Quando si filtrano gli esempi (con ds.filter ), per decodificare le immagini dopo che gli esempi sono stati filtrati.
  • Quando si ritagliano le immagini, per utilizzare il fused tf.image.decode_and_crop_jpeg op.

Il codice per entrambi gli esempi è disponibile nella guida alla decodifica .