def nearest_neighbor_upsampling(input_tensor, scale): """Nearest neighbor upsampling implementation. Nearest neighbor upsampling function that maps input tensor with shape [batch_size, height, width, channels] to [batch_size, height * scale , width * scale, channels]. This implementation only uses reshape and broadcasting to make it TPU compatible. Args: input_tensor: A float32 tensor of size [batch, height_in, width_in, channels]. scale: An integer multiple to scale resolution of input data. Returns: data_up: A float32 tensor of size [batch, height_in*scale, width_in*scale, channels]. """ with tf.name_scope('nearest_neighbor_upsampling'): (batch_size, height, width, channels ) = shape_utils.combined_static_and_dynamic_shape(input_tensor) output_tensor = tf.reshape(input_tensor, [ batch_size, height, 1, width, 1, channels ]) * tf.ones([1, 1, scale, 1, scale, 1], dtype=input_tensor.dtype) return tf.reshape( output_tensor, [batch_size, height * scale, width * scale, channels])
def select_random_box(boxlist, default_box=None, seed=None, scope=None): """Selects a random bounding box from a `BoxList`. Args: boxlist: A BoxList. default_box: A [1, 4] float32 tensor. If no boxes are present in `boxlist`, this default box will be returned. If None, will use a default box of [[-1., -1., -1., -1.]]. seed: Random seed. scope: Name scope. Returns: bbox: A [1, 4] tensor with a random bounding box. valid: A bool tensor indicating whether a valid bounding box is returned (True) or whether the default box is returned (False). """ with tf.name_scope(scope, 'SelectRandomBox'): bboxes = boxlist.get() combined_shape = shape_utils.combined_static_and_dynamic_shape(bboxes) number_of_boxes = combined_shape[0] default_box = default_box or tf.constant([[-1., -1., -1., -1.]]) def select_box(): random_index = tf.random_uniform([], maxval=number_of_boxes, dtype=tf.int32, seed=seed) return tf.expand_dims(bboxes[random_index], axis=0), tf.constant(True) return tf.cond(tf.greater_equal(number_of_boxes, 1), true_fn=select_box, false_fn=lambda: (default_box, tf.constant(False)))
def _create_regression_targets(self, anchors, groundtruth_boxes, match): matched_gt_boxes = match.gather_based_on_match( groundtruth_boxes.get(), unmatched_value=tf.zeros(4), ignored_value=tf.zeros(4)) matched_gt_boxlist = box_list.BoxList(matched_gt_boxes) #### if groundtruth_boxes.has_field(KEYPOINTS_FIELD_NAME): groundtruth_keypoints = groundtruth_boxes.get_field( KEYPOINTS_FIELD_NAME) matched_keypoints = match.gather_based_on_match( groundtruth_keypoints, unmatched_value=tf.zeros( groundtruth_keypoints.get_shape()[1:]), ignored_value=tf.zeros(groundtruth_keypoints.get_shape()[1:])) matched_gt_boxlist.add_field(KEYPOINTS_FIELD_NAME, matched_keypoints) #### matched_reg_targets = self._box_coder.encode(matched_gt_boxlist, anchors) match_results_shape = shape_utils.combined_static_and_dynamic_shape( match.match_results) unmatched_ignored_reg_targets = tf.tile( self._default_regression_target(), [match_results_shape[0], 1]) matched_anchors_mask = match.matched_column_indicator() reg_targets = tf.where(matched_anchors_mask, matched_reg_targets, unmatched_ignored_reg_targets) return reg_targets
def matmul_gather_on_zeroth_axis(params, indices, scope=None): """Matrix multiplication based implementation of tf.gather on zeroth axis. TODO(rathodv, jonathanhuang): enable sparse matmul option. Args: params: A float32 Tensor. The tensor from which to gather values. Must be at least rank 1. indices: A Tensor. Must be one of the following types: int32, int64. Must be in range [0, params.shape[0]) scope: A name for the operation (optional). Returns: A Tensor. Has the same type as params. Values from params gathered from indices given by indices, with shape indices.shape + params.shape[1:]. """ with tf.name_scope(scope, 'MatMulGather'): params_shape = shape_utils.combined_static_and_dynamic_shape(params) indices_shape = shape_utils.combined_static_and_dynamic_shape(indices) params2d = tf.reshape(params, [params_shape[0], -1]) indicator_matrix = tf.one_hot(indices, params_shape[0]) gathered_result_flattened = tf.matmul(indicator_matrix, params2d) return tf.reshape(gathered_result_flattened, tf.stack(indices_shape + params_shape[1:]))
def nearest_neighbor_upsampling(input_tensor, scale=None, height_scale=None, width_scale=None): """Nearest neighbor upsampling implementation. Nearest neighbor upsampling function that maps input tensor with shape [batch_size, height, width, channels] to [batch_size, height * scale , width * scale, channels]. This implementation only uses reshape and broadcasting to make it TPU compatible. Args: input_tensor: A float32 tensor of size [batch, height_in, width_in, channels]. scale: An integer multiple to scale resolution of input data in both height and width dimensions. height_scale: An integer multiple to scale the height of input image. This option when provided overrides `scale` option. width_scale: An integer multiple to scale the width of input image. This option when provided overrides `scale` option. Returns: data_up: A float32 tensor of size [batch, height_in*scale, width_in*scale, channels]. Raises: ValueError: If both scale and height_scale or if both scale and width_scale are None. """ if not scale and (height_scale is None or width_scale is None): raise ValueError('Provide either `scale` or `height_scale` and' ' `width_scale`.') with tf.name_scope('nearest_neighbor_upsampling'): h_scale = scale if height_scale is None else height_scale w_scale = scale if width_scale is None else width_scale (batch_size, height, width, channels ) = shape_utils.combined_static_and_dynamic_shape(input_tensor) output_tensor = tf.stack([input_tensor] * w_scale, axis=3) output_tensor = tf.stack([output_tensor] * h_scale, axis=2) return tf.reshape( output_tensor, [batch_size, height * h_scale, width * w_scale, channels])
def assign(self, anchors, groundtruth_boxes, groundtruth_labels=None, groundtruth_weights=None, **params): if not isinstance(anchors, box_list.BoxList): raise ValueError('anchors must be an BoxList') if not isinstance(groundtruth_boxes, box_list.BoxList): raise ValueError('groundtruth_boxes must be an BoxList') if groundtruth_labels is None: #shape=[N,1] groundtruth_labels = tf.ones( tf.expand_dims(groundtruth_boxes.num_boxes(), 0)) groundtruth_labels = tf.expand_dims(groundtruth_labels, -1) unmatched_shape_assert = shape_utils.assert_shape_equal( shape_utils.combined_static_and_dynamic_shape(groundtruth_labels) [1:], shape_utils.combined_static_and_dynamic_shape( self._unmatched_cls_target)) labels_and_box_shapes_assert = shape_utils.assert_shape_equal( shape_utils.combined_static_and_dynamic_shape(groundtruth_labels) [:1], shape_utils.combined_static_and_dynamic_shape( groundtruth_boxes.get())[:1]) if groundtruth_weights is None: num_gt_boxes = groundtruth_boxes.num_boxes_static() if not num_gt_boxes: num_gt_boxes = groundtruth_boxes.num_boxes() groundtruth_weights = tf.ones([num_gt_boxes], dtype=tf.float32) with tf.control_dependencies( [unmatched_shape_assert, labels_and_box_shapes_assert]): match_quality_matrix = self._similarity_calc.compare( groundtruth_boxes, anchors) match = self._matcher.match(match_quality_matrix, **params) #shape=[anchor_num,4] reg_targets = self._create_regression_targets( anchors, groundtruth_boxes, match) #shape=[anchor_num,1] cls_targets = self._create_classification_targets( groundtruth_labels, match) #shape=[anchor_num,] reg_weights = self._create_regression_weights( match, groundtruth_weights) #shape=[anchor_num,] cls_weights = self._create_classification_weights( match, groundtruth_weights) num_anchors = anchors.num_boxes_static() if num_anchors is not None: reg_targets = self._reset_target_shape(reg_targets, num_anchors) cls_targets = self._reset_target_shape(cls_targets, num_anchors) reg_weights = self._reset_target_shape(reg_weights, num_anchors) cls_weights = self._reset_target_shape(cls_weights, num_anchors) return cls_targets, cls_weights, reg_targets, reg_weights, match