def test_get_correct_counts(self): print('\n==========================================================') print('test_get_correct_counts') match_results = tf.constant([3, 1, -1, 0, -1, 5, -2]) match = matcher.Match(match_results) exp_num_matched_columns = 4 exp_num_unmatched_columns = 2 exp_num_ignored_columns = 1 num_matched_columns = match.num_matched_columns() num_unmatched_columns = match.num_unmatched_columns() num_ignored_columns = match.num_ignored_columns() self.assertEquals(num_matched_columns.dtype, tf.int32) self.assertEquals(num_unmatched_columns.dtype, tf.int32) self.assertEquals(num_ignored_columns.dtype, tf.int32) with self.test_session() as sess: (num_matched_columns_out, num_unmatched_columns_out, num_ignored_columns_out) \ = sess.run([num_matched_columns, num_unmatched_columns, num_ignored_columns]) self.assertAllEqual(num_matched_columns_out, exp_num_matched_columns) self.assertAllEqual(num_unmatched_columns_out, exp_num_unmatched_columns) self.assertAllEqual(num_ignored_columns_out, exp_num_ignored_columns)
def graph_fn(): match_results = tf.constant([3, 1, -1, 0, -1, 5, -2]) input_tensor = tf.constant([0, 1, 2, 3, 4, 5, 6, 7], dtype=tf.float32) match = matcher.Match(match_results) gathered_tensor = match.gather_based_on_match(input_tensor, unmatched_value=100., ignored_value=200.) return gathered_tensor
def graph_fn(): match_results = tf.random_uniform( [num_matches], minval=-2, maxval=5, dtype=tf.int32) match = matcher.Match(match_results) matched_column_indices = match.matched_column_indices() unmatched_column_indices = match.unmatched_column_indices() ignored_column_indices = match.ignored_column_indices() return (matched_column_indices, unmatched_column_indices, ignored_column_indices)
def graph_fn(): match_results = tf.constant([1, -1, -2]) input_tensor = tf.constant([[0, 0.5, 0, 0.5], [0, 0, 0.5, 0.5]], dtype=tf.float32) match = matcher.Match(match_results, use_matmul_gather=True) gathered_tensor = match.gather_based_on_match(input_tensor, unmatched_value=tf.zeros(4), ignored_value=tf.zeros(4)) return gathered_tensor
def test_get_correct_unmatched_column_indicator(self): match_results = tf.constant([3, 1, -1, 0, -1, 5, -2]) match = matcher.Match(match_results) expected_column_indicator = [False, False, True, False, True, False, False] unmatched_column_indicator = match.unmatched_column_indicator() self.assertEquals(unmatched_column_indicator.dtype, tf.bool) with self.test_session() as sess: unmatched_column_indicator = sess.run(unmatched_column_indicator) self.assertAllEqual(unmatched_column_indicator, expected_column_indicator)
def test_get_correct_ignored_column_indices(self): match_results = tf.constant([3, 1, -1, 0, -1, 5, -2]) match = matcher.Match(match_results) expected_column_indices = [6] ignored_column_indices = match.ignored_column_indices() self.assertEquals(ignored_column_indices.dtype, tf.int32) with self.test_session() as sess: ignored_column_indices = sess.run(ignored_column_indices) self.assertAllEqual(ignored_column_indices, expected_column_indices)
def testGetCorrectUnmatchedColumnIndices(self): match_results = tf.constant([3, 1, -1, 0, -1, 5, -2]) match = matcher.Match(match_results) expected_column_indices = [2, 4] unmatched_column_indices = match.unmatched_column_indices() self.assertEquals(unmatched_column_indices.dtype, tf.int32) with self.test_session() as sess: unmatched_column_indices = sess.run(unmatched_column_indices) self.assertAllEqual(unmatched_column_indices, expected_column_indices)
def graph_fn(): match_results = tf.constant([3, 1, -1, 0, -1, 1, -2]) match = matcher.Match(match_results) num_matched_columns = match.num_matched_columns() num_unmatched_columns = match.num_unmatched_columns() num_ignored_columns = match.num_ignored_columns() num_matched_rows = match.num_matched_rows() return [num_matched_columns, num_unmatched_columns, num_ignored_columns, num_matched_rows]
def testGetCorrectMatchedRowIndices(self): match_results = tf.constant([3, 1, -1, 0, -1, 5, -2]) match = matcher.Match(match_results) expected_row_indices = [3, 1, 0, 5] matched_row_indices = match.matched_row_indices() self.assertEquals(matched_row_indices.dtype, tf.int32) with self.test_session() as sess: matched_row_inds = sess.run(matched_row_indices) self.assertAllEqual(matched_row_inds, expected_row_indices)
def test_scalar_gather_based_on_match(self): match_results = tf.constant([3, 1, -1, 0, -1, 5, -2]) input_tensor = tf.constant([0, 1, 2, 3, 4, 5, 6, 7], dtype=tf.float32) expected_gathered_tensor = [3, 1, 100, 0, 100, 5, 200] match = matcher.Match(match_results) gathered_tensor = match.gather_based_on_match(input_tensor, unmatched_value=100., ignored_value=200.) self.assertEqual(gathered_tensor.dtype, tf.float32) with self.test_session(): gathered_tensor_out = gathered_tensor.eval() self.assertAllEqual(expected_gathered_tensor, gathered_tensor_out)
def test_get_correct_unmatched_ignored_column_indices(self): match_results = tf.constant([3, 1, -1, 0, -1, 5, -2]) match = matcher.Match(match_results) expected_column_indices = [2, 4, 6] unmatched_ignored_column_indices = ( match.unmatched_or_ignored_column_indices()) self.assertEqual(unmatched_ignored_column_indices.dtype, tf.int32) with self.test_session() as sess: unmatched_ignored_column_indices = sess.run( unmatched_ignored_column_indices) self.assertAllEqual(unmatched_ignored_column_indices, expected_column_indices)
def test_multidimensional_gather_based_on_match(self): match_results = tf.constant([1, -1, -2]) input_tensor = tf.constant([[0, 0.5, 0, 0.5], [0, 0, 0.5, 0.5]], dtype=tf.float32) expected_gathered_tensor = [[0, 0, 0.5, 0.5], [0, 0, 0, 0], [0, 0, 0, 0]] match = matcher.Match(match_results) gathered_tensor = match.gather_based_on_match(input_tensor, unmatched_value=tf.zeros(4), ignored_value=tf.zeros(4)) self.assertEquals(gathered_tensor.dtype, tf.float32) with self.test_session(): gathered_tensor_out = gathered_tensor.eval() self.assertAllEqual(expected_gathered_tensor, gathered_tensor_out)
def testEnforceNegativesPerPositiveRatioWithMinNegativesPerImage(self): location_losses = tf.constant([[100, 90, 80, 0, 1, 2, 3, 10, 20, 100, 20, 3]], tf.float32) cls_losses = tf.constant([[0, 0, 100, 0, 90, 70, 0, 60, 0, 17, 13, 0]], tf.float32) box_corners = tf.constant([[0.0, 0.0, 0.2, 0.1], [0.0, 0.0, 0.2, 0.1], [0.0, 0.0, 0.2, 0.1], [0.0, 0.0, 0.2, 0.1], [0.0, 0.0, 0.5, 0.1], [0.0, 0.0, 0.6, 0.1], [0.0, 0.0, 0.2, 0.1], [0.0, 0.0, 0.8, 0.1], [0.0, 0.0, 0.2, 0.1], [0.0, 0.0, 1.0, 0.1], [0.0, 0.0, 1.1, 0.1], [0.0, 0.0, 0.2, 0.1]], tf.float32) match_results = tf.constant([-1] * 12) match_list = [matcher.Match(match_results)] decoded_boxlist_list = [] decoded_boxlist_list.append(box_list.BoxList(box_corners)) min_negatives_per_image_list = [0, 1, 2, 4, 5, 6] exp_loc_loss_list = [0, 80, 80 + 1, 80 + 1 + 2 + 10, 80 + 1 + 2 + 10 + 100, 80 + 1 + 2 + 10 + 100 + 20] exp_cls_loss_list = [0, 100, 100 + 90, 100 + 90 + 70 + 60, 100 + 90 + 70 + 60 + 17, 100 + 90 + 70 + 60 + 17 + 13] for min_negatives_per_image, exp_loc_loss, exp_cls_loss in zip( min_negatives_per_image_list, exp_loc_loss_list, exp_cls_loss_list): loss_op = losses.HardExampleMiner( num_hard_examples=None, iou_threshold=0.9999, loss_type='cls', cls_loss_weight=1, loc_loss_weight=1, max_negatives_per_positive=3, min_negatives_per_image=min_negatives_per_image) (loc_loss, cls_loss) = loss_op(location_losses, cls_losses, decoded_boxlist_list, match_list) with self.test_session() as sess: loc_loss_output = sess.run(loc_loss) self.assertAllClose(loc_loss_output, exp_loc_loss) cls_loss_output = sess.run(cls_loss) self.assertAllClose(cls_loss_output, exp_cls_loss)
def test_multidimensional_gather_based_on_match_with_matmul_gather_op(self): match_results = tf.constant([1, -1, -2]) input_tensor = tf.constant([[0, 0.5, 0, 0.5], [0, 0, 0.5, 0.5]], dtype=tf.float32) expected_gathered_tensor = [[0, 0, 0.5, 0.5], [0, 0, 0, 0], [0, 0, 0, 0]] match = matcher.Match(match_results, use_matmul_gather=True) gathered_tensor = match.gather_based_on_match(input_tensor, unmatched_value=tf.zeros(4), ignored_value=tf.zeros(4)) self.assertEquals(gathered_tensor.dtype, tf.float32) with self.test_session() as sess: self.assertTrue( all([op.name is not 'Gather' for op in sess.graph.get_operations()])) gathered_tensor_out = gathered_tensor.eval() self.assertAllEqual(expected_gathered_tensor, gathered_tensor_out)
def test_get_correct_matched_columnIndices(self): print( '\n===============================================================' ) print('test_get_correct_matched_columnIndices') match_results = tf.constant([3, 1, -1, 0, -1, 5, -2]) match = matcher.Match(match_results) expected_column_indices = [0, 1, 3, 5] matched_column_indices = match.matched_column_indices() self.assertEquals(matched_column_indices.dtype, tf.int32) with self.test_session() as sess: matched_column_indices_out = sess.run(matched_column_indices) self.assertAllEqual(matched_column_indices_out, expected_column_indices)
def test_scalar_gather_based_on_match(self): print( '\n=============================================================') print('test_scalar_gather_based_on_match') input_tensor = tf.constant([7, 6, 5, 4, 3, 2, 1, 0], dtype=tf.float32) match_results = tf.constant([3, 1, -1, 0, -1, 5, -2]) expected_gathered_tensor = [4, 6, 100, 7, 100, 2, 200] match = matcher.Match(match_results) gathered_tensor = match.gather_based_on_match(input_tensor, unmatched_value=100., ignored_value=200.) self.assertEquals(gathered_tensor.dtype, tf.float32) with self.test_session(): gathered_tensor_out = gathered_tensor.eval() print('gathered_tensor_out: {}'.format(gathered_tensor_out)) self.assertAllEqual(expected_gathered_tensor, gathered_tensor_out)
def test_all_columns_accounted_for(self): # Note: deliberately setting to small number so not always # all possibilities appear (matched, unmatched, ignored) num_matches = 10 match_results = tf.random_uniform( [num_matches], minval=-2, maxval=5, dtype=tf.int32) match = matcher.Match(match_results) matched_column_indices = match.matched_column_indices() unmatched_column_indices = match.unmatched_column_indices() ignored_column_indices = match.ignored_column_indices() with self.test_session() as sess: matched, unmatched, ignored = sess.run([ matched_column_indices, unmatched_column_indices, ignored_column_indices ]) all_indices = np.hstack((matched, unmatched, ignored)) all_indices_sorted = np.sort(all_indices) self.assertAllEqual(all_indices_sorted, np.arange(num_matches, dtype=np.int32))
def batch_get_targets(batch_match, groundtruth_tensor_list, groundtruth_weights_list, unmatched_value, unmatched_weight): """Returns targets based on anchor-groundtruth box matching results. Args: batch_match: An int32 tensor of shape [batch, num_anchors] containing the result of target assignment returned by TargetAssigner.assign(..). groundtruth_tensor_list: A list of groundtruth tensors of shape [num_groundtruth, d_1, d_2, ..., d_k]. The tensors can be of any type. groundtruth_weights_list: A list of weights, one per groundtruth tensor, of shape [num_groundtruth]. unmatched_value: A tensor of shape [d_1, d_2, ..., d_k] of the same type as groundtruth tensor containing target value for anchors that remain unmatched. unmatched_weight: Scalar weight to assign to anchors that remain unmatched. Returns: targets: A tensor of shape [batch, num_anchors, d_1, d_2, ..., d_k] containing targets for anchors. weights: A float tensor of shape [batch, num_anchors] containing the weights to assign to each target. """ match_list = tf.unstack(batch_match) targets_list = [] weights_list = [] for match_tensor, groundtruth_tensor, groundtruth_weight in zip( match_list, groundtruth_tensor_list, groundtruth_weights_list): match_object = mat.Match(match_tensor) targets = match_object.gather_based_on_match( groundtruth_tensor, unmatched_value=unmatched_value, ignored_value=unmatched_value) targets_list.append(targets) weights = match_object.gather_based_on_match( groundtruth_weight, unmatched_value=unmatched_weight, ignored_value=tf.zeros_like(unmatched_weight)) weights_list.append(weights) return tf.stack(targets_list), tf.stack(weights_list)
def graph_fn(): match_results = tf.constant([3, 1, -1, 0, -1, 5, -2]) match = matcher.Match(match_results) matched_row_indices = match.matched_row_indices() return matched_row_indices
def graph_fn(): match_results = tf.constant([3, 1, -1, 0, -1, 5, -2]) match = matcher.Match(match_results) ignored_column_indices = match.ignored_column_indices() return ignored_column_indices
def graph_fn(): match_results = tf.constant([3, 1, -1, 0, -1, 5, -2]) match = matcher.Match(match_results) unmatched_ignored_column_indices = (match. unmatched_or_ignored_column_indices()) return unmatched_ignored_column_indices
def graph_fn(): match_results = tf.constant([3, 1, -1, 0, -1, 5, -2]) match = matcher.Match(match_results) unmatched_column_indicator = match.unmatched_column_indicator() return unmatched_column_indicator
def loss(self, prediction_dict, true_image_shapes, scope=None): """Computes scalar loss tensors with respect to provided groundtruth. Calling this function requires that groundtruth tensors have been provided via the provide_groundtruth function. Args: prediction_dict: a dictionary holding prediction tensors with 1) box_encodings: 3-D float tensor of shape [batch_size, num_anchors, box_code_dimension] containing predicted boxes. 2) class_predictions_with_background: 3-D float tensor of shape [batch_size, num_anchors, num_classes+1] containing class predictions (logits) for each of the anchors. Note that this tensor *includes* background class predictions. true_image_shapes: int32 tensor of shape [batch, 3] where each row is of the form [height, width, channels] indicating the shapes of true images in the resized images, as resized images can be padded with zeros. scope: Optional scope name. Returns: a dictionary mapping loss keys (`localization_loss` and `classification_loss`) to scalar tensors representing corresponding loss values. """ with tf.name_scope(scope, 'Loss', prediction_dict.values()): keypoints = None if self.groundtruth_has_field(fields.BoxListFields.keypoints): keypoints = self.groundtruth_lists( fields.BoxListFields.keypoints) weights = None if self.groundtruth_has_field(fields.BoxListFields.weights): weights = self.groundtruth_lists(fields.BoxListFields.weights) (batch_cls_targets, batch_cls_weights, batch_reg_targets, batch_reg_weights, batch_match) = self._assign_targets( self.groundtruth_lists(fields.BoxListFields.boxes), self.groundtruth_lists(fields.BoxListFields.classes), keypoints, weights) match_list = [ matcher.Match(match) for match in tf.unstack(batch_match) ] if self._add_summaries: self._summarize_target_assignment( self.groundtruth_lists(fields.BoxListFields.boxes), match_list) location_losses = self._localization_loss( prediction_dict['box_encodings'], batch_reg_targets, ignore_nan_targets=True, weights=batch_reg_weights) cls_losses = ops.reduce_sum_trailing_dimensions( self._classification_loss( prediction_dict['class_predictions_with_background'], batch_cls_targets, weights=batch_cls_weights), ndims=2) if self._hard_example_miner: (loc_loss_list, cls_loss_list) = self._apply_hard_mining( location_losses, cls_losses, prediction_dict, match_list) localization_loss = tf.reduce_sum(tf.stack(loc_loss_list)) classification_loss = tf.reduce_sum(tf.stack(cls_loss_list)) if self._add_summaries: self._hard_example_miner.summarize() else: if self._add_summaries: class_ids = tf.argmax(batch_cls_targets, axis=2) flattened_class_ids = tf.reshape(class_ids, [-1]) flattened_classification_losses = tf.reshape( cls_losses, [-1]) self._summarize_anchor_classification_loss( flattened_class_ids, flattened_classification_losses) localization_loss = tf.reduce_sum(location_losses) classification_loss = tf.reduce_sum(cls_losses) # Optionally normalize by number of positive matches normalizer = tf.constant(1.0, dtype=tf.float32) if self._normalize_loss_by_num_matches: normalizer = tf.maximum( tf.to_float(tf.reduce_sum(batch_reg_weights)), 1.0) with tf.name_scope('localization_loss'): localization_loss_normalizer = normalizer if self._normalize_loc_loss_by_codesize: localization_loss_normalizer *= self._box_coder.code_size localization_loss = ((self._localization_loss_weight / (localization_loss_normalizer)) * localization_loss) with tf.name_scope('classification_loss'): classification_loss = ( (self._classification_loss_weight / normalizer) * classification_loss) loss_dict = { 'localization_loss': localization_loss, 'classification_loss': classification_loss } return loss_dict