Path: blob/master/site/pt-br/datasets/common_gotchas.md
25115 views
Problemas comuns de implementação
Esta página descreve os problemas comuns de implementação ao implementar um novo dataset.
O SplitGenerator
legado deve ser evitado
A antiga API tfds.core.SplitGenerator
está obsoleta.
Deve ser substituído por:
Justificativa: a nova API é menos detalhada e mais explícita. A API antiga será removida na versão futura.
Novos datasets devem armazenados em uma pasta própria
Ao adicionar um dataset dentro do repositório tensorflow_datasets/
, certifique-se de seguir a estrutura "dataset como pasta" (todas as checksums, dados de teste, código de implementação, etc. armazenados numa pasta).
Datasets antigos (ruim):
<category>/<ds_name>.py
Novos datasets (bom):
<category>/<ds_name>/<ds_name>.py
Use a CLI do TFDS (tfds new
ou gtfds new
para googlers) para gerar o modelo.
Justificativa: A estrutura antiga exigia caminhos absolutos para checksums, dados falsos e distribuía os arquivos do datasets em muitos lugares. Dificultava a implementação de datasets fora do repositório TFDS. Para manter a consistência, a nova estrutura deve ser usada em todos os lugares.
Listas de descrição devem ser formatadas como markdown
A str
DatasetInfo.description
é formatada como markdown. As listas em markdown requerem uma linha vazia antes do primeiro item:
Justificativa: uma descrição mal formatada cria artefatos visuais em nossa documentação de catálogo. Sem as linhas vazias, o texto acima seria renderizado como:
Some text. 1. Item 1 2. Item 1 3. Item 1 Some other text
Nomes ClassLabel
Ao usar tfds.features.ClassLabel
, tente fornecer rótulos str
legíveis por humanos com names=
ou names_file=
(em vez de num_classes=10
).
Justificativa: rótulos legíveis por humanos são usados em muitos lugares:
Permitem o uso de
str
diretamente em_generate_examples
:yield {'label': 'dog'}
Expostos nos usuários como
info.features['label'].names
(método de conversão.str2int('dog')
,... também disponível)Usados nos utilitários de visualização
tfds.show_examples
,tfds.as_dataframe
Formato de imagens
Ao usar tfds.features.Image
, tfds.features.Video
, se as imagens tiverem formato estático, elas deverão ser especificadas explicitamente:
Justificativa: permite inferência de forma estática (por exemplo, ds.element_spec['image'].shape
), que é necessário para a criação de lotes (um lote de imagens de formato desconhecido exigiria primeiro redimensioná-las).
Prefira um tipo mais específico em vez de tfds.features.Tensor
Quando possível, dê preferência aos tipos mais específicos tfds.features.ClassLabel
, tfds.features.BBoxFeatures
,... em vez do tipo genérico tfds.features.Tensor
.
Justificativa: além de serem mais semanticamente corretos, recursos específicos fornecem metadados adicionais aos usuários e são detectados por ferramentas.
Importações lazy no espaço global
As importações lazy não devem ser retiradas do espaço global. Por exemplo, fazer o seguinte é errado:
Justificativa: usar importações lazy no escopo global importaria o módulo para todos os usuários do tfds, anulando o propósito das importações lazy.
Computação dinâmica de divisões de treinamento/teste
Se o dataset não fornecer divisões oficiais, o TFDS também não deve fazer o mesmo. O seguinte deve ser evitado:
Justificativa: o TFDS tenta fornecer datasets tão próximos quanto os dados originais. A API subsplit (subdivisão) deve ser usada para permitir que os usuários criem dinamicamente as subdivisões que desejarem:
Guia de estilo Python
Dê preferência ao uso da API pathlib
Em vez da API tf.io.gfile
, é preferível usar a API pathlib. Todos os métodos dl_manager
retornam objetos do tipo pathlib compatíveis com GCS, S3,...
Justificativa: a API pathlib é uma API de arquivo orientada a objetos moderna que remove código boilerplate. Usar .read_text()
/ .read_bytes()
também garante que os arquivos sejam fechados corretamente.
Se o método não estiver usando self
, ele deve ser uma função
Se um método de classe não estiver usando self
, ele deveria ser uma função simples (definida fora da classe).
Justificativa: deixa explícito ao leitor que a função não tem efeitos colaterais, nem entrada/saída oculta:
Importações lazy em Python
Importamos de forma lazy grandes módulos como o TensorFlow. As importações lazy adiam a importação real do módulo para o primeiro uso do módulo. Portanto, os usuários que não precisam deste grande módulo jamais irão importá-lo.
Nos bastidores, a classe LazyModule
atua como uma fábrica, que só importará o módulo quando um atributo for acessado (__getattr__
).
Você também pode usá-lo convenientemente com um gerenciador de contexto: