Stringhe di documenti verificabili
TensorFlow utilizza DocTest per testare frammenti di codice nelle 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, consultare la sezione di esempio dei consigli sui documenti API di TensorFlow 2 . (Tenere presente che il Task Tracker in questo foglio non è più in uso.)
Rendi il codice testabile con DocTest
Attualmente, molte docstring utilizzano i backtick (```) per identificare il codice. Per rendere il codice testabile con DocTest:
- Rimuovi gli apici inversi (```) e utilizza le parentesi sinistre (>>>) davanti a ciascuna riga. Utilizzare (...) davanti alle righe continue.
- Aggiungi una nuova riga per separare i frammenti DocTest dal testo Markdown per renderli 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 tolleranze liberaliatol
ertol
. Ciò consente:- 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 sulla stringa di documento
- Nel complesso : 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.
- Se possibile, utilizzare numeri tondi.
- Formato di output : l'output dello snippet deve trovarsi direttamente sotto il 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 extra sulla nuova riga e DocTest lo riconoscerà. Ad esempio, vedere i blocchi multilinea di seguito.
- Globali : i moduli
`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 non definito nel file corrente, utilizza l'API pubblica di TensorFlow
tf.xxx
anzichéxxx
. 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 di risultato 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 precise che causano errori dovuti a problemi numerici. Basta incollare il valore previsto.Output non deterministico : utilizzare 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 su più righe : DocTest è rigoroso riguardo alla differenza tra un'istruzione singola e una su più righe. Notare 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'>`.
Utilizzare una copia locale del progetto di tf-doctest.
Alcune API in TensorFlow provengono da un progetto esterno:
-
tf.estimator
(da tensorflow_estimator ) -
tf.summary
tensorboard ) -
tf.keras.preprocessing
(da keras-preprocessing )
Se stai lavorando su un progetto esterno o su API TensorFlow ospitate in un progetto esterno, queste istruzioni non funzioneranno a meno che il progetto non disponga di una propria copia locale di tf_doctest
e utilizzi quella copia invece di quella di TensorFlow.
Ad esempio: tf_estimator_doctest.py .
Prova sul tuo computer locale
Esistono due modi per testare localmente il codice nella docstring:
Se stai modificando solo 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'installazione pip tf-nightly aggiornata
pip install -U tf-nightly
- Ribasare la tua richiesta pull su un pull recente dal ramo principale di TensorFlow .
- Utilizzare un'installazione pip tf-nightly aggiornata
Se stai modificando il codice e la docstring di una classe/funzione/metodo, dovrai creare TensorFlow dal sorgente . Una volta impostato per compilare dal sorgente, puoi 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
.