Path: blob/master/site/es-419/datasets/determinism.ipynb
25115 views
Copyright 2020 The TensorFlow Authors.
TFDS y determinismo
En este documento se explica:
Las garantías de TFDS en el determinismo
El orden en el que TFDS lee los ejemplos
Una variedad de precauciones y errores
Preparación
Conjuntos de datos
Se necesita algo de contexto para entender cómo TFDS lee los datos.
Durante la generación, TFDS escribe los datos originales en archivos .tfrecord
estandarizados. Para los conjuntos de datos grandes, se crean varios archivos .tfrecord
, cada uno de los cuales contiene varios ejemplos. A cada archivo .tfrecord
lo llamamos partición.
Esta guía usa imagenet que tiene 1024 particiones:
Encontrar los id de los ejemplos del conjunto de datos
Vaya a la siguiente sección si solo desea saber sobre el determinismo.
Cada ejemplo de los conjuntos de datos se identifica de forma única mediante un id
(por ejemplo 'imagenet2012-train.tfrecord-01023-of-01024__32'
). Se puede recuperar el id
al pasar read_config.add_tfds_id = True
, que agregará una clave 'tfds_id'
en el dict de tf.data.Dataset
.
En este tutorial, definimos una pequeña util que imprimirá los id de ejemplo del conjunto de datos (convertidos en números enteros para que sean más legibles para los humanos):
Determinismo cuando se lee
En esta sección se explica la garantía determinista de tfds.load
.
Con shuffle_files=False
(predeterminado)
De forma predeterminada, TFDS produce ejemplos de forma determinista (shuffle_files=False
)
Para mejorar el rendimiento, TFDS lee varias particiones al mismo tiempo con tf.data.Dataset.interleave. En este ejemplo, vemos que TFDS cambia a la partición 2 después de leer 16 ejemplos (..., 14, 15, 1251, 1252, ...
). A continuación, tiene más información sobre la intercalación.
De manera similar, la API de subdivisión también es determinista:
Si está entrenando para más de una época, no se recomienda la configuración anterior ya que todas las épocas leerán las particiones en el mismo orden (por lo que la aleatoriedad se limita al tamaño del búfer ds = ds.shuffle(buffer)
).
Con shuffle_files=True
Con shuffle_files=True
, las particiones se aleatorizan para cada época, por lo que la lectura ya no es determinista.
Nota: Al configurar shuffle_files=True
también se desactiva deterministic
en tf.data.Options
para mejorar el rendimiento. Por lo tanto, incluso los conjuntos de datos pequeños que solo tienen una partición (como mnist) se vuelven no deterministas.
Vea la receta a continuación para obtener una aleatorización de archivos determinista.
Advertencia de determinismo: intercalar args
Al cambiar read_config.interleave_cycle_length
, read_config.interleave_block_length
cambiará el orden de los ejemplos.
TFDS depende de tf.data.Dataset.interleave para cargar solo unas pocas particiones a la vez, lo que mejora el rendimiento y reduce el uso de memoria.
Solo se puede garantizar que el orden del ejemplo sea el mismo para un valor fijo de args intercalados. Consulte el documento de intercalación para entender qué cycle_length
y block_length
corresponden también.
cycle_length=16
,block_length=16
(predeterminado, igual que antes):
cycle_length=3
,block_length=2
:
En el segundo ejemplo, vemos que el conjunto de datos lee 2 ejemplos (block_length=2
) en una partición y luego cambia la siguiente partición. Cada 2 * 3 ejemplos (cycle_length=3
), vuelve a la primera partición shard0-ex0, shard0-ex1, shard1-ex0, shard1-ex1, shard2-ex0, shard2-ex1, shard0-ex2, shard0-ex3, shard1-ex2, shard1-ex3, shard2-ex2,...
).
Subdivisión y orden del ejemplo
Cada ejemplo tiene un id 0, 1, ..., num_examples-1
. La API de subdivisión selecciona un segmento de ejemplos (por ejemplo, train[:x]
selecciona 0, 1, ..., x-1
).
Sin embargo, dentro de la subdivisión, los ejemplos no se leen en orden ascendiente del id (debido a las particiones y la intercalación).
Más específicamente, ds.take(x)
y split='train[:x]'
no son equivalentes.
Esto se puede ver fácilmente en el ejemplo de intercalación anterior, donde los ejemplos provienen de diferentes particiones.
Después de los 16 ejemplos (block_length), .take(25)
cambia a la siguiente partición mientras que train[:25]
continúa leyendo ejemplos desde la primera partición.
Recetas
Obtenga una aleatorización de archivos determinista
Hay 2 formas de realizar una aleatorización determinista:
Configurar
shuffle_seed
. Nota: Se requiere cambiar el valor de iniciación en cada época; de lo contrario, se leerán las particiones en el mismo orden entre épocas.
Con
experimental_interleave_sort_fn
: brinda control total sobre qué particiones se leen y en qué orden, en lugar de depender del ordends.shuffle
.
Obtener una canalización determinista que se puede interrumpir
Éste es más complicado. No existe una solución fácil y satisfactoria.
En teoría, sin
ds.shuffle
y con una aleatorización determinista, debería ser posible contar los ejemplos que se han leído y deducir qué ejemplos se han leído en cada partición (como una función decycle_length
,block_length
y el orden de las particiones). Luego, se podría instertarskip
,take
para cada partición medianteexperimental_interleave_sort_fn
.Es probable que no sea posible con
ds.shuffle
sin volver a reproducir toda la canalización del entrenamiento. Sería necesario guardar el estado del búferds.shuffle
para deducir qué ejemplos se han leído. Los ejemplos podrían ser discontinuos (por ejemplo, que se leashard5_ex2
,shard5_ex4
pero noshard5_ex3
).Con
ds.shuffle
, una forma sería guardar todos los shards_ids/example_ids leídos (que se deducen detfds_id
) y luego deducir las instrucciones del archivo a partir de eso.
El caso más simple para 1.
es hacer que .skip(x).take(y)
coincida con train[x:x+y]
. Se debe hacer lo siguiente:
Establecer
cycle_length=1
(para que se lean las particiones secuencialmente)Establecer
shuffle_files=False
No usar
ds.shuffle
Solo debe usarse en conjuntos de datos grandes donde el entrenamiento es de solo 1 época. Los ejemplos se leerán en el orden aleatorio predeterminado.
Encuentrar qué particiones/ejemplos se leen para una subdivisión determinada
Con tfds.core.DatasetInfo
, se tiene acceso directo a las instrucciones de lectura.