model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(units, activation='relu'))
# model.add(tf.keras.layers.Embedding(len(test_encoding), 64))
model.add(tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)))
# model.add(tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)))
# One or more dense layers.
# Edit the list in the `for` line to experiment with layer sizes.
for units in [64, 64]:
  model.add(tf.keras.layers.Dense(units, activation='relu'))

# Output layer. The first argument is the number of labels.
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))

model.compile(optimizer='adam',
              loss='binary_crossentropy',
              metrics=['accuracy', tf.keras.metrics.TruePositives(name='tp'),
      tf.keras.metrics.FalsePositives(name='fp'),
      tf.keras.metrics.TrueNegatives(name='tn'),
      tf.keras.metrics.FalseNegatives(name='fn')])

model.fit(train_data, epochs=100, validation_data=test_data)

loss, accuracy, tp, fp, tn, fn,   = model.evaluate(test_data)
print('Test Loss: {}'.format(loss))
print('Test Accuracy: {}'.format(accuracy))
print('Test TP: {}'.format(tp))
print('Test FP: {}'.format(fp))
print('Test TN: {}'.format(tn))
print('Test FN: {}'.format(fn))

# print('\nEval loss: {:.3f}, Eval accuracy: {:.3f}'.format(eval_loss, eval_acc))
                  activation='relu'),
     layers.BatchNormalization(),
     layers.Dropout(rate=0.2),
     layers.Dense(units=256, activation='relu'),
     layers.BatchNormalization(),
     layers.Dropout(rate=0.2),
     layers.Dense(units=256, activation='relu'),
     layers.BatchNormalization(),
     layers.Dropout(rate=0.2),
     layers.Dense(units=n_tags, activation='sigmoid')
 ])
 # see model's info:
 model.summary()
 # compile model: (get it readdy for training)
 model.compile(optimizer='Adam',
               loss='categorical_crossentropy',
               metrics=[keras.metrics.CategoricalAccuracy()])
 log_dir = prj_dir + r"logs\\" + name + r'\\' + datetime.datetime.now(
 ).strftime("%Y%m%d-%H%M%S")
 my_callbacks = [
     keras.callbacks.EarlyStopping(patience=8),
     keras.callbacks.ModelCheckpoint(
         filepath=prj_dir + r".\\model\\" + name +
         r"\\model.{epoch:02d}-{val_loss:.2f}.h5"),
     keras.callbacks.TensorBoard(log_dir=log_dir)
 ]
 epochs = 100
 # train model:
 # verbose can be 0/1/2 (0=no output, 2=max output)
 # shuffle happens after the validation split!!
 # validation set is set to be 5% of train data
            activation=partial(tf.nn.leaky_relu, alpha=0.01),
            kernel_initializer=k.initializers.GlorotNormal()),
    l.GaussianDropout(0.1),
    l.Dense(128,
            activation=partial(tf.nn.leaky_relu, alpha=0.01),
            kernel_initializer=k.initializers.GlorotNormal()),
    l.GaussianDropout(0.1),
    l.Dense(64,
            activation=partial(tf.nn.leaky_relu, alpha=0.01),
            kernel_initializer=k.initializers.GlorotNormal()),
    l.Dense(1, activation=tf.nn.sigmoid),
])

model.compile(optimizer=tf.optimizers.Adam(learning_rate=0.001,
                                           beta_1=0.93,
                                           amsgrad=False),
              loss='binary_crossentropy',
              metrics=['accuracy'])


class CallbackLimit(tf.keras.callbacks.Callback):
    def on_epoch_end(self, epoch, logs={}):
        if logs.get('loss') < 0.25:
            print(
                "\n\nReached under 0.25 of loss.\nWe stop the process here.\n\n"
            )
            self.model.stop_training = True


class CallbackLimitAcc(tf.keras.callbacks.Callback):
    def on_epoch_end(self, epoch, logs={}):
# load bert_dev
# pickle_in = open("bert_dev_1024.pickle", "rb")
# bert_x_dev = pickle.load(pickle_in)
#
# # load bert_test
# pickle_in = open("bert_test_1024.pickle", "rb")
# bert_x_test = pickle.load(pickle_in)

input_layer = Input((None, 1024))
model = Dense(256, activation='relu')(input_layer)
model = Bidirectional(LSTM(units=512, return_sequences=True))(model)
model = Bidirectional(LSTM(64, return_sequences=False))(model)
pred = Dense(1, activation='sigmoid')(model)
model = Model(inputs=input_layer, outputs=pred)
model.compile(loss='binary_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])
model.summary()
model.fit(bert_x_train,
          y_train,
          epochs=10,
          verbose=True,
          validation_data=(bert_x_dev, y_dev),
          batch_size=32)
predictions = model.predict(bert_x_dev, verbose=True, batch_size=32)

# Dev predict
for i in range(0, len(predictions)):
    if float(predictions[i]) > 0.5:
        result_dev.update({'dev-%d' % i: {'label': 1}})
    else: