Esempio n. 1
0
    def depthwise_block(x, strides, **metaparameters):
        """ Construct a Depthwise Separable Convolution block
            x         : input to the block
            strides   : strides
            n_filters : number of filters
            alpha     : width multiplier
        """
        n_filters = metaparameters['n_filters']
        alpha     = metaparameters['alpha']
        del metaparameters['n_filters']
            
        # Apply the width filter to the number of feature maps
        filters = int(n_filters * alpha)

        # Strided convolution to match number of filters
        if strides == (2, 2):
            x = ZeroPadding2D(padding=((0, 1), (0, 1)))(x)
            padding = 'valid'
        else:
            padding = 'same'

        # Depthwise Convolution
        x = Composable.DepthwiseConv2D(x, (3, 3), strides, padding=padding, use_bias=False, 
                                       **metaparameters)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)

        # Pointwise Convolution
        x = Composable.Conv2D(x, filters, (1, 1), strides=(1, 1), padding='same', use_bias=False, 
                              **metaparameters)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)
        return x
    def residual_block(x, **metaparameters):
        """ Construct a Residual Block
            x        : input to the block
            n_filters: number of filters in convolution layer in residual block
        """
        if 'n_filters' in metaparameters:
            n_filters = metaparameters['n_filters']
            del metaparameters['n_filters']
        else:
            n_filters = DenseNet.n_filters

            
        # Remember input tensor into residual block
        shortcut = x 
    
        # BN-RE-Conv pre-activation form of convolutions

        # Dimensionality expansion, expand filters by 4 (DenseNet-B)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)
        x = Composable.Conv2D(x, 4 * n_filters, (1, 1), strides=(1, 1), use_bias=False, 
                              **metaparameters)
    
        # Bottleneck convolution
        # 3x3 convolution with padding=same to preserve same shape of feature maps
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)
        x = Composable.Conv2D(x, n_filters, (3, 3), strides=(1, 1), padding='same', use_bias=False, 
                              **metaparameters)

        # Concatenate the input (identity) with the output of the residual block
        # Concatenation (vs. merging) provides Feature Reuse between layers
        x = Concatenate()([shortcut, x])
        return x
    def decoder(x, init_weights=None, **metaparameters):
        ''' Construct the Decoder
            x     : input to the decoder
            layers: number of filters per layer
            reg   : kernel regularizer
        '''
        layers = metaparameters['layers']
        if 'reg' in metaparameters:
            reg = metaparameters['reg']
        else:
            reg = AutoEncoder.reg
        if 'init_weights' in metaparameters:
            init_weights = metaparameters['init_weights']
        else:
            init_weights = AutoEncoder.init_weights

        # Progressive Feature Unpooling
        for _ in range(len(layers)-1, 0, -1):
            n_filters = layers[_]['n_filters']
            x = Conv2DTranspose(n_filters, (3, 3), strides=2, padding='same',
                                kernel_initializer=init_weights, kernel_regularizer=reg)(x)
            x = BatchNormalization()(x)
            x = Composable.ReLU(x)

        # Last unpooling and match shape to input
        x = Conv2DTranspose(3, (3, 3), strides=2, padding='same',
                            kernel_initializer=init_weights, kernel_regularizer=reg)(x)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)

        # The decoded image
        return x
    def projection_block(x, **metaparameters):
        """ Create a residual block using Depthwise Separable Convolutions with Projection shortcut
            x        : input into residual block
            n_filters: number of filters
        """
        n_filters = metaparameters['n_filters']
        del metaparameters['n_filters']

        # Remember the input
        shortcut = x
    
        # Strided convolution to double number of filters in identity link to
        # match output of residual block for the add operation (projection shortcut)
        shortcut = Composable.Conv2D(x, n_filters, (1, 1), strides=(2, 2), padding='same', **metaparameters)
        shortcut = BatchNormalization()(shortcut)

        # First Depthwise Separable Convolution
        x = Composable.SeparableConv2D(x, n_filters, (3, 3), padding='same', **metaparameters)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)

        # Second depthwise Separable Convolution
        x = Composable.SeparableConv2D(x, n_filters, (3, 3), padding='same', **metaparameters)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)

        # Create pooled feature maps, reduce size by 75%
        x = MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x)

        # Add the projection shortcut to the output of the block
        x = Add()([x, shortcut])

        return x
    def residual_block(x, **metaparameters):
        """ Create a residual block using Depthwise Separable Convolutions
            x        : input into residual block
            n_filters: number of filters
        """
        n_filters = metaparameters['n_filters']
        del metaparameters['n_filters']

        # Remember the input
        shortcut = x

        # First Depthwise Separable Convolution
        x = Composable.SeparableConv2D(x, n_filters, (3, 3), padding='same', **metaparameters)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)

        # Second depthwise Separable Convolution
        x = Composable.SeparableConv2D(x, n_filters, (3, 3), padding='same', **metaparameters)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)

        # Third depthwise Separable Convolution
        x = Composable.SeparableConv2D(x, n_filters, (3, 3), padding='same', **metaparameters)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)
    
        # Add the identity link to the output of the block
        x = Add()([x, shortcut])
        return x
