Skip to content
This repository has been archived by the owner on Oct 31, 2023. It is now read-only.

agnostic-regression for bbox #390

Merged
merged 21 commits into from
Feb 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f93b369
make pixel indexes 0-based for bounding box in pascal voc dataset
zimenglan-sysu-512 Nov 25, 2018
45e4ba8
Merge remote-tracking branch 'upstream/master'
zimenglan-sysu-512 Nov 29, 2018
86caae2
Merge remote-tracking branch 'upstream/master'
zimenglan-sysu-512 Dec 5, 2018
a46bfb9
replacing all instances of torch.distributed.deprecated with torch.di…
zimenglan-sysu-512 Dec 5, 2018
7bbf46f
replacing all instances of torch.distributed.deprecated with torch.di…
zimenglan-sysu-512 Dec 5, 2018
7c8cf41
Merge remote-tracking branch 'upstream/master'
zimenglan-sysu-512 Dec 6, 2018
07a0f9c
Merge remote-tracking branch 'upstream/master'
zimenglan-sysu-512 Dec 26, 2018
6f09a6f
Merge remote-tracking branch 'upstream/master'
zimenglan-sysu-512 Jan 11, 2019
c4e3245
Merge remote-tracking branch 'upstream/master'
zimenglan-sysu-512 Jan 15, 2019
baba31f
add GroupNorm
zimenglan-sysu-512 Jan 15, 2019
4877e36
add GroupNorm -- sort out yaml files
zimenglan-sysu-512 Jan 16, 2019
d4ae039
use torch.nn.GroupNorm instead, replace 'use_gn' with 'conv_block' an…
zimenglan-sysu-512 Jan 18, 2019
333864d
modification on 'group_norm' and 'conv_with_kaiming_uniform' function
zimenglan-sysu-512 Jan 18, 2019
58da4d5
modification on yaml files in configs/gn_baselines/ and reduce the am…
zimenglan-sysu-512 Jan 21, 2019
1798e63
Merge remote-tracking branch 'upstream/master'
zimenglan-sysu-512 Jan 21, 2019
ecc68c4
Merge remote-tracking branch 'upstream/master'
zimenglan-sysu-512 Jan 22, 2019
02a86f3
Merge remote-tracking branch 'upstream/master'
zimenglan-sysu-512 Jan 23, 2019
9808a21
use 'kaiming_uniform' to initialize resnet, disable gn after fc layer…
zimenglan-sysu-512 Jan 23, 2019
d1ce06e
Merge remote-tracking branch 'upstream/master'
zimenglan-sysu-512 Jan 28, 2019
4de3488
agnostic-regression for bbox
zimenglan-sysu-512 Jan 28, 2019
52be8d7
Merge remote-tracking branch 'upstream/master'
zimenglan-sysu-512 Feb 1, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions maskrcnn_benchmark/config/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
_C.MODEL.MASK_ON = False
_C.MODEL.DEVICE = "cuda"
_C.MODEL.META_ARCHITECTURE = "GeneralizedRCNN"
_C.MODEL.CLS_AGNOSTIC_BBOX_REG = False

