-
Notifications
You must be signed in to change notification settings - Fork 45.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Identity box coder, similarity calculator, target assigner #8962
Identity box coder, similarity calculator, target assigner #8962
Conversation
tf.expand_dims(tf.transpose(w1), axis=1)) | ||
return ycenters + xcenters + heights + widths | ||
|
||
def giou_loss(boxlist1, boxlist2, scope=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is already available at https://www.tensorflow.org/addons/api_docs/python/tfa/losses/GIoULoss
If you need any extension please open a PR in TFA. /cc @tensorflow/sig-addons-maintainers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tombstone told me to implement this separately so we wouldn't need that dependency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok thanks.
@tombstone Our check it is just part of the approved RFC at https://github.com/tensorflow/community/blame/master/rfcs/20190802-model-garden-redesign.md#L60-L61
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another GIOU Is landing from #9083
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @kmindspark
@@ -31,11 +31,11 @@ | |||
from object_detection.core import box_list_ops | |||
from object_detection.core import standard_fields as fields | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Internal lint required two lines.
EPSILON = 1e-8 | ||
|
||
|
||
class DETRBoxCoder(box_coder.BoxCoder): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed offline, it might be best to follow CenterNet's pattern here to create a single class that does the target assignment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @kmindspark. I left some comments. PTAL
@@ -35,7 +35,8 @@ | |||
class RegionSimilarityCalculator(six.with_metaclass(ABCMeta, object)): | |||
"""Abstract base class for region similarity calculator.""" | |||
|
|||
def compare(self, boxlist1, boxlist2, scope=None): | |||
def compare(self, boxlist1, boxlist2, scope=None, | |||
groundtruth_labels=None, predicted_labels=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
groundtruth_labels and predicted_labels can be fields inside boxlist. We don't need to add additional arguments to the interface.
""" | ||
classification_scores = tf.matmul(groundtruth_labels, | ||
tf.nn.softmax(predicted_labels), transpose_b=True) | ||
return -5 * box_list_ops.l1(boxlist1, boxlist2) + 2 * box_list_ops.giou( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add the scale factors 5 and 2 as constructor arguments. Also are these values mentioned in the paper ?
""" | ||
classification_scores = tf.matmul(groundtruth_labels, | ||
tf.nn.softmax(predicted_labels), transpose_b=True) | ||
return -5 * box_list_ops.l1(boxlist1, boxlist2) + 2 * box_list_ops.giou( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't the second term be -2 * box_list_ops.giou(..) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is + because this is calculating similarity, and box list ops giou is not doing 1-giou
"""Target assigner to compute classification and regression targets.""" | ||
|
||
def __init__(self, | ||
similarity_calc, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's hardcode this class to use DETRSimilarityCalc
self._negative_class_weight = negative_class_weight | ||
|
||
def assign(self, | ||
anchors, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we have anchors here ? Do you mean predicted boxes ?
anchors, | ||
groundtruth_boxes, | ||
groundtruth_labels=None, | ||
unmatched_class_label=None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need unmatched_class_label for DETR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is that? Should I hard code it to [1] + [0]*num_classes inside target assigner?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needed to keep compatible with batch_assign_targets so decided to leave this in, is that ok?
representing weights for each element in cls_targets. | ||
reg_targets: a float32 tensor with shape [num_anchors, box_code_dimension] | ||
reg_weights: a float32 tensor with shape [num_anchors] | ||
match: an int32 tensor of shape [num_anchors] containing result of anchor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to return match object. Let's simplify.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case it would be difficult to use the existing batch_assign_targets right? Which would be nice to use.
0)) | ||
groundtruth_labels = tf.expand_dims(groundtruth_labels, -1) | ||
|
||
unmatched_shape_assert = shape_utils.assert_shape_equal( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove shape asserts.
|
||
def __init__(self, | ||
similarity_calc, | ||
matcher, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hardcode to use hungarian matcher.
cls_weights = tf.tile(cls_weights, weights_multiple) | ||
|
||
num_anchors = anchors.num_boxes_static() | ||
if num_anchors is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you rename anchors throughout to be predicted_boxes
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @kmindspark
@@ -107,7 +108,8 @@ def assign(self, | |||
groundtruth_boxes, | |||
groundtruth_labels=None, | |||
unmatched_class_label=None, | |||
groundtruth_weights=None): | |||
groundtruth_weights=None, | |||
class_predictions=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need this change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do because in batch_assign it by default now passes in class predictions.
@@ -434,6 +436,9 @@ def create_target_assigner(reference, stage=None, | |||
use_matmul_gather=use_matmul_gather) | |||
box_coder_instance = faster_rcnn_box_coder.FasterRcnnBoxCoder() | |||
|
|||
elif reference == 'DETR': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't need to add it here. In DETR meta architecture you can directly create DETRTargetAssigner()
@@ -1897,3 +1911,197 @@ def assign_corner_offset_targets( | |||
|
|||
return (tf.stack(corner_targets, axis=0), | |||
tf.stack(foreground_targets, axis=0)) | |||
|
|||
class DETRTargetAssigner(object): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am still a bit worried that we are carrying around a lot of legacy code for the DETR Target Assigner. Can you take a look at https://github.com/facebookresearch/detr/blob/master/models/matcher.py and see if we can do something similiar ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That file just does the matching. Do you mean the fact that we do similarity calculation separately from the target assigner?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @kmindspark . This is looking good.
groundtruth_boxes, | ||
box_preds) | ||
match = self._matcher.match(match_quality_matrix, | ||
valid_rows=tf.greater(groundtruth_weights, 0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question - where do we ensure that the number of predicted boxes and number of padded groundtruth boxes is equal ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the default number of boxes to pad to in the config (max_number_of_boxes) is 100. I could explicitly set this in the config. I can also add an assert to confirm.
groundtruth_boxes, | ||
box_preds) | ||
match = self._matcher.match(match_quality_matrix, | ||
valid_rows=tf.greater(groundtruth_weights, 0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In practice does DETR use zeros to represent null groundtruths ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's how the data loading works I believe (giving 0 weights to padded boxes), if that's not the case let me know 👍
@@ -0,0 +1,118 @@ | |||
# Faster R-CNN with Resnet-50 (v1) with 640x640 input resolution |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this config from the PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops not sure how this snuck in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @kmindspark
Description
Type of change
For a new feature or function, please create an issue first to discuss it
with us before submitting a pull request.
Note: Please delete options that are not relevant.
Tests
Test Configuration:
Checklist