<filename>layers.py
from keras.layers import Conv2D, BatchNormalization, add

def conv_bn(X, filters, kernel_size, strides=(1,1), padding='same', prefix=None):
    """A convolutional block with batchNormalization.
    
    Arguments:
        X {tensor} -- Input tensor
        filters {integer} -- The filters of convolutional layer
        kernel_size {integer} -- The kernel size of convolutional layer
    
    Keyword Arguments:
        strides {tuple} -- The strides of convolutional layer (default: {(1,1)})
        padding {str} -- Padding method (default: {'same'})
        prefix {str} -- Predix of layer names (default: {None})

    Returns:
        Output tensor for the block.
    """

    X = Conv2D(filters=filters, kernel_size=kernel_size, strides=strides, padding=padding, 
               activation='relu', name=prefix)(X)
    X = BatchNormalization(axis=3, name=prefix+'bn')(X)

    return X


def identity_block(X, filters, kernel_size, strides=(1,1), prefix=None, with_conv_shortcut=False):
    """A identity block.
    
    Arguments:
        X {tensor} -- Input tensor
        filters {integer} -- The filters of convolutional layer
        kernel_size {integer} -- The kernel size of convolutional layer
    
    Keyword Arguments:
        strides {tuple} -- The strides of convolutional layer (default: {(1,1)})
        prefix {str} -- Predix of layer names (default: {None})
        with_conv_shortcut {bool} -- With a convolutional layer at shortcut or not (default: {False})
    
    Returns:
        Output tensor for the block.
    """

    X_shortcut = X
    X = conv_bn(X=X, filters=filters, kernel_size=kernel_size, strides=strides, padding='same', prefix=prefix+'_1')
    X = conv_bn(X=X, filters=filters, kernel_size=kernel_size, padding='same', prefix=prefix+'_2')

    if with_conv_shortcut:
        X_shortcut = conv_bn(X=X_shortcut, filters=filters, kernel_size=kernel_size, strides=strides, 
                             padding='same', prefix=prefix+'_0')
        X = add([X, X_shortcut])

        return X
    else:
        X = add([X, X_shortcut])

        return X


def bottleneck_block(X, filters, strides=(1,1), prefix=None, with_conv_shortcut=False):
    """A bottleneck block
    
    Arguments:
        X {tensor} -- Input tensor
        filters {list} -- The filterss of 3 conv layer at main path
    
    Keyword Arguments:
        strides {tuple} -- The strides of convolutional layer (default: {(1,1)})
        prefix {str} -- Predix of layer names (default: {None})
        with_conv_shortcut {bool} -- With a convolutional layer at shortcut or not (default: {False})
    
    Returns:
        Output tensor for the block.
    """
    
    X_shortcut = X
    f1, f2, f3 = filters

    X = conv_bn(X=X, filters=f1, kernel_size=1, strides=strides, padding='same', prefix=prefix+'_1')
    X = conv_bn(X=X, filters=f2, kernel_size=3, padding='same', prefix=prefix+'_2')
    X = conv_bn(X=X, filters=f3, kernel_size=1, padding='same', prefix=prefix+'_3')

    if with_conv_shortcut:
        X_shortcut = conv_bn(X=X_shortcut, filters=f3, kernel_size=1, strides=strides, prefix=prefix+'_0')
        X = add([X, X_shortcut])

        return X
    else:
        X = add([X, X_shortcut])

        return X

<filename>layers.py
from keras.layers import Conv2D, BatchNormalization, add

def conv_bn(X, filters, kernel_size, strides=(1,1), padding='same', prefix=None):
    """A convolutional block with batchNormalization.
    
    Arguments:
        X {tensor} -- Input tensor
        filters {integer} -- The filters of convolutional layer
        kernel_size {integer} -- The kernel size of convolutional layer
    
    Keyword Arguments:
        strides {tuple} -- The strides of convolutional layer (default: {(1,1)})
        padding {str} -- Padding method (default: {'same'})
        prefix {str} -- Predix of layer names (default: {None})

    Returns:
        Output tensor for the block.
    """

    X = Conv2D(filters=filters, kernel_size=kernel_size, strides=strides, padding=padding, 
               activation='relu', name=prefix)(X)
    X = BatchNormalization(axis=3, name=prefix+'bn')(X)

    return X


