import paddle import paddle.fluid as fluid from paddle.fluid.param_attr import ParamAttr from paddle.fluid.dygraph.nn import Conv2D, Pool2D, BatchNorm, Linear __all__ = ["VGG11", "VGG13", "VGG16", "VGG19"] class ConvBlock(fluid.dygraph.Layer): def __init__(self, input_channels, output_channels, groups, name=None): super(ConvBlock, self).__init__() self.groups = groups self._conv_1 = Conv2D(num_channels=input_channels, num_filters=output_channels, filter_size=3, stride=1, padding=1, act="relu", param_attr=ParamAttr(name=name + "1_weights"), bias_attr=False) if groups == 2 or groups == 3 or groups == 4: self._conv_2 = Conv2D(num_channels=output_channels, num_filters=output_channels, filter_size=3, stride=1, padding=1, act="relu", param_attr=ParamAttr(name=name + "2_weights"), bias_attr=False) if groups == 3 or groups == 4: self._conv_3 = Conv2D(num_channels=output_channels, num_filters=output_channels, filter_size=3, stride=1, padding=1, act="relu", param_attr=ParamAttr(name=name + "3_weights"), bias_attr=False) if groups == 4: self._conv_4 = Conv2D(num_channels=output_channels, num_filters=output_channels, filter_size=3, stride=1, padding=1, act="relu", param_attr=ParamAttr(name=name + "4_weights"), bias_attr=False) self._pool = Pool2D(pool_size=2, pool_type="max", pool_stride=2) def forward(self, inputs): x = self._conv_1(inputs) if self.groups == 2 or self.groups == 3 or self.groups == 4: x = self._conv_2(x) if self.groups == 3 or self.groups == 4 : x = self._conv_3(x) if self.groups == 4: x = self._conv_4(x) x = self._pool(x) return x class VGGNet(fluid.dygraph.Layer): def __init__(self, layers=11, class_dim=1000): super(VGGNet, self).__init__() self.layers = layers self.vgg_configure = {11: [1, 1, 2, 2, 2], 13: [2, 2, 2, 2, 2], 16: [2, 2, 3, 3, 3], 19: [2, 2, 4, 4, 4]} assert self.layers in self.vgg_configure.keys(), \ "supported layers are {} but input layer is {}".format(vgg_configure.keys(), layers) self.groups = self.vgg_configure[self.layers] self._conv_block_1 = ConvBlock(3, 64, self.groups[0], name="conv1_") self._conv_block_2 = ConvBlock(64, 128, self.groups[1], name="conv2_") self._conv_block_3 = ConvBlock(128, 256, self.groups[2], name="conv3_") self._conv_block_4 = ConvBlock(256, 512, self.groups[3], name="conv4_") self._conv_block_5 = ConvBlock(512, 512, self.groups[4], name="conv5_") self._drop = fluid.dygraph.Dropout(p=0.5) self._fc1 = Linear(input_dim=7*7*512, output_dim=4096, act="relu", param_attr=ParamAttr(name="fc6_weights"), bias_attr=ParamAttr(name="fc6_offset")) self._fc2 = Linear(input_dim=4096, output_dim=4096, act="relu", param_attr=ParamAttr(name="fc7_weights"), bias_attr=ParamAttr(name="fc7_offset")) self._out = Linear(input_dim=4096, output_dim=class_dim, param_attr=ParamAttr(name="fc8_weights"), bias_attr=ParamAttr(name="fc8_offset")) def forward(self, inputs): x = self._conv_block_1(inputs) x = self._conv_block_2(x) x = self._conv_block_3(x) x = self._conv_block_4(x) x = self._conv_block_5(x) x = fluid.layers.reshape(x, [0,-1]) x = self._fc1(x) x = self._drop(x) x = self._fc2(x) x = self._drop(x) x = self._out(x) return x def VGG11(**args): model = VGGNet(layers=11, **args) return model def VGG13(**args): model = VGGNet(layers=13, **args) return model def VGG16(**args): model = VGGNet(layers=16, **args) return model def VGG19(**args): model = VGGNet(layers=19, **args) return model