inception_v4.py 14.4 KB
Newer Older
littletomatodonkey's avatar
littletomatodonkey 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# 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.

W
WuHaobo 已提交
15
import paddle
littletomatodonkey's avatar
littletomatodonkey 已提交
16 17 18
from paddle import ParamAttr
import paddle.nn as nn
import paddle.nn.functional as F
littletomatodonkey's avatar
littletomatodonkey 已提交
19 20
from paddle.nn import Conv2d, BatchNorm, Linear, Dropout
from paddle.nn import AdaptiveAvgPool2d, MaxPool2d, AvgPool2d
littletomatodonkey's avatar
littletomatodonkey 已提交
21
from paddle.nn.initializer import Uniform
22 23 24 25
import math

__all__ = ["InceptionV4"]

littletomatodonkey's avatar
littletomatodonkey 已提交
26 27

class ConvBNLayer(nn.Layer):
28 29 30 31 32 33 34 35 36 37 38
    def __init__(self,
                 num_channels,
                 num_filters,
                 filter_size,
                 stride=1,
                 padding=0,
                 groups=1,
                 act='relu',
                 name=None):
        super(ConvBNLayer, self).__init__()

littletomatodonkey's avatar
littletomatodonkey 已提交
39 40 41 42
        self._conv = Conv2d(
            in_channels=num_channels,
            out_channels=num_filters,
            kernel_size=filter_size,
W
WuHaobo 已提交
43 44 45
            stride=stride,
            padding=padding,
            groups=groups,
littletomatodonkey's avatar
littletomatodonkey 已提交
46
            weight_attr=ParamAttr(name=name + "_weights"),
47
            bias_attr=False)
W
WuHaobo 已提交
48
        bn_name = name + "_bn"
49 50
        self._batch_norm = BatchNorm(
            num_filters,
W
WuHaobo 已提交
51 52 53 54 55 56
            act=act,
            param_attr=ParamAttr(name=bn_name + "_scale"),
            bias_attr=ParamAttr(name=bn_name + "_offset"),
            moving_mean_name=bn_name + '_mean',
            moving_variance_name=bn_name + '_variance')

57 58 59 60
    def forward(self, inputs):
        y = self._conv(inputs)
        y = self._batch_norm(y)
        return y
W
WuHaobo 已提交
61 62


littletomatodonkey's avatar
littletomatodonkey 已提交
63
class InceptionStem(nn.Layer):
64
    def __init__(self):
W
wqz960 已提交
65
        super(InceptionStem, self).__init__()
66 67 68 69 70
        self._conv_1 = ConvBNLayer(
            3, 32, 3, stride=2, act="relu", name="conv1_3x3_s2")
        self._conv_2 = ConvBNLayer(32, 32, 3, act="relu", name="conv2_3x3_s1")
        self._conv_3 = ConvBNLayer(
            32, 64, 3, padding=1, act="relu", name="conv3_3x3_s1")
littletomatodonkey's avatar
littletomatodonkey 已提交
71
        self._pool = MaxPool2d(kernel_size=3, stride=2, padding=0)
72 73 74 75 76 77 78 79 80 81
        self._conv2 = ConvBNLayer(
            64, 96, 3, stride=2, act="relu", name="inception_stem1_3x3_s2")
        self._conv1_1 = ConvBNLayer(
            160, 64, 1, act="relu", name="inception_stem2_3x3_reduce")
        self._conv1_2 = ConvBNLayer(
            64, 96, 3, act="relu", name="inception_stem2_3x3")
        self._conv2_1 = ConvBNLayer(
            160, 64, 1, act="relu", name="inception_stem2_1x7_reduce")
        self._conv2_2 = ConvBNLayer(
            64,
W
WuHaobo 已提交
82 83
            64, (7, 1),
            padding=(3, 0),
84
            act="relu",
W
WuHaobo 已提交
85
            name="inception_stem2_1x7")
86 87
        self._conv2_3 = ConvBNLayer(
            64,
W
WuHaobo 已提交
88 89
            64, (1, 7),
            padding=(0, 3),
90
            act="relu",
W
WuHaobo 已提交
91
            name="inception_stem2_7x1")
