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
5b42b739
Commit
5b42b739
authored
May 14, 2020
by
liyinhao
Browse files
Merge branch 'main_tmp' into indoor_pipeline
parents
fefbdd12
0df95010
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
137 additions
and
101 deletions
+137
-101
.gitlab-ci.yml
.gitlab-ci.yml
+2
-1
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
+2
-2
configs/kitti/dv_pointpillars_secfpn_6x8_160e_kitti-3d-car.py
...igs/kitti/dv_pointpillars_secfpn_6x8_160e_kitti-3d-car.py
+2
-2
configs/kitti/dv_second_secfpn_2x8_cosine_80e_kitti-3d-3class.py
.../kitti/dv_second_secfpn_2x8_cosine_80e_kitti-3d-3class.py
+2
-2
configs/kitti/dv_second_secfpn_6x8_80e_kitti-3d-car.py
configs/kitti/dv_second_secfpn_6x8_80e_kitti-3d-car.py
+2
-2
configs/kitti/hv_PartA2_secfpn_4x8_cosine_80e_kitti-3d-3class.py
.../kitti/hv_PartA2_secfpn_4x8_cosine_80e_kitti-3d-3class.py
+2
-2
configs/kitti/hv_pointpillars_secfpn_6x8_160e_kitti-3d-car.py
...igs/kitti/hv_pointpillars_secfpn_6x8_160e_kitti-3d-car.py
+2
-2
configs/kitti/hv_second_secfpn_6x8_80e_kitti-3d-car.py
configs/kitti/hv_second_secfpn_6x8_80e_kitti-3d-car.py
+2
-2
configs/nus/hv_pointpillars_secfpn_sbn-all_4x8_2x_nus-3d.py
configs/nus/hv_pointpillars_secfpn_sbn-all_4x8_2x_nus-3d.py
+2
-2
mmdet3d/models/backbones/second.py
mmdet3d/models/backbones/second.py
+32
-39
mmdet3d/models/necks/second_fpn.py
mmdet3d/models/necks/second_fpn.py
+48
-43
requirements/build.txt
requirements/build.txt
+1
-1
requirements/runtime.txt
requirements/runtime.txt
+1
-1
tests/test_fpn.py
tests/test_fpn.py
+37
-0
No files found.
.gitlab-ci.yml
View file @
5b42b739
...
...
@@ -16,7 +16,7 @@ before_script:
.linting_template
:
&linting_template_def
stage
:
linting
script
:
-
pip install flake8 yapf isort
-
pip install flake8
==3.7.9
yapf isort
-
flake8 .
-
isort -rc --check-only --diff mmdet3d/ tools/ tests/
-
yapf -r -d mmdet3d/ tools/ tests/ configs/
...
...
@@ -26,6 +26,7 @@ before_script:
script
:
-
echo "Start building..."
-
pip install "git+https://github.com/cocodataset/cocoapi.git#subdirectory=PythonAPI"
-
pip install git+https://github.com/open-mmlab/mmcv.git
-
pip install git+https://github.com/open-mmlab/mmdetection.git
-
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 @
5b42b739
...
...
@@ -57,13 +57,13 @@ model = dict(
in_channels
=
256
,
layer_nums
=
[
5
,
5
],
layer_strides
=
[
1
,
2
],
num_filter
s
=
[
128
,
256
],
out_channel
s
=
[
128
,
256
],
),
pts_neck
=
dict
(
type
=
'SECONDFPN'
,
in_channels
=
[
128
,
256
],
upsample_strides
=
[
1
,
2
],
num_upsample_filter
s
=
[
256
,
256
],
out_channel
s
=
[
256
,
256
],
),
pts_bbox_head
=
dict
(
type
=
'SECONDHead'
,
...
...
configs/kitti/dv_pointpillars_secfpn_6x8_160e_kitti-3d-car.py
View file @
5b42b739
...
...
@@ -28,13 +28,13 @@ model = dict(
in_channels
=
64
,
layer_nums
=
[
3
,
5
,
5
],
layer_strides
=
[
2
,
2
,
2
],
num_filter
s
=
[
64
,
128
,
256
],
out_channel
s
=
[
64
,
128
,
256
],
),
neck
=
dict
(
type
=
'SECONDFPN'
,
in_channels
=
[
64
,
128
,
256
],
upsample_strides
=
[
1
,
2
,
4
],
num_upsample_filter
s
=
[
128
,
128
,
128
],
out_channel
s
=
[
128
,
128
,
128
],
),
bbox_head
=
dict
(
type
=
'SECONDHead'
,
...
...
configs/kitti/dv_second_secfpn_2x8_cosine_80e_kitti-3d-3class.py
View file @
5b42b739
...
...
@@ -26,13 +26,13 @@ model = dict(
in_channels
=
256
,
layer_nums
=
[
5
,
5
],
layer_strides
=
[
1
,
2
],
num_filter
s
=
[
128
,
256
],
out_channel
s
=
[
128
,
256
],
),
neck
=
dict
(
type
=
'SECONDFPN'
,
in_channels
=
[
128
,
256
],
upsample_strides
=
[
1
,
2
],
num_upsample_filter
s
=
[
256
,
256
],
out_channel
s
=
[
256
,
256
],
),
bbox_head
=
dict
(
type
=
'SECONDHead'
,
...
...
configs/kitti/dv_second_secfpn_6x8_80e_kitti-3d-car.py
View file @
5b42b739
...
...
@@ -26,13 +26,13 @@ model = dict(
in_channels
=
256
,
layer_nums
=
[
5
,
5
],
layer_strides
=
[
1
,
2
],
num_filter
s
=
[
128
,
256
],
out_channel
s
=
[
128
,
256
],
),
neck
=
dict
(
type
=
'SECONDFPN'
,
in_channels
=
[
128
,
256
],
upsample_strides
=
[
1
,
2
],
num_upsample_filter
s
=
[
256
,
256
],
out_channel
s
=
[
256
,
256
],
),
bbox_head
=
dict
(
type
=
'SECONDHead'
,
...
...
configs/kitti/hv_PartA2_secfpn_4x8_cosine_80e_kitti-3d-3class.py
View file @
5b42b739
...
...
@@ -22,12 +22,12 @@ model = dict(
in_channels
=
256
,
layer_nums
=
[
5
,
5
],
layer_strides
=
[
1
,
2
],
num_filter
s
=
[
128
,
256
]),
out_channel
s
=
[
128
,
256
]),
neck
=
dict
(
type
=
'SECONDFPN'
,
in_channels
=
[
128
,
256
],
upsample_strides
=
[
1
,
2
],
num_upsample_filter
s
=
[
256
,
256
]),
out_channel
s
=
[
256
,
256
]),
rpn_head
=
dict
(
type
=
'PartA2RPNHead'
,
class_name
=
[
'Pedestrian'
,
'Cyclist'
,
'Car'
],
...
...
configs/kitti/hv_pointpillars_secfpn_6x8_160e_kitti-3d-car.py
View file @
5b42b739
...
...
@@ -27,13 +27,13 @@ model = dict(
in_channels
=
64
,
layer_nums
=
[
3
,
5
,
5
],
layer_strides
=
[
2
,
2
,
2
],
num_filter
s
=
[
64
,
128
,
256
],
out_channel
s
=
[
64
,
128
,
256
],
),
neck
=
dict
(
type
=
'SECONDFPN'
,
in_channels
=
[
64
,
128
,
256
],
upsample_strides
=
[
1
,
2
,
4
],
num_upsample_filter
s
=
[
128
,
128
,
128
],
out_channel
s
=
[
128
,
128
,
128
],
),
bbox_head
=
dict
(
type
=
'SECONDHead'
,
...
...
configs/kitti/hv_second_secfpn_6x8_80e_kitti-3d-car.py
View file @
5b42b739
...
...
@@ -26,13 +26,13 @@ model = dict(
in_channels
=
256
,
layer_nums
=
[
5
,
5
],
layer_strides
=
[
1
,
2
],
num_filter
s
=
[
128
,
256
],
out_channel
s
=
[
128
,
256
],
),
neck
=
dict
(
type
=
'SECONDFPN'
,
in_channels
=
[
128
,
256
],
upsample_strides
=
[
1
,
2
],
num_upsample_filter
s
=
[
256
,
256
],
out_channel
s
=
[
256
,
256
],
),
bbox_head
=
dict
(
type
=
'SECONDHead'
,
...
...
configs/nus/hv_pointpillars_secfpn_sbn-all_4x8_2x_nus-3d.py
View file @
5b42b739
...
...
@@ -34,14 +34,14 @@ model = dict(
norm_cfg
=
dict
(
type
=
'naiveSyncBN2d'
,
eps
=
1e-3
,
momentum
=
0.01
),
layer_nums
=
[
3
,
5
,
5
],
layer_strides
=
[
2
,
2
,
2
],
num_filter
s
=
[
64
,
128
,
256
],
out_channel
s
=
[
64
,
128
,
256
],
),
pts_neck
=
dict
(
type
=
'SECONDFPN'
,
norm_cfg
=
dict
(
type
=
'naiveSyncBN2d'
,
eps
=
1e-3
,
momentum
=
0.01
),
in_channels
=
[
64
,
128
,
256
],
upsample_strides
=
[
1
,
2
,
4
],
num_upsample_filter
s
=
[
128
,
128
,
128
],
out_channel
s
=
[
128
,
128
,
128
],
),
pts_bbox_head
=
dict
(
type
=
'Anchor3DVeloHead'
,
...
...
mmdet3d/models/backbones/second.py
View file @
5b42b739
from
functools
import
partial
import
torch.nn
as
nn
from
mmcv.cnn
import
build_norm_layer
from
mmcv.cnn
import
build_conv_layer
,
build_norm_layer
from
mmcv.runner
import
load_checkpoint
from
mmdet.models
import
BACKBONES
class
Empty
(
nn
.
Module
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
Empty
,
self
).
__init__
()
def
forward
(
self
,
*
args
,
**
kwargs
):
if
len
(
args
)
==
1
:
return
args
[
0
]
elif
len
(
args
)
==
0
:
return
None
return
args
@
BACKBONES
.
register_module
()
class
SECOND
(
nn
.
Module
):
"""Compare with RPN, RPNV2 support arbitrary number of stage.
"""Backbone network for SECOND/PointPillars/PartA2/MVXNet
Args:
in_channels (int): Input channels
out_channels (list[int]): Output channels for multi-scale feature maps
layer_nums (list[int]): Number of layers in each stage
layer_strides (list[int]): Strides of each stage
norm_cfg (dict): Config dict of normalization layers
conv_cfg (dict): Config dict of convolutional layers
"""
def
__init__
(
self
,
in_channels
=
128
,
out_channels
=
[
128
,
128
,
256
],
layer_nums
=
[
3
,
5
,
5
],
layer_strides
=
[
2
,
2
,
2
],
n
um_filters
=
[
128
,
128
,
256
]
,
norm
_cfg
=
dict
(
type
=
'
BN'
,
eps
=
1e-3
,
momentum
=
0.01
)):
n
orm_cfg
=
dict
(
type
=
'BN'
,
eps
=
1e-3
,
momentum
=
0.01
)
,
conv
_cfg
=
dict
(
type
=
'
Conv2d'
,
bias
=
False
)):
super
(
SECOND
,
self
).
__init__
()
assert
len
(
layer_strides
)
==
len
(
layer_nums
)
assert
len
(
num_filters
)
==
len
(
layer_nums
)
if
norm_cfg
is
not
None
:
Conv2d
=
partial
(
nn
.
Conv2d
,
bias
=
False
)
else
:
Conv2d
=
partial
(
nn
.
Conv2d
,
bias
=
True
)
assert
len
(
out_channels
)
==
len
(
layer_nums
)
in_filters
=
[
in_channels
,
*
num_filter
s
[:
-
1
]]
in_filters
=
[
in_channels
,
*
out_channel
s
[:
-
1
]]
# note that when stride > 1, conv2d with same padding isn't
# equal to pad-conv2d. we should use pad-conv2d.
blocks
=
[]
for
i
,
layer_num
in
enumerate
(
layer_nums
):
norm_layer
=
(
build_norm_layer
(
norm_cfg
,
num_filters
[
i
])[
1
]
if
norm_cfg
is
not
None
else
Empty
)
block
=
[
nn
.
ZeroPad2d
(
1
),
Conv2d
(
in_filters
[
i
],
num_filters
[
i
],
3
,
stride
=
layer_strides
[
i
]),
norm_layer
,
build_conv_layer
(
conv_cfg
,
in_filters
[
i
],
out_channels
[
i
],
3
,
stride
=
layer_strides
[
i
],
padding
=
1
),
build_norm_layer
(
norm_cfg
,
out_channels
[
i
])[
1
],
nn
.
ReLU
(
inplace
=
True
),
]
for
j
in
range
(
layer_num
):
norm_layer
=
(
build_norm_layer
(
norm_cfg
,
num_filters
[
i
])[
1
]
if
norm_cfg
is
not
None
else
Empty
)
block
.
append
(
Conv2d
(
num_filters
[
i
],
num_filters
[
i
],
3
,
padding
=
1
))
block
.
append
(
norm_layer
)
build_conv_layer
(
conv_cfg
,
out_channels
[
i
],
out_channels
[
i
],
3
,
padding
=
1
))
block
.
append
(
build_norm_layer
(
norm_cfg
,
out_channels
[
i
])[
1
])
block
.
append
(
nn
.
ReLU
(
inplace
=
True
))
block
=
nn
.
Sequential
(
*
block
)
...
...
@@ -71,6 +62,8 @@ class SECOND(nn.Module):
self
.
blocks
=
nn
.
ModuleList
(
blocks
)
def
init_weights
(
self
,
pretrained
=
None
):
# Do not initialize the conv layers
# to follow the original implementation
if
isinstance
(
pretrained
,
str
):
from
mmdet3d.utils
import
get_root_logger
logger
=
get_root_logger
()
...
...
mmdet3d/models/necks/second_fpn.py
View file @
5b42b739
from
functools
import
partial
import
torch
import
torch.nn
as
nn
from
mmcv.cnn
import
build_norm_layer
,
constant_init
,
kaiming_init
from
torch.nn
import
Sequential
from
torch.nn.modules.batchnorm
import
_BatchNorm
from
mmcv.cnn
import
(
build_norm_layer
,
build_upsample_layer
,
constant_init
,
is_norm
,
kaiming_init
)
from
mmdet.models
import
NECKS
from
..
import
builder
...
...
@@ -12,36 +9,40 @@ from .. import builder
@
NECKS
.
register_module
()
class
SECONDFPN
(
nn
.
Module
):
"""Compare with RPN, RPNV2 support arbitrary number of stage.
"""FPN used in SECOND/PointPillars/PartA2/MVXNet
Args:
in_channels (list[int]): Input channels of multi-scale feature maps
out_channels (list[int]): Output channels of feature maps
upsample_strides (list[int]): Strides used to upsample the feature maps
norm_cfg (dict): Config dict of normalization layers
upsample_cfg (dict): Config dict of upsample layers
"""
def
__init__
(
self
,
use_norm
=
True
,
in_channels
=
[
128
,
128
,
256
],
out_channels
=
[
256
,
256
,
256
],
upsample_strides
=
[
1
,
2
,
4
],
n
um_upsample_filters
=
[
256
,
256
,
256
]
,
norm
_cfg
=
dict
(
type
=
'
BN'
,
eps
=
1e-3
,
momentum
=
0.01
)):
n
orm_cfg
=
dict
(
type
=
'BN'
,
eps
=
1e-3
,
momentum
=
0.01
)
,
upsample
_cfg
=
dict
(
type
=
'
deconv'
,
bias
=
False
)):
# if for GroupNorm,
# cfg is dict(type='GN', num_groups=num_groups, eps=1e-3, affine=True)
super
(
SECONDFPN
,
self
).
__init__
()
assert
len
(
num_upsample_filter
s
)
==
len
(
upsample_strides
)
assert
len
(
out_channel
s
)
==
len
(
upsample_strides
)
==
len
(
in_channels
)
self
.
in_channels
=
in_channels
ConvTranspose2d
=
partial
(
nn
.
ConvTranspose2d
,
bias
=
False
)
self
.
out_channels
=
out_channels
deblocks
=
[]
for
i
,
num_upsample_filter
in
enumerate
(
num_upsample_filters
):
norm_layer
=
build_norm_layer
(
norm_cfg
,
num_upsample_filter
)[
1
]
deblock
=
Sequential
(
ConvTranspose2d
(
in_channels
[
i
],
num_upsample_filter
,
upsample_strides
[
i
],
stride
=
upsample_strides
[
i
]),
norm_layer
,
nn
.
ReLU
(
inplace
=
True
),
)
for
i
,
out_channel
in
enumerate
(
out_channels
):
upsample_layer
=
build_upsample_layer
(
upsample_cfg
,
in_channels
=
in_channels
[
i
],
out_channels
=
out_channel
,
kernel_size
=
upsample_strides
[
i
],
stride
=
upsample_strides
[
i
])
deblock
=
nn
.
Sequential
(
upsample_layer
,
build_norm_layer
(
norm_cfg
,
out_channel
)[
1
],
nn
.
ReLU
(
inplace
=
True
))
deblocks
.
append
(
deblock
)
self
.
deblocks
=
nn
.
ModuleList
(
deblocks
)
...
...
@@ -49,7 +50,7 @@ class SECONDFPN(nn.Module):
for
m
in
self
.
modules
():
if
isinstance
(
m
,
nn
.
Conv2d
):
kaiming_init
(
m
)
elif
is
instance
(
m
,
(
_BatchNorm
,
nn
.
GroupNorm
)
):
elif
is
_norm
(
m
):
constant_init
(
m
,
1
)
def
forward
(
self
,
x
):
...
...
@@ -65,30 +66,34 @@ class SECONDFPN(nn.Module):
@
NECKS
.
register_module
()
class
SECONDFusionFPN
(
SECONDFPN
):
"""Compare with RPN, RPNV2 support arbitrary number of stage.
"""FPN used in multi-modality SECOND/PointPillars
Args:
in_channels (list[int]): Input channels of multi-scale feature maps
out_channels (list[int]): Output channels of feature maps
upsample_strides (list[int]): Strides used to upsample the feature maps
norm_cfg (dict): Config dict of normalization layers
upsample_cfg (dict): Config dict of upsample layers
downsample_rates (list[int]): The downsample rate of feature map in
comparison to the original voxelization input
fusion_layer (dict): Config dict of fusion layers
"""
def
__init__
(
self
,
use_norm
=
True
,
in_channels
=
[
128
,
128
,
256
],
out_channels
=
[
256
,
256
,
256
],
upsample_strides
=
[
1
,
2
,
4
],
num_upsample_filters
=
[
256
,
256
,
256
],
norm_cfg
=
dict
(
type
=
'BN'
,
eps
=
1e-3
,
momentum
=
0.01
),
down_sample_rate
=
[
40
,
8
,
8
],
fusion_layer
=
None
,
cat_points
=
False
):
super
(
SECONDFusionFPN
,
self
).
__init__
(
use_norm
,
in_channels
,
upsample_strides
,
num_upsample_filters
,
norm_cfg
,
)
upsample_cfg
=
dict
(
type
=
'deconv'
,
bias
=
False
),
downsample_rates
=
[
40
,
8
,
8
],
fusion_layer
=
None
):
super
(
SECONDFusionFPN
,
self
).
__init__
(
in_channels
,
out_channels
,
upsample_strides
,
norm_cfg
,
upsample_cfg
)
self
.
fusion_layer
=
None
if
fusion_layer
is
not
None
:
self
.
fusion_layer
=
builder
.
build_fusion_layer
(
fusion_layer
)
self
.
cat_points
=
cat_points
self
.
down_sample_rate
=
down_sample_rate
self
.
downsample_rates
=
downsample_rates
def
forward
(
self
,
x
,
...
...
@@ -107,11 +112,11 @@ class SECONDFusionFPN(SECONDFPN):
downsample_pts_coors
=
torch
.
zeros_like
(
coors
)
downsample_pts_coors
[:,
0
]
=
coors
[:,
0
]
downsample_pts_coors
[:,
1
]
=
(
coors
[:,
1
]
/
self
.
down
_
sample_rate
[
0
])
coors
[:,
1
]
/
self
.
downsample_rate
s
[
0
])
downsample_pts_coors
[:,
2
]
=
(
coors
[:,
2
]
/
self
.
down
_
sample_rate
[
1
])
coors
[:,
2
]
/
self
.
downsample_rate
s
[
1
])
downsample_pts_coors
[:,
3
]
=
(
coors
[:,
3
]
/
self
.
down
_
sample_rate
[
2
])
coors
[:,
3
]
/
self
.
downsample_rate
s
[
2
])
# fusion for each point
out
=
self
.
fusion_layer
(
img_feats
,
points
,
out
,
downsample_pts_coors
,
img_meta
)
...
...
requirements/build.txt
View file @
5b42b739
# These must be installed before building mmdetection
numpy
torch>=1.
1
torch>=1.
3
requirements/runtime.txt
View file @
5b42b739
matplotlib
mmcv>=0.5.
0
mmcv>=0.5.
1
numba==0.45.1
numpy
# need older pillow until torchvision is fixed
...
...
tests/test_fpn.py
0 → 100644
View file @
5b42b739
import
pytest
def
test_secfpn
():
neck_cfg
=
dict
(
type
=
'SECONDFPN'
,
in_channels
=
[
2
,
3
],
upsample_strides
=
[
1
,
2
],
out_channels
=
[
4
,
6
],
)
from
mmdet.models.builder
import
build_neck
neck
=
build_neck
(
neck_cfg
)
assert
neck
.
deblocks
[
0
][
0
].
in_channels
==
2
assert
neck
.
deblocks
[
1
][
0
].
in_channels
==
3
assert
neck
.
deblocks
[
0
][
0
].
out_channels
==
4
assert
neck
.
deblocks
[
1
][
0
].
out_channels
==
6
assert
neck
.
deblocks
[
0
][
0
].
stride
==
(
1
,
1
)
assert
neck
.
deblocks
[
1
][
0
].
stride
==
(
2
,
2
)
assert
neck
is
not
None
neck_cfg
=
dict
(
type
=
'SECONDFPN'
,
in_channels
=
[
2
,
2
],
upsample_strides
=
[
1
,
2
,
4
],
out_channels
=
[
2
,
2
],
)
with
pytest
.
raises
(
AssertionError
):
build_neck
(
neck_cfg
)
neck_cfg
=
dict
(
type
=
'SECONDFPN'
,
in_channels
=
[
2
,
2
,
4
],
upsample_strides
=
[
1
,
2
,
4
],
out_channels
=
[
2
,
2
],
)
with
pytest
.
raises
(
AssertionError
):
build_neck
(
neck_cfg
)
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