Пример #1
0
def segment_softmax(scores, segment_ids):
    """Given scores and a partition, converts scores to probs by performing
    softmax over all rows within a partition."""

    # Subtract max
    num_segments = tf.reduce_max(segment_ids) + 1
    if len(scores.get_shape()) == 2:
        max_per_partition = tf.unsorted_segment_max(
            tf.reduce_max(scores, axis=1), segment_ids, num_segments)
        scores -= tf.expand_dims(tf.gather(max_per_partition, segment_ids),
                                 axis=1)
    else:
        max_per_partition = tf.unsorted_segment_max(scores, segment_ids,
                                                    num_segments)
        scores -= tf.gather(max_per_partition, segment_ids)

    # Compute probs
    scores_exp = tf.exp(scores)
    if len(scores.get_shape()) == 2:
        scores_exp_sum_per_partition = tf.unsorted_segment_sum(
            tf.reduce_sum(scores_exp, axis=1), segment_ids, num_segments)
        probs = scores_exp / tf.expand_dims(
            tf.gather(scores_exp_sum_per_partition, segment_ids), axis=1)
    else:
        scores_exp_sum_per_partition = tf.unsorted_segment_sum(
            scores_exp, segment_ids, num_segments)
        probs = scores_exp / tf.gather(scores_exp_sum_per_partition,
                                       segment_ids)

    return probs
Пример #2
0
def get_component_bounds(image):
  """Returns the bounding box of each connected component in `image`.

  Connected components are segments of adjacent True pixels in the image.

  Args:
    image: A 2D boolean image tensor.

  Returns:
    A tensor of shape (num_components, 5), where each row represents a connected
        component of the image as `(x0, y0, x1, y1, size)`. `size` is the count
        of True pixels in the component, and the coordinates are the top left
        and bottom right corners of the bounding box.
  """
  with tf.name_scope('get_component_bounds'):
    components = tf.contrib.image.connected_components(image)
    num_components = tf.reduce_max(components) + 1
    width = tf.shape(image)[1]
    height = tf.shape(image)[0]
    xs, ys = tf.meshgrid(tf.range(width), tf.range(height))
    component_x0 = _unsorted_segment_min(xs, components, num_components)[1:]
    component_x1 = tf.unsorted_segment_max(xs, components, num_components)[1:]
    component_y0 = _unsorted_segment_min(ys, components, num_components)[1:]
    component_y1 = tf.unsorted_segment_max(ys, components, num_components)[1:]
    component_size = tf.bincount(components)[1:]
    return tf.stack(
        [
            component_x0, component_y0, component_x1, component_y1,
            component_size
        ],
        axis=1)
Пример #3
0
def aggregate(data, agg_idx, new_size, method="sum"):
    """ Aggregate data

  Args:
    data: tf tensor, see "unsorted_segment_x" in tf documents for more detail
    agg_idx: tf tensor of int, index for aggregation
    new_size: tf tensor of int, size of the data after aggregation
    method: aggregation method

  Returns:
    agg_data: tf tensor, aggregated data
  """

    if method == "sum":
        agg_data = tf.unsorted_segment_sum(data, agg_idx, new_size)
    elif method == "avg":
        agg_data = tf.unsorted_segment_sum(data, agg_idx, new_size)
        denom_const = tf.unsorted_segment_sum(tf.ones_like(data), agg_idx,
                                              new_size)
        agg_data = tf.div(agg_data, (denom_const + tf.constant(1.0e-10)))
    elif method == "max":
        agg_data = tf.unsorted_segment_max(data, agg_idx, new_size)
    elif method == "min":
        agg_data = tf.unsorted_segment_max(-data, agg_idx, new_size)
    else:
        raise ValueError("Unsupported aggregation method!")

    return agg_data
Пример #4
0
def vertical_run_length_encoding(image):
    """Returns the runs in each column of the image.

  A run is a subsequence of consecutive pixels that all have the same value.
  Internally, we treat the image as batches of single-column images in order to
  use connected component analysis.

  Args:
    image: A 2D image.

  Returns:
    The column index of each vertical run.
    The value in the image for each vertical run.
    The length of each vertical run.
  """
    with tf.name_scope('run_length_encoding'):
        image = tf.convert_to_tensor(image, name='image', dtype=tf.bool)
        # Set arbitrary, distinct, nonzero values for True and False pixels.
        # True pixels map to 2, and False pixels map to 1.
        # Transpose the image, and insert an extra dimension. This creates a batch
        # of "images" for connected component analysis, where each image is a single
        # column of the original image. Therefore, the connected components are
        # actually runs from a single column.
        components = contrib_image.connected_components(
            tf.to_int32(tf.expand_dims(tf.transpose(image), axis=1)) + 1)
        # Flatten in order to use with unsorted segment ops.
        flat_components = tf.reshape(components, [-1])

        num_components = tf.maximum(0, tf.reduce_max(components) + 1)
        # Get the column index corresponding to each pixel present in
        # flat_components.
        column_indices = tf.reshape(
            tf.tile(
                # Count 0 through `width - 1` on axis 0, then repeat each element
                # `height` times.
                tf.expand_dims(tf.range(tf.shape(image)[1]), axis=1),
                multiples=[1, tf.shape(image)[0]]),
            # pyformat: disable
            [-1])
        # Take the column index for each component. For each component index k,
        # we want any entry of column_indices where the corresponding entry in
        # flat_components is k. column_indices should be the same for all pixels in
        # the same component, so we can just take the max of all of them. Disregard
        # component 0, which just represents all of the zero pixels across the
        # entire array (should be empty, because we pass in a nonzero image).
        component_columns = tf.unsorted_segment_max(column_indices,
                                                    flat_components,
                                                    num_components)[1:]
        # Take the original value of each component. Again, the value should be the
        # same for all pixels in a single component, so we can just take the max.
        component_values = tf.unsorted_segment_max(
            tf.to_int32(tf.reshape(tf.transpose(image), [-1])),
            flat_components, num_components)[1:]
        # Take the length of each component (run), by counting the number of pixels
        # in the component.
        component_lengths = tf.to_int32(tf.bincount(flat_components)[1:])
        return component_columns, component_values, component_lengths
