Exemple #1
0
 def _should_continue(a, b, f_a, f_b, t, num_iterations, converged):
     del a, b, f_a, f_b, t  # Unused.
     all_converged = stopping_policy_fn(
         tf.logical_or(converged, num_iterations >= max_iterations))
     return ~all_converged
Exemple #2
0
 def add_or_or(x1, x2):
   if x1.dtype == tf.bool:
     assert x2.dtype == tf.bool
     return tf.logical_or(x1, x2)
   return tf.add(x1, x2)
Exemple #3
0
 def max_or_or(x1, x2):
   if x1.dtype == tf.bool:
     assert x2.dtype == tf.bool
     return tf.logical_or(x1, x2)
   return tf.math.maximum(x1, x2)
def _calculate_spline_coeffs(x_data, y_data):
    """Calculates the coefficients for the spline interpolation.

  These are the values of the second derivative of the spline at `x_data`.
  See p.548 of [1].

  Below is an outline of the function when number of observations if equal to 7.
  The coefficients are obtained by building and solving a tridiagonal linear
  system of equations with symmetric matrix

   w2,  dx2,   0,   0,   0
   dx2,  w3, dx3,   0,   0
   0,  dx3,   w4, dx4,   0
   0,    0,  dx4,  w5, dx5
   0,    0,    0, dx5,  w6

   where:
   wn = 2 * (x_data[n-2] + x_data[n-1])
   dxn = x_data[n-1] - x_data[n-2]

   and the right hand side of the equation is:
   [[3*( (d2-d1)/X1 - (d1-d0)/x0],
    [3*( (d3-d2)/X2 - (d2-d1)/x1],
    ...
   ]

   with di = y_data[..., i]

   Solve for `spline_coeffs`, so that  matrix * spline_coeffs = rhs

   the solution is the `spline_coeffs` parameter of the spline equation:

   y_pred = a(spline_coeffs) * t^3 + b(spline_coeffs) * t^2
            + c(spline_coeffs) * t + d(spline_coeffs)
   with t being the proportion of the difference between the x value of
   the spline used and the nx_value of the next spline:

   t = (x_values - x_data[:,n]) / (x_data[:,n+1]-x_data[:,n])

   and `a`, `b`, `c`, and `d` are functions of `spline_coeffs` and `x_data` and
   are provided in the `interpolate` function.

  ## References:
  [1]: R. Sedgewick, Algorithms in C, 1990, p. 545-550.
    Link: http://index-of.co.uk/Algorithms/Algorithms%20in%20C.pdf

  Args:
    x_data: A real `Tensor` of shape `[..., num_points]` containing
      X-coordinates of points to fit the splines to. The values have to
      be monotonically non-decreasing along the last dimension.
    y_data: A `Tensor` of the same shape and `dtype` as `x_data` containing
      Y-coordinates of points to fit the splines to.

  Returns:
     A `Tensor` of the same shape and `dtype` as `x_data`. Represents the
     spline coefficients for the cubic spline interpolation.
  """

    # `dx` is the distances between the x points. It is 1 element shorter than
    # `x_data`
    dx = x_data[..., 1:] - x_data[..., :-1]

    # `diag_values` are the diagonal values 2 * (x_data[i+1] - x_data[i-1])
    # its length 2 shorter

    diag_values = 2.0 * (x_data[..., 2:] - x_data[..., :-2])
    superdiag = dx[..., 1:]
    subdiag = dx[..., :-1]

    corr_term = tf.logical_or(tf.equal(superdiag, 0), tf.equal(subdiag, 0))
    diag_values_corr = tf.where(corr_term, tf.ones_like(diag_values),
                                diag_values)
    superdiag_corr = tf.where(tf.equal(subdiag, 0), tf.zeros_like(superdiag),
                              superdiag)
    subdiag_corr = tf.where(tf.equal(superdiag, 0), tf.zeros_like(subdiag),
                            subdiag)
    diagonals = tf.stack([superdiag_corr, diag_values_corr, subdiag_corr],
                         axis=-2)

    # determine the rhs of the equation
    dd = (y_data[..., 1:] - y_data[..., :-1]) / dx
    dd = tf.where(tf.equal(dx, 0), tf.zeros_like(dd), dd)
    # rhs is a column vector:
    # [[-3((y1-y0)/dx0 - (y2-y1)/dx0], ...]
    rhs = -3 * (dd[..., :-1] - dd[..., 1:])
    rhs = tf.where(corr_term, tf.zeros_like(rhs), rhs)
    # Partial pivoting is unnecessary since the matrix is diagonally dominant.
    spline_coeffs = tf.linalg.tridiagonal_solve(diagonals,
                                                rhs,
                                                partial_pivoting=False)
    # Reshape `spline_coeffs`
    zero = tf.zeros_like(dx[..., :1], dtype=x_data.dtype)
    spline_coeffs = tf.concat([zero, spline_coeffs, zero], axis=-1)
    return spline_coeffs
