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
OpenPCDet
Commits
09b289ea
Commit
09b289ea
authored
Jun 24, 2020
by
Gus-Guo
Browse files
support pointpillar
parent
2fa93c69
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
196 additions
and
8 deletions
+196
-8
pcdet/models/backbones_2d/map_to_bev/__init__.py
pcdet/models/backbones_2d/map_to_bev/__init__.py
+3
-2
pcdet/models/backbones_2d/map_to_bev/height_compression.py
pcdet/models/backbones_2d/map_to_bev/height_compression.py
+1
-1
pcdet/models/backbones_2d/map_to_bev/pointpillar_scatter.py
pcdet/models/backbones_2d/map_to_bev/pointpillar_scatter.py
+37
-0
pcdet/models/backbones_3d/vfe/__init__.py
pcdet/models/backbones_3d/vfe/__init__.py
+3
-1
pcdet/models/backbones_3d/vfe/pillar_vfe.py
pcdet/models/backbones_3d/vfe/pillar_vfe.py
+110
-0
pcdet/models/detectors/__init__.py
pcdet/models/detectors/__init__.py
+3
-2
pcdet/models/detectors/detector3d_template.py
pcdet/models/detectors/detector3d_template.py
+5
-2
pcdet/models/detectors/pointpillar.py
pcdet/models/detectors/pointpillar.py
+34
-0
No files found.
pcdet/models/backbones_2d/map_to_bev/__init__.py
View file @
09b289ea
from
.height_compression
import
HeightCompression
from
.height_compression
import
HeightCompression
from
.pointpillar_scatter
import
PointPillarScatter
__all__
=
{
__all__
=
{
'HeightCompression'
:
HeightCompression
'HeightCompression'
:
HeightCompression
,
'PointPillarScatter'
:
PointPillarScatter
}
}
pcdet/models/backbones_2d/map_to_bev/height_compression.py
View file @
09b289ea
...
@@ -2,7 +2,7 @@ import torch.nn as nn
...
@@ -2,7 +2,7 @@ import torch.nn as nn
class
HeightCompression
(
nn
.
Module
):
class
HeightCompression
(
nn
.
Module
):
def
__init__
(
self
,
model_cfg
):
def
__init__
(
self
,
model_cfg
,
**
kwargs
):
super
().
__init__
()
super
().
__init__
()
self
.
model_cfg
=
model_cfg
self
.
model_cfg
=
model_cfg
self
.
num_bev_features
=
self
.
model_cfg
.
NUM_BEV_FEATURES
self
.
num_bev_features
=
self
.
model_cfg
.
NUM_BEV_FEATURES
...
...
pcdet/models/backbones_2d/map_to_bev/pointpillar_scatter.py
0 → 100644
View file @
09b289ea
import
torch
import
torch.nn
as
nn
class
PointPillarScatter
(
nn
.
Module
):
def
__init__
(
self
,
model_cfg
,
grid_size
,
**
kwargs
):
super
().
__init__
()
self
.
model_cfg
=
model_cfg
self
.
num_bev_features
=
self
.
model_cfg
.
NUM_BEV_FEATURES
self
.
nx
,
self
.
ny
,
self
.
nz
=
grid_size
assert
self
.
nz
==
1
def
forward
(
self
,
batch_dict
,
**
kwargs
):
pillar_features
,
coords
=
batch_dict
[
'pillar_features'
],
batch_dict
[
'voxel_coords'
]
batch_spatial_features
=
[]
batch_size
=
coords
[:,
0
].
max
().
int
().
item
()
+
1
for
batch_idx
in
range
(
batch_size
):
spatial_feature
=
torch
.
zeros
(
self
.
num_bev_features
,
self
.
nz
*
self
.
nx
*
self
.
ny
,
dtype
=
pillar_features
.
dtype
,
device
=
pillar_features
.
device
)
batch_mask
=
coords
[:,
0
]
==
batch_idx
this_coords
=
coords
[
batch_mask
,
:]
indices
=
this_coords
[:,
1
]
+
this_coords
[:,
2
]
*
self
.
nx
+
this_coords
[:,
3
]
indices
=
indices
.
type
(
torch
.
long
)
pillars
=
pillar_features
[
batch_mask
,
:]
pillars
=
pillars
.
t
()
spatial_feature
[:,
indices
]
=
pillars
batch_spatial_features
.
append
(
spatial_feature
)
batch_spatial_features
=
torch
.
stack
(
batch_spatial_features
,
0
)
batch_spatial_features
=
batch_spatial_features
.
view
(
batch_size
,
self
.
num_bev_features
*
self
.
nz
,
self
.
ny
,
self
.
nx
)
batch_dict
[
'spatial_features'
]
=
batch_spatial_features
return
batch_dict
pcdet/models/backbones_3d/vfe/__init__.py
View file @
09b289ea
from
.vfe_template
import
VFETemplate
from
.vfe_template
import
VFETemplate
from
.mean_vfe
import
MeanVFE
from
.mean_vfe
import
MeanVFE
from
.pillar_vfe
import
PillarVFE
__all__
=
{
__all__
=
{
'VFETemplate'
:
VFETemplate
,
'VFETemplate'
:
VFETemplate
,
'MeanVFE'
:
MeanVFE
'MeanVFE'
:
MeanVFE
,
'PillarVFE'
:
PillarVFE
}
}
pcdet/models/backbones_3d/vfe/pillar_vfe.py
0 → 100644
View file @
09b289ea
import
torch
import
torch.nn
as
nn
import
torch.nn.functional
as
F
from
.vfe_template
import
VFETemplate
class
PFNLayer
(
nn
.
Module
):
def
__init__
(
self
,
in_channels
,
out_channels
,
use_norm
=
True
,
last_layer
=
False
):
super
().
__init__
()
self
.
last_vfe
=
last_layer
self
.
use_norm
=
use_norm
if
not
self
.
last_vfe
:
out_channels
=
out_channels
//
2
if
self
.
use_norm
:
self
.
linear
=
nn
.
Linear
(
in_channels
,
out_channels
,
bias
=
False
)
self
.
norm
=
nn
.
BatchNorm1d
(
out_channels
,
eps
=
1e-3
,
momentum
=
0.01
)
else
:
self
.
linear
=
nn
.
Linear
(
in_channels
,
out_channels
,
bias
=
True
)
def
forward
(
self
,
inputs
):
x
=
self
.
linear
(
inputs
)
total_points
,
voxel_points
,
channels
=
x
.
shape
x
=
self
.
norm
(
x
.
view
(
-
1
,
channels
)).
view
(
total_points
,
voxel_points
,
channels
)
if
self
.
use_norm
else
x
x
=
F
.
relu
(
x
)
x_max
=
torch
.
max
(
x
,
dim
=
1
,
keepdim
=
True
)[
0
]
if
self
.
last_vfe
:
return
x_max
else
:
x_repeat
=
x_max
.
repeat
(
1
,
inputs
.
shape
[
1
],
1
)
x_concatenated
=
torch
.
cat
([
x
,
x_repeat
],
dim
=
2
)
return
x_concatenated
class
PillarVFE
(
VFETemplate
):
def
__init__
(
self
,
model_cfg
,
num_point_features
,
voxel_size
,
point_cloud_range
):
super
().
__init__
(
model_cfg
=
model_cfg
)
self
.
use_norm
=
self
.
model_cfg
.
USE_NORM
self
.
with_distance
=
self
.
model_cfg
.
WITH_DISTANCE
self
.
use_absolute_xyz
=
self
.
model_cfg
.
USE_ABSLOTE_XYZ
num_point_features
+=
6
if
self
.
use_absolute_xyz
else
3
if
self
.
with_distance
:
num_point_features
+=
1
self
.
num_filters
=
self
.
model_cfg
.
NUM_FILTERS
assert
len
(
self
.
num_filters
)
>
0
num_filters
=
[
num_point_features
]
+
list
(
self
.
num_filters
)
pfn_layers
=
[]
for
i
in
range
(
len
(
num_filters
)
-
1
):
in_filters
=
num_filters
[
i
]
out_filters
=
num_filters
[
i
+
1
]
pfn_layers
.
append
(
PFNLayer
(
in_filters
,
out_filters
,
self
.
use_norm
,
last_layer
=
(
i
>=
len
(
num_filters
)
-
2
))
)
self
.
pfn_layers
=
nn
.
ModuleList
(
pfn_layers
)
self
.
voxel_x
=
voxel_size
[
0
]
self
.
voxel_y
=
voxel_size
[
1
]
self
.
voxel_z
=
voxel_size
[
2
]
self
.
x_offset
=
self
.
voxel_x
/
2
+
point_cloud_range
[
0
]
self
.
y_offset
=
self
.
voxel_y
/
2
+
point_cloud_range
[
1
]
self
.
z_offset
=
self
.
voxel_z
/
2
+
point_cloud_range
[
2
]
def
get_output_feature_dim
(
self
):
return
self
.
num_filters
[
-
1
]
def
get_paddings_indicator
(
self
,
actual_num
,
max_num
,
axis
=
0
):
actual_num
=
torch
.
unsqueeze
(
actual_num
,
axis
+
1
)
max_num_shape
=
[
1
]
*
len
(
actual_num
.
shape
)
max_num_shape
[
axis
+
1
]
=
-
1
max_num
=
torch
.
arange
(
max_num
,
dtype
=
torch
.
int
,
device
=
actual_num
.
device
).
view
(
max_num_shape
)
paddings_indicator
=
actual_num
.
int
()
>
max_num
return
paddings_indicator
def
forward
(
self
,
batch_dict
,
**
kwargs
):
voxel_features
,
voxel_num_points
,
coords
=
batch_dict
[
'voxels'
],
batch_dict
[
'voxel_num_points'
],
batch_dict
[
'voxel_coords'
]
points_mean
=
voxel_features
[:,
:,
:
3
].
sum
(
dim
=
1
,
keepdim
=
True
)
/
voxel_num_points
.
type_as
(
voxel_features
).
view
(
-
1
,
1
,
1
)
f_cluster
=
voxel_features
[:,
:,
:
3
]
-
points_mean
f_center
=
torch
.
zeros_like
(
voxel_features
[:,
:,
:
3
])
f_center
[:,
:,
0
]
=
voxel_features
[:,
:,
0
]
-
(
coords
[:,
3
].
to
(
voxel_features
.
dtype
).
unsqueeze
(
1
)
*
self
.
voxel_x
+
self
.
x_offset
)
f_center
[:,
:,
1
]
=
voxel_features
[:,
:,
1
]
-
(
coords
[:,
2
].
to
(
voxel_features
.
dtype
).
unsqueeze
(
1
)
*
self
.
voxel_y
+
self
.
y_offset
)
f_center
[:,
:,
2
]
=
voxel_features
[:,
:,
2
]
-
(
coords
[:,
1
].
to
(
voxel_features
.
dtype
).
unsqueeze
(
1
)
*
self
.
voxel_z
+
self
.
z_offset
)
if
self
.
use_absolute_xyz
:
features
=
[
voxel_features
,
f_cluster
,
f_center
]
else
:
features
=
[
voxel_features
[...,
3
:],
f_cluster
,
f_center
]
if
self
.
with_distance
:
points_dist
=
torch
.
norm
(
voxel_features
[:,
:,
:
3
],
2
,
2
,
keepdim
=
True
)
features
.
append
(
points_dist
)
features
=
torch
.
cat
(
features
,
dim
=-
1
)
voxel_count
=
features
.
shape
[
1
]
mask
=
self
.
get_paddings_indicator
(
voxel_num_points
,
voxel_count
,
axis
=
0
)
mask
=
torch
.
unsqueeze
(
mask
,
-
1
).
type_as
(
voxel_features
)
features
*=
mask
for
pfn
in
self
.
pfn_layers
:
features
=
pfn
(
features
)
features
=
features
.
squeeze
()
batch_dict
[
'pillar_features'
]
=
features
return
batch_dict
pcdet/models/detectors/__init__.py
View file @
09b289ea
...
@@ -2,13 +2,14 @@ from .detector3d_template import Detector3DTemplate
...
@@ -2,13 +2,14 @@ from .detector3d_template import Detector3DTemplate
from
.second_net
import
SECONDNet
from
.second_net
import
SECONDNet
from
.PartA2_net
import
PartA2Net
from
.PartA2_net
import
PartA2Net
from
.pv_rcnn
import
PVRCNN
from
.pv_rcnn
import
PVRCNN
from
.pointpillar
import
PointPillar
__all__
=
{
__all__
=
{
'Detector3DTemplate'
:
Detector3DTemplate
,
'Detector3DTemplate'
:
Detector3DTemplate
,
'SECONDNet'
:
SECONDNet
,
'SECONDNet'
:
SECONDNet
,
'PartA2Net'
:
PartA2Net
,
'PartA2Net'
:
PartA2Net
,
'PVRCNN'
:
PVRCNN
'PVRCNN'
:
PVRCNN
,
'PointPillar'
:
PointPillar
}
}
...
...
pcdet/models/detectors/detector3d_template.py
View file @
09b289ea
...
@@ -49,7 +49,9 @@ class Detector3DTemplate(nn.Module):
...
@@ -49,7 +49,9 @@ class Detector3DTemplate(nn.Module):
vfe_module
=
vfe
.
__all__
[
self
.
model_cfg
.
VFE
.
NAME
](
vfe_module
=
vfe
.
__all__
[
self
.
model_cfg
.
VFE
.
NAME
](
model_cfg
=
self
.
model_cfg
.
VFE
,
model_cfg
=
self
.
model_cfg
.
VFE
,
num_point_features
=
model_info_dict
[
'num_rawpoint_features'
]
num_point_features
=
model_info_dict
[
'num_rawpoint_features'
],
point_cloud_range
=
model_info_dict
[
'point_cloud_range'
],
voxel_size
=
model_info_dict
[
'voxel_size'
]
)
)
model_info_dict
[
'num_point_features'
]
=
vfe_module
.
get_output_feature_dim
()
model_info_dict
[
'num_point_features'
]
=
vfe_module
.
get_output_feature_dim
()
model_info_dict
[
'module_list'
].
append
(
vfe_module
)
model_info_dict
[
'module_list'
].
append
(
vfe_module
)
...
@@ -75,7 +77,8 @@ class Detector3DTemplate(nn.Module):
...
@@ -75,7 +77,8 @@ class Detector3DTemplate(nn.Module):
return
None
,
model_info_dict
return
None
,
model_info_dict
map_to_bev_module
=
map_to_bev
.
__all__
[
self
.
model_cfg
.
MAP_TO_BEV
.
NAME
](
map_to_bev_module
=
map_to_bev
.
__all__
[
self
.
model_cfg
.
MAP_TO_BEV
.
NAME
](
model_cfg
=
self
.
model_cfg
.
MAP_TO_BEV
model_cfg
=
self
.
model_cfg
.
MAP_TO_BEV
,
grid_size
=
model_info_dict
[
'grid_size'
]
)
)
model_info_dict
[
'module_list'
].
append
(
map_to_bev_module
)
model_info_dict
[
'module_list'
].
append
(
map_to_bev_module
)
model_info_dict
[
'num_bev_features'
]
=
map_to_bev_module
.
num_bev_features
model_info_dict
[
'num_bev_features'
]
=
map_to_bev_module
.
num_bev_features
...
...
pcdet/models/detectors/pointpillar.py
0 → 100644
View file @
09b289ea
from
.detector3d_template
import
Detector3DTemplate
class
PointPillar
(
Detector3DTemplate
):
def
__init__
(
self
,
model_cfg
,
num_class
,
dataset
):
super
().
__init__
(
model_cfg
=
model_cfg
,
num_class
=
num_class
,
dataset
=
dataset
)
self
.
module_list
=
self
.
build_networks
()
def
forward
(
self
,
batch_dict
):
for
cur_module
in
self
.
module_list
:
batch_dict
=
cur_module
(
batch_dict
)
if
self
.
training
:
loss
,
tb_dict
,
disp_dict
=
self
.
get_training_loss
()
ret_dict
=
{
'loss'
:
loss
}
return
ret_dict
,
tb_dict
,
disp_dict
else
:
pred_dicts
,
recall_dicts
=
self
.
post_processing
(
batch_dict
)
return
pred_dicts
,
recall_dicts
def
get_training_loss
(
self
):
disp_dict
=
{}
loss_rpn
,
tb_dict
=
self
.
dense_head
.
get_loss
()
tb_dict
=
{
'loss_rpn'
:
loss_rpn
.
item
(),
**
tb_dict
}
loss
=
loss_rpn
return
loss
,
tb_dict
,
disp_dict
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