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
OpenDAS
mmdetection3d
Commits
6d71b439
"vscode:/vscode.git/clone" did not exist on "0f83aff166b3ba5d0fdddc2015a5fe95826a4d2b"
Commit
6d71b439
authored
Apr 18, 2020
by
zhangwenwei
Browse files
Refactor optimizer and samplers
parent
ba492be7
Changes
38
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
32 additions
and
376 deletions
+32
-376
.gitlab-ci.yml
.gitlab-ci.yml
+1
-0
configs/kitti/dv_mvx-v2_second_secfpn_fpn-fusion_adamw_2x8_80e_kitti-3d-3class.py
...second_secfpn_fpn-fusion_adamw_2x8_80e_kitti-3d-3class.py
+1
-1
configs/kitti/dv_pointpillars_secfpn_6x8_160e_kitti-3d-car.py
...igs/kitti/dv_pointpillars_secfpn_6x8_160e_kitti-3d-car.py
+1
-1
configs/kitti/dv_second_secfpn_2x8_cosine_80e_kitti-3d-3class.py
.../kitti/dv_second_secfpn_2x8_cosine_80e_kitti-3d-3class.py
+1
-1
configs/kitti/dv_second_secfpn_6x8_80e_kitti-3d-car.py
configs/kitti/dv_second_secfpn_6x8_80e_kitti-3d-car.py
+1
-1
configs/kitti/faster_rcnn_r50_fpn_caffe_1x_kitti-2d-3class_coco-3x-pretrain.py
...rcnn_r50_fpn_caffe_1x_kitti-2d-3class_coco-3x-pretrain.py
+1
-1
configs/kitti/hv_pointpillars_secfpn_6x8_160e_kitti-3d-car.py
...igs/kitti/hv_pointpillars_secfpn_6x8_160e_kitti-3d-car.py
+1
-1
configs/kitti/hv_second_secfpn_6x8_80e_kitti-3d-car.py
configs/kitti/hv_second_secfpn_6x8_80e_kitti-3d-car.py
+1
-1
configs/nus/faster_rcnn_r50_fpn_caffe_2x8_1x_nus.py
configs/nus/faster_rcnn_r50_fpn_caffe_2x8_1x_nus.py
+1
-1
configs/nus/hv_pointpillars_secfpn_sbn-all_4x8_20e_nus-3d.py
configs/nus/hv_pointpillars_secfpn_sbn-all_4x8_20e_nus-3d.py
+1
-1
configs/nus/retinanet_r50_fpn_caffe_2x8_1x_nus.py
configs/nus/retinanet_r50_fpn_caffe_2x8_1x_nus.py
+1
-1
mmdet3d/apis/train.py
mmdet3d/apis/train.py
+0
-170
mmdet3d/core/anchor/__init__.py
mmdet3d/core/anchor/__init__.py
+5
-5
mmdet3d/core/anchor/anchor_3d_generator.py
mmdet3d/core/anchor/anchor_3d_generator.py
+0
-90
mmdet3d/core/bbox/__init__.py
mmdet3d/core/bbox/__init__.py
+7
-11
mmdet3d/core/bbox/assign_sampling.py
mmdet3d/core/bbox/assign_sampling.py
+1
-1
mmdet3d/core/bbox/coders/__init__.py
mmdet3d/core/bbox/coders/__init__.py
+2
-2
mmdet3d/core/bbox/coders/box_coder.py
mmdet3d/core/bbox/coders/box_coder.py
+1
-1
mmdet3d/core/bbox/samplers/__init__.py
mmdet3d/core/bbox/samplers/__init__.py
+5
-8
mmdet3d/core/bbox/samplers/base_sampler.py
mmdet3d/core/bbox/samplers/base_sampler.py
+0
-78
No files found.
.gitlab-ci.yml
View file @
6d71b439
...
...
@@ -25,6 +25,7 @@ before_script:
stage
:
test
script
:
-
echo "Start building..."
-
pip install "git+https://github.com/cocodataset/cocoapi.git#subdirectory=PythonAPI"
-
pip install git+https://github.com/open-mmlab/mmdetection.git@v2.0
-
python -c "import mmdet; print(mmdet.__version__)"
-
pip install -v -e .[all]
...
...
configs/kitti/dv_mvx-v2_second_secfpn_fpn-fusion_adamw_2x8_80e_kitti-3d-3class.py
View file @
6d71b439
...
...
@@ -83,7 +83,7 @@ model = dict(
anchor_rotations
=
[
0
,
1.57
],
diff_rad_by_sin
=
True
,
assign_per_class
=
True
,
bbox_coder
=
dict
(
type
=
'ResidualCoder'
,
),
bbox_coder
=
dict
(
type
=
'Residual
3DBox
Coder'
,
),
loss_cls
=
dict
(
type
=
'FocalLoss'
,
use_sigmoid
=
True
,
...
...
configs/kitti/dv_pointpillars_secfpn_6x8_160e_kitti-3d-car.py
View file @
6d71b439
...
...
@@ -48,7 +48,7 @@ model = dict(
anchor_sizes
=
[[
1.6
,
3.9
,
1.56
]],
anchor_rotations
=
[
0
,
1.57
],
diff_rad_by_sin
=
True
,
bbox_coder
=
dict
(
type
=
'ResidualCoder'
,
),
bbox_coder
=
dict
(
type
=
'Residual
3DBox
Coder'
,
),
loss_cls
=
dict
(
type
=
'FocalLoss'
,
use_sigmoid
=
True
,
...
...
configs/kitti/dv_second_secfpn_2x8_cosine_80e_kitti-3d-3class.py
View file @
6d71b439
...
...
@@ -52,7 +52,7 @@ model = dict(
diff_rad_by_sin
=
True
,
assigner_per_size
=
True
,
assign_per_class
=
True
,
bbox_coder
=
dict
(
type
=
'ResidualCoder'
,
),
bbox_coder
=
dict
(
type
=
'Residual
3DBox
Coder'
,
),
loss_cls
=
dict
(
type
=
'FocalLoss'
,
use_sigmoid
=
True
,
...
...
configs/kitti/dv_second_secfpn_6x8_80e_kitti-3d-car.py
View file @
6d71b439
...
...
@@ -46,7 +46,7 @@ model = dict(
anchor_sizes
=
[[
1.6
,
3.9
,
1.56
]],
anchor_rotations
=
[
0
,
1.57
],
diff_rad_by_sin
=
True
,
bbox_coder
=
dict
(
type
=
'ResidualCoder'
,
),
bbox_coder
=
dict
(
type
=
'Residual
3DBox
Coder'
,
),
loss_cls
=
dict
(
type
=
'FocalLoss'
,
use_sigmoid
=
True
,
...
...
configs/kitti/faster_rcnn_r50_fpn_caffe_1x_kitti-2d-3class_coco-3x-pretrain.py
View file @
6d71b439
...
...
@@ -29,7 +29,7 @@ model = dict(
target_stds
=
[
1.0
,
1.0
,
1.0
,
1.0
],
loss_cls
=
dict
(
type
=
'CrossEntropyLoss'
,
use_sigmoid
=
True
,
loss_weight
=
1.0
),
loss_bbox
=
dict
(
type
=
'
Smooth
L1Loss'
,
beta
=
0.0
,
loss_weight
=
1.0
)),
loss_bbox
=
dict
(
type
=
'L1Loss'
,
loss_weight
=
1.0
)),
roi_head
=
dict
(
type
=
'StandardRoIHead'
,
bbox_roi_extractor
=
dict
(
...
...
configs/kitti/hv_pointpillars_secfpn_6x8_160e_kitti-3d-car.py
View file @
6d71b439
...
...
@@ -47,7 +47,7 @@ model = dict(
anchor_sizes
=
[[
1.6
,
3.9
,
1.56
]],
anchor_rotations
=
[
0
,
1.57
],
diff_rad_by_sin
=
True
,
bbox_coder
=
dict
(
type
=
'ResidualCoder'
,
),
bbox_coder
=
dict
(
type
=
'Residual
3DBox
Coder'
,
),
loss_cls
=
dict
(
type
=
'FocalLoss'
,
use_sigmoid
=
True
,
...
...
configs/kitti/hv_second_secfpn_6x8_80e_kitti-3d-car.py
View file @
6d71b439
...
...
@@ -46,7 +46,7 @@ model = dict(
anchor_sizes
=
[[
1.6
,
3.9
,
1.56
]],
anchor_rotations
=
[
0
,
1.57
],
diff_rad_by_sin
=
True
,
bbox_coder
=
dict
(
type
=
'ResidualCoder'
,
),
bbox_coder
=
dict
(
type
=
'Residual
3DBox
Coder'
,
),
loss_cls
=
dict
(
type
=
'FocalLoss'
,
use_sigmoid
=
True
,
...
...
configs/nus/faster_rcnn_r50_fpn_caffe_2x8_1x_nus.py
View file @
6d71b439
...
...
@@ -29,7 +29,7 @@ model = dict(
target_stds
=
[
1.0
,
1.0
,
1.0
,
1.0
],
loss_cls
=
dict
(
type
=
'CrossEntropyLoss'
,
use_sigmoid
=
True
,
loss_weight
=
1.0
),
loss_bbox
=
dict
(
type
=
'
Smooth
L1Loss'
,
beta
=
0.0
,
loss_weight
=
1.0
)),
loss_bbox
=
dict
(
type
=
'L1Loss'
,
loss_weight
=
1.0
)),
roi_head
=
dict
(
type
=
'StandardRoIHead'
,
bbox_roi_extractor
=
dict
(
...
...
configs/nus/hv_pointpillars_secfpn_sbn-all_4x8_20e_nus-3d.py
View file @
6d71b439
...
...
@@ -77,7 +77,7 @@ model = dict(
diff_rad_by_sin
=
True
,
dir_offset
=
0.7854
,
# pi/4
dir_limit_offset
=
0
,
bbox_coder
=
dict
(
type
=
'ResidualCoder'
,
),
bbox_coder
=
dict
(
type
=
'Residual
3DBox
Coder'
,
),
loss_cls
=
dict
(
type
=
'FocalLoss'
,
use_sigmoid
=
True
,
...
...
configs/nus/retinanet_r50_fpn_caffe_2x8_1x_nus.py
View file @
6d71b439
...
...
@@ -38,7 +38,7 @@ model = dict(
gamma
=
2.0
,
alpha
=
0.25
,
loss_weight
=
1.0
),
loss_bbox
=
dict
(
type
=
'
Smooth
L1Loss'
,
beta
=
0.0
,
loss_weight
=
1.0
)))
loss_bbox
=
dict
(
type
=
'L1Loss'
,
loss_weight
=
1.0
)))
# training and testing settings
train_cfg
=
dict
(
assigner
=
dict
(
...
...
mmdet3d/apis/train.py
View file @
6d71b439
import
torch
from
mmcv.parallel
import
MMDataParallel
,
MMDistributedDataParallel
from
mmcv.runner
import
DistSamplerSeedHook
,
Runner
from
mmdet3d.core
import
build_optimizer
from
mmdet3d.datasets
import
build_dataloader
,
build_dataset
from
mmdet.apis.train
import
parse_losses
from
mmdet.core
import
(
DistEvalHook
,
DistOptimizerHook
,
EvalHook
,
Fp16OptimizerHook
)
from
mmdet.utils
import
get_root_logger
def
batch_processor
(
model
,
data
,
train_mode
):
...
...
@@ -36,164 +27,3 @@ def batch_processor(model, data, train_mode):
outputs
=
dict
(
loss
=
loss
,
log_vars
=
log_vars
,
num_samples
=
num_samples
)
return
outputs
def
train_detector
(
model
,
dataset
,
cfg
,
distributed
=
False
,
validate
=
False
,
timestamp
=
None
,
meta
=
None
):
logger
=
get_root_logger
(
cfg
.
log_level
)
# start training
if
distributed
:
_dist_train
(
model
,
dataset
,
cfg
,
validate
=
validate
,
logger
=
logger
,
timestamp
=
timestamp
,
meta
=
meta
)
else
:
_non_dist_train
(
model
,
dataset
,
cfg
,
validate
=
validate
,
logger
=
logger
,
timestamp
=
timestamp
,
meta
=
meta
)
def
_dist_train
(
model
,
dataset
,
cfg
,
validate
=
False
,
logger
=
None
,
timestamp
=
None
,
meta
=
None
):
# prepare data loaders
dataset
=
dataset
if
isinstance
(
dataset
,
(
list
,
tuple
))
else
[
dataset
]
data_loaders
=
[
build_dataloader
(
ds
,
cfg
.
data
.
samples_per_gpu
,
cfg
.
data
.
workers_per_gpu
,
dist
=
True
,
seed
=
cfg
.
seed
)
for
ds
in
dataset
]
# put model on gpus
find_unused_parameters
=
cfg
.
get
(
'find_unused_parameters'
,
False
)
# Sets the `find_unused_parameters` parameter in
# torch.nn.parallel.DistributedDataParallel
model
=
MMDistributedDataParallel
(
model
.
cuda
(),
device_ids
=
[
torch
.
cuda
.
current_device
()],
broadcast_buffers
=
False
,
find_unused_parameters
=
find_unused_parameters
)
# build runner
optimizer
=
build_optimizer
(
model
,
cfg
.
optimizer
)
runner
=
Runner
(
model
,
batch_processor
,
optimizer
,
cfg
.
work_dir
,
logger
=
logger
,
meta
=
meta
)
# an ugly walkaround to make the .log and .log.json filenames the same
runner
.
timestamp
=
timestamp
# fp16 setting
fp16_cfg
=
cfg
.
get
(
'fp16'
,
None
)
if
fp16_cfg
is
not
None
:
optimizer_config
=
Fp16OptimizerHook
(
**
cfg
.
optimizer_config
,
**
fp16_cfg
)
else
:
optimizer_config
=
DistOptimizerHook
(
**
cfg
.
optimizer_config
)
# register hooks
runner
.
register_training_hooks
(
cfg
.
lr_config
,
optimizer_config
,
cfg
.
checkpoint_config
,
cfg
.
log_config
)
runner
.
register_hook
(
DistSamplerSeedHook
())
# register eval hooks
if
validate
:
val_dataset
=
build_dataset
(
cfg
.
data
.
val
,
dict
(
test_mode
=
True
))
val_dataloader
=
build_dataloader
(
val_dataset
,
samples_per_gpu
=
1
,
workers_per_gpu
=
cfg
.
data
.
workers_per_gpu
,
dist
=
True
,
shuffle
=
False
)
eval_cfg
=
cfg
.
get
(
'evaluation'
,
{})
runner
.
register_hook
(
DistEvalHook
(
val_dataloader
,
**
eval_cfg
))
if
cfg
.
resume_from
:
runner
.
resume
(
cfg
.
resume_from
)
elif
cfg
.
load_from
:
runner
.
load_checkpoint
(
cfg
.
load_from
)
runner
.
run
(
data_loaders
,
cfg
.
workflow
,
cfg
.
total_epochs
)
def
_non_dist_train
(
model
,
dataset
,
cfg
,
validate
=
False
,
logger
=
None
,
timestamp
=
None
,
meta
=
None
):
# prepare data loaders
dataset
=
dataset
if
isinstance
(
dataset
,
(
list
,
tuple
))
else
[
dataset
]
data_loaders
=
[
build_dataloader
(
ds
,
cfg
.
data
.
samples_per_gpu
,
cfg
.
data
.
workers_per_gpu
,
cfg
.
gpus
,
dist
=
False
,
seed
=
cfg
.
seed
)
for
ds
in
dataset
]
# put model on gpus
model
=
MMDataParallel
(
model
,
device_ids
=
range
(
cfg
.
gpus
)).
cuda
()
# build runner
optimizer
=
build_optimizer
(
model
,
cfg
.
optimizer
)
runner
=
Runner
(
model
,
batch_processor
,
optimizer
,
cfg
.
work_dir
,
logger
=
logger
,
meta
=
meta
)
# an ugly walkaround to make the .log and .log.json filenames the same
runner
.
timestamp
=
timestamp
# fp16 setting
fp16_cfg
=
cfg
.
get
(
'fp16'
,
None
)
if
fp16_cfg
is
not
None
:
optimizer_config
=
Fp16OptimizerHook
(
**
cfg
.
optimizer_config
,
**
fp16_cfg
,
distributed
=
False
)
else
:
optimizer_config
=
cfg
.
optimizer_config
runner
.
register_training_hooks
(
cfg
.
lr_config
,
optimizer_config
,
cfg
.
checkpoint_config
,
cfg
.
log_config
)
# register eval hooks
if
validate
:
val_dataset
=
build_dataset
(
cfg
.
data
.
val
,
dict
(
test_mode
=
True
))
val_dataloader
=
build_dataloader
(
val_dataset
,
samples_per_gpu
=
1
,
workers_per_gpu
=
cfg
.
data
.
workers_per_gpu
,
dist
=
False
,
shuffle
=
False
)
eval_cfg
=
cfg
.
get
(
'evaluation'
,
{})
runner
.
register_hook
(
EvalHook
(
val_dataloader
,
**
eval_cfg
))
if
cfg
.
resume_from
:
runner
.
resume
(
cfg
.
resume_from
)
elif
cfg
.
load_from
:
runner
.
load_checkpoint
(
cfg
.
load_from
)
runner
.
run
(
data_loaders
,
cfg
.
workflow
,
cfg
.
total_epochs
)
mmdet3d/core/anchor/__init__.py
View file @
6d71b439
from
.anchor_generator
import
(
AlignedAnchorGeneratorRange
,
AnchorGenerator
,
from
.anchor_
3d_
generator
import
(
AlignedAnchorGeneratorRange
,
AnchorGeneratorRange
)
__all__
=
[
'AnchorGenerator'
,
'AlignedAnchorGeneratorRange'
,
'AnchorGeneratorRange'
,
'AlignedAnchorGeneratorRange'
,
'AnchorGeneratorRange'
,
'build_anchor_generator'
]
def
build_anchor_generator
(
cfg
,
**
kwargs
):
from
.
import
anchor_generator
from
.
import
anchor_
3d_
generator
import
mmcv
if
isinstance
(
cfg
,
dict
):
return
mmcv
.
runner
.
obj_from_dict
(
cfg
,
anchor_generator
,
default_args
=
kwargs
)
cfg
,
anchor_
3d_
generator
,
default_args
=
kwargs
)
else
:
raise
TypeError
(
'Invalid type {} for building a sampler'
.
format
(
type
(
cfg
)))
mmdet3d/core/anchor/anchor_generator.py
→
mmdet3d/core/anchor/anchor_
3d_
generator.py
View file @
6d71b439
import
torch
class
AnchorGenerator
(
object
):
"""
Examples:
>>> from mmdet.core import AnchorGenerator
>>> self = AnchorGenerator(9, [1.], [1.])
>>> all_anchors = self.grid_anchors((2, 2), device='cpu')
>>> print(all_anchors)
tensor([[ 0., 0., 8., 8.],
[16., 0., 24., 8.],
[ 0., 16., 8., 24.],
[16., 16., 24., 24.]])
"""
def
__init__
(
self
,
base_size
,
scales
,
ratios
,
scale_major
=
True
,
ctr
=
None
):
self
.
base_size
=
base_size
self
.
scales
=
torch
.
Tensor
(
scales
)
self
.
ratios
=
torch
.
Tensor
(
ratios
)
self
.
scale_major
=
scale_major
self
.
ctr
=
ctr
self
.
base_anchors
=
self
.
gen_base_anchors
()
@
property
def
num_base_anchors
(
self
):
return
self
.
base_anchors
.
size
(
0
)
def
gen_base_anchors
(
self
):
w
=
self
.
base_size
h
=
self
.
base_size
h_ratios
=
torch
.
sqrt
(
self
.
ratios
)
w_ratios
=
1
/
h_ratios
if
self
.
scale_major
:
ws
=
(
w
*
w_ratios
[:,
None
]
*
self
.
scales
[
None
,
:]).
view
(
-
1
)
hs
=
(
h
*
h_ratios
[:,
None
]
*
self
.
scales
[
None
,
:]).
view
(
-
1
)
else
:
ws
=
(
w
*
self
.
scales
[:,
None
]
*
w_ratios
[
None
,
:]).
view
(
-
1
)
hs
=
(
h
*
self
.
scales
[:,
None
]
*
h_ratios
[
None
,
:]).
view
(
-
1
)
# yapf: disable
base_anchors
=
torch
.
stack
(
[
-
0.5
*
ws
,
-
0.5
*
hs
,
0.5
*
ws
,
0.5
*
hs
],
dim
=-
1
)
# yapf: enable
return
base_anchors
def
_meshgrid
(
self
,
x
,
y
,
row_major
=
True
):
xx
=
x
.
repeat
(
len
(
y
))
yy
=
y
.
view
(
-
1
,
1
).
repeat
(
1
,
len
(
x
)).
view
(
-
1
)
if
row_major
:
return
xx
,
yy
else
:
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)
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,
# then (0, 1), (0, 2), ...
return
all_anchors
def
valid_flags
(
self
,
featmap_size
,
valid_size
,
device
=
'cuda'
):
feat_h
,
feat_w
=
featmap_size
valid_h
,
valid_w
=
valid_size
assert
valid_h
<=
feat_h
and
valid_w
<=
feat_w
valid_x
=
torch
.
zeros
(
feat_w
,
dtype
=
torch
.
uint8
,
device
=
device
)
valid_y
=
torch
.
zeros
(
feat_h
,
dtype
=
torch
.
uint8
,
device
=
device
)
valid_x
[:
valid_w
]
=
1
valid_y
[:
valid_h
]
=
1
valid_xx
,
valid_yy
=
self
.
_meshgrid
(
valid_x
,
valid_y
)
valid
=
valid_xx
&
valid_yy
valid
=
valid
[:,
None
].
expand
(
valid
.
size
(
0
),
self
.
num_base_anchors
).
contiguous
().
view
(
-
1
).
bool
()
return
valid
class
AnchorGeneratorRange
(
object
):
def
__init__
(
self
,
...
...
mmdet3d/core/bbox/__init__.py
View file @
6d71b439
from
.
import
box_torch_ops
from
.assigners
import
AssignResult
,
BaseAssigner
,
MaxIoUAssigner
from
.coders
import
ResidualCoder
from
.coders
import
Residual
3DBox
Coder
# from .bbox_target import bbox_target
from
.iou_calculators
import
(
BboxOverlaps3D
,
BboxOverlapsNearest3D
,
bbox_overlaps_3d
,
bbox_overlaps_nearest_3d
)
from
.samplers
import
(
BaseSampler
,
CombinedSampler
,
InstanceBalancedPosSampler
,
IoUBalancedNegSampler
,
PseudoSampler
,
RandomSampler
,
SamplingResult
)
from
.transforms
import
delta2bbox
# bbox2result_kitti,
from
.transforms
import
(
bbox2delta
,
bbox2result_coco
,
bbox2roi
,
bbox_flip
,
bbox_mapping
,
bbox_mapping_back
,
boxes3d_to_bev_torch_lidar
,
distance2bbox
,
roi2bbox
)
from
.transforms
import
boxes3d_to_bev_torch_lidar
from
.assign_sampling
import
(
# isort:skip, avoid recursive imports
build_bbox_coder
,
# temporally settings
...
...
@@ -19,10 +16,9 @@ from .assign_sampling import ( # isort:skip, avoid recursive imports
__all__
=
[
'BaseAssigner'
,
'MaxIoUAssigner'
,
'AssignResult'
,
'BaseSampler'
,
'PseudoSampler'
,
'RandomSampler'
,
'InstanceBalancedPosSampler'
,
'IoUBalancedNegSampler'
,
'CombinedSampler'
,
'SamplingResult'
,
'bbox2delta'
,
'delta2bbox'
,
'bbox_flip'
,
'bbox_mapping'
,
'bbox_mapping_back'
,
'bbox2roi'
,
'roi2bbox'
,
'bbox2result_coco'
,
'distance2bbox'
,
'build_assigner'
,
'build_sampler'
,
'assign_and_sample'
,
'box_torch_ops'
,
'build_bbox_coder'
,
'ResidualCoder'
,
'boxes3d_to_bev_torch_lidar'
,
'BboxOverlapsNearest3D'
,
'BboxOverlaps3D'
,
'bbox_overlaps_nearest_3d'
,
'bbox_overlaps_3d'
'IoUBalancedNegSampler'
,
'CombinedSampler'
,
'SamplingResult'
,
'build_assigner'
,
'build_sampler'
,
'assign_and_sample'
,
'box_torch_ops'
,
'build_bbox_coder'
,
'Residual3DBoxCoder'
,
'boxes3d_to_bev_torch_lidar'
,
'BboxOverlapsNearest3D'
,
'BboxOverlaps3D'
,
'bbox_overlaps_nearest_3d'
,
'bbox_overlaps_3d'
]
mmdet3d/core/bbox/assign_sampling.py
View file @
6d71b439
...
...
@@ -14,7 +14,7 @@ def build_assigner(cfg, **kwargs):
def
build_bbox_coder
(
cfg
,
**
kwargs
):
if
isinstance
(
cfg
,
coders
.
ResidualCoder
):
if
isinstance
(
cfg
,
coders
.
Residual
3DBox
Coder
):
return
cfg
elif
isinstance
(
cfg
,
dict
):
return
mmcv
.
runner
.
obj_from_dict
(
cfg
,
coders
,
default_args
=
kwargs
)
...
...
mmdet3d/core/bbox/coders/__init__.py
View file @
6d71b439
from
.box_coder
import
ResidualCoder
from
.box_coder
import
Residual
3DBox
Coder
__all__
=
[
'ResidualCoder'
]
__all__
=
[
'Residual
3DBox
Coder'
]
mmdet3d/core/bbox/coders/box_coder.py
View file @
6d71b439
...
...
@@ -2,7 +2,7 @@ import numpy as np
import
torch
class
ResidualCoder
(
object
):
class
Residual
3DBox
Coder
(
object
):
def
__init__
(
self
,
code_size
=
7
,
mean
=
None
,
std
=
None
):
super
().
__init__
()
...
...
mmdet3d/core/bbox/samplers/__init__.py
View file @
6d71b439
from
.base_sampler
import
BaseSampler
from
.combined_sampler
import
CombinedSampler
from
.instance_balanced_pos_sampler
import
InstanceBalancedPosSampler
from
.iou_balanced_neg_sampler
import
IoUBalancedNegSampler
from
.ohem_sampler
import
OHEMSampler
from
.pseudo_sampler
import
PseudoSampler
from
.random_sampler
import
RandomSampler
from
.sampling_result
import
SamplingResult
from
mmdet.core.bbox.samplers
import
(
BaseSampler
,
CombinedSampler
,
InstanceBalancedPosSampler
,
IoUBalancedNegSampler
,
OHEMSampler
,
PseudoSampler
,
RandomSampler
,
SamplingResult
)
__all__
=
[
'BaseSampler'
,
'PseudoSampler'
,
'RandomSampler'
,
...
...
mmdet3d/core/bbox/samplers/base_sampler.py
deleted
100644 → 0
View file @
ba492be7
from
abc
import
ABCMeta
,
abstractmethod
import
torch
from
.sampling_result
import
SamplingResult
class
BaseSampler
(
metaclass
=
ABCMeta
):
def
__init__
(
self
,
num
,
pos_fraction
,
neg_pos_ub
=-
1
,
add_gt_as_proposals
=
True
,
**
kwargs
):
self
.
num
=
num
self
.
pos_fraction
=
pos_fraction
self
.
neg_pos_ub
=
neg_pos_ub
self
.
add_gt_as_proposals
=
add_gt_as_proposals
self
.
pos_sampler
=
self
self
.
neg_sampler
=
self
@
abstractmethod
def
_sample_pos
(
self
,
assign_result
,
num_expected
,
**
kwargs
):
pass
@
abstractmethod
def
_sample_neg
(
self
,
assign_result
,
num_expected
,
**
kwargs
):
pass
def
sample
(
self
,
assign_result
,
bboxes
,
gt_bboxes
,
gt_labels
=
None
,
**
kwargs
):
"""Sample positive and negative bboxes.
This is a simple implementation of bbox sampling given candidates,
assigning results and ground truth bboxes.
Args:
assign_result (:obj:`AssignResult`): Bbox assigning results.
bboxes (Tensor): Boxes to be sampled from.
gt_bboxes (Tensor): Ground truth bboxes.
gt_labels (Tensor, optional): Class labels of ground truth bboxes.
Returns:
:obj:`SamplingResult`: Sampling result.
"""
bboxes
=
bboxes
[:,
:
4
]
gt_flags
=
bboxes
.
new_zeros
((
bboxes
.
shape
[
0
],
),
dtype
=
torch
.
uint8
)
if
self
.
add_gt_as_proposals
:
bboxes
=
torch
.
cat
([
gt_bboxes
,
bboxes
],
dim
=
0
)
assign_result
.
add_gt_
(
gt_labels
)
gt_ones
=
bboxes
.
new_ones
(
gt_bboxes
.
shape
[
0
],
dtype
=
torch
.
uint8
)
gt_flags
=
torch
.
cat
([
gt_ones
,
gt_flags
])
num_expected_pos
=
int
(
self
.
num
*
self
.
pos_fraction
)
pos_inds
=
self
.
pos_sampler
.
_sample_pos
(
assign_result
,
num_expected_pos
,
bboxes
=
bboxes
,
**
kwargs
)
# We found that sampled indices have duplicated items occasionally.
# (may be a bug of PyTorch)
pos_inds
=
pos_inds
.
unique
()
num_sampled_pos
=
pos_inds
.
numel
()
num_expected_neg
=
self
.
num
-
num_sampled_pos
if
self
.
neg_pos_ub
>=
0
:
_pos
=
max
(
1
,
num_sampled_pos
)
neg_upper_bound
=
int
(
self
.
neg_pos_ub
*
_pos
)
if
num_expected_neg
>
neg_upper_bound
:
num_expected_neg
=
neg_upper_bound
neg_inds
=
self
.
neg_sampler
.
_sample_neg
(
assign_result
,
num_expected_neg
,
bboxes
=
bboxes
,
**
kwargs
)
neg_inds
=
neg_inds
.
unique
()
return
SamplingResult
(
pos_inds
,
neg_inds
,
bboxes
,
gt_bboxes
,
assign_result
,
gt_flags
)
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