示例#1
0
 def apply_hard_selection(self, scores):
     # <int32>[batch_size, seq_length]
     # Using argsort(argsort(.)) gives the rank of the score.
     sorted_indexes = tf.argsort(
         tf.argsort(scores, direction="DESCENDING", axis=-1, stable=True))
     # <float32>[batch_size, seq_length]
     mask = tf.cast(sorted_indexes <
                    tf.ones_like(sorted_indexes) * self._max_num_tokens,
                    dtype=tf.float32)
     return mask
示例#2
0
    def _face_model_map_fn(example):
        vertices = example['vertices']

        # Randomly shift vertices
        if apply_random_shift:
            vertices = random_shift(vertices)
        example['num_vertices'] = tf.shape(vertices)[0]

        # Optionally shuffle vertices and re-order faces to match
        if shuffle_vertices:
            permutation = tf.random_shuffle(tf.range(example['num_vertices']))
            vertices = tf.gather(vertices, permutation)
            face_permutation = tf.concat([
                tf.constant([0, 1], dtype=tf.int32),
                tf.argsort(permutation) + 2
            ],
                                         axis=0)
            example['faces'] = tf.cast(
                tf.gather(face_permutation, example['faces']), tf.int64)

        # Vertices are quantized. So convert to floats for input to face model
        example['vertices'] = modules.dequantize_verts(vertices,
                                                       quantization_bits)
        example['vertices_mask'] = tf.ones_like(example['vertices'][Ellipsis,
                                                                    0],
                                                dtype=tf.float32)
        example['faces_mask'] = tf.ones_like(example['faces'],
                                             dtype=tf.float32)
        return example
示例#3
0
def boolean_mask(tensor, mask):
    """Select elements from tensor where mask is True, and pads the rest with 0.

  Example:
    tensor = [1 2 3 4 5 6 7]
    mask   = [T T F F T T T]
    output = [1 2 5 6 7 0 0]

  Args:
    tensor: <T> [batch_size, dim, ...]
    mask: <bool> [batch_size, dim]

  Returns:
    masked_tensor: <T> [batch_size, dim, ...]. The first k items of row i
      correspond to the k truthy values in row i of the mask tensor,
      indexed into the provided tensor.
  """
    batch_size = shape(mask, 0)
    dim = shape(mask, 1)

    # Bring the coordinates of un-masked elements to the front.
    mask = tf.cast(mask, tensor.dtype)
    indices = tf.argsort(mask, axis=1, direction="DESCENDING", stable=True)
    batch_indices = tf.expand_dims(tf.range(tf.shape(mask)[0]), 1)
    batch_indices = tf.tile(batch_indices, [1, tf.shape(indices)[1]])
    coords = tf.stack([batch_indices, indices], axis=2)

    # Gather and zero masked elements.
    selected_tensor = tf.gather_nd(tensor, coords)
    selected_mask = tf.gather_nd(mask, coords)
    reshape = [batch_size, dim] + [1] * (tensor.get_shape().ndims - 2)
    selected_mask = tf.reshape(selected_mask, reshape)
    masked_tensor = selected_tensor * selected_mask

    return masked_tensor
示例#4
0
def _top_k_sample(logits, ignore_ids=None, num_samples=1, k=10):
    """
    Does top-k sampling. if ignore_ids is on, then we will zero out those logits.
    :param logits: [batch_size, vocab_size] tensor
    :param ignore_ids: [vocab_size] one-hot representation of the indices we'd like to ignore and never predict,
                        like padding maybe
    :param p: topp threshold to use, either a float or a [batch_size] vector
    :return: [batch_size, num_samples] samples

    # TODO FIGURE OUT HOW TO DO THIS ON TPUS. IT'S HELLA SLOW RIGHT NOW, DUE TO ARGSORT I THINK
    """
    with tf.variable_scope('top_p_sample'):
        batch_size, vocab_size = get_shape_list(logits, expected_rank=2)

        probs = tf.nn.softmax(logits if ignore_ids is None else logits - tf.cast(ignore_ids[None], tf.float32) * 1e10,
                              axis=-1)
        # [batch_size, vocab_perm]
        indices = tf.argsort(probs, direction='DESCENDING')

        # find the top pth index to cut off. careful we don't want to cutoff everything!
        # result will be [batch_size, vocab_perm]
        k_expanded = k if isinstance(k, int) else k[:, None]
        exclude_mask = tf.range(vocab_size)[None] >= k_expanded

        # OPTION A - sample in the sorted space, then unsort.
        logits_to_use = tf.batch_gather(logits, indices) - tf.cast(exclude_mask, tf.float32) * 1e10
        sample_perm = tf.random.categorical(logits=logits_to_use, num_samples=num_samples)
        sample = tf.batch_gather(indices, sample_perm)

    return {
        'probs': probs,
        'sample': sample,
    }
示例#5
0
def nms_tf(dets, thresh):
  """Non-maximum suppression with tf graph mode."""
  x1 = dets[:, 0]
  y1 = dets[:, 1]
  x2 = dets[:, 2]
  y2 = dets[:, 3]
  scores = dets[:, 4]

  areas = (x2 - x1 + 1) * (y2 - y1 + 1)
  order = tf.argsort(scores, direction='DESCENDING')

  keep = tf.TensorArray(tf.int32, size=0, dynamic_size=True)
  index = 0
  while tf.shape(order)[0] > 0:
    i = order[0]
    keep = keep.write(index, i)
    xx1 = tf.maximum(x1[i], tf.gather(x1, order[1:]))
    yy1 = tf.maximum(y1[i], tf.gather(y1, order[1:]))
    xx2 = tf.minimum(x2[i], tf.gather(x2, order[1:]))
    yy2 = tf.minimum(y2[i], tf.gather(y2, order[1:]))

    w = tf.maximum(0.0, xx2 - xx1 + 1)
    h = tf.maximum(0.0, yy2 - yy1 + 1)
    intersection = w * h
    overlap = intersection / (
        areas[i] + tf.gather(areas, order[1:]) - intersection)

    inds = tf.where_v2(overlap <= thresh)
    order = tf.concat(tf.gather(order, inds + 1), axis=1)
    order = tf.squeeze(order, axis=-1)
    index += 1
  return keep.stack()
示例#6
0
def build_decoder(encoded_image, caption_input, params, is_training):

    decoder_output = transformer.decoder_layer(caption_input, encoded_image,
                                               params, is_training)  # n,20,512
    logit = tf.layers.dense(decoder_output, params.vocab_size)  # n,16,5000
    probs = tf.nn.softmax(logit, name='probs')
    sorted_indices = tf.identity(tf.argsort(probs,
                                            axis=-1,
                                            direction='DESCENDING'),
                                 name='sorted_indices')

    return probs, sorted_indices
