@@ -16,42 +16,40 @@ def __init__(self, backbone_out_channels, **kwargs):
16
16
result_num = kwargs .get ('result_num' , 6 )
17
17
inplace = True
18
18
conv_out = 256
19
-
20
- # Top layer
21
- self .toplayer = nn .Sequential (
22
- nn .Conv2d (backbone_out_channels [3 ], conv_out , kernel_size = 1 , stride = 1 , padding = 0 ),
19
+ # reduce layers
20
+ self .reduce_conv_c2 = nn .Sequential (
21
+ nn .Conv2d (backbone_out_channels [0 ], conv_out , kernel_size = 1 , stride = 1 , padding = 0 ),
23
22
nn .BatchNorm2d (conv_out ),
24
23
nn .ReLU (inplace = inplace )
25
24
)
26
- # Lateral layers
27
- self .latlayer1 = nn .Sequential (
28
- nn .Conv2d (backbone_out_channels [2 ], conv_out , kernel_size = 1 , stride = 1 , padding = 0 ),
25
+ self .reduce_conv_c3 = nn .Sequential (
26
+ nn .Conv2d (backbone_out_channels [1 ], conv_out , kernel_size = 1 , stride = 1 , padding = 0 ),
29
27
nn .BatchNorm2d (conv_out ),
30
28
nn .ReLU (inplace = inplace )
31
29
)
32
- self .latlayer2 = nn .Sequential (
33
- nn .Conv2d (backbone_out_channels [1 ], conv_out , kernel_size = 1 , stride = 1 , padding = 0 ),
30
+ self .reduce_conv_c4 = nn .Sequential (
31
+ nn .Conv2d (backbone_out_channels [2 ], conv_out , kernel_size = 1 , stride = 1 , padding = 0 ),
34
32
nn .BatchNorm2d (conv_out ),
35
33
nn .ReLU (inplace = inplace )
36
34
)
37
- self .latlayer3 = nn .Sequential (
38
- nn .Conv2d (backbone_out_channels [0 ], conv_out , kernel_size = 1 , stride = 1 , padding = 0 ),
35
+
36
+ self .reduce_conv_c5 = nn .Sequential (
37
+ nn .Conv2d (backbone_out_channels [3 ], conv_out , kernel_size = 1 , stride = 1 , padding = 0 ),
39
38
nn .BatchNorm2d (conv_out ),
40
39
nn .ReLU (inplace = inplace )
41
40
)
42
-
43
41
# Smooth layers
44
- self .smooth1 = nn .Sequential (
42
+ self .smooth_p4 = nn .Sequential (
45
43
nn .Conv2d (conv_out , conv_out , kernel_size = 3 , stride = 1 , padding = 1 ),
46
44
nn .BatchNorm2d (conv_out ),
47
45
nn .ReLU (inplace = inplace )
48
46
)
49
- self .smooth2 = nn .Sequential (
47
+ self .smooth_p3 = nn .Sequential (
50
48
nn .Conv2d (conv_out , conv_out , kernel_size = 3 , stride = 1 , padding = 1 ),
51
49
nn .BatchNorm2d (conv_out ),
52
50
nn .ReLU (inplace = inplace )
53
51
)
54
- self .smooth3 = nn .Sequential (
52
+ self .smooth_p2 = nn .Sequential (
55
53
nn .Conv2d (conv_out , conv_out , kernel_size = 3 , stride = 1 , padding = 1 ),
56
54
nn .BatchNorm2d (conv_out ),
57
55
nn .ReLU (inplace = inplace )
@@ -67,27 +65,27 @@ def __init__(self, backbone_out_channels, **kwargs):
67
65
def forward (self , x ):
68
66
c2 , c3 , c4 , c5 = x
69
67
# Top-down
70
- p5 = self .toplayer (c5 )
71
- p4 = self ._upsample_add (p5 , self .latlayer1 (c4 ))
72
- p4 = self .smooth1 (p4 )
73
- p3 = self ._upsample_add (p4 , self .latlayer2 (c3 ))
74
- p3 = self .smooth2 (p3 )
75
- p2 = self ._upsample_add (p3 , self .latlayer3 (c2 ))
76
- p2 = self .smooth3 (p2 )
68
+ p5 = self .reduce_conv_c5 (c5 )
69
+ p4 = self ._upsample_add (p5 , self .reduce_conv_c4 (c4 ))
70
+ p4 = self .smooth_p4 (p4 )
71
+ p3 = self ._upsample_add (p4 , self .reduce_conv_c3 (c3 ))
72
+ p3 = self .smooth_p3 (p3 )
73
+ p2 = self ._upsample_add (p3 , self .reduce_conv_c2 (c2 ))
74
+ p2 = self .smooth_p2 (p2 )
77
75
78
76
x = self ._upsample_cat (p2 , p3 , p4 , p5 )
79
77
x = self .conv (x )
80
78
x = self .out_conv (x )
81
79
return x
82
80
83
81
def _upsample_add (self , x , y ):
84
- return F .interpolate (x , size = y .size ()[2 :], mode = 'bilinear' , align_corners = False ) + y
82
+ return F .interpolate (x , size = y .size ()[2 :], mode = 'bilinear' ) + y
85
83
86
84
def _upsample_cat (self , p2 , p3 , p4 , p5 ):
87
85
h , w = p2 .size ()[2 :]
88
- p3 = F .interpolate (p3 , size = (h , w ), mode = 'bilinear' , align_corners = False )
89
- p4 = F .interpolate (p4 , size = (h , w ), mode = 'bilinear' , align_corners = False )
90
- p5 = F .interpolate (p5 , size = (h , w ), mode = 'bilinear' , align_corners = False )
86
+ p3 = F .interpolate (p3 , size = (h , w ), mode = 'bilinear' )
87
+ p4 = F .interpolate (p4 , size = (h , w ), mode = 'bilinear' )
88
+ p5 = F .interpolate (p5 , size = (h , w ), mode = 'bilinear' )
91
89
return torch .cat ([p2 , p3 , p4 , p5 ], dim = 1 )
92
90
93
91
@@ -99,22 +97,40 @@ def __init__(self, backbone_out_channels, **kwargs):
99
97
"""
100
98
super ().__init__ ()
101
99
fpem_repeat = kwargs .get ('fpem_repeat' , 2 )
102
- self .conv_c2 = nn .Conv2d (in_channels = backbone_out_channels [0 ], out_channels = 128 , kernel_size = 1 )
103
- self .conv_c3 = nn .Conv2d (in_channels = backbone_out_channels [1 ], out_channels = 128 , kernel_size = 1 )
104
- self .conv_c4 = nn .Conv2d (in_channels = backbone_out_channels [2 ], out_channels = 128 , kernel_size = 1 )
105
- self .conv_c5 = nn .Conv2d (in_channels = backbone_out_channels [3 ], out_channels = 128 , kernel_size = 1 )
100
+ conv_out = 128
101
+ # reduce layers
102
+ self .reduce_conv_c2 = nn .Sequential (
103
+ nn .Conv2d (in_channels = backbone_out_channels [0 ], out_channels = conv_out , kernel_size = 1 ),
104
+ nn .BatchNorm2d (conv_out ),
105
+ nn .ReLU ()
106
+ )
107
+ self .reduce_conv_c3 = nn .Sequential (
108
+ nn .Conv2d (in_channels = backbone_out_channels [1 ], out_channels = conv_out , kernel_size = 1 ),
109
+ nn .BatchNorm2d (conv_out ),
110
+ nn .ReLU ()
111
+ )
112
+ self .reduce_conv_c4 = nn .Sequential (
113
+ nn .Conv2d (in_channels = backbone_out_channels [2 ], out_channels = conv_out , kernel_size = 1 ),
114
+ nn .BatchNorm2d (conv_out ),
115
+ nn .ReLU ()
116
+ )
117
+ self .reduce_conv_c5 = nn .Sequential (
118
+ nn .Conv2d (in_channels = backbone_out_channels [3 ], out_channels = conv_out , kernel_size = 1 ),
119
+ nn .BatchNorm2d (conv_out ),
120
+ nn .ReLU ()
121
+ )
106
122
self .fpems = nn .ModuleList ()
107
123
for i in range (fpem_repeat ):
108
- self .fpems .append (FPEM (128 ))
109
- self .out_conv = nn .Conv2d (in_channels = 512 , out_channels = 6 , kernel_size = 1 )
124
+ self .fpems .append (FPEM (conv_out ))
125
+ self .out_conv = nn .Conv2d (in_channels = conv_out * 4 , out_channels = 6 , kernel_size = 1 )
110
126
111
127
def forward (self , x ):
112
128
c2 , c3 , c4 , c5 = x
113
129
# reduce channel
114
- c2 = self .conv_c2 (c2 )
115
- c3 = self .conv_c3 (c3 )
116
- c4 = self .conv_c4 (c4 )
117
- c5 = self .conv_c5 (c5 )
130
+ c2 = self .reduce_conv_c2 (c2 )
131
+ c3 = self .reduce_conv_c3 (c3 )
132
+ c4 = self .reduce_conv_c4 (c4 )
133
+ c5 = self .reduce_conv_c5 (c5 )
118
134
119
135
# FPEM
120
136
for i , fpem in enumerate (self .fpems ):
@@ -142,38 +158,28 @@ def forward(self, x):
142
158
class FPEM (nn .Module ):
143
159
def __init__ (self , in_channels = 128 ):
144
160
super ().__init__ ()
145
- # self.add_up = nn.Sequential(
146
- # nn.Conv2d(in_channels=in_channel, out_channels=in_channel, kernel_size=3, padding=1, groups=in_channel),
147
- # nn.Conv2d(in_channels=in_channel, out_channels=in_channel, kernel_size=1),
148
- # nn.BatchNorm2d(in_channel),
149
- # nn.ReLU()
150
- # )
151
- # self.add_down = nn.Sequential(
152
- # nn.Conv2d(in_channels=in_channel, out_channels=in_channel, kernel_size=3, padding=1, groups=in_channel,
153
- # stride=2),
154
- # nn.Conv2d(in_channels=in_channel, out_channels=in_channel, kernel_size=1),
155
- # nn.BatchNorm2d(in_channel),
156
- # nn.ReLU()
157
- # )
158
161
self .up_add1 = SeparableConv2d (in_channels , in_channels , 1 )
159
162
self .up_add2 = SeparableConv2d (in_channels , in_channels , 1 )
160
- self .up_add2 = SeparableConv2d (in_channels , in_channels , 1 )
163
+ self .up_add3 = SeparableConv2d (in_channels , in_channels , 1 )
161
164
self .down_add1 = SeparableConv2d (in_channels , in_channels , 2 )
162
165
self .down_add2 = SeparableConv2d (in_channels , in_channels , 2 )
163
166
self .down_add3 = SeparableConv2d (in_channels , in_channels , 2 )
164
167
165
168
def forward (self , c2 , c3 , c4 , c5 ):
166
169
# up阶段
167
- c4 = self .up_add1 (c4 + F . interpolate (c5 , c4 . size ()[ - 2 :], mode = 'bilinear' , align_corners = True ))
168
- c3 = self .up_add2 (c3 + F . interpolate (c4 , c3 . size ()[ - 2 :], mode = 'bilinear' , align_corners = True ))
169
- c2 = self .up_add2 ( c2 + F . interpolate (c3 , c2 . size ()[ - 2 :], mode = 'bilinear' , align_corners = True ))
170
+ c4 = self .up_add1 (self . _upsample_add (c5 , c4 ))
171
+ c3 = self .up_add2 (self . _upsample_add (c4 , c3 ))
172
+ c2 = self .up_add3 ( self . _upsample_add (c3 , c2 ))
170
173
171
174
# down 阶段
172
- c3 = self .down_add1 (c2 + F . interpolate (c3 , c2 . size ()[ - 2 :], mode = 'bilinear' , align_corners = True ))
173
- c4 = self .down_add2 (c3 + F . interpolate (c4 , c3 . size ()[ - 2 :], mode = 'bilinear' , align_corners = True ))
174
- c5 = self .down_add3 (c4 + F . interpolate (c5 , c4 . size ()[ - 2 :], mode = 'bilinear' , align_corners = True ))
175
+ c3 = self .down_add1 (self . _upsample_add (c3 , c2 ))
176
+ c4 = self .down_add2 (self . _upsample_add (c4 , c3 ))
177
+ c5 = self .down_add3 (self . _upsample_add (c5 , c4 ))
175
178
return c2 , c3 , c4 , c5
176
179
180
+ def _upsample_add (self , x , y ):
181
+ return F .interpolate (x , size = y .size ()[2 :], mode = 'bilinear' ) + y
182
+
177
183
178
184
class SeparableConv2d (nn .Module ):
179
185
def __init__ (self , in_channels , out_channels , stride = 1 ):
@@ -186,8 +192,8 @@ def __init__(self, in_channels, out_channels, stride=1):
186
192
self .relu = nn .ReLU ()
187
193
188
194
def forward (self , x ):
189
- x = self .out_channels (x )
195
+ x = self .depthwise_conv (x )
190
196
x = self .pointwise_conv (x )
191
197
x = self .bn (x )
192
- x = self .relu
198
+ x = self .relu ( x )
193
199
return x
0 commit comments