Construtores de conjuntos de dados específicos de formato

Este guia documenta todos os construtores de conjuntos de dados específicos de formato atualmente disponíveis no TFDS.

Os construtores de conjuntos de dados específicos de formato são subclasses de tfds.core.GeneratorBasedBuilder que cuidam da maior parte do processamento de dados para um formato de dados específico.

Conjuntos de dados baseados em tf.data.Dataset

Se você deseja criar um conjunto de dados TFDS a partir de um conjunto de dados que está no formato tf.data.Dataset ( referência ), você pode usar tfds.dataset_builders.TfDataBuilder (consulte a documentação da API ).

Imaginamos dois usos típicos desta classe:

  • Criação de conjuntos de dados experimentais em um ambiente semelhante a um notebook
  • Definindo um construtor de conjunto de dados no código

Criando um novo conjunto de dados a partir de um notebook

Suponha que você esteja trabalhando em um notebook, carregou alguns dados como tf.data.Dataset , aplicou diversas transformações (mapa, filtro, etc) e agora deseja armazenar esses dados e compartilhá-los facilmente com colegas de equipe ou carregá-los em outros notebooks. Em vez de definir uma nova classe de construtor de conjunto de dados, você também pode instanciar um tfds.dataset_builders.TfDataBuilder e chamar download_and_prepare para armazenar seu conjunto de dados como um conjunto de dados TFDS.

Por ser um conjunto de dados TFDS, você pode versioná-lo, usar configurações, ter divisões diferentes e documentá-lo para facilitar o uso posterior. Isso significa que você também precisa informar ao TFDS quais são os recursos do seu conjunto de dados.

Aqui está um exemplo fictício de como você pode usá-lo.

import tensorflow as tf
import tensorflow_datasets as tfds

my_ds_train = tf.data.Dataset.from_tensor_slices({"number": [1, 2, 3]})
my_ds_test = tf.data.Dataset.from_tensor_slices({"number": [4, 5]})

# Optionally define a custom `data_dir`.
# If None, then the default data dir is used.
custom_data_dir = "/my/folder"

# Define the builder.
single_number_builder = tfds.dataset_builders.TfDataBuilder(
    name="my_dataset",
    config="single_number",
    version="1.0.0",
    data_dir=custom_data_dir,
    split_datasets={
        "train": my_ds_train,
        "test": my_ds_test,
    },
    features=tfds.features.FeaturesDict({
        "number": tfds.features.Scalar(dtype=tf.int64),
    }),
    description="My dataset with a single number.",
    release_notes={
        "1.0.0": "Initial release with numbers up to 5!",
    }
)

# Make the builder store the data as a TFDS dataset.
single_number_builder.download_and_prepare()

O método download_and_prepare irá iterar sobre a entrada tf.data.Dataset s e armazenar o conjunto de dados TFDS correspondente em /my/folder/my_dataset/single_number/1.0.0 , que conterá as divisões de treinamento e teste.

O argumento config é opcional e pode ser útil se você quiser armazenar configurações diferentes no mesmo conjunto de dados.

O argumento data_dir pode ser usado para armazenar o conjunto de dados TFDS gerado em uma pasta diferente, por exemplo, em sua própria sandbox, se você não quiser compartilhar isso com outras pessoas (ainda). Observe que ao fazer isso, você também precisa passar data_dir para tfds.load . Se o argumento data_dir não for especificado, o diretório de dados TFDS padrão será usado.

Carregando seu conjunto de dados

Depois que o conjunto de dados TFDS for armazenado, ele poderá ser carregado a partir de outros scripts ou por colegas de equipe se eles tiverem acesso aos dados:

# If no custom data dir was specified:
ds_test = tfds.load("my_dataset/single_number", split="test")

# When there are multiple versions, you can also specify the version.
ds_test = tfds.load("my_dataset/single_number:1.0.0", split="test")

# If the TFDS was stored in a custom folder, then it can be loaded as follows:
custom_data_dir = "/my/folder"
ds_test = tfds.load("my_dataset/single_number:1.0.0", split="test", data_dir=custom_data_dir)

Adicionando uma nova versão ou configuração

Depois de iterar ainda mais no seu conjunto de dados, você pode ter adicionado ou alterado algumas das transformações dos dados de origem. Para armazenar e compartilhar este conjunto de dados, você pode armazená-lo facilmente como uma nova versão.

def add_one(example):
  example["number"] = example["number"] + 1
  return example

my_ds_train_v2 = my_ds_train.map(add_one)
my_ds_test_v2 = my_ds_test.map(add_one)

single_number_builder_v2 = tfds.dataset_builders.TfDataBuilder(
    name="my_dataset",
    config="single_number",
    version="1.1.0",
    data_dir=custom_data_dir,
    split_datasets={
        "train": my_ds_train_v2,
        "test": my_ds_test_v2,
    },
    features=tfds.features.FeaturesDict({
        "number": tfds.features.Scalar(dtype=tf.int64, doc="Some number"),
    }),
    description="My dataset with a single number.",
    release_notes={
        "1.1.0": "Initial release with numbers up to 6!",
        "1.0.0": "Initial release with numbers up to 5!",
    }
)

