예제 #1
0
파일: fcos_head.py 프로젝트: wavce/letsdet
    def _make_shared_convs(self):
        self.box_shared_convs = tf.keras.Sequential(name="box_net")
        self.class_shared_convs = tf.keras.Sequential(name="cls_net")

        i = 0
        for _ in range(self.cfg.repeats):
            self.box_shared_convs.add(
                tf.keras.layers.Conv2D(filters=self.cfg.feat_dims,
                                       kernel_size=(3, 3),
                                       padding="same",
                                       strides=(1, 1),
                                       use_bias=True,
                                       name="%d" % i))
            self.class_shared_convs.add(
                tf.keras.layers.Conv2D(filters=self.cfg.feat_dims,
                                       kernel_size=(3, 3),
                                       strides=(1, 1),
                                       padding="same",
                                       use_bias=True,
                                       name="%d" % i))
            i += 1
            self.box_shared_convs.add(
                build_normalization(name="%d" % i,
                                    **self.cfg.normalization.as_dict()))
            self.class_shared_convs.add(
                build_normalization(name="%d" % i,
                                    **self.cfg.normalization.as_dict()))
            i += 1
            self.box_shared_convs.add(
                build_activation(name="%d" % i,
                                 **self.cfg.activation.as_dict()))
            self.class_shared_convs.add(
                build_activation(name="%d" % i,
                                 **self.cfg.activation.as_dict()))
            i += 1
예제 #2
0
파일: new_resnet.py 프로젝트: wavce/letsdet
    def __init__(self,
                 convolution,
                 filters,
                 strides=1,
                 dilation_rate=1,
                 normalization="group_norm",
                 group=16,
                 activation="relu",
                 weight_decay=0.,
                 use_conv_shortcut=False,
                 **kwargs):
        super(BasicBlock, self).__init__(**kwargs)

        axis = 3 if tf.keras.backend.image_data_format(
        ) == "channels_last" else 1

        self.conv1 = build_convolution(
            convolution,
            filters=filters,
            kernel_size=3,
            strides=strides,
            padding="same",
            dilation_rate=dilation_rate if strides == 1 else 1,
            kernel_regularizer=tf.keras.regularizers.l2(weight_decay),
            use_bias=False)
        self.norm1 = build_normalization(normalization, axis=axis, group=group)
        self.act = tf.keras.layers.Activation(activation)
        self.conv2 = build_convolution(
            convolution,
            filters=filters,
            kernel_size=3,
            strides=1,
            padding="same",
            dilation_rate=dilation_rate,
            kernel_regularizer=tf.keras.regularizers.l2(weight_decay),
            use_bias=False)
        self.norm2 = build_normalization(normalization, axis=axis, group=group)

        if use_conv_shortcut:
            if strides >= 2:
                self.avg_pool = tf.keras.layers.AvgPool2D(2, strides, "same")
            self.conv3 = build_convolution(
                convolution,
                filters=filters,
                kernel_size=1,
                strides=1,
                padding="same",
                kernel_regularizer=tf.keras.regularizers.l2(weight_decay))
            self.norm3 = build_normalization(normalization,
                                             axis=axis,
                                             group=group)

        self.use_conv_shortcut = use_conv_shortcut
예제 #3
0
    def __init__(self,
                 convolution="conv2d",
                 normalization=dict(normalization="batch_norm",
                                    momentum=0.9,
                                    epsilon=1e-3,
                                    axis=-1,
                                    trainable=True),
                 activation=dict(activation="swish"),
                 feat_dims=64,
                 conv_bn_act_pattern=False,
                 data_format="channels_last",
                 name='op_after_combine'):
        super(OpAfterCombine, self).__init__(name=name)
        self.feat_dims = feat_dims
        self.data_format = data_format
        self.conv_bn_act_pattern = conv_bn_act_pattern

        self.conv_op = build_convolution(convolution=convolution,
                                         filters=feat_dims,
                                         kernel_size=(3, 3),
                                         padding='same',
                                         use_bias=not self.conv_bn_act_pattern,
                                         data_format=self.data_format,
                                         name='conv')
        self.bn = build_normalization(**normalization, name='bn')
        self.act = build_activation(**activation)