Esempio n. 6
0
    def fire_block(x, **metaparameters):
        ''' Construct a Fire Block  with complex bypass
            x        : input to the block
            n_filters: number of filters in block
            reg      : kernel regularizer
        '''
        n_filters = metaparameters['n_filters']
        if 'reg' in metaparameters:
            reg = metaparameters['reg']
        else:
            reg = SqueezeNetComplex.reg
        if 'init_weights' in metaparameters:
            init_weights = metaparameters['init_weights']
        else:
            init_weights = SqueezeNetComplex.init_weights

        # remember the input (identity)
        shortcut = x

        # if the number of input filters does not equal the number of output filters, then use
        # a transition convolution to match the number of filters in identify link to output
        if shortcut.shape[3] != 8 * n_filters:
            shortcut = Conv2D(n_filters * 8, (1, 1),
                              strides=1,
                              padding='same',
                              kernel_initializer=init_weights,
                              kernel_regularizer=reg)(shortcut)
            shortcut = Composable.ReLU(shortcut)

        # squeeze layer
        squeeze = Conv2D(n_filters, (1, 1),
                         strides=1,
                         padding='same',
                         kernel_initializer=init_weights,
                         kernel_regularizer=reg)(x)
        squeeze = Composable.ReLU(squeeze)

        # branch the squeeze layer into a 1x1 and 3x3 convolution and double the number
        # of filters
        expand1x1 = Conv2D(n_filters * 4, (1, 1),
                           strides=1,
                           padding='same',
                           kernel_initializer=init_weights,
                           kernel_regularizer=reg)(squeeze)
        expand1x1 = Composable.ReLU(expand1x1)
        expand3x3 = Conv2D(n_filters * 4, (3, 3),
                           strides=1,
                           padding='same',
                           kernel_initializer=init_weights,
                           kernel_regularizer=reg)(squeeze)
        expand3x3 = Composable.ReLU(expand3x3)

        # concatenate the feature maps from the 1x1 and 3x3 branches
        x = Concatenate()([expand1x1, expand3x3])

        # if identity link, add (matrix addition) input filters to output filters
        if shortcut is not None:
            x = Add()([x, shortcut])
        return x
Esempio n. 7
0
    def identity_block(x, **metaparameters):
        """ Construct a ResNeXT block with identity link
            x           : input to block
            filters_in  : number of filters  (channels) at the input convolution
            filters_out : number of filters (channels) at the output convolution
            cardinality : width of group convolution
        """
        filters_in = metaparameters['filters_in']
        filters_out = metaparameters['filters_out']
        if 'cardinality' in metaparameters:
            cardinality = metaparameters['cardinality']
        else:
            cardinality = ResNeXt.cardinality

        # Remember the input
        shortcut = x

        # Dimensionality Reduction
        x = Composable.Conv2D(x,
                              filters_in, (1, 1),
                              strides=(1, 1),
                              padding='same',
                              use_bias=False,
                              **metaparameters)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)

        # Cardinality (Wide) Layer (split-transform)
        filters_card = filters_in // cardinality
        groups = []
        for i in range(cardinality):
            group = Lambda(lambda z: z[:, :, :, i * filters_card:i *
                                       filters_card + filters_card])(x)
            groups.append(
                Composable.Conv2D(group,
                                  filters_card, (3, 3),
                                  strides=(1, 1),
                                  padding='same',
                                  use_bias=False,
                                  **metaparameters))

        # Concatenate the outputs of the cardinality layer together (merge)
        x = Concatenate()(groups)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)

        # Dimensionality restoration
        x = Composable.Conv2D(x,
                              filters_out, (1, 1),
                              strides=(1, 1),
                              padding='same',
                              use_bias=False,
                              **metaparameters)
        x = BatchNormalization()(x)

        # Identity Link: Add the shortcut (input) to the output of the block
        x = Add()([shortcut, x])
        x = Composable.ReLU(x)
        return x
