Beispiel #1
0
    def build(self) -> tf.keras.models.Model:
        x = self.stem_module(self.section_filters[0], self.image_input)

        for block, (layers, filters) in enumerate(
                zip(self.section_blocks, self.section_filters)):
            for layer in range(layers):
                if filters != x.shape[-1]:
                    x = self.transition_block(x, filters, strides=2)
                x = self.residual_block(x)

        if self.include_top:
            x = tf.keras.layers.Activation("relu")(x)
            x = utils.global_pool(x)
            x = lq.layers.QuantDense(
                self.num_classes,
                kernel_initializer="glorot_normal",
            )(x)
            x = tf.keras.layers.Activation("softmax", dtype="float32")(x)

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

        # Load weights.
        if self.weights == "imagenet":
            weights_path = (self.imagenet_weights_path if self.include_top else
                            self.imagenet_no_top_weights_path)
            model.load_weights(weights_path)
        elif self.weights is not None:
            model.load_weights(self.weights)
        return model
Beispiel #2
0
    def _scale_binary_conv_output(self, conv_input: tf.Tensor,
                                  conv_output: tf.Tensor,
                                  name: str) -> tf.Tensor:
        """Data-dependent convolution scaling.

        Scales the output of the convolution in the (squeeze-and-excite
        style) data-dependent way described in Section 4.3 of Martinez at. al.
        """
        in_filters = conv_input.shape[-1]
        out_filters = conv_output.shape[-1]

        z = utils.global_pool(conv_input, name=f"{name}_scaling_pool")
        dim_reduction = tf.keras.layers.Dense(
            int(in_filters // self.scaling_r),
            activation="relu",
            kernel_initializer="he_normal",
            kernel_regularizer=self.kernel_regularizer,
            name=f"{name}_scaling_dense_reduce",
            use_bias=False,
        )(z)
        dim_expansion = tf.keras.layers.Dense(
            out_filters,
            activation="sigmoid",
            kernel_initializer="he_normal",
            kernel_regularizer=self.kernel_regularizer,
            name=f"{name}_scaling_dense_expand",
            use_bias=False,
        )(dim_reduction)
        scales = tf.keras.layers.Reshape(
            (1, 1, out_filters), name=f"{name}_scaling_reshape")(dim_expansion)

        return tf.keras.layers.Multiply(name=f"{name}_scaling_multiplication")(
            [conv_output, scales])
Beispiel #3
0
    def build(self) -> tf.keras.models.Model:
        x = stem_module(self.stem_filters, self.image_input)

        for block, (layers, filters, use_squeeze_and_excite) in enumerate(
                zip(
                    self.blocks_per_section,
                    self.section_filters,
                    self.use_squeeze_and_excite_in_section,
                )):
            for layer in range(layers):
                if filters == x.shape[-1]:
                    x = self.residual_block(x, use_squeeze_and_excite)
                else:
                    strides = 1 if (block == 0 or layer != 0) else 2
                    x = self.transition_block(x, filters, strides,
                                              use_squeeze_and_excite)

        x = tf.keras.layers.Activation("relu")(x)

        if self.include_top:
            x = utils.global_pool(x)
            x = tf.keras.layers.Dense(self.num_classes,
                                      kernel_initializer="glorot_normal")(x)
            x = tf.keras.layers.Activation("softmax", dtype="float32")(x)

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

        return model
Beispiel #4
0
    def build(self) -> tf.keras.models.Model:
        # Layer 1
        out = tf.keras.layers.Conv2D(
            self.filters,
            (7, 7),
            strides=2,
            kernel_initializer=self.kernel_initializer,
            padding="same",
            use_bias=False,
        )(self.image_input)
        out = tf.keras.layers.BatchNormalization(momentum=0.8)(out)
        out = tf.keras.layers.MaxPool2D((3, 3), strides=2, padding="same")(out)

        # Layer 2
        out = self.residual_block(out, filters=self.filters)

        # Layer 3 - 5
        for _ in range(3):
            out = self.residual_block(out)

        # Layer 6 - 17
        for _ in range(3):
            out = self.residual_block(out, double_filters=True)
            for _ in range(3):
                out = self.residual_block(out)

        # Layer 18
        if self.include_top:
            out = utils.global_pool(out)
            out = tf.keras.layers.Dense(self.num_classes)(out)
            out = tf.keras.layers.Activation("softmax", dtype="float32")(out)

        model = tf.keras.Model(inputs=self.image_input,
                               outputs=out,
                               name="birealnet18")

        # Load weights.
        if self.weights == "imagenet":
            # Download appropriate file
            if self.include_top:
                weights_path = utils.download_pretrained_model(
                    model="birealnet",
                    version="v0.3.0",
                    file="birealnet_weights.h5",
                    file_hash=
                    "6e6efac1584fcd60dd024198c87f42eb53b5ec719a5ca1f527e1fe7e8b997117",
                )
            else:
                weights_path = utils.download_pretrained_model(
                    model="birealnet",
                    version="v0.3.0",
                    file="birealnet_weights_notop.h5",
                    file_hash=
                    "5148b61c0c2a1094bdef811f68bf4957d5ba5f83ad26437b7a4a6855441ab46b",
                )
            model.load_weights(weights_path)
        elif self.weights is not None:
            model.load_weights(self.weights)
        return model
Beispiel #5
0
    def last_block(self, x: tf.Tensor, name: str = "") -> tf.Tensor:
        """Last block, shared across ResNet, StrongBaselineNet and Real-to-Bin nets."""

        x = utils.global_pool(x, name=f"{name}_global_pool")
        x = tf.keras.layers.Dense(
            self.num_classes,
            name=f"{name}_logits",
        )(x)
        return tf.keras.layers.Softmax(name=f"{name}_probs",
                                       dtype=tf.float32)(x)
Beispiel #6
0
 def build_model(input_res=(32, 32), data_format="channels_first"):
     if data_format == "channels_first":
         input_shape = (3, input_res[0], input_res[1])
     else:
         input_shape = (input_res[0], input_res[1], 3)
     inp = tf.keras.Input(shape=input_shape)
     x = tf.keras.layers.Conv2D(6, 3, 2, data_format=data_format)(inp)
     x = utils.global_pool(x, data_format=data_format)
     x = tf.keras.layers.Dense(2)(x)
     return tf.keras.Model(inputs=inp, outputs=x)
Beispiel #7
0
def test_global_pool(input_res, data_format):
    shape = (3,
             *input_res) if data_format == "channels_first" else (*input_res,
                                                                  3)
    inp = tf.keras.Input(shape=shape)
    x = tf.keras.layers.Conv2D(6, 3, 2, data_format=data_format)(inp)
    x = utils.global_pool(x, data_format=data_format)
    x = tf.keras.layers.Dense(2)(x)
    model = tf.keras.Model(inp, x)

    assert model.outputs[0].shape.as_list() == [None, 2]
Beispiel #8
0
def squeeze_and_excite(inp: tf.Tensor, filters: int, r: int = 16):
    """Squeeze and Excite as per [Squeeze-and-Excitation Networks](https://arxiv.org/abs/1709.01507).

    Use of S&E in BNNs was pioneered in [Training binary neural networks with
    real-to-binary convolutions](https://openreview.net/forum?id=BJg4NgBKvH).
    """
    out = utils.global_pool(inp)
    out = tf.keras.layers.Dense(
        inp.shape[-1] // r,
        activation="relu",
        kernel_initializer="he_normal",
        use_bias=False,
        kernel_regularizer=tf.keras.regularizers.l2(1e-5),
    )(out)
    out = tf.keras.layers.Dense(
        filters,
        activation="sigmoid",
        kernel_initializer="he_normal",
        use_bias=False,
        kernel_regularizer=tf.keras.regularizers.l2(1e-5),
    )(out)

    return tf.reshape(out, [-1, 1, 1, filters])
Beispiel #9
0
    def build(self) -> tf.keras.models.Model:
        x = self.image_input
        x = self.group_stem(x, name="stem")
        for i, (n, f) in enumerate(zip(self.num_blocks, self.transition_features)):
            for j in range(n):
                x = self.block(x, f"section_{i}_block_{j}")
            if f:
                x = self.transition_block(x, f, f"section_{i}_transition")

        x = self.norm(x, "head_bn")
        x = self.act(x, "head_relu")

        if self.include_top:
            x = utils.global_pool(x, name="head_globalpool")
            x = tf.keras.layers.Dense(
                self.num_classes,
                kernel_initializer=self.kernel_initializer,
                name="head_dense",
            )(x)
            x = tf.keras.layers.Activation(
                "softmax", dtype="float32", name="head_softmax"
            )(x)

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

        if self.weights == "imagenet":
            model.load_weights(
                self.imagenet_weights_path
                if self.include_top
                else self.imagenet_no_top_weights_path
            )
        elif self.weights is not None:
            model.load_weights(self.weights)

        return model
Beispiel #10
0
    def build(self) -> BinaryDenseNet:
        if self.image_input.shape[1] and self.image_input.shape[1] < 50:
            x = tf.keras.layers.Conv2D(
                self.initial_filters,
                kernel_size=3,
                padding="same",
                kernel_initializer="he_normal",
                use_bias=False,
            )(self.image_input)
        else:
            x = tf.keras.layers.Conv2D(
                self.initial_filters,
                kernel_size=7,
                strides=2,
                padding="same",
                kernel_initializer="he_normal",
                use_bias=False,
            )(self.image_input)

            x = tf.keras.layers.BatchNormalization(momentum=0.9,
                                                   epsilon=1e-5)(x)
            x = tf.keras.layers.Activation("relu")(x)
            x = tf.keras.layers.MaxPool2D(3, strides=2, padding="same")(x)

        for block, layers_per_block in enumerate(self.layers):
            for _ in range(layers_per_block):
                x = self.densely_connected_block(x, self.dilation_rate[block])

            if block < len(self.layers) - 1:
                x = tf.keras.layers.BatchNormalization(momentum=0.9,
                                                       epsilon=1e-5)(x)
                if self.dilation_rate[block + 1] == 1:
                    x = tf.keras.layers.MaxPooling2D(2, strides=2)(x)
                x = tf.keras.layers.Activation("relu")(x)
                x = tf.keras.layers.Conv2D(
                    round(x.shape.as_list()[-1] // self.reduction[block] / 32)
                    * 32,
                    kernel_size=1,
                    kernel_initializer="he_normal",
                    use_bias=False,
                )(x)

        x = tf.keras.layers.BatchNormalization(momentum=0.9, epsilon=1e-5)(x)
        x = tf.keras.layers.Activation("relu")(x)

        if self.include_top:
            x = utils.global_pool(x)
            x = tf.keras.layers.Dense(self.num_classes,
                                      kernel_initializer="he_normal")(x)
            x = tf.keras.layers.Activation("softmax", dtype="float32")(x)

        model = BinaryDenseNet(inputs=self.image_input,
                               outputs=x,
                               name=self.name)

        if self.weights == "imagenet":
            if self.include_top:
                weights_path = self.imagenet_weights_path
            else:
                weights_path = self.imagenet_no_top_weights_path
            model.load_weights(weights_path)
        elif self.weights is not None:
            model.load_weights(self.weights)

        return model
Beispiel #11
0
    def build(self) -> tf.keras.models.Model:
        if self.image_input.shape[1] and self.image_input.shape[1] < 50:
            x = tf.keras.layers.Conv2D(
                self.initial_filters,
                kernel_size=3,
                padding="same",
                kernel_initializer="he_normal",
                use_bias=False,
            )(self.image_input)
        else:
            x = tf.keras.layers.Conv2D(
                self.initial_filters,
                kernel_size=7,
                strides=2,
                padding="same",
                kernel_initializer="he_normal",
                use_bias=False,
            )(self.image_input)

            x = tf.keras.layers.BatchNormalization(momentum=0.9,
                                                   epsilon=1e-5)(x)
            x = tf.keras.layers.Activation("relu")(x)
            x = tf.keras.layers.MaxPool2D(3, strides=2, padding="same")(x)
            x = tf.keras.layers.BatchNormalization(momentum=0.9,
                                                   epsilon=1e-5)(x)

        for block, (layers, filters) in enumerate(zip(*self.spec)):
            # This trick adds shortcut connections between original ResNet
            # blocks. We wultiply the number of blocks by two, but add only one
            # layer instead of two in each block
            for layer in range(layers * 2):
                strides = 1 if block == 0 or layer != 0 else 2
                x = self.residual_block(x, filters, strides=strides)

        x = tf.keras.layers.Activation("relu")(x)

        if self.include_top:
            x = utils.global_pool(x)
            x = tf.keras.layers.Dense(self.num_classes,
                                      kernel_initializer="glorot_normal")(x)
            x = tf.keras.layers.Activation("softmax", dtype="float32")(x)

        model = tf.keras.Model(
            inputs=self.image_input,
            outputs=x,
            name=f"binary_resnet_e_{self.num_layers}",
        )

        # Load weights.
        if self.weights == "imagenet":
            # Download appropriate file
            if self.include_top:
                weights_path = utils.download_pretrained_model(
                    model="resnet_e",
                    version="v0.1.0",
                    file="resnet_e_18_weights.h5",
                    file_hash=
                    "bde4a64d42c164a7b10a28debbe1ad5b287c499bc0247ecb00449e6e89f3bf5b",
                )
            else:
                weights_path = utils.download_pretrained_model(
                    model="resnet_e",
                    version="v0.1.0",
                    file="resnet_e_18_weights_notop.h5",
                    file_hash=
                    "14cb037e47d223827a8d09db88ec73d60e4153a4464dca847e5ae1a155e7f525",
                )
            model.load_weights(weights_path)
        elif self.weights is not None:
            model.load_weights(self.weights)
        return model