示例#7
0
def _top_p_sample(logits, ignore_ids=None, num_samples=1, p=0.9):
    """
    Does top-p sampling. if ignore_ids is on, then we will zero out those logits.
    :param logits: [batch_size, vocab_size] tensor
    :param ignore_ids: [vocab_size] one-hot representation of the indices we'd like to ignore and never predict,
                        like padding maybe
    :param p: topp threshold to use, either a float or a [batch_size] vector
    :return: [batch_size, num_samples] samples

    # TODO FIGURE OUT HOW TO DO THIS ON TPUS. IT'S HELLA SLOW RIGHT NOW, DUE TO ARGSORT I THINK
    """
    with tf.variable_scope('top_p_sample'):
        batch_size, vocab_size = get_shape_list(logits, expected_rank=2)

        probs = tf.nn.softmax(logits if ignore_ids is None else logits - tf.cast(ignore_ids[None], tf.float32) * 1e10,
                              axis=-1)

        if isinstance(p, float) and p > 0.999999:
            # Don't do top-p sampling in this case
            print("Top-p sampling DISABLED", flush=True)
            return {
                'probs': probs,
                'sample': tf.random.categorical(
                    logits=logits if ignore_ids is None else logits - tf.cast(ignore_ids[None], tf.float32) * 1e10,
                    num_samples=num_samples, dtype=tf.int32),
            }

        # [batch_size, vocab_perm]
        indices = tf.argsort(probs, direction='DESCENDING')
        cumulative_probabilities = tf.math.cumsum(tf.batch_gather(probs, indices), axis=-1, exclusive=False)

        # find the top pth index to cut off. careful we don't want to cutoff everything!
        # result will be [batch_size, vocab_perm]
        p_expanded = p if isinstance(p, float) else p[:, None]
        exclude_mask = tf.logical_not(
            tf.logical_or(cumulative_probabilities < p_expanded, tf.range(vocab_size)[None] < 1))

        # OPTION A - sample in the sorted space, then unsort.
        logits_to_use = tf.batch_gather(logits, indices) - tf.cast(exclude_mask, tf.float32) * 1e10
        sample_perm = tf.random.categorical(logits=logits_to_use, num_samples=num_samples)
        sample = tf.batch_gather(indices, sample_perm)

        # OPTION B - unsort first - Indices need to go back to 0 -> N-1 -- then sample
        # unperm_indices = tf.argsort(indices, direction='ASCENDING')
        # include_mask_unperm = tf.batch_gather(include_mask, unperm_indices)
        # logits_to_use = logits - (1 - tf.cast(include_mask_unperm, tf.float32)) * 1e10
        # sample = tf.random.categorical(logits=logits_to_use, num_samples=num_samples, dtype=tf.int32)

    return {
        'probs': probs,
        'sample': sample,
    }
    def _classification_loss(self, pred_label, gt_label, num_matched_boxes):
        """Computes the classification loss.

    Computes the classification loss with hard negative mining.
    Args:
      pred_label: a flatten tensor that includes all predicted class. The shape
        is [batch_size, num_anchors, num_classes].
      gt_label: a tensor that represents the classification groundtruth targets.
        The shape is [batch_size, num_anchors, 1].
      num_matched_boxes: the number of anchors that are matched to a groundtruth
        targets. This is used as the loss normalizater.

    Returns:
      box_loss: a float32 representing total box regression loss.
    """
        cross_entropy = tf.losses.sparse_softmax_cross_entropy(
            gt_label, pred_label, reduction=tf.losses.Reduction.NONE)

        mask = tf.greater(tf.squeeze(gt_label), 0)
        float_mask = tf.cast(mask, tf.float32)

        # Hard example mining
        neg_masked_cross_entropy = cross_entropy * (1 - float_mask)
        relative_position = tf.argsort(
            tf.argsort(neg_masked_cross_entropy, direction='DESCENDING'))
        num_neg_boxes = tf.minimum(
            tf.to_int32(num_matched_boxes) * ssd_constants.NEGS_PER_POSITIVE,
            ssd_constants.NUM_SSD_BOXES)
        top_k_neg_mask = tf.cast(
            tf.less(
                relative_position,
                tf.tile(num_neg_boxes[:, tf.newaxis],
                        (1, ssd_constants.NUM_SSD_BOXES))), tf.float32)

        class_loss = tf.reduce_sum(tf.multiply(cross_entropy,
                                               float_mask + top_k_neg_mask),
                                   axis=1)

        return tf.reduce_mean(class_loss / num_matched_boxes)
示例#9
0
def _compute_bucket_id(bucket_size, header_size, token_type_id, input_mask):
    """Reorder inputs based on token_type index and compute the bucket index.

  Args:
    bucket_size: <int32> Only attend to position that fall in consecutive
      equally sized buckets, or to/from the first bucket.
    header_size: <int32> The size of the first bucket.
    token_type_id: <int32>[batch_size, seq_length]
    input_mask: <int32>[batch_size, seq_length]

  Returns:
    bucket_id: <int32>[batch_size, seq_lengh]
  """
    # Ensure that the padding tokens get sorted last
    masked_token_type_id = token_type_id + (-input_mask + 1) * 10000
    # Argsorting twice gives you the rank. Sorting once and using scatter could
    # be slightly faster, but not relevant for simulation code
    token_type_ranks = tf.argsort(tf.argsort(masked_token_type_id,
                                             stable=True),
                                  stable=True)
    # Elements from 0 to `header_size` - 1 are mapped to 0, the rest are dividied
    # evenly into groups of size `bucket_size` starting from 1.
    return tf.math.maximum((token_type_ranks - header_size) // bucket_size + 1,
                           0)
示例#10
0
def diffsort(offsets):
    """Calculate the argsort of the difference between the input offsets.

  Useful for sorting row indices in sparse matrices.

  Args:
    offsets: Tensor, array of offsets for the sparse of each row, where
      `offset[i+1] - offsets[i]` is the length of row i. Length `m+1`,
      where 'm' is the number of rows.

  Returns:
    Tensor, array of row indices sorted by row length, from largest to
      smallest.
  """
    diffs = (offsets - tf.roll(offsets, shift=-1, axis=0))[:-1]
    return tf.cast(tf.argsort(diffs, direction="DESCENDING"), tf.uint32)
示例#11
0
 def body(past, prev, output, addr):
     next_outputs = step(hparams, prev, past=past)
     logits = next_outputs['logits'][:, -1, :]
     samples = tf.gather_nd(
         tf.argsort(logits[0, :], direction="DESCENDING"), [
             [addr[0]],
         ])
     #print (">>>> next past=" + str (tf.concat([past, next_outputs['presents']], axis=-2)))
     #print (">>>> next prev=" + str(samples))
     #print (">>>> next output="+str(tf.concat([output, samples], axis=0)))
     #print (">>>> next addr="+str(addr[1:]))
     return [
         tf.concat([past, next_outputs['presents']], axis=-2),
         samples,
         tf.concat([output, samples], axis=0),
         addr[1:],
     ]
 def nucleus_sampling(self, logits):
     """Nucleus sampling."""
     p = self.hparams.nucleus_sampling
     tf.logging.info("Nucleus sampling top_p = {}".format(p))
     sort_indices = tf.argsort(logits, axis=-1, direction="DESCENDING")
     probs = tf.gather(tf.nn.softmax(logits), sort_indices, batch_dims=1)
     cumprobs = tf.cumsum(probs, axis=-1, exclusive=True)
     # The top 1 candidate always will not be masked.
     # This way ensures at least 1 indices will be selected.
     sort_mask = tf.cast(tf.greater(cumprobs, p), logits.dtype)
     batch_indices = tf.tile(
         tf.expand_dims(tf.range(logits.shape[0]), axis=-1),
         [1, logits.shape[1]])
     top_p_mask = tf.scatter_nd(
         tf.stack([batch_indices, sort_indices], axis=-1), sort_mask,
         logits.shape)
     logits -= top_p_mask * logits.dtype.max
     return logits