Esempio n. 8
0
    def strided_shuffle_block(x, **metaparameters):
        ''' Construct a Strided Shuffle Block 
            x           : input to the block
            n_partitions: number of groups to partition feature maps (channels) into.
            n_filters   : number of filters
            reduction   : dimensionality reduction factor (e.g, 0.25)
        '''
        n_partitions = metaparameters['n_partitions']
        n_filters = metaparameters['n_filters']
        reduction = metaparameters['reduction']
        del metaparameters['n_filters']
        del metaparameters['n_partitions']
        if 'reg' in metaparameters:
            reg = metaparameters['reg']
        else:
            reg = ShuffleNet.reg
        if 'init_weights' in metaparameters:
            init_weights = metaparameters['init_weights']
        else:
            init_weights = ShuffleNet.init_weights

        # projection shortcut
        shortcut = x
        shortcut = AveragePooling2D((3, 3), strides=2,
                                    padding='same')(shortcut)

        # On entry block, we need to adjust the number of output filters
        # of the entry pointwise group convolution to match the exit
        # pointwise group convolution, by subtracting the number of input filters
        n_filters -= int(x.shape[3])

        # pointwise group convolution, with dimensionality reduction
        x = ShuffleNet.pw_group_conv(x, n_partitions,
                                     int(reduction * n_filters),
                                     **metaparameters)
        x = Composable.ReLU(x)

        # channel shuffle layer
        x = ShuffleNet.channel_shuffle(x, n_partitions)

        # Depthwise 3x3 Strided Convolution
        x = DepthwiseConv2D((3, 3),
                            strides=2,
                            padding='same',
                            use_bias=False,
                            kernel_initializer=init_weights,
                            kernel_regularizer=reg)(x)
        x = BatchNormalization()(x)

        # pointwise group convolution, with dimensionality restoration
        x = ShuffleNet.pw_group_conv(x, n_partitions, n_filters,
                                     **metaparameters)

        # Concatenate the projection shortcut to the output
        x = Concatenate()([shortcut, x])
        x = Composable.ReLU(x)
        return x
    def projection_block(x, strides=(2, 2), **metaparameters):
        """ Create Bottleneck Residual Block with Projection Shortcut
            Increase the number of filters by 4X
            x        : input into the block
            strides  : whether entry convolution is strided (i.e., (2, 2) vs (1, 1))
            n_filters: number of filters
        """
        n_filters = metaparameters['n_filters']
        del metaparameters['n_filters']

        # Construct the projection shortcut
        # Increase filters by 4X to match shape when added to output of block
        shortcut = Composable.Conv2D(x,
                                     4 * n_filters, (1, 1),
                                     strides=strides,
                                     use_bias=False,
                                     **metaparameters)
        shortcut = BatchNormalization()(shortcut)

        ## Construct the 1x1, 3x3, 1x1 residual block (fig 3c)

        # Dimensionality reduction
        # Feature pooling when strides=(2, 2)
        x = Composable.Conv2D(x,
                              n_filters, (1, 1),
                              strides=strides,
                              use_bias=False,
                              **metaparameters)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)

        # Bottleneck layer
        x = Composable.Conv2D(x,
                              n_filters, (3, 3),
                              strides=(1, 1),
                              padding='same',
                              use_bias=False,
                              **metaparameters)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)

        # Dimensionality restoration - increase the number of filters by 4X
        x = Composable.Conv2D(x,
                              4 * n_filters, (1, 1),
                              strides=(1, 1),
                              use_bias=False,
                              **metaparameters)
        x = BatchNormalization()(x)

        # Pass the output through the squeeze and excitation block
        x = SEResNet.squeeze_excite_block(x, **metaparameters)

        # Add the projection shortcut link to the output of the residual block
        x = Add()([x, shortcut])
        x = Composable.ReLU(x)
        return x
