Esempio n. 1
0
def reduce_max(input_tensor, reduction_indices=None, keep_dims=False,
               name=None):
  """Computes the maximum of elements across dimensions of a tensor.

  Reduces `input_tensor` along the dimensions given in `reduction_indices`.
  Unless `keep_dims` is true, the rank of the tensor is reduced by 1 for each
  entry in `reduction_indices`. If `keep_dims` is true, the reduced dimensions
  are retained with length 1.

  If `reduction_indices` has no entries, all dimensions are reduced, and a
  tensor with a single element is returned.

  Args:
    input_tensor: The tensor to reduce. Should have numeric type.
    reduction_indices: The dimensions to reduce. If `None` (the default),
      reduces all dimensions.
    keep_dims: If true, retains reduced dimensions with length 1.
    name: A name for the operation (optional).

  Returns:
    The reduced tensor.
  """
  return gen_math_ops._max(input_tensor, _ReductionDims(input_tensor,
                                                        reduction_indices),
                           keep_dims, name=name)
Esempio n. 2
0
def sequence_mask_mid(lengths, maxlen=None, dtype=dtypes.bool, name=None):
    """Return a mask tensor representing the first N positions of each row.

    Example:

    ```python
    tf.sequence_mask([1, 3, 2], 5) =
      [[True, False, False, False, False],
       [False,False, False, False, False],
       [False, True, False, False, False]]
    ```

    Args:
      lengths: 1D integer tensor, all its values < maxlen.
      maxlen: scalar integer tensor, maximum length of each row. Default: use
              maximum over lengths.
      dtype: output type of the resulting tensor.
      name: name of the op.
    Returns:
      A 2D mask tensor, as shown in the example above, cast to specified dtype.

    Raises:
      ValueError: if the arguments have invalid rank.
    """
    with ops.name_scope(name, "SequenceMask", [lengths, maxlen]):
        lengths = (np.array(lengths)) / 2
        lengths = ops.convert_to_tensor(lengths, dtype=tf.int32)
        # lengths = ops.convert_to_tensor(lengths)
        if lengths.get_shape().ndims != 1:
            raise ValueError("lengths must be 1D for sequence_mask")

        if maxlen is None:
            maxlen = gen_math_ops._max(lengths, [0])
        else:
            maxlen = ops.convert_to_tensor(maxlen)
        if maxlen.get_shape().ndims != 0:
            raise ValueError("maxlen must be scalar for sequence_mask")

        # The basic idea is to compare a range row vector of size maxlen:
        # [0, 1, 2, 3, 4]
        # to length as a matrix with 1 column: [[1], [3], [2]].
        # Because of broadcasting on both arguments this comparison results
        # in a matrix of size (len(lengths), maxlen)
        row_vector = gen_math_ops._range(constant(0, maxlen.dtype), maxlen,
                                         constant(1, maxlen.dtype))
        # Since maxlen >= max(lengths), it is safe to use maxlen as a cast
        # authoritative type. Whenever maxlen fits into tf.int32, so do the lengths.
        matrix_0 = gen_math_ops.cast(expand_dims(lengths, 1), maxlen.dtype)
        matrix_1 = gen_math_ops.cast(expand_dims(lengths - 1, 1), maxlen.dtype)
        result_0 = (row_vector < matrix_0)
        result_1 = (row_vector >= matrix_1)
        result = tf.logical_and(result_0, result_1)

        if dtype is None or result.dtype.base_dtype == dtype.base_dtype:
            return result
        else:
            return gen_math_ops.cast(result, dtype)
Esempio n. 3
0
def sequence_mask(lengths, maxlen=None, dtype=dtypes.bool, name=None):
    """Returns a mask tensor representing the first N positions of each cell.
	If `lengths` has shape `[d_1, d_2, ..., d_n]` the resulting tensor `mask` has
	dtype `dtype` and shape `[d_1, d_2, ..., d_n, maxlen]`, with
	```
	mask[i_1, i_2, ..., i_n, j] = (j < lengths[i_1, i_2, ..., i_n])
	```
	Examples:
	```python
	tf.sequence_mask([1, 3, 2], 5)  # [[True, False, False, False, False],
																	#  [True, True, True, False, False],
																	#  [True, True, False, False, False]]
	tf.sequence_mask([[1, 3],[2,0]])  # [[[True, False, False],
																		#   [True, True, True]],
																		#  [[True, True, False],
																		#   [False, False, False]]]
	```
	Args:
		lengths: integer tensor, all its values <= maxlen.
		maxlen: scalar integer tensor, size of last dimension of returned tensor.
			Default is the maximum value in `lengths`.
		dtype: output type of the resulting tensor.
		name: name of the op.
	Returns:
		A mask tensor of shape `lengths.shape + (maxlen,)`, cast to specified dtype.
	Raises:
		ValueError: if `maxlen` is not a scalar.
	"""
    with ops.name_scope(name, "SequenceMask", [lengths, maxlen]):
        lengths = ops.convert_to_tensor(lengths)

        if maxlen is None:
            maxlen = gen_math_ops._max(lengths, _all_dimensions(lengths))
            maxlen = gen_math_ops.maximum(constant(0, maxlen.dtype), maxlen)
        else:
            maxlen = ops.convert_to_tensor(maxlen)
        if maxlen.get_shape(
        ).ndims is not None and maxlen.get_shape().ndims != 0:
            raise ValueError("maxlen must be scalar for sequence_mask")

        # The basic idea is to compare a range row vector of size maxlen:
        # [0, 1, 2, 3, 4]
        # to length as a matrix with 1 column: [[1], [3], [2]].
        # Because of broadcasting on both arguments this comparison results
        # in a matrix of size (len(lengths), maxlen)
        row_vector = gen_math_ops._range(constant(0, maxlen.dtype), maxlen,
                                         constant(1, maxlen.dtype))
        # Since maxlen >= max(lengths), it is safe to use maxlen as a cast
        # authoritative type. Whenever maxlen fits into tf.int32, so do the lengths.
        matrix = gen_math_ops.cast(expand_dims(lengths, -1), maxlen.dtype)
        result = row_vector < matrix

        if dtype is None or result.dtype.base_dtype == dtype.base_dtype:
            return result
        else:
            return gen_math_ops.cast(result, dtype)
