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
99ba595d
You need to sign in or sign up before continuing.
Commit
99ba595d
authored
Aug 22, 2018
by
Yuxin Wu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[MaskRCNN] use FastRCNNHead to manage head inputs&outputs
parent
02eb02e2
Changes
2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
131 additions
and
87 deletions
+131
-87
examples/FasterRCNN/model_frcnn.py
examples/FasterRCNN/model_frcnn.py
+102
-10
examples/FasterRCNN/train.py
examples/FasterRCNN/train.py
+29
-77
No files found.
examples/FasterRCNN/model_frcnn.py
View file @
99ba595d
...
...
@@ -8,9 +8,11 @@ from tensorpack.tfutils.argscope import argscope
from
tensorpack.tfutils.scope_utils
import
under_name_scope
from
tensorpack.models
import
(
Conv2D
,
FullyConnected
,
layer_register
)
from
tensorpack.utils.argtools
import
memoized
from
basemodel
import
GroupNorm
from
utils.box_ops
import
pairwise_iou
from
model_box
import
encode_bbox_target
,
decode_bbox_target
from
config
import
config
as
cfg
...
...
@@ -113,7 +115,7 @@ def fastrcnn_outputs(feature, num_classes):
box_regression
=
FullyConnected
(
'box'
,
feature
,
num_classes
*
4
,
kernel_initializer
=
tf
.
random_normal_initializer
(
stddev
=
0.001
))
box_regression
=
tf
.
reshape
(
box_regression
,
(
-
1
,
num_classes
,
4
))
box_regression
=
tf
.
reshape
(
box_regression
,
(
-
1
,
num_classes
,
4
)
,
name
=
'output_box'
)
return
classification
,
box_regression
...
...
@@ -125,6 +127,9 @@ def fastrcnn_losses(labels, label_logits, fg_boxes, fg_box_logits):
label_logits: nxC
fg_boxes: nfgx4, encoded
fg_box_logits: nfgxCx4
Returns:
label_loss, box_loss
"""
label_loss
=
tf
.
nn
.
sparse_softmax_cross_entropy_with_logits
(
labels
=
labels
,
logits
=
label_logits
)
...
...
@@ -132,10 +137,9 @@ def fastrcnn_losses(labels, label_logits, fg_boxes, fg_box_logits):
fg_inds
=
tf
.
where
(
labels
>
0
)[:,
0
]
fg_labels
=
tf
.
gather
(
labels
,
fg_inds
)
num_fg
=
tf
.
size
(
fg_inds
)
num_fg
=
tf
.
size
(
fg_inds
,
out_type
=
tf
.
int64
)
indices
=
tf
.
stack
(
[
tf
.
range
(
num_fg
),
tf
.
to_int32
(
fg_labels
)],
axis
=
1
)
# #fgx2
[
tf
.
range
(
num_fg
),
fg_labels
],
axis
=
1
)
# #fgx2
fg_box_logits
=
tf
.
gather_nd
(
fg_box_logits
,
indices
)
with
tf
.
name_scope
(
'label_metrics'
),
tf
.
device
(
'/cpu:0'
):
...
...
@@ -143,7 +147,7 @@ def fastrcnn_losses(labels, label_logits, fg_boxes, fg_box_logits):
correct
=
tf
.
to_float
(
tf
.
equal
(
prediction
,
labels
))
# boolean/integer gather is unavailable on GPU
accuracy
=
tf
.
reduce_mean
(
correct
,
name
=
'accuracy'
)
fg_label_pred
=
tf
.
argmax
(
tf
.
gather
(
label_logits
,
fg_inds
),
axis
=
1
)
num_zero
=
tf
.
reduce_sum
(
tf
.
to_int
32
(
tf
.
equal
(
fg_label_pred
,
0
)),
name
=
'num_zero'
)
num_zero
=
tf
.
reduce_sum
(
tf
.
to_int
64
(
tf
.
equal
(
fg_label_pred
,
0
)),
name
=
'num_zero'
)
false_negative
=
tf
.
truediv
(
num_zero
,
num_fg
,
name
=
'false_negative'
)
fg_accuracy
=
tf
.
reduce_mean
(
tf
.
gather
(
correct
,
fg_inds
),
name
=
'fg_accuracy'
)
...
...
@@ -163,12 +167,17 @@ def fastrcnn_predictions(boxes, probs):
Generate final results from predictions of all proposals.
Args:
boxes: n#c
at
x4 floatbox in float32
boxes: n#c
lass
x4 floatbox in float32
probs: nx#class
Returns:
indices: Kx2. Each is (box_id, class_id)
probs: K floats
"""
assert
boxes
.
shape
[
1
]
==
cfg
.
DATA
.
NUM_C
ATEGORY
assert
boxes
.
shape
[
1
]
==
cfg
.
DATA
.
NUM_C
LASS
assert
probs
.
shape
[
1
]
==
cfg
.
DATA
.
NUM_CLASS
boxes
=
tf
.
transpose
(
boxes
,
[
1
,
0
,
2
])
# #catxnx4
boxes
=
tf
.
transpose
(
boxes
,
[
1
,
0
,
2
])[
1
:,
:,
:]
# #catxnx4
boxes
.
set_shape
([
None
,
cfg
.
DATA
.
NUM_CATEGORY
,
None
])
probs
=
tf
.
transpose
(
probs
[:,
1
:],
[
1
,
0
])
# #catxn
def
f
(
X
):
...
...
@@ -209,8 +218,9 @@ def fastrcnn_predictions(boxes, probs):
tf
.
minimum
(
cfg
.
TEST
.
RESULTS_PER_IM
,
tf
.
size
(
probs
)),
sorted
=
False
)
filtered_selection
=
tf
.
gather
(
selected_indices
,
topk_indices
)
filtered_selection
=
tf
.
reverse
(
filtered_selection
,
axis
=
[
1
],
name
=
'filtered_indices'
)
return
filtered_selection
,
topk_probs
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
"""
...
...
@@ -267,3 +277,85 @@ def fastrcnn_4conv1fc_head(*args, **kwargs):
def
fastrcnn_4conv1fc_gn_head
(
*
args
,
**
kwargs
):
return
fastrcnn_Xconv1fc_head
(
*
args
,
num_convs
=
4
,
norm
=
'GN'
,
**
kwargs
)
class
FastRCNNHead
(
object
):
"""
A class to process & decode inputs/outputs of a fastrcnn classification+regression head.
"""
def
__init__
(
self
,
input_boxes
,
box_logits
,
label_logits
,
bbox_regression_weights
,
labels
=
None
,
matched_gt_boxes_per_fg
=
None
):
"""
Args:
input_boxes: Nx4, inputs to the head
box_logits: Nx#classx4, the output of the head
label_logits: Nx#class, the output of the head
bbox_regression_weights: a 4 element tensor
labels: N, each in [0, #class-1], the true label for each input box
matched_gt_boxes_per_fg: #fgx4, the matching gt boxes for each fg input box
The last two arguments could be None when not training.
"""
for
k
,
v
in
locals
()
.
items
():
if
k
!=
'self'
:
setattr
(
self
,
k
,
v
)
@
memoized
def
fg_inds_in_inputs
(
self
):
""" Returns: #fg indices in [0, N-1] """
return
tf
.
reshape
(
tf
.
where
(
self
.
labels
>
0
),
[
-
1
],
name
=
'fg_inds_in_inputs'
)
@
memoized
def
fg_input_boxes
(
self
):
""" Returns: #fgx4 """
return
tf
.
gather
(
self
.
input_boxes
,
self
.
fg_inds_in_inputs
(),
name
=
'fg_input_boxes'
)
@
memoized
def
fg_box_logits
(
self
):
""" Returns: #fg x #class x 4 """
return
tf
.
gather
(
self
.
box_logits
,
self
.
fg_inds_in_inputs
(),
name
=
'fg_box_logits'
)
@
memoized
def
fg_labels
(
self
):
""" Returns: #fg """
return
tf
.
gather
(
self
.
labels
,
self
.
fg_inds_in_inputs
(),
name
=
'fg_labels'
)
@
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
return
fastrcnn_losses
(
self
.
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
),
[
1
,
cfg
.
DATA
.
NUM_CLASS
,
1
])
# N x #class x 4
decoded_boxes
=
decode_bbox_target
(
self
.
box_logits
/
self
.
bbox_regression_weights
,
anchors
)
return
decoded_boxes
@
memoized
def
decoded_output_boxes_for_true_label
(
self
):
""" Returns: Nx4 decoded boxes """
indices
=
tf
.
stack
([
tf
.
range
(
tf
.
size
(
self
.
labels
,
out_type
=
tf
.
int64
)),
self
.
labels
])
needed_logits
=
tf
.
gather_nd
(
self
.
box_logits
,
indices
)
decoded
=
decode_bbox_target
(
needed_logits
/
self
.
bbox_regression_weights
,
self
.
input_boxes
)
return
decoded
@
memoized
def
output_scores
(
self
,
name
=
None
):
""" Returns: N x #class scores, summed to one for each box."""
return
tf
.
nn
.
softmax
(
self
.
label_logits
,
name
=
name
)
examples/FasterRCNN/train.py
View file @
99ba595d
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