Esempio n. 10
0
    def projection_block(x, strides=(2, 2), **metaparameters):
        """ Construct a Bottleneck Residual Block of Convolutions with Projection Shortcut
            Increase the number of filters by 4X
            x        : input into the block
            strides  : whether the first convolution is strided
            n_filters: number of filters
            reg      : kernel regularizer
        """
        n_filters = metaparameters['n_filters']
        del metaparameters['n_filters']

        # Construct the projection shortcut
        # Increase filters by 4X to match shape when added to output of block
        shortcut = BatchNormalization()(x)
        shortcut = Composable.Conv2D(shortcut,
                                     4 * n_filters, (1, 1),
                                     strides=strides,
                                     use_bias=False,
                                     **metaparameters)

        ## Construct the 1x1, 3x3, 1x1 convolution block

        # Dimensionality reduction
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)
        x = Composable.Conv2D(x,
                              n_filters, (1, 1),
                              strides=(1, 1),
                              use_bias=False,
                              **metaparameters)

        # Bottleneck layer
        # Feature pooling when strides=(2, 2)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)
        x = Composable.Conv2D(x,
                              n_filters, (3, 3),
                              strides=strides,
                              padding='same',
                              use_bias=False,
                              **metaparameters)

        # Dimensionality restoration - increase the number of filters by 4X
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)
        x = Composable.Conv2D(x,
                              4 * n_filters, (1, 1),
                              strides=(1, 1),
                              use_bias=False,
                              **metaparameters)

        # Add the projection shortcut to the output of the residual block
        x = Add()([x, shortcut])
        return x
Esempio n. 11
0
    def fire_block(x, **metaparameters):
        ''' Construct a Fire Block
            x        : input to the block
            n_filters: number of filters in the block
            bypass   : whether block has an identity shortcut
            reg      : kernel regularizer
        '''
        n_filters = metaparameters['n_filters']
        bypass = metaparameters['bypass']
        if 'reg' in metaparameters:
            reg = metaparameters['reg']
        else:
            reg = SqueezeNetBypass.reg
        if 'init_weights' in metaparameters:
            init_weights = metaparameters['init_weights']
        else:
            init_weights = SqueezeNetBypass.init_weights

        # remember the input
        shortcut = x

        # squeeze layer
        squeeze = Conv2D(n_filters, (1, 1),
                         strides=1,
                         padding='same',
                         kernel_initializer=init_weights,
                         kernel_regularizer=reg)(x)
        squeeze = Composable.ReLU(squeeze)

        # branch the squeeze layer into a 1x1 and 3x3 convolution and double the number
        # of filters
        expand1x1 = Conv2D(n_filters * 4, (1, 1),
                           strides=1,
                           padding='same',
                           kernel_initializer=init_weights,
                           kernel_regularizer=reg)(squeeze)
        expand1x1 = Composable.ReLU(expand1x1)
        expand3x3 = Conv2D(n_filters * 4, (3, 3),
                           strides=1,
                           padding='same',
                           kernel_initializer=init_weights,
                           kernel_regularizer=reg)(squeeze)
        expand3x3 = Composable.ReLU(expand3x3)

        # concatenate the feature maps from the 1x1 and 3x3 branches
        x = Concatenate()([expand1x1, expand3x3])

        # if identity link, add (matrix addition) input filters to output filters
        if bypass:
            x = Add()([x, shortcut])

        return x
