Ejemplo n.º 1
0
def rot90(image, k=1):
  """Rotate an image counter-clockwise by 90 degrees.

  Args:
    image: A 3-D tensor of shape `[height, width, channels].`
    k: Number of times the image is rotated by 90 degrees.

  Returns:
    A rotated 3-D tensor of the same type and shape as `image`.
  """
  image = ops.convert_to_tensor(image, name='image')
  _Check3DImage(image, require_static=False)
  k %= 4
  if k == 0:
    return image
  elif k == 1:
    return array_ops.transpose(
        array_ops.reverse(image, [False, True, False]),
        [1, 0, 2], name='rot90')
  elif k == 2:
    return array_ops.reverse(image, [True, True, False], name='rot90')
  elif k == 3:
    return array_ops.reverse(
        array_ops.transpose(image, [1, 0, 2], name='rot90'),
        [False, True, False])
Ejemplo n.º 2
0
 def _reverse(input_, seq_lengths, seq_dim, batch_dim):
   if seq_lengths is not None:
     return array_ops.reverse_sequence(
         input=input_, seq_lengths=seq_lengths,
         seq_dim=seq_dim, batch_dim=batch_dim)
   else:
     return array_ops.reverse(input_, axis=[seq_dim])
Ejemplo n.º 3
0
def calculate_sequence_by_mask(mask, time_major):
  """Calculate the sequence length tensor (1-D) based on the masking tensor.

  The masking tensor is a 2D boolean tensor with shape [batch, timestep]. For
  any timestep that should be masked, the corresponding field will be False.
  Consider the following example:
    a = [[True, True, False, False],
         [True, False, True, False]]
  It is a (2, 4) tensor, and the corresponding sequence length result should be
  1D tensor with value [2, 3]. Note that for the second example, we need to find
  the index of the last True value, which is 2 and sequence length is 3.

  Args:
    mask: Boolean tensor with shape [batch, timestep] or [timestep, batch] if
      time_major=True.
    time_major: Boolean, which indicates whether the mask is time major or batch
      major.
  Returns:
    sequence_length: 1D int32 tensor.
  """
  timestep_index = 0 if time_major else 1
  max_seq_length = array_ops.shape(mask)[timestep_index]
  reversed_mask = math_ops.cast(array_ops.reverse(mask, axis=[timestep_index]),
                                dtypes.int32)
  # Use the argmax to find the index of leading 1 in the reversed mask, which is
  # the index of the last True value in the original mask.
  reversed_index = math_ops.argmax(reversed_mask, axis=timestep_index,
                                   output_type=dtypes.int32)
  return max_seq_length - reversed_index
Ejemplo n.º 4
0
  def testReverse1DimAuto(self):
    x_np = [1, 4, 9]

    for use_gpu in [False, True]:
      with self.test_session(use_gpu=use_gpu):
        x_tf = array_ops.reverse(x_np, [True]).eval()
        self.assertAllEqual(x_tf, np.asarray(x_np)[::-1])
Ejemplo n.º 5
0
  def _reverse1DimAuto(self, np_dtype):
    x_np = np.array([1, 2, 3, 4, 5], dtype=np_dtype)

    for use_gpu in [False, True]:
      with self.test_session(use_gpu=use_gpu):
        x_tf = array_ops.reverse(x_np, [True]).eval()
        self.assertAllEqual(x_tf, np.asarray(x_np)[::-1])
Ejemplo n.º 6
0
def random_flip_left_right(image, seed=None):
  """Randomly flip an image horizontally (left to right).

  With a 1 in 2 chance, outputs the contents of `image` flipped along the
  second dimension, which is `width`.  Otherwise output the image as-is.

  Args:
    image: A 3-D tensor of shape `[height, width, channels].`
    seed: A Python integer. Used to create a random seed. See
      @{tf.set_random_seed}
      for behavior.

  Returns:
    A 3-D tensor of the same type and shape as `image`.

  Raises:
    ValueError: if the shape of `image` not supported.
  """
  image = ops.convert_to_tensor(image, name='image')
  _Check3DImage(image, require_static=False)
  uniform_random = random_ops.random_uniform([], 0, 1.0, seed=seed)
  mirror_cond = math_ops.less(uniform_random, .5)
  result = control_flow_ops.cond(mirror_cond,
                                 lambda: array_ops.reverse(image, [1]),
                                 lambda: image)
  return fix_image_flip_shape(image, result)
  def testReverseWithNonConstDims(self):
    if test.is_gpu_available(cuda_only=True):
      random_seed.set_random_seed(0)
      x = random_ops.truncated_normal([1, 784], seed=0)
      conv = _two_layer_model(x)
      dims = array_ops.placeholder(dtype='int32')
      reverse = array_ops.reverse(conv, dims)
      output = array_ops.identity(reverse)

      dims_val = [2, 3]
      with session.Session() as sess:
        output_val_ref = sess.run(output, feed_dict={dims: dims_val})

      with session.Session(config=_get_config()) as sess:
        metadata = config_pb2.RunMetadata()
        output_val = sess.run(
            output, run_metadata=metadata, feed_dict={
                dims: dims_val
            })

      nodes = []
      num_transposes = 0
      for node in metadata.cost_graph.node:
        if _is_transpose(node.name):
          num_transposes += 1
        nodes.append(node.name)

      # Four transposes were initially added in the Expand phase of
      # LayoutOptimizer; two of them are cancelled out in the Collapse phase.
      expected_num_transposes = 2
      self.assertEqual(expected_num_transposes, num_transposes)
      self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes)
      self._assert_trans_nchw_to_nhwc('ReverseV2-0-0', nodes)
      self._assert_map_nhwc_to_nchw('ReverseV2-1', nodes)
      self.assertAllClose(output_val_ref, output_val, atol=1e-3)
Ejemplo n.º 8
0
def random_flip_up_down(image, seed=None):
  """Randomly flips an image vertically (upside down).

  With a 1 in 2 chance, outputs the contents of `image` flipped along the first
  dimension, which is `height`.  Otherwise output the image as-is.

  Args:
    image: A 3-D tensor of shape `[height, width, channels].`
    seed: A Python integer. Used to create a random seed. See
      [`set_random_seed`](../../api_docs/python/constant_op.md#set_random_seed)
      for behavior.

  Returns:
    A 3-D tensor of the same type and shape as `image`.

  Raises:
    ValueError: if the shape of `image` not supported.
  """
  image = ops.convert_to_tensor(image, name='image')
  _Check3DImage(image, require_static=False)
  uniform_random = random_ops.random_uniform([], 0, 1.0, seed=seed)
  mirror_cond = math_ops.less(uniform_random, .5)
  result = control_flow_ops.cond(mirror_cond,
                                 lambda: array_ops.reverse(image, [0]),
                                 lambda: image)
  return fix_image_flip_shape(image, result)
Ejemplo n.º 9
0
  def testReverseWithConstDims(self):
    if test.is_gpu_available(cuda_only=True):
      random_seed.set_random_seed(0)
      x = random_ops.truncated_normal([1, 784], seed=0)
      conv = _two_layer_model(x)
      dims = constant_op.constant([3, 1], name='DimsConst')
      reverse = array_ops.reverse(conv, dims)
      output = array_ops.identity(reverse)

      with session.Session() as sess:
        output_val_ref = sess.run(output)

      with session.Session(config=_get_config()) as sess:
        metadata = config_pb2.RunMetadata()
        output_val = sess.run(output, run_metadata=metadata)

      nodes = []
      num_transposes = 0
      for node in metadata.cost_graph.node:
        if node.name.startswith('LayoutOptimizerTranspose'):
          num_transposes += 1
        nodes.append(node.name)

      # Four transposes were initially added in the Expand phase of
      # LayoutOptimizer; two of them are cancelled out in the Collapse phase.
      expected_num_transposes = 2
      self.assertEqual(expected_num_transposes, num_transposes)
      self.assertIn('LayoutOptimizerTransposeNHWCToNCHW-Conv2D-0', nodes)
      self.assertIn('LayoutOptimizerTransposeNCHWToNHWC-ReverseV2-0-0', nodes)
      self.assertIn('LayoutOptimizer-ReverseV2-DimsConst', nodes)
      self.assertAllClose(output_val_ref, output_val, atol=1e-3)
Ejemplo n.º 10
0
 def _reverse(input_, seq_lengths, seq_axis, batch_axis):
   if seq_lengths is not None:
     return array_ops.reverse_sequence(
         input=input_,
         seq_lengths=seq_lengths,
         seq_axis=seq_axis,
         batch_axis=batch_axis)
   else:
     return array_ops.reverse(input_, axis=[seq_axis])
Ejemplo n.º 11
0
 def _reverse(input_, seq_lengths, seq_dim, batch_dim):
   if seq_lengths is not None:
     return array_ops.reverse_sequence(
         input=input_, seq_lengths=seq_lengths,
         seq_dim=seq_dim, batch_dim=batch_dim)
   else:
     # See b/69305369.
     assert not use_tpu, (
         'Bidirectional with variable sequence lengths unsupported on TPU')
     return array_ops.reverse(input_, axis=[seq_dim])
Ejemplo n.º 12
0
def erosion2d(value, kernel, strides, rates, padding, name=None):
  """Computes the grayscale erosion of 4-D `value` and 3-D `kernel` tensors.

  The `value` tensor has shape `[batch, in_height, in_width, depth]` and the
  `kernel` tensor has shape `[kernel_height, kernel_width, depth]`, i.e.,
  each input channel is processed independently of the others with its own
  structuring function. The `output` tensor has shape
  `[batch, out_height, out_width, depth]`. The spatial dimensions of the
  output tensor depend on the `padding` algorithm. We currently only support the
  default "NHWC" `data_format`.

  In detail, the grayscale morphological 2-D erosion is given by:

      output[b, y, x, c] =
         min_{dy, dx} value[b,
                            strides[1] * y - rates[1] * dy,
                            strides[2] * x - rates[2] * dx,
                            c] -
                      kernel[dy, dx, c]

  Duality: The erosion of `value` by the `kernel` is equal to the negation of
  the dilation of `-value` by the reflected `kernel`.

  Args:
    value: A `Tensor`. 4-D with shape `[batch, in_height, in_width, depth]`.
    kernel: A `Tensor`. Must have the same type as `value`.
      3-D with shape `[kernel_height, kernel_width, depth]`.
    strides: A list of `ints` that has length `>= 4`.
      1-D of length 4. The stride of the sliding window for each dimension of
      the input tensor. Must be: `[1, stride_height, stride_width, 1]`.
    rates: A list of `ints` that has length `>= 4`.
      1-D of length 4. The input stride for atrous morphological dilation.
      Must be: `[1, rate_height, rate_width, 1]`.
    padding: A `string` from: `"SAME", "VALID"`.
      The type of padding algorithm to use.
    name: A name for the operation (optional). If not specified "erosion2d"
      is used.

  Returns:
    A `Tensor`. Has the same type as `value`.
    4-D with shape `[batch, out_height, out_width, depth]`.

  Raises:
    ValueError: If the `value` depth does not match `kernel`' shape, or if
      padding is other than `'VALID'` or `'SAME'`.
  """
  with ops.op_scope([value, kernel], name, "erosion2d") as name:
    # Reduce erosion to dilation by duality.
    return math_ops.neg(gen_nn_ops.dilation2d(input=math_ops.neg(value),
                                              filter=array_ops.reverse(
                                                  kernel, [True, True, False]),
                                              strides=strides,
                                              rates=rates,
                                              padding=padding,
                                              name=name))
Ejemplo n.º 13
0
  def event_shape(self, name='event_shape'):
    """Shape of a sample from a single distribution as a 1-D int32 `Tensor`.

    Args:
      name: name to give to the op

    Returns:
      `Tensor` `event_shape`
    """
    with ops.name_scope(self.name):
      with ops.op_scope([self._alpha], name):
        return array_ops.reverse(array_ops.shape(self._alpha), [True])[0]
