"src/git@developer.sourcefind.cn:one/TransferBench.git" did not exist on "f33c7fd968b8968674bb4ef07575b7075d60a5f1"
Unverified Commit 8ebfd2f5 authored by Vasilis Vryniotis's avatar Vasilis Vryniotis Committed by GitHub
Browse files

Improve speed/accuracy of FasterRCNN by introducing a score threshold on RPN (#3205)



* Introduce small score threshold on rpn

* Adding docs and fixing keypoint and mask.

* Making value 0.0 by default for BC.

* Fixing for onnx.

* Update threshold.

* Removing non-default threshold from reference scripts.
Co-authored-by: default avatarFrancisco Massa <fvsmassa@gmail.com>
parent d0063f3d
...@@ -92,8 +92,11 @@ def main(args): ...@@ -92,8 +92,11 @@ def main(args):
collate_fn=utils.collate_fn) collate_fn=utils.collate_fn)
print("Creating model") print("Creating model")
model = torchvision.models.detection.__dict__[args.model](num_classes=num_classes, kwargs = {}
pretrained=args.pretrained) if "rcnn" in args.model:
kwargs["rpn_score_thresh"] = 0.0
model = torchvision.models.detection.__dict__[args.model](num_classes=num_classes, pretrained=args.pretrained,
**kwargs)
model.to(device) model.to(device)
model_without_ddp = model model_without_ddp = model
......
...@@ -44,7 +44,7 @@ class Tester(unittest.TestCase): ...@@ -44,7 +44,7 @@ class Tester(unittest.TestCase):
rpn_anchor_generator, rpn_head, rpn_anchor_generator, rpn_head,
0.5, 0.3, 0.5, 0.3,
256, 0.5, 256, 0.5,
2000, 2000, 0.7) 2000, 2000, 0.7, 0.05)
labels, matched_gt_boxes = head.assign_targets_to_anchors(anchors, targets) labels, matched_gt_boxes = head.assign_targets_to_anchors(anchors, targets)
......
from common_utils import set_rng_seed
import io import io
import torch import torch
from torchvision import ops from torchvision import ops
...@@ -197,12 +198,14 @@ class ONNXExporterTester(unittest.TestCase): ...@@ -197,12 +198,14 @@ class ONNXExporterTester(unittest.TestCase):
rpn_pre_nms_top_n = dict(training=2000, testing=1000) rpn_pre_nms_top_n = dict(training=2000, testing=1000)
rpn_post_nms_top_n = dict(training=2000, testing=1000) rpn_post_nms_top_n = dict(training=2000, testing=1000)
rpn_nms_thresh = 0.7 rpn_nms_thresh = 0.7
rpn_score_thresh = 0.0
rpn = RegionProposalNetwork( rpn = RegionProposalNetwork(
rpn_anchor_generator, rpn_head, rpn_anchor_generator, rpn_head,
rpn_fg_iou_thresh, rpn_bg_iou_thresh, rpn_fg_iou_thresh, rpn_bg_iou_thresh,
rpn_batch_size_per_image, rpn_positive_fraction, rpn_batch_size_per_image, rpn_positive_fraction,
rpn_pre_nms_top_n, rpn_post_nms_top_n, rpn_nms_thresh) rpn_pre_nms_top_n, rpn_post_nms_top_n, rpn_nms_thresh,
score_thresh=rpn_score_thresh)
return rpn return rpn
def _init_test_roi_heads_faster_rcnn(self): def _init_test_roi_heads_faster_rcnn(self):
...@@ -255,6 +258,8 @@ class ONNXExporterTester(unittest.TestCase): ...@@ -255,6 +258,8 @@ class ONNXExporterTester(unittest.TestCase):
return features return features
def test_rpn(self): def test_rpn(self):
set_rng_seed(0)
class RPNModule(torch.nn.Module): class RPNModule(torch.nn.Module):
def __init__(self_module): def __init__(self_module):
super(RPNModule, self_module).__init__() super(RPNModule, self_module).__init__()
......
...@@ -173,10 +173,14 @@ class BoxCoder(object): ...@@ -173,10 +173,14 @@ class BoxCoder(object):
box_sum = 0 box_sum = 0
for val in boxes_per_image: for val in boxes_per_image:
box_sum += val box_sum += val
if box_sum > 0:
rel_codes = rel_codes.reshape(box_sum, -1)
pred_boxes = self.decode_single( pred_boxes = self.decode_single(
rel_codes.reshape(box_sum, -1), concat_boxes rel_codes, concat_boxes
) )
return pred_boxes.reshape(box_sum, -1, 4) if box_sum > 0:
pred_boxes = pred_boxes.reshape(box_sum, -1, 4)
return pred_boxes
def decode_single(self, rel_codes, boxes): def decode_single(self, rel_codes, boxes):
""" """
......
...@@ -79,6 +79,8 @@ class FasterRCNN(GeneralizedRCNN): ...@@ -79,6 +79,8 @@ class FasterRCNN(GeneralizedRCNN):
for computing the loss for computing the loss
rpn_positive_fraction (float): proportion of positive anchors in a mini-batch during training rpn_positive_fraction (float): proportion of positive anchors in a mini-batch during training
of the RPN of the RPN
rpn_score_thresh (float): during inference, only return proposals with a classification score
greater than rpn_score_thresh
box_roi_pool (MultiScaleRoIAlign): the module which crops and resizes the feature maps in box_roi_pool (MultiScaleRoIAlign): the module which crops and resizes the feature maps in
the locations indicated by the bounding boxes the locations indicated by the bounding boxes
box_head (nn.Module): module that takes the cropped feature maps as input box_head (nn.Module): module that takes the cropped feature maps as input
...@@ -153,6 +155,7 @@ class FasterRCNN(GeneralizedRCNN): ...@@ -153,6 +155,7 @@ class FasterRCNN(GeneralizedRCNN):
rpn_nms_thresh=0.7, rpn_nms_thresh=0.7,
rpn_fg_iou_thresh=0.7, rpn_bg_iou_thresh=0.3, rpn_fg_iou_thresh=0.7, rpn_bg_iou_thresh=0.3,
rpn_batch_size_per_image=256, rpn_positive_fraction=0.5, rpn_batch_size_per_image=256, rpn_positive_fraction=0.5,
rpn_score_thresh=0.0,
# Box parameters # Box parameters
box_roi_pool=None, box_head=None, box_predictor=None, box_roi_pool=None, box_head=None, box_predictor=None,
box_score_thresh=0.05, box_nms_thresh=0.5, box_detections_per_img=100, box_score_thresh=0.05, box_nms_thresh=0.5, box_detections_per_img=100,
...@@ -197,7 +200,8 @@ class FasterRCNN(GeneralizedRCNN): ...@@ -197,7 +200,8 @@ class FasterRCNN(GeneralizedRCNN):
rpn_anchor_generator, rpn_head, rpn_anchor_generator, rpn_head,
rpn_fg_iou_thresh, rpn_bg_iou_thresh, rpn_fg_iou_thresh, rpn_bg_iou_thresh,
rpn_batch_size_per_image, rpn_positive_fraction, rpn_batch_size_per_image, rpn_positive_fraction,
rpn_pre_nms_top_n, rpn_post_nms_top_n, rpn_nms_thresh) rpn_pre_nms_top_n, rpn_post_nms_top_n, rpn_nms_thresh,
score_thresh=rpn_score_thresh)
if box_roi_pool is None: if box_roi_pool is None:
box_roi_pool = MultiScaleRoIAlign( box_roi_pool = MultiScaleRoIAlign(
......
...@@ -74,6 +74,8 @@ class KeypointRCNN(FasterRCNN): ...@@ -74,6 +74,8 @@ class KeypointRCNN(FasterRCNN):
for computing the loss for computing the loss
rpn_positive_fraction (float): proportion of positive anchors in a mini-batch during training rpn_positive_fraction (float): proportion of positive anchors in a mini-batch during training
of the RPN of the RPN
rpn_score_thresh (float): during inference, only return proposals with a classification score
greater than rpn_score_thresh
box_roi_pool (MultiScaleRoIAlign): the module which crops and resizes the feature maps in box_roi_pool (MultiScaleRoIAlign): the module which crops and resizes the feature maps in
the locations indicated by the bounding boxes the locations indicated by the bounding boxes
box_head (nn.Module): module that takes the cropped feature maps as input box_head (nn.Module): module that takes the cropped feature maps as input
...@@ -158,6 +160,7 @@ class KeypointRCNN(FasterRCNN): ...@@ -158,6 +160,7 @@ class KeypointRCNN(FasterRCNN):
rpn_nms_thresh=0.7, rpn_nms_thresh=0.7,
rpn_fg_iou_thresh=0.7, rpn_bg_iou_thresh=0.3, rpn_fg_iou_thresh=0.7, rpn_bg_iou_thresh=0.3,
rpn_batch_size_per_image=256, rpn_positive_fraction=0.5, rpn_batch_size_per_image=256, rpn_positive_fraction=0.5,
rpn_score_thresh=0.0,
# Box parameters # Box parameters
box_roi_pool=None, box_head=None, box_predictor=None, box_roi_pool=None, box_head=None, box_predictor=None,
box_score_thresh=0.05, box_nms_thresh=0.5, box_detections_per_img=100, box_score_thresh=0.05, box_nms_thresh=0.5, box_detections_per_img=100,
...@@ -204,6 +207,7 @@ class KeypointRCNN(FasterRCNN): ...@@ -204,6 +207,7 @@ class KeypointRCNN(FasterRCNN):
rpn_nms_thresh, rpn_nms_thresh,
rpn_fg_iou_thresh, rpn_bg_iou_thresh, rpn_fg_iou_thresh, rpn_bg_iou_thresh,
rpn_batch_size_per_image, rpn_positive_fraction, rpn_batch_size_per_image, rpn_positive_fraction,
rpn_score_thresh,
# Box parameters # Box parameters
box_roi_pool, box_head, box_predictor, box_roi_pool, box_head, box_predictor,
box_score_thresh, box_nms_thresh, box_detections_per_img, box_score_thresh, box_nms_thresh, box_detections_per_img,
......
...@@ -75,6 +75,8 @@ class MaskRCNN(FasterRCNN): ...@@ -75,6 +75,8 @@ class MaskRCNN(FasterRCNN):
for computing the loss for computing the loss
rpn_positive_fraction (float): proportion of positive anchors in a mini-batch during training rpn_positive_fraction (float): proportion of positive anchors in a mini-batch during training
of the RPN of the RPN
rpn_score_thresh (float): during inference, only return proposals with a classification score
greater than rpn_score_thresh
box_roi_pool (MultiScaleRoIAlign): the module which crops and resizes the feature maps in box_roi_pool (MultiScaleRoIAlign): the module which crops and resizes the feature maps in
the locations indicated by the bounding boxes the locations indicated by the bounding boxes
box_head (nn.Module): module that takes the cropped feature maps as input box_head (nn.Module): module that takes the cropped feature maps as input
...@@ -158,6 +160,7 @@ class MaskRCNN(FasterRCNN): ...@@ -158,6 +160,7 @@ class MaskRCNN(FasterRCNN):
rpn_nms_thresh=0.7, rpn_nms_thresh=0.7,
rpn_fg_iou_thresh=0.7, rpn_bg_iou_thresh=0.3, rpn_fg_iou_thresh=0.7, rpn_bg_iou_thresh=0.3,
rpn_batch_size_per_image=256, rpn_positive_fraction=0.5, rpn_batch_size_per_image=256, rpn_positive_fraction=0.5,
rpn_score_thresh=0.0,
# Box parameters # Box parameters
box_roi_pool=None, box_head=None, box_predictor=None, box_roi_pool=None, box_head=None, box_predictor=None,
box_score_thresh=0.05, box_nms_thresh=0.5, box_detections_per_img=100, box_score_thresh=0.05, box_nms_thresh=0.5, box_detections_per_img=100,
...@@ -204,6 +207,7 @@ class MaskRCNN(FasterRCNN): ...@@ -204,6 +207,7 @@ class MaskRCNN(FasterRCNN):
rpn_nms_thresh, rpn_nms_thresh,
rpn_fg_iou_thresh, rpn_bg_iou_thresh, rpn_fg_iou_thresh, rpn_bg_iou_thresh,
rpn_batch_size_per_image, rpn_positive_fraction, rpn_batch_size_per_image, rpn_positive_fraction,
rpn_score_thresh,
# Box parameters # Box parameters
box_roi_pool, box_head, box_predictor, box_roi_pool, box_head, box_predictor,
box_score_thresh, box_nms_thresh, box_detections_per_img, box_score_thresh, box_nms_thresh, box_detections_per_img,
......
...@@ -141,7 +141,7 @@ class RegionProposalNetwork(torch.nn.Module): ...@@ -141,7 +141,7 @@ class RegionProposalNetwork(torch.nn.Module):
fg_iou_thresh, bg_iou_thresh, fg_iou_thresh, bg_iou_thresh,
batch_size_per_image, positive_fraction, batch_size_per_image, positive_fraction,
# #
pre_nms_top_n, post_nms_top_n, nms_thresh): pre_nms_top_n, post_nms_top_n, nms_thresh, score_thresh=0.0):
super(RegionProposalNetwork, self).__init__() super(RegionProposalNetwork, self).__init__()
self.anchor_generator = anchor_generator self.anchor_generator = anchor_generator
self.head = head self.head = head
...@@ -163,6 +163,7 @@ class RegionProposalNetwork(torch.nn.Module): ...@@ -163,6 +163,7 @@ class RegionProposalNetwork(torch.nn.Module):
self._pre_nms_top_n = pre_nms_top_n self._pre_nms_top_n = pre_nms_top_n
self._post_nms_top_n = post_nms_top_n self._post_nms_top_n = post_nms_top_n
self.nms_thresh = nms_thresh self.nms_thresh = nms_thresh
self.score_thresh = score_thresh
self.min_size = 1e-3 self.min_size = 1e-3
def pre_nms_top_n(self): def pre_nms_top_n(self):
...@@ -251,17 +252,29 @@ class RegionProposalNetwork(torch.nn.Module): ...@@ -251,17 +252,29 @@ class RegionProposalNetwork(torch.nn.Module):
levels = levels[batch_idx, top_n_idx] levels = levels[batch_idx, top_n_idx]
proposals = proposals[batch_idx, top_n_idx] proposals = proposals[batch_idx, top_n_idx]
objectness_prob = F.sigmoid(objectness)
final_boxes = [] final_boxes = []
final_scores = [] final_scores = []
for boxes, scores, lvl, img_shape in zip(proposals, objectness, levels, image_shapes): for boxes, scores, lvl, img_shape in zip(proposals, objectness_prob, levels, image_shapes):
boxes = box_ops.clip_boxes_to_image(boxes, img_shape) boxes = box_ops.clip_boxes_to_image(boxes, img_shape)
# remove small boxes
keep = box_ops.remove_small_boxes(boxes, self.min_size) keep = box_ops.remove_small_boxes(boxes, self.min_size)
boxes, scores, lvl = boxes[keep], scores[keep], lvl[keep] boxes, scores, lvl = boxes[keep], scores[keep], lvl[keep]
# remove low scoring boxes
# use >= for Backwards compatibility
keep = torch.where(scores >= self.score_thresh)[0]
boxes, scores, lvl = boxes[keep], scores[keep], lvl[keep]
# non-maximum suppression, independently done per level # non-maximum suppression, independently done per level
keep = box_ops.batched_nms(boxes, scores, lvl, self.nms_thresh) keep = box_ops.batched_nms(boxes, scores, lvl, self.nms_thresh)
# keep only topk scoring predictions # keep only topk scoring predictions
keep = keep[:self.post_nms_top_n()] keep = keep[:self.post_nms_top_n()]
boxes, scores = boxes[keep], scores[keep] boxes, scores = boxes[keep], scores[keep]
final_boxes.append(boxes) final_boxes.append(boxes)
final_scores.append(scores) final_scores.append(scores)
return final_boxes, final_scores return final_boxes, final_scores
......
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