# Make the builder store the data as a TFDS dataset.
single_number_builder_v2.download_and_prepare()

Definindo uma nova classe do construtor de conjunto de dados

Você também pode definir um novo DatasetBuilder baseado nesta classe.

import tensorflow as tf
import tensorflow_datasets as tfds

class MyDatasetBuilder(tfds.dataset_builders.TfDataBuilder):
  def __init__(self):
    ds_train = tf.data.Dataset.from_tensor_slices([1, 2, 3])
    ds_test = tf.data.Dataset.from_tensor_slices([4, 5])
    super().__init__(
        name="my_dataset",
        version="1.0.0",
        split_datasets={
            "train": ds_train,
            "test": ds_test,
        },
        features=tfds.features.FeaturesDict({
            "number": tfds.features.Scalar(dtype=tf.int64),
        }),
        config="single_number",
        description="My dataset with a single number.",
        release_notes={
            "1.0.0": "Initial release with numbers up to 5!",
        })

Construtor de Croissants

O formato

Croissant 🥐 é um formato de alto nível para conjuntos de dados de aprendizado de máquina que combina metadados, descrições de arquivos de recursos, estrutura de dados e semântica de ML padrão em um único arquivo; ele funciona com conjuntos de dados existentes para torná-los mais fáceis de encontrar, usar e oferecer suporte com ferramentas.

Croissant baseia-se no schema.org e em seu vocabulário sc:Dataset , um formato amplamente utilizado para representar conjuntos de dados na Web e torná-los pesquisáveis.

CroissantBuilder

Um CroissantBuilder define um conjunto de dados TFDS baseado em um arquivo de metadados Croissant 🥐; cada um dos record_set_ids especificados resultará em um ConfigBuilder separado.

Por exemplo, para inicializar um CroissantBuilder para o conjunto de dados MNIST usando sua definição Croissant 🥐 :

import tensorflow_datasets as tfds
builder = tfds.dataset_builders.CroissantBuilder(
    jsonld="https://raw.githubusercontent.com/mlcommons/croissant/main/datasets/0.8/huggingface-mnist/metadata.json",
    file_format='array_record',
)
builder.download_and_prepare()
ds = builder.as_data_source()
print(ds['default'][0])

CoNLL

O formato

CoNLL é um formato popular usado para representar dados de texto anotados.

Os dados formatados em CoNLL geralmente contêm um token com suas anotações linguísticas por linha; dentro da mesma linha, as anotações geralmente são separadas por espaços ou tabulações. As linhas vazias representam os limites das frases.

Considere como exemplo a seguinte frase do conjunto de dados conll2003 , que segue o formato de anotação CoNLL:

U.N. NNP I-NP I-ORG official
NN I-NP O
Ekeus NNP I-NP I-PER
heads VBZ I-VP O
for IN I-PP O
Baghdad NNP I-NP
I-LOC . . O O

ConllDatasetBuilder

Para adicionar um novo conjunto de dados baseado em CoNLL ao TFDS, você pode basear sua classe de construtor de conjunto de dados em tfds.dataset_builders.ConllDatasetBuilder . Esta classe base contém código comum para lidar com as especificidades dos conjuntos de dados CoNLL (iterando sobre o formato baseado em colunas, listas pré-compiladas de recursos e tags, ...).

tfds.dataset_builders.ConllDatasetBuilder implementa um GeneratorBasedBuilder específico do CoNLL. Consulte a classe a seguir como um exemplo mínimo de um construtor de conjunto de dados CoNLL:

from tensorflow_datasets.core.dataset_builders.conll import conll_dataset_builder_utils as conll_lib
import tensorflow_datasets.public_api as tfds

class MyCoNNLDataset(tfds.dataset_builders.ConllDatasetBuilder):
  VERSION = tfds.core.Version('1.0.0')
  RELEASE_NOTES = {'1.0.0': 'Initial release.'}

  # conllu_lib contains a set of ready-to-use CONLL-specific configs.
  BUILDER_CONFIGS = [conll_lib.CONLL_2003_CONFIG]

  def _info(self) -> tfds.core.DatasetInfo:
    return self.create_dataset_info(
        # ...
    )

  def _split_generators(self, dl_manager):
    path = dl_manager.download_and_extract('https://data-url')

    return {'train': self._generate_examples(path=path / 'train.txt'),
            'test': self._generate_examples(path=path / 'train.txt'),
    }

Quanto aos construtores de conjuntos de dados padrão, é necessário substituir os métodos de classe _info e _split_generators . Dependendo do conjunto de dados, pode ser necessário atualizar também conll_dataset_builder_utils.py para incluir os recursos e a lista de tags específicas do seu conjunto de dados.

O método _generate_examples não deve exigir substituição adicional, a menos que seu conjunto de dados precise de implementação específica.

Exemplos

