Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
seminar-breakout
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Shashank Suhas
seminar-breakout
Commits
6041a1a4
Commit
6041a1a4
authored
Aug 25, 2018
by
Yuxin Wu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[MaskRCNN] BoxProposals struct to manage proposals; rename probs->scores
parent
cf97218c
Changes
3
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
122 additions
and
116 deletions
+122
-116
examples/FasterRCNN/README.md
examples/FasterRCNN/README.md
+1
-1
examples/FasterRCNN/model_frcnn.py
examples/FasterRCNN/model_frcnn.py
+78
-50
examples/FasterRCNN/train.py
examples/FasterRCNN/train.py
+43
-65
No files found.
examples/FasterRCNN/README.md
View file @
6041a1a4
...
...
@@ -59,7 +59,7 @@ To predict on an image (and show output in a window):
./train.py --predict input.jpg --load /path/to/model --config SAME-AS-TRAINING
```
To
E
valuate the performance of a model on COCO:
To
e
valuate the performance of a model on COCO:
```
./train.py --evaluate output.json --load /path/to/COCO-R50C4-MaskRCNN-Standard.npz \
--config SAME-AS-TRAINING
...
...
examples/FasterRCNN/model_frcnn.py
View file @
6041a1a4
...
...
@@ -50,8 +50,9 @@ def sample_fast_rcnn_targets(boxes, gt_boxes, gt_labels):
gt_labels: m, int32
Returns:
A BoxProposals instance.
sampled_boxes: tx4 floatbox, the rois
sampled_labels: t int64 labels, in [0, #class
-1]
. Positive means foreground.
sampled_labels: t int64 labels, in [0, #class
)
. Positive means foreground.
fg_inds_wrt_gt: #fg indices, each in range [0, m-1].
It contains the matching GT of each foreground roi.
"""
...
...
@@ -94,9 +95,11 @@ def sample_fast_rcnn_targets(boxes, gt_boxes, gt_labels):
[
tf
.
gather
(
gt_labels
,
fg_inds_wrt_gt
),
tf
.
zeros_like
(
bg_inds
,
dtype
=
tf
.
int64
)],
axis
=
0
)
# stop the gradient -- they are meant to be training targets
return
tf
.
stop_gradient
(
ret_boxes
,
name
=
'sampled_proposal_boxes'
),
\
tf
.
stop_gradient
(
ret_labels
,
name
=
'sampled_labels'
),
\
tf
.
stop_gradient
(
fg_inds_wrt_gt
)
return
BoxProposals
(
tf
.
stop_gradient
(
ret_boxes
,
name
=
'sampled_proposal_boxes'
),
tf
.
stop_gradient
(
ret_labels
,
name
=
'sampled_labels'
),
tf
.
stop_gradient
(
fg_inds_wrt_gt
),
gt_boxes
,
gt_labels
)
@
layer_register
(
log_shape
=
True
)
...
...
@@ -168,23 +171,24 @@ def fastrcnn_losses(labels, label_logits, fg_boxes, fg_box_logits):
@
under_name_scope
()
def
fastrcnn_predictions
(
boxes
,
prob
s
):
def
fastrcnn_predictions
(
boxes
,
score
s
):
"""
Generate final results from predictions of all proposals.
Args:
boxes: n#classx4 floatbox in float32
prob
s: nx#class
score
s: nx#class
Returns:
indices: Kx2. Each is (box_id, class_id)
probs: K floats
boxes: Kx4
scores: K
labels: K
"""
assert
boxes
.
shape
[
1
]
==
cfg
.
DATA
.
NUM_CLASS
assert
prob
s
.
shape
[
1
]
==
cfg
.
DATA
.
NUM_CLASS
assert
score
s
.
shape
[
1
]
==
cfg
.
DATA
.
NUM_CLASS
boxes
=
tf
.
transpose
(
boxes
,
[
1
,
0
,
2
])[
1
:,
:,
:]
# #catxnx4
boxes
.
set_shape
([
None
,
cfg
.
DATA
.
NUM_CATEGORY
,
None
])
probs
=
tf
.
transpose
(
prob
s
[:,
1
:],
[
1
,
0
])
# #catxn
scores
=
tf
.
transpose
(
score
s
[:,
1
:],
[
1
,
0
])
# #catxn
def
f
(
X
):
"""
...
...
@@ -213,20 +217,24 @@ def fastrcnn_predictions(boxes, probs):
default_value
=
False
)
return
mask
masks
=
tf
.
map_fn
(
f
,
(
prob
s
,
boxes
),
dtype
=
tf
.
bool
,
masks
=
tf
.
map_fn
(
f
,
(
score
s
,
boxes
),
dtype
=
tf
.
bool
,
parallel_iterations
=
10
)
# #cat x N
selected_indices
=
tf
.
where
(
masks
)
# #selection x 2, each is (cat_id, box_id)
probs
=
tf
.
boolean_mask
(
prob
s
,
masks
)
scores
=
tf
.
boolean_mask
(
score
s
,
masks
)
# filter again by sorting scores
topk_
prob
s
,
topk_indices
=
tf
.
nn
.
top_k
(
prob
s
,
tf
.
minimum
(
cfg
.
TEST
.
RESULTS_PER_IM
,
tf
.
size
(
prob
s
)),
topk_
score
s
,
topk_indices
=
tf
.
nn
.
top_k
(
score
s
,
tf
.
minimum
(
cfg
.
TEST
.
RESULTS_PER_IM
,
tf
.
size
(
score
s
)),
sorted
=
False
)
filtered_selection
=
tf
.
gather
(
selected_indices
,
topk_indices
)
cat_ids
,
box_ids
=
tf
.
unstack
(
filtered_selection
,
axis
=
1
)
final_ids
=
tf
.
stack
([
box_ids
,
cat_ids
+
1
],
axis
=
1
,
name
=
'final_ids'
)
# Kx2, each is (box_id, class_id)
return
final_ids
,
topk_probs
final_scores
=
tf
.
identity
(
topk_scores
,
name
=
'scores'
)
final_labels
=
tf
.
add
(
cat_ids
,
1
,
name
=
'labels'
)
final_ids
=
tf
.
stack
([
cat_ids
,
box_ids
],
axis
=
1
,
name
=
'all_ids'
)
final_boxes
=
tf
.
gather_nd
(
boxes
,
final_ids
,
name
=
'boxes'
)
return
final_boxes
,
final_scores
,
final_labels
"""
...
...
@@ -284,63 +292,84 @@ def fastrcnn_4conv1fc_gn_head(*args, **kwargs):
return
fastrcnn_Xconv1fc_head
(
*
args
,
num_convs
=
4
,
norm
=
'GN'
,
**
kwargs
)
class
FastRCNNHead
(
object
):
class
BoxProposals
(
object
):
"""
A
class to process & decode inputs/outputs of a fastrcnn classification+regression head
.
A
structure to manage box proposals and their relation with ground truth
.
"""
def
__init__
(
self
,
input_boxes
,
box_logits
,
label_logits
,
bbox_regression_weights
,
labels
=
None
,
matched_gt_boxes_per_fg
=
None
):
def
__init__
(
self
,
boxes
,
labels
=
None
,
fg_inds_wrt_gt
=
None
,
gt_boxes
=
None
,
gt_labels
=
None
):
"""
Args:
input_boxes: Nx4, inputs to the head
box_logits: Nx#classx4 or Nx1x4, the output of the head
label_logits: Nx#class, the output of the head
bbox_regression_weights: a 4 element tensor
boxes: Nx4
labels: N, each in [0, #class), the true label for each input box
matched_gt_boxes_per_fg: #fgx4, the matching gt boxes for each fg input box
fg_inds_wrt_gt: #fg, each in [0, M)
gt_boxes: Mx4
gt_labels: M
The last
two
arguments could be None when not training.
The last
four
arguments could be None when not training.
"""
for
k
,
v
in
locals
()
.
items
():
if
k
!=
'self'
:
if
k
!=
'self'
and
v
is
not
None
:
setattr
(
self
,
k
,
v
)
self
.
_bbox_class_agnostic
=
int
(
box_logits
.
shape
[
1
])
==
1
@
memoized
def
fg_inds
_in_inputs
(
self
):
def
fg_inds
(
self
):
""" Returns: #fg indices in [0, N-1] """
assert
self
.
labels
is
not
None
return
tf
.
reshape
(
tf
.
where
(
self
.
labels
>
0
),
[
-
1
],
name
=
'fg_inds_in_inputs'
)
return
tf
.
reshape
(
tf
.
where
(
self
.
labels
>
0
),
[
-
1
],
name
=
'fg_inds'
)
@
memoized
def
fg_
input_
boxes
(
self
):
""" Returns: #fg
x4
"""
return
tf
.
gather
(
self
.
input_boxes
,
self
.
fg_inds_in_inputs
(),
name
=
'fg_input
_boxes'
)
def
fg_boxes
(
self
):
""" Returns: #fg
x4
"""
return
tf
.
gather
(
self
.
boxes
,
self
.
fg_inds
(),
name
=
'fg
_boxes'
)
@
memoized
def
fg_
box_logit
s
(
self
):
""" Returns: #fg
x ? x 4
"""
return
tf
.
gather
(
self
.
box_logits
,
self
.
fg_inds_in_inputs
(),
name
=
'fg_box_logit
s'
)
def
fg_
label
s
(
self
):
""" Returns: #fg"""
return
tf
.
gather
(
self
.
labels
,
self
.
fg_inds
(),
name
=
'fg_label
s'
)
@
memoized
def
fg_labels
(
self
):
""" Returns: #fg """
return
tf
.
gather
(
self
.
labels
,
self
.
fg_inds_in_inputs
(),
name
=
'fg_labels'
)
def
matched_gt_boxes
(
self
):
""" Returns: #fg x 4"""
return
tf
.
gather
(
self
.
gt_boxes
,
self
.
fg_inds_wrt_gt
)
class
FastRCNNHead
(
object
):
"""
A class to process & decode inputs/outputs of a fastrcnn classification+regression head.
"""
def
__init__
(
self
,
proposals
,
box_logits
,
label_logits
,
bbox_regression_weights
):
"""
Args:
proposals: BoxProposals
box_logits: Nx#classx4 or Nx1x4, the output of the head
label_logits: Nx#class, the output of the head
bbox_regression_weights: a 4 element tensor
"""
for
k
,
v
in
locals
()
.
items
():
if
k
!=
'self'
and
v
is
not
None
:
setattr
(
self
,
k
,
v
)
self
.
_bbox_class_agnostic
=
int
(
box_logits
.
shape
[
1
])
==
1
@
memoized
def
fg_box_logits
(
self
):
""" Returns: #fg x ? x 4 """
return
tf
.
gather
(
self
.
box_logits
,
self
.
proposals
.
fg_inds
(),
name
=
'fg_box_logits'
)
@
memoized
def
losses
(
self
):
encoded_fg_gt_boxes
=
encode_bbox_target
(
self
.
matched_gt_boxes_per_fg
,
self
.
fg_input
_boxes
())
*
self
.
bbox_regression_weights
self
.
proposals
.
matched_gt_boxes
()
,
self
.
proposals
.
fg
_boxes
())
*
self
.
bbox_regression_weights
return
fastrcnn_losses
(
self
.
labels
,
self
.
label_logits
,
self
.
proposals
.
labels
,
self
.
label_logits
,
encoded_fg_gt_boxes
,
self
.
fg_box_logits
()
)
@
memoized
def
decoded_output_boxes
(
self
):
""" Returns: N x #class x 4 """
anchors
=
tf
.
tile
(
tf
.
expand_dims
(
self
.
input_
boxes
,
1
),
anchors
=
tf
.
tile
(
tf
.
expand_dims
(
self
.
proposals
.
boxes
,
1
),
[
1
,
cfg
.
DATA
.
NUM_CLASS
,
1
])
# N x #class x 4
decoded_boxes
=
decode_bbox_target
(
self
.
box_logits
/
self
.
bbox_regression_weights
,
...
...
@@ -351,8 +380,7 @@ class FastRCNNHead(object):
@
memoized
def
decoded_output_boxes_for_true_label
(
self
):
""" Returns: Nx4 decoded boxes """
assert
self
.
labels
is
not
None
return
self
.
_decoded_output_boxes_for_label
(
self
.
labels
)
return
self
.
_decoded_output_boxes_for_label
(
self
.
proposals
.
labels
)
@
memoized
def
decoded_output_boxes_for_predicted_label
(
self
):
...
...
@@ -363,13 +391,13 @@ class FastRCNNHead(object):
def
decoded_output_boxes_for_label
(
self
,
labels
):
assert
not
self
.
_bbox_class_agnostic
indices
=
tf
.
stack
([
tf
.
range
(
tf
.
size
(
self
.
labels
,
out_type
=
tf
.
int64
)),
tf
.
range
(
tf
.
size
(
labels
,
out_type
=
tf
.
int64
)),
labels
])
needed_logits
=
tf
.
gather_nd
(
self
.
box_logits
,
indices
)
decoded
=
decode_bbox_target
(
needed_logits
/
self
.
bbox_regression_weights
,
self
.
input_
boxes
self
.
proposals
.
boxes
)
return
decoded
...
...
@@ -379,7 +407,7 @@ class FastRCNNHead(object):
box_logits
=
tf
.
reshape
(
self
.
box_logits
,
[
-
1
,
4
])
decoded
=
decode_bbox_target
(
box_logits
/
self
.
bbox_regression_weights
,
self
.
input_
boxes
self
.
proposals
.
boxes
)
return
decoded
...
...
examples/FasterRCNN/train.py
View file @
6041a1a4
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment