inception_v4.py 14.1 KB
Newer Older
1 2
import numpy as np
import argparse
W
WuHaobo 已提交
3 4 5
import paddle
import paddle.fluid as fluid
from paddle.fluid.param_attr import ParamAttr
6 7 8
from paddle.fluid.layer_helper import LayerHelper
from paddle.fluid.dygraph.nn import Conv2D, Pool2D, BatchNorm, Linear, Dropout
from paddle.fluid.dygraph.base import to_variable
W
WuHaobo 已提交
9

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
from paddle.fluid import framework
import math

__all__ = ["InceptionV4"]


class ConvBNLayer(fluid.dygraph.Layer):
    def __init__(self,
                 num_channels,
                 num_filters,
                 filter_size,
                 stride=1,
                 padding=0,
                 groups=1,
                 act='relu',
                 name=None):
        super(ConvBNLayer, self).__init__()

        self._conv = Conv2D(
            num_channels=num_channels,
W
WuHaobo 已提交
30 31 32 33 34 35 36
            num_filters=num_filters,
            filter_size=filter_size,
            stride=stride,
            padding=padding,
            groups=groups,
            act=None,
            param_attr=ParamAttr(name=name + "_weights"),
37
            bias_attr=False)
W
WuHaobo 已提交
38
        bn_name = name + "_bn"
39 40
        self._batch_norm = BatchNorm(
            num_filters,
W
WuHaobo 已提交
41 42 43 44 45 46
            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')

47 48 49 50
    def forward(self, inputs):
        y = self._conv(inputs)
        y = self._batch_norm(y)
        return y
W
WuHaobo 已提交
51 52


53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
class Inception_Stem(fluid.dygraph.Layer):
    def __init__(self):
        super(Inception_Stem, self).__init__()
        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")
        self._pool = Pool2D(pool_size=3, pool_type="max", pool_stride=2)
        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 已提交
72 73
            64, (7, 1),
            padding=(3, 0),
74
            act="relu",
W
WuHaobo 已提交
75
            name="inception_stem2_1x7")
76 77
        self._conv2_3 = ConvBNLayer(
            64,
W
WuHaobo 已提交
78 79
            64, (1, 7),
            padding=(0, 3),
80
            act="relu",
W
WuHaobo 已提交
81
            name="inception_stem2_7x1")
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
        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)
        concat = fluid.layers.concat([pool1, conv2], axis=1)

        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 已提交
103 104 105

        concat = fluid.layers.concat([conv1, conv2], axis=1)

106 107
        conv1 = self._conv3(concat)
        pool1 = self._pool(concat)
W
WuHaobo 已提交
108 109 110 111 112

        concat = fluid.layers.concat([conv1, pool1], axis=1)
        return concat


113 114 115 116 117 118 119 120 121 122 123 124
class InceptionA(fluid.dygraph.Layer):
    def __init__(self, name):
        super(InceptionA, self).__init__()
        self._pool = Pool2D(pool_size=3, pool_type="avg", pool_padding=1)
        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 已提交
125 126 127
            96,
            3,
            padding=1,
128
            act="relu",
W
WuHaobo 已提交
129
            name="inception_a" + name + "_3x3")
130 131
        self._conv4_1 = ConvBNLayer(
            384,
W
WuHaobo 已提交
132 133
            64,
            1,
134
            act="relu",
W
WuHaobo 已提交
135
            name="inception_a" + name + "_3x3_2_reduce")
136 137
        self._conv4_2 = ConvBNLayer(
            64,
W
WuHaobo 已提交
138 139 140
            96,
            3,
            padding=1,
141
            act="relu",
W
WuHaobo 已提交
142
            name="inception_a" + name + "_3x3_2")
143 144
        self._conv4_3 = ConvBNLayer(
            96,
W
WuHaobo 已提交
145 146 147
            96,
            3,
            padding=1,
148
            act="relu",
W
WuHaobo 已提交
149 150
            name="inception_a" + name + "_3x3_3")