Ejemplo n.º 14
0
def _auc_convert_hist_to_auc(hist_true_acc, hist_false_acc, nbins):
  """Convert histograms to auc.

  Args:
    hist_true_acc:  `Tensor` holding accumulated histogram of scores for records
      that were `True`.
    hist_false_acc:  `Tensor` holding accumulated histogram of scores for
      records that were `False`.
    nbins:  Integer number of bins in the histograms.

  Returns:
    Scalar `Tensor` estimating AUC.
  """
  # Note that this follows the "Approximating AUC" section in:
  # Efficient AUC learning curve calculation, R. R. Bouckaert,
  # AI'06 Proceedings of the 19th Australian joint conference on Artificial
  # Intelligence: advances in Artificial Intelligence
  # Pages 181-191.
  # Note that the above paper has an error, and we need to re-order our bins to
  # go from high to low score.

  # Normalize histogram so we get fraction in each bin.
  normed_hist_true = math_ops.truediv(hist_true_acc,
                                      math_ops.reduce_sum(hist_true_acc))
  normed_hist_false = math_ops.truediv(hist_false_acc,
                                       math_ops.reduce_sum(hist_false_acc))

  # These become delta x, delta y from the paper.
  delta_y_t = array_ops.reverse(normed_hist_true, [True], name='delta_y_t')
  delta_x_t = array_ops.reverse(normed_hist_false, [True], name='delta_x_t')

  # strict_1d_cumsum requires float32 args.
  delta_y_t = math_ops.cast(delta_y_t, dtypes.float32)
  delta_x_t = math_ops.cast(delta_x_t, dtypes.float32)

  # Trapezoidal integration, \int_0^1 0.5 * (y_t + y_{t-1}) dx_t
  y_t = _strict_1d_cumsum(delta_y_t, nbins)
  first_trap = delta_x_t[0] * y_t[0] / 2.0
  other_traps = delta_x_t[1:] * (y_t[1:] + y_t[:nbins - 1]) / 2.0
  return math_ops.add(first_trap, math_ops.reduce_sum(other_traps), name='auc')
Ejemplo n.º 15
0
def _PostProcessOutput(extended_acc_state, extended_final_state, func_cell,
                       total_time, inputs_lengths, is_reversed):
  """Post-process output of recurrent.

  This function takes the accumulated extended state and extracts the requested
  state and output.

  When `inputs_lengths` has been set, it extracts the output from the
  accumulated state. It also sets outputs past.

  When `is_reversed` is true, the output will be reversed in this function.

  It also sets the static shape information.

  Args:
    extended_acc_state: A structure containing the accumulated state at each
      time. It may contain the output at each time as well.
    extended_final_state: A structure containing the final state. It may
      contain the output at the final time.
    func_cell: The functional wrapper around the cell.
    total_time: A scalar integer tensor.
    inputs_lengths: An integer tensor with one entry per input.
    is_reversed: A boolean to indicate if the sequence is reversed.

  Returns:
    A tuple with the outputs at each time, and the final state.
  """
  if inputs_lengths is None or is_reversed:
    flat_final_state = func_cell.MaybeRemoveOutputFromState(
        nest.flatten(extended_final_state))
    tf_state = nest.pack_sequence_as(func_cell.state_template, flat_final_state)
  else:
    # The accumulated state is over the entire sequence, so we pick it
    # out from the acc_state sequence.
    flat_acc_state = func_cell.MaybeRemoveOutputFromState(
        nest.flatten(extended_acc_state))
    acc_state = nest.pack_sequence_as(
        func_cell.state_template, flat_acc_state)
    tf_state = _PickFinalStateFromHistory(acc_state, inputs_lengths)

  output_from_state = func_cell.GetOutputFromState(extended_acc_state)
  if is_reversed:
    output_from_state = array_ops.reverse(output_from_state, [0])
  tf_output = array_ops.transpose(output_from_state, [1, 0, 2])
  tf_output.set_shape(
      [func_cell.output_shape[0], total_time, func_cell.output_shape[1]])
  if inputs_lengths is not None:
    # Need set the outputs to zero.
    tf_output = _ApplyLengthsToBatch(inputs_lengths, tf_output)
  _SetShapeFromTemplate(tf_state, func_cell.state_template)
  return tf_output, tf_state
Ejemplo n.º 16
0
  def _AssertReverseEqual(self, revdims, shape):
    np.random.seed(120)
    pval = np.random.randint(0, 100, size=shape).astype(float)
    with self.test_session():
      with self.test_scope():
        p = array_ops.placeholder(dtypes.int32, shape=shape)
        axis = constant_op.constant(
            np.array(revdims, dtype=np.int32),
            shape=(len(revdims),), dtype=dtypes.int32)
        rval = array_ops.reverse(p, axis).eval({p: pval})

        slices = [
            slice(-1, None, -1) if d in revdims else slice(None)
            for d in range(len(shape))]
      self.assertEqual(
          pval[slices].flatten().tolist(),
          rval.flatten().tolist())
Ejemplo n.º 17
0
def functional_rnn(cell,
                   inputs,
                   sequence_length=None,
                   initial_state=None,
                   dtype=None,
                   time_major=False,
                   scope=None,
                   use_tpu=False,
                   reverse=False):
  """Same interface as `tf.nn.dynamic_rnn`."""
  with variable_scope.variable_scope(scope or 'rnn'):
    if not time_major:
      inputs = nest.map_structure(
          lambda t: array_ops.transpose(t, [1, 0, 2]), inputs)
    inputs_flat = nest.flatten(inputs)
    batch_size = array_ops.shape(inputs_flat[0])[1]
    if initial_state is None:
      initial_state = cell.zero_state(batch_size, dtype)
    func_cell = _FunctionalRnnCell(cell, inputs, initial_state)
  if sequence_length is not None:
    max_length = math_ops.reduce_max(sequence_length)
  else:
    max_length = None
  if reverse:
    inputs = array_ops.reverse(inputs, [0])
  extended_acc_state, extended_final_state = recurrent.Recurrent(
      theta=func_cell.theta,
      state0=func_cell.extended_initial_state,
      inputs=inputs,
      cell_fn=func_cell.cell_step,
      max_input_length=max_length,
      use_tpu=use_tpu,
      aligned_end=reverse)

  tf_output, tf_state = _PostProcessOutput(
      extended_acc_state,
      extended_final_state,
      func_cell,
      inputs_flat[0].shape[0],
      sequence_length,
      is_reversed=reverse)

  if time_major:
    tf_output = array_ops.transpose(tf_output, [1, 0, 2])
  return tf_output, tf_state
Ejemplo n.º 18
0
def flip_left_right(image):
  """Flip an image horizontally (left to right).

  Outputs the contents of `image` flipped along the second dimension, which is
  `width`.

  See also `reverse()`.

  Args:
    image: A 3-D tensor of shape `[height, width, channels].`

  Returns:
    A 3-D tensor of the same type and shape as `image`.

  Raises:
    ValueError: if the shape of `image` not supported.
  """
  _Check3DImage(image, require_static=False)
  return array_ops.reverse(image, [False, True, False])
Ejemplo n.º 19
0
def flip_up_down(image):
  """Flip an image horizontally (upside down).

  Outputs the contents of `image` flipped along the first dimension, which is
  `height`.

  See also `reverse()`.

  Args:
    image: A 3-D tensor of shape `[height, width, channels].`

  Returns:
    A 3-D tensor of the same type and shape as `image`.

  Raises:
    ValueError: if the shape of `image` not supported.
  """
  _Check3DImage(image)
  return array_ops.reverse(image, [True, False, False])
Ejemplo n.º 20
0
  def _reverse(self, t, lengths):
    """Time reverse the provided tensor or list of tensors.

    Assumes the top dimension is the time dimension.

    Args:
      t: 3D tensor or list of 2D tensors to be reversed
      lengths: 1D tensor of lengths, or None

    Returns:
      A reversed tensor or list of tensors
    """
    if isinstance(t, list):
      return list(reversed(t))
    else:
      if lengths is None:
        return array_ops.reverse(t, [True, False, False])
      else:
        return array_ops.reverse_sequence(t, lengths, 0, 1)
Ejemplo n.º 21
0
def flip_up_down(image):
  """Flip an image horizontally (upside down).

  Outputs the contents of `image` flipped along the first dimension, which is
  `height`.

  See also `reverse()`.

  Args:
    image: A 3-D tensor of shape `[height, width, channels].`

  Returns:
    A 3-D tensor of the same type and shape as `image`.

  Raises:
    ValueError: if the shape of `image` not supported.
  """
  image = ops.convert_to_tensor(image, name='image')
  _Check3DImage(image, require_static=False)
  return fix_image_flip_shape(image, array_ops.reverse(image, [0]))
Ejemplo n.º 22
0
def random_flip_left_right(image, seed=None):
  """Randomly flip an image horizontally (left to right).

  With a 1 in 2 chance, outputs the contents of `image` flipped along the
  second dimension, which is `width`.  Otherwise output the image as-is.

  Args:
    image: A 3-D tensor of shape `[height, width, channels].`
    seed: A Python integer. Used to create a random seed. See
      [`set_random_seed`](../../api_docs/python/constant_op.md#set_random_seed)
      for behavior.

  Returns:
    A 3-D tensor of the same type and shape as `image`.

  Raises:
    ValueError: if the shape of `image` not supported.
  """
  _Check3DImage(image)
  uniform_random = random_ops.random_uniform([], 0, 1.0, seed=seed)
  mirror = math_ops.less(array_ops.pack([1.0, uniform_random, 1.0]), 0.5)
  return array_ops.reverse(image, mirror)
Ejemplo n.º 23
0
def random_flip_left_right(image, seed=None):
    """Randomly flip an image horizontally (left to right).

  With a 1 in 2 chance, outputs the contents of `image` flipped along the
  second dimension, which is `width`.  Otherwise output the image as-is.

  Args:
    image: A 3-D tensor of shape `[height, width, channels].`
    seed: A Python integer. Used to create a random seed. See
      [`set_random_seed`](../../api_docs/python/constant_op.md#set_random_seed)
      for behavior.

  Returns:
    A 3-D tensor of the same type and shape as `image`.

  Raises:
    ValueError: if the shape of `image` not supported.
  """
    _Check3DImage(image)
    uniform_random = random_ops.random_uniform([], 0, 1.0, seed=seed)
    mirror = math_ops.less(array_ops.pack([1.0, uniform_random, 1.0]), 0.5)
    return array_ops.reverse(image, mirror)
Ejemplo n.º 24
0
def is_sequence_right_padded(mask, time_major):
    """Check the mask tensor and see if it right padded.

  For CuDNN kernel, it uses the sequence length param to skip the tailing
  timestep. If the data is left padded, or not a strict right padding (has
  masked value in the middle of the sequence), then CuDNN kernel won't be work
  properly in those cases.

  Left padded data: [[False, False, True, True, True]].
  Right padded data: [[True, True, True, False, False]].
  Mixture of mask/unmasked data: [[True, False, True, False, False]].

  Note that for the mixed data example above, the actually data RNN should see
  are those 2 Trues (index 0 and 2), the index 1 False should be ignored and not
  pollute the internal states.

  Args:
    mask: the Boolean tensor with shape [batch, timestep] or [timestep, batch]
      when time_major is True.
    time_major: Boolean, whether the input mask is time major or batch major.

  Returns:
    boolean scalar tensor, whether the mask is strictly right padded.
  """
    timestep_index = 0 if time_major else 1
    max_seq_length = array_ops.shape(mask)[timestep_index]
    reversed_mask = math_ops.cast(
        array_ops.reverse(mask, axis=[timestep_index]), dtypes.int32)
    # Use the argmax to find the index of leading 1 in the reversed mask, which is
    # the index of the last True value in the original mask.
    index = math_ops.argmax(reversed_mask,
                            axis=timestep_index,
                            output_type=dtypes.int32)
    count_of_true = math_ops.reduce_sum(reversed_mask, axis=timestep_index)
    # If the data is strictly right padded, then the
    # "index = max_seq_length - count_of_true" should hold.
    return math_ops.reduce_all(
        math_ops.equal(index, max_seq_length - count_of_true))
