-
Notifications
You must be signed in to change notification settings - Fork 3
/
second_backbone.py
119 lines (105 loc) · 3.96 KB
/
second_backbone.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This code is based on https://github.com/open-mmlab/mmdetection3d/blob/master/mmdet3d/models/backbones/second.py
Ths copyright of mmdetection3d is as follows:
Apache-2.0 license [see LICENSE for details].
"""
import math
import paddle
import paddle.nn as nn
from paddle import ParamAttr
from paddle.nn.initializer import Constant, Normal, Uniform
from paddle3d.apis import manager
from paddle3d.models.voxel_encoders.pillar_encoder import build_norm_layer
__all__ = ['SecondBackbone', 'build_conv_layer']
def build_conv_layer(in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
dilation=1,
groups=1,
bias=True,
distribution="uniform"):
"""Build convolution layer."""
if distribution == "uniform":
bound = 1 / math.sqrt(in_channels * kernel_size**2)
param_attr = ParamAttr(initializer=Uniform(-bound, bound))
bias_attr = False
if bias:
bias_attr = ParamAttr(initializer=Uniform(-bound, bound))
else:
fan_out = out_channels * kernel_size**2
std = math.sqrt(2) / math.sqrt(fan_out)
param_attr = ParamAttr(initializer=Normal(0, std))
bias_attr = False
if bias:
bias_attr = ParamAttr(initializer=Constant(0.))
conv_layer = nn.Conv2D(
in_channels=in_channels,
out_channels=out_channels,
kernel_size=kernel_size,
stride=stride,
padding=padding,
dilation=dilation,
groups=groups,
weight_attr=param_attr,
bias_attr=bias_attr)
return conv_layer
@manager.BACKBONES.add_component
class SecondBackbone(nn.Layer):
def __init__(self,
in_channels=128,
out_channels=[128, 128, 256],
layer_nums=[3, 5, 5],
downsample_strides=[2, 2, 2]):
super(SecondBackbone, self).__init__()
assert len(downsample_strides) == len(layer_nums)
assert len(out_channels) == len(layer_nums)
self.downsample_strides = downsample_strides
norm_cfg = dict(type='BatchNorm2D', eps=1e-3, momentum=0.01)
in_filters = [in_channels, *out_channels[:-1]]
blocks = []
for i, layer_num in enumerate(layer_nums):
block = [
build_conv_layer(
in_filters[i],
out_channels[i],
3,
stride=downsample_strides[i],
padding=1,
bias=False),
build_norm_layer(norm_cfg, out_channels[i]),
nn.ReLU(),
]
for j in range(layer_num):
block.append(
build_conv_layer(
out_channels[i],
out_channels[i],
3,
padding=1,
bias=False))
block.append(build_norm_layer(norm_cfg, out_channels[i]))
block.append(nn.ReLU())
block = nn.Sequential(*block)
blocks.append(block)
self.blocks = nn.LayerList(blocks)
def forward(self, x):
outs = []
for i in range(len(self.blocks)):
x = self.blocks[i](x)
outs.append(x)
return tuple(outs)