示例#13
0
def sort2d(tensor2d,
           ref_indices2d,
           first_k=float("inf"),
           direction="DESCENDING"):
  """Perform sort in 2D based on tensor2d values with indices in ref_indices2d.

  Args:
    tensor2d: 3D Tensor of size [batch_size, height, width]
    ref_indices2d: 4D Tensor of size [batch_size, height, width, 2]
      with reference coordinates in 2D.
    first_k: (Integer) return indices of first_k elements.
    direction: "ASCENDING" or "DESCENDING".

  Returns:
    sorted_tensor: 2D Tensor of size (first_k, batch_size)
    sorted_ref_indices: 3D Tensor of size (first_k, batch_size, 2) with
      ref_indices sorted order based on the order of the input (tensor2d).
  """
  _, height, width = tensor2d.shape.as_list()
  batch_size = tf.shape(tensor2d)[0]
  first_k = min(first_k, height*width)
  tensor2d_reshaped = tf.reshape(
      tensor2d, [batch_size, height*width])
  ref_indices2d_reshaped = tf.reshape(
      ref_indices2d, [batch_size, height*width, 2])
  sort_indices = tf.argsort(
      tensor2d_reshaped, axis=1, direction=direction)
  sort_indices = tf.gather(sort_indices,
                           tf.cast(np.array(range(first_k)), tf.int32), axis=1)
  sorted_ref_indices = tf.reduce_sum(
      tf.eye(batch_size, batch_size)[:, :, tf.newaxis, tf.newaxis] * tf.gather(
          ref_indices2d_reshaped, sort_indices, axis=1),
      axis=1)

  sorted_tensor = tf.reduce_sum(
      tf.eye(batch_size, batch_size)[:, :, tf.newaxis] * tf.gather(
          tensor2d_reshaped, sort_indices, axis=1),
      axis=1)
  sorted_tensor = tf.transpose(sorted_tensor, [1, 0])
  sorted_ref_indices = tf.transpose(sorted_ref_indices, [1, 0, 2])
  return sorted_tensor, sorted_ref_indices
示例#14
0
def idx2csr(indices, rows, columns):
    """Convert index format meta-data to compressed sparse row format.

  Args:
    indices: Tensor, the linear indices for the sparse matrix.
    rows: Tensor, the number of rows in the sparse matrix.
    columns: Tensor, the number of columns in the sparse matrix.

  Returns:
    row_indices: Tensor, the row indices sorted by size.
    row_offset: Tensor, the offsets for each row in the sparse matrix.
    column_indices: Tensor, the column indices for each nonzero in the
      matrix.
  """
    # Calculate the length of each row by histogramming the indices.
    row_lengths = tf.histogram_fixed_width(indices, [0, rows * columns],
                                           nbins=rows)

    row_offsets = tf.concat([[0], tf.cumsum(row_lengths)], axis=0)
    row_indices = tf.argsort(row_lengths, direction="DESCENDING")
    column_indices = tf.mod(indices, columns)
    return row_indices, row_offsets, column_indices
示例#15
0
    def d2s(self, matrix, weight):
        """dense to sparse operation"""

        # Extract the nonzero values.
        mask = tf.math.not_equal(matrix, 0)
        values = tf.boolean_mask(weight, mask)

        # Calculate offset of each row
        mask = tf.cast(mask, tf.int32)
        row_offsets = tf.concat(
            [[0], tf.cumsum(tf.reduce_sum(mask, axis=1))], axis=0)

        # Create the row indices and sort them.
        row_indices = tf.argsort(-(row_offsets[1:] - row_offsets[:-1]))

        # Extract the column indices for the nonzero values.
        x = mask * (tf.range(matrix.shape[1]) + 1)
        column_indices = tf.boolean_mask(x, tf.math.not_equal(matrix, 0))
        column_indices = column_indices - 1

        row_indices = tf.cast(row_indices, tf.uint32)
        row_offsets = tf.cast(row_offsets, tf.uint32)
        column_indices = tf.cast(column_indices, tf.uint32)
        return self._rows, self._columns, values, row_indices, row_offsets, column_indices
示例#16
0
    def _face_model_map_fn(example):
        vertices = example['vertices']

        # Randomly shift vertices
        if apply_random_shift:
            vertices = random_shift(vertices)
        example['num_vertices'] = tf.shape(vertices)[0]

        # Optionally shuffle vertices and re-order faces to match
        if shuffle_vertices:
            permutation = tf.random_shuffle(tf.range(example['num_vertices']))
            vertices = tf.gather(vertices, permutation)
            face_permutation = tf.concat([
                tf.constant([0, 1], dtype=tf.int32),
                tf.argsort(permutation) + 2
            ],
                                         axis=0)
            example['faces'] = tf.cast(
                tf.gather(face_permutation, example['faces']), tf.int64)

        def _dequantize_verts(verts, n_bits):
            min_range = -0.5
            max_range = 0.5
            range_quantize = 2**n_bits - 1
            verts = tf.cast(verts, tf.float32)
            verts = verts * (max_range -
                             min_range) / range_quantize + min_range
            return verts

        # Vertices are quantized. So convert to floats for input to face model
        example['vertices'] = _dequantize_verts(vertices, quantization_bits)
        example['vertices_mask'] = tf.ones_like(example['vertices'][..., 0],
                                                dtype=tf.float32)
        example['faces_mask'] = tf.ones_like(example['faces'],
                                             dtype=tf.float32)
        return example
示例#17
0
def random_crop_to_size(protein,
                        crop_size,
                        max_templates,
                        shape_schema,
                        subsample_templates=False):
    """Crop randomly to `crop_size`, or keep as is if shorter than that."""
    seq_length = protein['seq_length']
    if 'template_mask' in protein:
        num_templates = tf.cast(
            shape_helpers.shape_list(protein['template_mask'])[0], tf.int32)
    else:
        num_templates = tf.constant(0, dtype=tf.int32)
    num_res_crop_size = tf.math.minimum(seq_length, crop_size)

    # Ensures that the cropping of residues and templates happens in the same way
    # across ensembling iterations.
    # Do not use for randomness that should vary in ensembling.
    seed_maker = utils.SeedMaker(
        initial_seed=protein['random_crop_to_size_seed'])

    if subsample_templates:
        templates_crop_start = tf.random.stateless_uniform(
            shape=(),
            minval=0,
            maxval=num_templates + 1,
            dtype=tf.int32,
            seed=seed_maker())
    else:
        templates_crop_start = 0

    num_templates_crop_size = tf.math.minimum(
        num_templates - templates_crop_start, max_templates)

    num_res_crop_start = tf.random.stateless_uniform(shape=(),
                                                     minval=0,
                                                     maxval=seq_length -
                                                     num_res_crop_size + 1,
                                                     dtype=tf.int32,
                                                     seed=seed_maker())

    templates_select_indices = tf.argsort(
        tf.random.stateless_uniform([num_templates], seed=seed_maker()))

    for k, v in protein.items():
        if k not in shape_schema or ('template' not in k
                                     and NUM_RES not in shape_schema[k]):
            continue

        # randomly permute the templates before cropping them.
        if k.startswith('template') and subsample_templates:
            v = tf.gather(v, templates_select_indices)

        crop_sizes = []
        crop_starts = []
        for i, (dim_size, dim) in enumerate(
                zip(shape_schema[k], shape_helpers.shape_list(v))):
            is_num_res = (dim_size == NUM_RES)
            if i == 0 and k.startswith('template'):
                crop_size = num_templates_crop_size
                crop_start = templates_crop_start
            else:
                crop_start = num_res_crop_start if is_num_res else 0
                crop_size = (num_res_crop_size if is_num_res else
                             (-1 if dim is None else dim))
            crop_sizes.append(crop_size)
            crop_starts.append(crop_start)
        protein[k] = tf.slice(v, crop_starts, crop_sizes)

    protein['seq_length'] = num_res_crop_size
    return protein
