Aiuto proteggere la Grande Barriera Corallina con tensorflow sul Kaggle Join Sfida

Suggerimenti per le prestazioni

Questo documento fornisce suggerimenti sulle prestazioni specifici per TensorFlow Datasets (TFDS). Si noti che TFDS fornisce set di dati come tf.data.Dataset oggetti, in modo che il parere del tf.data guida si applica ancora.

Set di dati di riferimento

Usa tfds.benchmark(ds) al benchmark qualsiasi tf.data.Dataset oggetto.

Assicurati di indicare il batch_size= per normalizzare i risultati (ad esempio, 100 iter / sec -> 3200 ex / sec). Questo 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)

Piccoli set di dati (meno di 1 GB)

Tutti i set di dati TFDS memorizzare i dati su disco nel TFRecord formato. Per piccoli gruppi di dati (ad esempio MNIST, CIFAR-10 / -100), leggendo .tfrecord può aggiungere overhead significativo.

Poiché tali 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 (la sezione seguente contiene i dettagli).

Memorizzazione nella cache del set di dati

Ecco un esempio di una pipeline di dati che memorizza esplicitamente nella cache il set di dati dopo aver normalizzato le 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.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)

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

Memorizzazione automatica nella cache

Per impostazione predefinita, TFDS auto-cache (con ds.cache() ) serie di dati che soddisfano i seguenti vincoli:

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

E 'possibile scegliere di non auto-caching passando try_autocaching=False per 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 l'intero set di dati come un singolo array Tensor o NumPy. È possibile farlo dalla regolazione batch_size=-1 a lotto 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,
))

Grandi set di dati

I set di dati di grandi dimensioni vengono sharded (divisi in più file) e in genere non si adattano alla memoria, quindi non dovrebbero essere memorizzati nella cache.

Shuffle e allenamento

Durante l'allenamento, è importante mescolare bene i dati: dati mescolati male possono comportare una minore precisione dell'allenamento.

Oltre a utilizzare ds.shuffle a mischiare i record, si dovrebbe anche impostare shuffle_files=True per ottenere un buon comportamento rimescolamento per i set di dati più grandi che sono sharded in più file. Altrimenti, le epoche leggeranno i frammenti nello stesso ordine, quindi i dati non saranno veramente casuali.

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

Inoltre, quando shuffle_files=True , TFDS disabilita options.deterministic , che può dare un leggero incremento delle prestazioni. Per ottenere rimescolamento deterministica, è possibile opt-out di questa funzione con tfds.ReadConfig : o impostando read_config.shuffle_seed o sovrascrittura read_config.options.deterministic .

Condivisione automatica dei dati tra i lavoratori (TF)

Quando la formazione su più lavoratori, è possibile utilizzare il input_context argomento della tfds.ReadConfig , in modo che ogni lavoratore leggere 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. In primo luogo, l'API subplit viene applicato: train[:50%] viene convertito in un elenco di file da leggere. Poi, un ds.shard() op è applicato su tali file. Ad esempio, quando si utilizza train[:50%] con num_input_pipelines=2 , ciascuno dei 2 operai leggerà 1/4 dei dati.

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

Condivisione automatica dei dati tra i lavoratori (Jax)

Con Jax, è possibile utilizzare l' tfds.even_splits API per distribuire i dati tra i lavoratori. Vedere la guida divisa API .

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

Decodifica delle immagini più veloce

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

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

Salta le funzioni inutilizzate

Se stai utilizzando solo un sottoinsieme delle funzionalità, è possibile saltare completamente alcune funzionalità. Se il tuo set di dati ha molte funzionalità inutilizzate, non decodificarle può migliorare significativamente le prestazioni. Vedi https://www.tensorflow.org/datasets/decode#only_decode_a_sub-set_of_the_features