docstring testabili
TensorFlow utilizza DocTest per testare frammenti di codice in docstring Python. Lo snippet deve essere codice Python eseguibile. Per abilitare il test, anteporre alla riga >>>
(tre parentesi angolari). Ad esempio, ecco un estratto dalla funzione tf.concat
nel file sorgente 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>
Per valutare la qualità della documentazione di riferimento, vedere la sezione di esempio del consiglio sui documenti API di TensorFlow 2 . (Tieni presente che Task Tracker su questo foglio non è più in uso.)
Rendi il codice testabile con DocTest
Attualmente, molte docstring usano i backtick (```) per identificare il codice. Per rendere il codice testabile con DocTest:
- Rimuovi i backtick (```) e usa le parentesi di sinistra (>>>) davanti a ciascuna linea. Usa (...) davanti alle linee continue.
- Aggiungi una nuova riga per separare i frammenti di DocTest dal testo di Markdown per renderizzare correttamente su tensorflow.org.
Personalizzazioni
TensorFlow utilizza alcune personalizzazioni della logica doctest integrata:
- Non confronta i valori float come testo: i valori float vengono estratti dal testo e confrontati utilizzando
allclose
con liberalatol
ertol
tolleranze . Questo permette :- Documenti più chiari - Gli autori non devono includere tutte le cifre decimali.
- Test più robusti: le modifiche numeriche nell'implementazione sottostante non dovrebbero mai causare il fallimento di un doctest.
- Controlla l'output solo se l'autore include l'output per una riga. Ciò consente documenti più chiari perché gli autori di solito non hanno bisogno di acquisire valori intermedi irrilevanti per impedirne la stampa.
Considerazioni sulle stringhe di documenti
- In generale : l'obiettivo di doctest è fornire documentazione e confermare che la documentazione funzioni. Questo è diverso dal test unitario. Così:
- Mantieni gli esempi semplici.
- Evita output lunghi o complicati.
- Usa numeri rotondi, se possibile.
- Formato di output : l'output dello snippet deve essere direttamente al di sotto del codice che genera l'output. Inoltre, l'output nella docstring deve essere esattamente uguale a quello che sarebbe l'output dopo l'esecuzione del codice. Vedi l'esempio sopra. Inoltre, controlla questa parte nella documentazione di DocTest. Se l'output supera il limite di 80 righe, puoi inserire l'output aggiuntivo sulla nuova riga e DocTest lo riconoscerà. Ad esempio, vedere i blocchi multilinea di seguito.
- Globali : I
`tf`
,np
eos
sono sempre disponibili in DocTest di TensorFlow. Usa simboli : In DocTest puoi accedere direttamente ai simboli definiti nello stesso file. Per utilizzare un simbolo che non è definito nel file corrente, utilizzare l'API pubblica di TensorFlow
tf.xxx
invece dixxx
. Come puoi vedere nell'esempio seguente, si accede a ``random.normal`
tramite`tf.random.normal`
. Questo perché`random.normal`
non è visibile inNewLayer
.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=...> """
Valori in virgola mobile : il doctest TensorFlow estrae i valori float dalle stringhe dei risultati e li confronta utilizzando
np.allclose
con tolleranze ragionevoli (atol=1e-6
,rtol=1e-6
). In questo modo gli autori non devono preoccuparsi di docstring eccessivamente precisi che causano errori dovuti a problemi numerici. Basta incollare il valore previsto.Output non deterministico : usa ellipsis(
...
) per le parti incerte e DocTest ignorerà quella sottostringa.x = tf.random.normal((1,))
print(x)
<tf.Tensor: shape=(1,), dtype=float32, numpy=..., dtype=float32)>
Blocchi a più righe : DocTest è rigoroso sulla differenza tra un'istruzione a riga singola e una a più righe. Nota l'uso di (...) di seguito:
if x > 0:
print("X is positive")
model.compile(
loss="mse",
optimizer="adam")
Eccezioni : i dettagli dell'eccezione vengono ignorati tranne l'eccezione sollevata. Vedi questo per maggiori dettagli.
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'>`.
Usa una copia locale del progetto di tf-doctest.
Alcune API in TensorFlow provengono da un progetto esterno:
-
tf.estimator
(da tensorflow_estimator ) -
tf.summary
riassuntiva ) -
tf.keras.preprocessing
(da keras-preprocessing )
Se stai lavorando su un progetto esterno o su API TensorFlow che sono ospitate in un progetto esterno, queste istruzioni non funzioneranno a meno che quel progetto non abbia la propria copia locale di tf_doctest
e tu usi quella copia invece di TensorFlow.
Ad esempio: tf_estimator_doctest.py .
Prova sul tuo computer locale
Esistono due modi per testare il codice nella docstring in locale:
Se stai solo modificando la docstring di una classe/funzione/metodo, puoi testarla passando il percorso di quel file a tf_doctest.py . Per esempio:
python tf_doctest.py --file=<file_path>
Questo lo eseguirà utilizzando la versione installata di TensorFlow. Per essere sicuro di eseguire lo stesso codice che stai testando:
- Utilizzare un aggiornamento pip tf-nightly
pip install -U tf-nightly
- Ribasare la tua richiesta pull su un pull recente dal ramo principale di TensorFlow .
- Utilizzare un aggiornamento pip tf-nightly
Se stai modificando il codice e la docstring di una classe/funzione/metodo, dovrai compilare TensorFlow da source . Una volta configurato per la compilazione dal sorgente, è possibile eseguire i test:
bazel run //tensorflow/tools/docs:tf_doctest
o
bazel run //tensorflow/tools/docs:tf_doctest -- --module=ops.array_ops
Il
--module
è relativo atensorflow.python
.