示例#18
0
        def body_cross_entropy(itr, cond_terminate, sample_mean,
                               sample_covariance_diag, top_k_value,
                               top_k_action_samples):
            """Function for cross entropy search of actions."""
            del top_k_action_samples
            top_k_value_prev = top_k_value
            batch_sample_mean = tf.reshape(
                tf.tile(sample_mean, [1, num_samples]),
                [self._dynamic_batch_size * num_samples, self.action_dim])
            batch_sample_covariance_diag = tf.reshape(
                tf.tile(sample_covariance_diag, [1, num_samples]),
                [self._dynamic_batch_size * num_samples, self.action_dim])

            action_samples = self._action_projection(
                batch_sample_mean +
                batch_sample_covariance_diag * tf.cast(random_sampler.sample(
                    sample_shape=[self._dynamic_batch_size * num_samples]),
                                                       dtype=tf.float32))

            state_samples = tf.reshape(
                tf.tile(self._state_tensor, [1, num_samples]),
                [self._dynamic_batch_size * num_samples, self.state_dim])
            action_samples = tf.reshape(
                action_samples,
                [self._dynamic_batch_size * num_samples, self.action_dim])
            values = tf.reshape(
                self._build_q_function_net(state_samples, action_samples),
                [self._dynamic_batch_size, num_samples])

            # everything is in batch mode
            top_k_index = tf.argsort(values, axis=1,
                                     direction="DESCENDING")[:, 0:top_k_num]
            top_k_index_1d = tf.reshape(
                top_k_index, [self._dynamic_batch_size * top_k_num, 1])
            counter_tensor_1d = tf.reshape(
                tf.tile(
                    tf.reshape(tf.range(self._dynamic_batch_size),
                               [self._dynamic_batch_size, 1]), [1, top_k_num]),
                [self._dynamic_batch_size * top_k_num, 1])

            top_k_index_2d = tf.concat([counter_tensor_1d, top_k_index_1d],
                                       axis=1)

            action_samples = tf.reshape(
                action_samples,
                [self._dynamic_batch_size, num_samples, self.action_dim])
            top_k_action_samples = tf.gather_nd(action_samples, top_k_index_2d)
            top_k_action_samples = tf.reshape(
                top_k_action_samples,
                [self._dynamic_batch_size, top_k_num, self.action_dim])

            top_k_values = tf.gather_nd(values, top_k_index_2d)
            top_k_values = tf.reshape(top_k_values,
                                      [self._dynamic_batch_size, top_k_num])

            # it's a batch_size x 1 tensor
            top_k_value = tf.reshape(tf.reduce_mean(top_k_values, axis=1),
                                     [self._dynamic_batch_size, 1])

            sample_mean = tf.reduce_mean(top_k_action_samples, axis=1)
            sample_covariance_diag = tf.math.reduce_variance(
                top_k_action_samples, axis=1)

            itr = itr + 1
            cond_terminate = tf.less_equal(
                tf.reduce_mean(tf.math.abs(top_k_value - top_k_value_prev)),
                self._tolerance_tensor)
            return itr, cond_terminate, sample_mean, sample_covariance_diag, \
                top_k_value, top_k_action_samples
示例#19
0
def create_cm_sketch(topk_obj_ids, topk_obj_weights, all_entity_sketches,
                     cm_width):
    """Create cm sketches for a set of weighted entities.

  Args:
    topk_obj_ids: batch_size, topk
    topk_obj_weights: batch_size, topk
    all_entity_sketches: num_entities, depth
    cm_width: width of count-min sketch

  Returns:
    k hot dense vectors: batch_size, depth, width
  """
    topk_fact_obj_sketches = tf.gather(all_entity_sketches,
                                       topk_obj_ids,
                                       axis=0)
    # batch_size, topk, depth
    batch_size = tf.shape(topk_fact_obj_sketches)[0]
    topk = tf.shape(topk_fact_obj_sketches)[1]
    cm_depth = tf.shape(topk_fact_obj_sketches)[2]

    # We first create a sparse matrix from the hash values. We will then
    # convert it into dense matrix. This is more efficient than creating
    # k one-hot vectors and then aggregating them into one k-hot vector.

    # First prepare ids of non-zero values in the sparse matrix
    flattened_topk_hash_ids = tf.reshape(topk_fact_obj_sketches, shape=[-1])
    # batch_size * topk * depth
    topk_obj_weights = tf.tile(tf.expand_dims(topk_obj_weights, axis=2),
                               multiples=[1, 1, cm_depth])
    # batch_size, topk, depth
    flattened_topk_obj_weights = tf.reshape(topk_obj_weights, shape=[-1])
    # batch_size * topk * depth
    batch_ids = tf.range(batch_size)
    # batch_size,
    batch_ids = tf.expand_dims(tf.expand_dims(batch_ids, axis=1), axis=2)
    # batch_size, 1, 1
    batch_ids = tf.tile(batch_ids, multiples=[1, topk, cm_depth])
    # batch_size, topk, depth
    flattened_batch_ids = tf.reshape(batch_ids, shape=[-1])
    # batch_size * topk * depth
    depth_ids = tf.range(cm_depth)
    # depth,
    depth_ids = tf.expand_dims(tf.expand_dims(depth_ids, axis=0), axis=1)
    # 1, 1, depth
    depth_ids = tf.tile(depth_ids, multiples=[batch_size, topk, 1])
    # batch_size, topk, depth
    flattened_depth_ids = tf.reshape(depth_ids, shape=[-1])
    # batch_size * topk * depth
    sparse_value_ids = tf.cast(tf.stack(
        [flattened_batch_ids, flattened_depth_ids, flattened_topk_hash_ids],
        axis=1),
                               dtype=tf.int64)

    # Then prepare values of non-zero values in the sparse matrix. Values
    # are sorted to ascending order. If there are duplicates, later (larger)
    # values will be kept.
    sorted_orders = tf.argsort(flattened_topk_obj_weights,
                               direction='ASCENDING',
                               stable=True)
    # batch_size * topk * depth
    sorted_flattened_topk_obj_weights = tf.gather(flattened_topk_obj_weights,
                                                  sorted_orders)
    sorted_sparse_value_ids = tf.gather(sparse_value_ids, sorted_orders)

    # Finally create sketch in sparse tensors and convert it to dense tensors.
    # We donot validate indices here. If multiple values are about to be assigned
    # to the same row and column, we will keep the last value, because the last
    # value is the larger one. This behaviour is by design.
    sparse_k_hot_sketch = tf.SparseTensor(
        indices=sorted_sparse_value_ids,
        values=sorted_flattened_topk_obj_weights,
        dense_shape=[batch_size, cm_depth, cm_width])
    dense_k_hot_sketch = tf.sparse.to_dense(sparse_k_hot_sketch,
                                            validate_indices=False)
    # batch_size, cm_depth, cm_width
    return dense_k_hot_sketch