# If the WEIGHT starts with a catalog://, like :R-50, the code will look for
# the path in paths_catalog. Else, it will use it as the specified absolute
Expand Down
19 changes: 17 additions & 2 deletions maskrcnn_benchmark/modeling/roi_heads/box_head/inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ class PostProcessor(nn.Module):
"""

def __init__(
self, score_thresh=0.05, nms=0.5, detections_per_img=100, box_coder=None
self,
score_thresh=0.05,
nms=0.5,
detections_per_img=100,
box_coder=None,
cls_agnostic_bbox_reg=False
):
"""
Arguments:
Expand All @@ -33,6 +38,7 @@ def __init__(
if box_coder is None:
box_coder = BoxCoder(weights=(10., 10., 5., 5.))
self.box_coder = box_coder
self.cls_agnostic_bbox_reg = cls_agnostic_bbox_reg

def forward(self, x, boxes):
"""
Expand All @@ -54,9 +60,13 @@ def forward(self, x, boxes):
boxes_per_image = [len(box) for box in boxes]
concat_boxes = torch.cat([a.bbox for a in boxes], dim=0)

if self.cls_agnostic_bbox_reg:
box_regression = box_regression[:, -4:]
proposals = self.box_coder.decode(
box_regression.view(sum(boxes_per_image), -1), concat_boxes
)
if self.cls_agnostic_bbox_reg:
proposals = proposals.repeat(1, class_prob.shape[1])

num_classes = class_prob.shape[1]

Expand Down Expand Up @@ -145,8 +155,13 @@ def make_roi_box_post_processor(cfg):
score_thresh = cfg.MODEL.ROI_HEADS.SCORE_THRESH
nms_thresh = cfg.MODEL.ROI_HEADS.NMS
detections_per_img = cfg.MODEL.ROI_HEADS.DETECTIONS_PER_IMG
cls_agnostic_bbox_reg = cfg.MODEL.CLS_AGNOSTIC_BBOX_REG

postprocessor = PostProcessor(
score_thresh, nms_thresh, detections_per_img, box_coder
score_thresh,
nms_thresh,
detections_per_img,
box_coder,
cls_agnostic_bbox_reg
)
return postprocessor
24 changes: 21 additions & 3 deletions maskrcnn_benchmark/modeling/roi_heads/box_head/loss.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ class FastRCNNLossComputation(object):
Also supports FPN
"""

def __init__(self, proposal_matcher, fg_bg_sampler, box_coder):
def __init__(
self,
proposal_matcher,
fg_bg_sampler,
box_coder,
cls_agnostic_bbox_reg=False
):
"""
Arguments:
proposal_matcher (Matcher)
Expand All @@ -28,6 +34,7 @@ def __init__(self, proposal_matcher, fg_bg_sampler, box_coder):
self.proposal_matcher = proposal_matcher
self.fg_bg_sampler = fg_bg_sampler
self.box_coder = box_coder
self.cls_agnostic_bbox_reg = cls_agnostic_bbox_reg

def match_targets_to_proposals(self, proposal, target):
match_quality_matrix = boxlist_iou(target, proposal)
Expand Down Expand Up @@ -143,7 +150,11 @@ def __call__(self, class_logits, box_regression):
# advanced indexing
sampled_pos_inds_subset = torch.nonzero(labels > 0).squeeze(1)
labels_pos = labels[sampled_pos_inds_subset]
map_inds = 4 * labels_pos[:, None] + torch.tensor([0, 1, 2, 3], device=device)
if self.cls_agnostic_bbox_reg:
map_inds = torch.tensor([4, 5, 6, 7], device=device)
else:
map_inds = 4 * labels_pos[:, None] + torch.tensor(
[0, 1, 2, 3], device=device)

box_loss = smooth_l1_loss(
box_regression[sampled_pos_inds_subset[:, None], map_inds],
Expand All @@ -170,6 +181,13 @@ def make_roi_box_loss_evaluator(cfg):
cfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE, cfg.MODEL.ROI_HEADS.POSITIVE_FRACTION
)

loss_evaluator = FastRCNNLossComputation(matcher, fg_bg_sampler, box_coder)
cls_agnostic_bbox_reg = cfg.MODEL.CLS_AGNOSTIC_BBOX_REG

loss_evaluator = FastRCNNLossComputation(
matcher,
fg_bg_sampler,
box_coder,
cls_agnostic_bbox_reg
)

return loss_evaluator
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ def __init__(self, config, pretrained=None):
num_classes = config.MODEL.ROI_BOX_HEAD.NUM_CLASSES
self.avgpool = nn.AvgPool2d(kernel_size=7, stride=7)
self.cls_score = nn.Linear(num_inputs, num_classes)
self.bbox_pred = nn.Linear(num_inputs, num_classes * 4)
num_bbox_reg_classes = 2 if cfg.MODEL.CLS_AGNOSTIC_BBOX_REG else num_classes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is how Detectron implements it: by using 0 for background and 1 for the other classes.

But I'm starting to wonder if this is actually necessary here: given that we index out all negative examples via sampled_pos_inds_subset, we don't backprop through the background elements anyway.
Given that, I think we could have only num_bbox_reg_classes = 1, and the rest of the code should work as well.

@rbgirshick what do you think? Am I missing something here?

self.bbox_pred = nn.Linear(num_inputs, num_bbox_reg_classes * 4)

nn.init.normal_(self.cls_score.weight, mean=0, std=0.01)
nn.init.constant_(self.cls_score.bias, 0)
Expand All @@ -37,7 +38,8 @@ def __init__(self, cfg):
representation_size = cfg.MODEL.ROI_BOX_HEAD.MLP_HEAD_DIM

self.cls_score = nn.Linear(representation_size, num_classes)
self.bbox_pred = nn.Linear(representation_size, num_classes * 4)
num_bbox_reg_classes = 2 if cfg.MODEL.CLS_AGNOSTIC_BBOX_REG else num_classes
self.bbox_pred = nn.Linear(representation_size, num_bbox_reg_classes * 4)

nn.init.normal_(self.cls_score.weight, std=0.01)
nn.init.normal_(self.bbox_pred.weight, std=0.001)
Expand Down