Exemple #5
0
    def _maybe_validate_shape_override(self, override_shape, base_is_scalar_fn,
                                       static_base_shape, is_init):
        """Helper which ensures override batch/event_shape are valid."""

        assertions = []
        concretized_shape = None

        # Check valid dtype
        if is_init:  # No xor check because `dtype` cannot change.
            dtype_ = override_shape.dtype
            if dtype_ is None:
                if concretized_shape is None:
                    concretized_shape = tf.convert_to_tensor(override_shape)
                dtype_ = concretized_shape.dtype
            if dtype_util.base_dtype(dtype_) not in {tf.int32, tf.int64}:
                raise TypeError('Shape override must be integer type; '
                                'saw {}.'.format(dtype_util.name(dtype_)))

        # Check non-negative elements
        if is_init != tensor_util.is_ref(override_shape):
            override_shape_ = tf.get_static_value(override_shape)
            msg = 'Shape override must have non-negative elements.'
            if override_shape_ is not None:
                if np.any(np.array(override_shape_) < 0):
                    raise ValueError('{} Saw: {}'.format(msg, override_shape_))
            elif self.validate_args:
                if concretized_shape is None:
                    concretized_shape = tf.convert_to_tensor(override_shape)
                assertions.append(
                    assert_util.assert_non_negative(concretized_shape,
                                                    message=msg))

        # Check valid shape
        override_ndims_ = tensorshape_util.rank(override_shape.shape)
        if is_init != (override_ndims_ is None):
            msg = 'Shape override must be a vector.'
            if override_ndims_ is not None:
                if override_ndims_ != 1:
                    raise ValueError(msg)
            elif self.validate_args:
                if concretized_shape is None:
                    concretized_shape = tf.convert_to_tensor(override_shape)
                override_rank = tf.rank(concretized_shape)
                assertions.append(
                    assert_util.assert_equal(override_rank, 1, message=msg))

        static_base_rank = tensorshape_util.rank(static_base_shape)

        # Determine if the override shape is `[]` (static_override_dims == [0]),
        # in which case the base distribution may be nonscalar.
        static_override_dims = tensorshape_util.dims(override_shape.shape)

        if is_init != (static_base_rank is None
                       or static_override_dims is None):
            msg = 'Base distribution is not scalar.'
            if static_base_rank is not None and static_override_dims is not None:
                if static_base_rank != 0 and static_override_dims != [0]:
                    raise ValueError(msg)
            elif self.validate_args:
                if concretized_shape is None:
                    concretized_shape = tf.convert_to_tensor(override_shape)
                override_is_empty = tf.logical_not(
                    self._has_nonzero_rank(concretized_shape))
                assertions.append(
                    assert_util.assert_equal(tf.logical_or(
                        base_is_scalar_fn(), override_is_empty),
                                             True,
                                             message=msg))
        return assertions