示例#20
0
def _generate_detections_tf(cls_outputs, box_outputs, anchor_boxes, indices,
                            classes, image_id, image_scale, num_classes,
                            min_score_thresh=0.2, max_boxes_to_draw=50,
                            soft_nms_sigma=0.0, iou_threshold=0.5,
                            use_native_nms=False):
  """Generates detections with model outputs and anchors.

  Args:
    cls_outputs: a numpy array with shape [N, 1], which has the highest class
      scores on all feature levels. The N is the number of selected
      top-K total anchors on all levels.  (k being MAX_DETECTION_POINTS)
    box_outputs: a numpy array with shape [N, 4], which stacks box regression
      outputs on all feature levels. The N is the number of selected top-k
      total anchors on all levels. (k being MAX_DETECTION_POINTS)
    anchor_boxes: a numpy array with shape [N, 4], which stacks anchors on all
      feature levels. The N is the number of selected top-k total anchors on
      all levels.
    indices: a numpy array with shape [N], which is the indices from top-k
      selection.
    classes: a numpy array with shape [N], which represents the class
      prediction on all selected anchors from top-k selection.
    image_id: an integer number to specify the image id.
    image_scale: a float tensor representing the scale between original image
      and input image for the detector. It is used to rescale detections for
      evaluating with the original groundtruth annotations.
    num_classes: a integer that indicates the number of classes.
    min_score_thresh: A float representing the threshold for deciding when to
      remove boxes based on score.
    max_boxes_to_draw: Max number of boxes to draw.
    soft_nms_sigma: A scalar float representing the Soft NMS sigma parameter;
      See Bodla et al, https://arxiv.org/abs/1704.04503).  When
        `soft_nms_sigma=0.0` (which is default), we fall back to standard (hard)
        NMS.
    iou_threshold: A float representing the threshold for deciding whether boxes
      overlap too much with respect to IOU.
    use_native_nms: a bool that indicates whether to use native nms.

  Returns:
    detections: detection results in a tensor with each row representing
      [image_id, y, x, height, width, score, class]
  """
  anchor_boxes = tf.gather(anchor_boxes, indices)

  scores = tf.math.sigmoid(cls_outputs)
  # apply bounding box regression to anchors
  boxes = decode_box_outputs_tf(
      tf.transpose(box_outputs, [1, 0]), tf.transpose(anchor_boxes, [1, 0]))

  def _else(detections, class_id, indices):
    """Else branch for generating detections."""
    boxes_cls = tf.gather(boxes, indices)
    scores_cls = tf.gather(scores, indices)
    # Select top-scoring boxes in each class and apply non-maximum suppression
    # (nms) for boxes in the same class. The selected boxes from each class are
    # then concatenated for the final detection outputs.

    if use_native_nms:
      top_detection_idx, scores_cls = tf.image.non_max_suppression_with_scores(
          boxes_cls,
          scores_cls,
          max_boxes_to_draw,
          iou_threshold=iou_threshold,
          score_threshold=min_score_thresh,
          soft_nms_sigma=soft_nms_sigma)
      scores_cls = tf.expand_dims(scores_cls, axis=1)
      boxes_cls = tf.gather(boxes_cls, top_detection_idx)
      top_detections_cls = tf.concat([boxes_cls, scores_cls], axis=1)
    else:
      scores_cls = tf.expand_dims(scores_cls, axis=1)
      all_detections_cls = tf.concat([boxes_cls, scores_cls], axis=1)
      top_detection_idx = nms_tf(all_detections_cls, iou_threshold)
      top_detections_cls = tf.gather(all_detections_cls, top_detection_idx)
    height = top_detections_cls[:, 2] - top_detections_cls[:, 0]
    width = top_detections_cls[:, 3] - top_detections_cls[:, 1]
    top_detections_cls = tf.stack([top_detections_cls[:, 0] * image_scale,
                                   top_detections_cls[:, 1] * image_scale,
                                   height * image_scale, width * image_scale,
                                   top_detections_cls[:, 4]], axis=-1)

    top_detections_cls = tf.stack(
        [
            tf.cast(
                tf.repeat(image_id, tf.size(top_detection_idx)), tf.float32),
            *tf.unstack(top_detections_cls, 5, axis=1),
            tf.repeat(class_id + 1.0, tf.size(top_detection_idx))
        ],
        axis=1)

    detections = tf.concat([detections, top_detections_cls], axis=0)

    return detections

  detections = tf.constant([], tf.float32, [0, 7])
  for c in range(num_classes):
    indices_cls = tf.squeeze(tf.where_v2(tf.equal(classes, c)), axis=-1)
    detections = tf.cond(
        tf.equal(tf.size(indices), 0), lambda: detections,
        lambda id=c, id_cls=indices_cls: _else(detections, id, id_cls))
  indices_final = tf.argsort(detections[:, -2], direction='DESCENDING')
  detections = tf.gather(
      detections, indices_final[:max_boxes_to_draw], name='detection')
  return detections
示例#21
0
    def build(self,
              input_list,
              noisy_params=None,
              noise_rate=0.05,
              is_training=False,
              **kwargs):
        """Create embedding RNN sequence-to-sequence model. No support for noisy parameters.

        Args:
            input_list: (list<tf.Tensor>) A list of tensors containing the features
                        for a list of documents.
            is_training: (bool) A flag indicating whether the model is running in training mode.

        Returns:
            A list of tf.Tensor containing the ranking scores for each instance in input_list.
        """
        feed_previous = self.feed_previous
        embed_size = input_list[0].get_shape()[-1].value
        dtype = dtypes.float32
        output_projection = None
        list_size = len(input_list)  # len_seq
        with tf.variable_scope("cell", reuse=tf.AUTO_REUSE):
            # single_cell = tf.contrib.rnn.GRUCell(
            single_cell = tf.keras.layers.GRUCell(embed_size +
                                                  self.expand_embed_size)
            # double_cell = tf.contrib.rnn.GRUCell(
            double_cell = tf.keras.layers.GRUCell(
                (embed_size + self.expand_embed_size) * 2)
            if self.hparams.use_lstm:
                # single_cell = tf.contrib.rnn.BasicLSTMCell(
                single_cell = tf.keras.layers.LSTMCell(
                    (embed_size + self.expand_embed_size))
                # double_cell = tf.contrib.rnn.BasicLSTMCell(
                double_cell = tf.keras.layers.LSTMCell(
                    (embed_size + self.expand_embed_size) * 2)
            cell = single_cell
            self.double_cell = double_cell
            self.cell = cell
            self.output_projection = output_projection

            if self.hparams.num_layers > 1:
                # cell = tf.contrib.rnn.MultiRNNCell(
                cell = tf.keras.layers.StackedRNNCells([single_cell] *
                                                       self.hparams.num_layers)
                # self.double_cell = tf.contrib.rnn.MultiRNNCell(
                self.double_cell = tf.keras.layers.StackedRNNCells(
                    [double_cell] * self.hparams.num_layers)
        with tf.variable_scope(tf.get_variable_scope()
                               or "embedding_rnn_seq2seq",
                               reuse=tf.AUTO_REUSE):

            def abstract(input_data, index):
                reuse = None if index < 1 else True
                # print(reuse, "reuse or not", tf.AUTO_REUSE, "tf.AUTO_REUSE")
                with tf.variable_scope(tf.get_variable_scope(),
                                       reuse=tf.AUTO_REUSE):
                    output_data = input_data
                    output_sizes = [
                        int((embed_size + self.expand_embed_size) / 2),
                        self.expand_embed_size
                    ]
                    current_size = embed_size
                    for i in xrange(2):
                        expand_W = self.get_variable(
                            "expand_W_%d" % i, [current_size, output_sizes[i]])
                        expand_b = self.get_variable("expand_b_%d" % i,
                                                     [output_sizes[i]])
                        output_data = tf.nn.bias_add(
                            tf.matmul(output_data, expand_W), expand_b)
                        output_data = tf.nn.elu(output_data)
                        current_size = output_sizes[i]
                    return output_data

            for i in xrange(list_size):
                input_list[i] = self.Layer_embedding(input_list[i])
                if self.expand_embed_size > 0:
                    input_list[i] = tf.concat(
                        axis=1,
                        values=[
                            input_list[i],
                            abstract(input_list[i], i)
                        ])  # [batch,feature_size+expand_embed_size]*len_seq