151 152 153
    def forward(self, inputs):
        pool1 = self._pool(inputs)
        conv1 = self._conv1(pool1)
W
WuHaobo 已提交
154

155
        conv2 = self._conv2(inputs)
W
WuHaobo 已提交
156

157 158
        conv3 = self._conv3_1(inputs)
        conv3 = self._conv3_2(conv3)
W
WuHaobo 已提交
159

160 161 162
        conv4 = self._conv4_1(inputs)
        conv4 = self._conv4_2(conv4)
        conv4 = self._conv4_3(conv4)
W
WuHaobo 已提交
163

164 165
        concat = fluid.layers.concat([conv1, conv2, conv3, conv4], axis=1)
        return concat
W
WuHaobo 已提交
166 167


168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
class ReductionA(fluid.dygraph.Layer):
    def __init__(self):
        super(ReductionA, self).__init__()
        self._pool = Pool2D(pool_size=3, pool_type="max", pool_stride=2)
        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)
        concat = fluid.layers.concat([pool1, conv2, conv3], axis=1)
W
WuHaobo 已提交
188 189 190
        return concat


191 192 193 194 195 196 197 198 199 200
class InceptionB(fluid.dygraph.Layer):
    def __init__(self, name=None):
        super(InceptionB, self).__init__()
        self._pool = Pool2D(pool_size=3, pool_type="avg", pool_padding=1)
        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 已提交
201 202
            192,
            1,
203
            act="relu",
W
WuHaobo 已提交
204
            name="inception_b" + name + "_1x7_reduce")
205 206
        self._conv3_2 = ConvBNLayer(
            192,
W
WuHaobo 已提交
207 208
            224, (1, 7),
            padding=(0, 3),
209
            act="relu",
W
WuHaobo 已提交
210
            name="inception_b" + name + "_1x7")
211 212
        self._conv3_3 = ConvBNLayer(
            224,
W
WuHaobo 已提交
213 214
            256, (7, 1),
            padding=(3, 0),
215
            act="relu",
W
WuHaobo 已提交
216
            name="inception_b" + name + "_7x1")
217 218
        self._conv4_1 = ConvBNLayer(
            1024,
W
WuHaobo 已提交
219 220
            192,
            1,
221
            act="relu",
W
WuHaobo 已提交
222
            name="inception_b" + name + "_7x1_2_reduce")
223 224
        self._conv4_2 = ConvBNLayer(
            192,
W
WuHaobo 已提交
225 226
            192, (1, 7),
            padding=(0, 3),
227
            act="relu",
W
WuHaobo 已提交
228
            name="inception_b" + name + "_1x7_2")
229 230
        self._conv4_3 = ConvBNLayer(
            192,
W
WuHaobo 已提交
231 232
            224, (7, 1),
            padding=(3, 0),
233
            act="relu",
W
WuHaobo 已提交
234
            name="inception_b" + name + "_7x1_2")
235 236
        self._conv4_4 = ConvBNLayer(
            224,
W
WuHaobo 已提交
237 238
            224, (1, 7),
            padding=(0, 3),
239
            act="relu",
W
WuHaobo 已提交
240
            name="inception_b" + name + "_1x7_3")
241 242
        self._conv4_5 = ConvBNLayer(
            224,
W
WuHaobo 已提交
243 244
            256, (7, 1),
            padding=(3, 0),
245
            act="relu",
W
WuHaobo 已提交
246 247
            name="inception_b" + name + "_7x1_3")

248 249 250
    def forward(self, inputs):
        pool1 = self._pool(inputs)
        conv1 = self._conv1(pool1)
W
WuHaobo 已提交
251

252 253 254 255 256
        conv2 = self._conv2(inputs)

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

258 259 260 261 262
        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 已提交
263

264 265
        concat = fluid.layers.concat([conv1, conv2, conv3, conv4], axis=1)
        return concat
W
WuHaobo 已提交
266

267 268 269 270 271 272 273 274 275 276 277 278 279