Ejemplo n.º 25
0
def random_flip_up_down(image, seed=None):
    """Randomly flips an image vertically (upside down).

  With a 1 in 2 chance, outputs the contents of `image` flipped along the first
  dimension, which is `height`.  Otherwise output the image as-is.

  Args:
    image: A 3-D tensor of shape `[height, width, channels].`
    seed: A Python integer. Used to create a random seed. See
      [`set_random_seed`](../../api_docs/python/constant_op.md#set_random_seed)
      for behavior.

  Returns:
    A 3-D tensor of the same type and shape as `image`.

  Raises:
    ValueError: if the shape of `image` not supported.
  """
    image = ops.convert_to_tensor(image, name='image')
    _Check3DImage(image, require_static=False)
    uniform_random = random_ops.random_uniform([], 0, 1.0, seed=seed)
    mirror = math_ops.less(array_ops.pack([uniform_random, 1.0, 1.0]), 0.5)
    return array_ops.reverse(image, mirror)
Ejemplo n.º 26
0
def is_sequence_right_padded(mask, time_major):
  """Check the mask tensor and see if it right padded.

  For CuDNN kernel, it uses the sequence length param to skip the tailing
  timestep. If the data is left padded, or not a strict right padding (has
  masked value in the middle of the sequence), then CuDNN kernel won't be work
  properly in those cases.

  Left padded data: [[False, False, True, True, True]].
  Right padded data: [[True, True, True, False, False]].
  Mixture of mask/unmasked data: [[True, False, True, False, False]].

  Note that for the mixed data example above, the actually data RNN should see
  are those 2 Trues (index 0 and 2), the index 1 False should be ignored and not
  pollute the internal states.

  Args:
    mask: the Boolean tensor with shape [batch, timestep] or [timestep, batch]
      when time_major is True.
    time_major: Boolean, whether the input mask is time major or batch major.

  Returns:
    boolean scalar tensor, whether the mask is strictly right padded.
  """
  timestep_index = 0 if time_major else 1
  max_seq_length = array_ops.shape(mask)[timestep_index]
  reversed_mask = math_ops.cast(array_ops.reverse(mask, axis=[timestep_index]),
                                dtypes.int32)
  # Use the argmax to find the index of leading 1 in the reversed mask, which is
  # the index of the last True value in the original mask.
  index = math_ops.argmax(reversed_mask, axis=timestep_index,
                          output_type=dtypes.int32)
  count_of_true = math_ops.reduce_sum(reversed_mask, axis=timestep_index)
  # If the data is strictly right padded, then the
  # "index = max_seq_length - count_of_true" should hold.
  return math_ops.reduce_all(
      math_ops.equal(index, max_seq_length - count_of_true))
 def _to_dense(self):
   total_shape = array_ops.broadcast_dynamic_shape(
       array_ops.shape(self.row), array_ops.shape(self.col))
   n = array_ops.shape(self.row)[-1]
   row = array_ops.broadcast_to(self.row, total_shape)
   col = array_ops.broadcast_to(self.col, total_shape)
   # We concatenate the column in reverse order to the row.
   # This gives us 2*n + 1 elements.
   elements = array_ops.concat(
       [array_ops.reverse(col, axis=[-1]), row[..., 1:]], axis=-1)
   # Given the above vector, the i-th row of the Toeplitz matrix
   # is the last n elements of the above vector shifted i right
   # (hence the first row is just the row vector provided, and
   # the first element of each row will belong to the column vector).
   # We construct these set of indices below.
   indices = math_ops.mod(
       # How much to shift right. This corresponds to `i`.
       math_ops.range(0, n) +
       # Specifies the last `n` indices.
       math_ops.range(n - 1, -1, -1)[..., array_ops.newaxis],
       # Mod out by the total number of elements to ensure the index is
       # non-negative (for tf.gather) and < 2 * n - 1.
       2 * n - 1)
   return array_ops.gather(elements, indices, axis=-1)
Ejemplo n.º 28
0
def gpu_lstm(inputs, init_h, init_c, kernel, recurrent_kernel, bias, mask,
             time_major, go_backwards, sequence_lengths):
  """LSTM with either CuDNN or ROCm implementation which is only available for GPU.

  Note that currently only right padded data is supported, or the result will be
  polluted by the unmasked data which should be filtered.

  Args:
    inputs: Input tensor of LSTM layer.
    init_h: Initial state tensor for the cell output.
    init_c: Initial state tensor for the cell hidden state.
    kernel: Weights for cell kernel.
    recurrent_kernel: Weights for cell recurrent kernel.
    bias: Weights for cell kernel bias and recurrent bias. Only recurrent bias
      is used in this case.
    mask: Boolean tensor for mask out the steps within sequence.
    time_major: Boolean, whether the inputs are in the format of [time, batch,
      feature] or [batch, time, feature].
    go_backwards: Boolean (default False). If True, process the input sequence
      backwards and return the reversed sequence.
    sequence_lengths: The lengths of all sequences coming from a variable length
      input, such as ragged tensors. If the input has a fixed timestep size,
      this should be None.

  Returns:
    last_output: Output tensor for the last timestep, which has shape
      [batch, units].
    outputs: Output tensor for all timesteps, which has shape
      [batch, time, units].
    state_0: The cell output, which has same shape as init_h.
    state_1: The cell hidden state, which has same shape as init_c.
    runtime: Constant string tensor which indicate real runtime hardware. This
      value is for testing purpose and should not be used by user.
  """
  if not time_major and mask is None:
    inputs = array_ops.transpose(inputs, perm=(1, 0, 2))
    seq_axis, batch_axis = (0, 1)
  else:
    seq_axis, batch_axis = (0, 1) if time_major else (1, 0)
  # For init_h and init_c, cuDNN expects one more dim of num_layers before or
  # after batch dim for time major or batch major inputs respectively
  init_h = array_ops.expand_dims(init_h, axis=seq_axis)
  init_c = array_ops.expand_dims(init_c, axis=seq_axis)

  weights = array_ops.split(kernel, 4, axis=1)
  weights += array_ops.split(recurrent_kernel, 4, axis=1)
  # CuDNN has an extra set of bias for inputs, we disable them (setting to 0),
  # so that mathematically it is same as the canonical LSTM implementation.
  full_bias = array_ops.concat((array_ops.zeros_like(bias), bias), 0)

  if build_info.is_rocm_build:
    # ROCm MIOpen's weight sequence for LSTM is different from both canonical
    # and Cudnn format
    # MIOpen: [i, f, o, c] Cudnn/Canonical: [i, f, c, o]
    # i is input gate weights.
    # f is forget gate weights.
    # o is output gate weights.
    # c is cell gate weights.
    weights = [weights[x] for x in (0, 1, 3, 2, 4, 5, 7, 6)]
    # full_bias is a tensor of shape (8*n,)
    full_bias = array_ops.split(full_bias, 8, axis=0)
    full_bias = [full_bias[x] for x in (0, 1, 3, 2, 4, 5, 7, 6)]

  params = _canonical_to_params(
      weights=weights,
      biases=array_ops.split(full_bias, 8),
      shape=constant_op.constant([-1]),
      transpose_weights=True)

  if mask is not None:
    sequence_lengths = calculate_sequence_by_mask(mask, time_major)

  if sequence_lengths is not None:
    if go_backwards:
      # Three reversals are required. E.g.,
      # normal input = [1, 2, 3, 0, 0]  # where 0 need to be masked
      # reversed_input_to_cudnn = [3, 2, 1, 0, 0]
      # output_from_cudnn = [6, 5, 4, 0, 0]
      # expected_output = [0, 0, 6, 5 ,4]
      inputs = array_ops.reverse_sequence_v2(
          inputs, sequence_lengths, seq_axis=seq_axis, batch_axis=batch_axis)
    outputs, h, c, _, _ = gen_cudnn_rnn_ops.cudnn_rnnv3(
        inputs,
        input_h=init_h,
        input_c=init_c,
        params=params,
        is_training=True,
        rnn_mode='lstm',
        sequence_lengths=sequence_lengths,
        time_major=time_major)
    if go_backwards:
      outputs = array_ops.reverse_sequence_v2(
          outputs, sequence_lengths, seq_axis=seq_axis, batch_axis=batch_axis)
      outputs = array_ops.reverse(outputs, axis=[seq_axis])
  else:
    # # Fill the array with shape [batch] with value of max timesteps.
    # sequence_length = array_ops.fill([array_ops.shape(inputs)[1]],
    #                                  array_ops.shape(inputs)[0])
    if go_backwards:
      # Reverse axis 0 since the input is already convert to time major.
      inputs = array_ops.reverse(inputs, axis=[0])
    outputs, h, c, _ = gen_cudnn_rnn_ops.cudnn_rnn(
        inputs, input_h=init_h, input_c=init_c, params=params, is_training=True,
        rnn_mode='lstm')

  last_output = outputs[-1]
  if not time_major and mask is None:
    outputs = array_ops.transpose(outputs, perm=[1, 0, 2])
  h = array_ops.squeeze(h, axis=seq_axis)
  c = array_ops.squeeze(c, axis=seq_axis)

  # In the case of variable length input, the cudnn kernel will fill zeros for
  # the output, whereas the default keras behavior is to bring over the previous
  # output for t-1, so that in the return_sequence=False case, user can quickly
  # get the final effect output instead just 0s at the last timestep.
  # In order to mimic the default keras behavior, we copy the final h state as
  # the last_output, since it is numerically same as the output.
  if mask is not None:
    last_output = h
  return last_output, outputs, h, c, _runtime(_RUNTIME_GPU)
Ejemplo n.º 29
0
 def loop_fn(i):
     x1 = array_ops.gather(x, i)
     return (array_ops.reverse(x1, axis=[0]),
             array_ops.reverse(x1, axis=[-1]),
             array_ops.reverse(x1, axis=[1, -1]))
Ejemplo n.º 30
0
def _FFTSizeForGrad(grad, rank):
  return math_ops.reduce_prod(
      array_ops.slice(
          array_ops.reverse(array_ops.shape(grad), (True,)), (0,), (rank,)))
Ejemplo n.º 31
0
def _ReverseGrad(op, grad):
    reverse_dims = op.inputs[1]
    return array_ops.reverse(grad, reverse_dims), None
Ejemplo n.º 32
0
 def _rot270():
     return array_ops.reverse(array_ops.transpose(image, [1, 0, 2]),
                              [False, True, False])
    def __init__(self,
                 n,
                 alpha,
                 name='DirichletMultinomial',
                 allow_arbitrary_counts=False):
        """Initialize a batch of DirichletMultinomial distributions.

    Args:
      n:  Non-negative `float` or `double` tensor with shape
        broadcastable to `[N1,..., Nm]` with `m >= 0`.  Defines this as a batch
        of `N1 x ... x Nm` different Dirichlet multinomial distributions. Its
        components should be equal to integral values.
      alpha:  Positive `float` or `double` tensor with shape broadcastable to
        `[N1,..., Nm, k]` `m >= 0`.  Defines this as a batch of `N1 x ... x Nm`
         different `k` class Dirichlet multinomial distributions.
      name: The name to prefix Ops created by this distribution class.
      allow_arbitrary_counts: Boolean. This represents whether the pmf/cdf
        allows for the `counts` tensor to be non-integral values.
        The pmf/cdf are functions that can be evaluated at non-integral values,
        but are only a distribution over non-negative integers.

    Examples:

    ```python
    # Define 1-batch of 2-class Dirichlet multinomial distribution,
    # also known as a beta-binomial.
    dist = DirichletMultinomial(2.0, [1.1, 2.0])

    # Define a 2-batch of 3-class distributions.
    dist = DirichletMultinomial([3., 4], [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
    ```
    """
        with ops.op_scope([n, alpha], name):
            # Broadcasting works because:
            # * The broadcasting convention is to prepend dimensions of size [1], and
            #   we use the last dimension for the distribution, wherease
            #   the batch dimensions are the leading dimensions, which forces the
            #   distribution dimension to be defined explicitly (i.e. it cannot be
            #   created automatically by prepending).  This forces enough
            #   explicitivity.
            #   * All calls involving `counts` eventually require a broadcast between
            #   `counts` and alpha.
            self._alpha = _check_alpha(alpha)
            self._name = name

            n = _check_n(n)
            n = math_ops.cast(n, self._alpha.dtype)
            self._n = n

            self._allow_arbitrary_counts = allow_arbitrary_counts

            alpha_sum = math_ops.reduce_sum(self._alpha,
                                            reduction_indices=[-1],
                                            keep_dims=False)

            mean = self._alpha / array_ops.expand_dims(alpha_sum, -1)
            self._mean = array_ops.expand_dims(n, -1) * mean

            self._batch_shape = array_ops.shape(alpha_sum)
            self._get_batch_shape = alpha_sum.get_shape()

            self._event_shape = array_ops.reverse(array_ops.shape(self._mean),
                                                  [True])[0]
            self._get_event_shape = self._mean.get_shape().with_rank_at_least(
                1)[-1:]