Exemple #6
0
def assign_and_sample_proposals(proposed_boxes,
                                gt_boxes,
                                gt_classes,
                                num_samples_per_image=512,
                                mix_gt_boxes=True,
                                fg_fraction=0.25,
                                fg_iou_thresh=0.5,
                                bg_iou_thresh_hi=0.5,
                                bg_iou_thresh_lo=0.0):
    """Assigns the proposals with groundtruth classes and performs subsmpling.

  Given `proposed_boxes`, `gt_boxes`, and `gt_classes`, the function uses the
  following algorithm to generate the final `num_samples_per_image` RoIs.
    1. Calculates the IoU between each proposal box and each gt_boxes.
    2. Assigns each proposed box with a groundtruth class and box by choosing
       the largest IoU overlap.
    3. Samples `num_samples_per_image` boxes from all proposed boxes, and
       returns box_targets, class_targets, and RoIs.

  Args:
    proposed_boxes: a tensor of shape of [batch_size, N, 4]. N is the number
      of proposals before groundtruth assignment. The last dimension is the
      box coordinates w.r.t. the scaled images in [ymin, xmin, ymax, xmax]
      format.
    gt_boxes: a tensor of shape of [batch_size, MAX_NUM_INSTANCES, 4].
      The coordinates of gt_boxes are in the pixel coordinates of the scaled
      image. This tensor might have padding of values -1 indicating the invalid
      box coordinates.
    gt_classes: a tensor with a shape of [batch_size, MAX_NUM_INSTANCES]. This
      tensor might have paddings with values of -1 indicating the invalid
      classes.
    num_samples_per_image: a integer represents RoI minibatch size per image.
    mix_gt_boxes: a bool indicating whether to mix the groundtruth boxes before
      sampling proposals.
    fg_fraction: a float represents the target fraction of RoI minibatch that
      is labeled foreground (i.e., class > 0).
    fg_iou_thresh: a float represents the IoU overlap threshold for an RoI to be
      considered foreground (if >= fg_iou_thresh).
    bg_iou_thresh_hi: a float represents the IoU overlap threshold for an RoI to
      be considered background (class = 0 if overlap in [LO, HI)).
    bg_iou_thresh_lo: a float represents the IoU overlap threshold for an RoI to
      be considered background (class = 0 if overlap in [LO, HI)).

  Returns:
    sampled_rois: a tensor of shape of [batch_size, K, 4], representing the
      coordinates of the sampled RoIs, where K is the number of the sampled
      RoIs, i.e. K = num_samples_per_image.
    sampled_gt_boxes: a tensor of shape of [batch_size, K, 4], storing the
      box coordinates of the matched groundtruth boxes of the samples RoIs.
    sampled_gt_classes: a tensor of shape of [batch_size, K], storing the
      classes of the matched groundtruth boxes of the sampled RoIs.
    sampled_gt_indices: a tensor of shape of [batch_size, K], storing the
      indices of the sampled groudntruth boxes in the original `gt_boxes`
      tensor, i.e. gt_boxes[sampled_gt_indices[:, i]] = sampled_gt_boxes[:, i].
  """

    with tf.name_scope('sample_proposals'):
        if mix_gt_boxes:
            boxes = tf.concat([proposed_boxes, gt_boxes], axis=1)
        else:
            boxes = proposed_boxes

        (matched_gt_boxes, matched_gt_classes, matched_gt_indices, matched_iou,
         _) = box_matching(boxes, gt_boxes, gt_classes)

        positive_match = tf.greater(matched_iou, fg_iou_thresh)
        negative_match = tf.logical_and(
            tf.greater_equal(matched_iou, bg_iou_thresh_lo),
            tf.less(matched_iou, bg_iou_thresh_hi))
        ignored_match = tf.less(matched_iou, 0.0)

        # re-assign negatively matched boxes to the background class.
        matched_gt_classes = tf.where(negative_match,
                                      tf.zeros_like(matched_gt_classes),
                                      matched_gt_classes)
        matched_gt_indices = tf.where(negative_match,
                                      tf.zeros_like(matched_gt_indices),
                                      matched_gt_indices)

        sample_candidates = tf.logical_and(
            tf.logical_or(positive_match, negative_match),
            tf.logical_not(ignored_match))

        sampler = (
            balanced_positive_negative_sampler.BalancedPositiveNegativeSampler(
                positive_fraction=fg_fraction, is_static=True))

        batch_size, _ = sample_candidates.get_shape().as_list()
        sampled_indicators = []
        for i in range(batch_size):
            sampled_indicator = sampler.subsample(sample_candidates[i],
                                                  num_samples_per_image,
                                                  positive_match[i])
            sampled_indicators.append(sampled_indicator)
        sampled_indicators = tf.stack(sampled_indicators)
        _, sampled_indices = tf.nn.top_k(tf.cast(sampled_indicators,
                                                 dtype=tf.int32),
                                         k=num_samples_per_image,
                                         sorted=True)

        sampled_indices_shape = tf.shape(sampled_indices)
        batch_indices = (
            tf.expand_dims(tf.range(sampled_indices_shape[0]), axis=-1) *
            tf.ones([1, sampled_indices_shape[-1]], dtype=tf.int32))
        gather_nd_indices = tf.stack([batch_indices, sampled_indices], axis=-1)

        sampled_rois = tf.gather_nd(boxes, gather_nd_indices)
        sampled_gt_boxes = tf.gather_nd(matched_gt_boxes, gather_nd_indices)
        sampled_gt_classes = tf.gather_nd(matched_gt_classes,
                                          gather_nd_indices)
        sampled_gt_indices = tf.gather_nd(matched_gt_indices,
                                          gather_nd_indices)

        return (sampled_rois, sampled_gt_boxes, sampled_gt_classes,
                sampled_gt_indices)