def identity_block(X, filters, kernel_size, strides=(1,1), prefix=None, with_conv_shortcut=False):
    """A identity block.
    
    Arguments:
        X {tensor} -- Input tensor
        filters {integer} -- The filters of convolutional layer
        kernel_size {integer} -- The kernel size of convolutional layer
    
    Keyword Arguments:
        strides {tuple} -- The strides of convolutional layer (default: {(1,1)})
        prefix {str} -- Predix of layer names (default: {None})
        with_conv_shortcut {bool} -- With a convolutional layer at shortcut or not (default: {False})
    
    Returns:
        Output tensor for the block.
    """

    X_shortcut = X
    X = conv_bn(X=X, filters=filters, kernel_size=kernel_size, strides=strides, padding='same', prefix=prefix+'_1')
    X = conv_bn(X=X, filters=filters, kernel_size=kernel_size, padding='same', prefix=prefix+'_2')

    if with_conv_shortcut:
        X_shortcut = conv_bn(X=X_shortcut, filters=filters, kernel_size=kernel_size, strides=strides, 
                             padding='same', prefix=prefix+'_0')
        X = add([X, X_shortcut])

        return X
    else:
        X = add([X, X_shortcut])

        return X


def bottleneck_block(X, filters, strides=(1,1), prefix=None, with_conv_shortcut=False):
    """A bottleneck block
    
    Arguments:
        X {tensor} -- Input tensor
        filters {list} -- The filterss of 3 conv layer at main path
    
    Keyword Arguments:
        strides {tuple} -- The strides of convolutional layer (default: {(1,1)})
        prefix {str} -- Predix of layer names (default: {None})
        with_conv_shortcut {bool} -- With a convolutional layer at shortcut or not (default: {False})
    
    Returns:
        Output tensor for the block.
    """
    
    X_shortcut = X
    f1, f2, f3 = filters

    X = conv_bn(X=X, filters=f1, kernel_size=1, strides=strides, padding='same', prefix=prefix+'_1')
    X = conv_bn(X=X, filters=f2, kernel_size=3, padding='same', prefix=prefix+'_2')
    X = conv_bn(X=X, filters=f3, kernel_size=1, padding='same', prefix=prefix+'_3')

    if with_conv_shortcut:
        X_shortcut = conv_bn(X=X_shortcut, filters=f3, kernel_size=1, strides=strides, prefix=prefix+'_0')
        X = add([X, X_shortcut])

        return X
    else:
        X = add([X, X_shortcut])

        return X

A convolutional block with batchNormalization.          Arguments:         X {tensor} -- Input tensor         filters {integer} -- The filters of convolutional layer         kernel_size {integer} -- The kernel size of convolutional layer          Keyword Arguments:         strides {tuple} -- The strides of convolutional layer (default: {(1,1)})         padding {str} -- Padding method (default: {'same'})         prefix {str} -- Predix of layer names (default: {None})      Returns:         Output tensor for the block. A identity block.          Arguments:         X {tensor} -- Input tensor         filters {integer} -- The filters of convolutional layer         kernel_size {integer} -- The kernel size of convolutional layer          Keyword Arguments:         strides {tuple} -- The strides of convolutional layer (default: {(1,1)})         prefix {str} -- Predix of layer names (default: {None})         with_conv_shortcut {bool} -- With a convolutional layer at shortcut or not (default: {False})          Returns:         Output tensor for the block. A bottleneck block          Arguments:         X {tensor} -- Input tensor         filters {list} -- The filterss of 3 conv layer at main path          Keyword Arguments:         strides {tuple} -- The strides of convolutional layer (default: {(1,1)})         prefix {str} -- Predix of layer names (default: {None})         with_conv_shortcut {bool} -- With a convolutional layer at shortcut or not (default: {False})          Returns:         Output tensor for the block.