Documentos testáveis
O TensorFlow usa DocTest para testar trechos de código em docstrings Python. O snippet deve ser um código Python executável. Para ativar o teste, acrescente a linha com >>>
(três colchetes à esquerda). Por exemplo, aqui está um trecho da função tf.concat
no arquivo de origem array_ops.py :
def concat(values, axis, name="concat"):
"""Concatenates tensors along one dimension.
...
>>> t1 = [[1, 2, 3], [4, 5, 6]]
>>> t2 = [[7, 8, 9], [10, 11, 12]]
>>> concat([t1, t2], 0)
<tf.Tensor: shape=(4, 3), dtype=int32, numpy=
array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]], dtype=int32)>
<... more description or code snippets ...>
Args:
values: A list of `tf.Tensor` objects or a single `tf.Tensor`.
axis: 0-D `int32` `Tensor`. Dimension along which to concatenate. Must be
in the range `[-rank(values), rank(values))`. As in Python, indexing for
axis is 0-based. Positive axis in the rage of `[0, rank(values))` refers
to `axis`-th dimension. And negative axis refers to `axis +
rank(values)`-th dimension.
name: A name for the operation (optional).
Returns:
A `tf.Tensor` resulting from concatenation of the input tensors.
"""
<code here>
Para avaliar a qualidade da documentação de referência, consulte a seção de exemplo do conselho dos documentos da API do TensorFlow 2 . (Esteja ciente de que o Rastreador de Tarefas nesta planilha não está mais em uso.)
Torne o código testável com DocTest
Atualmente, muitos docstrings usam crases (```) para identificar o código. Para tornar o código testável com DocTest:
- Remova os crases (```) e use os colchetes esquerdos (>>>) na frente de cada linha. Use (...) na frente de linhas continuadas.
- Adicione uma nova linha para separar trechos do DocTest do texto Markdown para renderizar corretamente em tensorflow.org.
Personalizações
O TensorFlow usa algumas personalizações na lógica doctest integrada:
- Ele não compara valores flutuantes como texto: os valores flutuantes são extraídos do texto e comparados usando
allclose
com tolerâncias liberaisatol
ertol
. Isto permite:- Documentos mais claros - Os autores não precisam incluir todas as casas decimais.
- Testes mais robustos - Mudanças numéricas na implementação subjacente nunca devem causar falha em um doctest.
- Ele só verifica a saída se o autor incluir a saída de uma linha. Isso permite documentos mais claros porque os autores geralmente não precisam capturar valores intermediários irrelevantes para evitar que sejam impressos.
Considerações de doutrina
- Geral : O objetivo do doctest é fornecer documentação e confirmar se a documentação funciona. Isso é diferente do teste de unidade. Então:
- Mantenha os exemplos simples.
- Evite resultados longos ou complicados.
- Use números redondos, se possível.
- Formato de saída : a saída do snippet precisa estar diretamente abaixo do código que está gerando a saída. Além disso, a saída na docstring deve ser exatamente igual à saída após a execução do código. Veja o exemplo acima. Além disso, verifique esta parte na documentação do DocTest. Se a saída exceder o limite de 80 linhas, você poderá colocar a saída extra na nova linha e o DocTest a reconhecerá. Por exemplo, veja os blocos multilinhas abaixo.
- Globais : Os módulos
`tf`
,np
eos
estão sempre disponíveis no DocTest do TensorFlow. Usar símbolos : No DocTest você pode acessar diretamente os símbolos definidos no mesmo arquivo. Para usar um símbolo que não está definido no arquivo atual, use a API pública do TensorFlow
tf.xxx
em vez dexxx
. Como você pode ver no exemplo abaixo,`random.normal`
é acessado via`tf.random.normal`
. Isso ocorre porque`random.normal`
não é visível emNewLayer
.def NewLayer(): """This layer does cool stuff. Example usage: >>> x = tf.random.normal((1, 28, 28, 3)) >>> new_layer = NewLayer(x) >>> new_layer <tf.Tensor: shape=(1, 14, 14, 3), dtype=int32, numpy=...> """
Valores de ponto flutuante : o doctest do TensorFlow extrai valores flutuantes das strings de resultados e compara usando
np.allclose
com tolerâncias razoáveis (atol=1e-6
,rtol=1e-6
). Dessa forma, os autores não precisam se preocupar com doutrinas excessivamente precisas que causam falhas devido a problemas numéricos. Basta colar o valor esperado.Saída não determinística : use reticências(
...
) para as partes incertas e o DocTest irá ignorar essa substring.x = tf.random.normal((1,))
print(x)
<tf.Tensor: shape=(1,), dtype=float32, numpy=..., dtype=float32)>
Blocos multilinhas : DocTest é rigoroso quanto à diferença entre uma instrução única e uma instrução multilinha. Observe o uso de (...) abaixo:
if x > 0:
print("X is positive")
model.compile(
loss="mse",
optimizer="adam")
Exceções : os detalhes da exceção são ignorados, exceto a exceção que é gerada. Veja isto para mais detalhes.
np_var = np.array([1, 2])
tf.keras.backend.is_keras_tensor(np_var)
Traceback (most recent call last):
ValueError: Unexpectedly found an instance of type `<class 'numpy.ndarray'>`.
Use uma cópia local do projeto do tf-doctest.
Algumas APIs no TensorFlow vêm de um projeto externo:
-
tf.estimator
(de tensorflow_estimator ) - tensorboard
tf.summary
) -
tf.keras.preprocessing
(de keras-preprocessing )
Se você estiver trabalhando em um projeto externo ou em APIs do TensorFlow hospedadas em um projeto externo, essas instruções não funcionarão, a menos que esse projeto tenha sua própria cópia local de tf_doctest
e você use essa cópia em vez da do TensorFlow.
Por exemplo: tf_estimator_doctest.py .
Teste em sua máquina local
Existem duas maneiras de testar o código na docstring localmente:
Se você estiver alterando apenas a docstring de uma classe/função/método, poderá testá-la passando o caminho desse arquivo para tf_doctest.py . Por exemplo:
python tf_doctest.py --file=<file_path>
Isso irá executá-lo usando sua versão instalada do TensorFlow. Para ter certeza de que você está executando o mesmo código que está testando:
- Use um pip install tf-nightly atualizado
pip install -U tf-nightly
- Rebaseie sua solicitação pull em um pull recente do branch master do TensorFlow .
- Use um pip install tf-nightly atualizado
Se você estiver alterando o código e a docstring de uma classe/função/método, precisará criar o TensorFlow a partir de source . Assim que estiver configurado para compilar a partir do código-fonte, você pode executar os testes:
bazel run //tensorflow/tools/docs:tf_doctest
ou
bazel run //tensorflow/tools/docs:tf_doctest -- --module=ops.array_ops
O
--module
é relativo atensorflow.python
.