You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
560 lines
21 KiB
560 lines
21 KiB
# code was heavily based on https://github.com/pytorch/vision/blob/main/torchvision/models/inception.py |
|
# BSD 3-Clause License |
|
# Copyright (c) Soumith Chintala 2016 |
|
|
|
import math |
|
import paddle |
|
import paddle.nn as nn |
|
from paddle.nn import Conv2D, AvgPool2D, MaxPool2D, BatchNorm, Linear, AdaptiveAvgPool2D |
|
|
|
__all__ = ['InceptionV3'] |
|
|
|
|
|
class InceptionV3(nn.Layer): |
|
DEFAULT_BLOCK_INDEX = 3 |
|
BLOCK_INDEX_BY_DIM = { |
|
64: 0, # First max pooling features |
|
192: 1, # Second max pooling featurs |
|
768: 2, # Pre-aux classifier features |
|
2048: 3 # Final average pooling features |
|
} |
|
|
|
def __init__(self, |
|
output_blocks=[DEFAULT_BLOCK_INDEX], |
|
class_dim=1000, |
|
aux_logits=False, |
|
resize_input=True, |
|
normalize_input=True): |
|
super(InceptionV3, self).__init__() |
|
self.resize_input = resize_input |
|
self.normalize_input = normalize_input |
|
self.output_blocks = sorted(output_blocks) |
|
self.last_needed_block = max(output_blocks) |
|
self.class_dim = class_dim |
|
self.aux_logits = aux_logits |
|
|
|
assert self.last_needed_block <= 3, 'Last possible output block index is 3' |
|
self.blocks = [] |
|
|
|
self.Conv2d_1a_3x3 = ConvBNLayer( |
|
3, 32, 3, stride=2, name='Conv2d_1a_3x3') |
|
self.Conv2d_2a_3x3 = ConvBNLayer(32, 32, 3, name='Conv2d_2a_3x3') |
|
self.Conv2d_2b_3x3 = ConvBNLayer( |
|
32, 64, 3, padding=1, name='Conv2d_2b_3x3') |
|
self.maxpool1 = MaxPool2D(kernel_size=3, stride=2) |
|
|
|
block0 = [ |
|
self.Conv2d_1a_3x3, self.Conv2d_2a_3x3, self.Conv2d_2b_3x3, |
|
self.maxpool1 |
|
] |
|
self.blocks.append(nn.Sequential(*block0)) |
|
### block1 |
|
|
|
if self.last_needed_block >= 1: |
|
self.Conv2d_3b_1x1 = ConvBNLayer(64, 80, 1, name='Conv2d_3b_1x1') |
|
self.Conv2d_4a_3x3 = ConvBNLayer(80, 192, 3, name='Conv2d_4a_3x3') |
|
self.maxpool2 = MaxPool2D(kernel_size=3, stride=2) |
|
block1 = [self.Conv2d_3b_1x1, self.Conv2d_4a_3x3, self.maxpool2] |
|
self.blocks.append(nn.Sequential(*block1)) |
|
|
|
### block2 |
|
### Mixed_5b 5c 5d |
|
if self.last_needed_block >= 2: |
|
self.Mixed_5b = Fid_inceptionA( |
|
192, pool_features=32, name='Mixed_5b') |
|
self.Mixed_5c = Fid_inceptionA( |
|
256, pool_features=64, name='Mixed_5c') |
|
self.Mixed_5d = Fid_inceptionA( |
|
288, pool_features=64, name='Mixed_5d') |
|
|
|
### Mixed_6 |
|
self.Mixed_6a = InceptionB(288, name='Mixed_6a') |
|
self.Mixed_6b = Fid_inceptionC(768, c7=128, name='Mixed_6b') |
|
self.Mixed_6c = Fid_inceptionC(768, c7=160, name='Mixed_6c') |
|
self.Mixed_6d = Fid_inceptionC(768, c7=160, name='Mixed_6d') |
|
self.Mixed_6e = Fid_inceptionC(768, c7=192, name='Mixed_6e') |
|
|
|
block2 = [ |
|
self.Mixed_5b, self.Mixed_5c, self.Mixed_5d, self.Mixed_6a, |
|
self.Mixed_6b, self.Mixed_6c, self.Mixed_6d, self.Mixed_6e |
|
] |
|
self.blocks.append(nn.Sequential(*block2)) |
|
|
|
if self.aux_logits: |
|
self.AuxLogits = InceptionAux(768, self.class_dim, name='AuxLogits') |
|
### block3 |
|
### Mixed_7 |
|
if self.last_needed_block >= 3: |
|
self.Mixed_7a = InceptionD(768, name='Mixed_7a') |
|
self.Mixed_7b = Fid_inceptionE_1(1280, name='Mixed_7b') |
|
self.Mixed_7c = Fid_inceptionE_2(2048, name='Mixed_7c') |
|
self.avgpool = AdaptiveAvgPool2D(output_size=1) |
|
|
|
block3 = [self.Mixed_7a, self.Mixed_7b, self.Mixed_7c, self.avgpool] |
|
self.blocks.append(nn.Sequential(*block3)) |
|
|
|
def forward(self, x): |
|
out = [] |
|
aux = None |
|
if self.resize_input: |
|
x = nn.functional.interpolate( |
|
x, |
|
size=[299, 299], |
|
mode='bilinear', |
|
align_corners=False, |
|
align_mode=0) |
|
|
|
if self.normalize_input: |
|
x = x * 2 - 1 |
|
|
|
for idx, block in enumerate(self.blocks): |
|
x = block(x) |
|
if self.aux_logits and (idx == 2): |
|
aux = self.AuxLogits(x) |
|
if idx in self.output_blocks: |
|
out.append(x) |
|
if idx == self.last_needed_block: |
|
break |
|
|
|
return out, aux |
|
|
|
|
|
class InceptionA(nn.Layer): |
|
def __init__(self, in_channels, pool_features, name=None): |
|
super(InceptionA, self).__init__() |
|
self.branch1x1 = ConvBNLayer( |
|
in_channels, 64, 1, name=name + '.branch1x1') |
|
|
|
self.branch5x5_1 = ConvBNLayer( |
|
in_channels, 48, 1, name=name + '.branch5x5_1') |
|
self.branch5x5_2 = ConvBNLayer( |
|
48, 64, 5, padding=2, name=name + '.branch5x5_2') |
|
|
|
self.branch3x3dbl_1 = ConvBNLayer( |
|
in_channels, 64, 1, name=name + '.branch3x3dbl_1') |
|
self.branch3x3dbl_2 = ConvBNLayer( |
|
64, 96, 3, padding=1, name=name + '.branch3x3dbl_2') |
|
self.branch3x3dbl_3 = ConvBNLayer( |
|
96, 96, 3, padding=1, name=name + '.branch3x3dbl_3') |
|
|
|
self.branch_pool0 = AvgPool2D( |
|
kernel_size=3, stride=1, padding=1, exclusive=True) |
|
self.branch_pool = ConvBNLayer( |
|
in_channels, pool_features, 1, name=name + '.branch_pool') |
|
|
|
def forward(self, x): |
|
branch1x1 = self.branch1x1(x) |
|
|
|
branch5x5 = self.branch5x5_1(x) |
|
branch5x5 = self.branch5x5_2(branch5x5) |
|
|
|
branch3x3dbl = self.branch3x3dbl_1(x) |
|
branch3x3dbl = self.branch3x3dbl_2(branch3x3dbl) |
|
branch3x3dbl = self.branch3x3dbl_3(branch3x3dbl) |
|
|
|
branch_pool = self.branch_pool0(x) |
|
branch_pool = self.branch_pool(branch_pool) |
|
return paddle.concat( |
|
[branch1x1, branch5x5, branch3x3dbl, branch_pool], axis=1) |
|
|
|
|
|
class InceptionB(nn.Layer): |
|
def __init__(self, in_channels, name=None): |
|
super(InceptionB, self).__init__() |
|
self.branch3x3 = ConvBNLayer( |
|
in_channels, 384, 3, stride=2, name=name + '.branch3x3') |
|
|
|
self.branch3x3dbl_1 = ConvBNLayer( |
|
in_channels, 64, 1, name=name + '.branch3x3dbl_1') |
|
self.branch3x3dbl_2 = ConvBNLayer( |
|
64, 96, 3, padding=1, name=name + '.branch3x3dbl_2') |
|
self.branch3x3dbl_3 = ConvBNLayer( |
|
96, 96, 3, stride=2, name=name + '.branch3x3dbl_3') |
|
|
|
self.branch_pool = MaxPool2D(kernel_size=3, stride=2) |
|
|
|
def forward(self, x): |
|
branch3x3 = self.branch3x3(x) |
|
|
|
branch3x3dbl = self.branch3x3dbl_1(x) |
|
branch3x3dbl = self.branch3x3dbl_2(branch3x3dbl) |
|
branch3x3dbl = self.branch3x3dbl_3(branch3x3dbl) |
|
|
|
branch_pool = self.branch_pool(x) |
|
return paddle.concat([branch3x3, branch3x3dbl, branch_pool], axis=1) |
|
|
|
|
|
class InceptionC(nn.Layer): |
|
def __init__(self, in_channels, c7, name=None): |
|
super(InceptionC, self).__init__() |
|
self.branch1x1 = ConvBNLayer( |
|
in_channels, 192, 1, name=name + '.branch1x1') |
|
|
|
self.branch7x7_1 = ConvBNLayer( |
|
in_channels, c7, 1, name=name + '.branch7x7_1') |
|
self.branch7x7_2 = ConvBNLayer( |
|
c7, c7, (1, 7), padding=(0, 3), name=name + '.branch7x7_2') |
|
self.branch7x7_3 = ConvBNLayer( |
|
c7, 192, (7, 1), padding=(3, 0), name=name + '.branch7x7_3') |
|
|
|
self.branch7x7dbl_1 = ConvBNLayer( |
|
in_channels, c7, 1, name=name + '.branch7x7dbl_1') |
|
self.branch7x7dbl_2 = ConvBNLayer( |
|
c7, c7, (7, 1), padding=(3, 0), name=name + '.branch7x7dbl_2') |
|
self.branch7x7dbl_3 = ConvBNLayer( |
|
c7, c7, (1, 7), padding=(0, 3), name=name + '.branch7x7dbl_3') |
|
self.branch7x7dbl_4 = ConvBNLayer( |
|
c7, c7, (7, 1), padding=(3, 0), name=name + '.branch7x7dbl_4') |
|
self.branch7x7dbl_5 = ConvBNLayer( |
|
c7, 192, (1, 7), padding=(0, 3), name=name + '.branch7x7dbl_5') |
|
|
|
self.branch_pool0 = AvgPool2D( |
|
kernel_size=3, stride=1, padding=1, exclusive=True) |
|
self.branch_pool = ConvBNLayer( |
|
in_channels, 192, 1, name=name + '.branch_pool') |
|
|
|
def forward(self, x): |
|
branch1x1 = self.branch1x1(x) |
|
|
|
branch7x7 = self.branch7x7_1(x) |
|
branch7x7 = self.branch7x7_2(branch7x7) |
|
branch7x7 = self.branch7x7_3(branch7x7) |
|
|
|
branch7x7dbl = self.branch7x7dbl_1(x) |
|
branch7x7dbl = self.branch7x7dbl_2(branch7x7dbl) |
|
branch7x7dbl = self.branch7x7dbl_3(branch7x7dbl) |
|
branch7x7dbl = self.branch7x7dbl_4(branch7x7dbl) |
|
branch7x7dbl = self.branch7x7dbl_5(branch7x7dbl) |
|
|
|
branch_pool = self.branch_pool0(x) |
|
branch_pool = self.branch_pool(branch_pool) |
|
|
|
return paddle.concat( |
|
[branch1x1, branch7x7, branch7x7dbl, branch_pool], axis=1) |
|
|
|
|
|
class InceptionD(nn.Layer): |
|
def __init__(self, in_channels, name=None): |
|
super(InceptionD, self).__init__() |
|
self.branch3x3_1 = ConvBNLayer( |
|
in_channels, 192, 1, name=name + '.branch3x3_1') |
|
self.branch3x3_2 = ConvBNLayer( |
|
192, 320, 3, stride=2, name=name + '.branch3x3_2') |
|
|
|
self.branch7x7x3_1 = ConvBNLayer( |
|
in_channels, 192, 1, name=name + '.branch7x7x3_1') |
|
self.branch7x7x3_2 = ConvBNLayer( |
|
192, 192, (1, 7), padding=(0, 3), name=name + '.branch7x7x3_2') |
|
self.branch7x7x3_3 = ConvBNLayer( |
|
192, 192, (7, 1), padding=(3, 0), name=name + '.branch7x7x3_3') |
|
self.branch7x7x3_4 = ConvBNLayer( |
|
192, 192, 3, stride=2, name=name + '.branch7x7x3_4') |
|
|
|
self.branch_pool = MaxPool2D(kernel_size=3, stride=2) |
|
|
|
def forward(self, x): |
|
branch3x3 = self.branch3x3_1(x) |
|
branch3x3 = self.branch3x3_2(branch3x3) |
|
|
|
branch7x7x3 = self.branch7x7x3_1(x) |
|
branch7x7x3 = self.branch7x7x3_2(branch7x7x3) |
|
branch7x7x3 = self.branch7x7x3_3(branch7x7x3) |
|
branch7x7x3 = self.branch7x7x3_4(branch7x7x3) |
|
|
|
branch_pool = self.branch_pool(x) |
|
|
|
return paddle.concat([branch3x3, branch7x7x3, branch_pool], axis=1) |
|
|
|
|
|
class InceptionE(nn.Layer): |
|
def __init__(self, in_channels, name=None): |
|
super(InceptionE, self).__init__() |
|
self.branch1x1 = ConvBNLayer( |
|
in_channels, 320, 1, name=name + '.branch1x1') |
|
|
|
self.branch3x3_1 = ConvBNLayer( |
|
in_channels, 384, 1, name=name + '.branch3x3_1') |
|
self.branch3x3_2a = ConvBNLayer( |
|
384, 384, (1, 3), padding=(0, 1), name=name + '.branch3x3_2a') |
|
self.branch3x3_2b = ConvBNLayer( |
|
384, 384, (3, 1), padding=(1, 0), name=name + '.branch3x3_2b') |
|
|
|
self.branch3x3dbl_1 = ConvBNLayer( |
|
in_channels, 448, 1, name=name + '.branch3x3dbl_1') |
|
self.branch3x3dbl_2 = ConvBNLayer( |
|
448, 384, 3, padding=1, name=name + '.branch3x3dbl_2') |
|
self.branch3x3dbl_3a = ConvBNLayer( |
|
384, 384, (1, 3), padding=(0, 1), name=name + '.branch3x3dbl_3a') |
|
self.branch3x3dbl_3b = ConvBNLayer( |
|
384, 384, (3, 1), padding=(1, 0), name=name + '.branch3x3dbl_3b') |
|
|
|
self.branch_pool0 = AvgPool2D( |
|
kernel_size=3, stride=1, padding=1, exclusive=True) |
|
self.branch_pool = ConvBNLayer( |
|
in_channels, 192, 1, name=name + '.branch_pool') |
|
|
|
def forward(self, x): |
|
branch1x1 = self.branch1x1(x) |
|
branch3x3_1 = self.branch3x3_1(x) |
|
branch3x3_2a = self.branch3x3_2a(branch3x3_1) |
|
branch3x3_2b = self.branch3x3_2b(branch3x3_1) |
|
branch3x3 = paddle.concat([branch3x3_2a, branch3x3_2b], axis=1) |
|
|
|
branch3x3dbl = self.branch3x3dbl_1(x) |
|
branch3x3dbl = self.branch3x3dbl_2(branch3x3dbl) |
|
branch3x3dbl_3a = self.branch3x3dbl_3a(branch3x3dbl) |
|
branch3x3dbl_3b = self.branch3x3dbl_3b(branch3x3dbl) |
|
branch3x3dbl = paddle.concat([branch3x3dbl_3a, branch3x3dbl_3b], axis=1) |
|
|
|
branch_pool = self.branch_pool0(x) |
|
branch_pool = self.branch_pool(branch_pool) |
|
|
|
return paddle.concat( |
|
[branch1x1, branch3x3, branch3x3dbl, branch_pool], axis=1) |
|
|
|
|
|
class InceptionAux(nn.Layer): |
|
def __init__(self, in_channels, num_classes, name=None): |
|
super(InceptionAux, self).__init__() |
|
self.num_classes = num_classes |
|
self.pool0 = AvgPool2D(kernel_size=5, stride=3) |
|
self.conv0 = ConvBNLayer(in_channels, 128, 1, name=name + '.conv0') |
|
self.conv1 = ConvBNLayer(128, 768, 5, name=name + '.conv1') |
|
self.pool1 = AvgPool2D(global_pooling=True) |
|
|
|
def forward(self, x): |
|
x = self.pool0(x) |
|
x = self.conv0(x) |
|
x = self.conv1(x) |
|
x = self.pool1(x) |
|
x = paddle.flatten(x, axis=1) |
|
x = paddle.static.nn.fc(x, size=self.num_classes) |
|
return x |
|
|
|
|
|
class Fid_inceptionA(nn.Layer): |
|
""" FID block in inception v3 |
|
""" |
|
|
|
def __init__(self, in_channels, pool_features, name=None): |
|
super(Fid_inceptionA, self).__init__() |
|
self.branch1x1 = ConvBNLayer( |
|
in_channels, 64, 1, name=name + '.branch1x1') |
|
|
|
self.branch5x5_1 = ConvBNLayer( |
|
in_channels, 48, 1, name=name + '.branch5x5_1') |
|
self.branch5x5_2 = ConvBNLayer( |
|
48, 64, 5, padding=2, name=name + '.branch5x5_2') |
|
|
|
self.branch3x3dbl_1 = ConvBNLayer( |
|
in_channels, 64, 1, name=name + '.branch3x3dbl_1') |
|
self.branch3x3dbl_2 = ConvBNLayer( |
|
64, 96, 3, padding=1, name=name + '.branch3x3dbl_2') |
|
self.branch3x3dbl_3 = ConvBNLayer( |
|
96, 96, 3, padding=1, name=name + '.branch3x3dbl_3') |
|
|
|
self.branch_pool0 = AvgPool2D( |
|
kernel_size=3, stride=1, padding=1, exclusive=True) |
|
self.branch_pool = ConvBNLayer( |
|
in_channels, pool_features, 1, name=name + '.branch_pool') |
|
|
|
def forward(self, x): |
|
branch1x1 = self.branch1x1(x) |
|
|
|
branch5x5 = self.branch5x5_1(x) |
|
branch5x5 = self.branch5x5_2(branch5x5) |
|
|
|
branch3x3dbl = self.branch3x3dbl_1(x) |
|
branch3x3dbl = self.branch3x3dbl_2(branch3x3dbl) |
|
branch3x3dbl = self.branch3x3dbl_3(branch3x3dbl) |
|
|
|
branch_pool = self.branch_pool0(x) |
|
branch_pool = self.branch_pool(branch_pool) |
|
return paddle.concat( |
|
[branch1x1, branch5x5, branch3x3dbl, branch_pool], axis=1) |
|
|
|
|
|
class Fid_inceptionC(nn.Layer): |
|
""" FID block in inception v3 |
|
""" |
|
|
|
def __init__(self, in_channels, c7, name=None): |
|
super(Fid_inceptionC, self).__init__() |
|
self.branch1x1 = ConvBNLayer( |
|
in_channels, 192, 1, name=name + '.branch1x1') |
|
|
|
self.branch7x7_1 = ConvBNLayer( |
|
in_channels, c7, 1, name=name + '.branch7x7_1') |
|
self.branch7x7_2 = ConvBNLayer( |
|
c7, c7, (1, 7), padding=(0, 3), name=name + '.branch7x7_2') |
|
self.branch7x7_3 = ConvBNLayer( |
|
c7, 192, (7, 1), padding=(3, 0), name=name + '.branch7x7_3') |
|
|
|
self.branch7x7dbl_1 = ConvBNLayer( |
|
in_channels, c7, 1, name=name + '.branch7x7dbl_1') |
|
self.branch7x7dbl_2 = ConvBNLayer( |
|
c7, c7, (7, 1), padding=(3, 0), name=name + '.branch7x7dbl_2') |
|
self.branch7x7dbl_3 = ConvBNLayer( |
|
c7, c7, (1, 7), padding=(0, 3), name=name + '.branch7x7dbl_3') |
|
self.branch7x7dbl_4 = ConvBNLayer( |
|
c7, c7, (7, 1), padding=(3, 0), name=name + '.branch7x7dbl_4') |
|
self.branch7x7dbl_5 = ConvBNLayer( |
|
c7, 192, (1, 7), padding=(0, 3), name=name + '.branch7x7dbl_5') |
|
|
|
self.branch_pool0 = AvgPool2D( |
|
kernel_size=3, stride=1, padding=1, exclusive=True) |
|
self.branch_pool = ConvBNLayer( |
|
in_channels, 192, 1, name=name + '.branch_pool') |
|
|
|
def forward(self, x): |
|
branch1x1 = self.branch1x1(x) |
|
|
|
branch7x7 = self.branch7x7_1(x) |
|
branch7x7 = self.branch7x7_2(branch7x7) |
|
branch7x7 = self.branch7x7_3(branch7x7) |
|
|
|
branch7x7dbl = self.branch7x7dbl_1(x) |
|
branch7x7dbl = self.branch7x7dbl_2(branch7x7dbl) |
|
branch7x7dbl = self.branch7x7dbl_3(branch7x7dbl) |
|
branch7x7dbl = self.branch7x7dbl_4(branch7x7dbl) |
|
branch7x7dbl = self.branch7x7dbl_5(branch7x7dbl) |
|
|
|
branch_pool = self.branch_pool0(x) |
|
branch_pool = self.branch_pool(branch_pool) |
|
|
|
return paddle.concat( |
|
[branch1x1, branch7x7, branch7x7dbl, branch_pool], axis=1) |
|
|
|
|
|
class Fid_inceptionE_1(nn.Layer): |
|
""" FID block in inception v3 |
|
""" |
|
|
|
def __init__(self, in_channels, name=None): |
|
super(Fid_inceptionE_1, self).__init__() |
|
self.branch1x1 = ConvBNLayer( |
|
in_channels, 320, 1, name=name + '.branch1x1') |
|
|
|
self.branch3x3_1 = ConvBNLayer( |
|
in_channels, 384, 1, name=name + '.branch3x3_1') |
|
self.branch3x3_2a = ConvBNLayer( |
|
384, 384, (1, 3), padding=(0, 1), name=name + '.branch3x3_2a') |
|
self.branch3x3_2b = ConvBNLayer( |
|
384, 384, (3, 1), padding=(1, 0), name=name + '.branch3x3_2b') |
|
|
|
self.branch3x3dbl_1 = ConvBNLayer( |
|
in_channels, 448, 1, name=name + '.branch3x3dbl_1') |
|
self.branch3x3dbl_2 = ConvBNLayer( |
|
448, 384, 3, padding=1, name=name + '.branch3x3dbl_2') |
|
self.branch3x3dbl_3a = ConvBNLayer( |
|
384, 384, (1, 3), padding=(0, 1), name=name + '.branch3x3dbl_3a') |
|
self.branch3x3dbl_3b = ConvBNLayer( |
|
384, 384, (3, 1), padding=(1, 0), name=name + '.branch3x3dbl_3b') |
|
|
|
self.branch_pool0 = AvgPool2D( |
|
kernel_size=3, stride=1, padding=1, exclusive=True) |
|
self.branch_pool = ConvBNLayer( |
|
in_channels, 192, 1, name=name + '.branch_pool') |
|
|
|
def forward(self, x): |
|
branch1x1 = self.branch1x1(x) |
|
branch3x3_1 = self.branch3x3_1(x) |
|
branch3x3_2a = self.branch3x3_2a(branch3x3_1) |
|
branch3x3_2b = self.branch3x3_2b(branch3x3_1) |
|
branch3x3 = paddle.concat([branch3x3_2a, branch3x3_2b], axis=1) |
|
|
|
branch3x3dbl = self.branch3x3dbl_1(x) |
|
branch3x3dbl = self.branch3x3dbl_2(branch3x3dbl) |
|
branch3x3dbl_3a = self.branch3x3dbl_3a(branch3x3dbl) |
|
branch3x3dbl_3b = self.branch3x3dbl_3b(branch3x3dbl) |
|
branch3x3dbl = paddle.concat([branch3x3dbl_3a, branch3x3dbl_3b], axis=1) |
|
|
|
branch_pool = self.branch_pool0(x) |
|
branch_pool = self.branch_pool(branch_pool) |
|
|
|
return paddle.concat( |
|
[branch1x1, branch3x3, branch3x3dbl, branch_pool], axis=1) |
|
|
|
|
|
class Fid_inceptionE_2(nn.Layer): |
|
""" FID block in inception v3 |
|
""" |
|
|
|
def __init__(self, in_channels, name=None): |
|
super(Fid_inceptionE_2, self).__init__() |
|
self.branch1x1 = ConvBNLayer( |
|
in_channels, 320, 1, name=name + '.branch1x1') |
|
|
|
self.branch3x3_1 = ConvBNLayer( |
|
in_channels, 384, 1, name=name + '.branch3x3_1') |
|
self.branch3x3_2a = ConvBNLayer( |
|
384, 384, (1, 3), padding=(0, 1), name=name + '.branch3x3_2a') |
|
self.branch3x3_2b = ConvBNLayer( |
|
384, 384, (3, 1), padding=(1, 0), name=name + '.branch3x3_2b') |
|
|
|
self.branch3x3dbl_1 = ConvBNLayer( |
|
in_channels, 448, 1, name=name + '.branch3x3dbl_1') |
|
self.branch3x3dbl_2 = ConvBNLayer( |
|
448, 384, 3, padding=1, name=name + '.branch3x3dbl_2') |
|
self.branch3x3dbl_3a = ConvBNLayer( |
|
384, 384, (1, 3), padding=(0, 1), name=name + '.branch3x3dbl_3a') |
|
self.branch3x3dbl_3b = ConvBNLayer( |
|
384, 384, (3, 1), padding=(1, 0), name=name + '.branch3x3dbl_3b') |
|
### same with paper |
|
self.branch_pool0 = MaxPool2D(kernel_size=3, stride=1, padding=1) |
|
self.branch_pool = ConvBNLayer( |
|
in_channels, 192, 1, name=name + '.branch_pool') |
|
|
|
def forward(self, x): |
|
branch1x1 = self.branch1x1(x) |
|
branch3x3_1 = self.branch3x3_1(x) |
|
branch3x3_2a = self.branch3x3_2a(branch3x3_1) |
|
branch3x3_2b = self.branch3x3_2b(branch3x3_1) |
|
branch3x3 = paddle.concat([branch3x3_2a, branch3x3_2b], axis=1) |
|
|
|
branch3x3dbl = self.branch3x3dbl_1(x) |
|
branch3x3dbl = self.branch3x3dbl_2(branch3x3dbl) |
|
branch3x3dbl_3a = self.branch3x3dbl_3a(branch3x3dbl) |
|
branch3x3dbl_3b = self.branch3x3dbl_3b(branch3x3dbl) |
|
branch3x3dbl = paddle.concat([branch3x3dbl_3a, branch3x3dbl_3b], axis=1) |
|
|
|
branch_pool = self.branch_pool0(x) |
|
branch_pool = self.branch_pool(branch_pool) |
|
|
|
return paddle.concat( |
|
[branch1x1, branch3x3, branch3x3dbl, branch_pool], axis=1) |
|
|
|
|
|
class ConvBNLayer(nn.Layer): |
|
def __init__(self, |
|
in_channels, |
|
num_filters, |
|
filter_size, |
|
stride=1, |
|
padding=0, |
|
groups=1, |
|
act='relu', |
|
name=None): |
|
super(ConvBNLayer, self).__init__() |
|
self.conv = Conv2D( |
|
in_channels=in_channels, |
|
out_channels=num_filters, |
|
kernel_size=filter_size, |
|
stride=stride, |
|
padding=padding, |
|
groups=groups, |
|
weight_attr=paddle.ParamAttr(name=name + ".conv.weight"), |
|
bias_attr=False) |
|
self.bn = BatchNorm( |
|
num_filters, |
|
act=act, |
|
epsilon=0.001, |
|
param_attr=paddle.ParamAttr(name=name + ".bn.weight"), |
|
bias_attr=paddle.ParamAttr(name=name + ".bn.bias"), |
|
moving_mean_name=name + '.bn.running_mean', |
|
moving_variance_name=name + '.bn.running_var') |
|
|
|
def forward(self, inputs): |
|
y = self.conv(inputs) |
|
y = self.bn(y) |
|
return y
|
|
|