92 93 94 95 96 97 98 99 100 101 102 103
        self._conv2_4 = ConvBNLayer(
            64, 96, 3, act="relu", name="inception_stem2_3x3_2")
        self._conv3 = ConvBNLayer(
            192, 192, 3, stride=2, act="relu", name="inception_stem3_3x3_s2")

    def forward(self, inputs):
        conv = self._conv_1(inputs)
        conv = self._conv_2(conv)
        conv = self._conv_3(conv)

        pool1 = self._pool(conv)
        conv2 = self._conv2(conv)
littletomatodonkey's avatar
littletomatodonkey 已提交
104
        concat = paddle.concat([pool1, conv2], axis=1)
105 106 107 108 109 110 111 112

        conv1 = self._conv1_1(concat)
        conv1 = self._conv1_2(conv1)

        conv2 = self._conv2_1(concat)
        conv2 = self._conv2_2(conv2)
        conv2 = self._conv2_3(conv2)
        conv2 = self._conv2_4(conv2)
W
WuHaobo 已提交
113

littletomatodonkey's avatar
littletomatodonkey 已提交
114
        concat = paddle.concat([conv1, conv2], axis=1)
W
WuHaobo 已提交
115

116 117
        conv1 = self._conv3(concat)
        pool1 = self._pool(concat)
W
WuHaobo 已提交
118

littletomatodonkey's avatar
littletomatodonkey 已提交
119
        concat = paddle.concat([conv1, pool1], axis=1)
W
WuHaobo 已提交
120 121 122
        return concat


littletomatodonkey's avatar
littletomatodonkey 已提交
123
class InceptionA(nn.Layer):
124 125
    def __init__(self, name):
        super(InceptionA, self).__init__()
littletomatodonkey's avatar
littletomatodonkey 已提交
126
        self._pool = AvgPool2d(kernel_size=3, stride=1, padding=1)
127 128 129 130 131 132 133 134
        self._conv1 = ConvBNLayer(
            384, 96, 1, act="relu", name="inception_a" + name + "_1x1")
        self._conv2 = ConvBNLayer(
            384, 96, 1, act="relu", name="inception_a" + name + "_1x1_2")
        self._conv3_1 = ConvBNLayer(
            384, 64, 1, act="relu", name="inception_a" + name + "_3x3_reduce")
        self._conv3_2 = ConvBNLayer(
            64,
W
WuHaobo 已提交
135 136 137
            96,
            3,
            padding=1,
138
            act="relu",
W
WuHaobo 已提交
139
            name="inception_a" + name + "_3x3")
140 141
        self._conv4_1 = ConvBNLayer(
            384,
W
WuHaobo 已提交
142 143
            64,
            1,
144
            act="relu",
W
WuHaobo 已提交
145
            name="inception_a" + name + "_3x3_2_reduce")
146 147
        self._conv4_2 = ConvBNLayer(
            64,
W
WuHaobo 已提交
148 149 150
            96,
            3,
            padding=1,
151
            act="relu",
W
WuHaobo 已提交
152
            name="inception_a" + name + "_3x3_2")
153 154
        self._conv4_3 = ConvBNLayer(
            96,
W
WuHaobo 已提交
155 156 157
            96,
            3,
            padding=1,
158
            act="relu",
W
WuHaobo 已提交
159 160
            name="inception_a" + name + "_3x3_3")

161 162 163
    def forward(self, inputs):
        pool1 = self._pool(inputs)
        conv1 = self._conv1(pool1)
W
WuHaobo 已提交
164

165
        conv2 = self._conv2(inputs)
W
WuHaobo 已提交
166

167 168
        conv3 = self._conv3_1(inputs)
        conv3 = self._conv3_2(conv3)
W
WuHaobo 已提交
169

170 171 172
        conv4 = self._conv4_1(inputs)
        conv4 = self._conv4_2(conv4)
        conv4 = self._conv4_3(conv4)
W
WuHaobo 已提交
173

littletomatodonkey's avatar
littletomatodonkey 已提交
174
        concat = paddle.concat([conv1, conv2, conv3, conv4], axis=1)
175
        return concat
W
WuHaobo 已提交
176 177


littletomatodonkey's avatar
littletomatodonkey 已提交
178
class ReductionA(nn.Layer):
179 180
    def __init__(self):
        super(ReductionA, self).__init__()
