Dokumenty testowalne
TensorFlow używa DocTest do testowania fragmentów kodu w dokumentacjach Pythona. Fragment kodu musi być wykonywalnym kodem Pythona. Aby umożliwić testowanie, poprzedź linię znakiem >>>
(trzy lewe nawiasy ostrokątne). Na przykład, oto fragment funkcji tf.concat
w pliku źródłowym 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>
Aby ocenić jakość dokumentacji referencyjnej, zapoznaj się z przykładową sekcją porad dotyczących Dokumentów API TensorFlow 2 . (Pamiętaj, że narzędzie do śledzenia zadań na tym arkuszu nie jest już używane).
Spraw, aby kod można było przetestować za pomocą DocTest
Obecnie wiele dokumentów docstringów używa backticków (```) do identyfikacji kodu. Aby kod był testowalny za pomocą DocTest:
- Usuń backticki (```) i użyj lewych nawiasów (>>>) przed każdą linią. Użyj (...) przed kolejnymi liniami.
- Dodaj znak nowej linii, aby oddzielić fragmenty DocTest od tekstu Markdown, aby poprawnie renderować na tensorflow.org.
Modyfikacje
TensorFlow wykorzystuje kilka dostosowań wbudowanej logiki doctest:
- Nie porównuje wartości zmiennoprzecinkowych z tekstem: wartości zmiennoprzecinkowe są wyodrębniane z tekstu i porównywane przy użyciu funkcji
allclose
z liberalnymi tolerancjamiatol
irtol
. To pozwala :- Bardziej przejrzyste dokumenty — autorzy nie muszą podawać wszystkich miejsc po przecinku.
- Bardziej niezawodne testy — zmiany numeryczne w podstawowej implementacji nigdy nie powinny powodować niepowodzenia doctestu.
- Sprawdza dane wyjściowe tylko wtedy, gdy autor zawiera dane wyjściowe dla wiersza. Dzięki temu dokumenty są bardziej przejrzyste, ponieważ autorzy zwykle nie muszą przechwytywać nieistotnych wartości pośrednich, aby zapobiec ich wydrukowaniu.
Uwagi dotyczące dokumentacji
- Ogólnie : Celem doctest jest dostarczenie dokumentacji i potwierdzenie, że dokumentacja działa. Różni się to od testów jednostkowych. Więc:
- Zachowaj proste przykłady.
- Unikaj długich lub skomplikowanych danych wyjściowych.
- Jeśli to możliwe, używaj okrągłych liczb.
- Format wyjściowy : dane wyjściowe fragmentu kodu muszą znajdować się bezpośrednio pod kodem, który generuje dane wyjściowe. Ponadto dane wyjściowe w docstring muszą być dokładnie takie same, jak dane wyjściowe po wykonaniu kodu. Zobacz powyższy przykład. Zapoznaj się również z tą częścią w dokumentacji DocTest. Jeśli wyjście przekroczy limit 80 linii, możesz umieścić dodatkowe wyjście w nowej linii, a DocTest go rozpozna. Na przykład zobacz bloki wielowierszowe poniżej.
- Globals :
`tf`
,np
ios
są zawsze dostępne w DocTest TensorFlow. Użyj symboli : W DocTest masz bezpośredni dostęp do symboli zdefiniowanych w tym samym pliku. Aby użyć symbolu, który nie jest zdefiniowany w bieżącym pliku, użyj publicznego interfejsu API
tf.xxx
zamiastxxx
. Jak widać w poniższym przykładzie,`random.normal`
jest dostępny poprzez`tf.random.normal`
. Dzieje się tak, ponieważ`random.normal`
nie jest widoczny wNewLayer
.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=...> """
Wartości zmiennoprzecinkowe : Doctest TensorFlow wyodrębnia wartości zmiennoprzecinkowe z ciągów wynikowych i porównuje przy użyciu
np.allclose
z rozsądnymi tolerancjami (atol=1e-6
,rtol=1e-6
). W ten sposób autorzy nie muszą się martwić o zbyt precyzyjne docstringi powodujące awarie z powodu problemów numerycznych. Po prostu wklej oczekiwaną wartość.Wynik niedeterministyczny : użyj elipsy (
...
) dla niepewnych części, a DocTest zignoruje ten podłańcuch.x = tf.random.normal((1,))
print(x)
<tf.Tensor: shape=(1,), dtype=float32, numpy=..., dtype=float32)>
Bloki wielowierszowe : DocTest ściśle określa różnicę między instrukcją jedno- i wielowierszową. Zwróć uwagę na użycie (...) poniżej:
if x > 0:
print("X is positive")
model.compile(
loss="mse",
optimizer="adam")
Wyjątki : szczegóły wyjątku są ignorowane, z wyjątkiem zgłoszonego wyjątku. Zobacz to po więcej szczegółów.
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'>`.
Użyj lokalnej kopii tf-doctest.
Niektóre API w TensorFlow pochodzą z projektu zewnętrznego:
-
tf.estimator
(z tensorflow_estimator ) -
tf.summary
tensorboard ) -
tf.keras.preprocessing
(z keras-preprocessing )
Jeśli pracujesz nad projektem zewnętrznym lub nad interfejsami API TensorFlow, które znajdują się w projekcie zewnętrznym, te instrukcje nie będą działać, chyba że projekt ma własną lokalną kopię tf_doctest
i używasz tej kopii zamiast TensorFlow.
Na przykład: tf_estimator_doctest.py .
Przetestuj na swoim lokalnym komputerze
Istnieją dwa sposoby lokalnego przetestowania kodu w docstringu:
Jeśli zmieniasz tylko dokumentację klasy/funkcji/metody, możesz ją przetestować, przekazując ścieżkę tego pliku do tf_doctest.py . Na przykład:
python tf_doctest.py --file=<file_path>
Spowoduje to uruchomienie go przy użyciu zainstalowanej wersji TensorFlow. Aby mieć pewność, że używasz tego samego kodu, który testujesz:
- Użyj aktualnego tf-nightly
pip install -U tf-nightly
- Zmień podstawę swojego pull requestu na niedawnym pull z głównej gałęzi TensorFlow .
- Użyj aktualnego tf-nightly
Jeśli zmieniasz kod i dokumentację klasy/funkcji/metody, będziesz musiał zbudować TensorFlow ze źródła . Po skonfigurowaniu kompilacji ze źródeł możesz uruchomić testy:
bazel run //tensorflow/tools/docs:tf_doctest
lub
bazel run //tensorflow/tools/docs:tf_doctest -- --module=ops.array_ops
--module
jest względemtensorflow.python
.