为 TensorFlow API 文档做出贡献

可测试的文档字符串

TensorFlow 使用 DocTest 测试 Python 文档字符串中的代码片段。该片段必须是可执行的 Python 代码。要启用测试,请在行首添加 >>>(三个左尖括号)。例如,以下是 tf.concat 函数在 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>

要评估参考文档质量,请参阅 TensorFlow 2 API 文档建议 的示例部分。(请注意,此表格上的任务跟踪器不再使用。)

使用 DocTest 使代码可测试

目前,许多文档字符串使用反引号 (```) 来标识代码。要使用 DocTest 使代码可测试

  • 删除反引号 (```) 并使用左括号 (>>>) 放在每行前面。在续行前面使用 (...)。
  • 添加一个换行符以将 DocTest 代码片段与 Markdown 文本分隔开,以便在 tensorflow.org 上正确呈现。

自定义

TensorFlow 对内置 doctest 逻辑进行了一些自定义

  • 它不将浮点值作为文本进行比较:浮点值从文本中提取,并使用 allclose 进行比较,具有宽松的 atolrtol 容差。这允许
    • 更清晰的文档 - 作者无需包含所有小数位。
    • 更健壮的测试 - 底层实现中的数值更改永远不会导致 doctest 失败。
  • 它只在作者为某一行包含输出时才检查输出。这允许更清晰的文档,因为作者通常不需要捕获无关的中间值以防止它们被打印。

文档字符串注意事项

  • 总体:doctest 的目标是提供文档,并确认文档有效。这与单元测试不同。所以
    • 保持示例简单。
    • 避免长或复杂的输出。
    • 如果可能,使用四舍五入的数字。
  • 输出格式:代码片段的输出需要直接放在生成该输出的代码下方。此外,文档字符串中的输出必须与代码执行后的输出完全相同。请参阅上面的示例。此外,请查看 DocTest 文档中的这部分。如果输出超过 80 行限制,您可以将额外的输出放在新行上,DocTest 将识别它。例如,请参阅下面的多行块。
  • 全局变量`tf`npos 模块始终在 TensorFlow 的 DocTest 中可用。
  • 使用符号:在 DocTest 中,您可以直接访问在同一文件中定义的符号。要使用当前文件中未定义的符号,请使用 TensorFlow 的公共 API tf.xxx 而不是 xxx。正如您在下面的示例中看到的,`random.normal` 通过 `tf.random.normal` 访问。这是因为 `random.normal`NewLayer 中不可见。

    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=...>
      """
    
  • 浮点值:TensorFlow doctest 从结果字符串中提取浮点值,并使用 np.allclose 进行比较,具有合理的容差 (atol=1e-6rtol=1e-6)。这样,作者就不需要担心过于精确的文档字符串因数值问题而导致失败。只需粘贴预期值即可。

  • 非确定性输出:对不确定的部分使用省略号 (...),DocTest 将忽略该子字符串。

    x = tf.random.normal((1,))
    print(x)
        <tf.Tensor: shape=(1,), dtype=float32, numpy=..., dtype=float32)>
        
    
  • 多行块:DocTest 对单行语句和多行语句之间的区别很严格。请注意下面 (...) 的用法

    if x > 0:
      print("X is positive")
    model.compile(
      loss="mse",
      optimizer="adam")
        
    
  • 异常:除了引发的异常外,异常详细信息将被忽略。有关更多详细信息,请参阅 此处

    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'>`.
        
    

使用项目本地副本的 tf-doctest。

TensorFlow 中的一些 API 来自外部项目

如果您正在处理外部项目,或者正在处理位于外部项目的 TensorFlow API,那么这些说明将不起作用,除非该项目有自己的本地副本的 tf_doctest,并且您使用该副本而不是 TensorFlow 的副本。

例如:tf_estimator_doctest.py

在本地机器上测试

有两种方法可以在本地测试文档字符串中的代码

  • 如果您只更改类/函数/方法的文档字符串,那么您可以通过将该文件的路径传递给 tf_doctest.py 来测试它。例如

    python tf_doctest.py --file=<file_path>
    

    这将使用您安装的 TensorFlow 版本运行它。为了确保您运行的代码与您测试的代码相同

    • 使用最新的 tf-nightly pip install -U tf-nightly
    • 将您的拉取请求重新绑定到来自 TensorFlow 主分支的最新拉取请求。
  • 如果您正在更改类/函数/方法的代码和文档字符串,则需要 从源代码构建 TensorFlow。一旦您设置好从源代码构建,您就可以运行测试

    bazel run //tensorflow/tools/docs:tf_doctest
    

    bazel run //tensorflow/tools/docs:tf_doctest -- --module=ops.array_ops
    

    The --module is relative to tensorflow.python.