class ReductionB(fluid.dygraph.Layer):
    def __init__(self):
        super(ReductionB, self).__init__()
        self._pool = Pool2D(pool_size=3, pool_type="max", pool_stride=2)
        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 已提交
280 281
            256, (1, 7),
            padding=(0, 3),
282
            act="relu",
W
WuHaobo 已提交
283
            name="reduction_b_1x7")
284 285
        self._conv3_3 = ConvBNLayer(
            256,
W
WuHaobo 已提交
286 287
            320, (7, 1),
            padding=(3, 0),
288
            act="relu",
W
WuHaobo 已提交
289
            name="reduction_b_7x1")
290 291 292 293 294 295 296 297 298 299 300 301 302
        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 已提交
303 304 305 306 307 308

        concat = fluid.layers.concat([pool1, conv2, conv3], axis=1)

        return concat


309 310 311 312 313 314 315 316 317 318 319 320
class InceptionC(fluid.dygraph.Layer):
    def __init__(self, name=None):
        super(InceptionC, self).__init__()
        self._pool = Pool2D(pool_size=3, pool_type="avg", pool_padding=1)
        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 已提交
321 322
            256, (1, 3),
            padding=(0, 1),
323
            act="relu",
W
WuHaobo 已提交
324
            name="inception_c" + name + "_1x3")
325 326
        self._conv3_2 = ConvBNLayer(
            384,
W
WuHaobo 已提交
327 328
            256, (3, 1),
            padding=(1, 0),
329
            act="relu",
W
WuHaobo 已提交
330
            name="inception_c" + name + "_3x1")
331 332 333 334
        self._conv4_0 = ConvBNLayer(
            1536, 384, 1, act="relu", name="inception_c" + name + "_1x1_4")
        self._conv4_00 = ConvBNLayer(
            384,
W
WuHaobo 已提交
335 336
            448, (1, 3),
            padding=(0, 1),
337
            act="relu",
W
WuHaobo 已提交
338
            name="inception_c" + name + "_1x3_2")
339 340
        self._conv4_000 = ConvBNLayer(
            448,
W
WuHaobo 已提交
341 342
            512, (3, 1),
            padding=(1, 0),
343
            act="relu",
W
WuHaobo 已提交
344
            name="inception_c" + name + "_3x1_2")
345 346
        self._conv4_1 = ConvBNLayer(
            512,
W
WuHaobo 已提交
347 348
            256, (1, 3),
            padding=(0, 1),
349
            act="relu",
W
WuHaobo 已提交
350
            name="inception_c" + name + "_1x3_3")
351 352
        self._conv4_2 = ConvBNLayer(
            512,
W
WuHaobo 已提交
353 354
            256, (3, 1),
            padding=(1, 0),
355
            act="relu",
W
WuHaobo 已提交
356 357
            name="inception_c" + name + "_3x1_3")

358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
    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)

W
WuHaobo 已提交
374 375 376 377
        concat = fluid.layers.concat(
            [conv1, conv2, conv3_1, conv3_2, conv4_1, conv4_2], axis=1)

        return concat
378 379


W
fix  
wqz960 已提交
380
class InceptionV4DY(fluid.dygraph.Layer):
381
    def __init__(self, class_dim=1000):
W
fix  
wqz960 已提交
382
        super(InceptionV4DY, self).__init__()
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
        self._inception_stem = Inception_Stem()

        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")

        self.avg_pool = Pool2D(pool_type='avg', global_pooling=True)
        self._drop = Dropout(p=0.2)
        stdv = 1.0 / math.sqrt(1536 * 1.0)
        self.out = Linear(
            1536,
            class_dim,
            param_attr=ParamAttr(
                initializer=fluid.initializer.Uniform(-stdv, stdv),
                name="final_fc_weights"),
            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)
        x = fluid.layers.squeeze(x, axes=[2, 3])
        x = self._drop(x)
        x = self.out(x)
        return x


def InceptionV4():
W
fix  
wqz960 已提交
445
    model = InceptionV4DY()
446
    return model