Esempio n. 4
0
def repeat_with_axis(data, repeats, axis, name=None):
  """Repeats elements of `data`.
  Args:
    data: An `N`-dimensional tensor.
    repeats: A 1-D integer tensor specifying how many times each element in
      `axis` should be repeated.  `len(repeats)` must equal `data.shape[axis]`.
      Supports broadcasting from a scalar value.
    axis: `int`.  The axis along which to repeat values.  Must be less than
      `max(N, 1)`.
    name: A name for the operation.
  Returns:
    A tensor with `max(N, 1)` dimensions.  Has the same shape as `data`,
    except that dimension `axis` has size `sum(repeats)`.
  #### Examples:
    ```python
    >>> repeat(['a', 'b', 'c'], repeats=[3, 0, 2], axis=0)
    ['a', 'a', 'a', 'c', 'c']
    >>> repeat([[1, 2], [3, 4]], repeats=[2, 3], axis=0)
    [[1, 2], [1, 2], [3, 4], [3, 4], [3, 4]]
    >>> repeat([[1, 2], [3, 4]], repeats=[2, 3], axis=1)
    [[1, 1, 2, 2, 2], [3, 3, 4, 4, 4]]
    ```
  """
  if not isinstance(axis, int):
    raise TypeError("axis must be an int; got %s" % type(axis).__name__)

  with ops.name_scope(name, "Repeat", [data, repeats]):
    data = ops.convert_to_tensor(data, name="data")
    repeats = convert_to_int_tensor(repeats, name="repeats")
    repeats.shape.with_rank_at_most(1)

    # If `data` is a scalar, then upgrade it to a vector.
    data = _with_nonzero_rank(data)
    data_shape = shape(data)

    # If `axis` is negative, then convert it to a positive value.
    axis = get_positive_axis(axis, data.shape.ndims)

    # Check data Tensor shapes.
    if repeats.shape.ndims == 1:
      data.shape.dims[axis].assert_is_compatible_with(repeats.shape[0])

    # If we know that `repeats` is a scalar, then we can just tile & reshape.
    if repeats.shape.ndims == 0:
      expanded = expand_dims(data, axis + 1)
      tiled = tile_one_dimension(expanded, axis + 1, repeats)
      result_shape = concat([data_shape[:axis], [-1], data_shape[axis + 1:]],
                            axis=0)
      return tf.reshape(tiled, result_shape)

    # Broadcast the `repeats` tensor so rank(repeats) == axis + 1.
    if repeats.shape.ndims != axis + 1:
      repeats_shape = shape(repeats)
      repeats_ndims = rank(repeats)
      broadcast_shape = concat(
          [data_shape[:axis + 1 - repeats_ndims], repeats_shape], axis=0)
      repeats = broadcast_to(repeats, broadcast_shape)
      repeats.set_shape([None] * (axis + 1))

    # Create a "sequence mask" based on `repeats`, where slices across `axis`
    # contain one `True` value for each repetition.  E.g., if
    # `repeats = [3, 1, 2]`, then `mask = [[1, 1, 1], [1, 0, 0], [1, 1, 0]]`.
    max_repeat = gen_math_ops.maximum(
        0, gen_math_ops._max(repeats, _all_dimensions(repeats)))
    mask = tf.sequence_mask(repeats, max_repeat)

    # Add a new dimension around each value that needs to be repeated, and
    # then tile that new dimension to match the maximum number of repetitions.
    expanded = expand_dims(data, axis + 1)
    tiled = tile_one_dimension(expanded, axis + 1, max_repeat)

    # Use `boolean_mask` to discard the extra repeated values.  This also
    # flattens all dimensions up through `axis`.
    masked = tf.boolean_mask(tiled, mask)

    # Reshape the output tensor to add the outer dimensions back.
    if axis == 0:
      result = masked
    else:
      result_shape = concat([data_shape[:axis], [-1], data_shape[axis + 1:]],
                            axis=0)
      result = tf.reshape(masked, result_shape)

    # Preserve shape information.
    if data.shape.ndims is not None:
      new_axis_size = 0 if repeats.shape[0] == 0 else None
      result.set_shape(data.shape[:axis].concatenate(
          [new_axis_size]).concatenate(data.shape[axis + 1:]))

    return result