Ejemplo n.º 34
0
def multi_dimentional_rnn(rnn_size,
                          input_data,
                          sh,
                          dims=None,
                          scope_name="layer1"):
    """Implements naive multidimentional recurent neural networks

  Args:
    rnn_size: int, the hidden units
    input_data: (num_images, height, width, depth) tensor,
    the data to process of shape
    sh: list, [heigth,width] of the windows
    dims: list, dimentions to reverse the input data
    scope_name: string,  the scope

  Returns:
    (batch,h/sh[0],w/sh[1],chanels*sh[0]*sh[1]) tensor
  """
    with vs.variable_scope("MultiDimentionalLSTMCell-" + scope_name):
        cell = MultiDimentionalLSTMCell(rnn_size)

        shape = input_data.get_shape().as_list()

        #pad if the dimmention are not correct for the block size
        if shape[1] % sh[0] != 0:
            offset = array_ops.zeros(
                [shape[0], sh[0] - (shape[1] % sh[0]), shape[2], shape[3]])
            input_data = array_ops.concat([input_data, offset], 1)
            shape = input_data.get_shape().as_list()
        if shape[2] % sh[1] != 0:
            offset = array_ops.zeros(
                [shape[0], shape[1], sh[1] - (shape[2] % sh[1]), shape[3]])
            input_data = array_ops.concat([input_data, offset], 2)
            shape = input_data.get_shape().as_list()

        h, w = int(shape[1] / sh[0]), int(shape[2] / sh[1])
        features = sh[1] * sh[0] * shape[3]
        batch_size = shape[0]

        lines = array_ops.split(input_data, h, axis=1)
        line_blocks = []
        for line in lines:
            line = array_ops.transpose(line, [0, 2, 3, 1])
            line = array_ops.reshape(line, [batch_size, w, features])
            line_blocks.append(line)
        x = array_ops.stack(line_blocks, axis=1)
        if dims is not None:
            x = array_ops.reverse(x, dims)
        x = array_ops.transpose(x, [1, 2, 0, 3])
        x = array_ops.reshape(x, [-1, features])
        x = array_ops.split(x, h * w, 0)

        inputs_ta = tensor_array_ops.TensorArray(dtype=dtypes.float32,
                                                 size=h * w,
                                                 name='input_ta')
        inputs_ta = inputs_ta.unstack(x)
        states_ta = tensor_array_ops.TensorArray(dtype=dtypes.float32,
                                                 size=h * w + 1,
                                                 name='state_ta',
                                                 clear_after_read=False)
        outputs_ta = tensor_array_ops.TensorArray(dtype=dtypes.float32,
                                                  size=h * w,
                                                  name='output_ta')

        states_ta = states_ta.write(
            h * w,
            rnn.LSTMStateTuple(
                array_ops.zeros([batch_size, rnn_size], dtypes.float32),
                array_ops.zeros([batch_size, rnn_size], dtypes.float32)))

        def get_index_state_up(t, w):
            """get_index_state_up"""
            return control_flow_ops.cond(
                math_ops.less_equal(array_ops.constant(w),
                                    t), lambda: t - array_ops.constant(w),
                lambda: array_ops.constant(h * w))

        def get_index_state_last(t, w):
            """get_index_state_last"""
            return control_flow_ops.cond(
                math_ops.less(array_ops.constant(0),
                              math_ops.mod(t, array_ops.constant(w))),
                lambda: t - array_ops.constant(1),
                lambda: array_ops.constant(h * w))

        time = array_ops.constant(0)

        def body(time, outputs_ta, states_ta):
            """Implements multi dimmentions lstm while_loop

      Args:
        time: int
        outputs_ta: tensor_array
        states_ta: tensor_array
      """
            constant_val = array_ops.constant(0)
            state_up = control_flow_ops.cond(
                math_ops.less_equal(array_ops.constant(w), time),
                lambda: states_ta.read(get_index_state_up(time, w)),
                lambda: states_ta.read(h * w))
            state_last = control_flow_ops.cond(
                math_ops.less(constant_val,
                              math_ops.mod(time, array_ops.constant(w))),
                lambda: states_ta.read(get_index_state_last(time, w)),
                lambda: states_ta.read(h * w))

            current_state = state_up[0], state_last[0], state_up[
                1], state_last[1]
            out, state = cell(inputs_ta.read(time), current_state)
            outputs_ta = outputs_ta.write(time, out)
            states_ta = states_ta.write(time, state)
            return time + 1, outputs_ta, states_ta

        def condition(time, outputs_ta, states_ta):
            return math_ops.less(time, array_ops.constant(h * w))

        _, outputs_ta, _ = control_flow_ops.while_loop(
            condition,
            body, [time, outputs_ta, states_ta],
            parallel_iterations=1)

        outputs = outputs_ta.stack()

        outputs = array_ops.reshape(outputs, [h, w, batch_size, rnn_size])
        outputs = array_ops.transpose(outputs, [2, 0, 1, 3])
        if dims is not None:
            outputs = array_ops.reverse(outputs, dims)

        return outputs
Ejemplo n.º 35
0
  def handle_l_s_t_m(cls, node, input_dict):
    # Get LSTM inputs
    X = node.inputs[0] # [seq_length, batch_size, input_size]
    W = node.inputs[1] # [num_directions, 4*hidden_size, input_size]
    R = node.inputs[2] # [num_directions, 4*hidden_size, hidden_size]
    B = node.inputs[3] # or 0  # [num_directions, 8*hidden_size]
    sequence_lens = node.inputs[4] if len(node.inputs) >= 5 else None # [batch_size]
    initial_h = node.inputs[5] if len(node.inputs) >= 6 else None # [num_directions, batch_size, hidden_size]
    initial_c = node.inputs[6] if len(node.inputs) >= 7 else None # [num_directions, batch_size, hidden_size]
    P = node.inputs[7] if len(node.inputs) == 8 else None  # [num_directions, 3*hidden_size]
    if P is not None:
      raise NotImplementedError("Peephole connections for LSTMs have not been implemented yet.")


    # Get LSTM attributes
    activation_alpha = node.attrs.get("activation_alpha", None) # Does not do anything yet
    activation_beta = node.attrs.get("activation_beta", None)   # Does not do anything yet
    direction = node.attrs.get("direction", "forward")
    if "activations" in node.attrs: # TODO: Warning in case of activations which are not supported by TF
      activations = list(map(lambda x: x.lower(), node.attrs["activations"]))
    else:
      if direction == "bidirectional":
        activations = ["sigmoid", "tanh", "tanh", "sigmoid", "tanh", "tanh"]
      else:
        activations = ["sigmoid", "tanh", "tanh"]
    clip = float(node.attrs["clip"]) if "clip" in node.attrs else None
    hidden_size = int(node.attrs["hidden_size"])
    input_forget = int(node.attrs.get("input_forget", "0"))
    output_sequence = int(node.attrs.get("output_sequence", "0"))


    # Read weights and create TensorFlow LSTMs, differentiating
    # between the unidirectional and the bidirectional case
    dummy_session = tf.Session()
    if direction == "forward" or direction == "reverse":
      W_weights = input_dict[W].eval(session=dummy_session)
      R_weights = input_dict[R].eval(session=dummy_session)
      B_weights = input_dict[B].eval(session=dummy_session)
      tf_kernel, tf_bias = extract_onnx_lstm_weights(W_weights, R_weights,  B_weights)

      tf_kern_init = tf.constant_initializer(tf_kernel, verify_shape=True, dtype=tf.float32)
      tf_bias_init = tf.constant_initializer(tf_bias, verify_shape=True, dtype=tf.float32)
      tf_initial_state = tf.contrib.rnn.LSTMStateTuple(tf.reshape(input_dict[initial_c], (1,hidden_size)) , tf.reshape(input_dict[initial_h], (1,hidden_size)))
      tf_activation = ONNX_OP_TO_TF_OP[activations[2]]

      # Create TensorFlow LSTM cell
      tf_cell = OnnxLSTMCell(hidden_size,
                          kernel_initializer=tf_kern_init,
                          bias_initializer=tf_bias_init,
                          activation = tf_activation,
                          cell_clip=clip)

      if direction == "reverse":
        tf_lstm_input = array_ops.reverse(input_dict[X], axis=0)
      else:
        tf_lstm_input = input_dict[X]

      outputs, (last_cell, last_hidden) = tf.nn.dynamic_rnn(tf_cell,
                                          tf_lstm_input,
                                          time_major=True,
                                          initial_state=tf_initial_state)
    
      return [outputs, last_hidden, last_cell]

      
    else: # direction == "bidirectional"
      raise NotImplementedError("Bidirectional LSTMs have not been implemented yet.")
Ejemplo n.º 36
0
def fill_triangular(x, upper=False, name=None):
    """Creates a (batch of) triangular matrix from a vector of inputs.
    Created matrix can be lower- or upper-triangular. (It is more efficient to
    create the matrix as upper or lower, rather than transpose.)
    Triangular matrix elements are filled in a clockwise spiral. See example,
    below.
    If `x.get_shape()` is `[b1, b2, ..., bK, d]` then the output shape is `[b1,
    b2, ..., bK, n, n]` where `n` is such that `d = n(n+1)/2`, i.e.,
    `n = int(np.sqrt(0.25 + 2. * m) - 0.5)`.
    Example:
    ```python
    fill_triangular([1, 2, 3, 4, 5, 6])
    # ==> [[4, 0, 0],
    #      [6, 5, 0],
    #      [3, 2, 1]]
    fill_triangular([1, 2, 3, 4, 5, 6], upper=True)
    # ==> [[1, 2, 3],
    #      [0, 5, 6],
    #      [0, 0, 4]]
    ```
    For comparison, a pure numpy version of this function can be found in
    `util_test.py`, function `_fill_triangular`.
    Args:
      x: `Tensor` representing lower (or upper) triangular elements.
      upper: Python `bool` representing whether output matrix should be upper
        triangular (`True`) or lower triangular (`False`, default).
      name: Python `str`. The name to give this op.
    Returns:
      tril: `Tensor` with lower (or upper) triangular elements filled from `x`.
    Raises:
      ValueError: if `x` cannot be mapped to a triangular matrix.
    """

    with ops.name_scope(name, "fill_triangular", values=[x]):
        x = ops.convert_to_tensor(x, name="x")
        if x.shape.with_rank_at_least(1)[-1].value is not None:
            # Formula derived by solving for n: m = n(n+1)/2.
            m = np.int32(x.shape[-1].value)
            n = np.sqrt(0.25 + 2. * m) - 0.5
            if n != np.floor(n):
                raise ValueError(
                    "Input right-most shape ({}) does not "
                    "correspond to a triangular matrix.".format(m))
            n = np.int32(n)
            static_final_shape = x.shape[:-1].concatenate([n, n])
        else:
            m = array_ops.shape(x)[-1]
            # For derivation, see above. Casting automatically lops off the 0.5, so we
            # omit it.  We don't validate n is an integer because this has
            # graph-execution cost; an error will be thrown from the reshape, below.
            n = math_ops.cast(
                math_ops.sqrt(0.25 +
                              math_ops.cast(2 * m, dtype=dtypes.float32)),
                dtype=dtypes.int32)
            static_final_shape = x.shape.with_rank_at_least(
                1)[:-1].concatenate([None, None])
        # We now concatenate the "tail" of `x` to `x` (and reverse one of them).
        #
        # We do this based on the insight that the input `x` provides `ceil(n/2)`
        # rows of an `n x n` matrix, some of which will get zeroed out being on the
        # wrong side of the diagonal. The first row will not get zeroed out at all,
        # and we need `floor(n/2)` more rows, so the first is what we omit from
        # `x_tail`. If we then stack those `ceil(n/2)` rows with the `floor(n/2)`
        # rows provided by a reversed tail, it is exactly the other set of elements
        # of the reversed tail which will be zeroed out for being on the wrong side
        # of the diagonal further up/down the matrix. And, in doing-so, we've filled
        # the triangular matrix in a clock-wise spiral pattern. Neat!
        #
        # Try it out in numpy:
        #  n = 3
        #  x = np.arange(n * (n + 1) / 2)
        #  m = x.shape[0]
        #  n = np.int32(np.sqrt(.25 + 2 * m) - .5)
        #  x_tail = x[(m - (n**2 - m)):]
        #  np.concatenate([x_tail, x[::-1]], 0).reshape(n, n)  # lower
        #  # ==> array([[3, 4, 5],
        #               [5, 4, 3],
        #               [2, 1, 0]])
        #  np.concatenate([x, x_tail[::-1]], 0).reshape(n, n)  # upper
        #  # ==> array([[0, 1, 2],
        #               [3, 4, 5],
        #               [5, 4, 3]])
        #
        # Note that we can't simply do `x[..., -(n**2 - m):]` because this doesn't
        # correctly handle `m == n == 1`. Hence, we do nonnegative indexing.
        # Furthermore observe that:
        #   m - (n**2 - m)
        #   = n**2 / 2 + n / 2 - (n**2 - n**2 / 2 + n / 2)
        #   = 2 (n**2 / 2 + n / 2) - n**2
        #   = n**2 + n - n**2
        #   = n
        if upper:
            x_list = [x, array_ops.reverse(x[..., n:], axis=[-1])]
        else:
            x_list = [x[..., n:], array_ops.reverse(x, axis=[-1])]
        new_shape = (static_final_shape.as_list()
                     if static_final_shape.is_fully_defined() else
                     array_ops.concat([array_ops.shape(x)[:-1], [n, n]],
                                      axis=0))
        x = array_ops.reshape(array_ops.concat(x_list, axis=-1), new_shape)
        x = array_ops.matrix_band_part(x,
                                       num_lower=(0 if upper else -1),
                                       num_upper=(-1 if upper else 0))
        x.set_shape(static_final_shape)
        return x
