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
Adding tf.image.non_max_suppression_with_overlaps #16543
Adding tf.image.non_max_suppression_with_overlaps #16543
Conversation
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed, please reply here (e.g.
|
signed cla |
CLAs look good, thanks! |
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.
Looks fine to me overall. Adding jch1 to double check from a object detection perspective.
Please:
-
Double check the performance now that we're jumping through a double indirection for
suppress_check_fn
? -
Since the op doesn't replace the existing NonMaxSuppression, let's use a different name so it's more apparent it can be used concurrently:
NonMaxSuppressionWithOverlaps
? -
Add or adapt the NonMaxV2 tests.
The latest commit changes the name and adds the missing unit tests. |
Thanks. I'm not aware of any existing benchmark. If you run through with a reasonable number of boxes (50000-100000?) before and after that would be sufficient. I just want to double check it's not a major performance change for existing code. |
I use the following script to measure the average runtime with > 1000000 boxes: import tensorflow as tf
import numpy as np
import timeit
def create_boxgrid():
coord_linspace = np.linspace(start=0.0, stop=1.0, num=600)
x_grid, y_grid = np.meshgrid(coord_linspace, coord_linspace)
box_centers = np.stack((x_grid, y_grid), axis=2).reshape((-1,2))
def create_boxes(width, height):
xmin = box_centers[:, 0] - width/2
xmax = box_centers[:, 0] + width/2
ymin = box_centers[:, 1] - height/2
ymax = box_centers[:, 1] + height/2
return np.stack((ymin, xmin, ymax, xmax), axis=1)
return np.concatenate((create_boxes(0.2, 0.2), create_boxes(0.5, 0.3), create_boxes(0.3, 0.5)))
if __name__ == '__main__':
boxes = create_boxgrid()
num_boxes = len(boxes)
scores = np.ones(shape=(num_boxes,), dtype=np.float32)
print('Number of boxes: {:d}'.format(num_boxes))
keep_idx = tf.image.non_max_suppression(boxes, scores, num_boxes)
with tf.Session() as sess:
def run():
return sess.run(keep_idx)
# warmup
print('Warming up...')
for _ in range(1000):
np_keep_idx = run()
num_runs = 100000
print('Measuring time for {:d} runs...'.format(num_runs))
elapsed_time = timeit.timeit(run, number=num_runs)
avg_time = elapsed_time / num_runs
print('Elapsed time: {:f} seconds'.format(elapsed_time))
print('Average time: {:f} seconds'.format(avg_time))
print('Keep {:d} boxes'.format(len(np_keep_idx))) Version in master:
New version:
Looks like the performance is pretty much the same! |
(From API review: We'd be interested in @jch1 s opinion as well) |
Thanks for running the tests! Looks good to me pending feedback from @jch1 . |
Sorry for the delay. Everything looks good from here. |
Here is the API failure. Note that you have to run the following on a python 2 environment.
|
Thanks, I've added the changes to the API golden files (I hope that's how it is supposed to be done). |
The change looks correct to me. |
Approval for API review. |
Thank you very much for the API review. |
Thanks for the approval! |
PiperOrigin-RevId: 204026736
This commit introduces the op
tf.image.non_max_suppression_overlaps
.It allows to perform non-max-suppression with an overlap criterion different to IOU by providing an n-by-n matrix with precomputed overlap values for each box pair.
In this way it is possible to use a custom overlap criterion for NMS (eg. intersection-over-area) without implementing a specialized op.
There are currently no unit tests. If you are willing to integrate this pull request, I will copy and rewrite the existing unit tests for
NonMaxSuppressionV2
.