num_of_GPU_cores = 1

tryparameters = [
    {'A': 512, 'A1': 512, 'B': 2, 'DENSE1': 256, 'DENSE2': 256, 'DROP1': 0.1, 'DROP2': 0.1, 'NBE': 30},
 ]

def create(A, A1, B, DENSE1, DENSE2, DROP1,DROP2,NBE, compile=True):

    from keras.callbacks import EarlyStopping, ReduceLROnPlateau
    from keras import optimizers
    early_stopping = EarlyStopping(monitor='val_loss', patience=33)
    reduce_LR = ReduceLROnPlateau(monitor='val_acc', factor=0.333, patience=6, verbose=1, mode='auto', cooldown=0, min_lr=0.0000001)
    callbacks = [early_stopping, reduce_LR]

    trainsettings = {'nb_epoch': NBE,
                     'verbose': 1,
                     'callbacks': callbacks,
                     'class_weight': None
            }

    if not compile: return trainsettings


    from keras.models import Model
    from keras.layers import Input, Dense, Dropout, CuDNNLSTM, average, Conv2D, Reshape

    input = Input(shape=(512, 88), name='Input')
    reshapedInput = Reshape((1, 512, 88), input_shape=(512, 88), name='RespapeInput')(input)

    convolution2D = Conv2D(400, (2, 88), data_format="channels_first", activation='relu', name='FirstConvolution1')(reshapedInput)
    convolution2D = Conv2D(200, (2, 1), data_format="channels_first", activation='relu', name='SecondConvolution1')(convolution2D)
    reshapedconv2 = Reshape((510 ,200), input_shape=(200,510,1), name='ReshapeConvolution1')(convolution2D)

    a = CuDNNLSTM(A, kernel_initializer='glorot_uniform',  recurrent_initializer='orthogonal', bias_initializer='zeros', name='FirstCuDNNLSTM1',  unit_forget_bias=True, return_sequences=True)(reshapedconv2)
    cca = Dropout(DROP1, name='DropoutCuDNNLSTM1')(a)
    b = CuDNNLSTM(A1, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros',  name='SecondCuDNNLSTM1',
                  unit_forget_bias=True, return_sequences=False)(cca)
    convolution2Db = Conv2D(600, (2, 88), data_format="channels_first", activation='relu', name='FirstConvolution2')(reshapedInput)

    convolution2Db = Conv2D(300, (2, 1), data_format="channels_first", activation='relu', name='SecondConvolution2')(convolution2Db)
    reshapedconv2b = Reshape((510, 300), input_shape=(300, 510, 1), name='ReshapeConvolution2')(convolution2Db)

    aa = CuDNNLSTM(A, kernel_initializer='glorot_uniform',  recurrent_initializer='orthogonal', bias_initializer='zeros', name='FirstCuDNNLSTM2', unit_forget_bias=True, return_sequences=True)(reshapedconv2b)
    cc = Dropout(DROP1, name='DropoutCuDNNLSTM2')(aa)
    bb = CuDNNLSTM(A1, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', name='SecondCuDNNLSTM2',
                  unit_forget_bias=True, return_sequences=False)(cc)

    x = average([b, bb], name='AverageCuDNNLSTM1_2')
    c = Dropout(DROP2, name='DenseDropout1')(x)
    d = Dense(DENSE1, activation='relu', name='Dense1')(c)
    e = Dropout(DROP2, name='DenseDropout2')(d)
    d = Dense(DENSE2, activation='relu', name='Dense2')(e)
    f = Dropout(DROP2, name='SoftmaxDropout3')(d)
    out = Dense(B, activation='softmax', name='Softmax1')(f)

    model = Model(input, out)
    adam = optimizers.adam(lr=0.01, epsilon=0.03)
    model.compile(loss='categorical_crossentropy', optimizer=adam, metrics=["accuracy"])

    return model, trainsettings