Ejemplo n.º 37
0
    def __init__(self,
                 col,
                 row,
                 is_non_singular=None,
                 is_self_adjoint=None,
                 is_positive_definite=None,
                 is_square=None,
                 name="LinearOperatorToeplitz"):
        r"""Initialize a `LinearOperatorToeplitz`.

    Args:
      col: Shape `[B1,...,Bb, N]` `Tensor` with `b >= 0` `N >= 0`.
        The first column of the operator. Allowed dtypes: `float16`, `float32`,
          `float64`, `complex64`, `complex128`. Note that the first entry of
          `col` is assumed to be the same as the first entry of `row`.
      row: Shape `[B1,...,Bb, N]` `Tensor` with `b >= 0` `N >= 0`.
        The first row of the operator. Allowed dtypes: `float16`, `float32`,
          `float64`, `complex64`, `complex128`. Note that the first entry of
          `row` is assumed to be the same as the first entry of `col`.
      is_non_singular:  Expect that this operator is non-singular.
      is_self_adjoint:  Expect that this operator is equal to its hermitian
        transpose.  If `diag.dtype` is real, this is auto-set to `True`.
      is_positive_definite:  Expect that this operator is positive definite,
        meaning the quadratic form `x^H A x` has positive real part for all
        nonzero `x`.  Note that we do not require the operator to be
        self-adjoint to be positive-definite.  See:
        https://en.wikipedia.org/wiki/Positive-definite_matrix#Extension_for_non-symmetric_matrices
      is_square:  Expect that this operator acts like square [batch] matrices.
      name: A name for this `LinearOperator`.
    """

        with ops.name_scope(name, values=[row, col]):
            self._row = ops.convert_to_tensor(row, name="row")
            self._col = ops.convert_to_tensor(col, name="col")
            self._check_row_col(self._row, self._col)

            circulant_col = array_ops.concat([
                self._col,
                array_ops.zeros_like(self._col[..., 0:1]),
                array_ops.reverse(self._row[..., 1:], axis=[-1])
            ],
                                             axis=-1)

            # To be used for matmul.
            self._circulant = linear_operator_circulant.LinearOperatorCirculant(
                fft_ops.fft(_to_complex(circulant_col)),
                input_output_dtype=self._row.dtype)

            if is_square is False:  # pylint:disable=g-bool-id-comparison
                raise ValueError(
                    "Only square Toeplitz operators currently supported.")
            is_square = True

            super(LinearOperatorToeplitz,
                  self).__init__(dtype=self._row.dtype,
                                 graph_parents=[self._row, self._col],
                                 is_non_singular=is_non_singular,
                                 is_self_adjoint=is_self_adjoint,
                                 is_positive_definite=is_positive_definite,
                                 is_square=is_square,
                                 name=name)
Ejemplo n.º 38
0
 def _event_shape(self):
     return array_ops.reverse(array_ops.shape(self.alpha), [True])[0]
Ejemplo n.º 39
0
    def __call__(self,
                 inputs,
                 seq_len=None,
                 batch_first=True,
                 scope='bidirection_cudnn_rnn',
                 reuse=None):
        if batch_first:
            # transpose to batch second
            inputs = tf.transpose(inputs, [1, 0, 2])
        outputs = [inputs]

        with tf.variable_scope(scope, reuse=reuse):
            for layer in range(self.num_layers):
                (init_rw_c, init_rw_h), (init_bw_c,
                                         init_bw_h) = self.inits[layer]
                rnn_fw, rnn_bw = self.rnns[layer]
                mask_fw, mask_bw = self.dropout_mask[layer]

                # forward
                with tf.variable_scope("fw_{}".format(layer)):
                    if self.kernel == 'lstm':
                        initial_state = (init_rw_c, init_rw_h)
                    else:
                        initial_state = (init_rw_c, )

                    out_fw, state_fw = rnn_fw(outputs[-1] * mask_fw,
                                              initial_state=initial_state)

                # backword
                with tf.variable_scope("bw_{}".format(layer)):
                    if self.kernel == 'lstm':
                        initial_state = (init_rw_c, init_rw_h)
                    else:
                        initial_state = (init_rw_c, )
                    if seq_len is not None:
                        inputs_bw = tf.reverse_sequence(outputs[-1] * mask_bw,
                                                        seq_lengths=seq_len,
                                                        seq_dim=0,
                                                        batch_dim=1)
                    else:
                        inputs_bw = array_ops.reverse(outputs[-1] * mask_bw,
                                                      axis=[0])

                    out_bw, state_bw = rnn_bw(inputs_bw,
                                              initial_state=initial_state)
                    if seq_len is not None:
                        out_bw = tf.reverse_sequence(out_bw,
                                                     seq_lengths=seq_len,
                                                     seq_dim=0,
                                                     batch_dim=1)
                    else:
                        out_bw = array_ops.reverse(out_bw, axis=[0])

                outputs.append(tf.concat([out_fw, out_bw], axis=2))

            res = tf.concat(outputs[1:], axis=2)

            if batch_first:
                # transpose back
                res = tf.transpose(res, [1, 0, 2])

            if self.kernel == 'lstm':
                C = tf.concat([state_fw[0][0], state_bw[0][0]], axis=1)
                H = tf.concat([state_fw[1][0], state_bw[1][0]], axis=1)
                return res, C, H
            C = tf.concat([state_fw[0][0], state_bw[0][0]], axis=1)
            return res, C
Ejemplo n.º 40
0
 def _reverse(input_, seq_dim):
     return array_ops.reverse(input_, axis=[seq_dim])
Ejemplo n.º 41
0
def _ReverseGrad(op, grad):
  reverse_dims = op.inputs[1]
  return array_ops.reverse(grad, reverse_dims), None
Ejemplo n.º 42
0
  def create_batch(self):
    """Create queues to window and batch time series data.

    Returns:
      A dictionary of Tensors corresponding to the output of `self._reader`
      (from the `time_series_reader` constructor argument), each with shapes
      prefixed by [`batch_size`, `window_size`].
    """
    features = self._reader.read()
    if self._jitter:
      # TODO(agarwal, allenl): Figure out if more jitter is needed here.
      jitter = random_ops.random_uniform(shape=[], maxval=2, dtype=dtypes.int32)
    else:
      jitter = 0
    # To keep things efficient, we pass from the windowing batcher to the
    # batch-of-windows batcher in batches. This avoids the need for huge numbers
    # of threads, but does mean that jitter is only applied occasionally.
    # TODO(allenl): Experiment with different internal passing sizes.
    internal_passing_size = self._batch_size
    features_windowed = input_lib.batch(
        features,
        batch_size=self._window_size * internal_passing_size + jitter,
        enqueue_many=True,
        capacity=(self._queue_capacity_multiplier
                  * internal_passing_size * self._window_size),
        num_threads=self._num_threads)
    raw_features_windowed = features_windowed
    if self._jitter:
      features_windowed = {
          key: value[jitter:]
          for key, value in features_windowed.items()}
    features_windowed = {
        key: array_ops.reshape(
            value,
            array_ops.concat(
                [[internal_passing_size, self._window_size],
                 array_ops.shape(value)[1:]],
                axis=0))
        for key, value in features_windowed.items()}
    batch_and_window_shape = tensor_shape.TensorShape(
        [internal_passing_size, self._window_size])
    for key in features_windowed.keys():
      features_windowed[key].set_shape(
          batch_and_window_shape.concatenate(
              raw_features_windowed[key].get_shape()[1:]))
    # When switching files, we may end up with windows where the time is not
    # decreasing, even if times within each file are sorted (and even if those
    # files are visited in order, when looping back around to the beginning of
    # the first file). This is hard for models to deal with, so we either
    # discard such examples, creating a bias where the beginning and end of the
    # series is under-sampled, or we sort the window, creating large gaps.
    times = features_windowed[feature_keys.TrainEvalFeatures.TIMES]
    if self._discard_out_of_order:
      non_decreasing = math_ops.reduce_all(
          times[:, 1:] >= times[:, :-1], axis=1)
      # Ensure that no more than self._discard_limit complete batches are
      # discarded contiguously (resetting the count when we find a single clean
      # window). This prevents infinite looping when the dataset is smaller than
      # the window size.
      # TODO(allenl): Figure out a way to return informative errors from
      # count_up_to.
      discarded_windows_limiter = variable_scope.variable(
          initial_value=constant_op.constant(0, dtype=dtypes.int64),
          name="discarded_windows_limiter",
          trainable=False,
          collections=[ops.GraphKeys.LOCAL_VARIABLES])
      def _initialized_limit_check():
        return control_flow_ops.cond(
            math_ops.reduce_any(non_decreasing),
            lambda: state_ops.assign(discarded_windows_limiter, 0),
            lambda: discarded_windows_limiter.count_up_to(self._discard_limit))
      discard_limit_op = control_flow_ops.cond(
          state_ops.is_variable_initialized(discarded_windows_limiter),
          _initialized_limit_check,
          lambda: constant_op.constant(0, dtype=dtypes.int64))
      with ops.control_dependencies([discard_limit_op]):
        non_decreasing = array_ops.identity(non_decreasing)
    else:
      _, indices_descending = nn.top_k(
          times, k=array_ops.shape(times)[-1], sorted=True)
      indices = array_ops.reverse(indices_descending, axis=[0])
      features_windowed = {
          key: array_ops.gather(params=value, indices=indices)
          for key, value in features_windowed.items()
      }
      non_decreasing = True
    features_batched = input_lib.maybe_shuffle_batch(
        features_windowed,
        num_threads=self._num_threads,
        seed=self._shuffle_seed,
        batch_size=self._batch_size,
        capacity=self._queue_capacity_multiplier * self._batch_size,
        min_after_dequeue=(self._shuffle_min_after_dequeue_multiplier *
                           self._batch_size),
        keep_input=non_decreasing,
        enqueue_many=True)
    return (features_batched, None)