Esempio n. 12
0
    def shuffle_block(x, **metaparameters):
        ''' Construct a shuffle Shuffle block  
            x           : input to the block
            n_partitions: number of groups to partition feature maps (channels) into.
            n_filters   : number of filters
            reduction   : dimensionality reduction factor (e.g, 0.25)
            reg         : kernel regularizer
        '''
        n_partitions = metaparameters['n_partitions']
        n_filters = metaparameters['n_filters']
        reduction = metaparameters['reduction']
        del metaparameters['n_filters']
        del metaparameters['n_partitions']
        if 'reg' in metaparameters:
            reg = metaparameters['reg']
        else:
            reg = ShuffleNet.reg
        if 'init_weights' in metaparameters:
            init_weights = metaparameters['init_weights']
        else:
            init_weights = ShuffleNet.init_weights

        # identity shortcut
        shortcut = x

        # pointwise group convolution, with dimensionality reduction
        x = ShuffleNet.pw_group_conv(x, n_partitions,
                                     int(reduction * n_filters),
                                     **metaparameters)
        x = Composable.ReLU(x)

        # channel shuffle layer
        x = ShuffleNet.channel_shuffle(x, n_partitions)

        # Depthwise 3x3 Convolution
        x = Composable.DepthwiseConv2D(x, (3, 3),
                                       strides=1,
                                       padding='same',
                                       use_bias=False,
                                       **metaparameters)
        x = BatchNormalization()(x)

        # pointwise group convolution, with dimensionality restoration
        x = ShuffleNet.pw_group_conv(x, n_partitions, n_filters,
                                     **metaparameters)

        # Add the identity shortcut (input added to output)
        x = Add()([shortcut, x])
        x = Composable.ReLU(x)
        return x
    def classifier(self, x, n_classes):
        ''' Construct the Classifier 
            x        : input to the classifier
            n_classes: number of output classes
        '''
        # Save the encoding layer
        self.encoding = x

        # set the number of filters equal to number of classes
        x = Conv2D(n_classes, (1, 1),
                   strides=1,
                   padding='same',
                   kernel_initializer=self.init_weights,
                   kernel_regularizer=self.reg)(x)
        x = Composable.ReLU(x)

        # reduce each filter (class) to a single value
        x = GlobalAveragePooling2D()(x)

        # Save the pre-activation probabilities layer
        self.probabilities = x

        outputs = Activation('softmax')(x)

        # Save the post-activation probabilities layer
        self.softmax = outputs
        return outputs
Esempio n. 14
0
    def stem(self, inputs):
        """ Construct the Stem Convolutional Group 
            inputs : the input vector
        """
        # The 224x224 images are zero padded (black - no signal) to be 230x230 images prior to the first convolution
        x = ZeroPadding2D(padding=(3, 3))(inputs)
    
        # First Convolutional layer which uses a large (coarse) filter 
        x = self.Conv2D(x, 64, (7, 7), strides=(2, 2), padding='valid', use_bias=False)
        x = BatchNormalization()(x)
        x = self.ReLU(x)

        # Pooled feature maps will be reduced by 75%
        x = ZeroPadding2D(padding=(1, 1))(x)
        x = MaxPooling2D((3, 3), strides=(2, 2))(x)

        # Second Convolutional layer which uses a mid-size filter
        x = self.Conv2D(x, 64, (1, 1), strides=(1, 1), padding='same', use_bias=False)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)
        x = ZeroPadding2D(padding=(1, 1))(x)
        x = self.Conv2D(x, 192, (3, 3), strides=(1, 1), padding='valid', use_bias=False)
        x = BatchNormalization()(x)
        x = self.ReLU(x)
    
        # Pooled feature maps will be reduced by 75%
        x = ZeroPadding2D(padding=(1, 1))(x)
        x = MaxPooling2D((3, 3), strides=(2, 2))(x)
        return x
    def encoder(x, init_weights=None, **metaparameters):
        ''' Construct the Encoder 
            x     : input to the encoder
            layers: number of filters per layer
            reg   : kernel regularizer
        '''
        layers = metaparameters['layers']
        if 'reg' in metaparameters:
            reg = metaparameters['reg']
        else:
            reg = AutoEncoder.reg
        if 'init_weights' in metaparameters:
            init_weights = metaparameters['init_weights']
        else:
            init_weights = AutoEncoder.init_weights

        # Progressive Feature Pooling
        for layer in layers:
            n_filters = layer['n_filters']
            x = Conv2D(n_filters, (3, 3), strides=2, padding='same',
                       kernel_initializer=init_weights, kernel_regularizer=reg)(x)
            x = BatchNormalization()(x)
            x = Composable.ReLU(x)

        # The Encoding
        return x
        def stem(inputs):
            """ Create the stem entry into the neural network
                inputs : input tensor to neural network
            """
            # Strided convolution - dimensionality reduction
            # Reduce feature maps by 75%
            x = Composable.Conv2D(inputs, 32, (3, 3), strides=(2, 2), **metaparameters)
            x = BatchNormalization()(x)
            x = Composable.ReLU(x)

            # Convolution - dimensionality expansion
            # Double the number of filters
            x = Composable.Conv2D(x, 64, (3, 3), strides=(1, 1), **metaparameters)
            x = BatchNormalization()(x)
            x = Composable.ReLU(x)
            return x
    def identity_block(x, **metaparameters):
        """ Create a Bottleneck Residual Block with Identity Link
            x        : input into the block
            n_filters: number of filters
        """
        n_filters = metaparameters['n_filters']
        del metaparameters['n_filters']

        # Save input vector (feature maps) for the identity link
        shortcut = x

        ## Construct the 1x1, 3x3, 1x1 residual block (fig 3c)

        # Dimensionality reduction
        x = Composable.Conv2D(x,
                              n_filters, (1, 1),
                              strides=(1, 1),
                              use_bias=False,
                              **metaparameters)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)

        # Bottleneck layer
        x = Composable.Conv2D(x,
                              n_filters, (3, 3),
                              strides=(1, 1),
                              padding="same",
                              use_bias=False,
                              **metaparameters)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)

        # Dimensionality restoration - increase the number of output filters by 4X
        x = Composable.Conv2D(x,
                              n_filters * 4, (1, 1),
                              strides=(1, 1),
                              use_bias=False,
                              **metaparameters)
        x = BatchNormalization()(x)

        # Pass the output through the squeeze and excitation block
        x = SEResNet.squeeze_excite_block(x, **metaparameters)

        # Add the identity link (input) to the output of the residual block
        x = Add()([shortcut, x])
        x = Composable.ReLU(x)
        return x
