Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ModelZoo
SOLOv2-pytorch
Commits
879a6ae4
Commit
879a6ae4
authored
Sep 23, 2018
by
Kai Chen
Browse files
bug fix and cleaning
parent
1e35964c
Changes
26
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
208 additions
and
201 deletions
+208
-201
.gitignore
.gitignore
+2
-1
mmdet/core/__init__.py
mmdet/core/__init__.py
+0
-2
mmdet/core/bbox_ops/sampling.py
mmdet/core/bbox_ops/sampling.py
+3
-6
mmdet/core/bbox_ops/transforms.py
mmdet/core/bbox_ops/transforms.py
+4
-4
mmdet/core/eval/__init__.py
mmdet/core/eval/__init__.py
+2
-1
mmdet/core/eval/coco_utils.py
mmdet/core/eval/coco_utils.py
+26
-0
mmdet/core/losses/losses.py
mmdet/core/losses/losses.py
+36
-35
mmdet/core/mask_ops/utils.py
mmdet/core/mask_ops/utils.py
+0
-4
mmdet/core/post_processing/merge_augs.py
mmdet/core/post_processing/merge_augs.py
+10
-8
mmdet/core/rpn_ops/anchor_generator.py
mmdet/core/rpn_ops/anchor_generator.py
+4
-1
mmdet/core/rpn_ops/anchor_target.py
mmdet/core/rpn_ops/anchor_target.py
+19
-14
mmdet/core/test_engine.py
mmdet/core/test_engine.py
+0
-14
mmdet/core/train_engine.py
mmdet/core/train_engine.py
+0
-40
mmdet/core/utils/dist_utils.py
mmdet/core/utils/dist_utils.py
+6
-7
mmdet/core/utils/hooks.py
mmdet/core/utils/hooks.py
+1
-1
mmdet/core/utils/misc.py
mmdet/core/utils/misc.py
+8
-14
mmdet/nn/parallel/scatter_gather.py
mmdet/nn/parallel/scatter_gather.py
+14
-4
setup.py
setup.py
+1
-1
tools/coco_eval.py
tools/coco_eval.py
+23
-0
tools/configs/r50_fpn_frcnn_1x.py
tools/configs/r50_fpn_frcnn_1x.py
+49
-44
No files found.
.gitignore
View file @
879a6ae4
...
...
@@ -104,4 +104,5 @@ venv.bak/
.mypy_cache/
# cython generated cpp
mmdet/ops/nms/*.cpp
\ No newline at end of file
mmdet/ops/nms/*.cpp
data
mmdet/core/__init__.py
View file @
879a6ae4
from
.train_engine
import
*
from
.test_engine
import
*
from
.rpn_ops
import
*
from
.bbox_ops
import
*
from
.mask_ops
import
*
...
...
mmdet/core/bbox_ops/sampling.py
View file @
879a6ae4
...
...
@@ -244,6 +244,7 @@ def bbox_sampling(assigned_gt_inds,
num_expected_pos
=
int
(
num_expected
*
pos_fraction
)
pos_inds
=
sample_positives
(
assigned_gt_inds
,
num_expected_pos
,
pos_balance_sampling
)
pos_inds
=
pos_inds
.
unique
()
num_sampled_pos
=
pos_inds
.
numel
()
num_neg_max
=
int
(
neg_pos_ub
*
...
...
@@ -252,10 +253,10 @@ def bbox_sampling(assigned_gt_inds,
neg_inds
=
sample_negatives
(
assigned_gt_inds
,
num_expected_neg
,
max_overlaps
,
neg_balance_thr
,
neg_hard_fraction
)
neg_inds
=
neg_inds
.
unique
()
return
pos_inds
,
neg_inds
def
sample_proposals
(
proposals_list
,
gt_bboxes_list
,
gt_crowds_list
,
gt_labels_list
,
cfg
):
cfg_list
=
[
cfg
for
_
in
range
(
len
(
proposals_list
))]
...
...
@@ -265,11 +266,7 @@ def sample_proposals(proposals_list, gt_bboxes_list, gt_crowds_list,
return
tuple
(
map
(
list
,
zip
(
*
results
)))
def
sample_proposals_single
(
proposals
,
gt_bboxes
,
gt_crowds
,
gt_labels
,
cfg
):
def
sample_proposals_single
(
proposals
,
gt_bboxes
,
gt_crowds
,
gt_labels
,
cfg
):
proposals
=
proposals
[:,
:
4
]
assigned_gt_inds
,
assigned_labels
,
argmax_overlaps
,
max_overlaps
=
\
bbox_assign
(
...
...
mmdet/core/bbox_ops/transforms.py
View file @
879a6ae4
...
...
@@ -84,18 +84,18 @@ def bbox_flip(bboxes, img_shape):
return
mmcv
.
bbox_flip
(
bboxes
,
img_shape
)
def
bbox_mapping
(
bboxes
,
img_shape
,
flip
):
def
bbox_mapping
(
bboxes
,
img_shape
,
scale_factor
,
flip
):
"""Map bboxes from the original image scale to testing scale"""
new_bboxes
=
bboxes
*
img_shape
[
-
1
]
new_bboxes
=
bboxes
*
scale_factor
if
flip
:
new_bboxes
=
bbox_flip
(
new_bboxes
,
img_shape
)
return
new_bboxes
def
bbox_mapping_back
(
bboxes
,
img_shape
,
flip
):
def
bbox_mapping_back
(
bboxes
,
img_shape
,
scale_factor
,
flip
):
"""Map bboxes from testing scale to original image scale"""
new_bboxes
=
bbox_flip
(
bboxes
,
img_shape
)
if
flip
else
bboxes
new_bboxes
=
new_bboxes
/
img_shape
[
-
1
]
new_bboxes
=
new_bboxes
/
scale_factor
return
new_bboxes
...
...
mmdet/core/eval/__init__.py
View file @
879a6ae4
from
.class_names
import
(
voc_classes
,
imagenet_det_classes
,
imagenet_vid_classes
,
coco_classes
,
dataset_aliases
,
get_classes
)
from
.coco_utils
import
coco_eval
from
.mean_ap
import
average_precision
,
eval_map
,
print_map_summary
from
.recall
import
(
eval_recalls
,
print_recall_summary
,
plot_num_recall
,
plot_iou_recall
)
...
...
@@ -9,5 +10,5 @@ __all__ = [
'voc_classes'
,
'imagenet_det_classes'
,
'imagenet_vid_classes'
,
'coco_classes'
,
'dataset_aliases'
,
'get_classes'
,
'average_precision'
,
'eval_map'
,
'print_map_summary'
,
'eval_recalls'
,
'print_recall_summary'
,
'plot_num_recall'
,
'plot_iou_recall'
'plot_num_recall'
,
'plot_iou_recall'
,
'coco_eval'
]
mmdet/core/eval/coco_utils.py
0 → 100644
View file @
879a6ae4
import
mmcv
from
pycocotools.coco
import
COCO
from
pycocotools.cocoeval
import
COCOeval
def
coco_eval
(
result_file
,
result_types
,
coco
,
max_dets
=
(
100
,
300
,
1000
)):
assert
result_file
.
endswith
(
'.json'
)
for
res_type
in
result_types
:
assert
res_type
in
[
'proposal'
,
'bbox'
,
'segm'
,
'keypoints'
]
if
mmcv
.
is_str
(
coco
):
coco
=
COCO
(
coco
)
assert
isinstance
(
coco
,
COCO
)
coco_dets
=
coco
.
loadRes
(
result_file
)
img_ids
=
coco
.
getImgIds
()
for
res_type
in
result_types
:
iou_type
=
'bbox'
if
res_type
==
'proposal'
else
res_type
cocoEval
=
COCOeval
(
coco
,
coco_dets
,
iou_type
)
cocoEval
.
params
.
imgIds
=
img_ids
if
res_type
==
'proposal'
:
cocoEval
.
params
.
useCats
=
0
cocoEval
.
params
.
maxDets
=
list
(
max_dets
)
cocoEval
.
evaluate
()
cocoEval
.
accumulate
()
cocoEval
.
summarize
()
mmdet/core/losses/losses.py
View file @
879a6ae4
# TODO merge naive and weighted loss
to one function
.
# TODO merge naive and weighted loss.
import
torch
import
torch.nn.functional
as
F
from
..bbox_ops
import
bbox_transform_inv
,
bbox_overlaps
def
weighted_nll_loss
(
pred
,
label
,
weight
,
avg_factor
=
None
):
if
avg_factor
is
None
:
avg_factor
=
max
(
torch
.
sum
(
weight
>
0
).
float
().
item
(),
1.
)
raw
=
F
.
nll_loss
(
pred
,
label
,
reduction
=
'none'
)
return
torch
.
sum
(
raw
*
weight
)[
None
]
/
avg_factor
def
weighted_nll_loss
(
pred
,
label
,
weight
,
ave_factor
=
None
):
if
ave_factor
is
None
:
ave_factor
=
max
(
torch
.
sum
(
weight
>
0
).
float
().
item
(),
1.
)
raw
=
F
.
nll_loss
(
pred
,
label
,
size_average
=
False
,
reduce
=
False
)
return
torch
.
sum
(
raw
*
weight
)[
None
]
/
ave_factor
def
weighted_cross_entropy
(
pred
,
label
,
weight
,
avg_factor
=
None
):
if
avg_factor
is
None
:
avg_factor
=
max
(
torch
.
sum
(
weight
>
0
).
float
().
item
(),
1.
)
raw
=
F
.
cross_entropy
(
pred
,
label
,
reduction
=
'none'
)
return
torch
.
sum
(
raw
*
weight
)[
None
]
/
avg_factor
def
weighted_cross_entropy
(
pred
,
label
,
weight
,
ave_factor
=
None
):
if
ave_factor
is
None
:
ave_factor
=
max
(
torch
.
sum
(
weight
>
0
).
float
().
item
(),
1.
)
raw
=
F
.
cross_entropy
(
pred
,
label
,
size_average
=
False
,
reduce
=
False
)
return
torch
.
sum
(
raw
*
weight
)[
None
]
/
ave_factor
def
weighted_binary_cross_entropy
(
pred
,
label
,
weight
,
ave_factor
=
None
):
if
ave_factor
is
None
:
ave_factor
=
max
(
torch
.
sum
(
weight
>
0
).
float
().
item
(),
1.
)
def
weighted_binary_cross_entropy
(
pred
,
label
,
weight
,
avg_factor
=
None
):
if
avg_factor
is
None
:
avg_factor
=
max
(
torch
.
sum
(
weight
>
0
).
float
().
item
(),
1.
)
return
F
.
binary_cross_entropy_with_logits
(
pred
,
label
.
float
(),
weight
.
float
(),
size_average
=
False
)[
None
]
/
av
e
_factor
reduction
=
'sum'
)[
None
]
/
av
g
_factor
def
sigmoid_focal_loss
(
pred
,
...
...
@@ -46,13 +44,13 @@ def weighted_sigmoid_focal_loss(pred,
weight
,
gamma
=
2.0
,
alpha
=
0.25
,
av
e
_factor
=
None
,
av
g
_factor
=
None
,
num_classes
=
80
):
if
av
e
_factor
is
None
:
av
e
_factor
=
torch
.
sum
(
weight
>
0
).
float
().
item
()
/
num_classes
+
1e-6
if
av
g
_factor
is
None
:
av
g
_factor
=
torch
.
sum
(
weight
>
0
).
float
().
item
()
/
num_classes
+
1e-6
return
sigmoid_focal_loss
(
pred
,
target
,
weight
,
gamma
=
gamma
,
alpha
=
alpha
,
size_average
=
False
)[
None
]
/
av
e
_factor
reduction
=
'sum'
)[
None
]
/
av
g
_factor
def
mask_cross_entropy
(
pred
,
target
,
label
):
...
...
@@ -60,7 +58,7 @@ def mask_cross_entropy(pred, target, label):
inds
=
torch
.
arange
(
0
,
num_rois
,
dtype
=
torch
.
long
,
device
=
pred
.
device
)
pred_slice
=
pred
[
inds
,
label
].
squeeze
(
1
)
return
F
.
binary_cross_entropy_with_logits
(
pred_slice
,
target
,
size_average
=
True
)[
None
]
pred_slice
,
target
,
reduction
=
'sum'
)[
None
]
def
weighted_mask_cross_entropy
(
pred
,
target
,
weight
,
label
):
...
...
@@ -73,24 +71,27 @@ def weighted_mask_cross_entropy(pred, target, weight, label):
pred_slice
,
target
,
weight
,
size_average
=
False
)[
None
]
/
num_samples
def
smooth_l1_loss
(
pred
,
target
,
beta
=
1.0
,
size_average
=
True
,
reduce
=
True
):
def
smooth_l1_loss
(
pred
,
target
,
beta
=
1.0
,
reduction
=
'elementwise_mean'
):
assert
beta
>
0
assert
pred
.
size
()
==
target
.
size
()
and
target
.
numel
()
>
0
diff
=
torch
.
abs
(
pred
-
target
)
loss
=
torch
.
where
(
diff
<
beta
,
0.5
*
diff
*
diff
/
beta
,
diff
-
0.5
*
beta
)
if
size_average
:
loss
/=
pred
.
numel
()
if
reduce
:
loss
=
loss
.
sum
()
return
loss
def
weighted_smoothl1
(
pred
,
target
,
weight
,
beta
=
1.0
,
ave_factor
=
None
):
if
ave_factor
is
None
:
ave_factor
=
torch
.
sum
(
weight
>
0
).
float
().
item
()
/
4
+
1e-6
loss
=
smooth_l1_loss
(
pred
,
target
,
beta
,
size_average
=
False
,
reduce
=
False
)
return
torch
.
sum
(
loss
*
weight
)[
None
]
/
ave_factor
reduction
=
F
.
_Reduction
.
get_enum
(
reduction
)
# none: 0, elementwise_mean:1, sum: 2
if
reduction
==
0
:
return
loss
elif
reduction
==
1
:
return
loss
.
sum
()
/
pred
.
numel
()
elif
reduction
==
2
:
return
loss
.
sum
()
def
weighted_smoothl1
(
pred
,
target
,
weight
,
beta
=
1.0
,
avg_factor
=
None
):
if
avg_factor
is
None
:
avg_factor
=
torch
.
sum
(
weight
>
0
).
float
().
item
()
/
4
+
1e-6
loss
=
smooth_l1_loss
(
pred
,
target
,
beta
,
reduction
=
'none'
)
return
torch
.
sum
(
loss
*
weight
)[
None
]
/
avg_factor
def
accuracy
(
pred
,
target
,
topk
=
1
):
...
...
mmdet/core/mask_ops/utils.py
View file @
879a6ae4
import
cvbase
as
cvb
import
numpy
as
np
import
pycocotools.mask
as
mask_utils
import
mmcv
...
...
mmdet/core/post_processing/merge_augs.py
View file @
879a6ae4
import
torch
from
mmdet.ops
import
nms
import
numpy
as
np
from
mmdet.ops
import
nms
from
..bbox_ops
import
bbox_mapping_back
...
...
@@ -21,11 +21,12 @@ def merge_aug_proposals(aug_proposals, img_metas, rpn_test_cfg):
"""
recovered_proposals
=
[]
for
proposals
,
img_info
in
zip
(
aug_proposals
,
img_metas
):
shape_scale
=
img_info
[
'shape_scale'
][
0
]
flip
=
img_info
[
'flip'
][
0
]
img_shape
=
img_info
[
'img_shape'
]
scale_factor
=
img_info
[
'scale_factor'
]
flip
=
img_info
[
'flip'
]
_proposals
=
proposals
.
clone
()
_proposals
[:,
:
4
]
=
bbox_mapping_back
(
_proposals
[:,
:
4
],
shap
e_scal
e
,
flip
)
_proposals
[:,
:
4
]
=
bbox_mapping_back
(
_proposals
[:,
:
4
],
img_
shape
,
scale_factor
,
flip
)
recovered_proposals
.
append
(
_proposals
)
aug_proposals
=
torch
.
cat
(
recovered_proposals
,
dim
=
0
)
nms_keep
=
nms
(
aug_proposals
,
rpn_test_cfg
.
nms_thr
,
...
...
@@ -53,9 +54,10 @@ def merge_aug_bboxes(aug_bboxes, aug_scores, img_metas, rcnn_test_cfg):
"""
recovered_bboxes
=
[]
for
bboxes
,
img_info
in
zip
(
aug_bboxes
,
img_metas
):
shape_scale
=
img_info
[
'shape_scale'
][
0
]
flip
=
img_info
[
'flip'
][
0
]
bboxes
=
bbox_mapping_back
(
bboxes
,
shape_scale
,
flip
)
img_shape
=
img_info
[
'img_shape'
]
scale_factor
=
img_info
[
'scale_factor'
]
flip
=
img_info
[
'flip'
]
bboxes
=
bbox_mapping_back
(
bboxes
,
img_shape
,
scale_factor
,
flip
)
recovered_bboxes
.
append
(
bboxes
)
bboxes
=
torch
.
stack
(
recovered_bboxes
).
mean
(
dim
=
0
)
if
aug_scores
is
None
:
...
...
mmdet/core/rpn_ops/anchor_generator.py
View file @
879a6ae4
...
...
@@ -50,15 +50,18 @@ class AnchorGenerator(object):
return
yy
,
xx
def
grid_anchors
(
self
,
featmap_size
,
stride
=
16
,
device
=
'cuda'
):
base_anchors
=
self
.
base_anchors
.
to
(
device
)
feat_h
,
feat_w
=
featmap_size
shift_x
=
torch
.
arange
(
0
,
feat_w
,
device
=
device
)
*
stride
shift_y
=
torch
.
arange
(
0
,
feat_h
,
device
=
device
)
*
stride
shift_xx
,
shift_yy
=
self
.
_meshgrid
(
shift_x
,
shift_y
)
shifts
=
torch
.
stack
([
shift_xx
,
shift_yy
,
shift_xx
,
shift_yy
],
dim
=-
1
)
shifts
=
shifts
.
type_as
(
base_anchors
)
# first feat_w elements correspond to the first row of shifts
# add A anchors (1, A, 4) to K shifts (K, 1, 4) to get
# shifted anchors (K, A, 4), reshape to (K*A, 4)
base_anchors
=
self
.
base_anchors
.
to
(
device
)
all_anchors
=
base_anchors
[
None
,
:,
:]
+
shifts
[:,
None
,
:]
all_anchors
=
all_anchors
.
view
(
-
1
,
4
)
# first A rows correspond to A anchors of (0, 0) in feature map,
...
...
mmdet/core/rpn_ops/anchor_target.py
View file @
879a6ae4
...
...
@@ -4,12 +4,14 @@ from ..bbox_ops import (bbox_assign, bbox_transform, bbox_sampling)
def
anchor_target
(
anchor_list
,
valid_flag_list
,
featmap_sizes
,
gt_bboxes_list
,
img_shapes
,
target_means
,
target_stds
,
cfg
):
"""Compute anchor regression and classification targets
img_metas
,
target_means
,
target_stds
,
cfg
):
"""Compute regression and classification targets for anchors.
There may be multiple feature levels,
Args:
anchor_list(list): anchors of each feature map level
feat
ure
map_sizes(list): feature map sizes
featmap_sizes(list): feature map sizes
gt_bboxes_list(list): ground truth bbox of images in a mini-batch
img_shapes(list): shape of each image in a mini-batch
cfg(dict): configs
...
...
@@ -17,15 +19,16 @@ def anchor_target(anchor_list, valid_flag_list, featmap_sizes, gt_bboxes_list,
Returns:
tuple
"""
if
len
(
featmap_sizes
)
==
len
(
anchor_list
):
num_imgs
=
len
(
img_metas
)
num_levels
=
len
(
featmap_sizes
)
if
len
(
anchor_list
)
==
num_levels
:
all_anchors
=
torch
.
cat
(
anchor_list
,
0
)
anchor_nums
=
[
anchors
.
size
(
0
)
for
anchors
in
anchor_list
]
use_isomerism_anchors
=
False
elif
len
(
img_shapes
)
==
len
(
anchor_list
):
elif
len
(
anchor_list
)
==
num_imgs
:
# using different anchors for different images
all_anchors_list
=
[
torch
.
cat
(
anchor_list
[
img_id
],
0
)
for
img_id
in
range
(
len
(
img_shapes
))
torch
.
cat
(
anchor_list
[
img_id
],
0
)
for
img_id
in
range
(
num_imgs
)
]
anchor_nums
=
[
anchors
.
size
(
0
)
for
anchors
in
anchor_list
[
0
]]
use_isomerism_anchors
=
True
...
...
@@ -37,7 +40,7 @@ def anchor_target(anchor_list, valid_flag_list, featmap_sizes, gt_bboxes_list,
all_bbox_targets
=
[]
all_bbox_weights
=
[]
num_total_sampled
=
0
for
img_id
in
range
(
len
(
img_shapes
)
):
for
img_id
in
range
(
num_imgs
):
if
isinstance
(
valid_flag_list
[
img_id
],
list
):
valid_flags
=
torch
.
cat
(
valid_flag_list
[
img_id
],
0
)
else
:
...
...
@@ -45,7 +48,7 @@ def anchor_target(anchor_list, valid_flag_list, featmap_sizes, gt_bboxes_list,
if
use_isomerism_anchors
:
all_anchors
=
all_anchors_list
[
img_id
]
inside_flags
=
anchor_inside_flags
(
all_anchors
,
valid_flags
,
img_
shape
s
[
img_id
][:
2
],
img_
meta
s
[
img_id
][
'img_shape'
][
:
2
],
cfg
.
allowed_border
)
if
not
inside_flags
.
any
():
return
None
...
...
@@ -83,7 +86,7 @@ def anchor_target(anchor_list, valid_flag_list, featmap_sizes, gt_bboxes_list,
def
anchor_target_single
(
all_anchors
,
inside_flags
,
gt_bboxes
,
target_means
,
target_stds
,
cfg
):
num_total_anchors
=
all_anchors
.
size
(
0
)
# assign gt and sample anchors
anchors
=
all_anchors
[
inside_flags
,
:]
assigned_gt_inds
,
argmax_overlaps
,
max_overlaps
=
bbox_assign
(
anchors
,
...
...
@@ -99,10 +102,9 @@ def anchor_target_single(all_anchors, inside_flags, gt_bboxes, target_means,
bbox_targets
=
torch
.
zeros_like
(
anchors
)
bbox_weights
=
torch
.
zeros_like
(
anchors
)
labels
=
torch
.
zeros_like
(
assigned_gt_inds
)
label_weights
=
torch
.
zeros_like
(
assigned_gt_inds
,
dtype
=
torch
.
float
)
label_weights
=
torch
.
zeros_like
(
assigned_gt_inds
,
dtype
=
anchors
.
dtype
)
if
len
(
pos_inds
)
>
0
:
pos_inds
=
unique
(
pos_inds
)
pos_anchors
=
anchors
[
pos_inds
,
:]
pos_gt_bbox
=
gt_bboxes
[
assigned_gt_inds
[
pos_inds
]
-
1
,
:]
pos_bbox_targets
=
bbox_transform
(
pos_anchors
,
pos_gt_bbox
,
...
...
@@ -115,10 +117,10 @@ def anchor_target_single(all_anchors, inside_flags, gt_bboxes, target_means,
else
:
label_weights
[
pos_inds
]
=
cfg
.
pos_weight
if
len
(
neg_inds
)
>
0
:
neg_inds
=
unique
(
neg_inds
)
label_weights
[
neg_inds
]
=
1.0
# map up to original set of anchors
num_total_anchors
=
all_anchors
.
size
(
0
)
labels
=
unmap
(
labels
,
num_total_anchors
,
inside_flags
)
label_weights
=
unmap
(
label_weights
,
num_total_anchors
,
inside_flags
)
bbox_targets
=
unmap
(
bbox_targets
,
num_total_anchors
,
inside_flags
)
...
...
@@ -127,8 +129,9 @@ def anchor_target_single(all_anchors, inside_flags, gt_bboxes, target_means,
return
(
labels
,
label_weights
,
bbox_targets
,
bbox_weights
,
pos_inds
,
neg_inds
)
def
anchor_inside_flags
(
all_anchors
,
valid_flags
,
img_shape
,
allowed_border
=
0
):
img_h
,
img_w
=
img_shape
.
float
()
img_h
,
img_w
=
img_shape
[:
2
]
if
allowed_border
>=
0
:
inside_flags
=
valid_flags
&
\
(
all_anchors
[:,
0
]
>=
-
allowed_border
)
&
\
...
...
@@ -139,6 +142,7 @@ def anchor_inside_flags(all_anchors, valid_flags, img_shape, allowed_border=0):
inside_flags
=
valid_flags
return
inside_flags
def
unique
(
tensor
):
if
tensor
.
is_cuda
:
u_tensor
=
np
.
unique
(
tensor
.
cpu
().
numpy
())
...
...
@@ -146,6 +150,7 @@ def unique(tensor):
else
:
return
torch
.
unique
(
tensor
)
def
unmap
(
data
,
count
,
inds
,
fill
=
0
):
""" Unmap a subset of item (data) back to the original set of items (of
size count) """
...
...
mmdet/core/test_engine.py
deleted
100644 → 0
View file @
1e35964c
from
mmdet.datasets
import
collate
from
mmdet.nn.parallel
import
scatter
__all__
=
[
'_data_func'
]
def
_data_func
(
data
,
gpu_id
):
imgs
,
img_metas
=
tuple
(
scatter
(
collate
([
data
],
samples_per_gpu
=
1
),
[
gpu_id
])[
0
])
return
dict
(
img
=
imgs
,
img_meta
=
img_metas
,
return_loss
=
False
,
return_bboxes
=
True
,
rescale
=
True
)
mmdet/core/train_engine.py
deleted
100644 → 0
View file @
1e35964c
import
numpy
as
np
import
torch
from
collections
import
OrderedDict
from
mmdet.nn.parallel
import
scatter
def
parse_losses
(
losses
):
log_vars
=
OrderedDict
()
for
loss_key
,
loss_value
in
losses
.
items
():
if
isinstance
(
loss_value
,
dict
):
for
_key
,
_value
in
loss_value
.
items
():
if
isinstance
(
_value
,
list
):
_value
=
sum
([
_loss
.
mean
()
for
_loss
in
_value
])
else
:
_value
=
_value
.
mean
()
log_vars
[
_keys
]
=
_value
elif
isinstance
(
loss_value
,
list
):
log_vars
[
loss_key
]
=
sum
(
_loss
.
mean
()
for
_loss
in
loss_value
)
else
:
log_vars
[
loss_key
]
=
loss_value
.
mean
()
loss
=
sum
(
_value
for
_key
,
_value
in
log_vars
.
items
()
if
'loss'
in
_key
)
log_vars
[
'loss'
]
=
loss
for
_key
,
_value
in
log_vars
.
items
():
log_vars
[
_key
]
=
_value
.
item
()
return
loss
,
log_vars
def
batch_processor
(
model
,
data
,
train_mode
,
args
=
None
):
data
=
scatter
(
data
,
[
torch
.
cuda
.
current_device
()])[
0
]
losses
=
model
(
**
data
)
loss
,
log_vars
=
parse_losses
(
losses
)
outputs
=
dict
(
loss
=
loss
/
args
.
world_size
,
log_vars
=
log_vars
,
num_samples
=
len
(
data
[
'img'
].
data
))
return
outputs
mmdet/core/utils/dist_utils.py
View file @
879a6ae4
...
...
@@ -3,11 +3,11 @@ import torch
import
torch.multiprocessing
as
mp
import
torch.distributed
as
dist
from
torch.nn.utils
import
clip_grad
from
mmcv.torchpack
import
Hook
,
Optimizer
Stepper
Hook
from
mmcv.torchpack
import
Hook
,
OptimizerHook
__all__
=
[
'init_dist'
,
'average_gradients'
,
'broadcast_params'
,
'DistOptimizerStepperHook'
,
'DistSamplerSeedHook'
'init_dist'
,
'average_gradients'
,
'broadcast_params'
,
'DistOptimizerHook'
,
'DistSamplerSeedHook'
]
...
...
@@ -40,17 +40,16 @@ def broadcast_params(model):
dist
.
broadcast
(
p
,
0
)
class
DistOptimizer
Stepper
Hook
(
Optimizer
Stepper
Hook
):
class
DistOptimizerHook
(
OptimizerHook
):
def
after_train_iter
(
self
,
runner
):
runner
.
optimizer
.
zero_grad
()
runner
.
outputs
[
'loss'
].
backward
()
average_gradients
(
runner
.
model
)
if
self
.
grad_clip
:
if
self
.
grad_clip
is
not
None
:
clip_grad
.
clip_grad_norm_
(
filter
(
lambda
p
:
p
.
requires_grad
,
runner
.
model
.
parameters
()),
max_norm
=
self
.
max_norm
,
norm_type
=
self
.
norm_type
)
**
self
.
grad_clip
)
runner
.
optimizer
.
step
()
...
...
mmdet/core/utils/hooks.py
View file @
879a6ae4
...
...
@@ -7,7 +7,7 @@ import mmcv
import
numpy
as
np
import
torch
from
mmcv.torchpack
import
Hook
from
mmdet.datasets
import
collate
from
mmdet.datasets
.loader
import
collate
from
mmdet.nn.parallel
import
scatter
from
pycocotools.cocoeval
import
COCOeval
...
...
mmdet/core/utils/misc.py
View file @
879a6ae4
import
subprocess
import
mmcv
import
numpy
as
np
import
torch
...
...
@@ -7,20 +5,14 @@ import torch
__all__
=
[
'tensor2imgs'
,
'unique'
,
'unmap'
,
'results2json'
]
def
tensor2imgs
(
tensor
,
color_order
=
'RGB'
,
color_mean
=
(
0.485
,
0.456
,
0.406
),
color_std
=
(
0.229
,
0.224
,
0.225
)):
assert
color_order
in
[
'RGB'
,
'BGR'
]
img_per_gpu
=
tensor
.
size
(
0
)
color_mean
=
np
.
array
(
color_mean
,
dtype
=
np
.
float32
)
color_std
=
np
.
array
(
color_std
,
dtype
=
np
.
float32
)
def
tensor2imgs
(
tensor
,
mean
=
(
0
,
0
,
0
),
std
=
(
1
,
1
,
1
),
to_rgb
=
True
):
num_imgs
=
tensor
.
size
(
0
)
mean
=
np
.
array
(
mean
,
dtype
=
np
.
float32
)
std
=
np
.
array
(
std
,
dtype
=
np
.
float32
)
imgs
=
[]
for
img_id
in
range
(
img_per_gpu
):
for
img_id
in
range
(
num_imgs
):
img
=
tensor
[
img_id
,
...].
cpu
().
numpy
().
transpose
(
1
,
2
,
0
)
if
color_order
==
'RGB'
:
img
=
mmcv
.
rgb2bgr
(
img
)
img
=
img
*
color_std
+
color_mean
img
=
mmcv
.
imdenorm
(
img
,
mean
,
std
,
to_bgr
=
to_rgb
).
astype
(
np
.
uint8
)
imgs
.
append
(
np
.
ascontiguousarray
(
img
))
return
imgs
...
...
@@ -45,6 +37,7 @@ def unmap(data, count, inds, fill=0):
ret
[
inds
,
:]
=
data
return
ret
def
xyxy2xywh
(
bbox
):
_bbox
=
bbox
.
tolist
()
return
[
...
...
@@ -54,6 +47,7 @@ def xyxy2xywh(bbox):
_bbox
[
3
]
-
_bbox
[
1
]
+
1
,
]
def
det2json
(
dataset
,
results
):
json_results
=
[]
for
idx
in
range
(
len
(
dataset
)):
...
...
mmdet/nn/parallel/scatter_gather.py
View file @
879a6ae4
...
...
@@ -14,14 +14,24 @@ def scatter(inputs, target_gpus, dim=0):
def
scatter_map
(
obj
):
if
isinstance
(
obj
,
torch
.
Tensor
):
return
OrigScatter
.
apply
(
target_gpus
,
None
,
dim
,
obj
)
if
isinstance
(
obj
,
DataContainer
)
and
isinstance
(
obj
.
data
,
list
):
return
Scatter
.
forward
(
target_gpus
,
obj
.
data
)
if
isinstance
(
obj
,
DataContainer
):
# print('data container', obj)
if
obj
.
cpu_only
:
return
obj
.
data
else
:
return
Scatter
.
forward
(
target_gpus
,
obj
.
data
)
if
isinstance
(
obj
,
tuple
)
and
len
(
obj
)
>
0
:
return
list
(
zip
(
*
map
(
scatter_map
,
obj
)))
if
isinstance
(
obj
,
list
)
and
len
(
obj
)
>
0
:
return
list
(
map
(
list
,
zip
(
*
map
(
scatter_map
,
obj
))))
# print('list', obj)
out
=
list
(
map
(
list
,
zip
(
*
map
(
scatter_map
,
obj
))))
# print('list out', out)
return
out
if
isinstance
(
obj
,
dict
)
and
len
(
obj
)
>
0
:
return
list
(
map
(
type
(
obj
),
zip
(
*
map
(
scatter_map
,
obj
.
items
()))))
# print('dict\n', obj)
out
=
list
(
map
(
type
(
obj
),
zip
(
*
map
(
scatter_map
,
obj
.
items
()))))
# print('dict output\n', out)
return
out
return
[
obj
for
targets
in
target_gpus
]
# After scatter_map is called, a scatter_map cell will exist. This cell
...
...
setup.py
View file @
879a6ae4
...
...
@@ -8,7 +8,7 @@ def readme():
def
get_version
():
version_file
=
'mm
cv
/version.py'
version_file
=
'mm
det
/version.py'
with
open
(
version_file
,
'r'
)
as
f
:
exec
(
compile
(
f
.
read
(),
version_file
,
'exec'
))
return
locals
()[
'__version__'
]
...
...
tools/coco_eval.py
0 → 100644
View file @
879a6ae4
from
argparse
import
ArgumentParser
from
mmdet.core
import
coco_eval
def
main
():
parser
=
ArgumentParser
(
description
=
'COCO Evaluation'
)
parser
.
add_argument
(
'result'
,
help
=
'result file path'
)
parser
.
add_argument
(
'--ann'
,
help
=
'annotation file path'
)
parser
.
add_argument
(
'--types'
,
type
=
str
,
nargs
=
'+'
,
default
=
[
'bbox'
],
help
=
'result types'
)
parser
.
add_argument
(
'--max-dets'
,
type
=
int
,
nargs
=
'+'
,
default
=
[
100
,
300
,
1000
],
help
=
'result types'
)
args
=
parser
.
parse_args
()
coco_eval
(
args
.
result
,
args
.
types
,
args
.
ann
,
args
.
max_dets
)
if
__name__
==
'__main__'
:
main
()
tools/
example
s/r50_fpn_frcnn_1x.py
→
tools/
config
s/r50_fpn_frcnn_1x.py
View file @
879a6ae4
# model settings
model
=
dict
(
pretrained
=
'/mnt/lustre/pangjiangmiao/initmodel/pytorch/resnet50-19c8e357.pth
'
,
type
=
'FasterRCNN'
,
pretrained
=
'modelzoo://resnet50
'
,
backbone
=
dict
(
type
=
'resnet'
,
depth
=
50
,
...
...
@@ -25,7 +25,7 @@ model = dict(
target_means
=
[.
0
,
.
0
,
.
0
,
.
0
],
target_stds
=
[
1.0
,
1.0
,
1.0
,
1.0
],
use_sigmoid_cls
=
True
),
roi_block
=
dict
(
bbox_roi_extractor
=
dict
(
type
=
'SingleLevelRoI'
,
roi_layer
=
dict
(
type
=
'RoIAlign'
,
out_size
=
7
,
sample_num
=
2
),
out_channels
=
256
,
...
...
@@ -40,8 +40,9 @@ model = dict(
target_means
=
[
0.
,
0.
,
0.
,
0.
],
target_stds
=
[
0.1
,
0.1
,
0.2
,
0.2
],
reg_class_agnostic
=
False
))
meta_params
=
dict
(
rpn_train_cfg
=
dict
(
# model training and testing settings
train_cfg
=
dict
(
rpn
=
dict
(
pos_fraction
=
0.5
,
pos_balance_sampling
=
False
,
neg_pos_ub
=
256
,
...
...
@@ -54,14 +55,7 @@ meta_params = dict(
pos_weight
=-
1
,
smoothl1_beta
=
1
/
9.0
,
debug
=
False
),
rpn_test_cfg
=
dict
(
nms_across_levels
=
False
,
nms_pre
=
2000
,
nms_post
=
2000
,
max_num
=
2000
,
nms_thr
=
0.7
,
min_bbox_size
=
0
),
rcnn_train_cfg
=
dict
(
rcnn
=
dict
(
pos_iou_thr
=
0.5
,
neg_iou_thr
=
0.5
,
crowd_thr
=
1.1
,
...
...
@@ -72,54 +66,65 @@ meta_params = dict(
neg_pos_ub
=
512
,
neg_balance_thr
=
0
,
pos_weight
=-
1
,
debug
=
False
),
rcnn_test_cfg
=
dict
(
score_thr
=
1e-3
,
max_per_img
=
100
,
nms_thr
=
0.5
)
)
debug
=
False
))
test_cfg
=
dict
(
rpn
=
dict
(
nms_across_levels
=
False
,
nms_pre
=
2000
,
nms_post
=
2000
,
max_num
=
2000
,
nms_thr
=
0.7
,
min_bbox_size
=
0
),
rcnn
=
dict
(
score_thr
=
1e-3
,
max_per_img
=
100
,
nms_thr
=
0.5
))
# dataset settings
data_root
=
'/mnt/lustre/pangjiangmiao/dataset/coco/'
dataset_type
=
'CocoDataset'
data_root
=
'../data/coco/'
img_norm_cfg
=
dict
(
mean
=
[
123.675
,
116.28
,
103.53
],
std
=
[
58.395
,
57.12
,
57.375
],
to_rgb
=
True
)
img_per_gpu
=
1
data_workers
=
2
train_dataset
=
dict
(
ann_file
=
data_root
+
'annotations/instances_train2017.json'
,
img_prefix
=
data_root
+
'train2017/'
,
img_scale
=
(
1333
,
800
),
img_norm_cfg
=
img_norm_cfg
,
size_divisor
=
32
,
flip_ratio
=
0.5
)
test_dataset
=
dict
(
ann_file
=
data_root
+
'annotations/instances_val2017.json'
,
img_prefix
=
data_root
+
'val2017/'
,
img_scale
=
(
1333
,
800
),
img_norm_cfg
=
img_norm_cfg
,
size_divisor
=
32
)
mean
=
[
123.675
,
116.28
,
103.53
],
std
=
[
58.395
,
57.12
,
57.375
],
to_rgb
=
True
)
data
=
dict
(
imgs_per_gpu
=
2
,
workers_per_gpu
=
2
,
train
=
dict
(
type
=
dataset_type
,
ann_file
=
data_root
+
'annotations/instances_train2017.json'
,
img_prefix
=
data_root
+
'train2017/'
,
img_scale
=
(
1333
,
800
),
img_norm_cfg
=
img_norm_cfg
,
size_divisor
=
32
,
flip_ratio
=
0.5
),
test
=
dict
(
type
=
dataset_type
,
ann_file
=
data_root
+
'annotations/instances_val2017.json'
,
img_prefix
=
data_root
+
'val2017/'
,
img_scale
=
(
1333
,
800
),
flip_ratio
=
0
,
img_norm_cfg
=
img_norm_cfg
,
size_divisor
=
32
))
# optimizer
optimizer
=
dict
(
type
=
'SGD'
,
lr
=
0.02
,
momentum
=
0.9
,
weight_decay
=
0.0001
)
grad_clip
_config
=
dict
(
grad_clip
=
True
,
max_norm
=
35
,
norm_type
=
2
)
optimizer
_config
=
dict
(
grad_clip
=
dict
(
max_norm
=
35
,
norm_type
=
2
)
)
# learning policy
lr_
policy
=
dict
(
lr_
config
=
dict
(
policy
=
'step'
,
warmup
=
'linear'
,
warmup_iters
=
500
,
warmup_ratio
=
0.33
3
,
warmup_ratio
=
1.0
/
3
,
step
=
[
8
,
11
])
max_epoch
=
12
checkpoint_config
=
dict
(
interval
=
1
)
dist_params
=
dict
(
backend
=
'nccl'
,
port
=
'29500'
,
master_ip
=
'127.0.0.1'
)
# logging settings
log_level
=
'INFO'
# yapf:disable
log_config
=
dict
(
interval
=
50
,
hooks
=
[
dict
(
type
=
'TextLoggerHook'
),
#
(
'TensorboardLoggerHook',
dict(
log_dir=work_dir + '/log')
),
#
dict(type=
'TensorboardLoggerHook', log_dir=work_dir + '/log')
])
# yapf:enable
work_dir
=
'./model/r50_fpn_frcnn_1x'
# runtime settings
total_epochs
=
12
device_ids
=
range
(
8
)
dist_params
=
dict
(
backend
=
'nccl'
,
port
=
'29500'
,
master_ip
=
'127.0.0.1'
)
log_level
=
'INFO'
work_dir
=
'./work_dirs/fpn_faster_rcnn_r50_1x'
load_from
=
None
resume_from
=
None
workflow
=
[(
'train'
,
1
)]
Prev
1
2
Next
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