#             input_list= [tf.reshape(e, [1, -1,self.expand_embed_size+embed_size])
#                         for e in input_list]
#             input_list = tf.concat(axis=0, values=input_list)###[len_seq,batch,feature_size+expand_embed_size]
# [len_seq,batch,feature_size+expand_embed_size]
            input_list = tf.stack(input_list, axis=0)
            enc_cell = copy.deepcopy(cell)
            ind = tf.range(0, list_size)
            print(self.hparams.input_sequence)
            if self.hparams.input_sequence == "reverse":
                ind = ind
            elif self.hparams.input_sequence == "initial":
                ind = tf.range(list_size - 1, -1, -1)
            elif self.hparams.input_sequence == "random":
                ind = tf.random.shuffle(ind)
            # [len_seq,batch,feature_size+expand_embed_size]
            input_list_input = tf.nn.embedding_lookup(input_list, ind)
            # [batch,feature_size+expand_embed_size]*len_seq
            input_list_input_list = tf.unstack(input_list_input, axis=0)
            # cprint('input_list_input_list: {}'.format(input_list_input_list), 'green')
            '''
            [<tf.Tensor 'ranking_model_1/ranking_model/unstack:0' shape=(?, 186) dtype=float32>,
             <tf.Tensor 'ranking_model_1/ranking_model/unstack:1' shape=(?, 186) dtype=float32>,
             <tf.Tensor 'ranking_model_1/ranking_model/unstack:2' shape=(?, 186) dtype=float32>,
             <tf.Tensor 'ranking_model_1/ranking_model/unstack:3' shape=(?, 186) dtype=float32>,
             <tf.Tensor 'ranking_model_1/ranking_model/unstack:4' shape=(?, 186) dtype=float32>,
             <tf.Tensor 'ranking_model_1/ranking_model/unstack:5' shape=(?, 186) dtype=float32>,
             <tf.Tensor 'ranking_model_1/ranking_model/unstack:6' shape=(?, 186) dtype=float32>,
             <tf.Tensor 'ranking_model_1/ranking_model/unstack:7' shape=(?, 186) dtype=float32>,
             <tf.Tensor 'ranking_model_1/ranking_model/unstack:8' shape=(?, 186) dtype=float32>]
            '''
            encoder_outputs_some_order, encoder_state = tf.nn.static_rnn(  # encoder_state就是final state
                enc_cell,
                input_list_input_list,
                dtype=dtype)
            # _rnn = tf.keras.layers.RNN(enc_cell, unroll=True)
            # _rnn = tf.keras.layers.RNN(enc_cell, unroll=True, return_sequences=True)
            # _output = _rnn(input_list_input_list)
            # cprint('_output: {}'.format(_output), 'green')
            # cprint('encoder_outputs_some_order: {}'.format(encoder_outputs_some_order), 'green')
            '''
            下面是运行tf.nn.static_rnn版本的代码输出的结果:
            [<tf.Tensor 'ranking_model/ranking_model/rnn/gru_cell/add_5:0' shape=(?, 186) dtype=float32>,
             <tf.Tensor 'ranking_model/ranking_model/rnn/gru_cell_1/add_5:0' shape=(?, 186) dtype=float32>,
             <tf.Tensor 'ranking_model/ranking_model/rnn/gru_cell_2/add_5:0' shape=(?, 186) dtype=float32>,
             <tf.Tensor 'ranking_model/ranking_model/rnn/gru_cell_3/add_5:0' shape=(?, 186) dtype=float32>, 
             <tf.Tensor 'ranking_model/ranking_model/rnn/gru_cell_4/add_5:0' shape=(?, 186) dtype=float32>,
             <tf.Tensor 'ranking_model/ranking_model/rnn/gru_cell_5/add_5:0' shape=(?, 186) dtype=float32>,
             <tf.Tensor 'ranking_model/ranking_model/rnn/gru_cell_6/add_5:0' shape=(?, 186) dtype=float32>,
             <tf.Tensor 'ranking_model/ranking_model/rnn/gru_cell_7/add_5:0' shape=(?, 186) dtype=float32>,
             <tf.Tensor 'ranking_model/ranking_model/rnn/gru_cell_8/add_5:0' shape=(?, 186) dtype=float32>]
            '''
            # cprint('encoder_state: {}'.format(encoder_state), 'green')
            '''
            下面是运行tf.nn.static_rnn版本的代码输出的结果:
            Tensor("ranking_model/ranking_model/rnn/gru_cell_8/add_5:0", shape=(?, 186), dtype=float32)
            '''
            ind_sort = tf.argsort(ind)  # find the order of sequence
            #             ind_sort=tf.Print(tf.argsort(ind),[tf.argsort(ind),ind],"sequence")
            self.ind_sort = [ind_sort, ind]
            # [len_seq,batch,feature_size+expand_embed_size]
            encoder_outputs_some_order = tf.stack(encoder_outputs_some_order,
                                                  axis=0)
            #             encoder_outputs=[None]*list_size
            #             for i in range(list_size):
            #                 encoder_outputs[ind[i]]=encoder_outputs_some_order[i]## back to the order of initial list.
            # [len_seq,batch,feature_size+expand_embed_size]
            input_list_output = tf.nn.embedding_lookup(
                encoder_outputs_some_order, ind_sort)
            # [feature_size+expand_embed_size] *len_seq
            input_list_output_list = tf.unstack(input_list_output, axis=0)
            top_states = [
                tf.reshape(self.layer_norm_hidden(e),
                           [-1, 1, cell.output_size])
                for e in input_list_output_list
            ]  # [batch,1,encoder_out]*len_seq
            encoder_state = self.layer_norm_final(
                encoder_state)  # [batch,encoder_state]
            #             top_states = [tf.reshape(e, [-1, 1, cell.output_size])
            #                         for e in encoder_outputs]  ##[]
            #             encoder_state=encoder_state
            # for e in input_list]
            # [batch,len_seq,encoder_out]
            attention_states = tf.concat(axis=1, values=top_states)
            #             print(attention_states.get_shape(),"attention_states.get_shape()")
            if isinstance(feed_previous, bool):
                outputs, state = self.embedding_rnn_decoder(
                    encoder_state,
                    cell,
                    attention_states,
                    input_list,
                    num_heads=self.hparams.num_heads,
                    output_projection=output_projection,
                    feed_previous=feed_previous)
                print(outputs[0].get_shape(), "outputs[0].get_shape()")
                return outputs[0]

            # If feed_previous is a Tensor, we construct 2 graphs and use cond.
            def decoder(feed_previous_bool):
                reuse = None if feed_previous_bool else True
                with tf.variable_scope(tf.get_variable_scope(), reuse=reuse):
                    outputs, state = self.embedding_rnn_decoder(
                        encoder_state,
                        cell,
                        attention_states,
                        input_list,
                        num_heads=self.hparams.num_heads,
                        output_projection=output_projection,
                        feed_previous=feed_previous_bool,
                        update_embedding_for_previous=False)
                    return outputs + [state]

            outputs_and_state = control_flow_ops.cond(feed_previous,
                                                      lambda: decoder(True),
                                                      lambda: decoder(False))
            print(outputs[0].get_shape(), "outputs[0].get_shape()")
            return outputs_and_state[0]