littletomatodonkey's avatar
littletomatodonkey 已提交
181
        self._pool = MaxPool2d(kernel_size=3, stride=2, padding=0)
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
        self._conv2 = ConvBNLayer(
            384, 384, 3, stride=2, act="relu", name="reduction_a_3x3")
        self._conv3_1 = ConvBNLayer(
            384, 192, 1, act="relu", name="reduction_a_3x3_2_reduce")
        self._conv3_2 = ConvBNLayer(
            192, 224, 3, padding=1, act="relu", name="reduction_a_3x3_2")
        self._conv3_3 = ConvBNLayer(
            224, 256, 3, stride=2, act="relu", name="reduction_a_3x3_3")

    def forward(self, inputs):
        pool1 = self._pool(inputs)
        conv2 = self._conv2(inputs)
        conv3 = self._conv3_1(inputs)
        conv3 = self._conv3_2(conv3)
        conv3 = self._conv3_3(conv3)
littletomatodonkey's avatar
littletomatodonkey 已提交
197
        concat = paddle.concat([pool1, conv2, conv3], axis=1)
W
WuHaobo 已提交
198 199 200
        return concat


littletomatodonkey's avatar
littletomatodonkey 已提交
201
class InceptionB(nn.Layer):
202 203
    def __init__(self, name=None):
        super(InceptionB, self).__init__()
littletomatodonkey's avatar
littletomatodonkey 已提交
204
        self._pool = AvgPool2d(kernel_size=3, stride=1, padding=1)
205 206 207 208 209 210
        self._conv1 = ConvBNLayer(
            1024, 128, 1, act="relu", name="inception_b" + name + "_1x1")
        self._conv2 = ConvBNLayer(
            1024, 384, 1, act="relu", name="inception_b" + name + "_1x1_2")
        self._conv3_1 = ConvBNLayer(
            1024,
W
WuHaobo 已提交
211 212
            192,
            1,
213
            act="relu",
W
WuHaobo 已提交
214
            name="inception_b" + name + "_1x7_reduce")
215 216
        self._conv3_2 = ConvBNLayer(
            192,
W
WuHaobo 已提交
217 218
            224, (1, 7),
            padding=(0, 3),
219
            act="relu",
W
WuHaobo 已提交
220
            name="inception_b" + name + "_1x7")
221 222
        self._conv3_3 = ConvBNLayer(
            224,
W
WuHaobo 已提交
223 224
            256, (7, 1),
            padding=(3, 0),
225
            act="relu",
W
WuHaobo 已提交
226
            name="inception_b" + name + "_7x1")
227 228
        self._conv4_1 = ConvBNLayer(
            1024,
W
WuHaobo 已提交
229 230
            192,
            1,
231
            act="relu",
W
WuHaobo 已提交
232
            name="inception_b" + name + "_7x1_2_reduce")
233 234
        self._conv4_2 = ConvBNLayer(
            192,
W
WuHaobo 已提交
235 236
            192, (1, 7),
            padding=(0, 3),
237
            act="relu",
W
WuHaobo 已提交
238
            name="inception_b" + name + "_1x7_2")
239 240
        self._conv4_3 = ConvBNLayer(
            192,
W
WuHaobo 已提交
241 242
            224, (7, 1),
            padding=(3, 0),
243
            act="relu",
W
WuHaobo 已提交
244
            name="inception_b" + name + "_7x1_2")
245 246
        self._conv4_4 = ConvBNLayer(
            224,
W
WuHaobo 已提交
247 248
            224, (1, 7),
            padding=(0, 3),
249
            act="relu",
W
WuHaobo 已提交
250
            name="inception_b" + name + "_1x7_3")
251 252
        self._conv4_5 = ConvBNLayer(
            224,
W
WuHaobo 已提交
253 254
            256, (7, 1),
            padding=(3, 0),
255
            act="relu",
W
WuHaobo 已提交
256 257
            name="inception_b" + name + "_7x1_3")

258 259 260
    def forward(self, inputs):
        pool1 = self._pool(inputs)
        conv1 = self._conv1(pool1)
W
WuHaobo 已提交
261

262 263 264 265 266
        conv2 = self._conv2(inputs)

        conv3 = self._conv3_1(inputs)
        conv3 = self._conv3_2(conv3)
        conv3 = self._conv3_3(conv3)
W
WuHaobo 已提交
267

268 269 270 271 272
        conv4 = self._conv4_1(inputs)
        conv4 = self._conv4_2(conv4)
        conv4 = self._conv4_3(conv4)
        conv4 = self._conv4_4(conv4)
        conv4 = self._conv4_5(conv4)
W
WuHaobo 已提交
273

