Divide y rebana

Todos los conjuntos de datos TFDS exponen varias divisiones de datos (por ejemplo, 'train' , 'test' ) que se pueden explorar en el catálogo . Se puede utilizar cualquier cadena alfabética como nombre de división, excepto all (que es un término reservado que corresponde a la unión de todas las divisiones, ver más abajo).

Además de las divisiones de conjuntos de datos "oficiales", TFDS permite seleccionar porciones de divisiones y varias combinaciones.

API de corte

Las instrucciones de corte se especifican en tfds.load o tfds.DatasetBuilder.as_dataset mediante split= kwarg.

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

La división puede ser:

  • Nombres de división simples (una cadena como 'train' , 'test' , ...): todos los ejemplos dentro de la división seleccionada.
  • Sectores : Los sectores tienen la misma semántica que la notación de sectores de Python . Las rebanadas pueden ser:
    • Absoluto ( 'train[123:450]' , train[:4000] ): (consulte la nota a continuación para conocer las advertencias sobre el orden de lectura)
    • Porcentaje ( 'train[:75%]' , 'train[25%:75%]' ): divide los datos completos en porciones pares. Si los datos no son divisibles uniformemente, algún porcentaje podría contener ejemplos adicionales. Se admiten porcentajes fraccionarios.
    • Fragmento ( train[:4shard] , train[4shard] ): seleccione todos los ejemplos en el fragmento solicitado. (consulte info.splits['train'].num_shards para obtener el número de fragmentos de la división)
  • Unión de divisiones ( 'train+test' , 'train[:25%]+test' ): Las divisiones se entrelazarán juntas.
  • Conjunto de datos completo ( 'all' ): 'all' es un nombre de división especial correspondiente a la unión de todas las divisiones (equivalente a 'train+test+...' ).
  • Lista de divisiones ( ['train', 'test'] ): Múltiples tf.data.Dataset se devuelven por separado:
# Returns both train and test split separately
train_ds, test_ds = tfds.load('mnist', split=['train', 'test[:50%]'])

tfds.even_splits y capacitación multihost

tfds.even_splits genera una lista de subdivisiones no superpuestas del mismo tamaño.

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

Esto puede resultar especialmente útil cuando se entrena en un entorno distribuido, donde cada host debe recibir una porción de los datos originales.

Con Jax , esto se puede simplificar aún más usando 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 es un alias simple para:

# 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 acepta cualquier valor dividido como entrada (por ejemplo 'train[75%:]+test' )

Corte y metadatos

Es posible obtener información adicional sobre las divisiones/subdivisiones ( num_examples , file_instructions ,...) utilizando la información del conjunto de datos :

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

Validación cruzada

Ejemplos de validación cruzada 10 veces utilizando la API de cadena:

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

Cada uno de los conjuntos de datos de validación será del 10%: [0%:10%] , [10%:20%] , ..., [90%:100%] . Y cada uno de los conjuntos de datos de entrenamiento será el 90% complementario: [10%:100%] (para un conjunto de validación correspondiente de [0%:10%] ), `[0%:10%]

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

tfds.core.ReadInstruction y redondeo

En lugar de str , es posible pasar divisiones como tfds.core.ReadInstruction :

Por ejemplo, split = 'train[50%:75%] + test' es equivalente a:

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

unit puede ser:

  • abs : corte absoluto
  • % : Porcentaje de corte
  • shard : Rebanado de fragmentos

tfds.ReadInstruction también tiene un argumento de redondeo. Si el número de ejemplos en el conjunto de datos no se divide en partes iguales:

  • rounding='closest' (predeterminado): los ejemplos restantes se distribuyen entre el porcentaje, por lo que algún porcentaje puede contener ejemplos adicionales.
  • rounding='pct1_dropremainder' : los ejemplos restantes se eliminan, pero esto garantiza que todos los porcentajes contengan exactamente el mismo número de ejemplos (por ejemplo: len(5%) == 5 * len(1%) ).

Reproducibilidad y determinismo

Durante la generación, para una versión determinada del conjunto de datos, TFDS garantiza que los ejemplos se ordenen de manera determinista en el disco. Por lo tanto, generar el conjunto de datos dos veces (en 2 computadoras diferentes) no cambiará el orden del ejemplo.

De manera similar, la API de subdivisión siempre seleccionará el mismo set de ejemplos, independientemente de la plataforma, la arquitectura, etc. Esto significa set('train[:20%]') == set('train[:10%]') + set('train[10%:20%]') .

Sin embargo, el orden en que se leen los ejemplos puede no ser determinista. Esto depende de otros parámetros (por ejemplo, si shuffle_files=True ).