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
from paddle.fluid import framework
W
WuHaobo 已提交
11

12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
import math
import sys
import time

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

50 51 52 53
    def forward(self, inputs):
        y = self._conv(inputs)
        y = self._batch_norm(y)
        return y
W
WuHaobo 已提交
54 55


56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
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 已提交
75 76
            64, (7, 1),
            padding=(3, 0),
77
            act="relu",
W
WuHaobo 已提交
78
            name="inception_stem2_1x7")
79 80
        self._conv2_3 = ConvBNLayer(
            64,
W
WuHaobo 已提交
81 82
            64, (1, 7),
            padding=(0, 3),
83
            act="relu",
W
WuHaobo 已提交
84
            name="inception_stem2_7x1")
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
        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 已提交
106 107 108

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

109 110
        conv1 = self._conv3(concat)
        pool1 = self._pool(concat)
W
WuHaobo 已提交
111 112 113 114 115

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


116 117 118 119 120 121 122 123 124 125 126 127
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 已提交
128 129 130
            96,
            3,
            padding=1,
131
            act="relu",
W
WuHaobo 已提交
132
            name="inception_a" + name + "_3x3")
133 134
        self._conv4_1 = ConvBNLayer(
            384,
W
WuHaobo 已提交
135 136
            64,
            1,
137
            act="relu",
W
WuHaobo 已提交
138
            name="inception_a" + name + "_3x3_2_reduce")
139 140
        self._conv4_2 = ConvBNLayer(
            64,
W
WuHaobo 已提交
141 142 143
            96,
            3,
            padding=1,
144
            act="relu",
W
WuHaobo 已提交
145
            name="inception_a" + name + "_3x3_2")
146 147
        self._conv4_3 = ConvBNLayer(
            96,
W
WuHaobo 已提交
148 149 150
            96,
            3,
            padding=1,
151
            act="relu",
W
WuHaobo 已提交
152 153
            name="inception_a" + name + "_3x3_3")

154 155 156
    def forward(self, inputs):
        pool1 = self._pool(inputs)
        conv1 = self._conv1(pool1)
W
WuHaobo 已提交
157

158
        conv2 = self._conv2(inputs)
W
WuHaobo 已提交
159

160 161
        conv3 = self._conv3_1(inputs)
        conv3 = self._conv3_2(conv3)
W
WuHaobo 已提交
162

163 164 165
        conv4 = self._conv4_1(inputs)
        conv4 = self._conv4_2(conv4)
        conv4 = self._conv4_3(conv4)
W
WuHaobo 已提交
166

167 168
        concat = fluid.layers.concat([conv1, conv2, conv3, conv4], axis=1)
        return concat
W
WuHaobo 已提交
169 170


171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
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 已提交
191 192 193
        return concat


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

251 252 253
    def forward(self, inputs):
        pool1 = self._pool(inputs)
        conv1 = self._conv1(pool1)
W
WuHaobo 已提交
254

255 256 257 258 259
        conv2 = self._conv2(inputs)

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

261 262 263 264 265
        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 已提交
266

267 268
        concat = fluid.layers.concat([conv1, conv2, conv3, conv4], axis=1)
        return concat
W
WuHaobo 已提交
269

270 271 272 273 274 275 276 277 278 279 280 281 282

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 已提交
283 284
            256, (1, 7),
            padding=(0, 3),
285
            act="relu",
W
WuHaobo 已提交
286
            name="reduction_b_1x7")
287 288
        self._conv3_3 = ConvBNLayer(
            256,
W
WuHaobo 已提交
289 290
            320, (7, 1),
            padding=(3, 0),
291
            act="relu",
W
WuHaobo 已提交
292
            name="reduction_b_7x1")
293 294 295 296 297 298 299 300 301 302 303 304 305
        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 已提交
306 307 308 309 310 311

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

        return concat


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

361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
    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 已提交
377 378 379 380
        concat = fluid.layers.concat(
            [conv1, conv2, conv3_1, conv3_2, conv4_1, conv4_2], axis=1)

        return concat
381 382 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 445 446 447 448 449


class InceptionV4_DY(fluid.dygraph.Layer):
    def __init__(self, class_dim=1000):
        super(InceptionV4_DY, self).__init__()
        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():
    model = InceptionV4_DY()
    return model