"""
Separated File containing all different models implemented

Creation Date: May 2020
Creator: GranScudetto
"""
from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense
from tensorflow.keras.layers import MaxPool2D, Concatenate, Flatten
from tensorflow.keras import Model


def model_1(input_shape, nb_classes):
    # 32 x 32
    inp = Input(shape=input_shape)
    conv_1 = Conv2D(filters=16, kernel_size=(3, 3), activation='relu', padding='same')(inp)
    pool_1 = MaxPool2D(pool_size=(2, 2))(conv_1)
    # 16 x 16
    conv_2 = Conv2D(filters=32, kernel_size=(3, 3), activation='relu', padding='same')(pool_1)
    conv_3 = Conv2D(filters=64, kernel_size=(3, 3), activation='relu', padding='same')(conv_2)
    pool_2 = MaxPool2D(pool_size=(2, 2))(conv_3)
    # 8 x 8
    conv_4 = Conv2D(filters=64, kernel_size=(3, 3), activation='relu', padding='same')(pool_2)
    conv_5 = Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='same')(conv_4)
    pool_3 = MaxPool2D(pool_size=(2, 2))(conv_5)
    # 4 x 4
    conv_6 = Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='same')(pool_3)
    conv_7 = Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='same')(conv_6)
    flatten = Flatten()(conv_7)
    dense_1 = Dense(units=512, activation='relu')(flatten)
    out = Dense(units=nb_classes, activation='softmax')(dense_1)

    return Model(inputs=inp, outputs=out)


def model_2(input_shape, nb_classes):
    
    # 32, 16, 8, 4, 2
    inp = Input(shape=input_shape)  # 32 x 32
    
    conv_3x3_1 = Conv2D(filters=16, kernel_size=(3, 3), padding='same')(inp)
    conv_3x3_1 = BatchNormalization()(conv_3x3_1)
    conv_3x3_1 = Activation(activation='relu')(conv_3x3_1)
    
    conv_5x5_1 = Conv2D(filters=16, kernel_size=(3, 3), padding='same')(inp)
    conv_5x5_1 = BatchNormalization()(conv_5x5_1)
    conv_5x5_1 = Activation(activation='relu')(conv_5x5_1)
    
    network_layer_1 = Concatenate()([conv_3x3_1, conv_5x5_1])
    network_layer_1_pooled = MaxPool2D(pool_size=(2, 2))(network_layer_1)  # 16x16
    
    conv_3x3_2 = Conv2D(filters=32, kernel_size=(3, 3), padding='same')(network_layer_1_pooled)
    conv_3x3_2 = BatchNormalization()(conv_3x3_2)
    conv_3x3_2 = Activation(activation='relu')(conv_3x3_2)
    
    conv_5x5_2 = Conv2D(filters=32, kernel_size=(3, 3), padding='same')(network_layer_1_pooled)
    conv_5x5_2 = BatchNormalization()(conv_5x5_2)
    conv_5x5_2 = Activation(activation='relu')(conv_5x5_2)
    
    scaled_input = MaxPool2D(pool_size=(2, 2))(inp)
    conv_3x3_1_3 = Conv2D(filters=16, kernel_size=(3, 3), padding='same')(scaled_input)
    conv_3x3_1_3 = BatchNormalization()(conv_3x3_1_3)
    conv_3x3_1_3 = Activation(activation='relu')(conv_3x3_1_3)
    conv_3x3_2_3 = Conv2D(filters=32, kernel_size=(3, 3), padding='same')(conv_3x3_1_3)
    conv_3x3_2_3 = BatchNormalization()(conv_3x3_2_3)
    conv_3x3_2_3 = Activation(activation='relu')(conv_3x3_2_3)
    
    network_layer_2 = Concatenate()([conv_3x3_2, conv_5x5_2, conv_3x3_2_3])
    network_layer_2_pooled = MaxPool2D(pool_size=(2, 2))(network_layer_2)  # 8x8
    
    conv_3x3_3 = Conv2D(filters=64, kernel_size=(3, 3), padding='same')(network_layer_2_pooled)
    conv_3x3_3 = BatchNormalization()(conv_3x3_3)
    conv_3x3_3 = Activation(activation='relu')(conv_3x3_3)
    
    conv_3x3_3_3 = Conv2D(filters=64, kernel_size=(3, 3), padding='same')(conv_3x3_2_3)
    conv_3x3_3_3 = BatchNormalization()(conv_3x3_3_3)
    conv_3x3_3_3 = Activation(activation='relu')(conv_3x3_3_3)
    
    conv_3x3_3_3 = MaxPool2D(pool_size=(2, 2))(conv_3x3_3_3)
    network_layer_3 = Concatenate()([conv_3x3_3, conv_3x3_3_3])
    network_layer_3_pooled = MaxPool2D(pool_size=(2, 2))(network_layer_3)
    
    conv_3x3_4 = Conv2D(filters=128, kernel_size=(3, 3), padding='same')(network_layer_3_pooled)
    conv_3x3_4 = BatchNormalization()(conv_3x3_4)
    conv_3x3_4 = Activation(activation='relu')(conv_3x3_4)
    
    conv_3x3_5 = Conv2D(filters=64, kernel_size=(3, 3), padding='same')(conv_3x3_4)
    conv_3x3_5 = BatchNormalization()(conv_3x3_5)
    conv_3x3_5 = Activation(activation='relu')(conv_3x3_5)
    
    conv_3x3_6 = Conv2D(filters=128, kernel_size=(3, 3), padding='same')(conv_3x3_5)
    conv_3x3_6 = BatchNormalization()(conv_3x3_6)
    conv_3x3_6 = Activation(activation='relu')(conv_3x3_6)
    
    flattened = Flatten()(conv_3x3_6)
    flattened = Dense(units=128, activation='relu')(flattened)
    dense_pre_out = Dense(units=nb_classes, activation='relu')(flattened)
    
    out = Dense(units=nb_classes, activation='softmax')(dense_pre_out)
    
    return Model(inputs=inp, outputs=out)