littletomatodonkey's avatar
littletomatodonkey 已提交
274
        concat = paddle.concat([conv1, conv2, conv3, conv4], axis=1)
275
        return concat
W
WuHaobo 已提交
276

277

littletomatodonkey's avatar
littletomatodonkey 已提交
278
class ReductionB(nn.Layer):
279 280
    def __init__(self):
        super(ReductionB, self).__init__()
littletomatodonkey's avatar
littletomatodonkey 已提交
281
        self._pool = MaxPool2d(kernel_size=3, stride=2, padding=0)
282 283 284 285 286 287 288 289
        self._conv2_1 = ConvBNLayer(
            1024, 192, 1, act="relu", name="reduction_b_3x3_reduce")
        self._conv2_2 = ConvBNLayer(
            192, 192, 3, stride=2, act="relu", name="reduction_b_3x3")
        self._conv3_1 = ConvBNLayer(
            1024, 256, 1, act="relu", name="reduction_b_1x7_reduce")
        self._conv3_2 = ConvBNLayer(
            256,
W
WuHaobo 已提交
290 291
            256, (1, 7),
            padding=(0, 3),
292
            act="relu",
W
WuHaobo 已提交
293
            name="reduction_b_1x7")
294 295
        self._conv3_3 = ConvBNLayer(
            256,
W
WuHaobo 已提交
296 297
            320, (7, 1),
            padding=(3, 0),
298
            act="relu",
W
WuHaobo 已提交
299
            name="reduction_b_7x1")
300 301 302 303 304 305 306 307 308 309 310 311 312
        self._conv3_4 = ConvBNLayer(
            320, 320, 3, stride=2, act="relu", name="reduction_b_3x3_2")

    def forward(self, inputs):
        pool1 = self._pool(inputs)

        conv2 = self._conv2_1(inputs)
        conv2 = self._conv2_2(conv2)

        conv3 = self._conv3_1(inputs)
        conv3 = self._conv3_2(conv3)
        conv3 = self._conv3_3(conv3)
        conv3 = self._conv3_4(conv3)
W
WuHaobo 已提交
313

littletomatodonkey's avatar
littletomatodonkey 已提交
314
        concat = paddle.concat([pool1, conv2, conv3], axis=1)
W
WuHaobo 已提交
315 316 317 318

        return concat


littletomatodonkey's avatar
littletomatodonkey 已提交
319
class InceptionC(nn.Layer):
320 321
    def __init__(self, name=None):
        super(InceptionC, self).__init__()
littletomatodonkey's avatar
littletomatodonkey 已提交
322
        self._pool = AvgPool2d(kernel_size=3, stride=1, padding=1)
323 324 325 326 327 328 329 330
        self._conv1 = ConvBNLayer(
            1536, 256, 1, act="relu", name="inception_c" + name + "_1x1")
        self._conv2 = ConvBNLayer(
            1536, 256, 1, act="relu", name="inception_c" + name + "_1x1_2")
        self._conv3_0 = ConvBNLayer(
            1536, 384, 1, act="relu", name="inception_c" + name + "_1x1_3")
        self._conv3_1 = ConvBNLayer(
            384,
W
WuHaobo 已提交
331 332
            256, (1, 3),
            padding=(0, 1),
333
            act="relu",
W
WuHaobo 已提交
334
            name="inception_c" + name + "_1x3")
335 336
        self._conv3_2 = ConvBNLayer(
            384,
W
WuHaobo 已提交
337 338
            256, (3, 1),
            padding=(1, 0),
339
            act="relu",
W
WuHaobo 已提交
340
            name="inception_c" + name + "_3x1")
341 342 343 344
        self._conv4_0 = ConvBNLayer(
            1536, 384, 1, act="relu", name="inception_c" + name + "_1x1_4")
        self._conv4_00 = ConvBNLayer(
            384,
W
WuHaobo 已提交
345 346
            448, (1, 3),
            padding=(0, 1),
347
            act="relu",
W
WuHaobo 已提交
348
            name="inception_c" + name + "_1x3_2")
349 350
        self._conv4_000 = ConvBNLayer(
            448,
W
WuHaobo 已提交
351 352
            512, (3, 1),
            padding=(1, 0),
353
            act="relu",
W
WuHaobo 已提交
354
            name="inception_c" + name + "_3x1_2")
