Path: blob/master/site/pt-br/datasets/add_dataset.md
25115 views
Escrevendo datasets personalizados
Siga este guia para criar um novo dataset (no TFDS ou no seu próprio repositório).
Confira nossa lista de datasets para ver se o dataset que você procura já está presente.
Resumo
A maneira mais fácil de escrever um novo dataset é usar o TFDS CLI:
Para usar o novo dataset com tfds.load('my_dataset')
:
tfds.load
vai automaticamente detectar e carregar o dataset gerado em~/tensorflow_datasets/my_dataset/
(por exemplo, viatfds build
).Alternativamente, você pode explicitamente importar (
import my.project.datasets.my_dataset
) para registrar seu dataset:
Visão geral
Datasets são distribuídos em todos os tipos de formatos e em todos os tipos de lugares, e nem sempre são armazenados num formato que esteja pronto para alimentar um pipeline de aprendizado de máquina. Então temos o TFDS.
O TFDS processa esses datasets para um formato padrão (dados externos -> arquivos serializados), que podem então ser carregados como pipeline de aprendizado de máquina (arquivos serializados -> tf.data.Dataset
). A serialização é feita apenas uma vez. O acesso subsequente vai ler esses arquivos pré-processados diretamente.
A maior parte do pré-processamento é feita automaticamente. Cada dataset implementa uma subclasse de tfds.core.DatasetBuilder
, que especifica:
De onde vêm os dados (ou seja, suas URLs);
Como se apresenta o dataset (ou seja, suas características);
Como os dados devem ser divididos (ex.
TRAIN
eTEST
);e os exemplos individuais no dataset.
Escreva seu dataset
Modelo padrão: tfds new
Use o TFDS CLI para gerar os arquivos modelo Python necessários.
Este comando irá gerar uma nova pasta my_dataset/
com a seguinte estrutura:
Aqui, procure por TODO(my_dataset)
aqui e modifique de acordo.
Exemplo de dataset
Todos os datasets são subclasses implementadas de tfds.core.DatasetBuilder
, que contém a maior parte do código basico. Essa classe suporta:
Datasets pequenos/médios que podem ser gerados numa única máquina (este tutorial).
Datasets muito grandes que requerem geração distribuída (usando o Apache Beam, veja nosso guia para datasets gigantes)
Aqui está um exemplo mínimo de um construtor de dataset baseado em tfds.core.GeneratorBasedBuilder
:
Observe que, para alguns formatos de dados específicos, fornecemos construtores de datasets prontos para uso para cuidar da maior parte do processamento de dados.
Vamos ver, em detalhes, os 3 métodos abstratos que precisamos sobrescrever.
_info
: metadados do dataset
_info
retorna tfds.core.DatasetInfo
contendo os metadados do dataset.
A maior parte dos campos deve ser autoexplicativa. Algumas explicações:
features
: especifica a estrutura do dataset, formato, ... Suporta tipos de dados complexos (áudio, vídeo, sequências aninhadas, ...). Para mais informações, veja os guias características disponíveis ou o guia do conector de características.disable_shuffling
: Veja a seção Mantenha a ordem do dataset.
Escrevendo o arquivo BibText
CITATIONS.bib
:
Pesquise no site do dataset por instruções de citação (use no formato BibTex).
Para artigos arXiv: encontre o artigo e clique no link
BibText
no lado direito.Encontre o artigo no Google Scholar e clique nas aspas duplas abaixo do título e no pop-up, clique em
BibTeX
.Se não houver nenhum documento associado (por exemplo, há apenas um site), você pode usar o Editor Online do BibTeX para criar uma entrada BibTeX personalizada (o menu suspenso tem um tipo de entrada
Online
).
Atualizando o arquivo TAGS.txt
:
Todas as tags permitidas são pré-preenchidas no arquivo gerado.
Remova todas as tags que não se aplicam ao dataset.
Tags válidas estão listadas em tensorflow_datasets/core/valid_tags.txt.
Para acrescentar uma tag a essa lista, envie um pull request.
Mantenha a ordem do dataset
Por padrão, os registros dos datasets são embaralhados quando armazenados para tornar a distribuição das classes mais uniforme no dataset, uma vez que muitas vezes os registros pertencentes à mesma classe são contíguos. Para especificar que o dataset deve ser classificado pela chave gerada fornecida por _generate_examples
o campo disable_shuffling
deve ser definido como True
. Por padrão, está definido como False
.
Tenha em mente que desabilitar o embaralhamento tem um impacto no desempenho, já que os fragmentos não podem mais ser lidos em paralelo.
_split_generators
: baixa e divide dados
Baixando e extraindo dados de fonte
A maioria dos datasets precisa baixar dados da web. Isto é feito usando o argumento de entrada tfds.download.DownloadManager
de _split_generators
. dl_manager
possui os seguintes métodos:
download
: suportahttp(s)://
,ftp(s)://
extract
: atualmente suporta arquivos.zip
,.gz
e.tar
.download_and_extract
: O mesmo quedl_manager.extract(dl_manager.download(urls))
Todos esses métodos retornam tfds.core.Path
(aliases para epath.Path
), que são objetos semelhantes a pathlib.Path.
Esses métodos suportam estruturas aninhadas arbitrárias (list
, dict
), como:
Download e extração manuais
Alguns dados não podem ser baixados automaticamente (por exemplo, requerem um login); neste caso, o usuário baixará manualmente os dados da fonte e os colocará em manual_dir/
(o padrão é ~/tensorflow_datasets/downloads/manual/
).
Os arquivos podem depois ser acessados através de dl_manager.manual_dir
:
A localização manual_dir
pode ser personalizada com tfds build --manual_dir=
ou usando tfds.download.DownloadConfig
.
Leia o arquivo diretamente
dl_manager.iter_archive
lê arquivos sequencialmente sem extraí-los. Isso pode economizar espaço de armazenamento e melhorar o desempenho em alguns sistemas de arquivos.
fobj
tem os mesmos métodos with open('rb') as fobj:
(por exemplo, fobj.read()
)
Especificando divisões em datasets
Se o dataset vier com divisões (splits) predefinidas (por exemplo, MNIST
tem as divisões train
e test
), mantenha-as. Caso contrário, especifique apenas uma única divisão all
. Os usuários podem criar dinamicamente suas próprias subdivisões com a subsplit API (por exemplo split='train[80%:]'
). Observe que qualquer string alfabética pode ser usada como nome de divisão, exceto o já mencionado all
.
_generate_examples
: gerador de exemplos
_generate_examples
gera os exemplos para cada divisão dos dados de fonte.
Este método normalmente irá ler artefatos do dataset fonte (por exemplo, um arquivo CSV) e produzir tuplas (key, feature_dict)
:
key
: identificador de exemplo. Usado para embaralhar deterministicamente os exemplos usandohash(key)
ou para classificar por chave quando o embaralhamento estiver desativado (veja a seção Mantenha a ordem do dataset). Deve ser:exclusiva: se dois exemplos usarem a mesma chave, uma exceção será gerada.
determinístic : não deve depender da ordem
download_dir
,os.path.listdir
,... Gerar os dados duas vezes deve produzir a mesma chave.comparável: se o embaralhamento estiver desabilitado, a chave será usada para classificar o dataset.
feature_dict
: umdict
contendo os valores de exemplo.A estrutura deve corresponder à estrutura
features=
definida emtfds.core.DatasetInfo
.Tipos de dados complexos (imagem, vídeo, áudio,...) serão codificados automaticamente.
Cada característica geralmente aceita múltiplos tipos de entrada (por exemplo, vídeo aceita
/path/to/vid.mp4
,np.array(shape=(l, h, w, c))
,List[paths]
,List[np.array(shape=(h, w, c)]
,List[img_bytes]
,...)Consulte o guia do conector de características para mais informações.
Importante: ao processar valores booleanos de strings ou números inteiros, use a função util tfds.core.utils.bool_utils.parse_bool
para evitar erros de processamento (por exemplo, bool("False") == True
).
Acesso a arquivos e tf.io.gfile
Para oferecer suporte a sistemas de armazenamento em nuvem, evite o uso das operações de E/S nativas do Python.
Em vez disso, o dl_manager
retorna objetos similares a pathlib diretamente compatíveis com o armazenamento do Google Cloud:
Como alternativa, use a API tf.io.gfile
em vez da API nativa para realizar operações com arquivos:
open
->tf.io.gfile.GFile
os.rename
->tf.io.gfile.rename
...
Deve-se dar preferência a Pathlib em vez de tf.io.gfile
(veja rational.
Dependências extras
Alguns datasets requerem dependências adicionais do Python apenas durante a geração. Por exemplo, o dataset SVHN usa scipy
para carregar alguns dados.
Se você estiver adicionando um dataset ao repositório TFDS, use tfds.core.lazy_imports
para manter o pacote tensorflow-datasets
pequeno. Os usuários instalarão dependências adicionais somente conforme necessário.
Para usar lazy_imports
:
Adicione uma entrada para seu dataset em
DATASET_EXTRAS
emsetup.py
. Isso permitirá que os usuários possam fazer, por exemplo,pip install 'tensorflow-datasets[svhn]'
para instalar as dependências extras.Adicione uma entrada para sua importação ao
LazyImporter
e aoLazyImportsTest
.Use
tfds.core.lazy_imports
para acessar a dependência (por exemplo,tfds.core.lazy_imports.scipy
) em seuDatasetBuilder
.
Dados corrompidos
Alguns conjuntos de dados não estão perfeitamente limpos e contêm alguns dados corrompidos (por exemplo, as imagens estão em arquivos JPEG, mas algumas podem ser JPEGs inválidos). Esses exemplos devem ser ignorados, mas deixe uma nota na descrição do dataset sobre quantos exemplos foram descartados e por quê.
Configuração/variantes do dataset (tfds.core.BuilderConfig)
Alguns datasets podem ter múltiplas variantes ou opções de como os dados são pré-processados e gravados no disco. Por exemplo, cycle_gan tem uma configuração para cada par de objetos (cycle_gan/horse2zebra
, cycle_gan/monet2photo
,...).
Isto é feito através de tfds.core.BuilderConfig
:
Defina seu objeto de configuração como uma subclasse de
tfds.core.BuilderConfig
. Por exemplo,MyDatasetConfig
.Observação: Os valores padrão são obrigatórios devido a https://bugs.python.org/issue33129.
Defina o membro de classe
BUILDER_CONFIGS = []
emMyDataset
que lista osMyDatasetConfig
que o dataset expõe.Observação:
# pytype: disable=wrong-keyword-args
é necessário devido ao bug do Pytype com herança de classes de dados.Use
self.builder_config
emMyDataset
para configurar a geração de dados (por exemplo,shape=self.builder_config.img_size
). Isto pode incluir a definição de valores diferentes em_info()
ou a alteração do acesso aos dados de download.
Observações:
Cada configuração tem um nome exclusivo. O nome totalmente qualificado de uma configuração é
dataset_name/config_name
(por exemplo,coco/2017
).Se não for especificado, a primeira configuração em
BUILDER_CONFIGS
será usada (por exemplotfds.load('c4')
padrão parac4/en
)
Veja anli
para um exemplo de dataset que usa BuilderConfig
.
Versão
A versão pode ter dois significados diferentes:
A versão dos dados originais "external": por exemplo, COCO v2019, v2017,...
A versão "internal" do código TFDS: por exemplo, renomeia uma característica em
tfds.features.FeaturesDict
, corrige um bug em_generate_examples
Para atualizar um dataset:
Para atualização de dados "external": vários usuários podem querer acessar um ano/versão específico simultaneamente. Isso é feito usando um
tfds.core.BuilderConfig
por versão (por exemplo,coco/2017
,coco/2019
) ou uma classe por versão (por exemplo,Voc2007
,Voc2012
).Para atualização de código "internal": os usuários baixam apenas a versão mais recente. Qualquer atualização de código deve incrementar o atributo da classe
VERSION
(por exemplo, de1.0.0
paraVERSION = tfds.core.Version('2.0.0')
) após o versionamento semântico.
Adicione uma importação para registro
Não se esqueça de importar o módulo do dataset para o seu projeto __init__
para ser registrado automaticamente em tfds.load
, tfds.builder
.
Por exemplo, se você estiver contribuindo para tensorflow/datasets
, adicione o módulo import ao __init__.py
de seu subdiretório (por exemplo, image/__init__.py
.
Verifique para detectar problemas comuns de implementação
Dê uma olhada nos problemas comuns de implementação.
Teste seu dataset
Baixe e prepare: tfds build
Para gerar o dataset, execute tfds build
no diretório my_dataset/
:
Alguns sinalizadores úteis para desenvolvimento:
--pdb
: entra no modo de depuração se uma exceção for levantada.--overwrite
: exclui os arquivos existentes se o dataset já tiver sido gerado.--max_examples_per_split
: gera apenas os primeiros X exemplos (padrão 1), em vez do dataset completo.--register_checksums
: registra checksums das URLs baixadas. Só deve ser usado durante o desenvolvimento.
Consulte a documentação da CLI para uma lista completa de sinalizadores.
Checksums
Recomenda-se registrar os checksums dos seus datasets para garantir o determinismo, ajudar com a documentação,... Isto é feito gerando o dataset com o --register_checksums
(veja a seção anterior).
Se você estiver liberando seus dataset através do PyPI, não esqueça de exportar os arquivos checksums.tsv
(por exemplo, no package_data
do seu setup.py
).
Faça testes de unidade no seu dataset
tfds.testing.DatasetBuilderTestCase
é um TestCase
base para exercitar um dataset por completo. Ele usa "dados fictícios" como dados de teste que imitam a estrutura do dataset fonte.
Os dados de teste devem ser colocados no diretório
my_dataset/dummy_data/
e devem imitar os artefatos do dataset fonte baixados e extraídos. Pode ser criado manualmente ou automaticamente com um script (exemplo de script).Certifique-se de usar dados diferentes nas divisões de dados de teste, pois o teste falhará se as divisões do dataset se sobrepuserem.
Os dados de teste não devem conter nenhum material protegido por direitos autorais. Em caso de dúvida, não crie os dados utilizando material do dataset original.
Execute o comando a seguir para testar o dataset.
Envie feedback
Tentamos continuamente melhorar o workflow de criação de datasets, mas só poderemos fazê-lo se estivermos cientes dos problemas. Quais problemas ou erros você encontrou ao criar o dataset? Houve alguma parte que foi confusa ou não funcionou de primeira?
Compartilhe seu feedback no GitHub.