示例#22
0
    def __init__(self, item_num, args, reuse=None):
        self.args = args
        self.is_training = tf.placeholder(tf.bool, shape=())
        self.input_seq = tf.placeholder(tf.int32, shape=(None, args.maxlen))
        self.pos = tf.placeholder(tf.int32, shape=None)
        self.exemplar_logits = tf.placeholder(tf.float32, shape=(None, None))
        self.exemplar_pos = tf.placeholder(tf.int32, shape=None)
        self.max_item = tf.placeholder(tf.int32, shape=())
        self.lr = tf.placeholder(tf.float32, shape=())
        self.dropout_rate = tf.placeholder(tf.float32, shape=())
        pos = self.pos
        mask = tf.expand_dims(tf.to_float(tf.not_equal(self.input_seq, 0)), -1)

        with tf.variable_scope("SASRec", reuse=reuse):
            # sequence embedding, item embedding table
            self.seq, item_emb_table = embedding(self.input_seq,
                                                 vocab_size=item_num + 1,
                                                 num_units=args.hidden_units,
                                                 zero_pad=True,
                                                 scale=True,
                                                 l2_reg=args.l2_emb,
                                                 scope="input_embeddings",
                                                 with_t=True,
                                                 reuse=reuse
                                                 )

            # # Positional Encoding
            t, pos_emb_table = embedding(
                tf.tile(tf.expand_dims(tf.range(tf.shape(self.input_seq)[1]), 0), [tf.shape(self.input_seq)[0], 1]),
                vocab_size=args.maxlen,
                num_units=args.hidden_units,
                zero_pad=False,
                scale=False,
                l2_reg=args.l2_emb,
                scope="dec_pos",
                reuse=reuse,
                with_t=True
            )
            self.seq += t

            # Dropout
            self.seq = tf.layers.dropout(self.seq,
                                         rate=self.dropout_rate,
                                         training=tf.convert_to_tensor(self.is_training),
                                         seed=args.random_seed)

            self.seq *= mask

            # Build blocks
            for i in range(args.num_blocks):
                with tf.variable_scope("num_blocks_%d" % i):
                    # Self-attention
                    self.seq = multihead_attention(queries=normalize(self.seq),
                                                   keys=self.seq,
                                                   num_units=args.hidden_units,
                                                   num_heads=args.num_heads,
                                                   dropout_rate=self.dropout_rate,
                                                   seed=args.random_seed,
                                                   is_training=self.is_training,
                                                   causality=True,
                                                   scope="self_attention")

                    # Feed forward
                    self.seq = feedforward(normalize(self.seq), num_units=[args.hidden_units, args.hidden_units],
                                           dropout_rate=self.dropout_rate, is_training=self.is_training,
                                           seed=args.random_seed)
                    self.seq *= mask

            self.seq = normalize(self.seq)

        # find representation
        self.rep = self.seq[:, -1, :]

        # define loss
        seq_emb = tf.reshape(self.rep, [tf.shape(self.input_seq)[0], args.hidden_units])
        indices = pos - 1
        self.labels = tf.one_hot(indices, self.max_item)
        item_emb = tf.nn.embedding_lookup(item_emb_table, tf.range(1, self.max_item + 1))
        self.logits = tf.matmul(seq_emb, tf.transpose(item_emb))
        self.loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=self.labels, logits=self.logits))

        self.global_step = tf.Variable(0, name='global_step', trainable=False)
        self.optimizer = tf.train.AdamOptimizer(learning_rate=self.lr)

        # prediction
        self.test_item = tf.placeholder(tf.int32, shape=None)
        self.test_item_emb = tf.nn.embedding_lookup(item_emb_table, self.test_item)
        self.test_logits = tf.matmul(seq_emb, tf.transpose(self.test_item_emb))
        self.test_logits = tf.reshape(self.test_logits, [tf.shape(self.input_seq)[0], tf.shape(self.test_item)[0]])
        self.pred_last = tf.argsort(tf.argsort(-self.test_logits))
示例#23
0
def interleave_shells(shells, radii):
  """Interleave spherical shell tensors out-to-in by radii."""

  radius_order = tf.argsort(radii, direction='DESCENDING')
  shells_interleaved = tf.gather(shells, radius_order, axis=3)
  return shells_interleaved
示例#24
0
def create_bucketed_attention_layer(input_mask, input_header, bucket_size,
                                    header_size, token_type_ids,
                                    sort_after_projection):
    """Returns a drop-in replacement for attention_layer using sparsse attention.

  Args:
    input_mask: int32<batch_size, seq_length> The values should be 1 or 0. The
      attention scores will effectively be set to -infinity for any positions in
      the mask that are 0, and will be unchanged for positions that are 1.
    input_header: bool<batch_size, seq_length> The values should be 1 or 0.
      Attention will not be restricted to or from tokens where header is 1.
    bucket_size: int. Size of sections where self attention happens.
    header_size: Size of the first bucket that will attend to/from everything.
      If None is passed will use the same as `bucket_size`.
    token_type_ids: List<(int, bool, <int32>[batch_size, seq_length])> contains
      the number of heads for each token type, whether they are sorted, and the
      ids of each position. Attention is restricted between tokens with the same
      type id and this field is used to sort/bucket. ids must be non-negative.
    sort_after_projection: Sorting can happen on the layer input or after
      applying the projection to keys, queries and values. Depending on the
      accelerator, one option could be more convenient.

  Returns:
    Function with same signature as `attention_layer`.
    See `_bucketed_attention_layer`.
  """
    type_counts = [cnt for cnt, _, _ in token_type_ids]
    num_heads = sum(type_counts)

    # Ensure that the padding tokens get sorted last.
    additive_mask = _additive_mask(input_mask)

    type_sorted = [is_sorted for _, is_sorted, _ in token_type_ids]
    type_ids_masked = [ids - additive_mask for _, _, ids in token_type_ids]
    type_ids_argsorted = [
        None if is_sorted else tf.argsort(ids, stable=True)
        for is_sorted, ids in zip(type_sorted, type_ids_masked)
    ]

    def _gather_and_repeat(tensors, name):
        """Reorder each tensor using its type_id and copies it once per head."""
        if len(tensors) == 1:
            tensors = tensors * len(type_ids_argsorted)
        with tf.variable_scope(name):
            gathered_tensors = []
            for tensor, indices in zip(tensors, type_ids_argsorted):
                gathered_tensors.append(tensor if indices is None else tf.
                                        gather(tensor, indices, batch_dims=1))

            return tf.repeat(tf.stack(gathered_tensors, axis=1),
                             repeats=type_counts,
                             axis=1)

    # <int32>[batch_size, num_types, seq_length]
    type_ids = tf.stack(type_ids_masked, axis=1)
    type_order = tf.argsort(type_ids, stable=True)
    type_rank = tf.argsort(type_order, stable=True)

    # For each head the correct order to sort the embeddings.
    # <int32>[batch_size, num_attention_heads, seq_length].
    type_order_repeated = tf.repeat(type_order, repeats=type_counts, axis=1)

    # For each head the inverse of the correct order to sort the embeddings.
    # <int32>[batch_size, num_attention_heads, seq_length].
    type_rank_repeated = tf.repeat(type_rank, repeats=type_counts, axis=1)
    input_header = input_header & tf.math.equal(input_mask, 1)

    if sort_after_projection:
        # No need to sort in this case since this will happen in the BucketedTensor.
        type_ids_repeated = tf.repeat(type_ids, repeats=type_counts, axis=1)
        attend_always_repeated = tf.repeat(tf.expand_dims(input_header,
                                                          axis=1),
                                           repeats=num_heads,
                                           axis=1)
    else:
        type_ids_repeated = _gather_and_repeat(type_ids_masked,
                                               'type_id_gather')
        attend_always_repeated = _gather_and_repeat([input_header],
                                                    'attend_always_gather')

    if header_size is None:
        header_size = bucket_size

    args = {
        'order_indices': type_order_repeated,
        'bucket_size': bucket_size,
        'header_size': header_size,
        'num_heads': num_heads,
        'sort_after_projection': sort_after_projection,
    }
    ids = _create_bucketed_tensor(type_ids_repeated, 'type_id', **args)
    attend_always = _create_bucketed_tensor(attend_always_repeated,
                                            'attend_always', **args)
    head_full_mask = _compute_bucketed_attention_mask('head', 'full', ids,
                                                      attend_always)
    tail_head_mask = _compute_bucketed_attention_mask('tail', 'head', ids,
                                                      attend_always)
    tail_window_mask = _compute_bucketed_attention_mask(
        'tail', 'window', ids, attend_always)
    return functools.partial(_bucketed_attention_layer,
                             sort_after_projection=sort_after_projection,
                             gather_and_repeat=_gather_and_repeat,
                             bucketed_tensor_args=args,
                             header_size=header_size,
                             type_ranks=type_rank_repeated,
                             head_full_mask=head_full_mask,
                             tail_head_mask=tail_head_mask,
                             tail_window_mask=tail_window_mask)