Ejemplo n.º 43
0
 def _rot180():
     return array_ops.reverse(image, [True, True, False])
Ejemplo n.º 44
0
 def _get_num_classes(self):
     return ops.convert_to_tensor(array_ops.reverse(
         array_ops.shape(self._alpha), [True])[0],
                                  name='num_classes')
Ejemplo n.º 45
0
def circular_convolution(shift, w_i, N, S, zero_pad=False):
    '''
    This method convolves the shift output from the controller with the
    interpolated address vector, which can move the location that the address
    is pointing to.
    It's just like regular convolution, just imagine that one of the things
    that's being convolved is repeated an infinite number of times on both
    sides so that you never have to convolve with zeros. This implementation
    is kinda of tough to follow because it performs circular convolution
    between matrices (rank(2) tensors), not just vectors.

    Arguments:
      shift - Rank(2) tensor with [BxS] elements indicating the magnitude and
        direction by which the address vector will be shifted for every batch.
        This is produced by the controller, so in most cases it won't be rows
        of one-hots.
      w_i - Rank(2) tensor with [BxN] elements corresponding to interpolated
        addresses.
      N - Integer number of memory locations in the memory matrix.
      S - Integer number of shifts that can be applied to the interpolated
        address.
      zero_pad - Not used, left because I'm a code packrat.

    Outputs:
      op(w_conv) - An operation to stack the individual, shifted tensors into
        one big tensor.
    '''

    #shift_rev = array_ops.reverse(shift, axis=[1])
    zeros = array_ops.zeros_like(shift)

    split_loc = N % S
    center = int(S / 2)
    #print('center:', center)
    #center = 1

    if not zero_pad:
        num_tiles = max(int(N / S), 0)
        if num_tiles > 0:
            shift_tile = array_ops.tile(shift, [1, num_tiles])
        else:
            shift_tile = shift

        if split_loc > 0:
            tack = array_ops.split(shift, [split_loc, -1], axis=1)[0]
            shift_long = array_ops.concat([shift_tile, tack], axis=1)

    else:
        num_tiles = max(int((N - S) / S), 0)
        if num_tiles > 0:
            zeros_tile = array_ops.tile(zeros, [1, num_tiles])
        else:
            zeros_tile = zeros

        if split_loc > 0:
            tack = array_ops.split(zeros, [split_loc, -1], axis=1)[0]
            shift_long = array_ops.concat([shift, zeros_tile, tack], axis=1)

    #shift_rev_ = array_ops.reverse(shift_long, axis=[1])
    center_split = array_ops.split(shift_long, [center, -1], axis=1)
    shift_rev_ = array_ops.concat([center_split[1], center_split[0]], axis=1)
    shift_rev = array_ops.reverse(shift_rev_, axis=[1])

    circ = []
    for j in range(N):
        loc = (j + 1) % N
        shift_split = array_ops.split(shift_rev, [N - loc, loc], axis=1)
        circ.append(array_ops.concat([shift_split[1], shift_split[0]], axis=1))

    w_conv = [math_ops.reduce_sum(w_i * c, axis=1) for c in circ]

    return array_ops.stack(w_conv, axis=1)