Esempio n. 18
0
    def projection_block(x, **metaparameters):
        """ Construct a B(3,3) style block
            x        : input into the block
            n_filters: number of filters
            k        : width factor
            strides  : whether the projection shortcut is strided
        """
        n_filters = metaparameters['n_filters']
        strides = metaparameters['strides']
        k = metaparameters['k']
        del metaparameters['n_filters']
        del metaparameters['strides']

        # Save input vector (feature maps) for the identity link
        shortcut = BatchNormalization()(x)
        shortcut = Composable.Conv2D(shortcut,
                                     n_filters * k, (3, 3),
                                     strides=strides,
                                     padding='same',
                                     use_bias=False,
                                     **metaparameters)

        ## Construct the 3x3, 3x3 convolution block

        x = BatchNormalization()(x)
        x = Composable.ReLU(x)
        x = Composable.Conv2D(x,
                              n_filters * k, (3, 3),
                              strides=strides,
                              padding='same',
                              use_bias=False,
                              **metaparameters)

        x = BatchNormalization()(x)
        x = Composable.ReLU(x)
        x = Composable.Conv2D(x,
                              n_filters * k, (3, 3),
                              strides=(1, 1),
                              padding='same',
                              use_bias=False,
                              **metaparameters)

        # Add the identity link (input) to the output of the residual block
        x = Add()([shortcut, x])
        return x
    def exitFlow(x, n_classes, **metaparameters):
        """ Create the exit flow section
            x         : input to the exit flow section
            n_classes : number of output classes
        """     
        # Remember the input
        shortcut = x

        # Strided convolution to double number of filters in identity link to
        # match output of residual block for the add operation (projection shortcut)
        shortcut = Composable.Conv2D(x, 1024, (1, 1), strides=(2, 2), padding='same', **metaparameters)
        shortcut = BatchNormalization()(shortcut)

        # First Depthwise Separable Convolution
        # Dimensionality reduction - reduce number of filters
        x = Composable.SeparableConv2D(x, 728, (3, 3), padding='same', **metaparameters)
        x = BatchNormalization()(x)

        # Second Depthwise Separable Convolution
        # Dimensionality restoration
        x = Composable.SeparableConv2D(x, 1024, (3, 3), padding='same', **metaparameters)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)

        # Create pooled feature maps, reduce size by 75%
        x = MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x)

        # Add the projection shortcut to the output of the pooling layer
        x = Add()([x, shortcut])

        # Third Depthwise Separable Convolution
        x = Composable.SeparableConv2D(x, 1556, (3, 3), padding='same', **metaparameters)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)

        # Fourth Depthwise Separable Convolution
        x = Composable.SeparableConv2D(x, 2048, (3, 3), padding='same', **metaparameters)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)

        # Create classifier section
        x = Composable.classifier(x, n_classes, **metaparameters)

        return x