示例#25
0
    def add_single_image_info(self, image_id, eval_dict):
        groundtruth_boxes = eval_dict[
            standard_fields.InputDataFields.groundtruth_boxes]
        groundtruth_classes = eval_dict[
            standard_fields.InputDataFields.groundtruth_classes]
        detection_boxes = eval_dict[
            standard_fields.DetectionResultFields.detection_boxes]
        detection_scores = eval_dict[
            standard_fields.DetectionResultFields.detection_scores]
        detection_classes = eval_dict[
            standard_fields.DetectionResultFields.detection_classes]

        groundtruth_has_rotation = groundtruth_classes > 1
        groundtruth_boxes_with_rotation = groundtruth_boxes[
            groundtruth_has_rotation]

        #ensure classes are both not 'dot' class, so they have a meaningful rotation value
        detection_within_score = detection_scores > self._score_threshold
        detection_class_has_rotation = detection_classes > 1
        detection_has_rotation_and_score = tf.logical_and(
            detection_within_score, detection_class_has_rotation)
        detection_boxes_within_score = detection_boxes[
            detection_has_rotation_and_score]
        detection_classes_within_score = detection_classes[
            detection_has_rotation_and_score]

        gt_boxlist = box_list.BoxList(
            tf.convert_to_tensor(groundtruth_boxes_with_rotation))
        det_boxlist = box_list.BoxList(
            tf.convert_to_tensor(detection_boxes_within_score))

        detection_y_rotation_angles = eval_dict[
            additional_fields.DetectionResultFields.y_rotation_angles]
        groundtruth_y_rotation_angles = eval_dict[
            additional_fields.GroundtruthResultFields.y_rotation_angles]
        detection_y_rotation_angles_within_score = detection_y_rotation_angles[
            detection_has_rotation_and_score]

        for iou_threshold, assigner in self._iou_thresholds_and_assigners:
            cls_targets, cls_weights, reg_targets, reg_weights, match = assigner.assign(
                det_boxlist, gt_boxlist)

            fg_detections = match >= 0
            fg_detection_boxes = detection_boxes_within_score[fg_detections, :]
            fg_matches = match[fg_detections]

            fg_matches_argsort = tf.argsort(fg_matches)
            fg_matches_sorted = tf.gather(fg_matches, fg_matches_argsort)

            gt_match_indices, fg_match_sorted_indices_with_repeats, fg_match_sorted_indices_counts = tf.unique_with_counts(
                fg_matches_sorted)
            fg_match_sorted_indices_no_repeats = tf.cumsum(
                tf.pad(fg_match_sorted_indices_counts, [[1, 0]]))[:-1]

            fg_match_indices_no_repeats = tf.gather(
                fg_matches_argsort, fg_match_sorted_indices_no_repeats)

            def get_matches_and_angle_difference(fg_match_idx_tensor,
                                                 gt_match_idx_tensor):
                if debug_get_matching_boxes:
                    gt_matching_detection_boxes = tf.gather(
                        groundtruth_boxes_with_rotation,
                        gt_match_idx_tensor,
                        axis=0)
                    fg_matching_detection_boxes = tf.gather(
                        fg_detection_boxes, fg_match_idx_tensor, axis=0)
                    pass

                fg_matching_detection_y_rot_angles = tf.gather(
                    detection_y_rotation_angles_within_score,
                    fg_match_idx_tensor,
                    axis=0)

                groundtruth_y_rotation_angles_matches = tf.gather(
                    groundtruth_y_rotation_angles, gt_match_idx_tensor, axis=0)
                groundtruth_has_y_rot = tf.math.logical_not(
                    tf.math.equal(groundtruth_y_rotation_angles_matches, 0))
                groundtruth_existant_y_rot_angle = groundtruth_y_rotation_angles_matches[
                    groundtruth_has_y_rot]

                detection_existant_y_rot_angle = fg_matching_detection_y_rot_angles[
                    groundtruth_has_y_rot]

                angle_diff = detection_existant_y_rot_angle - groundtruth_existant_y_rot_angle
                angle_diff_unwrapped = tf.math.atan2(tf.math.sin(angle_diff),
                                                     tf.math.cos(angle_diff))
                angle_diff_abs = tf.math.abs(angle_diff_unwrapped)

                n_angle_matches = len(angle_diff)

                return n_angle_matches, angle_diff_abs

            num_angle_matches, abs_angle_differences = get_matches_and_angle_difference(
                fg_match_indices_no_repeats, gt_match_indices)
            angle_diff_sum_square = tf.reduce_sum(
                tf.math.square(abs_angle_differences * 180 / np.pi))
            match_angle_diff_histogram = tf.histogram_fixed_width(
                abs_angle_differences * 180 / np.pi,
                self._histogram_range,
                nbins=self._num_angle_bins,
                dtype=tf.dtypes.int32)

            self.total_num_angle_matches[iou_threshold] += num_angle_matches
            self.total_angle_diff_sum_squared[
                iou_threshold] += angle_diff_sum_square
            self.angle_histograms[iou_threshold] += match_angle_diff_histogram