Ejemplo n.º 46
0
 def even_s(off, size):
     off = array_ops.reshape(off, [-1, size // 2, 2])
     off = array_ops.reshape(array_ops.reverse(off, [2]),
                             [-1, size])
     return off
Ejemplo n.º 47
0
def get_augmented_images(images, output_shape):

    # Store transformations and augmented_images for the input batch
    transformations = []
    augmented_images = []

    # Augmentation option
    min_scale = 1/1.5 
    max_scale = 1.5 
    max_aspect_ratio=1.5 
    max_hue=0.05 
    max_brightness=0.05 
    max_saturation=1.25 
    max_contrast=1.25 
    horizontal_flip=True 

    for i in range(len(images)):

        image = images[i]
        image = _utils.convert_shared_float_array_to_numpy(image)
        
        height, width, _ = tf.unstack(tf.shape(image))
        scale_h = tf.random_uniform([], minval=min_scale, maxval=max_scale)
        scale_w = scale_h * tf.exp(tf.random_uniform([], minval=-np.log(max_aspect_ratio), maxval=np.log(max_aspect_ratio)))
        new_height = tf.to_int32(tf.to_float(height) * scale_h)
        new_width = tf.to_int32(tf.to_float(width) * scale_w)

        image_scaled = tf.squeeze(tf.image.resize_bilinear(tf.expand_dims(image, 0), [new_height, new_width]), [0])
        # Image padding
        pad_image, pad_offset = pad_to_ensure_size(image_scaled, output_shape[0], output_shape[1])

        new_height = tf.maximum(output_shape[0], new_height)
        new_width = tf.maximum(output_shape[1], new_width)

        slice_offset = (tf.random_uniform([], minval=0, maxval=new_height - output_shape[0] + 1, dtype=tf.int32),
                        tf.random_uniform([], minval=0, maxval=new_width - output_shape[1] + 1, dtype=tf.int32))
        augmented_image = array_ops.slice(pad_image, [slice_offset[0], slice_offset[1], 0], [output_shape[0], output_shape[1], 3])

        if horizontal_flip:
            uniform_random = random_ops.random_uniform([], 0, 1.0)
            did_horiz_flip = math_ops.less(uniform_random, .5)
            augmented_image = control_flow_ops.cond(did_horiz_flip,
                                             lambda: array_ops.reverse(augmented_image, [1]),
                                             lambda: augmented_image)
            flip_sign = 1 - tf.to_float(did_horiz_flip) * 2
        else:
            flip_sign = 1
            did_horiz_flip = tf.constant(False)

        ty = tf.to_float(pad_offset[0] - slice_offset[0] ) 
        tx = flip_sign * tf.to_float(pad_offset[1] - slice_offset[1] ) + tf.to_float(did_horiz_flip) * output_shape[1]

        # Make the transformation matrix
        transformation = tf.reshape(tf.stack([
            scale_h, 0.0,                  ty,
            0.0,     flip_sign * scale_w,   tx,
            0.0,     0.0,                 1.0]
            ), (3, 3))

        if max_hue is not None and max_hue > 0:
            image = tf.image.random_hue(augmented_image, max_delta=max_hue)

        if max_brightness is not None and max_brightness > 0:
            image = tf.image.random_brightness(augmented_image, max_delta=max_brightness)

        if max_saturation is not None and max_saturation > 1.0:
            log_sat = np.log(max_saturation)
            image = tf.image.random_saturation(augmented_image, lower=np.exp(-log_sat), upper=np.exp(log_sat))

        if max_contrast is not None and max_contrast > 1.0:
            log_con = np.log(max_contrast)
            image = tf.image.random_contrast(augmented_image, lower=np.exp(-log_con), upper=np.exp(log_con))

        augmented_image = tf.clip_by_value(augmented_image, 0, 1)
        augmented_images.append(augmented_image)
        transformations.append(transformation)
        
    return augmented_images, transformations
Ejemplo n.º 48
0
 def modify(off_normal, dist, normal_size):
     off_normal = array_ops.reshape(array_ops.reverse(array_ops.reshape(off_normal, [-1, normal_size//(2**dist), 2, (2**(dist-1))]), [2]), [-1, normal_size])
     return off_normal
Ejemplo n.º 49
0
def rnn(step_fn,
        inputs,
        initial_states,
        go_backwards=False,
        unroll=False,
        input_length=None,
        name='rnn_block'):
    with ops.name_scope(name):
        dim = ndim(inputs)
        if dim < 3:
            raise ValueError("Input should be at least 3D")
        perm = [1, 0] + list(range(2, dim))
        inputs = array_ops.transpose(inputs, perm=perm, name='to_time_major')
        if unroll:
            assert int_shape(inputs)[0] is not None,\
                "Unrolling requires a fixed number of time steps"
            states = initial_states
            successive_states = []
            successive_outputs = []
            input_list = array_ops.unstack(inputs)
            if go_backwards:
                input_list.reverse()
            for x in input_list:
                outputs, states = step_fn(x, states)
                successive_outputs.append(outputs)
                successive_states.append(states)
            last_output = successive_outputs[-1]
            new_states = successive_states[-1]
            outputs = array_ops.stack(successive_outputs)
        else:
            if go_backwards:
                inputs = array_ops.reverse(inputs, axis=0)
            states = tuple(initial_states)
            time_steps = array_ops.shape(inputs)[0]
            outputs, _ = step_fn(inputs[0], initial_states)
            output_ta = tensor_array_ops.TensorArray(
                dtype=outputs.dtype,
                size=time_steps,
                tensor_array_name='output_ta')
            input_ta = tensor_array_ops.TensorArray(
                dtype=inputs.dtype,
                size=time_steps,
                tensor_array_name='input_ta')
            # unstack inputs and write into input array
            input_ta = input_ta.unstack(inputs)
            time = array_ops.constant(0, dtype='int32', name='time')

            def _step(_time, _output_ta, *_states):
                current_input = input_ta.read(_time)
                output, _new_states = step_fn(current_input, tuple(_states))
                for state, new_state in zip(_states, _new_states):
                    new_state.set_shape(state.get_shape())
                _output_ta = _output_ta.write(_time, output)
                return (_time + 1, _output_ta) + tuple(_new_states)

            final_outputs = control_flow_ops.while_loop(
                cond=lambda _time, *_: _time < time_steps,
                body=_step,
                loop_vars=(time, output_ta) + states,
                parallel_iterations=32,
                swap_memory=True,
                maximum_iterations=input_length)
            last_time = final_outputs[0]
            output_ta = final_outputs[1]
            new_states = final_outputs[2:]
            outputs = output_ta.stack()
            last_output = output_ta.read(last_time - 1)
        perm = [1, 0] + list(range(2, ndim(outputs)))
        outputs = array_ops.transpose(outputs, perm=perm)
    return last_output, outputs, new_states
Ejemplo n.º 50
0
def inverse_mdct(mdcts,
                 window_fn=window_ops.vorbis_window,
                 norm=None,
                 name=None):
    """Computes the inverse modified DCT of `mdcts`.

  To reconstruct an original waveform, the same window function should
  be used with `mdct` and `inverse_mdct`.

  Example usage:

  >>> @tf.function
  ... def compare_round_trip():
  ...   samples = 1000
  ...   frame_length = 400
  ...   halflen = frame_length // 2
  ...   waveform = tf.random.normal(dtype=tf.float32, shape=[samples])
  ...   waveform_pad = tf.pad(waveform, [[halflen, 0],])
  ...   mdct = tf.signal.mdct(waveform_pad, frame_length, pad_end=True,
  ...                         window_fn=tf.signal.vorbis_window)
  ...   inverse_mdct = tf.signal.inverse_mdct(mdct,
  ...                                         window_fn=tf.signal.vorbis_window)
  ...   inverse_mdct = inverse_mdct[halflen: halflen + samples]
  ...   return waveform, inverse_mdct
  >>> waveform, inverse_mdct = compare_round_trip()
  >>> np.allclose(waveform.numpy(), inverse_mdct.numpy(), rtol=1e-3, atol=1e-4)
  True

  Implemented with TPU/GPU-compatible ops and supports gradients.

  Args:
    mdcts: A `float32`/`float64` `[..., frames, frame_length // 2]`
      `Tensor` of MDCT bins representing a batch of `frame_length // 2`-point
      MDCTs.
    window_fn: A callable that takes a window length and a `dtype` keyword
      argument and returns a `[window_length]` `Tensor` of samples in the
      provided datatype. If set to `None`, no windowing is used.
    norm: If "ortho", orthonormal inverse DCT4 is performed, if it is None,
      a regular dct4 followed by scaling of `1/frame_length` is performed.
    name: An optional name for the operation.

  Returns:
    A `[..., samples]` `Tensor` of `float32`/`float64` signals representing
    the inverse MDCT for each input MDCT in `mdcts` where `samples` is
    `(frames - 1) * (frame_length // 2) + frame_length`.

  Raises:
    ValueError: If `mdcts` is not at least rank 2.

  [mdct]: https://en.wikipedia.org/wiki/Modified_discrete_cosine_transform
  """
    with ops.name_scope(name, 'inverse_mdct', [mdcts]):
        mdcts = ops.convert_to_tensor(mdcts, name='mdcts')
        mdcts.shape.with_rank_at_least(2)
        half_len = math_ops.cast(mdcts.shape[-1], dtype=dtypes.int32)

        if norm is None:
            half_len_float = math_ops.cast(half_len, dtype=mdcts.dtype)
            result_idct4 = (0.5 / half_len_float) * dct_ops.dct(mdcts, type=4)
        elif norm == 'ortho':
            result_idct4 = dct_ops.dct(mdcts, type=4, norm='ortho')
        split_result = array_ops.split(result_idct4, 2, axis=-1)
        real_frames = array_ops.concat(
            (split_result[1], -array_ops.reverse(split_result[1], [-1]),
             -array_ops.reverse(split_result[0], [-1]), -split_result[0]),
            axis=-1)

        # Optionally window and overlap-add the inner 2 dimensions of real_frames
        # into a single [samples] dimension.
        if window_fn is not None:
            window = window_fn(2 * half_len, dtype=mdcts.dtype)
            real_frames *= window
        else:
            real_frames *= 1.0 / np.sqrt(2)
        return reconstruction_ops.overlap_and_add(real_frames, half_len)
Ejemplo n.º 51
0
 def testReverse0DimAuto(self):
     x_np = 4
     for use_gpu in [False, True]:
         with self.test_session(use_gpu=use_gpu):
             x_tf = array_ops.reverse(x_np, []).eval()
             self.assertAllEqual(x_tf, x_np)
Ejemplo n.º 52
0
 def _rot180():
   return array_ops.reverse(image, [True, True, False])
Ejemplo n.º 53
0
def _FFTSizeForGrad(grad, rank):
    return math_ops.reduce_prod(
        array_ops.slice(array_ops.reverse(array_ops.shape(grad), (True, )),
                        (0, ), (rank, )))
Ejemplo n.º 54
0
 def _rot270():
   return array_ops.reverse(array_ops.transpose(image, [1, 0, 2]),
                            [False, True, False])
Ejemplo n.º 55
0
def load_keypoints_from_quantiles(feature_names,
                                  save_dir,
                                  num_keypoints,
                                  output_min,
                                  output_max,
                                  reversed_dict=None,
                                  missing_input_values_dict=None,
                                  dtype=dtypes.float32):
  """Retrieves keypoints initialization values for selected features.

  It expects that the quantiles have already been calculated and saved in the
  save_dir by the save_quantiles_for_keypoints function. It will raise
  an I/O error if not.

  Args:
    feature_names: List of features names for which to get keypoints
      initialization values.
    save_dir: Directory where the quantiles have been saved to. Same value used
      when save_quantiles_for_keypoints was called.
    num_keypoints: Desired number of keypoints to use for calibration. This
      can either be a scalar to be used for all features, or a dict mapping
      feature name to num_keypoints. Fewer keypoints than requested can end
      up being used when for the given feature there are not enough different
      values. If num_keypoints for a feature is missing, None or 0, no
      initialization is generated.
    output_min: Initial calibrated value associated with the first calibration
      keypoint. The keypoints outputs in between will be linearly interpolated.
      It can be given as a scalar, in which case value is used for all features,
      or a dict mapping feature name to output_min.
    output_max: Like output_min, but the calibrated value associated to the
      last keypoint. Scalar or dict.
    reversed_dict: An optional dict. If reversed_dict[feature_name] is True,
      then the initial output keypoints will be in reversed order for that
      feature, i.e., input_min will be mapped to output_max, and input_max will
      be mapped to output_min. Reversing output keypoints is useful for
      decreasing monotonic calibrators.
    missing_input_values_dict: An optional dict. If provided, it should include
      all features passed via feature_names. If the value of
      missing_input_values[feature_name] is Not none, it is excluded from the
      input keypoint values.
    dtype: Type to be used for calibration.

  Returns:
    Dict of feature name to pair of constant tensors that can be used to
    initialize calibrators keypoints inputs and outputs.

  Raises:
    tf.errors.NotFoundError: if quantiles file not found.


    values in the signal. This would probably be better handled as categorical,
    but still this should handle the case correctly.
  """
  subdir = os.path.join(save_dir, _QUANTILES_SUBDIRECTORY)
  num_keypoints = tools.cast_to_dict(num_keypoints, feature_names,
                                     num_keypoints)
  output_min = tools.cast_to_dict_of_tensor_scalars(output_min, feature_names,
                                                    dtype, "output_min")
  output_max = tools.cast_to_dict_of_tensor_scalars(output_max, feature_names,
                                                    dtype, "output_max")

  keypoints = {}
  for feature_name in feature_names:
    if feature_name not in num_keypoints or not num_keypoints[feature_name]:
      continue
    all_quantiles = _load_quantiles(subdir, feature_name)
    if (missing_input_values_dict is not None and
        feature_name in missing_input_values_dict):
      exclude_val = missing_input_values_dict[feature_name]
      if exclude_val is not None:
        all_quantiles = [q for q in all_quantiles if q != exclude_val]
    percentiles = np.linspace(0., 100., num_keypoints[feature_name])
    quantiles = np.percentile(
        all_quantiles, percentiles, interpolation="nearest")
    quantiles = sorted(set(quantiles))  # Remove repeated quantiles.
    input_kpts = array_ops.constant(
        quantiles, shape=[len(quantiles)], dtype=dtype)
    output_kpts = math_ops.linspace(output_min[feature_name],
                                    output_max[feature_name], len(quantiles))
    if reversed_dict is not None and reversed_dict[feature_name]:
      output_kpts = array_ops.reverse(output_kpts, axis=[0])
    keypoints[feature_name] = (input_kpts, output_kpts)
  return keypoints
Ejemplo n.º 56
0
def mdct(signals,
         frame_length,
         window_fn=window_ops.vorbis_window,
         pad_end=False,
         norm=None,
         name=None):
    """Computes the [Modified Discrete Cosine Transform][mdct] of `signals`.

  Implemented with TPU/GPU-compatible ops and supports gradients.

  Args:
    signals: A `[..., samples]` `float32`/`float64` `Tensor` of real-valued
      signals.
    frame_length: An integer scalar `Tensor`. The window length in samples
      which must be divisible by 4.
    window_fn: A callable that takes a window length and a `dtype` keyword
      argument and returns a `[window_length]` `Tensor` of samples in the
      provided datatype. If set to `None`, no windowing is used.
    pad_end: Whether to pad the end of `signals` with zeros when the provided
      frame length and step produces a frame that lies partially past its end.
    norm: If it is None, unnormalized dct4 is used, if it is "ortho"
      orthonormal dct4 is used.
    name: An optional name for the operation.

  Returns:
    A `[..., frames, frame_length // 2]` `Tensor` of `float32`/`float64`
    MDCT values where `frames` is roughly `samples // (frame_length // 2)`
    when `pad_end=False`.

  Raises:
    ValueError: If `signals` is not at least rank 1, `frame_length` is
      not scalar, or `frame_length` is not a multiple of `4`.

  [mdct]: https://en.wikipedia.org/wiki/Modified_discrete_cosine_transform
  """
    with ops.name_scope(name, 'mdct', [signals, frame_length]):
        signals = ops.convert_to_tensor(signals, name='signals')
        signals.shape.with_rank_at_least(1)
        frame_length = ops.convert_to_tensor(frame_length, name='frame_length')
        frame_length.shape.assert_has_rank(0)
        # Assert that frame_length is divisible by 4.
        frame_length_static = tensor_util.constant_value(frame_length)
        if frame_length_static is not None:
            if frame_length_static % 4 != 0:
                raise ValueError('The frame length must be a multiple of 4.')
            frame_step = ops.convert_to_tensor(frame_length_static // 2,
                                               dtype=frame_length.dtype)
        else:
            frame_step = frame_length // 2

        framed_signals = shape_ops.frame(signals,
                                         frame_length,
                                         frame_step,
                                         pad_end=pad_end)

        # Optionally window the framed signals.
        if window_fn is not None:
            window = window_fn(frame_length, dtype=framed_signals.dtype)
            framed_signals *= window
        else:
            framed_signals *= 1.0 / np.sqrt(2)

        split_frames = array_ops.split(framed_signals, 4, axis=-1)
        frame_firsthalf = -array_ops.reverse(split_frames[2],
                                             [-1]) - split_frames[3]
        frame_secondhalf = split_frames[0] - array_ops.reverse(
            split_frames[1], [-1])
        frames_rearranged = array_ops.concat(
            (frame_firsthalf, frame_secondhalf), axis=-1)
        # Below call produces the (frame_length // 2) unique components of the
        # type 4 orthonormal DCT of the real windowed signals in frames_rearranged.
        return dct_ops.dct(frames_rearranged, type=4, norm=norm)
Ejemplo n.º 57
0
  def test_slicing(self):
    v = [
        variables_lib.Variable([[1, 2], [3, 4], [5, 6]]),
        variables_lib.Variable([[7, 8], [9, 10], [11, 12]]),
        variables_lib.Variable([[13, 14], [15, 16]])
    ]
    sv = sharded_variable.ShardedVariable(v)
    empty = v[0][0:0]

    # Test cases: positive step
    self.assertAllEqual(sv[:], array_ops.concat(v, axis=0))
    self.assertAllEqual(sv[:2], [[1, 2], [3, 4]])
    self.assertAllEqual(sv[-8:2], [[1, 2], [3, 4]])
    self.assertAllEqual(sv[-10:2], [[1, 2], [3, 4]])
    self.assertAllEqual(sv[5:], [[11, 12], [13, 14], [15, 16]])
    self.assertAllEqual(sv[5:-1], [[11, 12], [13, 14]])
    self.assertAllEqual(sv[::3], [[1, 2], [7, 8], [13, 14]])
    self.assertAllEqual(sv[::5], [[1, 2], [11, 12]])
    self.assertAllEqual(sv[1::6], [[3, 4], [15, 16]])
    self.assertAllEqual(sv[1:5:6], [[3, 4]])
    self.assertAllEqual(sv[1::7], [[3, 4]])
    self.assertAllEqual(sv[2:7], [[5, 6], [7, 8], [9, 10], [11, 12], [13, 14]])
    self.assertAllEqual(sv[2:7:2], [[5, 6], [9, 10], [13, 14]])
    self.assertAllEqual(sv[2:7:3], [[5, 6], [11, 12]])

    # Test cases: negative step
    self.assertAllEqual(
        sv[::-1], array_ops.reverse(array_ops.concat(v, axis=0), axis=[0]))
    self.assertAllEqual(sv[2::-1], [[5, 6], [3, 4], [1, 2]])
    self.assertAllEqual(sv[2:-8:-1], [[5, 6], [3, 4]])
    self.assertAllEqual(sv[2:-10:-1], [[5, 6], [3, 4], [1, 2]])
    self.assertAllEqual(sv[4::-1], [[9, 10], [7, 8], [5, 6], [3, 4], [1, 2]])
    self.assertAllEqual(sv[-1:-3:-1], [[15, 16], [13, 14]])
    self.assertAllEqual(sv[::-5], [[15, 16], [5, 6]])
    self.assertAllEqual(sv[6::-6], [[13, 14], [1, 2]])
    self.assertAllEqual(sv[6:5:-6], [[13, 14]])
    self.assertAllEqual(sv[6::-7], [[13, 14]])
    self.assertAllEqual(sv[7:1:-1],
                        [[15, 16], [13, 14], [11, 12], [9, 10], [7, 8], [5, 6]])
    self.assertAllEqual(sv[7:1:-2], [[15, 16], [11, 12], [7, 8]])
    self.assertAllEqual(sv[7:1:-4], [[15, 16], [7, 8]])

    # Test cases: empty slice
    self.assertAllEqual(sv[0:0], empty)
    self.assertAllEqual(sv[5:3], empty)
    self.assertAllEqual(sv[3:5:-1], empty)
    self.assertAllEqual(sv[-1:0], empty)
    self.assertAllEqual(sv[2:-1:-1], empty)

    # Test cases: slicing other dimensions
    self.assertAllEqual(sv[:, 0], [1, 3, 5, 7, 9, 11, 13, 15])
    self.assertAllEqual(sv[:, 0:1], [[1], [3], [5], [7], [9], [11], [13], [15]])

    # Test cases: normal indexing
    self.assertAllEqual(sv[2], [5, 6])
    self.assertAllEqual(sv[6], [13, 14])
    self.assertAllEqual(sv[2, 1], 6)
    self.assertAllEqual(sv[-2], [13, 14])
    with self.assertRaisesRegex(IndexError, 'out of bounds'):
      _ = sv[100]
    with self.assertRaisesRegex(IndexError, 'out of bounds'):
      _ = sv[-100]

    # Test cases: Ellipsis
    self.assertAllEqual(sv[...], array_ops.concat(v, axis=0))
    self.assertAllEqual(sv[..., 0], [1, 3, 5, 7, 9, 11, 13, 15])
    self.assertAllEqual(sv[0:1, ...], [[1, 2]])

    # Test cases: newaxis
    self.assertAllEqual(
        sv[array_ops.newaxis, ...],
        array_ops.expand_dims_v2(array_ops.concat(v, axis=0), axis=0))

    # Test cases: boolean masks
    self.assertAllEqual(sv[ops.convert_to_tensor(sv) > 10],
                        [11, 12, 13, 14, 15, 16])

    # Test cases: tensor input
    with self.assertRaisesRegex(TypeError, 'not allowed'):
      _ = sv[constant_op.constant(1)::]
    with self.assertRaisesRegex(TypeError, 'not allowed'):
      _ = sv[:constant_op.constant(1):]
    with self.assertRaisesRegex(TypeError, 'not allowed'):
      _ = sv[constant_op.constant(1)]

    # Test cases: inside tf.function
    @def_function.function
    def func():
      a = sv[:, 0]
      return a

    self.assertAllEqual(func(), [1, 3, 5, 7, 9, 11, 13, 15])
Ejemplo n.º 58
0
def fill_triangular(x, upper=False, name=None):
  """Creates a (batch of) triangular matrix from a vector of inputs.

  Created matrix can be lower- or upper-triangular. (It is more efficient to
  create the matrix as upper or lower, rather than transpose.)

  Triangular matrix elements are filled in a clockwise spiral. See example,
  below.

  If `x.get_shape()` is `[b1, b2, ..., bK, d]` then the output shape is `[b1,
  b2, ..., bK, n, n]` where `n` is such that `d = n(n+1)/2`, i.e.,
  `n = int(np.sqrt(0.25 + 2. * m) - 0.5)`.

  Example:

  ```python
  fill_triangular([1, 2, 3, 4, 5, 6])
  # ==> [[4, 0, 0],
  #      [6, 5, 0],
  #      [3, 2, 1]]

  fill_triangular([1, 2, 3, 4, 5, 6], upper=True)
  # ==> [[1, 2, 3],
  #      [0, 5, 6],
  #      [0, 0, 4]]
  ```

  For comparison, a pure numpy version of this function can be found in
  `util_test.py`, function `_fill_triangular`.

  Args:
    x: `Tensor` representing lower (or upper) triangular elements.
    upper: Python `bool` representing whether output matrix should be upper
      triangular (`True`) or lower triangular (`False`, default).
    name: Python `str`. The name to give this op.

  Returns:
    tril: `Tensor` with lower (or upper) triangular elements filled from `x`.

  Raises:
    ValueError: if `x` cannot be mapped to a triangular matrix.
  """

  with ops.name_scope(name, "fill_triangular", values=[x]):
    x = ops.convert_to_tensor(x, name="x")
    if x.shape.with_rank_at_least(1)[-1].value is not None:
      # Formula derived by solving for n: m = n(n+1)/2.
      m = np.int32(x.shape[-1].value)
      n = np.sqrt(0.25 + 2. * m) - 0.5
      if n != np.floor(n):
        raise ValueError("Input right-most shape ({}) does not "
                         "correspond to a triangular matrix.".format(m))
      n = np.int32(n)
      static_final_shape = x.shape[:-1].concatenate([n, n])
    else:
      m = array_ops.shape(x)[-1]
      # For derivation, see above. Casting automatically lops off the 0.5, so we
      # omit it.  We don't validate n is an integer because this has
      # graph-execution cost; an error will be thrown from the reshape, below.
      n = math_ops.cast(
          math_ops.sqrt(0.25 + math_ops.cast(2 * m, dtype=dtypes.float32)),
          dtype=dtypes.int32)
      static_final_shape = x.shape.with_rank_at_least(1)[:-1].concatenate(
          [None, None])
    # We now concatenate the "tail" of `x` to `x` (and reverse one of them).
    #
    # We do this based on the insight that the input `x` provides `ceil(n/2)`
    # rows of an `n x n` matrix, some of which will get zeroed out being on the
    # wrong side of the diagonal. The first row will not get zeroed out at all,
    # and we need `floor(n/2)` more rows, so the first is what we omit from
    # `x_tail`. If we then stack those `ceil(n/2)` rows with the `floor(n/2)`
    # rows provided by a reversed tail, it is exactly the other set of elements
    # of the reversed tail which will be zeroed out for being on the wrong side
    # of the diagonal further up/down the matrix. And, in doing-so, we've filled
    # the triangular matrix in a clock-wise spiral pattern. Neat!
    #
    # Try it out in numpy:
    #  n = 3
    #  x = np.arange(n * (n + 1) / 2)
    #  m = x.shape[0]
    #  n = np.int32(np.sqrt(.25 + 2 * m) - .5)
    #  x_tail = x[(m - (n**2 - m)):]
    #  np.concatenate([x_tail, x[::-1]], 0).reshape(n, n)  # lower
    #  # ==> array([[3, 4, 5],
    #               [5, 4, 3],
    #               [2, 1, 0]])
    #  np.concatenate([x, x_tail[::-1]], 0).reshape(n, n)  # upper
    #  # ==> array([[0, 1, 2],
    #               [3, 4, 5],
    #               [5, 4, 3]])
    #
    # Note that we can't simply do `x[..., -(n**2 - m):]` because this doesn't
    # correctly handle `m == n == 1`. Hence, we do nonnegative indexing.
    # Furthermore observe that:
    #   m - (n**2 - m)
    #   = n**2 / 2 + n / 2 - (n**2 - n**2 / 2 + n / 2)
    #   = 2 (n**2 / 2 + n / 2) - n**2
    #   = n**2 + n - n**2
    #   = n
    if upper:
      x_list = [x, array_ops.reverse(x[..., n:], axis=[-1])]
    else:
      x_list = [x[..., n:], array_ops.reverse(x, axis=[-1])]
    new_shape = (
        static_final_shape.as_list()
        if static_final_shape.is_fully_defined()
        else array_ops.concat([array_ops.shape(x)[:-1], [n, n]], axis=0))
    x = array_ops.reshape(array_ops.concat(x_list, axis=-1), new_shape)
    x = array_ops.matrix_band_part(
        x,
        num_lower=(0 if upper else -1),
        num_upper=(-1 if upper else 0))
    x.set_shape(static_final_shape)
    return x
Ejemplo n.º 59
0
 def testReverse0DimAuto(self):
   x_np = 4
   for use_gpu in [False, True]:
     with self.test_session(use_gpu=use_gpu):
       x_tf = array_ops.reverse(x_np, []).eval()
       self.assertAllEqual(x_tf, x_np)
Ejemplo n.º 60
0
    def create_batch(self):
        """Create queues to window and batch time series data.

    Returns:
      A dictionary of Tensors corresponding to the output of `self._reader`
      (from the `time_series_reader` constructor argument), each with shapes
      prefixed by [`batch_size`, `window_size`].
    """
        features = self._reader.read()
        if self._jitter:
            # TODO(agarwal, allenl): Figure out if more jitter is needed here.
            jitter = random_ops.random_uniform(shape=[],
                                               maxval=2,
                                               dtype=dtypes.int32)
        else:
            jitter = 0
        # To keep things efficient, we pass from the windowing batcher to the
        # batch-of-windows batcher in batches. This avoids the need for huge numbers
        # of threads, but does mean that jitter is only applied occasionally.
        # TODO(allenl): Experiment with different internal passing sizes.
        internal_passing_size = self._batch_size
        features_windowed = input_lib.batch(
            features,
            batch_size=self._window_size * internal_passing_size + jitter,
            enqueue_many=True,
            capacity=(self._queue_capacity_multiplier * internal_passing_size *
                      self._window_size),
            num_threads=self._num_threads)
        raw_features_windowed = features_windowed
        if self._jitter:
            features_windowed = {
                key: value[jitter:]
                for key, value in features_windowed.items()
            }
        features_windowed = {
            key: array_ops.reshape(
                value,
                array_ops.concat([[internal_passing_size, self._window_size],
                                  array_ops.shape(value)[1:]],
                                 axis=0))
            for key, value in features_windowed.items()
        }
        batch_and_window_shape = tensor_shape.TensorShape(
            [internal_passing_size, self._window_size])
        for key in features_windowed.keys():
            features_windowed[key].set_shape(
                batch_and_window_shape.concatenate(
                    raw_features_windowed[key].get_shape()[1:]))
        # When switching files, we may end up with windows where the time is not
        # decreasing, even if times within each file are sorted (and even if those
        # files are visited in order, when looping back around to the beginning of
        # the first file). This is hard for models to deal with, so we either
        # discard such examples, creating a bias where the beginning and end of the
        # series is under-sampled, or we sort the window, creating large gaps.
        times = features_windowed[feature_keys.TrainEvalFeatures.TIMES]
        if self._discard_out_of_order:
            non_decreasing = math_ops.reduce_all(times[:, 1:] >= times[:, :-1],
                                                 axis=1)
            # Ensure that no more than self._discard_limit complete batches are
            # discarded contiguously (resetting the count when we find a single clean
            # window). This prevents infinite looping when the dataset is smaller than
            # the window size.
            # TODO(allenl): Figure out a way to return informative errors from
            # count_up_to.
            discarded_windows_limiter = variable_scope.variable(
                initial_value=constant_op.constant(0, dtype=dtypes.int64),
                name="discarded_windows_limiter",
                trainable=False,
                collections=[ops.GraphKeys.LOCAL_VARIABLES])

            def _initialized_limit_check():
                return control_flow_ops.cond(
                    math_ops.reduce_any(non_decreasing),
                    lambda: state_ops.assign(discarded_windows_limiter, 0),
                    lambda: discarded_windows_limiter.count_up_to(
                        self._discard_limit))

            discard_limit_op = control_flow_ops.cond(
                state_ops.is_variable_initialized(discarded_windows_limiter),
                _initialized_limit_check,
                lambda: constant_op.constant(0, dtype=dtypes.int64))
            with ops.control_dependencies([discard_limit_op]):
                non_decreasing = array_ops.identity(non_decreasing)
        else:
            _, indices_descending = nn.top_k(times,
                                             k=array_ops.shape(times)[-1],
                                             sorted=True)
            indices = array_ops.reverse(indices_descending, axis=[0])
            features_windowed = {
                key: array_ops.gather(params=value, indices=indices)
                for key, value in features_windowed.items()
            }
            non_decreasing = True
        features_batched = input_lib.maybe_shuffle_batch(
            features_windowed,
            num_threads=self._num_threads,
            seed=self._shuffle_seed,
            batch_size=self._batch_size,
            capacity=self._queue_capacity_multiplier * self._batch_size,
            min_after_dequeue=(self._shuffle_min_after_dequeue_multiplier *
                               self._batch_size),
            keep_input=non_decreasing,
            enqueue_many=True)
        return (features_batched, None)