Esempio n. 20
0
    def identity_block(x, **metaparameters):
        """ Construct a B(3,3) style block
            x        : input into the block
            n_filters: number of filters
            k        : width factor
            dropout  : dropout rate
        """
        n_filters = metaparameters['n_filters']
        k = metaparameters['k']
        dropout = metaparameters['dropout']
        del metaparameters['n_filters']
        del metaparameters['strides']

        # Save input vector (feature maps) for the identity link
        shortcut = x

        ## Construct the 3x3, 3x3 convolution block

        x = BatchNormalization()(x)
        x = Composable.ReLU(x)
        x = Composable.Conv2D(x,
                              n_filters * k, (3, 3),
                              strides=(1, 1),
                              padding='same',
                              use_bias=False,
                              **metaparameters)

        # dropout only in identity link (not projection)
        if dropout > 0:
            x = Dropout(dropout)

        x = BatchNormalization()(x)
        x = Composable.ReLU(x)
        x = Composable.Conv2D(x,
                              n_filters * k, (3, 3),
                              strides=(1, 1),
                              padding='same',
                              use_bias=False,
                              **metaparameters)

        # Add the identity link (input) to the output of the residual block
        x = Add()([shortcut, x])
        return x
    def fire_block(x, **metaparameters):
        ''' Construct a Fire Block
            x        : input to the block
            n_filters: number of filters
            reg      : kernel regularizer
        '''
        n_filters = metaparameters['n_filters']
        if 'reg' in metaparameters:
            reg = metaparameters['reg']
        else:
            reg = SqueezeNet.reg
        if 'init_weights' in metaparameters:
            init_weights = metaparameters['init_weights']
        else:
            init_weights = SqueezeNet.init_weights

        # squeeze layer
        squeeze = Conv2D(n_filters, (1, 1),
                         strides=1,
                         padding='same',
                         kernel_initializer=init_weights,
                         kernel_regularizer=reg)(x)
        squeeze = Composable.ReLU(x)

        # branch the squeeze layer into a 1x1 and 3x3 convolution and double the number
        # of filters
        expand1x1 = Conv2D(n_filters * 4, (1, 1),
                           strides=1,
                           padding='same',
                           kernel_initializer=init_weights,
                           kernel_regularizer=reg)(squeeze)
        expand1x1 = Composable.ReLU(expand1x1)
        expand3x3 = Conv2D(n_filters * 4, (3, 3),
                           strides=1,
                           padding='same',
                           kernel_initializer=init_weights,
                           kernel_regularizer=reg)(squeeze)
        expand3x3 = Composable.ReLU(expand3x3)

        # concatenate the feature maps from the 1x1 and 3x3 branches
        x = Concatenate()([expand1x1, expand3x3])
        return x
Esempio n. 22
0
 def stem(self, inputs):
     ''' Construct the Stem Group
         inputs : input tensor
     '''
     x = Conv2D(96, (7, 7),
                strides=2,
                padding='same',
                kernel_initializer=self.init_weights,
                kernel_regularizer=self.reg)(inputs)
     x = Composable.ReLU(x)
     x = MaxPooling2D(3, strides=2)(x)
     return x
Esempio n. 23
0
 def auxiliary(x, n_classes, **metaparameters):
     """ Construct the auxiliary classier
         x        : input to the auxiliary classifier
         n_classes: number of output classes
     """
     x = AveragePooling2D((5, 5), strides=(3, 3))(x)
     x = Composable.Conv2D(x, 128, (1, 1), strides=(1, 1), padding='same', use_bias=False, **metaparameters)
     x = BatchNormalization()(x)
     x = Composable.ReLU(x)
     x = Flatten()(x)
     x = Composable.Dense(x, 1024, activation=Composable.ReLU, **metaparameters)
     x = Dropout(0.7)(x)
     output = Composable.Dense(x, n_classes, activation='softmax', **metaparameters)
     return output