tensorflow.keras.layers.Concatenate tensorflow.keras.layers.Activation tensorflow.keras.layers.Dense tensorflow.keras.layers.Conv2D tensorflow.keras.layers.MaxPool2D tensorflow.keras.Model tensorflow.keras.layers.BatchNormalization tensorflow.keras.layers.Flatten tensorflow.keras.layers.Input
[(14, 'tensorflow.keras.layers.Input', 'Input', ([], {'shape': 'input_shape'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (32, 'tensorflow.keras.Model', 'Model', ([], {'inputs': 'inp', 'outputs': 'out'}), False, 'from tensorflow.keras import Model\n'), (38, 'tensorflow.keras.layers.Input', 'Input', ([], {'shape': 'input_shape'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (100, 'tensorflow.keras.Model', 'Model', ([], {'inputs': 'inp', 'outputs': 'out'}), False, 'from tensorflow.keras import Model\n'), (15, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(16)', 'kernel_size': '(3, 3)', 'activation': '"""relu"""', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (16, 'tensorflow.keras.layers.MaxPool2D', 'MaxPool2D', ([], {'pool_size': '(2, 2)'}), False, 'from tensorflow.keras.layers import MaxPool2D, Concatenate, Flatten\n'), (18, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(32)', 'kernel_size': '(3, 3)', 'activation': '"""relu"""', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (19, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(64)', 'kernel_size': '(3, 3)', 'activation': '"""relu"""', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (20, 'tensorflow.keras.layers.MaxPool2D', 'MaxPool2D', ([], {'pool_size': '(2, 2)'}), False, 'from tensorflow.keras.layers import MaxPool2D, Concatenate, Flatten\n'), (22, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(64)', 'kernel_size': '(3, 3)', 'activation': '"""relu"""', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (23, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(128)', 'kernel_size': '(3, 3)', 'activation': '"""relu"""', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (24, 'tensorflow.keras.layers.MaxPool2D', 'MaxPool2D', ([], {'pool_size': '(2, 2)'}), False, 'from tensorflow.keras.layers import MaxPool2D, Concatenate, Flatten\n'), (26, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(128)', 'kernel_size': '(3, 3)', 'activation': '"""relu"""', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (27, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(256)', 'kernel_size': '(3, 3)', 'activation': '"""relu"""', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (28, 'tensorflow.keras.layers.Flatten', 'Flatten', ([], {}), False, 'from tensorflow.keras.layers import MaxPool2D, Concatenate, Flatten\n'), (29, 'tensorflow.keras.layers.Dense', 'Dense', ([], {'units': '(512)', 'activation': '"""relu"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (30, 'tensorflow.keras.layers.Dense', 'Dense', ([], {'units': 'nb_classes', 'activation': '"""softmax"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (40, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(16)', 'kernel_size': '(3, 3)', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (41, 'tensorflow.keras.layers.BatchNormalization', 'BatchNormalization', ([], {}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (42, 'tensorflow.keras.layers.Activation', 'Activation', ([], {'activation': '"""relu"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (44, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(16)', 'kernel_size': '(3, 3)', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (45, 'tensorflow.keras.layers.BatchNormalization', 'BatchNormalization', ([], {}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (46, 'tensorflow.keras.layers.Activation', 'Activation', ([], {'activation': '"""relu"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (48, 'tensorflow.keras.layers.Concatenate', 'Concatenate', ([], {}), False, 'from tensorflow.keras.layers import MaxPool2D, Concatenate, Flatten\n'), (49, 'tensorflow.keras.layers.MaxPool2D', 'MaxPool2D', ([], {'pool_size': '(2, 2)'}), False, 'from tensorflow.keras.layers import MaxPool2D, Concatenate, Flatten\n'), (51, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(32)', 'kernel_size': '(3, 3)', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (52, 'tensorflow.keras.layers.BatchNormalization', 'BatchNormalization', ([], {}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (53, 'tensorflow.keras.layers.Activation', 'Activation', ([], {'activation': '"""relu"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (55, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(32)', 'kernel_size': '(3, 3)', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (56, 'tensorflow.keras.layers.BatchNormalization', 'BatchNormalization', ([], {}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (57, 'tensorflow.keras.layers.Activation', 'Activation', ([], {'activation': '"""relu"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (59, 'tensorflow.keras.layers.MaxPool2D', 'MaxPool2D', ([], {'pool_size': '(2, 2)'}), False, 'from tensorflow.keras.layers import MaxPool2D, Concatenate, Flatten\n'), (60, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(16)', 'kernel_size': '(3, 3)', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (61, 'tensorflow.keras.layers.BatchNormalization', 'BatchNormalization', ([], {}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (62, 'tensorflow.keras.layers.Activation', 'Activation', ([], {'activation': '"""relu"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (63, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(32)', 'kernel_size': '(3, 3)', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (64, 'tensorflow.keras.layers.BatchNormalization', 'BatchNormalization', ([], {}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (65, 'tensorflow.keras.layers.Activation', 'Activation', ([], {'activation': '"""relu"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (67, 'tensorflow.keras.layers.Concatenate', 'Concatenate', ([], {}), False, 'from tensorflow.keras.layers import MaxPool2D, Concatenate, Flatten\n'), (68, 'tensorflow.keras.layers.MaxPool2D', 'MaxPool2D', ([], {'pool_size': '(2, 2)'}), False, 'from tensorflow.keras.layers import MaxPool2D, Concatenate, Flatten\n'), (70, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(64)', 'kernel_size': '(3, 3)', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (71, 'tensorflow.keras.layers.BatchNormalization', 'BatchNormalization', ([], {}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (72, 'tensorflow.keras.layers.Activation', 'Activation', ([], {'activation': '"""relu"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (74, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(64)', 'kernel_size': '(3, 3)', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (75, 'tensorflow.keras.layers.BatchNormalization', 'BatchNormalization', ([], {}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (76, 'tensorflow.keras.layers.Activation', 'Activation', ([], {'activation': '"""relu"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (78, 'tensorflow.keras.layers.MaxPool2D', 'MaxPool2D', ([], {'pool_size': '(2, 2)'}), False, 'from tensorflow.keras.layers import MaxPool2D, Concatenate, Flatten\n'), (79, 'tensorflow.keras.layers.Concatenate', 'Concatenate', ([], {}), False, 'from tensorflow.keras.layers import MaxPool2D, Concatenate, Flatten\n'), (80, 'tensorflow.keras.layers.MaxPool2D', 'MaxPool2D', ([], {'pool_size': '(2, 2)'}), False, 'from tensorflow.keras.layers import MaxPool2D, Concatenate, Flatten\n'), (82, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(128)', 'kernel_size': '(3, 3)', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (83, 'tensorflow.keras.layers.BatchNormalization', 'BatchNormalization', ([], {}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (84, 'tensorflow.keras.layers.Activation', 'Activation', ([], {'activation': '"""relu"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (86, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(64)', 'kernel_size': '(3, 3)', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (87, 'tensorflow.keras.layers.BatchNormalization', 'BatchNormalization', ([], {}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (88, 'tensorflow.keras.layers.Activation', 'Activation', ([], {'activation': '"""relu"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (90, 'tensorflow.keras.layers.Conv2D', 'Conv2D', ([], {'filters': '(128)', 'kernel_size': '(3, 3)', 'padding': '"""same"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (91, 'tensorflow.keras.layers.BatchNormalization', 'BatchNormalization', ([], {}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (92, 'tensorflow.keras.layers.Activation', 'Activation', ([], {'activation': '"""relu"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (94, 'tensorflow.keras.layers.Flatten', 'Flatten', ([], {}), False, 'from tensorflow.keras.layers import MaxPool2D, Concatenate, Flatten\n'), (95, 'tensorflow.keras.layers.Dense', 'Dense', ([], {'units': '(128)', 'activation': '"""relu"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (96, 'tensorflow.keras.layers.Dense', 'Dense', ([], {'units': 'nb_classes', 'activation': '"""relu"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n'), (98, 'tensorflow.keras.layers.Dense', 'Dense', ([], {'units': 'nb_classes', 'activation': '"""softmax"""'}), False, 'from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Dense\n')]