Пример #5
0
    def marginalize_table(self, table, pool_mode, axis=None, keep_dims=False):
        vals = tf.reshape(table['values'], shape=[-1, self.units_in])
        eps = 1e-10
        out = None
        if axis == 0:
            inds = table['indices'][:, 1]
            num_segments = table['shape'][1]
            if pool_mode == 'mean':
                count = self.count_entries(table, axis,
                                           keep_dims=keep_dims) + eps
                out = tf.unsorted_segment_sum(vals,
                                              inds,
                                              num_segments=num_segments)
                if keep_dims:
                    out = tf.expand_dims(out, axis=0)
                out = out / count
            elif pool_mode == 'max':
                out = tf.unsorted_segment_max(vals,
                                              inds,
                                              num_segments=num_segments)
                if keep_dims:
                    out = tf.expand_dims(out, axis=0)
        elif axis == 1:
            inds = table['indices'][:, 0]
            num_segments = table['shape'][0]
            if pool_mode == 'mean':
                count = self.count_entries(table, axis,
                                           keep_dims=keep_dims) + eps
                out = tf.unsorted_segment_sum(vals,
                                              inds,
                                              num_segments=num_segments)
                if keep_dims:
                    out = tf.expand_dims(out, axis=1)
                out = out / count
            elif pool_mode == 'max':
                out = tf.unsorted_segment_max(vals,
                                              inds,
                                              num_segments=num_segments)
                if keep_dims:
                    out = tf.expand_dims(out, axis=1)
        elif axis == None:
            if 'mean' in pool_mode:
                count = self.count_entries(table, axis, keep_dims=keep_dims)
                out = tf.reduce_sum(vals, axis=0, keep_dims=keep_dims)
                out = out / count
            elif 'max' in pool_mode:
                out = tf.reduce_max(vals, axis=0, keep_dims=keep_dims)
                if keep_dims:
                    out = tf.expand_dims(out, axis=1)
        else:
            raise ValueError("Unknown axis: %s" % axis)

        if pool_mode == 'max':  ## Hack to avoid large negative number. How to deal with max over no entries?
            out = tf.where(tf.greater(out, -200000000), out,
                           tf.zeros_like(out))
        return out
Пример #6
0
    def compute_candidate_softmax_and_loss(self, cand_logits):
        # The following is softmax-ing over the candidates per graph.
        # As the number of candidates varies, we can't just use tf.softmax.
        # We implement it with the logsumexp trick:

        # Step (1): Obtain shift constant as max of the logits
        max_per_graph = tf.unsorted_segment_max(
            data=cand_logits,
            segment_ids=self.placeholders['cand_graph_nodes_list'],
            num_segments=self.placeholders['num_graphs_in_batch']
        )  # Shape [G]

        # # Step (2): Distribute max out to the corresponding logits again, and shift scores:
        max_per_cand = tf.gather(params=max_per_graph,
                                 indices=self.placeholders['cand_graph_nodes_list'])

        cand_logits_shifted = cand_logits - max_per_cand

        # # Step (3): Exp, sum up per target, compute exp(score) / exp(sum) as softmax:
        scores_exped = tf.exp(cand_logits_shifted)
        scores_sum_per_graph = tf.unsorted_segment_sum(
            data=scores_exped,
            segment_ids=self.placeholders['cand_graph_nodes_list'],
            num_segments=self.placeholders['num_graphs_in_batch']
        )  # Shape [G]

        scores_sum_per_cand = tf.gather(
            params=scores_sum_per_graph,
            indices=self.placeholders['cand_graph_nodes_list']
        )

        self.ops['softmax_values'] = scores_exped / (scores_sum_per_cand + utils.SMALL_NUMBER)
        self.ops['log_softmax_values'] = cand_logits_shifted - tf.log(scores_sum_per_cand + utils.SMALL_NUMBER)
        labels = self.placeholders['select_targets']
        flat_loss_values = -tf.cast(labels, "float32") * self.ops['log_softmax_values']
        losses = tf.unsorted_segment_sum(
            data=flat_loss_values,
            segment_ids=self.placeholders['cand_graph_nodes_list'],
            num_segments=self.placeholders['num_graphs_in_batch']
        )

        self.ops['loss'] = tf.reduce_mean(losses)

        flat_correct_prediction = tf.cast(tf.equal(cand_logits, max_per_cand), "int64") * self.placeholders[
            'select_targets']

        correct_prediction = tf.unsorted_segment_max(
            data=tf.cast(flat_correct_prediction, "float32"),
            segment_ids=self.placeholders['cand_graph_nodes_list'],
            num_segments=self.placeholders['num_graphs_in_batch']
        )

        self.ops['accuracy_task'] = tf.reduce_mean(correct_prediction)