Esempio n. 24
0
    def inception_block(x, f1x1, f3x3, f5x5, fpool, **metaparameters):
        """ Construct an Inception block (module)
            x    : input to the block
            f1x1 : filters for 1x1 branch
            f3x3 : filters for 3x3 branch
            f5x5 : filters for 5x5 branch
            fpool: filters for pooling branch
        """
        # 1x1 branch
        b1x1 = Composable.Conv2D(x, f1x1[0], (1, 1), strides=1, padding='same', use_bias=False, **metaparameters)
        b1x1 = BatchNormalization()(b1x1)
        b1x1 = Composable.ReLU(b1x1)

        # 3x3 branch
        # 3x3 reduction
        b3x3 = Composable.Conv2D(x, f3x3[0], (1, 1), strides=1, padding='same', use_bias=False, **metaparameters)
        b3x3 = BatchNormalization()(b3x3)
        b3x3 = Composable.ReLU(b3x3)
        b3x3 = ZeroPadding2D((1,1))(b3x3)
        b3x3 = Composable.Conv2D(b3x3, f3x3[1], (3, 3), strides=1, padding='valid', use_bias=False, **metaparameters)
        b3x3 = BatchNormalization()(b3x3)
        b3x3 = Composable.ReLU(b3x3)

        # 5x5 branch
        # 5x5 reduction
        b5x5 = Composable.Conv2D(x, f5x5[0], (1, 1), strides=1, padding='same', use_bias=False, **metaparameters)
        b5x5 = BatchNormalization()(b5x5)
        b5x5 = Composable.ReLU(b5x5)
        b5x5 = ZeroPadding2D((1,1))(b5x5)
        b5x5 = Composable.Conv2D(b5x5, f5x5[1], (3, 3), strides=1, padding='valid', use_bias=False, **metaparameters)
        b5x5 = BatchNormalization()(b5x5)
        b5x5 = Composable.ReLU(b5x5)

        # Pooling branch
        bpool = MaxPooling2D((3, 3), strides=1, padding='same')(x)
        # 1x1 projection
        bpool = Composable.Conv2D(bpool, fpool[0], (1, 1), strides=1, padding='same', use_bias=False, **metaparameters)
        bpool = BatchNormalization()(bpool)
        bpool = Composable.ReLU(bpool)

        # Concatenate the outputs (filters) of the branches
        x = Concatenate()([b1x1, b3x3, b5x5, bpool])
        return x
    def projection_block(x, strides=1, **metaparameters):
        """ Construct a ResNeXT block with projection shortcut
            x          : input to the block
            strides    : whether entry convolution is strided (i.e., (2, 2) vs (1, 1))
            filters_in : number of filters  (channels) at the input convolution
            filters_out: number of filters (channels) at the output convolution
            cardinality: width of cardinality layer
        """
        filters_in = metaparameters['filters_in']
        filters_out = metaparameters['filters_out']
        cardinality = metaparameters['cardinality']

        # Construct the projection shortcut
        # Increase filters by 2X to match shape when added to output of block
        shortcut = Composable.Conv2D(x,
                                     filters_out,
                                     kernel_size=(1, 1),
                                     strides=strides,
                                     padding='same',
                                     **metaparameters)
        shortcut = BatchNormalization()(shortcut)

        # Dimensionality Reduction
        x = Composable.Conv2D(x,
                              filters_in,
                              kernel_size=(1, 1),
                              strides=(1, 1),
                              padding='same',
                              use_bias=False,
                              **metaparameters)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)

        # Cardinality (Wide) Layer (split-transform)
        filters_card = filters_in // cardinality
        groups = []
        for i in range(cardinality):
            group = Lambda(lambda z: z[:, :, :, i * filters_card:i *
                                       filters_card + filters_card])(x)
            groups.append(
                Composable.Conv2D(group,
                                  filters_card,
                                  kernel_size=(3, 3),
                                  strides=strides,
                                  padding='same',
                                  use_bias=False,
                                  **metaparameters))

        # Concatenate the outputs of the cardinality layer together (merge)
        x = Concatenate()(groups)
        x = BatchNormalization()(x)
        x = Composable.ReLU(x)

        # Dimensionality restoration
        x = Composable.Conv2D(x,
                              filters_out,
                              kernel_size=(1, 1),
                              strides=(1, 1),
                              padding='same',
                              use_bias=False,
                              **metaparameters)
        x = BatchNormalization()(x)

        # Pass the output through the squeeze and excitation block
        x = SEResNeXt.squeeze_excite_block(x, **metaparameters)

        # Add the projection shortcut (input) to the output of the block
        x = Add()([shortcut, x])
        x = Composable.ReLU(x)
        return x