"git@developer.sourcefind.cn:OpenDAS/mmdetection3d.git" did not exist on "ac77413fe045093ce008a62b856eda3c6f75ff47"
Commit d31aba8a authored by Kaushik Shivakumar's avatar Kaushik Shivakumar
Browse files

using already pushed files

parent 245e9d16
...@@ -303,6 +303,7 @@ def iou(boxlist1, boxlist2, scope=None): ...@@ -303,6 +303,7 @@ def iou(boxlist1, boxlist2, scope=None):
tf.equal(intersections, 0.0), tf.equal(intersections, 0.0),
tf.zeros_like(intersections), tf.truediv(intersections, unions)) tf.zeros_like(intersections), tf.truediv(intersections, unions))
def l1(boxlist1, boxlist2, scope=None): def l1(boxlist1, boxlist2, scope=None):
"""Computes l1 loss (pairwise) between two boxlists. """Computes l1 loss (pairwise) between two boxlists.
...@@ -317,21 +318,20 @@ def l1(boxlist1, boxlist2, scope=None): ...@@ -317,21 +318,20 @@ def l1(boxlist1, boxlist2, scope=None):
with tf.name_scope(scope, 'PairwiseL1'): with tf.name_scope(scope, 'PairwiseL1'):
ycenter1, xcenter1, h1, w1 = boxlist1.get_center_coordinates_and_sizes() ycenter1, xcenter1, h1, w1 = boxlist1.get_center_coordinates_and_sizes()
ycenter2, xcenter2, h2, w2 = boxlist2.get_center_coordinates_and_sizes() ycenter2, xcenter2, h2, w2 = boxlist2.get_center_coordinates_and_sizes()
ycenters = tf.abs(tf.expand_dims(ycenter2, axis=0) - \ ycenters = tf.abs(tf.expand_dims(ycenter2, axis=0) - tf.expand_dims(
tf.expand_dims(tf.transpose(ycenter1), axis=1)) tf.transpose(ycenter1), axis=1))
xcenters = tf.abs(tf.expand_dims(xcenter2, axis=0) - \ xcenters = tf.abs(tf.expand_dims(xcenter2, axis=0) - tf.expand_dims(
tf.expand_dims(tf.transpose(xcenter1), axis=1)) tf.transpose(xcenter1), axis=1))
heights = tf.abs(tf.expand_dims(h2, axis=0) - \ heights = tf.abs(tf.expand_dims(h2, axis=0) - tf.expand_dims(
tf.expand_dims(tf.transpose(h1), axis=1)) tf.transpose(h1), axis=1))
widths = tf.abs(tf.expand_dims(w2, axis=0) - \ widths = tf.abs(tf.expand_dims(w2, axis=0) - tf.expand_dims(
tf.expand_dims(tf.transpose(w1), axis=1)) tf.transpose(w1), axis=1))
return ycenters + xcenters + heights + widths return ycenters + xcenters + heights + widths
def giou_loss(boxlist1, boxlist2, scope=None):
""" def giou(boxlist1, boxlist2, scope=None):
Computes generalized IOU loss between two boxlists pairwise, """Computes pairwise generalized IOU between two boxlists.
as described at giou.stanford.edu.
Args: Args:
boxlist1: BoxList holding N boxes boxlist1: BoxList holding N boxes
boxlist2: BoxList holding M boxes boxlist2: BoxList holding M boxes
...@@ -340,12 +340,13 @@ def giou_loss(boxlist1, boxlist2, scope=None): ...@@ -340,12 +340,13 @@ def giou_loss(boxlist1, boxlist2, scope=None):
Returns: Returns:
a tensor with shape [N, M] representing the pairwise GIoU loss. a tensor with shape [N, M] representing the pairwise GIoU loss.
""" """
with tf.name_scope(scope, "PairwiseGIoU"): with tf.name_scope(scope, 'PairwiseGIoU'):
N = boxlist1.num_boxes() n = boxlist1.num_boxes()
M = boxlist2.num_boxes() m = boxlist2.num_boxes()
boxes1 = tf.repeat(boxlist1.get(), repeats=M, axis=0) boxes1 = tf.repeat(boxlist1.get(), repeats=m, axis=0)
boxes2 = tf.tile(boxlist2.get(), multiples=[N, 1]) boxes2 = tf.tile(boxlist2.get(), multiples=[n, 1])
return tf.reshape(1.0 - ops.giou(boxes1, boxes2), [N, M]) return tf.reshape(ops.giou(boxes1, boxes2), [n, m])
def matched_iou(boxlist1, boxlist2, scope=None): def matched_iou(boxlist1, boxlist2, scope=None):
"""Compute intersection-over-union between corresponding boxes in boxlists. """Compute intersection-over-union between corresponding boxes in boxlists.
...@@ -367,6 +368,7 @@ def matched_iou(boxlist1, boxlist2, scope=None): ...@@ -367,6 +368,7 @@ def matched_iou(boxlist1, boxlist2, scope=None):
tf.equal(intersections, 0.0), tf.equal(intersections, 0.0),
tf.zeros_like(intersections), tf.truediv(intersections, unions)) tf.zeros_like(intersections), tf.truediv(intersections, unions))
def ioa(boxlist1, boxlist2, scope=None): def ioa(boxlist1, boxlist2, scope=None):
"""Computes pairwise intersection-over-area between box collections. """Computes pairwise intersection-over-area between box collections.
......
...@@ -217,6 +217,7 @@ class BoxListOpsTest(test_case.TestCase): ...@@ -217,6 +217,7 @@ class BoxListOpsTest(test_case.TestCase):
def test_iou(self): def test_iou(self):
def graph_fn(): def graph_fn():
corners1 = tf.constant([[4.0, 3.0, 7.0, 5.0], [5.0, 6.0, 10.0, 7.0]])
corners1 = tf.constant([[4.0, 3.0, 7.0, 5.0], [5.0, 6.0, 10.0, 7.0]]) corners1 = tf.constant([[4.0, 3.0, 7.0, 5.0], [5.0, 6.0, 10.0, 7.0]])
corners2 = tf.constant([[3.0, 4.0, 6.0, 8.0], [14.0, 14.0, 15.0, 15.0], corners2 = tf.constant([[3.0, 4.0, 6.0, 8.0], [14.0, 14.0, 15.0, 15.0],
[0.0, 0.0, 20.0, 20.0]]) [0.0, 0.0, 20.0, 20.0]])
...@@ -247,9 +248,9 @@ class BoxListOpsTest(test_case.TestCase): ...@@ -247,9 +248,9 @@ class BoxListOpsTest(test_case.TestCase):
corners2 = tf.constant([[5.0, 7.0, 7.0, 9.0], [5.0, 11.0, 7.0, 13.0]]) corners2 = tf.constant([[5.0, 7.0, 7.0, 9.0], [5.0, 11.0, 7.0, 13.0]])
boxes1 = box_list.BoxList(corners1) boxes1 = box_list.BoxList(corners1)
boxes2 = box_list.BoxList(corners2) boxes2 = box_list.BoxList(corners2)
giou = box_list_ops.giou_loss(boxes1, boxes2) giou = box_list_ops.giou(boxes1, boxes2)
return giou return giou
exp_output = [[0.0, 4.0 / 3.0]] exp_output = [[1.0, -1.0 / 3.0]]
giou_output = self.execute(graph_fn, []) giou_output = self.execute(graph_fn, [])
self.assertAllClose(giou_output, exp_output) self.assertAllClose(giou_output, exp_output)
......
...@@ -211,12 +211,11 @@ class WeightedIOULocalizationLoss(Loss): ...@@ -211,12 +211,11 @@ class WeightedIOULocalizationLoss(Loss):
return tf.reshape(weights, [-1]) * per_anchor_iou_loss return tf.reshape(weights, [-1]) * per_anchor_iou_loss
class WeightedGIOULocalizationLoss(Loss): class WeightedGIOULocalizationLoss(Loss):
"""IOU localization loss function. """GIOU localization loss function.
Sums the IOU for corresponding pairs of predicted/groundtruth boxes Sums the GIOU loss for corresponding pairs of predicted/groundtruth boxes
and for each pair assign a loss of 1 - IOU. We then compute a weighted and for each pair assign a loss of 1 - GIOU. We then compute a weighted
sum over all pairs which is returned as the total loss. sum over all pairs which is returned as the total loss.
""" """
......
...@@ -197,6 +197,7 @@ class WeightedIOULocalizationLossTest(test_case.TestCase): ...@@ -197,6 +197,7 @@ class WeightedIOULocalizationLossTest(test_case.TestCase):
loss_output = self.execute(graph_fn, []) loss_output = self.execute(graph_fn, [])
self.assertAllClose(loss_output, exp_loss) self.assertAllClose(loss_output, exp_loss)
class WeightedGIOULocalizationLossTest(test_case.TestCase): class WeightedGIOULocalizationLossTest(test_case.TestCase):
def testReturnsCorrectLoss(self): def testReturnsCorrectLoss(self):
......
...@@ -15,21 +15,16 @@ ...@@ -15,21 +15,16 @@
"""Hungarian bipartite matcher implementation.""" """Hungarian bipartite matcher implementation."""
import tensorflow.compat.v1 as tf
import numpy as np import numpy as np
from scipy.optimize import linear_sum_assignment
import tensorflow.compat.v1 as tf
from object_detection.core import matcher from object_detection.core import matcher
from scipy.optimize import linear_sum_assignment
class HungarianBipartiteMatcher(matcher.Matcher): class HungarianBipartiteMatcher(matcher.Matcher):
"""Wraps a Hungarian bipartite matcher into TensorFlow.""" """Wraps a Hungarian bipartite matcher into TensorFlow."""
def __init__(self):
"""Constructs a Matcher."""
super(HungarianBipartiteMatcher, self).__init__()
def _match(self, similarity_matrix, valid_rows): def _match(self, similarity_matrix, valid_rows):
"""Optimally bipartite matches a collection rows and columns. """Optimally bipartite matches a collection rows and columns.
......
# Copyright 2017 The TensorFlow Authors. All Rights Reserved. # Copyright 2020 The TensorFlow Authors. All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
...@@ -100,5 +100,6 @@ class HungarianBipartiteMatcherTest(test_case.TestCase): ...@@ -100,5 +100,6 @@ class HungarianBipartiteMatcherTest(test_case.TestCase):
self.assertAllEqual(match_results_out._match_results.numpy(), self.assertAllEqual(match_results_out._match_results.numpy(),
expected_match_results) expected_match_results)
if __name__ == '__main__': if __name__ == '__main__':
tf.test.main() tf.test.main()
...@@ -216,13 +216,13 @@ def pad_to_multiple(tensor, multiple): ...@@ -216,13 +216,13 @@ def pad_to_multiple(tensor, multiple):
height_pad = tf.zeros([ height_pad = tf.zeros([
batch_size, padded_tensor_height - tensor_height, tensor_width, batch_size, padded_tensor_height - tensor_height, tensor_width,
tensor_depth tensor_depth
]) ], dtype=tensor.dtype)
tensor = tf.concat([tensor, height_pad], 1) tensor = tf.concat([tensor, height_pad], 1)
if padded_tensor_width != tensor_width: if padded_tensor_width != tensor_width:
width_pad = tf.zeros([ width_pad = tf.zeros([
batch_size, padded_tensor_height, padded_tensor_width - tensor_width, batch_size, padded_tensor_height, padded_tensor_width - tensor_width,
tensor_depth tensor_depth
]) ], dtype=tensor.dtype)
tensor = tf.concat([tensor, width_pad], 2) tensor = tf.concat([tensor, width_pad], 2)
return tensor return tensor
...@@ -1135,10 +1135,11 @@ def decode_image(tensor_dict): ...@@ -1135,10 +1135,11 @@ def decode_image(tensor_dict):
tensor_dict[fields.InputDataFields.image].set_shape([None, None, 3]) tensor_dict[fields.InputDataFields.image].set_shape([None, None, 3])
return tensor_dict return tensor_dict
def giou(boxes1, boxes2): def giou(boxes1, boxes2):
""" """Computes generalized IOU between two tensors.
Computes generalized IOU between two tensors. Each box should be
represented as [ymin, xmin, ymax, xmax]. Each box should be represented as [ymin, xmin, ymax, xmax].
Args: Args:
boxes1: a tensor with shape [num_boxes, 4] boxes1: a tensor with shape [num_boxes, 4]
...@@ -1146,46 +1147,43 @@ def giou(boxes1, boxes2): ...@@ -1146,46 +1147,43 @@ def giou(boxes1, boxes2):
Returns: Returns:
a tensor of shape [num_boxes] containing GIoUs a tensor of shape [num_boxes] containing GIoUs
""" """
def two_boxes_giou(boxes): def _two_boxes_giou(boxes):
"""Compute giou between two boxes."""
boxes1, boxes2 = boxes boxes1, boxes2 = boxes
pred_ymin = tf.gather_nd(boxes1, [0]) pred_ymin, pred_xmin, pred_ymax, pred_xmax = tf.unstack(boxes1)
pred_xmin = tf.gather_nd(boxes1, [1]) gt_ymin, gt_xmin, gt_ymax, gt_xmax = tf.unstack(boxes2)
pred_ymax = tf.gather_nd(boxes1, [2])
pred_xmax = tf.gather_nd(boxes1, [3])
gt_ymin = tf.gather_nd(boxes2, [0])
gt_xmin = tf.gather_nd(boxes2, [1])
gt_ymax = tf.gather_nd(boxes2, [2])
gt_xmax = tf.gather_nd(boxes2, [3])
gt_area = (gt_ymax - gt_ymin) * (gt_xmax - gt_xmin) gt_area = (gt_ymax - gt_ymin) * (gt_xmax - gt_xmin)
pred_area = (pred_ymax - pred_ymin) * (pred_xmax - pred_xmin) pred_area = (pred_ymax - pred_ymin) * (pred_xmax - pred_xmin)
x1I = tf.maximum(pred_xmin, gt_xmin) x1_i = tf.maximum(pred_xmin, gt_xmin)
x2I = tf.minimum(pred_xmax, gt_xmax) x2_i = tf.minimum(pred_xmax, gt_xmax)
y1I = tf.maximum(pred_ymin, gt_ymin) y1_i = tf.maximum(pred_ymin, gt_ymin)
y2I = tf.minimum(pred_ymax, gt_ymax) y2_i = tf.minimum(pred_ymax, gt_ymax)
intersection_area = (y2I - y1I) * (x2I - x1I) if (y2I > y1I and intersection_area = tf.maximum(0.0, y2_i - y1_i) * tf.maximum(0.0,
x2I > x1I) else 0.0 x2_i - x1_i)
x1C = tf.minimum(pred_xmin, gt_xmin) x1_c = tf.minimum(pred_xmin, gt_xmin)
x2C = tf.maximum(pred_xmax, gt_xmax) x2_c = tf.maximum(pred_xmax, gt_xmax)
y1C = tf.minimum(pred_ymin, gt_ymin) y1_c = tf.minimum(pred_ymin, gt_ymin)
y2C = tf.maximum(pred_ymax, gt_ymax) y2_c = tf.maximum(pred_ymax, gt_ymax)
hull_area = (y2C - y1C) * (x2C - x1C) hull_area = (y2_c - y1_c) * (x2_c - x1_c)
union_area = gt_area + pred_area - intersection_area union_area = gt_area + pred_area - intersection_area
IoU = intersection_area/union_area if union_area != 0.0 else 1.0 iou = tf.where(
gIoU = IoU - (hull_area - union_area) / hull_area if hull_area != 0.0 else IoU tf.equal(union_area, 0.0), 0.0, intersection_area / union_area)
giou_ = iou - tf.where(hull_area > 0.0,
(hull_area - union_area) / hull_area, iou)
return giou_
return gIoU return shape_utils.static_or_dynamic_map_fn(_two_boxes_giou, [boxes1, boxes2])
return shape_utils.static_or_dynamic_map_fn(two_boxes_giou, [boxes1, boxes2])
def cy_cx_h_w_to_ymin_xmin_ymax_xmax(input_tensor): def center_to_corner_coordinate(input_tensor):
"""Converts input boxes from center to corner representation.""" """Converts input boxes from center to corner representation."""
reshaped_encodings = tf.reshape(input_tensor, [-1, 4]) reshaped_encodings = tf.reshape(input_tensor, [-1, 4])
ycenter = tf.gather(reshaped_encodings, [0], axis=1) ycenter = tf.gather(reshaped_encodings, [0], axis=1)
...@@ -1196,4 +1194,4 @@ def cy_cx_h_w_to_ymin_xmin_ymax_xmax(input_tensor): ...@@ -1196,4 +1194,4 @@ def cy_cx_h_w_to_ymin_xmin_ymax_xmax(input_tensor):
xmin = xcenter - w / 2. xmin = xcenter - w / 2.
ymax = ycenter + h / 2. ymax = ycenter + h / 2.
xmax = xcenter + w / 2. xmax = xcenter + w / 2.
return tf.squeeze(tf.stack([ymin, xmin, ymax, xmax], axis=1)) return tf.squeeze(tf.stack([ymin, xmin, ymax, xmax], axis=1))
\ No newline at end of file
...@@ -1630,20 +1630,95 @@ class TestGatherWithPaddingValues(test_case.TestCase): ...@@ -1630,20 +1630,95 @@ class TestGatherWithPaddingValues(test_case.TestCase):
self.assertAllClose(expected_gathered_tensor, gathered_tensor_np) self.assertAllClose(expected_gathered_tensor, gathered_tensor_np)
class TestGIoU(test_case.TestCase): class TestGIoU(test_case.TestCase):
def test_giou(self): def test_giou_with_no_overlap(self):
expected_giou_tensor = [
0, -1/3, -3/4, 0, -98/100
]
def graph_fn():
boxes1 = tf.constant([[3, 4, 5, 6], [3, 3, 5, 5],
[0, 0, 0, 0], [3, 3, 5, 5],
[9, 9, 10, 10]],
dtype=tf.float32)
boxes2 = tf.constant([[3, 2, 5, 4], [3, 7, 5, 9],
[5, 5, 10, 10], [3, 5, 5, 7],
[0, 0, 1, 1]], dtype=tf.float32)
giou = ops.giou(boxes1, boxes2)
self.assertEqual(giou.dtype, tf.float32)
return giou
giou = self.execute(graph_fn, [])
self.assertAllClose(expected_giou_tensor, giou)
def test_giou_with_overlaps(self):
expected_giou_tensor = [ expected_giou_tensor = [
1, 0, -1/3, 1/25, 1, -3/4 1/25, 1/4, 1/3, 1/7 - 2/9
] ]
def graph_fn(): def graph_fn():
boxes1 = tf.constant([[3, 3, 5, 5], [3, 4, 5, 6], boxes1 = tf.constant([[2, 1, 7, 6], [2, 2, 4, 4],
[3, 3, 5, 5], [2, 1, 7, 6], [2, 2, 4, 4], [2, 2, 4, 4]],
[1, 1, 1, 1], [0, 0, 0, 0]], dtype=tf.float32) dtype=tf.float32)
boxes2 = tf.constant([[3, 3, 5, 5], [3, 2, 5, 4], boxes2 = tf.constant([[4, 3, 5, 4], [3, 3, 4, 4],
[3, 7, 5, 9], [4, 3, 5, 4], [2, 3, 4, 5], [3, 3, 5, 5]], dtype=tf.float32)
[1, 1, 1, 1], [5, 5, 10, 10]], dtype=tf.float32)
giou = ops.giou(boxes1, boxes2)
self.assertEqual(giou.dtype, tf.float32)
return giou
giou = self.execute(graph_fn, [])
self.assertAllClose(expected_giou_tensor, giou)
def test_giou_with_perfect_overlap(self):
expected_giou_tensor = [1]
def graph_fn():
boxes1 = tf.constant([[3, 3, 5, 5]], dtype=tf.float32)
boxes2 = tf.constant([[3, 3, 5, 5]], dtype=tf.float32)
giou = ops.giou(boxes1, boxes2)
self.assertEqual(giou.dtype, tf.float32)
return giou
giou = self.execute(graph_fn, [])
self.assertAllClose(expected_giou_tensor, giou)
def test_giou_with_zero_area_boxes(self):
expected_giou_tensor = [0]
def graph_fn():
boxes1 = tf.constant([[1, 1, 1, 1]], dtype=tf.float32)
boxes2 = tf.constant([[1, 1, 1, 1]], dtype=tf.float32)
giou = ops.giou(boxes1, boxes2)
self.assertEqual(giou.dtype, tf.float32)
return giou
giou = self.execute(graph_fn, [])
self.assertAllClose(expected_giou_tensor, giou)
def test_giou_different_with_l1_same(self):
expected_giou_tensor = [
2/3, 3/5
]
def graph_fn():
boxes1 = tf.constant([[3, 3, 5, 5], [3, 3, 5, 5]], dtype=tf.float32)
boxes2 = tf.constant([[3, 2.5, 5, 5.5], [3, 2.5, 5, 4.5]],
dtype=tf.float32)
giou = ops.giou(boxes1, boxes2) giou = ops.giou(boxes1, boxes2)
self.assertEqual(giou.dtype, tf.float32) self.assertEqual(giou.dtype, tf.float32)
...@@ -1658,13 +1733,14 @@ class TestCoordinateConversion(test_case.TestCase): ...@@ -1658,13 +1733,14 @@ class TestCoordinateConversion(test_case.TestCase):
def test_coord_conv(self): def test_coord_conv(self):
expected_box_tensor = [ expected_box_tensor = [
[0.5, 0.5, 5.5, 5.5], [2, 1, 4, 7] [0.5, 0.5, 5.5, 5.5], [2, 1, 4, 7], [0, 0, 0, 0]
] ]
def graph_fn(): def graph_fn():
boxes = tf.constant([[3, 3, 5, 5], [3, 4, 2, 6]], dtype=tf.float32) boxes = tf.constant([[3, 3, 5, 5], [3, 4, 2, 6], [0, 0, 0, 0]],
dtype=tf.float32)
converted = ops.cy_cx_h_w_to_ymin_xmin_ymax_xmax(boxes) converted = ops.center_to_corner_coordinate(boxes)
self.assertEqual(converted.dtype, tf.float32) self.assertEqual(converted.dtype, tf.float32)
return converted return converted
...@@ -1673,6 +1749,5 @@ class TestCoordinateConversion(test_case.TestCase): ...@@ -1673,6 +1749,5 @@ class TestCoordinateConversion(test_case.TestCase):
self.assertAllClose(expected_box_tensor, converted) self.assertAllClose(expected_box_tensor, converted)
if __name__ == '__main__': if __name__ == '__main__':
tf.test.main() tf.test.main()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment