Se usó la API de Cloud Translation para traducir esta página.
Switch to English

Consejos de rendimiento

Este documento proporciona consejos de rendimiento específicos de TFDS. Tenga en cuenta que TFDS proporciona conjuntos de datos como tf.data.Dataset s, por lo que aún se aplican los consejos de la guía tf.data .

Conjuntos de datos de referencia

Utilice tfds.core.benchmark(ds) para comparar cualquier objeto tf.data.Dataset .

Asegúrese de indicar batch_size= para normalizar los resultados (por ejemplo, 100 iter / seg -> 3200 ex / seg).

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

Pequeños conjuntos de datos (<GB)

Todos los conjuntos de datos TFDS almacenan los datos en disco en formato TFRecord . Para conjuntos de datos pequeños (por ejemplo, Mnist, Cifar, ...), la lectura de .tfrecord puede agregar una sobrecarga significativa.

A medida que esos conjuntos de datos encajan en la memoria, es posible mejorar significativamente el rendimiento almacenando en caché o precargando el conjunto de datos. Tenga en cuenta que TFDS almacena automáticamente en caché pequeños conjuntos de datos (consulte la siguiente sección para obtener más detalles).

Almacenamiento en caché del conjunto de datos

A continuación se muestra un ejemplo de una canalización de datos que almacena en caché explícitamente el conjunto de datos después de normalizar las imágenes.

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)

Al iterar sobre este conjunto de datos, la segunda iteración será mucho más rápida que la primera gracias al almacenamiento en caché.

Almacenamiento en caché automático

De forma predeterminada, TFDS almacena automáticamente en caché los conjuntos de datos que satisfacen las siguientes restricciones:

  • El tamaño total del conjunto de datos (todas las divisiones) está definido y es <250 MiB
  • shuffle_files está deshabilitado, o solo se lee un fragmento

Es posible optar por no almacenar en caché automático pasando try_autocaching=False a tfds.ReadConfig en tfds.load . Eche un vistazo a la documentación del catálogo de conjuntos de datos para ver si un conjunto de datos específico utilizará la caché automática.

Cargando los datos completos como un solo tensor

Si su conjunto de datos cabe en la memoria, también puede cargar el conjunto de datos completo como una única matriz Tensor o NumPy. Es posible hacerlo configurando batch_size=-1 para batch_size=-1 todos los ejemplos en un solo tf.Tensor . Luego use tfds.as_numpy para la conversión de 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,
))

Grandes conjuntos de datos

Los conjuntos de datos grandes están fragmentados (divididos en varios archivos) y, por lo general, no caben en la memoria, por lo que no deben almacenarse en caché.

Barajar y entrenar

Durante el entrenamiento, es importante mezclar bien los datos; Los datos mal mezclados pueden resultar en una menor precisión del entrenamiento.

Además de usar ds.shuffle para mezclar registros, también debe establecer shuffle_files=True para obtener un buen comportamiento de mezcla para conjuntos de datos más grandes que se fragmentan en varios archivos. De lo contrario, las épocas leerán los fragmentos en el mismo orden, por lo que los datos no serán realmente aleatorios.

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

Además, cuando shuffle_files=True , TFDS desactiva options.experimental_deterministic , lo que puede dar un ligero aumento de rendimiento. Para obtener una mezcla determinista, es posible optar por no participar en esta función con tfds.ReadConfig : ya sea configurando read_config.shuffle_seed o sobrescribiendo read_config.options.experimental_deterministic .

Divida automáticamente sus datos entre trabajadores

Cuando el entrenamiento de varios trabajadores, se puede utilizar el input_context argumento de tfds.ReadConfig , por lo que cada trabajador leerá un subconjunto de los datos.

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)

Esto es complementario a la API subsplit. Primero se aplica la API subplit ( train[:50%] se convierte en una lista de archivos para leer), luego se ds.shard() una ds.shard() a esos archivos. Ejemplo: cuando se usa train[:50%] con num_input_pipelines=2 , cada uno de los 2 trabajadores leerá 1/4 de los datos.

Cuando shuffle_files=True , los archivos se mezclan dentro de un trabajador, pero no entre trabajadores. Cada trabajador leerá el mismo subconjunto de archivos entre épocas.

Decodificación de imágenes más rápida

Por defecto, TFDS decodifica automáticamente las imágenes. Sin embargo, hay casos en los que puede ser más tfds.decode.SkipDecoding omitir la decodificación de imágenes con tfds.decode.SkipDecoding y aplicar manualmente tf.io.decode_image op:

  • Al filtrar ejemplos (con ds.filter ), para decodificar imágenes después de que se hayan filtrado los ejemplos.
  • Al recortar imágenes, utilice la tf.image.decode_and_crop_jpeg op.

El código para ambos ejemplos está disponible en la guía de decodificación .