355 356
        self._conv4_1 = ConvBNLayer(
            512,
W
WuHaobo 已提交
357 358
            256, (1, 3),
            padding=(0, 1),
359
            act="relu",
W
WuHaobo 已提交
360
            name="inception_c" + name + "_1x3_3")
361 362
        self._conv4_2 = ConvBNLayer(
            512,
W
WuHaobo 已提交
363 364
            256, (3, 1),
            padding=(1, 0),
365
            act="relu",
W
WuHaobo 已提交
366 367
            name="inception_c" + name + "_3x1_3")

368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
    def forward(self, inputs):
        pool1 = self._pool(inputs)
        conv1 = self._conv1(pool1)

        conv2 = self._conv2(inputs)

        conv3 = self._conv3_0(inputs)
        conv3_1 = self._conv3_1(conv3)
        conv3_2 = self._conv3_2(conv3)

        conv4 = self._conv4_0(inputs)
        conv4 = self._conv4_00(conv4)
        conv4 = self._conv4_000(conv4)
        conv4_1 = self._conv4_1(conv4)
        conv4_2 = self._conv4_2(conv4)

littletomatodonkey's avatar
littletomatodonkey 已提交
384
        concat = paddle.concat(
W
WuHaobo 已提交
385 386 387
            [conv1, conv2, conv3_1, conv3_2, conv4_1, conv4_2], axis=1)

        return concat
388 389


littletomatodonkey's avatar
littletomatodonkey 已提交
390
class InceptionV4DY(nn.Layer):
391
    def __init__(self, class_dim=1000):
W
fix  
wqz960 已提交
392
        super(InceptionV4DY, self).__init__()
W
wqz960 已提交
393
        self._inception_stem = InceptionStem()
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413

        self._inceptionA_1 = InceptionA(name="1")
        self._inceptionA_2 = InceptionA(name="2")
        self._inceptionA_3 = InceptionA(name="3")
        self._inceptionA_4 = InceptionA(name="4")
        self._reductionA = ReductionA()

        self._inceptionB_1 = InceptionB(name="1")
        self._inceptionB_2 = InceptionB(name="2")
        self._inceptionB_3 = InceptionB(name="3")
        self._inceptionB_4 = InceptionB(name="4")
        self._inceptionB_5 = InceptionB(name="5")
        self._inceptionB_6 = InceptionB(name="6")
        self._inceptionB_7 = InceptionB(name="7")
        self._reductionB = ReductionB()

        self._inceptionC_1 = InceptionC(name="1")
        self._inceptionC_2 = InceptionC(name="2")
        self._inceptionC_3 = InceptionC(name="3")

littletomatodonkey's avatar
littletomatodonkey 已提交
414
        self.avg_pool = AdaptiveAvgPool2d(1)
littletomatodonkey's avatar
littletomatodonkey 已提交
415
        self._drop = Dropout(p=0.2, mode="downscale_in_infer")
416 417 418 419
        stdv = 1.0 / math.sqrt(1536 * 1.0)
        self.out = Linear(
            1536,
            class_dim,
littletomatodonkey's avatar
littletomatodonkey 已提交
420 421
            weight_attr=ParamAttr(
                initializer=Uniform(-stdv, stdv), name="final_fc_weights"),
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446
            bias_attr=ParamAttr(name="final_fc_offset"))

    def forward(self, inputs):
        x = self._inception_stem(inputs)

        x = self._inceptionA_1(x)
        x = self._inceptionA_2(x)
        x = self._inceptionA_3(x)
        x = self._inceptionA_4(x)
        x = self._reductionA(x)

        x = self._inceptionB_1(x)
        x = self._inceptionB_2(x)
        x = self._inceptionB_3(x)
        x = self._inceptionB_4(x)
        x = self._inceptionB_5(x)
        x = self._inceptionB_6(x)
        x = self._inceptionB_7(x)
        x = self._reductionB(x)

        x = self._inceptionC_1(x)
        x = self._inceptionC_2(x)
        x = self._inceptionC_3(x)

        x = self.avg_pool(x)
littletomatodonkey's avatar
littletomatodonkey 已提交
447
        x = paddle.squeeze(x, axis=[2, 3])
448 449 450 451 452
        x = self._drop(x)
        x = self.out(x)
        return x


W
wqz960 已提交
453 454
def InceptionV4(**args):
    model = InceptionV4DY(**args)
littletomatodonkey's avatar
littletomatodonkey 已提交
455
    return model