From f66f9bef95df1645b94c17f511a61082e7520a43 Mon Sep 17 00:00:00 2001 From: Yash Katariya Date: Mon, 23 Dec 2019 11:23:32 -0800 Subject: [PATCH] Update doc strings for tf.split PiperOrigin-RevId: 286920582 Change-Id: Ie268f6bd61603ab91121b288d18463021f94e49d --- tensorflow/python/ops/array_ops.py | 151 ++++++++++++++++------------- 1 file changed, 84 insertions(+), 67 deletions(-) diff --git a/tensorflow/python/ops/array_ops.py b/tensorflow/python/ops/array_ops.py index 125c9d68ce0..68110449f3b 100644 --- a/tensorflow/python/ops/array_ops.py +++ b/tensorflow/python/ops/array_ops.py @@ -210,32 +210,33 @@ def fill(dims, value, name=None): For example: - ``` - # Output tensor has shape [2, 3]. - fill([2, 3], 9) ==> [[9, 9, 9] - [9, 9, 9]] - ``` + >>> tf.fill([2, 3], 9) + - `tf.fill` differs from `tf.constant` in a few ways: - - * `tf.fill` only supports scalar contents, whereas `tf.constant` supports - Tensor values. - * `tf.fill` creates an Op in the computation graph that constructs the - actual - Tensor value at runtime. This is in contrast to `tf.constant` which embeds - the entire Tensor into the graph with a `Const` node. - * Because `tf.fill` evaluates at graph runtime, it supports dynamic shapes - based on other runtime Tensors, unlike `tf.constant`. + `tf.fill` evaluates at graph runtime and supports dynamic shapes based on + other runtime `tf.Tensors`, unlike `tf.constant(value, shape=dims)`, which + embeds the value as a `Const` node. Args: - dims: A `Tensor`. Must be one of the following types: `int32`, `int64`. 1-D. - Represents the shape of the output tensor. - value: A `Tensor`. 0-D (scalar). Value to fill the returned tensor. - @compatibility(numpy) Equivalent to np.full @end_compatibility - name: A name for the operation (optional). + dims: A 1-D sequence of non-negative numbers. Represents the shape of the + output `tf.Tensor`. Entries should be of type: `int32`, `int64`. + value: A value to fill the returned `tf.Tensor`. + name: Optional string. The name of the output `tf.Tensor`. Returns: - A `Tensor`. Has the same type as `value`. + A `tf.Tensor` with shape `dims` and the same dtype as `value`. + + Raises: + InvalidArgumentError: `dims` contains negative entries. + NotFoundError: `dims` contains non-integer entries. + + @compatibility(numpy) + Similar to `np.full`. In `numpy`, more parameters are supported. Passing a + number argument as the shape (`np.full(5, value)`) is valid in `numpy` for + specifying a 1-D shaped result, while TensorFlow does not support this syntax. + @end_compatibility """ result = gen_array_ops.fill(dims, value, name=name) tensor_util.maybe_set_static_shape(result, dims) @@ -542,6 +543,7 @@ def shape_v2(input, out_type=dtypes.int32, name=None): """Returns the shape of a tensor. This operation returns a 1-D integer tensor representing the shape of `input`. + This represents the minimal set of known information at definition time. For example: @@ -563,6 +565,10 @@ def shape_v2(input, out_type=dtypes.int32, name=None): >>> a.shape TensorShape([None, None, 10]) + `tf.shape` and `Tensor.shape` should be identical in eager mode. Within + `tf.function` or within a `compat.v1` context, not all dimensions may be + known until execution time. + Args: input: A `Tensor` or `SparseTensor`. out_type: (Optional) The specified output type of the operation (`int32` or @@ -1881,11 +1887,11 @@ unique_with_counts.__doc__ = gen_array_ops.unique_with_counts.__doc__ @tf_export("split") def split(value, num_or_size_splits, axis=0, num=None, name="split"): - """Splits a tensor `value` into a list of sub tensors. + """Splits a tensor into sub tensors. - If `num_or_size_splits` is an integer, then `value` is split along the - dimension `axis` into `num_split` smaller tensors. This requires that - `value.shape[axis]` is divisible by `num_split`. + If `num_or_size_splits` is an integer, then `value` is split along dimension + `axis` into `num_split` smaller tensors. This requires that `num_split` evenly + divides `value.shape[axis]`. If `num_or_size_splits` is a 1-D Tensor (or list), we call it `size_splits` and `value` is split into `len(size_splits)` elements. The shape of the `i`-th @@ -1894,14 +1900,15 @@ def split(value, num_or_size_splits, axis=0, num=None, name="split"): For example: - >>> x = tf.Variable(tf.random.uniform([5, 30], -1, 1)) - Split `x` into 3 tensors along dimension 1 + + >>> x = tf.Variable(tf.random.uniform([5, 30], -1, 1)) >>> s0, s1, s2 = tf.split(x, num_or_size_splits=3, axis=1) >>> tf.shape(s0).numpy() array([ 5, 10], dtype=int32) Split `x` into 3 tensors with sizes [4, 15, 11] along dimension 1 + >>> split0, split1, split2 = tf.split(x, [4, 15, 11], 1) >>> tf.shape(split0).numpy() array([5, 4], dtype=int32) @@ -1924,8 +1931,8 @@ def split(value, num_or_size_splits, axis=0, num=None, name="split"): name: A name for the operation (optional). Returns: - if `num_or_size_splits` is a scalar returns a list of `num_or_size_splits` - `Tensor` objects; if `num_or_size_splits` is a 1-D Tensor returns + if `num_or_size_splits` is a scalar returns `num_or_size_splits` `Tensor` + objects; if `num_or_size_splits` is a 1-D Tensor returns `num_or_size_splits.get_shape[0]` `Tensor` objects resulting from splitting `value`. @@ -1956,16 +1963,17 @@ def split(value, num_or_size_splits, axis=0, num=None, name="split"): @tf_export("transpose", v1=[]) def transpose_v2(a, perm=None, conjugate=False, name="transpose"): - """Transposes `a`. + """Transposes `a`, where `a` is a Tensor. - Permutes the dimensions according to `perm`. + Permutes the dimensions according to the value of `perm`. - The returned tensor's dimension i will correspond to the input dimension - `perm[i]`. If `perm` is not given, it is set to (n-1...0), where n is - the rank of the input tensor. Hence by default, this operation performs a - regular matrix transpose on 2-D input Tensors. If conjugate is True and - `a.dtype` is either `complex64` or `complex128` then the values of `a` - are conjugated and transposed. + The returned tensor's dimension `i` will correspond to the input dimension + `perm[i]`. If `perm` is not given, it is set to (n-1...0), where n is the rank + of the input tensor. Hence by default, this operation performs a regular + matrix transpose on 2-D input Tensors. + + If conjugate is `True` and `a.dtype` is either `complex64` or `complex128` + then the values of `a` are conjugated and transposed. @compatibility(numpy) In `numpy` transposes are memory-efficient constant time operations as they @@ -1977,43 +1985,52 @@ def transpose_v2(a, perm=None, conjugate=False, name="transpose"): For example: - ```python - x = tf.constant([[1, 2, 3], [4, 5, 6]]) - tf.transpose(x) # [[1, 4] - # [2, 5] - # [3, 6]] + >>> x = tf.constant([[1, 2, 3], [4, 5, 6]]) + >>> tf.transpose(x) + - # Equivalently - tf.transpose(x, perm=[1, 0]) # [[1, 4] - # [2, 5] - # [3, 6]] + Equivalently, you could call `tf.transpose(x, perm=[1, 0])`. - # If x is complex, setting conjugate=True gives the conjugate transpose - x = tf.constant([[1 + 1j, 2 + 2j, 3 + 3j], - [4 + 4j, 5 + 5j, 6 + 6j]]) - tf.transpose(x, conjugate=True) # [[1 - 1j, 4 - 4j], - # [2 - 2j, 5 - 5j], - # [3 - 3j, 6 - 6j]] + If `x` is complex, setting conjugate=True gives the conjugate transpose: - # 'perm' is more useful for n-dimensional tensors, for n > 2 - x = tf.constant([[[ 1, 2, 3], - [ 4, 5, 6]], - [[ 7, 8, 9], - [10, 11, 12]]]) + >>> x = tf.constant([[1 + 1j, 2 + 2j, 3 + 3j], + ... [4 + 4j, 5 + 5j, 6 + 6j]]) + >>> tf.transpose(x, conjugate=True) + - # Take the transpose of the matrices in dimension-0 - # (this common operation has a shorthand `linalg.matrix_transpose`) - tf.transpose(x, perm=[0, 2, 1]) # [[[1, 4], - # [2, 5], - # [3, 6]], - # [[7, 10], - # [8, 11], - # [9, 12]]] - ``` + 'perm' is more useful for n-dimensional tensors where n > 2: + + >>> x = tf.constant([[[ 1, 2, 3], + ... [ 4, 5, 6]], + ... [[ 7, 8, 9], + ... [10, 11, 12]]]) + + As above, simply calling `tf.transpose` will default to `perm=[2,1,0]`. + + To take the transpose of the matrices in dimension-0 (such as when you are + transposing matrices where 0 is the batch dimesnion), you would set + `perm=[0,2,1]`. + + >>> tf.transpose(x, perm=[0, 2, 1]) + + + Note: This has a shorthand `linalg.matrix_transpose`): Args: a: A `Tensor`. - perm: A permutation of the dimensions of `a`. + perm: A permutation of the dimensions of `a`. This should be a vector. conjugate: Optional bool. Setting it to `True` is mathematically equivalent to tf.math.conj(tf.transpose(input)). name: A name for the operation (optional).