Пример #7
0
 def _scale_and_center_cloud(self, points, ids):
     num_scenes = tf.to_int32((tf.reduce_max(ids) //
                               self.num_objects_per_scene) + 1)
     scene_ids = tf.to_int32(ids // self.num_objects_per_scene)
     # convert to int, as unsorted_segment_{min, max} is faster for int
     points_int = tf.to_int32(points * 10000.)
     axis_min = tf.to_float(
         tf.unsorted_segment_min(points_int, scene_ids,
                                 num_scenes)) / 10000.
     axis_max = tf.to_float(
         tf.unsorted_segment_max(points_int, scene_ids,
                                 num_scenes)) / 10000.
     axis_min.set_shape(axis_min.shape.with_rank(1))
     axis_max.set_shape(axis_max.shape.with_rank(1))
     axis_span = axis_max - axis_min
     with tf.name_scope("scale_to_image_cube"):
         max_span = tf.reduce_max(axis_span, axis=-1, keepdims=True)
         sfactor = tf.divide((self.img_size - 2.0),
                             max_span,
                             name="scale_factor")
         points = points * tf.gather(sfactor, scene_ids)
         # update min/max/span to save computation
     with tf.name_scope("center_objects"):
         axis_shift = (-axis_min * sfactor +
                       (((self.img_size - 2.0) - axis_span * sfactor) / 2))
         gathered_shift = tf.gather(axis_shift, scene_ids)
         points = points + gathered_shift
         return points
Пример #8
0
    def compute_attention_normalization(self, message_attention_scores, message_targets, num_nodes):
        if self.params['attention_normalization'] == 'softmax':
            # The following is softmax-ing over the incoming messages per node.
            # As the number of incoming varies, we can't just use tf.softmax.
            # Reimplement with logsumexp trick:

            # Step (1): Obtain shift constant as max of messages going into a node
            message_attention_score_max_per_target = tf.unsorted_segment_max(
                data=message_attention_scores,
                segment_ids=message_targets,
                num_segments=num_nodes)  # Shape [V]

            # Step (2): Distribute max out to the corresponding messages again, and shift scores:
            message_attention_score_max_per_message = tf.gather(
                params=message_attention_score_max_per_target,
                indices=message_targets)  # Shape [M]

            message_attention_scores -= message_attention_score_max_per_message

            # Step (3): Exp, sum up per target, compute exp(score) / exp(sum) as attention prob:
            message_attention_scores_exped = tf.exp(message_attention_scores)  # Shape [M]
            message_attention_score_sum_per_target = tf.unsorted_segment_sum(
                data=message_attention_scores_exped,
                segment_ids=message_targets,
                num_segments=num_nodes)  # Shape [V]

            message_attention_normalisation_sum_per_message = tf.gather(
                params=message_attention_score_sum_per_target,
                indices=message_targets)  # Shape [M]

            message_attention = message_attention_scores_exped / (
                    message_attention_normalisation_sum_per_message + utils.SMALL_NUMBER)  # Shape [M]

            return message_attention
Пример #9
0
def bidaf_layer(seq1,
                seq1_length,
                seq2,
                seq2_length,
                seq1_to_seq2=None,
                seq2_to_seq1=None):
    """Encodes seq1 conditioned on seq2, e.g., using word-by-word attention."""
    attn_scores, attn_probs, seq2_weighted = attention.diagonal_bilinear_attention(
        seq1, seq2, seq2_length, False, seq2_to_seq1=seq2_to_seq1)

    attn_scores += tf.expand_dims(
        mask_for_lengths(seq1_length,
                         tf.shape(attn_scores)[1]), 2)

    max_seq1 = tf.reduce_max(attn_scores, 2)
    if seq1_to_seq2 is None:
        seq1_attention = tf.nn.softmax(max_seq1, 1)
    else:
        segm_max_seq1 = tf.unsorted_segment_max(
            max_seq1, seq1_to_seq2,
            tf.reduce_max(seq1_to_seq2) + 1)
        seq1_attention = tf.nn.softmax(segm_max_seq1, 1)
        seq1_attention = tf.gather(seq1_attention, seq1_to_seq2)
        seq1_attention.set_shape(max_seq1.get_shape())
    seq1_weighted = tf.einsum('ij,ijk->ik', seq1_attention, seq1)
    seq1_weighted = tf.expand_dims(seq1_weighted, 1)
    seq1_weighted = tf.tile(seq1_weighted, [1, tf.shape(seq1)[1], 1])

    return tf.concat(
        [seq2_weighted, seq1 * seq2_weighted, seq1 * seq1_weighted], 2)
Пример #10
0
def find_and_solve_collided_indices(indices, values, shape):
    """Sometimes ground truth indices will be collided,

  shape: - a TensorShape
  We attempted to solved it by :
     * Find all a set of collided indices
     * For each set, update to the next possible index (based on iou_score)
     * If not possible, remove ground truths :(
  """
    width = shape[0].value
    height = shape[1].value
    depth = shape[2].value

    def reverse(index):
        # @TODO: linearize N-d dimension
        x = index / (height * depth)
        y = (index - x * height * depth) / depth
        z = index - x * height * depth - y * depth
        return tf.stack([x, y, z], -1)

    flatten = tf.matmul(tf.cast(indices, tf.int32),
                        [[height * depth], [depth], [1]])
    filtered_idx, idx = tf.unique(tf.squeeze(flatten))

    # @TODO: filter based on IOU
    updated_indices = tf.cast(
        tf.map_fn(fn=lambda i: reverse(i), elems=filtered_idx), tf.int64)
    updated_values = tf.unsorted_segment_max(
        values, idx, num_segments=tf.shape(filtered_idx)[0])

    return [updated_indices, updated_values]
Пример #11
0
def pick_max_features(feature, flatten, num_voxel):
    '''
    Args:
        feature : n x f
        flatten : n x 1 -> 1-d voxel id for each point
    '''
    
    # filtered: k -> unique voxel id 
    # idx : n -> indices of each point in filtered
    filtered, idx = tf.unique(tf.squeeze(flatten))

    # k x f -> max pooling in each unique voxel
    updated_features = tf.unsorted_segment_max(feature, idx, tf.shape(filtered)[0])
    #updated_features = tf.unsorted_segment_sum(feature, idx, tf.shape(filtered)[0])
    print(updated_features)

    # k x 3 -> 3-d voxel id for each unique voxel
    updated_indices = tf.map_fn(fn = lambda i: reverse(i, num_voxel), elems = filtered)
    print(updated_indices)

    num_features = updated_features.shape[-1]

    # D x H x W x f
    voxels = tf.scatter_nd(updated_indices, 
                           updated_features, 
                           tf.TensorShape([num_voxel, num_voxel, num_voxel, num_features]))

    return voxels
Пример #12
0
def _unsorted_segment_softmax(data,
                              segment_ids,
                              num_segments,
                              name="unsorted_segment_softmax"):
    """Performs an elementwise softmax operation along segments of a tensor.

  The input parameters are analogous to `tf.unsorted_segment_sum`. It produces
  an output of the same shape as the input data, after performing an
  elementwise sofmax operation between all of the rows with common segment id.

  Args:
    data: A tensor with at least one dimension.
    segment_ids: A tensor of indices segmenting `data` across the first
      dimension.
    num_segments: A scalar tensor indicating the number of segments. It should
      be at least `max(segment_ids) + 1`.
    name: A name for the operation (optional).

  Returns:
    A tensor with the same shape as `data` after applying the softmax operation.

  """
    with tf.name_scope(name):
        segment_maxes = tf.unsorted_segment_max(data, segment_ids,
                                                num_segments)
        maxes = tf.gather(segment_maxes, segment_ids)
        # Possibly refactor to `tf.stop_gradient(maxes)` for better performance.
        data -= maxes
        exp_data = tf.exp(data)
        segment_sum_exp_data = tf.unsorted_segment_sum(exp_data, segment_ids,
                                                       num_segments)
        sum_exp_data = tf.gather(segment_sum_exp_data, segment_ids)
        return exp_data / sum_exp_data
Пример #13
0
  def chain_pool(self,tensor,chains,num_chain_segments,empty,nonempty,mode):
    bsize = self.max_board_size
    assert(len(tensor.shape) == 4)
    assert(len(chains.shape) == 3)
    assert(len(num_chain_segments.shape) == 1)
    assert(tensor.shape[1].value == bsize)
    assert(tensor.shape[2].value == bsize)
    assert(chains.shape[1].value == bsize)
    assert(chains.shape[2].value == bsize)
    assert(mode == "sum" or mode == "max")
    num_channels = tensor.shape[3].value

    #Since tf.unsorted_segment* doesn't operate by batches or channels, we need to manually construct
    #a different shift to add to each batch and each channel so that they pool into disjoint buckets.
    #Each one needs max_chain_idxs different buckets.
    num_segments_by_batch_and_channel = tf.fill([1,num_channels],1) * tf.expand_dims(num_chain_segments,axis=1)
    shift = tf.cumsum(tf.reshape(num_segments_by_batch_and_channel,[-1]),exclusive=True)
    num_segments = tf.reduce_sum(num_chain_segments) * num_channels
    shift = tf.reshape(shift,[-1,1,1,num_channels])

    segments = tf.expand_dims(chains,3) + shift
    if mode == "sum":
      pools = tf.unsorted_segment_sum(tensor,segments,num_segments=num_segments)
    elif mode == "max":
      pools = tf.unsorted_segment_max(tensor,segments,num_segments=num_segments)
    else:
      assert False

    gathered = tf.gather(pools,indices=segments)
    return gathered * tf.expand_dims(nonempty,axis=3) # + tensor * empty
 def unique_with_inverse(x):
     y, idx = tf.unique(x)
     num_segments = tf.shape(y)[0]
     num_elems = tf.shape(x)[0]
     return (y, idx,
             tf.unsorted_segment_max(tf.range(num_elems), idx,
                                     num_segments))
Пример #15
0
            def non_zero_batchsize_op():
                max_length = tf.shape(seq)[1]
                encoded = tf.nn.embedding_lookup(ctxt_word_embeddings, seq)
                one_hot = [0.0] * num_sequences
                one_hot[i] = 1.0
                mode_feature = tf.constant([[one_hot]], tf.float32)
                mode_feature = tf.tile(mode_feature,
                                       tf.stack([num_seq, max_length, 1]))
                encoded = tf.concat([encoded, mode_feature], 2)
                encoded = modular_encoder.modular_encoder(
                    sequence_module, {'text': encoded}, {'text': length},
                    {'text': None}, size, 1.0 - keep_prob, is_eval)[0]['text']

                mask = misc.mask_for_lengths(length,
                                             max_length,
                                             mask_right=False,
                                             value=1.0)
                encoded = encoded * tf.expand_dims(mask, 2)

                seq_lemmas = tf.gather(word2lemma_off, tf.reshape(seq, [-1]))
                new_lemma_embeddings = tf.unsorted_segment_max(
                    tf.reshape(encoded, [-1, size]), seq_lemmas,
                    tf.reduce_max(word2lemma_off) + 1)
                new_lemma_embeddings = tf.nn.relu(new_lemma_embeddings)

                return tf.gather(new_lemma_embeddings, word2lemma_off)
Пример #16
0
def get_pixel_value(img, x, y):
    """Cantor pairing for removing non-unique updates and indices. At the time of implementation, unfixed issue with scatter_nd causes problems with int32 update values. Till resolution, implemented on cpu """

    with tf.device('/cpu:0'):
        indices = tf.stack([y, x], 2)
        indices = tf.reshape(indices, (375 * 1242, 2))
        values = tf.reshape(img, [-1])

        Y = indices[:, 0]
        X = indices[:, 1]
        Y = tf.cast(Y, tf.float64)
        X = tf.cast(X, tf.float64)
        Z = (X + Y) * (X + Y + 1) / 2 + Y

        filtered, idx = tf.unique(tf.squeeze(Z))
        updated_values = tf.unsorted_segment_max(values, idx,
                                                 tf.shape(filtered)[0])

        # updated_indices = tf.map_fn(fn=lambda i: reverse(i), elems=filtered, dtype=tf.float32)
        updated_indices = reverse_all(filtered)
        updated_indices = tf.cast(updated_indices, 'int32')
        resolved_map = tf.scatter_nd(updated_indices, updated_values,
                                     img.shape)

        return resolved_map
Пример #17
0
    def segment_pool(self, point_cloud, current, grid_size, scope=None):
        with tf.variable_scope(scope):
            point_cloud = (point_cloud + 1) / 2 * grid_size
            point_cloud_4d = tf.concat(
                (self.batch_idx, tf.reshape(point_cloud, (-1, 3))), axis=1)
            centers = tf.round(point_cloud_4d)
            point_cloud_idx = tf.cast(centers, tf.int64)
            grid_shape = tf.constant(
                [self.batch_size, grid_size, grid_size, grid_size],
                dtype=tf.int64)
            point_cloud_lin_idx = tf.squeeze(
                ravel_index(point_cloud_idx, grid_shape))
            vox_idx, idx, count = tf.unique_with_counts(point_cloud_lin_idx,
                                                        out_idx=tf.int32)
            vox_idx = tf.cast(vox_idx, dtype=tf.int32)
            vox_mult_idx = tf.transpose(unravel_index(vox_idx, grid_shape),
                                        (1, 0))
            #            batch_idx = tf.squeeze(tf.slice(vox_mult_idx,(0,0),(-1,1)))
            sh = current.get_shape().as_list()
            features_vox = tf.unsorted_segment_max(
                tf.reshape(current, (-1, sh[-1])), idx,
                tf.reduce_max(idx) + 1)
            features = tf.gather(features_vox, idx, axis=0)
            features = tf.reshape(features, sh)
#            max_point_per_vol = tf.segment_max(count,batch_idx)
#            max_point_per_vol = tf.gather(max_point_per_vol,batch_idx)
#            count_normalized = tf.divide(count,max_point_per_vol)
        return features, features_vox, vox_mult_idx, count
Пример #18
0
def get_pixel_value(img, x, y):
    """Cantor pairing for removing non-unique updates and indices. At the time of implementation, unfixed issue with scatter_nd causes problems with int32 update values. Till resolution, implemented on cpu """

    with tf.device('/cpu:0'):
        indices = tf.stack([y, x], 2)
        indices = tf.reshape(indices, (IMG_HT * IMG_WDT, 2))
        values = tf.reshape(img, [-1])

        Y = indices[:, 0]
        X = indices[:, 1]
        # The below raises an Error because
        # Y is int32 but Z1 results in float64 type on the laptop CPU
        # Z = (X + Y)*(X + Y + 1)/2 + Y
        Z1 = (X + Y) * (X + Y + 1) / 2
        Z1 = tf.cast(Z1, 'int32')
        Z = Z1 + Y

        filtered, idx = tf.unique(tf.squeeze(Z))
        updated_values = tf.unsorted_segment_max(values, idx,
                                                 tf.shape(filtered)[0])

        # updated_indices = tf.map_fn(fn=lambda i: reverse(i), elems=filtered, dtype=tf.float32)
        updated_indices = reverse_all(filtered)
        updated_indices = tf.cast(updated_indices, 'int32')
        resolved_map = tf.scatter_nd(updated_indices, updated_values,
                                     img.shape)

        return resolved_map
Пример #19
0
def segment_is_max(inputs, segment_ids):
    num_segments = tf.reduce_max(segment_ids) + 1
    if len(inputs.get_shape()) > 1:
        inputs_max = tf.reduce_max(inputs, reduction_indices=list(range(1, len(inputs.get_shape()))))
    else:
        inputs_max = inputs
    max_per_partition = tf.unsorted_segment_max(inputs_max, segment_ids, num_segments)
    return tf.equal(inputs, tf.gather(max_per_partition, segment_ids))
Пример #20
0
def _unsorted_segment_reduction_or_zero(reducer, values, indices, num_groups):
    """Common code for unsorted_segment_{min,max}_or_zero (below)."""
    reduced = reducer(values, indices, num_groups)
    present_indices = tf.unsorted_segment_max(
        tf.ones_like(indices, dtype=reduced.dtype), indices, num_groups)
    present_indices = tf.clip_by_value(present_indices, 0, 1)
    present_indices = tf.reshape(present_indices, [num_groups] + [1] *
                                 (reduced.shape.ndims - 1))
    reduced *= present_indices
    return reduced
Пример #21
0
def batch_unsrt_segment_max(data, segment_ids, num_segments):
    """ Performas the `tf.unsorted_segment_max` operation batch-wise"""
    # create distinct segments per batch
    num_batches = tf.shape(segment_ids, out_type=tf.int64)[0]
    batch_indices = tf.range(num_batches)
    segment_ids_per_batch = segment_ids + num_segments * tf.expand_dims(batch_indices, axis=1)

    # do the normal unsegment sum and reshape to original shape
    seg_maxs = tf.unsorted_segment_max(data, segment_ids_per_batch, num_segments * num_batches)
    return tf.reshape(seg_maxs, tf.stack((-1, num_segments)))
Пример #22
0
    def rasterize(self,mesh):
        samples_tri  = mesh.faces_up
        vertices_t   = mesh.vertices_t
        faces_values = tf.gather(vertices_t,samples_tri,axis=1) # [batch, samples, edge, xyz ]
        # projection of normals on Z axis
        V1 = tf.gather(faces_values,1,axis=2) - tf.gather(faces_values,0,axis=2)
        V2 = tf.gather(faces_values,2,axis=2) - tf.gather(faces_values,0,axis=2)
        V1x,V1y,V1z = tf.split(V1,[1,1,1],axis=2)
        V2x,V2y,V2z = tf.split(V2,[1,1,1],axis=2)
        normal_z = tf.reshape(V1x*V2y - V1y*V2x,(-1,))
        # Up sampling the mesh
        num_faces    = samples_tri.get_shape().as_list()[0]
        r1   = tf.random_uniform((self.batch_size,num_faces,1,1),dtype=tf.float32)
        r2   = tf.random_uniform((self.batch_size,num_faces,1,1),dtype=tf.float32)
        rand_samps = tf.concat(((1-tf.sqrt(r1)),(tf.sqrt(r1)*(1-r2)),(r2*tf.sqrt(r1))),axis=2)
        vertices_MC  = tf.reduce_sum(faces_values*rand_samps,axis=2)
        num_vertices = num_faces
        # Re-project
        batch_idx_np = np.expand_dims(np.meshgrid(np.arange(0, self.batch_size, 1),np.arange(0, num_vertices, 1))[0].transpose(),axis=2)
        batch_idx = tf.reshape(tf.convert_to_tensor(batch_idx_np.astype(np.float32)),(self.batch_size*num_vertices,1))
        vertices_trans_values = tf.reshape(vertices_MC,(-1,3))
        vertices_trans_values = (vertices_trans_values/2+0.5)
        image_mask = tf.logical_or(tf.reduce_any(tf.less_equal(vertices_trans_values,self.minValue),axis=1),
                                   tf.reduce_any(tf.greater_equal(vertices_trans_values,self.maxValue),axis=1))        
        image_mask = tf.logical_or(image_mask,tf.greater_equal(normal_z,0))
        image_mask = tf.tile(tf.expand_dims(image_mask,axis=-1),(1,3))
        
        
        vertices_trans_values  = tf.where(image_mask,tf.zeros(image_mask.get_shape().as_list(),dtype=tf.float32),vertices_trans_values)
#        vertices_up            = tf.reshape(vertices_trans_values,(self.batch_size,-1,3))*2-1
        vertices_trans_indices_4d = tf.concat((batch_idx,vertices_trans_values*(self.canvas_size-1)),axis=1)
        vertices_trans_indices_4d = tf.cast(vertices_trans_indices_4d,tf.int64)
        point_cloud_lin_idx       = tf.squeeze(ravel_index_bxy(tf.slice(vertices_trans_indices_4d,[0,0],[-1,3]),(self.batch_size,self.canvas_size,self.canvas_size)))
        vox_idx, idx, count       = tf.unique_with_counts(point_cloud_lin_idx,out_idx=tf.int32)
#        indices = tf.transpose(unravel_index(vox_idx,(self.batch_size,self.canvas_size,self.canvas_size),Type=tf.int64),(1,0))
        values_z = -1*tf.unsorted_segment_max(tf.slice(-1*vertices_trans_values,[0,2],[-1,1]),idx,tf.reduce_max(idx)+1)




        # get XYZ values corresponding to values_z
        max_values   = tf.squeeze(tf.gather(values_z,idx,axis=0),axis=1)
        max_xyz_idx  = tf.squeeze(tf.where(tf.equal(vertices_trans_values[:,2],max_values)),axis=1)
        values_xyz     = tf.gather(vertices_trans_values    ,max_xyz_idx,axis=0)
        values_xyz_idx = tf.gather(vertices_trans_indices_4d,max_xyz_idx,axis=0)
        image  = tf.scatter_nd(values_xyz_idx[:,0:3], values_xyz, (self.batch_size,self.canvas_size,self.canvas_size,3)) 
        
        # Semantic labeling image
        semantics = tf.tile(tf.expand_dims(mesh.semantics_up,axis=0),(self.batch_size,1,1))
        semantics = tf.reshape(semantics,(-1,3))
        semantics = tf.where(image_mask,tf.zeros(image_mask.get_shape().as_list(),dtype=tf.int64),semantics)
        semantics_visible = tf.gather(semantics, max_xyz_idx,axis=0)
        image_semantics   = tf.scatter_nd(values_xyz_idx[:,0:3], semantics_visible, (self.batch_size,self.canvas_size,self.canvas_size,3)) 

        return image, image_semantics
Пример #23
0
    def define_prediction_with_loss(self, node_embeddings):
        node_embeddings = tf.identity(node_embeddings)
        graph_embeddings = self.define_pooling(node_embeddings)
        domain_nodes_embeddings = tf.gather(
            params=node_embeddings, indices=self.placeholders['domain'])
        graph_embeddings_copied = tf.gather(
            params=graph_embeddings,
            indices=self.placeholders['domain_node_graph_ids_list'])

        domain_node_score_calculator = MLP(
            in_size=domain_nodes_embeddings.get_shape()[1] +
            graph_embeddings_copied.get_shape()[1],
            out_size=1,
            hid_sizes=self.classifier_hidden_dims)

        domain_node_logits = domain_node_score_calculator(
            tf.concat([domain_nodes_embeddings, graph_embeddings_copied],
                      axis=-1))
        domain_node_logits = tf.reshape(domain_node_logits, [-1])
        probs, log_probs = SegmentBasedSoftmax(
            data=domain_node_logits,
            segment_ids=self.placeholders['domain_node_graph_ids_list'],
            num_segments=self.placeholders['num_graphs'],
            return_log=True)
        self.ops['probabilities'] = probs

        loss_per_domain_node = -tf.cast(self.placeholders['domain_labels'],
                                        tf.float32) * log_probs
        loss_per_graph = tf.unsorted_segment_sum(
            data=loss_per_domain_node,
            segment_ids=self.placeholders['domain_node_graph_ids_list'],
            num_segments=self.placeholders['num_graphs'])
        self.ops['loss'] = tf.reduce_mean(loss_per_graph)

        domain_node_max_scores = tf.unsorted_segment_max(
            data=domain_node_logits,
            segment_ids=self.placeholders['domain_node_graph_ids_list'],
            num_segments=self.placeholders['num_graphs'])
        copied_domain_node_max_scores = tf.gather(
            params=domain_node_max_scores,
            indices=self.placeholders['domain_node_graph_ids_list'])

        selected_domain_nodes = tf.cast(tf.equal(copied_domain_node_max_scores,
                                                 domain_node_logits),
                                        dtype=tf.int32)
        correct_prediction_per_node = tf.cast(
            tf.equal(selected_domain_nodes,
                     self.placeholders['domain_labels']), tf.float32)
        correct_prediction = tf.unsorted_segment_prod(
            data=correct_prediction_per_node,
            segment_ids=self.placeholders['domain_node_graph_ids_list'],
            num_segments=self.placeholders['num_graphs'])

        self.ops['accuracy'] = tf.reduce_mean(correct_prediction)
def edge_normalize(edge_states, sender_node_ids, n_nodes=None, sorted=True):
    """
    Args:
        edge_states: batch_size x n_edges x n_edge_dims
        sender_node_ids: n_edges
        sorted: the list sender_node_ids is sorted or not
    Returns:
        edge_states_norm: batch_size x n_nodes x n_edge_dims
    """
    edge_states = tf.transpose(edge_states,
                               perm=[1, 0,
                                     2])  # n_edges x batch_size x n_edge_dims

    if sorted:
        edge_states_max = tf.segment_max(
            edge_states, sender_node_ids)  # n_nodes x batch_size x n_edge_dims
        edge_states_max = tf.gather(
            edge_states_max,
            sender_node_ids)  # n_edges x batch_size x n_edge_dims
        edge_states_exp = tf.exp(
            edge_states -
            edge_states_max)  # n_edges x batch_size x n_edge_dims
        edge_states_sumexp = tf.segment_sum(
            edge_states_exp,
            sender_node_ids)  # n_nodes x batch_size x n_edge_dims
        edge_states_sumexp = tf.gather(
            edge_states_sumexp,
            sender_node_ids)  # n_edges x batch_size x n_edge_dims
        edge_states_norm = edge_states_exp / edge_states_sumexp  # n_edges x batch_size x n_edge_dims
    else:
        if n_nodes is None:
            raise ValueError('`n_nodes` should not be None')
        edge_states_max = tf.unsorted_segment_max(
            tf.transpose(edge_states, perm=[1, 0, 2]), sender_node_ids,
            n_nodes)  # n_nodes x batch_size x n_edge_dims
        edge_states_max = tf.gather(
            edge_states_max,
            sender_node_ids)  # n_edges x batch_size x n_edge_dims
        edge_states_exp = tf.exp(
            edge_states -
            edge_states_max)  # n_edges x batch_size x n_edge_dims
        edge_states_sumexp = tf.unsorted_segment_sum(
            edge_states_exp, sender_node_ids,
            n_nodes)  # n_nodes x batch_size x n_edge_dims
        edge_states_sumexp = tf.gather(
            edge_states_sumexp,
            sender_node_ids)  # n_edges x batch_size x n_edge_dims
        edge_states_norm = edge_states_exp / edge_states_sumexp  # n_edges x batch_size x n_edge_dims

    edge_states_norm = tf.transpose(
        edge_states_norm, perm=[1, 0, 2])  # batch_size x n_edges x n_edge_dims
    return edge_states_norm
Пример #25
0
    def get_batch_max_per_key(tensor, key_uniques, dtype):  # pylint: disable=missing-docstring
        if tensor.get_shape().ndims < 2:
            row_maxes = tensor
        else:
            row_maxes = tf.reduce_max(tensor,
                                      axis=tf.range(1,
                                                    tensor.get_shape().ndims))
        batch_max = tf.unsorted_segment_max(row_maxes, key_uniques.idx,
                                            tf.size(input=key_uniques.y))

        # TODO(b/112309021): Remove workaround once tf.reduce_max of a tensor of all
        # NaNs produces -inf.
        return _inf_to_nan(batch_max, dtype)
Пример #26
0
def xqa_crossentropy_loss(start_scores,
                          end_scores,
                          answer_span,
                          answer2support,
                          support2question,
                          use_sum=True):
    """Very common XQA loss function."""
    num_questions = tf.reduce_max(support2question) + 1

    start, end = answer_span[:, 0], answer_span[:, 1]

    start_probs = segment_softmax(start_scores, support2question)
    start_probs = tf.gather_nd(start_probs, tf.stack([answer2support, start],
                                                     1))

    # only start probs are normalized on multi-paragraph, end probs conditioned on start only on per support level
    num_answers = tf.shape(answer_span)[0]
    is_aligned = tf.equal(tf.shape(end_scores)[0], num_answers)
    end_probs = tf.cond(
        is_aligned, lambda: tf.gather_nd(
            tf.nn.softmax(end_scores),
            tf.stack([tf.range(num_answers, dtype=tf.int32), end], 1)),
        lambda: tf.gather_nd(segment_softmax(end_scores, support2question),
                             tf.stack([answer2support, end], 1)))

    answer2question = tf.gather(support2question, answer2support)
    # compute losses individually
    if use_sum:
        span_probs = tf.unsorted_segment_sum(
            start_probs,
            answer2question, num_questions) * tf.unsorted_segment_sum(
                end_probs, answer2question, num_questions)
    else:
        span_probs = tf.unsorted_segment_max(
            start_probs,
            answer2question, num_questions) * tf.unsorted_segment_max(
                end_probs, answer2question, num_questions)

    return -tf.reduce_mean(tf.log(tf.maximum(1e-6, span_probs + 1e-6)))
Пример #27
0
 def apply(self, x, segments, num_sentences_mask):
     num_segments = tf.shape(num_sentences_mask)[0] * tf.reduce_max(
         num_sentences_mask)
     segmented = tf.unsorted_segment_max(x,
                                         segments,
                                         num_segments=num_segments)
     reshaped = tf.reshape(segmented,
                           (tf.shape(x)[0], -1, x.shape.as_list()[2]))
     mask = tf.expand_dims(
         tf.cast(
             tf.sequence_mask(num_sentences_mask,
                              tf.shape(reshaped)[1]), tf.float32), 2)
     reshaped *= mask
     return reshaped
Пример #28
0
def unsorted_segment_softmax(logits, segment_ids, num_segments):
    """Perform a safe unsorted segment softmax."""
    max_per_segment = tf.unsorted_segment_max(data=logits,
                                              segment_ids=segment_ids,
                                              num_segments=num_segments)
    scattered_maxes = tf.gather(params=max_per_segment, indices=segment_ids)
    recentered_scores = logits - scattered_maxes
    exped_recentered_scores = tf.exp(recentered_scores)

    per_segment_sums = tf.unsorted_segment_sum(exped_recentered_scores,
                                               segment_ids, num_segments)

    probs = exped_recentered_scores / (
        tf.gather(params=per_segment_sums, indices=segment_ids) + SMALL_NUMBER)
    return probs
Пример #29
0
def message_passing(state, read_ids, write_ids, node_count, name):
    values = tf.nn.embedding_lookup(
        state, read_ids, name="lookup_" + name)

    s_sum = tf.unsorted_segment_sum(
        values, write_ids, node_count, name="segment_sum_" + name)

    s_max = tf.unsorted_segment_max(
        values, write_ids, node_count, name="segment_max_" + name)
    s_max = tf.maximum(s_max, -1.0)

    s_min = tf.unsorted_segment_min(
        values, write_ids, node_count, name="segment_min_" + name)
    s_min = tf.minimum(s_min, 1.0)

    return [s_sum, s_max, s_min]
Пример #30
0
def unsorted_segment_logsumexp(scores, segment_ids, num_segments):
    """Perform an unsorted segment safe logsumexp."""
    # Note: if a segment is empty, the smallest value for the score will be returned,
    # which yields the correct behavior
    max_per_segment = tf.unsorted_segment_max(data=scores,
                                              segment_ids=segment_ids,
                                              num_segments=num_segments)
    scattered_log_maxes = tf.gather(params=max_per_segment,
                                    indices=segment_ids)
    recentered_scores = scores - scattered_log_maxes
    exped_recentered_scores = tf.exp(recentered_scores)

    per_segment_sums = tf.unsorted_segment_sum(exped_recentered_scores,
                                               segment_ids, num_segments)
    per_segment_logs = tf.log(per_segment_sums)
    return per_segment_logs + max_per_segment
Пример #31
0
def log_partition_function(num_nodes,
                           scores,
                           forest=False,
                           max_dynamic_range=None):
  r"""Returns the log of the sum-of-product of spanning trees or forests.

  Computing the sum-of-product in the log domain reduces the chance of overflow
  or underflow, and ML techniques (e.g., CRF loss functions) typically require
  the log partition function anyways.  For similar reasons, the scores input is
  assumed to be specified in the log domain.

  The partition function is caluclated via application of the Matrix-Tree
  theorem; see the following for details:
    https://en.wikipedia.org/wiki/Kirchhoff%27s_theorem
    http://www.aclweb.org/anthology/D/D07/D07-1015.pdf

  Computing the gradient of the log partition function requires inverting the
  Laplacian matrix.  Numerical issues may occur if the Laplacian is singular or
  nearly-so.  (Intuitively, the Laplacian will be close to singular when the
  input scores strongly favor invalid structures such as cycles).  In the EMNLP
  paper, we alleviated the numerical issues by clipping the difference between
  the minimum and maximum score for each node to 20 (in the log domain).  The
  |max_dynamic_range| argument can be used for this purpose.

  TODO(googleuser): Try improving the condition number of the Laplacian matrix
  directly, instead of using the indirect approach above.  For example, one
  could add c*I to the Laplacian (i.e., Tikhonov regularization).

  Args:
    num_nodes: [B] vector of graph sizes per batch item.
    scores: [B,M,M] tensor of padded batched arc and root scores, in the format
      used by the maximum_spanning_tree() op.  Padding values must be finite.
    forest: If true, sum over spanning forests instead of trees.
    max_dynamic_range: If specified, incoming scores for each node are clipped
      to at most this far from the maximum such score (in the log domain).

  Returns:
    [B] vector Z of log partition function values, where
      Z[b] = log(
          \sum_{tree spanning batch item b}
              score(root_of(tree)) \prod_{arc in tree} score(arc))
  """
  orig_dtype = scores.dtype.base_dtype
  scores_bxmxm = tf.to_double(scores)  # use doubles to reduce under/overflow
  shape_bxmxm = tf.shape(scores_bxmxm)
  batch_size = shape_bxmxm[0]
  max_nodes = shape_bxmxm[1]
  total_nodes = batch_size * max_nodes

  # To eliminate overflow, we locally normalize the scores.  Specifically, for
  # each node we divide its incoming arc scores and root selection score by the
  # maximum such score.  Since each node in a tree must select exactly one of
  # these scores (i.e., it is either a root or has exactly one incoming arc),
  # the local normalization factors are identical for all trees and can thus be
  # factored out of the sum over trees.
  #
  # More concretely, we find the maximum per node, divide all scores for that
  # node by the maximum, and then find the partition function of the normalized
  # scores.  Then we recover the un-normalized partition function by multiplying
  # the per-node maxima back in.  This final step is performed in the log domain
  # to avoid overflow.
  #
  # Note that underflow is still possible, but unlikely as long as the scores
  # are close to feasible (i.e., there is not too much mass on non-trees).  The
  # |max_dynamic_range| argument can be used to mitigate this.

  # Finding the maximum incoming score is difficult, because the batch padding
  # may contain arbitrary values.  We restrict the maximization to valid arcs
  # using tf.unsorted_segment_max() with a specially-constructed set of IDs.
  _, valid_tokens_bxm = digraph_ops.ValidArcAndTokenMasks(
      num_nodes, max_nodes, dtype=tf.int32)

  # Create a tensor of "target IDs".  In each row of each sub-matrix, the
  # positions of valid source tokens are filled with the 1-origin index of that
  # row in the entire batch, and zero elsewhere.  For example, given a batch
  # with num_nodes=[2, 3] we might have
  #   [[[1, 1, 0],
  #     [2, 2, 0],
  #     [3, 3, 0]],
  #    [[4, 4, 4],
  #     [5, 5, 5],
  #     [6, 6, 6]]]
  #
  # TODO(googleuser): The dynamic masking is pretty awkward.  Find an op that does
  # this (I looked, but maybe not hard enough), or write a custom op for this.
  valid_tokens_bx1xm = tf.expand_dims(valid_tokens_bxm, 1)
  valid_sources_bxmxm = tf.tile(valid_tokens_bx1xm, [1, max_nodes, 1])
  sequence_bm = 1 + tf.range(total_nodes, dtype=tf.int32)
  sequence_bxmx1 = tf.reshape(sequence_bm, [batch_size, max_nodes, 1])
  target_ids_bxmxm = valid_sources_bxmxm * sequence_bxmx1

  max_scores_bm1 = tf.unsorted_segment_max(scores_bxmxm, target_ids_bxmxm,
                                           total_nodes + 1)
  max_scores_bm = max_scores_bm1[1:]  # ID 0 corresponds to padding

  # Similar to above, we need to sum over the valid tokens.  We analogously use
  # tf.unsorted_segment_sum() with a specially-constructed set of "batch IDs".
  sequence_b = 1 + tf.range(batch_size, dtype=tf.int32)
  sequence_bx1 = tf.expand_dims(sequence_b, 1)
  batch_ids_bxm = valid_tokens_bxm * sequence_bx1
  batch_ids_bm = tf.reshape(batch_ids_bxm, [-1])

  log_normalization_factor_b1 = tf.unsorted_segment_sum(
      max_scores_bm, batch_ids_bm, batch_size + 1)
  log_normalization_factor_b = log_normalization_factor_b1[1:]

  # Locally-normalize and optionally clip the scores.
  max_scores_bxmx1 = tf.reshape(max_scores_bm, [batch_size, max_nodes, 1])
  scores_bxmxm -= max_scores_bxmx1
  if max_dynamic_range is not None:
    # After normalization, the scores are non-positive with max=0, so the
    # |max_dynamic_range| can be applied directly.
    #
    # PyLint thinks "-max_dynamic_range" is invalid because it defaults to None.

    scores_bxmxm = tf.maximum(scores_bxmxm, -max_dynamic_range)
  scores_bxmxm = tf.exp(scores_bxmxm)

  # Apply the Matrix-Tree theorem.
  exp_normalized_laplacian_bxmxm = digraph_ops.LaplacianMatrix(
      num_nodes, scores_bxmxm, forest=forest)
  log_normalized_partition_function_b = tf.log(
      tf.matrix_determinant(exp_normalized_laplacian_bxmxm))

  # Reapply the normalization factor that was divided out.
  log_partition_function_b = (
      log_normalized_partition_function_b + log_normalization_factor_b)
  return tf.cast(log_partition_function_b, orig_dtype)