예제 #4
0
    def build(self, input_shape):
        if self.padding == "same":
            p = ((self.kernel_size[0] - 1) // 2,
                 (self.kernel_size[1] - 1) // 2)
            self.pad = tf.keras.layers.ZeroPadding2D(
                p, data_format=self.data_format)

        self.conv = tf.keras.layers.DepthwiseConv2D(
            kernel_size=self.kernel_size,
            strides=self.strides,
            padding="valid",
            data_format=self.data_format,
            dilation_rate=self.dilation_rate,
            use_bias=self.use_bias,
            trainable=self.trainable,
            kernel_initializer=self.kernel_initializer,
            name="conv2d")
        self.norm_func = (build_normalization(
            name=self.normalization["normalization"], **self.normalization)
                          if self.normalization is not None else None)
        self.act_func = (build_activation(name=self.activation["activation"],
                                          **self.activation)
                         if self.activation is not None else None)
        self.dropblock_func = (DropBlock2D(name="dropblock", **self.dropblock)
                               if self.dropblock is not None else None)
예제 #5
0
파일: densenet.py 프로젝트: wavce/letsdet
    def transition_block(self, x, reduction, strides, trainable, name):
        """A transition block.

        Args:
            x: input tensor.
            reduction: float, compression rate at transition layers.
            strides: integer, stride in pool layer.
            trainable: bool, does freeze this block.
            name: string, block label.

        Returns:
            output tensor for the block.
        """
        bn_axis = 3 if tf.keras.backend.image_data_format(
        ) == "channels_last" else 1
        x = build_normalization(**self.normalization, name=name + "_bn")(x)
        x = tf.keras.layers.Activation(**self.activation,
                                       name=name + "_relu")(x)
        preact = x

        x = build_convolution(
            self.convolution,
            filters=int(tf.keras.backend.int_shape(x)[bn_axis] * reduction),
            kernel_size=1,
            use_bias=False,
            trainable=trainable,
            name=name + "_conv")(x)
        x = tf.keras.layers.AvgPool2D(2, strides=strides,
                                      name=name + "_pool")(x)

        return preact, x
예제 #6
0
    def __init__(self,
                 feat_level,
                 target_num_channels,
                 normalization=dict(normalization="batch_norm",
                                    momentum=0.9,
                                    epsilon=1e-3,
                                    axis=-1,
                                    trainable=True),
                 activation=dict(activation="swish"),
                 apply_bn=False,
                 conv_after_downsample=False,
                 data_format=None,
                 pooling_type=None,
                 upsampling_type=None,
                 name='resample_p0'):
        super(ResampleFeatureMap, self).__init__(name=name)
        self.apply_bn = apply_bn
        self.data_format = data_format
        self.target_num_channels = target_num_channels
        self.feat_level = feat_level
        self.conv_after_downsample = conv_after_downsample
        self.pooling_type = pooling_type or 'max'
        self.upsampling_type = upsampling_type or 'nearest'

        self.conv2d = tf.keras.layers.Conv2D(self.target_num_channels, (1, 1),
                                             padding='same',
                                             data_format=self.data_format,
                                             name='conv2d')
        self.bn = build_normalization(**normalization, name='bn')
예제 #7
0
    def resnet(self):
        trainable = 0 not in self.frozen_stages

        inputs = tf.keras.layers.Lambda(
            function=lambda inp: inp - [123.68, 116.78, 103.94],
            name="mean_subtraction")(self.img_input)
        x = tf.keras.layers.ZeroPadding2D(((3, 3), (3, 3)),
                                          name="conv1_pad")(inputs)
        x = build_convolution(self.convolution,
                              filters=64,
                              kernel_size=(7, 7),
                              strides=self.strides[0],
                              padding="valid",
                              dilation_rate=self.dilation_rates[0],
                              use_bias=True,
                              trainable=trainable,
                              kernel_initializer="he_normal",
                              kernel_regularizer=tf.keras.regularizers.l2(
                                  self.weight_decay),
                              name="conv1_conv")(x)
        x = build_normalization(**self.normalization, name="conv1_bn")(x)
        x1 = build_activation(**self.activation, name="conv1_relu")(x)
        x = tf.keras.layers.ZeroPadding2D(padding=((1, 1), (1, 1)),
                                          name="pool1_pad")(x1)
        x = tf.keras.layers.MaxPool2D((3, 3),
                                      self.strides[1],
                                      "valid",
                                      name="pool1_pool")(x)

        trainable = 2 not in self.frozen_stages
        x2 = self.stack(x, 64, 1, self.dilation_rates[1], trainable,
                        self.blocks[0], "conv2")
        trainable = 3 not in self.frozen_stages
        x3 = self.stack(x2, 128, self.strides[2], self.dilation_rates[2],
                        trainable, self.blocks[1], "conv3")
        trainable = 4 not in self.frozen_stages
        x4 = self.stack(x3, 256, self.strides[3], self.dilation_rates[3],
                        trainable, self.blocks[2], "conv4")
        trainable = 5 not in self.frozen_stages
        x5 = self.stack(x4, 512, self.strides[4], self.dilation_rates[4],
                        trainable, self.blocks[3], "conv5")

        if self._is_classifier:
            x = tf.keras.layers.GlobalAvgPool2D(name="avg_pool")(x5)
            x = tf.keras.layers.Dropout(rate=self.drop_rate)(x)
            outputs = tf.keras.layers.Dense(self.num_classes,
                                            activation="softmax",
                                            name="probs")(x)
            return tf.keras.Model(inputs=self.img_input,
                                  outputs=outputs,
                                  name=self.name)
        else:

            outputs = [
                o for i, o in enumerate([x1, x2, x3, x4, x5])
                if i + 1 in self.output_indices
            ]

        return outputs
예제 #8
0
def squeeze_excitation(inputs,
                       in_filters,
                       se_ratio=0.25,
                       data_format="channels_last",
                       normalization=None,
                       trainable=True,
                       name="se"):
    """Squeeze and excitation implementation.

        Args:
            inputs: `Tensor` of size `[batch, channels, height_in, width_in]`.
            in_filters: `int` number of input filteres before expansion.
            se_ratio: `float` a se ratio between 0 and 1 for squeeze and excitation.
            data_format: An optional string from: "channels_last", "channels_first".
                Defaults to "channels_last".
        Returns:
            A `Tensor` of shape `[batch, filters, height_out, width_out]`.
    """
    if isinstance(se_ratio, float):
        num_reduced_filters = max(1, int(in_filters * se_ratio))
    elif isinstance(se_ratio, int):
        num_reduced_filters = max(1, in_filters // se_ratio)
    else:
        raise ValueError("se_ratio should be `float` or `int`")
    # Process input
    if data_format == "channels_first":
        spatial_dims = [2, 3]
    else:
        spatial_dims = [1, 2]
    x = tf.keras.layers.Lambda(
        lambda inp: tf.reduce_mean(inp, spatial_dims, keepdims=True),
        name=name + "/global_avgpool")(inputs)
    x = tf.keras.layers.Conv2D(
        num_reduced_filters,
        kernel_size=[1, 1],
        strides=[1, 1],
        kernel_initializer=tf.keras.initializers.VarianceScaling(),
        padding="same",
        activation="relu" if normalization is None else None,
        data_format=data_format,
        trainable=trainable,
        name=name + "/squeeze")(x)
    if normalization is not None:
        x = build_normalization(**normalization,
                                name=name + "/squeeze/norm")(x)
        x = tf.keras.layers.ReLU(name=name + "/squeeze/relu")(x)
    x = tf.keras.layers.Conv2D(
        in_filters,
        kernel_size=[1, 1],
        strides=[1, 1],
        kernel_initializer=tf.keras.initializers.VarianceScaling(),
        padding="same",
        data_format=data_format,
        activation="sigmoid",
        trainable=trainable,
        use_bias=True,
        name=name + "/excitation")(x)

    return tf.keras.layers.Multiply(name=name + "/multiply")([x, inputs])
예제 #9
0
    def _make_shared_convs(self):
        self.box_shared_convs = [
            build_convolution(convolution=self.cfg.convolution,
                              filters=self.cfg.feat_dims,
                              kernel_size=(3, 3),
                              strides=(1, 1),
                              padding="same",
                              use_bias=self.cfg.normalization is None
                              or self.cfg.convolution == "separable_conv2d",
                              name="box_net/box-%d" % i)
            for i in range(self.cfg.repeats)
        ]

        if self.cfg.normalization:
            self.box_norm_layers = {
                "level%d" % level: [
                    build_normalization(**self.cfg.normalization.as_dict(),
                                        name="box_net/box-%d-bn-%d" %
                                        (i, level))
                    for i in range(self.cfg.repeats)
                ]
                for level in range(self.min_level, self.max_level + 1)
            }

        self.class_shared_convs = [
            build_convolution(convolution=self.cfg.convolution,
                              filters=self.cfg.feat_dims,
                              kernel_size=(3, 3),
                              strides=(1, 1),
                              padding="same",
                              use_bias=self.cfg.normalization is None
                              or self.cfg.convolution == "separable_conv2d",
                              name="class_net/class-%d" % i)
            for i in range(self.cfg.repeats)
        ]
        if self.cfg.normalization:
            self.class_norm_layers = {
                "level%d" % level: [
                    build_normalization(**self.cfg.normalization.as_dict(),
                                        name="class_net/class-%d-bn-%d" %
                                        (i, level))
                    for i in range(self.cfg.repeats)
                ]
                for level in range(self.min_level, self.max_level + 1)
            }
        self.act_fn = build_activation(**self.cfg.activation.as_dict())
예제 #10
0
파일: densenet.py 프로젝트: wavce/letsdet
    def conv_block(self, x, growth_rate, dilation_rate, drop_rate, trainable,
                   name):
        """A building block for a dense block.

        Args:
            x: input tensor.
            growth_rate: float, growth rate at dense layers.
            dilation_rate: integer, dilation rate.
            drop_rate: float, the dropout rate.
            trainable: bool, does freeze this block
            name: string, block label.

        Returns:
            Output tensor for the block.
        """
        bn_axis = 3 if tf.keras.backend.image_data_format(
        ) == "channels_last" else 1
        x1 = build_normalization(**self.normalization, name=name + "_0_bn")(x)
        x1 = tf.keras.layers.Activation(**self.activation,
                                        name=name + "_0_relu")(x1)

        x1 = build_convolution(self.convolution,
                               filters=4 * growth_rate,
                               kernel_size=1,
                               use_bias=False,
                               trainable=trainable,
                               name=name + "_1_conv")(x1)
        x1 = build_normalization(**self.normalization, name=name + "_1_bn")(x1)
        x1 = tf.keras.layers.Activation(**self.activation,
                                        name=name + "_1_relu")(x1)
        x1 = build_convolution(self.convolution,
                               filters=growth_rate,
                               kernel_size=3,
                               padding="same",
                               dilation_rate=dilation_rate,
                               use_bias=False,
                               trainable=trainable,
                               name=name + "_2_conv")(x1)
        x1 = tf.keras.layers.Dropout(rate=drop_rate)(x1)
        x = tf.keras.layers.Concatenate(axis=bn_axis,
                                        name=name + "_concat")([x, x1])

        return x
예제 #11
0
    def build(self, input_shape):

        if self.strides != (1, 1) and self.padding == "same":
            p = ((self.kernel_size[0] - 1) // 2,
                 (self.kernel_size[1] - 1) // 2)
            self.pad = tf.keras.layers.ZeroPadding2D(
                p, data_format=self.data_format)
            self.padding = "valid"

        self.conv = tf.keras.layers.Conv2D(
            filters=self.filters,
            kernel_size=self.kernel_size,
            strides=self.strides,
            padding=self.padding,
            data_format=self.data_format,
            dilation_rate=self.dilation_rate,
            groups=self.groups,
            use_bias=self.use_bias,
            trainable=self.trainable,
            kernel_initializer=self.kernel_initializer,
            name="conv2d")
        if self.normalization is not None:
            if self.gamma_zeros:
                self.norm_func = build_normalization(
                    name=self.normalization["normalization"],
                    **self.normalization)
            else:
                self.norm_func = build_normalization(
                    gamma_initializer="zeros",
                    name=self.normalization["normalization"],
                    **self.normalization)
        else:
            self.norm_func = None
        self.act_func = (build_activation(name=self.activation["activation"],
                                          **self.activation)
                         if self.activation is not None else None)
        self.dropblock_func = (DropBlock2D(**self.dropblock, name="dropblock")
                               if self.dropblock is not None else None)

        self.built = True
예제 #12
0
def prediction_head(inputs,
                    shared_convolutions,
                    normalization,
                    activation="swish",
                    repeats=3,
                    level=3,
                    name="prediction_head"):
    x = inputs
    for i in range(repeats):
        x = shared_convolutions[i](x)
        if normalization is not None:
            x = build_normalization(normalization=normalization.normalization,
                                    name=name + "-%d-bn-%d" % (i, level))(x)
        if activation is not None:
            x = build_activation(activation=activation.activation,
                                 name=name + "-%d-%s-%d" %
                                 (i, activation.activation, level))(x)
    return x
예제 #13
0
def dcn_deconv(inputs,
               filters,
               deconv_kernel_size,
               deconv_strides=2,
               deconv_padding="same",
               deconv_output_padding=None,
               data_format="channels_last",
               normalization=dict(normalization="batch_norm",
                                  momentum=0.9,
                                  epsilon=1e-5,
                                  axis=-1,
                                  trainable=True),
               activation=dict(activation="relu"),
               kernel_initializer="he_normal",
               groups=1,
               dilation_rate=1,
               name="deconv"):
    x = ConvNormActBlock(filters=filters,
                         kernel_size=3,
                         dilation_rate=dilation_rate,
                         normalization=normalization,
                         activation=activation,
                         kernel_initializer=kernel_initializer,
                         use_bias=True,
                         name=name + "/conv")(inputs)

    deconv_kernel_shape = [
        deconv_kernel_size, deconv_kernel_size, filters, filters
    ]
    x = tf.keras.layers.Conv2DTranspose(
        filters=filters,
        kernel_size=deconv_kernel_size,
        strides=deconv_strides,
        padding=deconv_padding,
        output_padding=deconv_output_padding,
        use_bias=False,
        kernel_initializer=tf.keras.initializers.Constant(
            _deconv_init(deconv_kernel_shape)),
        name=name + "/up_sample")(x)
    x = build_normalization(name=name + "/up_bn", **normalization)(x)
    x = build_activation(name=name + "/relu", **activation)(x)

    return x
예제 #14
0
    def build_model(self):
        # Build stem
        x = self.img_input
        x = layers.Rescaling(1. / 255.)(x)
        x = layers.Normalization(axis=self.bn_axis)(x)

        x = tf.keras.layers.ZeroPadding2D(padding=imagenet_utils.correct_pad(
            x, 3),
                                          name='stem_conv_pad')(x)
        x = tf.keras.layers.Conv2D(self.round_filters(32),
                                   3,
                                   strides=2,
                                   padding='valid',
                                   use_bias=False,
                                   kernel_initializer=CONV_KERNEL_INITIALIZER,
                                   name='stem_conv')(x)

        x = build_normalization(**self.normalization, name='stem_bn')(x)
        x = build_activation(**self.activation, name='stem_activation')(x)

        block_outputs = [x]
        # Build blocks
        blocks_args = copy.deepcopy(self.blocks_args)
        b = 0
        blocks = float(sum(args['repeats'] for args in blocks_args))
        output_stages = [1, 2, 4, 6]
        for (i, args) in enumerate(blocks_args):
            assert args['repeats'] > 0
            # Update block input and output filters based on depth multiplier.
            args['filters_in'] = self.round_filters(args['filters_in'])
            args['filters_out'] = self.round_filters(args['filters_out'])

            strides = args["strides"]

            for j in range(self.round_repeats(args.pop('repeats'))):
                # The first block needs to take care of stride and filter size increase.
                if j > 0:
                    args['strides'] = 1
                    args['filters_in'] = args['filters_out']
                x = self.block(x,
                               self.activation,
                               self.drop_connect_rate * b / blocks,
                               name='block{}{}_'.format(i + 1, chr(j + 97)),
                               **args)
                b += 1
            if i in output_stages:
                block_outputs.append(x)

        # Build top
        x = tf.keras.layers.Conv2D(self.round_filters(1280),
                                   1,
                                   padding='same',
                                   use_bias=False,
                                   kernel_initializer=CONV_KERNEL_INITIALIZER,
                                   name='top_conv')(x)
        x = build_normalization(**self.normalization, name='top_bn')(x)
        x = build_activation(**self.activation, name='top_activation')(x)
        if -1 in self.output_indices:
            x = tf.keras.layers.GlobalAveragePooling2D(name='avg_pool')(x)
            if self.dropout_rate > 0:
                x = tf.keras.layers.Dropout(self.dropout_rate,
                                            name='top_dropout')(x)
            x = tf.keras.layers.Dense(
                1000,
                activation=self.classifier_activation,
                kernel_initializer=DENSE_KERNEL_INITIALIZER,
                name='predictions')(x)
            # Ensure that the model takes into account
            # any potential predecessors of `input_tensor`.
            if self.input_tensor is not None:
                inputs = tf.keras.utils.get_source_inputs(self.input_tensor)
            else:
                inputs = self.img_input
            # Create model.
            return tf.keras.Model(inputs=self.img_input,
                                  outputs=x,
                                  name=model_name)

        return [block_outputs[i - 1] for i in self.output_indices]
예제 #15
0
파일: resnet_rs.py 프로젝트: wavce/letsdet
    def build_model(self):
        # rgb_mean = self._rgb_mean
        # rgb_std = self._rgb_std

        def _norm(inp):
            rgb_mean = tf.constant([0.485 * 255, 0.456 * 255, 0.406 * 255],
                                   inp.dtype, [1, 1, 1, 3])
            rgb_std = tf.constant([0.229 * 255, 0.224 * 255, 0.225 * 255],
                                  inp.dtype, [1, 1, 1, 3])
            return (inp - rgb_mean) * (1. / rgb_std)

        x = tf.keras.layers.Lambda(function=_norm,
                                   name="norm_input")(self.img_input)

        if self.use_resnetd_stem:
            x = ConvNormActBlock(filters=32,
                                 kernel_size=3,
                                 strides=self.strides[0],
                                 dilation_rate=self.dilation_rates[0]
                                 if self.strides[0] == 1 else 1,
                                 trainable=1 not in self.frozen_stages,
                                 kernel_initializer=self.kernel_initializer,
                                 normalization=self.normalization,
                                 activation=self.activation,
                                 data_format=self.data_format,
                                 name="stem/conv1")(x)
            x = ConvNormActBlock(filters=32,
                                 kernel_size=3,
                                 strides=1,
                                 dilation_rate=self.dilation_rates[0],
                                 trainable=1 not in self.frozen_stages,
                                 kernel_initializer=self.kernel_initializer,
                                 normalization=self.normalization,
                                 activation=self.activation,
                                 data_format=self.data_format,
                                 name="stem/conv2")(x)
            x = ConvNormActBlock(
                filters=64,
                kernel_size=3,
                strides=1,
                dilation_rate=self.dilation_rates[0],
                trainable=1 not in self.frozen_stages,
                kernel_initializer=self.kernel_initializer,
                normalization=None
                if self.preactivation else self.normalization,
                activation=None if self.preactivation else self.activation,
                data_format=self.data_format,
                name="stem/conv3")(x)
        else:
            x = ConvNormActBlock(
                filters=64,
                kernel_size=7,
                strides=self.strides[0],
                dilation_rate=self.dilation_rates[0]
                if self.strides[0] == 1 else 1,
                trainable=1 not in self.frozen_stages,
                kernel_initializer=self.kernel_initializer,
                normalization=None
                if self.preactivation else self.normalization,
                activation=None if self.preactivation else self.activation,
                data_format=self.data_format,
                name="stem/conv1")(x)

        if not self.skip_stem_max_pool:
            if self.replace_stem_max_pool:
                x = ConvNormActBlock(
                    filters=64,
                    kernel_size=3,
                    strides=self.strides[1],
                    dilation_rate=1,
                    trainable=1 not in self.frozen_stages,
                    kernel_initializer=self.kernel_initializer,
                    normalization=None
                    if self.preactivation else self.normalization,
                    activation=None if self.preactivation else self.activation,
                    data_format=self.data_format,
                    name="stem/maxpool")(x)
            else:
                x = tf.keras.layers.MaxPool2D(3,
                                              self.strides[1],
                                              "same",
                                              self.data_format,
                                              name="stem/maxpool")(x)

        self.in_filters = 64
        trainable = 2 not in self.frozen_stages
        x = self.stack(x, 64,
                       self.strides[1] if self.skip_stem_max_pool else 1,
                       self.dilation_rates[1], trainable, self.blocks[0],
                       "layer1")
        trainable = 3 not in self.frozen_stages
        x = self.stack(x, 128, self.strides[2], self.dilation_rates[2],
                       trainable, self.blocks[1], "layer2")
        trainable = 4 not in self.frozen_stages
        x = self.stack(x, 256, self.strides[3], self.dilation_rates[3],
                       trainable, self.blocks[2], "layer3")
        trainable = 5 not in self.frozen_stages
        x = self.stack(x, 512, self.strides[4], self.dilation_rates[4],
                       trainable, self.blocks[3], "layer4")
        if self.preactivation:
            x = build_normalization(**self.normalization)(x)
            x = build_activation(**self.activation)(x)
        x = tf.keras.layers.GlobalAvgPool2D(data_format=self.data_format)(x)
        x = tf.keras.layers.Dropout(rate=self.drop_rate)(x)
        x = tf.keras.layers.Dense(self.feat_dim, name="logits")(x)

        model = tf.keras.Model(inputs=self.img_input,
                               outputs=x,
                               name=self.name)

        return model
예제 #16
0
파일: resnet_rs.py 프로젝트: wavce/letsdet
def basic_block(inputs,
                filters,
                strides=1,
                dilation_rate=1,
                data_format="channels_last",
                kernel_initializer=tf.keras.initializers.VarianceScaling(),
                normalization=dict(normalization="batch_norm",
                                   momentum=0.9,
                                   epsilon=1e-3,
                                   axis=-1,
                                   trainable=True),
                init_gamma_zero=True,
                activation=dict(activation="relu"),
                trainable=True,
                dropblock=None,
                use_conv_shortcut=False,
                expansion=1,
                drop_connect_rate=None,
                se_ratio=None,
                preactivation=False,
                use_resnetd_shortcut=True,
                name=None,
                **kwargs):
    """
    Basic Residual block
    
    Args:
        filters(int): integer, filters of the bottleneck layer.
        strides(int): default 1, stride of the first layer.
        dilation_rate(int): default 1, dilation rate in 3x3 convolution.
        data_format(str): default channels_last,
        normalization(dict): the normalization name and hyper-parameters, e.g.
            dict(normalization="batch_norm", momentum=0.9, epsilon=1e-3, axis=-1, trainable=True), 
            dict(normalization="group_norm", epsilon=1e-3, axis=-1) etc.
        activation: the activation layer name.
        trainable: does this block is trainable.
        dropblock: the arguments in DropBlock2D
        use_conv_shortcut: default True, use convolution shortcut if True,
            otherwise identity shortcut.
        name: string, block label, default None.
    """
    if preactivation:
        x = build_normalization(name=name + "/norm1", **normalization)(inputs)
        x = build_activation(name=name + "/%s" % activation["activation"],
                             **activation)(x)
    else:
        x = inputs

    shortcut = x
    x = ConvNormActBlock(filters=filters,
                         kernel_size=3,
                         strides=strides,
                         data_format=data_format,
                         dilation_rate=1 if strides > 1 else dilation_rate,
                         kernel_initializer=kernel_initializer,
                         trainable=trainable,
                         normalization=normalization,
                         activation=activation,
                         dropblock=dropblock,
                         name=name + "/conv1")(x)
    x = ConvNormActBlock(
        filters=filters,
        kernel_size=3,
        strides=1,
        data_format=data_format,
        dilation_rate=dilation_rate,
        kernel_initializer=kernel_initializer,
        trainable=trainable,
        normalization=None if preactivation else normalization,
        activation=None,
        dropblock=dropblock,
        name=name + "/conv2")(x)

    if use_conv_shortcut:
        if use_resnetd_shortcut and strides > 1:
            shortcut = tf.keras.layers.AvgPool2D(pool_size=strides,
                                                 strides=strides,
                                                 padding="same",
                                                 data_format=data_format,
                                                 name=name +
                                                 "/avgpool")(shortcut)
            strides = 1
        shortcut = ConvNormActBlock(
            filters=filters,
            kernel_size=1,
            strides=strides,
            data_format=data_format,
            trainable=trainable,
            kernel_initializer=kernel_initializer,
            normalization=None if preactivation else normalization,
            activation=None,
            dropblock=dropblock,
            gamma_zeros=init_gamma_zero,
            name=name + "/shortcut")(shortcut)

    if preactivation:
        return tf.keras.layers.Add(name=name + "/add")([x, shortcut])

    if se_ratio is not None and se_ratio > 0 and se_ratio <= 1:
        x = squeeze_excitation(x,
                               in_filters=filters * expansion,
                               se_ratio=se_ratio,
                               data_format="channels_last",
                               name=name + "/se")
    if drop_connect_rate:
        x = DropConnect(drop_connect_rate, name=name + "/drop_connect")(x)
    x = tf.keras.layers.Add(name=name + "/add")([x, shortcut])
    x = build_activation(**activation,
                         name=name + "/" + activation["activation"])(x)

    return x
예제 #17
0
def mbconv_block(inputs,
                 global_params,
                 block_args,
                 normalization,
                 drop_connect_rate=None,
                 trainable=True,
                 l2_regularizer=tf.keras.regularizers.l2(l=4e-5),
                 name=""):
    expand_ratio = block_args.expand_ratio
    data_format = global_params.data_format

    _momentum = global_params.batch_norm_momentum
    _epsilon = global_params.batch_norm_epsilon
    _axis = normalization["axis"]
    _mean_axis = [1, 2] if _axis == -1 or _axis == 3 else [2, 3]
    filters = block_args.in_filters * expand_ratio
    expand_ratio = expand_ratio
    if expand_ratio != 1:
        x = tf.keras.layers.Conv2D(
            filters=filters,
            kernel_size=(1, 1),
            strides=(1, 1),
            padding="same",
            data_format=data_format,
            use_bias=False,
            name=name + "/conv2d",
            trainable=trainable,
            kernel_initializer=conv2d_kernel_initializer)(inputs)
        x = build_normalization(**normalization,
                                name=name + "/batch_normalization")(x)
        x = tf.keras.layers.Activation("swish", name=name + "/swish")(x)
    else:
        x = inputs

    # Depthwise Convolution
    # if block_args.strides == 2:
    #     x = tf.keras.layers.ZeroPadding2D(
    #         padding=imagenet_utils.correct_pad(x, block_args.kernel_size),
    #         name=name + '/dwconv_pad')(x)
    #     conv_pad = 'valid'
    # else:
    #     conv_pad = 'same'
    x = tf.keras.layers.DepthwiseConv2D(
        kernel_size=block_args.kernel_size,
        strides=block_args.strides,
        padding="same",
        data_format=data_format,
        use_bias=False,
        trainable=trainable,
        depthwise_initializer=conv2d_kernel_initializer,
        name=name + "/depthwise_conv2d")(x)
    x = build_normalization(**normalization,
                            name=name + "/batch_normalization" if expand_ratio
                            == 1 else name + "/batch_normalization_1")(x)
    x = tf.keras.layers.Activation(
        "swish",
        name=name + "/swish" if expand_ratio == 1 else name + "/swish_1")(x)

    has_se = block_args.se_ratio is not None and 0 < block_args.se_ratio < 1
    if has_se:
        squeeze_filters = max(1,
                              int(block_args.in_filters * block_args.se_ratio))
        se = tf.keras.layers.Lambda(
            lambda inp: tf.reduce_mean(inp, axis=_mean_axis, keepdims=True),
            name=name + "/se/global_pooling")(x)
        se = tf.keras.layers.Conv2D(
            filters=squeeze_filters,
            kernel_size=(1, 1),
            strides=(1, 1),
            padding="same",
            data_format=data_format,
            use_bias=True,
            kernel_initializer=conv2d_kernel_initializer,
            trainable=trainable,
            name=name + "/se/conv2d")(se)
        se = tf.keras.layers.Activation("swish", name=name + "/se/swish_1")(se)
        se = tf.keras.layers.Conv2D(
            filters=filters,
            kernel_size=(1, 1),
            strides=(1, 1),
            padding="same",
            data_format=data_format,
            use_bias=True,
            trainable=trainable,
            kernel_initializer=conv2d_kernel_initializer,
            name=name + "/se/conv2d_1")(se)
        se = tf.keras.layers.Activation("sigmoid",
                                        name=name + "/se/sigmoid")(se)
        x = tf.keras.layers.Multiply(name=name + "/se/multiply")([se, x])

    x = tf.keras.layers.Conv2D(
        block_args.out_filters,
        kernel_size=(1, 1),
        strides=(1, 1),
        padding="same",
        data_format=data_format,
        use_bias=False,
        trainable=trainable,
        kernel_initializer=conv2d_kernel_initializer,
        name=name + "/conv2d" if expand_ratio == 1 else name + "/conv2d_1")(x)
    x = build_normalization(**normalization,
                            name=name + "/batch_normalization_2"
                            if expand_ratio > 1 else name +
                            "/batch_normalization_1")(x)
    if block_args.id_skip:
        if all(s == 1 for s in block_args.strides
               ) and block_args.in_filters == block_args.out_filters:
            # x = DropConnect(drop_connect_rate, name=name + "/drop_connect")(x)
            # x = tf.keras.layers.Dropout(drop_connect_rate, noise_shape=(None, 1, 1, 1), name=name + '/drop')(x)
            x = tf.keras.layers.Add(name=name + "/add")([x, inputs])

    return x
예제 #18
0
    def build_model(self):
        x = tf.keras.layers.Lambda(
            lambda inp:
            (inp - tf.constant([0.485, 0.456, 0.406], dtype=inp.dtype)) *
            (1. / tf.constant([0.229, 0.224, 0.225], dtype=inp.dtype)),
            name="mean_subtraction")(self.img_input)

        x = tf.keras.layers.Conv2D(
            round_filters(32, self.global_params),
            kernel_size=(3, 3),
            strides=(2, 2),
            padding="same",
            data_format=self.data_format,
            use_bias=False,
            kernel_initializer=conv2d_kernel_initializer,
            trainable=1 not in self.frozen_stages,
            kernel_regularizer=self.l2_regularizer,
            name=self.name + "/stem/conv2d")(x)
        x = build_normalization(**self.normalization,
                                name=self.name +
                                "/stem/batch_normalization")(x)
        x = tf.keras.layers.Activation("swish",
                                       name=self.name + "/stem/swish")(x)

        block_outputs = []
        for idx, b_args in enumerate(self.blocks):
            drop_rate = self._drop_connect_rate
            is_reduction = False

            if b_args.super_pixel == 1 and idx == 0:
                block_outputs.append(x)
            elif (idx == self.num_blocks -
                  1) or self.blocks[idx + 1].strides[0] > 1:
                is_reduction = True
            if drop_rate:
                drop_rate = 1.0 - drop_rate * float(idx) / self.num_blocks

            x = mbconv_block(x,
                             global_params=self.global_params,
                             block_args=b_args,
                             normalization=self.normalization,
                             drop_connect_rate=drop_rate,
                             trainable=b_args.trainable,
                             l2_regularizer=self.l2_regularizer,
                             name=self.name + "/blocks_%d" % idx)
            if is_reduction:
                block_outputs.append(x)

        if -1 in self.output_indices:
            # Head part.
            x = tf.keras.layers.Conv2D(
                filters=round_filters(1280, self.global_params),
                kernel_size=[1, 1],
                strides=[1, 1],
                kernel_initializer=conv2d_kernel_initializer,
                padding="same",
                use_bias=False,
                data_format=self.data_format,
                kernel_regularizer=self.l2_regularizer,
                name=self.name + "/head/conv2d")(x)
            x = build_normalization(**self.normalization,
                                    name=self.name +
                                    "/head/batch_normalization")(x)
            x = tf.keras.layers.Activation("swish",
                                           name=self.name + "/head/swish")(x)
            x = tf.keras.layers.GlobalAveragePooling2D(
                data_format=self.data_format,
                name=self.name + "/head/global_avg_pooling")(x)
            x = tf.keras.layers.Dropout(self.global_params.dropout_rate,
                                        name=self.name + "/head/dropout")(x)
            x = tf.keras.layers.Dense(
                self.global_params.num_classes,
                activation="sigmoid",
                kernel_initializer=dense_kernel_initializer,
                name=self.name + "/head/dense")(x)
            outputs = x
            return tf.keras.Model(inputs=self.img_input,
                                  outputs=outputs,
                                  name=self.backbone_name)
        else:
            outputs = [block_outputs[i - 1] for i in self.output_indices]

            return outputs
예제 #19
0
    def resnet_v2(self):
        trainable = 0 not in self.frozen_stages

        x = tf.keras.layers.Lambda(function=lambda inp: inp / 127.5 - 1.,
                                   name="mean_subtraction")(self.img_input)
        x = tf.keras.layers.ZeroPadding2D(padding=((3, 3), (3, 3)),
                                          name="conv1_pad")(x)
        x1 = build_convolution(self.convolution,
                               filters=64,
                               kernel_size=7,
                               strides=self.strides[0],
                               padding="valid",
                               dilation_rate=self.dilation_rates[0],
                               trainable=trainable,
                               kernel_regularizer=tf.keras.regularizers.l2(
                                   self.weight_decay),
                               use_bias=True,
                               name="conv1_conv")(x)

        x = tf.keras.layers.ZeroPadding2D(padding=((1, 1), (1, 1)),
                                          name="pool1_pad")(x1)
        x = tf.keras.layers.MaxPool2D((3, 3),
                                      strides=self.strides[1],
                                      padding="valid",
                                      name="pool1_pool")(x)

        trainable = 1 not in self.frozen_stages
        x, _ = self.stack(x, 64, self.strides[2], self.dilation_rates[1],
                          trainable, self.blocks[0], "conv2")

        trainable = 2 not in self.frozen_stages
        x, preact2 = self.stack(x, 128, self.strides[3],
                                self.dilation_rates[2], trainable,
                                self.blocks[1], "conv3")

        trainable = 3 not in self.frozen_stages
        x, preact3 = self.stack(x, 256, self.strides[4],
                                self.dilation_rates[3], trainable,
                                self.blocks[2], "conv4")

        trainable = 4 not in self.frozen_stages
        x, preact4 = self.stack(x, 512, 1, self.dilation_rates[4], trainable,
                                self.blocks[3], "conv5")
        x = build_normalization(**self.normalization, name="post_bn")(x)
        x5 = tf.keras.layers.Activation(**self.activation, name="post_relu")(x)

        if self._is_classifier:
            x = tf.keras.layers.GlobalAvgPool2D(name="avg_pool")(x5)
            x = tf.keras.layers.Dropout(rate=self.drop_rate)(x)
            x = tf.keras.layers.Dense(self.num_classes,
                                      activation="softmax",
                                      name="probs")(x)

            return tf.keras.Model(inputs=self.img_input,
                                  outputs=x,
                                  name="resnet" + str(self.depth) + "v2")

        outputs = [
            o for i, o in enumerate([x1, preact2, preact3, preact4, x5])
            if i in self.output_indices
        ]

        return outputs
예제 #20
0
    def build_model(self):
        trainable = 0 not in self.frozen_stages

        def _norm(inp):
            inp = tf.image.convert_image_dtype(inp, tf.float32)
            inp = inp / 127.5 - 1.

            return inp

        x = tf.keras.layers.Lambda(function=_norm,
                                   name="norm_input")(self.img_input)
        x = tf.keras.layers.ZeroPadding2D(padding=((3, 3), (3, 3)),
                                          name="conv1_pad")(x)
        x1 = build_convolution(self.convolution,
                               filters=64,
                               kernel_size=7,
                               strides=self.strides[0],
                               padding="valid",
                               dilation_rate=self.dilation_rates[0],
                               trainable=trainable,
                               use_bias=True,
                               name="conv1_conv")(x)

        x = tf.keras.layers.ZeroPadding2D(padding=((1, 1), (1, 1)),
                                          name="pool1_pad")(x1)
        x = tf.keras.layers.MaxPool2D((3, 3),
                                      strides=self.strides[1],
                                      padding="valid",
                                      name="pool1_pool")(x)

        trainable = 1 not in self.frozen_stages
        x, _ = self.stack(x, 64, self.strides[2], self.dilation_rates[1],
                          trainable, self.blocks[0], "conv2")

        trainable = 2 not in self.frozen_stages
        x, preact2 = self.stack(x, 128, self.strides[3],
                                self.dilation_rates[2], trainable,
                                self.blocks[1], "conv3")

        trainable = 3 not in self.frozen_stages
        x, preact3 = self.stack(x, 256, self.strides[4],
                                self.dilation_rates[3], trainable,
                                self.blocks[2], "conv4")

        trainable = 4 not in self.frozen_stages
        x, preact4 = self.stack(x, 512, 1, self.dilation_rates[4], trainable,
                                self.blocks[3], "conv5")
        x = build_normalization(**self.normalization, name="post_bn")(x)
        x5 = tf.keras.layers.Activation(**self.activation, name="post_relu")(x)

        if -1 in self.output_indices:
            x = tf.keras.layers.GlobalAvgPool2D(name="avg_pool")(x5)
            x = tf.keras.layers.Dropout(rate=self.drop_rate)(x)
            outputs = tf.keras.layers.Dense(self.num_classes, name="probs")(x)
        else:
            outputs = [
                o for i, o in enumerate([x1, preact2, preact3, preact4, x5])
                if i in self.output_indices
            ]

        return tf.keras.Model(inputs=self.img_input,
                              outputs=outputs,
                              name=self.name)
예제 #21
0
파일: common.py 프로젝트: wavce/letsdet
    def __init__(self,
                 filters,
                 kernel_size,
                 strides=1,
                 groups=1,
                 modulation=True,
                 padding="same",
                 data_format="channels_last",
                 dilation_rate=1,
                 kernel_initializer="he_normal",
                 trainable=True,
                 use_bias=False,
                 normalization=dict(normalization="batch_norm",
                                    axis=-1,
                                    trainable=True),
                 gamma_zeros=False,
                 activation=None,
                 dropblock=None,
                 name=None):
        super(DCNNormActBlock, self).__init__(name=name)

        assert isinstance(kernel_size, (int, tuple, list))

        self.strides = strides
        if isinstance(kernel_size, int):
            kernel_size = (kernel_size, kernel_size)

        if isinstance(strides, int):
            strides = (strides, strides)

        # if strides != (1, 1):
        #     dilation_rate = (1, 1)
        if isinstance(dilation_rate, int):
            dilation_rate = (dilation_rate, dilation_rate)

        if strides == (1, 1):
            p = 1
            padding == "same"
        else:
            p = ((kernel_size[0] - 1) // 2 * dilation_rate[0],
                 (kernel_size[1] - 1) * dilation_rate[1] // 2)
            self.pad = tf.keras.layers.ZeroPadding2D(p,
                                                     data_format=data_format)
            padding = "valid"

        self.conv = DCNv2(filters=filters,
                          kernel_size=kernel_size,
                          strides=strides,
                          padding=padding,
                          data_format=data_format,
                          dilation_rate=dilation_rate,
                          groups=groups,
                          use_bias=normalization is None or use_bias,
                          trainable=trainable,
                          kernel_initializer=kernel_initializer,
                          name="dcn")
        self._nk = kernel_size * kernel_size if isinstance(
            kernel_size, int) else kernel_size[0] * kernel_size[1]
        if modulation:
            offset_filters = self._nk * 3
            self.offset_conv = tf.keras.layers.Conv2D(
                filters=offset_filters,
                kernel_size=(3, 3),
                strides=strides,
                padding=padding,
                data_format=data_format,
                dilation_rate=dilation_rate,
                groups=groups,
                use_bias=normalization is None or use_bias,
                trainable=trainable,
                kernel_initializer=kernel_initializer,
                name="offset_conv2d")
        else:
            offset_filters = kernel_size * kernel_size * 2 if isinstance(
                kernel_size, int) else kernel_size[0] * kernel_size[1] * 2
            self.offset_conv = tf.keras.layers.Conv2D(
                filters=filters,
                kernel_size=(3, 3),
                strides=strides,
                padding=padding,
                data_format=data_format,
                dilation_rate=dilation_rate,
                groups=groups,
                use_bias=normalization is None or use_bias,
                trainable=trainable,
                kernel_initializer=kernel_initializer,
                name="offset_conv2d")

        self.modulation = modulation

        channel_axis = -1 if data_format == "channels_last" else 1
        if not trainable and normalization is not None:
            normalization["trainable"] = False
        if normalization is not None:
            normalization["axis"] = channel_axis

            self.norm = build_normalization(
                **normalization,
                gamma_initializer="zeros" if gamma_zeros else "ones",
                name=normalization["normalization"])
        else:
            self.norm = None
        # self.act = build_activation(**activation, name=activation["activation"]) if activation is not None else None
        # self.dropblock = DropBlock2D(**dropblock, name="dropblock") if dropblock is not None else None
        if activation is not None:
            self.act = (build_activation(**activation) if isinstance(
                activation, dict) else build_activation(activation=activation))
        else:
            self.act = None
예제 #22
0
    def block(self,
              inputs,
              activation='swish',
              drop_rate=0.,
              name='',
              filters_in=32,
              filters_out=16,
              kernel_size=3,
              strides=1,
              expand_ratio=1,
              se_ratio=0.,
              id_skip=True):
        """An inverted residual block.

            Arguments:
                inputs: input tensor.
                activation: activation function.
                drop_rate: float between 0 and 1, fraction of the input units to drop.
                name: string, block label.
                filters_in: integer, the number of input filters.
                filters_out: integer, the number of output filters.
                kernel_size: integer, the dimension of the convolution window.
                strides: integer, the stride of the convolution.
                expand_ratio: integer, scaling coefficient for the input filters.
                se_ratio: float between 0 and 1, fraction to squeeze the input filters.
                id_skip: boolean.

            Returns:
                output tensor for the block.
        """
        # Expansion phase
        filters = filters_in * expand_ratio
        if expand_ratio != 1:
            x = tf.keras.layers.Conv2D(
                filters,
                1,
                padding='same',
                use_bias=False,
                kernel_initializer=CONV_KERNEL_INITIALIZER,
                name=name + 'expand_conv')(inputs)
            x = build_normalization(**self.normalization,
                                    name=name + 'expand_bn')(x)
            x = build_activation(**self.activation,
                                 name=name + 'expand_activation')(x)
        else:
            x = inputs

        # Depthwise Convolution
        if strides == 2:
            x = tf.keras.layers.ZeroPadding2D(
                padding=imagenet_utils.correct_pad(x, kernel_size),
                name=name + 'dwconv_pad')(x)
            conv_pad = 'valid'
        else:
            conv_pad = 'same'
        x = tf.keras.layers.DepthwiseConv2D(
            kernel_size,
            strides=strides,
            padding=conv_pad,
            use_bias=False,
            depthwise_initializer=CONV_KERNEL_INITIALIZER,
            name=name + 'dwconv')(x)
        x = build_normalization(**self.normalization, name=name + 'bn')(x)
        x = build_activation(**self.activation, name=name + 'activation')(x)

        # Squeeze and Excitation phase
        if 0 < se_ratio <= 1:
            filters_se = max(1, int(filters_in * se_ratio))
            se = tf.keras.layers.GlobalAveragePooling2D(name=name +
                                                        'se_squeeze')(x)
            se = tf.keras.layers.Reshape((1, 1, filters),
                                         name=name + 'se_reshape')(se)
            se = tf.keras.layers.Conv2D(
                filters_se,
                1,
                padding='same',
                activation=activation["activation"],
                kernel_initializer=CONV_KERNEL_INITIALIZER,
                name=name + 'se_reduce')(se)
            se = tf.keras.layers.Conv2D(
                filters,
                1,
                padding='same',
                activation='sigmoid',
                kernel_initializer=CONV_KERNEL_INITIALIZER,
                name=name + 'se_expand')(se)
            x = tf.keras.layers.multiply([x, se], name=name + 'se_excite')

        # Output phase
        x = tf.keras.layers.Conv2D(filters_out,
                                   1,
                                   padding='same',
                                   use_bias=False,
                                   kernel_initializer=CONV_KERNEL_INITIALIZER,
                                   name=name + 'project_conv')(x)
        x = build_normalization(**self.normalization,
                                name=name + 'project_bn')(x)
        if id_skip and strides == 1 and filters_in == filters_out:
            if drop_rate > 0:
                x = tf.keras.layers.Dropout(drop_rate,
                                            noise_shape=(None, 1, 1, 1),
                                            name=name + 'drop')(x)
                x = tf.keras.layers.add([x, inputs], name=name + 'add')
        return x
예제 #23
0
파일: densenet.py 프로젝트: wavce/letsdet
    def build_model(self):
        inputs = tf.keras.layers.Input((None, None, 3))
        trainable = 1 not in self.frozen_stages
        x = tf.keras.layers.Lambda(function=lambda inp: (
            (inp * (1. / 255.)) - self._rgb_mean) / self._rgb_std)(inputs)
        x = tf.keras.layers.ZeroPadding2D(padding=((3, 3), (3, 3)))(x)
        x = build_convolution(self.convolution,
                              filters=64,
                              kernel_size=7,
                              strides=self.strides[0],
                              use_bias=False,
                              trainable=trainable,
                              name="conv1/conv")(x)
        x = build_normalization(**self.normalization, name="conv1/bn")(x)
        x1 = tf.keras.layers.Activation(**self.activation,
                                        name="conv1/relu")(x)

        trainable = 2 not in self.frozen_stages
        x = tf.keras.layers.ZeroPadding2D(padding=((1, 1), (1, 1)))(x)
        x = tf.keras.layers.MaxPool2D(3, strides=self.strides[1],
                                      name="pool1")(x)
        x = self.dense_block(x,
                             blocks=self.blocks[0],
                             dilation_rate=self.dilation_rates[1],
                             drop_rate=self.drop_rate,
                             trainable=trainable,
                             name="conv2")

        trainable = 3 not in self.frozen_stages
        preact2, x = self.transition_block(x, 0.5, self.strides[2], trainable,
                                           "pool2")
        x = self.dense_block(x,
                             blocks=self.blocks[1],
                             dilation_rate=self.dilation_rates[2],
                             drop_rate=self.drop_rate,
                             trainable=trainable,
                             name="conv3")

        trainable = 4 not in self.frozen_stages
        preact3, x = self.transition_block(x, 0.5, self.strides[3], trainable,
                                           "pool3")
        x = self.dense_block(x,
                             blocks=self.blocks[2],
                             dilation_rate=self.dilation_rates[3],
                             drop_rate=self.drop_rate,
                             trainable=trainable,
                             name="conv4")

        trainable = 5 not in self.frozen_stages
        preact4, x = self.transition_block(x, 0.5, self.strides[4], trainable,
                                           "pool4")
        x = self.dense_block(x,
                             blocks=self.blocks[3],
                             dilation_rate=self.dilation_rates[4],
                             drop_rate=self.drop_rate,
                             trainable=trainable,
                             name="conv5")
        x = build_normalization(**self.normalization, name="bn")(x)
        x5 = tf.keras.layers.Activation(**self.activation, name="relu")(x)

        if self._is_classifier:
            x = tf.keras.layers.GlobalAvgPool2D(name="avg_pool")(x5)
            x = tf.keras.layers.Dense(self.num_classes, name="fc1000")(x)

            return tf.keras.Model(inputs=inputs, outputs=x)

        else:
            outputs = [
                o for i, o in enumerate([x1, preact2, preact3, preact4, x5])
                if i + 1 in self.output_indices
            ]

            return tf.keras.Model(inputs=inputs,
                                  outputs=outputs,
                                  name=self.name)
예제 #24
0
def bottleneck_v1(x,
                  convolution,
                  filters,
                  strides=1,
                  dilation_rate=1,
                  normalization=dict(normalization="batch_norm",
                                     momentum=0.9,
                                     epsilon=1e-5,
                                     axis=-1,
                                     trainable=True),
                  activation=dict(activation="relu"),
                  trainable=True,
                  weight_decay=0.,
                  dropblock=None,
                  use_conv_shortcut=True,
                  name=None):
    """A residual block.

        Args:
            x: input tensor.
            filters: integer, filters of the bottleneck layer.
            convolution: The convolution type.
            strides: default 1, stride of the first layer.
            dilation_rate: default 1, dilation rate in 3x3 convolution.
            activation: the activation layer name.
            trainable: does this block is trainable.
            normalization: the normalization, e.g. "batch_norm", "group_norm" etc.
            weight_decay: weight decay.
            dropblock: the arguments in DropBlock2D
            use_conv_shortcut: default True, use convolution shortcut if True,
                otherwise identity shortcut.
            name: string, block label.
        Returns:
            Output tensor for the residual block.
    """
    if use_conv_shortcut is True:
        shortcut = build_convolution(
            convolution,
            filters=4 * filters,
            kernel_size=1,
            strides=strides,
            trainable=trainable,
            kernel_regularizer=tf.keras.regularizers.l2(weight_decay),
            name=name + "_0_conv")(x)
        shortcut = build_normalization(**normalization,
                                       name=name + "_0_bn")(shortcut)
    else:
        shortcut = x

    if dropblock is not None:
        shortcut = DropBlock2D(**dropblock,
                               name=name + "_0_dropblock")(shortcut)

    x = build_convolution(
        convolution,
        filters=filters,
        kernel_size=1,
        strides=strides,
        trainable=trainable,
        kernel_regularizer=tf.keras.regularizers.l2(weight_decay),
        name=name + "_1_conv")(x)
    x = build_normalization(**normalization, name=name + "_1_bn")(x)
    x = tf.keras.layers.Activation(**activation, name=name + "_1_relu")(x)
    if dropblock is not None:
        x = DropBlock2D(**dropblock, name=name + "_1_dropblock")(x)

    x = build_convolution(
        convolution,
        filters=filters,
        kernel_size=3,
        strides=1,
        padding="SAME",
        dilation_rate=dilation_rate,
        trainable=trainable,
        kernel_regularizer=tf.keras.regularizers.l2(weight_decay),
        name=name + "_2_conv")(x)
    x = build_normalization(**normalization, name=name + "_2_bn")(x)
    x = tf.keras.layers.Activation(**activation, name=name + "_2_relu")(x)
    if dropblock is not None:
        x = DropBlock2D(**dropblock, name=name + "_2_dropblock")(x)

    x = build_convolution(
        convolution,
        filters=4 * filters,
        kernel_size=1,
        trainable=trainable,
        kernel_regularizer=tf.keras.regularizers.l2(weight_decay),
        name=name + "_3_conv")(x)
    x = build_normalization(**normalization, name=name + "_3_bn")(x)
    if dropblock is not None:
        x = DropBlock2D(**dropblock, name=name + "_3_dropblock")(x)
    x = tf.keras.layers.Add(name=name + "_add")([shortcut, x])
    x = tf.keras.layers.Activation(**activation, name=name + "_out")(x)

    return x
예제 #25
0
def bottleneckx(x,
                convolution,
                filters,
                strides=1,
                dilation_rate=1,
                cardinality=32,
                normalization=dict(normalization="batch_norm",
                                   momentum=0.9,
                                   epsilon=1e-5,
                                   axis=-1,
                                   trainable=True),
                activation=dict(activation="relu"),
                trainable=True,
                weight_decay=0.,
                use_conv_shortcut=True,
                name=None):
    """A residual block.
        Args:
            x: input tensor.
            filters: integer, filters of the bottleneck layer.
            convolution: The convolution type.
            strides: default 1, stride of the first layer.
            dilation_rate: default 1, dilation rate in 3x3 convolution.
            cardinality: default 32, the cardinality in resnext.
            activation: the activation layer name.
            trainable: does this block is trainable.
            normalization: the normalization, e.g. "batch_norm", "group_norm" etc.
            weight_decay: the weight decay.
            use_conv_shortcut: default True, use convolution shortcut if True,
                otherwise identity shortcut.
            name: string, block label.
        Returns:
            Output tensor for the residual block.
    """
    bn_axis = 3 if tf.keras.backend.image_data_format(
    ) == "channels_last" else 1

    if use_conv_shortcut:
        shortcut = build_convolution(
            convolution,
            filters=(64 // cardinality) * filters,
            kernel_size=1,
            strides=strides,
            use_bias=False,
            trainable=trainable,
            kernel_regularizer=tf.keras.regularizers.l2(weight_decay),
            name=name + "_0_conv")(x)
        shortcut = build_normalization(**normalization,
                                       name=name + "_0_bn")(shortcut)
    else:
        shortcut = x

    x = tf.keras.layers.Conv2D(filters,
                               1,
                               use_bias=False,
                               trainable=trainable,
                               name=name + "_1_conv")(x)
    x = build_normalization(**normalization, name=name + "_1_bn")(x)
    x = tf.keras.layers.Activation(activation, name=name + "_1_relu")(x)

    c = filters // cardinality
    x = tf.keras.layers.ZeroPadding2D(padding=((1, 1), (1, 1)),
                                      name=name + "_2_pad")(x)
    x = tf.keras.layers.DepthwiseConv2D(3,
                                        strides=strides,
                                        depth_multiplier=c,
                                        dilation_rate=dilation_rate,
                                        use_bias=False,
                                        trainable=trainable,
                                        name=name + "_2_conv")(x)
    kernel = np.zeros((1, 1, filters * c, filters), dtype=np.float32)
    for i in range(filters):
        start = (i // c) * c * c + i % c
        end = start + c * c
        kernel[:, :, start:end:c, i] = 1.

    x = tf.keras.layers.Conv2D(filters,
                               1,
                               use_bias=False,
                               trainable=False,
                               kernel_initializer={
                                   "class_name": "Constant",
                                   "config": {
                                       "value": kernel
                                   }
                               },
                               name=name + "_2_gconv")(x)
    x = build_normalization(**normalization, name=name + "_2_bn")(x)
    x = tf.keras.layers.Activation("relu", name=name + "_2_relu")(x)

    x = tf.keras.layers.Conv2D((64 // cardinality) * filters,
                               1,
                               use_bias=False,
                               trainable=trainable,
                               name=name + "_3_conv")(x)
    x = build_normalization(**normalization, name=name + "_3_bn")(x)

    x = tf.keras.layers.Add(name=name + "_add")([shortcut, x])
    x = tf.keras.layers.Activation("relu", name=name + "_out")(x)

    return x
예제 #26
0
def bottleneck_v2(x,
                  convolution,
                  filters,
                  strides=1,
                  dilation_rate=1,
                  normalization=dict(normalization="batch_norm",
                                     momentum=0.9,
                                     epsilon=1e-5,
                                     axis=-1,
                                     trainable=True),
                  activation=dict(activation="relu"),
                  trainable=True,
                  weight_decay=0.,
                  dropblock=None,
                  use_conv_shortcut=True,
                  name=None):
    """A residual block.

        Args:
            x: input tensor.
            filters: integer, filters of the bottleneck layer.
            convolution: The convolution type.
            strides: default 1, stride of the first layer.
            dilation_rate: default 1, dilation rate in 3x3 convolution.
            activation: the activation layer name.
            trainable: does this block is trainable.
            normalization: the normalization, e.g. "batch_norm", "group_norm" etc.
            weight_decay: weight decay.
            dropblock: the arguments in DropBlock2D.
            use_conv_shortcut: default True, use convolution shortcut if True,
                otherwise identity shortcut.
            name: string, block label.
    Returns:
        Output tensor for the residual block.
    """
    bn_axis = 3 if tf.keras.backend.image_data_format(
    ) == "channels_last" else 1

    preact = build_normalization(**normalization, name=name + "_preact_bn")(x)
    preact = tf.keras.layers.Activation(**activation,
                                        name=name + "_preact_relu")(preact)

    if use_conv_shortcut is True:
        shortcut = build_convolution(
            convolution,
            filters=4 * filters,
            kernel_size=1,
            strides=strides,
            trainable=trainable,
            kernel_regularizer=tf.keras.regularizers.l2(weight_decay),
            name=name + "_0_conv")(preact)
    else:
        shortcut = tf.keras.layers.MaxPooling2D(
            1, strides=strides)(x) if strides > 1 else x

    if dropblock is not None:
        shortcut = DropBlock2D(**dropblock,
                               name=name + "_0_dropblock")(shortcut)

    x = build_convolution(
        convolution,
        filters=filters,
        kernel_size=1,
        strides=1,
        use_bias=False,
        trainable=trainable,
        kernel_regularizer=tf.keras.regularizers.l2(weight_decay),
        name=name + "_1_conv")(preact)

    x = build_normalization(**normalization, name=name + "_1_bn")(x)
    x = tf.keras.layers.Activation(**activation, name=name + "_1_relu")(x)
    if dropblock is not None:
        x = DropBlock2D(**dropblock, name=name + "_1_dropblock")(x)

    x = tf.keras.layers.ZeroPadding2D(padding=((1, 1), (1, 1)),
                                      name=name + "_2_pad")(x)
    x = build_convolution(
        convolution,
        filters=filters,
        kernel_size=3,
        strides=strides,
        dilation_rate=1 if strides > 1 else dilation_rate,
        use_bias=False,
        trainable=trainable,
        kernel_regularizer=tf.keras.regularizers.l2(weight_decay),
        name=name + "_2_conv")(x)
    x = build_normalization(**normalization, name=name + "_2_bn")(x)
    x = tf.keras.layers.Activation(**activation, name=name + "_2_relu")(x)
    if dropblock is not None:
        x = DropBlock2D(**dropblock)(x)

    x = build_convolution(
        convolution,
        filters=4 * filters,
        kernel_size=1,
        trainable=trainable,
        kernel_regularizer=tf.keras.regularizers.l2(weight_decay),
        name=name + "_3_conv")(x)
    if dropblock is not None:
        x = DropBlock2D(**dropblock, name=name + "_2_dropblock")(x)
    x = tf.keras.layers.Add(name=name + "_out")([shortcut, x])

    return x, preact
예제 #27
0
파일: common.py 프로젝트: wavce/letsdet
    def __init__(self,
                 filters,
                 kernel_size,
                 strides=1,
                 groups=1,
                 padding="same",
                 data_format="channels_last",
                 dilation_rate=1,
                 kernel_initializer="he_normal",
                 trainable=True,
                 use_bias=False,
                 normalization=dict(normalization="batch_norm",
                                    axis=-1,
                                    trainable=True),
                 gamma_zeros=False,
                 activation=None,
                 dropblock=None,
                 name=None):
        super(ConvNormActBlock, self).__init__(name=name)

        self.strides = strides
        if isinstance(kernel_size, int):
            kernel_size = (kernel_size, kernel_size)

        if isinstance(strides, int):
            strides = (strides, strides)

        # if strides != (1, 1):
        #     dilation_rate = (1, 1)
        if isinstance(dilation_rate, int):
            dilation_rate = (dilation_rate, dilation_rate)

        if strides == (1, 1):
            p = 1
            padding == "same"
        else:
            p = ((kernel_size[0] - 1) // 2 * dilation_rate[0],
                 (kernel_size[1] - 1) * dilation_rate[1] // 2)
            self.pad = tf.keras.layers.ZeroPadding2D(p,
                                                     data_format=data_format)
            padding = "valid"

        self.conv = tf.keras.layers.Conv2D(
            filters=filters,
            kernel_size=kernel_size,
            strides=strides,
            padding=padding,
            data_format=data_format,
            dilation_rate=dilation_rate,
            groups=groups,
            use_bias=normalization is None or use_bias,
            trainable=trainable,
            kernel_initializer=kernel_initializer,
            name="conv2d")
        channel_axis = -1 if data_format == "channels_last" else 1
        if not trainable and normalization is not None:
            normalization["trainable"] = False
        if normalization is not None:
            normalization["axis"] = channel_axis

            norm_name = ("batch_norm"
                         if "batch_norm" in normalization["normalization"] else
                         normalization["normalization"])
            if norm_name == "batch_norm" and not trainable:
                normalization["normalization"] = "frozen_batch_norm"

            self.norm = build_normalization(
                gamma_initializer="zeros" if gamma_zeros else "ones",
                name=norm_name,
                **normalization)
        else:
            self.norm = None
        # self.act = build_activation(**activation, name=activation["activation"]) if activation is not None else None
        # self.dropblock = DropBlock2D(**dropblock, name="dropblock") if dropblock is not None else None
        if activation is not None:
            self.act = (build_activation(**activation) if isinstance(
                activation, dict) else build_activation(activation=activation))
        else:
            self.act = None
예제 #28
0
파일: bifpn.py 프로젝트: wavce/letsdet
def build_bifpn_layer(feats,
                      input_size,
                      feat_dims,
                      convolution="separable_conv2d",
                      normalization=dict(normalization="batch_norm",
                                         momentum=0.9,
                                         epsilon=1e-3,
                                         axis=-1,
                                         trainable=True),
                      activation=dict(activation="swish"),
                      min_level=3,
                      max_level=7,
                      pool_type=None,
                      apply_bn=True,
                      fusion_type="weighted_sum",
                      name="fpn_cells",
                      **kwargs):
    F = lambda x: 1.0 / (2**x)  # Resolution size for a given feature level.
    node_configs = [
        {
            "width_ratio": F(6),
            "inputs_offsets": [3, 4]
        },
        {
            "width_ratio": F(5),
            "inputs_offsets": [2, 5]
        },
        {
            "width_ratio": F(4),
            "inputs_offsets": [1, 6]
        },
        {
            "width_ratio": F(3),
            "inputs_offsets": [0, 7]
        },
        {
            "width_ratio": F(4),
            "inputs_offsets": [1, 7, 8]
        },
        {
            "width_ratio": F(5),
            "inputs_offsets": [2, 6, 9]
        },
        {
            "width_ratio": F(6),
            "inputs_offsets": [3, 5, 10]
        },
        {
            "width_ratio": F(7),
            "inputs_offsets": [4, 11]
        },
    ]

    num_output_connections = [0 for _ in feats]
    for i, fnode in enumerate(node_configs):
        nodes = []
        node_name = name + "/fnode{}".format(i)
        new_node_width = int(fnode["width_ratio"] * input_size[1])
        for idx, input_offset in enumerate(fnode["inputs_offsets"]):
            input_node = feats[input_offset]
            num_output_connections[input_offset] += 1
            input_node = resample_feature_map(
                input_node,
                new_node_width,
                feat_dims,
                convolution=convolution,
                normalization=normalization,
                activation=activation,
                pool_type=pool_type,
                apply_bn=apply_bn,
                name=node_name +
                "/resample_{}_{}_{}".format(idx, input_offset, len(feats)))
            nodes.append(input_node)
        if fusion_type == "weighted_sum":
            if len(fnode["inputs_offsets"]) == 2:
                new_node = WeightedFusion2(name=node_name)(nodes)
            if len(fnode["inputs_offsets"]) == 3:
                new_node = WeightedFusion3(name=node_name)(nodes)
        elif fusion_type == "sum":
            new_node = tf.keras.layers.Add(name=node_name)(nodes)
        else:
            raise ValueError("Unknown fusion type: {}".format(fusion_type))

        new_node_name = node_name + "/op_after_combine{}".format(len(feats))
        new_node = build_activation(**activation,
                                    name=new_node_name + "/" +
                                    activation["activation"])(new_node)

        new_node = build_convolution(convolution,
                                     filters=feat_dims,
                                     kernel_size=(3, 3),
                                     padding="same",
                                     name=new_node_name + "/conv")(new_node)
        new_node = build_normalization(**normalization,
                                       name=new_node_name + "/bn")(new_node)
        # new_node = build_activation(
        #     **activation, name=new_node_name + "/" + activation["activation"] + "_1")(new_node)

        feats.append(new_node)
        num_output_connections.append(0)

    outputs = []
    for level in range(min_level, max_level + 1):
        for i, fnode in enumerate(reversed(node_configs)):
            if fnode["width_ratio"] == F(level):
                outputs.append(feats[-1 - i])
                break

    return outputs
예제 #29
0
파일: new_resnet.py 프로젝트: wavce/letsdet
    def __init__(self,
                 convolution="conv2d",
                 normalization="batch_norm",
                 activation="relu",
                 output_indices=(-1, ),
                 strides=(2, 2, 2, 2, 2),
                 dilation_rates=(1, 1, 1, 1, 1),
                 freezing_stages=(-1, ),
                 freezing_batch_normalization=False,
                 group=32,
                 weight_decay=0.):
        super(NewResNet18, self).__init__(
            convolution=convolution,
            normalization=normalization,
            activation=activation,
            output_indices=output_indices,
            strides=strides,
            dilation_rates=dilation_rates,
            freezing_stages=freezing_stages,
            freezing_batch_normalization=freezing_batch_normalization,
            weight_decay=weight_decay)
        axis = 3 if tf.keras.backend.image_data_format(
        ) == "channels_last" else 1
        self.conv1_1 = tf.keras.Sequential([
            build_convolution(
                convolution,
                filters=16,
                kernsl_size=7,
                padding="same",
                dilation_rate=dilation_rates[0],
                kernel_regularizer=tf.keras.regularizers.l2(weight_decay),
                use_bias=False),
            build_normalization(normalization, asix=axis, group=group),
            tf.keras.layers.Activation(activation)
        ])
        self.conv1_2 = BasicBlock(convolution=convolution,
                                  filters=16,
                                  strides=1,
                                  dilation_rate=dilation_rates[0],
                                  normalization=normalization,
                                  group=16,
                                  activation=activation,
                                  weight_decay=weight_decay,
                                  use_conv_shortcut=False)
        self.conv1_3 = BasicBlock(convolution=convolution,
                                  filters=32,
                                  strides=strides[0],
                                  dilation_rate=dilation_rates[0],
                                  normalization=normalization,
                                  group=16,
                                  activation=activation,
                                  weight_decay=weight_decay,
                                  use_conv_shortcut=True)

        self.conv2_1 = BasicBlock(convolution=convolution,
                                  filters=64,
                                  strides=strides[1],
                                  dilation_rate=dilation_rates[1],
                                  normalization=normalization,
                                  group=16,
                                  activation=activation,
                                  weight_decay=weight_decay,
                                  use_conv_shortcut=True)
        self.conv2_2 = BasicBlock(convolution=convolution,
                                  filters=64,
                                  strides=1,
                                  dilation_rate=dilation_rates[1],
                                  normalization=normalization,
                                  group=16,
                                  activation=activation,
                                  weight_decay=weight_decay,
                                  use_conv_shortcut=False)

        self.conv3_1 = BasicBlock(convolution=convolution,
                                  filters=128,
                                  strides=strides[2],
                                  dilation_rate=dilation_rates[2],
                                  normalization=normalization,
                                  group=16,
                                  activation=activation,
                                  weight_decay=weight_decay,
                                  use_conv_shortcut=True)
        self.conv3_2 = BasicBlock(convolution=convolution,
                                  filters=128,
                                  strides=1,
                                  dilation_rate=dilation_rates[2],
                                  normalization=normalization,
                                  group=16,
                                  activation=activation,
                                  weight_decay=weight_decay,
                                  use_conv_shortcut=False)

        self.conv4_1 = BasicBlock(convolution=convolution,
                                  filters=256,
                                  strides=strides[3],
                                  dilation_rate=dilation_rates[3],
                                  normalization=normalization,
                                  group=16,
                                  activation=activation,
                                  weight_decay=weight_decay,
                                  use_conv_shortcut=True)
        self.conv4_2 = BasicBlock(convolution=convolution,
                                  filters=256,
                                  strides=1,
                                  dilation_rate=dilation_rates[3],
                                  normalization=normalization,
                                  group=16,
                                  activation=activation,
                                  weight_decay=weight_decay,
                                  use_conv_shortcut=False)

        self.conv5_1 = BasicBlock(convolution=convolution,
                                  filters=512,
                                  strides=strides[4],
                                  dilation_rate=dilation_rates[4],
                                  normalization=normalization,
                                  group=16,
                                  activation=activation,
                                  weight_decay=weight_decay,
                                  use_conv_shortcut=True)
        self.conv5_2 = BasicBlock(convolution=convolution,
                                  filters=512,
                                  strides=1,
                                  dilation_rate=dilation_rates[4],
                                  normalization=normalization,
                                  group=16,
                                  activation=activation,
                                  weight_decay=weight_decay,
                                  use_conv_shortcut=False)
예제 #30
0
파일: bifpn.py 프로젝트: wavce/letsdet
def resample_feature_map(feat,
                         target_width,
                         target_num_channels,
                         convolution="separable_conv2d",
                         normalization=dict(normalization="batch_norm",
                                            momentum=0.9,
                                            epsilon=1e-3,
                                            axis=-1,
                                            trainable=True),
                         activation=dict(activation="swish"),
                         pool_type=None,
                         apply_bn=True,
                         name="resample"):
    """Resample input feature map to have target number of channels and width."""
    _, _, width, num_channels = tf.keras.backend.int_shape(feat)
    if width > target_width:
        if num_channels != target_num_channels:
            feat = build_convolution("conv2d",
                                     filters=target_num_channels,
                                     kernel_size=(1, 1),
                                     padding="same",
                                     name=name + "/conv2d")(feat)
            if apply_bn:
                feat = build_normalization(**normalization,
                                           name=name + "/bn")(feat)
        strides = int(width // target_width)

        # if strides >= 2:
        #     feat = tf.keras.layers.ZeroPadding2D(
        #         padding=imagenet_utils.correct_pad(feat, strides + 1),
        #         name=name + '/stem/conv_pad')(feat)
        #     pad = "valid"
        # else:
        #     pad = "same"
        if pool_type == "max" or pool_type is None:
            feat = tf.keras.layers.MaxPool2D(pool_size=strides + 1,
                                             strides=[strides, strides],
                                             padding="same",
                                             name=name + "/max_pool")(feat)
        elif pool_type == "avg":
            feat = tf.keras.layers.AvgPool2D(pool_size=strides + 1,
                                             strides=[strides, strides],
                                             padding="same",
                                             name=name + "/avg_pool")(feat)
        else:
            raise ValueError("Unknown pooling type: {}".format(pool_type))
    else:
        if num_channels != target_num_channels:
            feat = build_convolution("conv2d",
                                     filters=target_num_channels,
                                     kernel_size=(1, 1),
                                     padding="same",
                                     name=name + "/conv2d")(feat)
            if apply_bn:
                feat = build_normalization(**normalization,
                                           name=name + "/bn")(feat)
        if width < target_width:
            scale = target_width // width
            feat = NearestUpsampling2D(scale=scale,
                                       name=name + "/nearest_upsampling")(feat)

    return feat