Considere conll2003 como um exemplo de conjunto de dados implementado usando o construtor de conjunto de dados específico do CoNLL.

CLI

A maneira mais fácil de escrever um novo conjunto de dados baseado em CoNLL é usar o TFDS CLI :

cd path/to/my/project/datasets/
tfds new my_dataset --format=conll   # Create `my_dataset/my_dataset.py` CoNLL-specific template files

CoNLL-U

O formato

CoNLL-U é um formato popular usado para representar dados de texto anotados.

CoNLL-U aprimora o formato CoNLL adicionando uma série de recursos, como suporte para palavras com vários tokens . Os dados formatados em CoNLL-U geralmente contêm um token com suas anotações linguísticas por linha; dentro da mesma linha, as anotações geralmente são separadas por caracteres de tabulação únicos. As linhas vazias representam os limites das frases.

Normalmente, cada linha de palavra anotada em CoNLL-U contém os seguintes campos, conforme relatado na documentação oficial :

  • ID: Índice da palavra, inteiro começando em 1 para cada nova frase; pode ser um intervalo para tokens multipalavras; pode ser um número decimal para nós vazios (os números decimais podem ser menores que 1, mas devem ser maiores que 0).
  • FORMA: Forma de palavra ou símbolo de pontuação.
  • LEMA: Lema ou radical da forma da palavra.
  • UPOS: etiqueta universal de classe gramatical.
  • XPOS: tag de classe gramatical específica do idioma; sublinhado se não estiver disponível.
  • TALENTOS: Lista de características morfológicas do inventário de características universais ou de uma extensão específica de idioma definida; sublinhado se não estiver disponível.
  • HEAD: Cabeçalho da palavra atual, que é um valor de ID ou zero (0).
  • DEPREL: Relação de dependência universal com o HEAD (raiz se HEAD = 0) ou um subtipo definido de um idioma específico.
  • DEPS: gráfico de dependência aprimorado na forma de uma lista de pares head-deprel.
  • MISC: Qualquer outra anotação.

Considere como exemplo a seguinte frase anotada CoNLL-U da documentação oficial :

1-2    vámonos   _
1      vamos     ir
2      nos       nosotros
3-4    al        _
3      a         a
4      el        el
5      mar       mar

ConllUDatasetBuilder

Para adicionar um novo conjunto de dados baseado em CoNLL-U ao TFDS, você pode basear sua classe de construtor de conjunto de dados em tfds.dataset_builders.ConllUDatasetBuilder . Esta classe base contém código comum para lidar com as especificidades dos conjuntos de dados CoNLL-U (iterando sobre o formato baseado em colunas, listas pré-compiladas de recursos e tags, ...).

tfds.dataset_builders.ConllUDatasetBuilder implementa um GeneratorBasedBuilder específico do CoNLL-U. Consulte a classe a seguir como um exemplo mínimo de um construtor de conjunto de dados CoNLL-U:

from tensorflow_datasets.core.dataset_builders.conll import conllu_dataset_builder_utils as conllu_lib
import tensorflow_datasets.public_api as tfds

class MyCoNNLUDataset(tfds.dataset_builders.ConllUDatasetBuilder):
  VERSION = tfds.core.Version('1.0.0')
  RELEASE_NOTES = {'1.0.0': 'Initial release.'}

  # conllu_lib contains a set of ready-to-use features.
  BUILDER_CONFIGS = [
      conllu_lib.get_universal_morphology_config(
          language='en',
          features=conllu_lib.UNIVERSAL_DEPENDENCIES_FEATURES,
      )
  ]

  def _info(self) -> tfds.core.DatasetInfo:
    return self.create_dataset_info(
        # ...
    )

  def _split_generators(self, dl_manager):
    path = dl_manager.download_and_extract('https://data-url')

    return {
        'train':
            self._generate_examples(
                path=path / 'train.txt',
                # If necessary, add optional custom processing (see conllu_lib
                # for examples).
                # process_example_fn=...,
            )
    }

Quanto aos construtores de conjuntos de dados padrão, é necessário substituir os métodos de classe _info e _split_generators . Dependendo do conjunto de dados, pode ser necessário atualizar também conllu_dataset_builder_utils.py para incluir os recursos e a lista de tags específicas do seu conjunto de dados.

O método _generate_examples não deve exigir substituição adicional, a menos que seu conjunto de dados precise de implementação específica. Observe que, se o seu conjunto de dados exigir pré-processamento específico - por exemplo, se considerar recursos de dependência universal não clássicos - talvez seja necessário atualizar o atributo process_example_fn da sua função generate_examples (veja o conjunto de dados xtreme_pos como exemplo).

Exemplos

Considere os seguintes conjuntos de dados, que usam o construtor de conjunto de dados específico CoNNL-U, como exemplos:

CLI

A maneira mais fácil de escrever um novo conjunto de dados baseado em CoNLL-U é usar o TFDS CLI :

cd path/to/my/project/datasets/
tfds new my_dataset --format=conllu   # Create `my_dataset/my_dataset.py` CoNLL-U specific template files