O Google I/O é um embrulho! Fique por dentro das sessões do TensorFlow Ver sessões

Separar e fatiar

Todos os conjuntos de dados TFDS expõem várias divisões de dados (por exemplo 'train' , 'test' ) que podem ser exploradas no catálogo .

Além das divisões de conjuntos de dados "oficiais", o TFDS permite selecionar fatia(s) de divisão(ões) e várias combinações.

API de fatiamento

As instruções de fatiamento são especificadas em tfds.load ou tfds.DatasetBuilder.as_dataset por meio de split= kwarg.

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

A divisão pode ser:

  • Divisão simples ( 'train' , 'test' ): Todos os exemplos dentro da divisão selecionada.
  • Fatias : As fatias têm a mesma semântica que a notação de fatias python . As fatias podem ser:
    • Absolute ( 'train[123:450]' , train[:4000] ): (veja a nota abaixo para advertência sobre a ordem de leitura)
    • Percent ( 'train[:75%]' , 'train[25%:75%]' ): Divida os dados completos em 100 fatias pares. Se os dados não forem divisíveis por 100, alguns por cento podem conter exemplos adicionais.
    • Shard ( train[:4shard] , train[4shard] ): Selecione todos os exemplos no fragmento solicitado. (consulte info.splits['train'].num_shards para obter o número de fragmentos da divisão)
  • União de divisões ( 'train+test' , 'train[:25%]+test' ): As divisões serão intercaladas.
  • Conjunto de dados completo ( 'all' ): 'all' é um nome de divisão especial correspondente à união de todas as divisões (equivalente a 'train+test+...' ).
  • Lista de divisões ( ['train', 'test'] ): Vários tf.data.Dataset são retornados separadamente:
# Returns both train and test split separately
train_ds, test_ds = tfds.load('mnist', split=['train', 'test[:50%]'])

tfds.even_splits e treinamento multi-host

tfds.even_splits gera uma lista de subdivisões não sobrepostas do mesmo tamanho.

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

Isso pode ser particularmente útil ao treinar em uma configuração distribuída, onde cada host deve receber uma fatia dos dados originais.

Com Jax , isso pode ser simplificado ainda mais 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 é um alias simples 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 aceita em qualquer valor de divisão como entrada (por exemplo 'train[75%:]+test' )

Fatiar e metadados

É possível obter informações adicionais sobre as divisões/subdivisões ( num_examples , file_instructions ,...) usando as informações do conjunto de dados:

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

Validação cruzada

Exemplos de validação cruzada de 10 vezes usando a API de string:

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

Os conjuntos de dados de validação serão cada um 10%: [0%:10%] , [10%:20%] , ..., [90%:100%] . E os conjuntos de dados de treinamento serão os 90% complementares: [10%:100%] (para um conjunto de validação correspondente de [0%:10%] ), `[0%:10%]

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

tfds.core.ReadInstruction e arredondamento

Em vez de str , é possível passar divisões como tfds.core.ReadInstruction :

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

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

unit pode ser:

  • abs : corte absoluto
  • % : Porcentagem de fatiamento
  • shard : fatiamento de fragmentos

tfds.ReadInstruction também tem um argumento de arredondamento. Se o número de exemplo no conjunto de dados não for dividido uniformemente por 100 :

  • rounding='closest' (padrão): Os exemplos restantes são distribuídos entre os percentuais, portanto, alguns percentuais podem conter exemplos adicionais.
  • rounding='pct1_dropremainder' : Os exemplos restantes são descartados, mas isso garante que todos os percentuais contenham exatamente o mesmo número de exemplos (por exemplo: len(5%) == 5 * len(1%) ).

Reprodutibilidade e determinismo

Durante a geração, para uma determinada versão do conjunto de dados, o TFDS garante que os exemplos sejam embaralhados deterministicamente no disco. Portanto, gerar o conjunto de dados duas vezes (em 2 computadores diferentes) não alterará a ordem do exemplo.

Da mesma forma, a API de subdivisão sempre selecionará o mesmo set de exemplos, independentemente da plataforma, arquitetura etc. Isso significa set('train[:20%]') == set('train[:10%]') + set('train[10%:20%]') .

No entanto, a ordem em que os exemplos são lidos pode não ser determinística. Isso depende de outros parâmetros (por exemplo, se shuffle_files=True ).