"""
# Libraries
"""
import numpy as np
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
from tqdm import tqdm

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' 

from tensorflow.keras import Input
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, Dense, LSTM, GRU, Dropout
from tensorflow.keras.initializers import Constant
from tensorflow.keras.optimizers import Adam
from tensorflow.keras import metrics, losses, models

from tensorflow import autograph
autograph.set_verbosity(0)
import tensorflow_addons as tfa
"""
# Datasets
"""
X_train = pd.read_csv('../input/lstm-gru-sentiment-analysis-data-prep/X_train.csv').to_numpy()
y_train = pd.read_csv('../input/lstm-gru-sentiment-analysis-data-prep/y_train.csv').to_numpy()
X_test  = pd.read_csv('../input/lstm-gru-sentiment-analysis-data-prep/X_test.csv').to_numpy()
y_test  = pd.read_csv('../input/lstm-gru-sentiment-analysis-data-prep/y_test.csv').to_numpy()

print("Shape of training examples : "+str(X_train.shape)+", and training labels : "+str(y_train.shape))

embedding_matrix  = pd.read_csv('../input/lstm-gru-sentiment-analysis-data-prep/embedding_matrix.csv').to_numpy()
num_words = np.shape(embedding_matrix)[0]

print("Number of words : "+str(num_words))
print("Shape of the embedding matrix : "+str(np.shape(embedding_matrix)))
"""
# Model
"""
INITIAL_DROPOUT = 0.1
NUM_UNITS_LSTM  = 32
LSTM_DROPOUT    = 0.2
NUM_UNITS_GRU   = 32
GRU_DROPOUT     = 0.2

DENSE_ACT = 'sigmoid'
LOSS_FCT  = 'mean_squared_error'
OPTIMIZER = Adam(learning_rate=0.002)
METRICS   = [metrics.CategoricalAccuracy()]
print("Shape of the X_train matrix" + str(X_train.shape) + " -- (num_examples, length of examples)")
print("Shape of the y_train vector" + str(y_train.shape) + " -- (num_examples,)")
print("Number of words in the corpus/embedding : "+str(num_words))

model = Sequential()
model.add(Input(shape=(X_train.shape[1],)))
model.add(Embedding(num_words,100,embeddings_initializer=Constant(embedding_matrix),trainable=False))

#model.add(Dropout(INITIAL_DROPOUT))

model.add(LSTM(NUM_UNITS_LSTM, return_sequences=True, dropout=LSTM_DROPOUT))

model.add(GRU(NUM_UNITS_GRU, dropout=GRU_DROPOUT))         
    
model.add(Dense(3, activation = DENSE_ACT))

model.compile(loss=LOSS_FCT,optimizer=OPTIMIZER,metrics=METRICS)

model.summary()
"""
# Training - First pass
"""
BATCH_SIZE = 100
NUM_EPOCHS = 10

history = model.fit(X_train,y_train,batch_size=BATCH_SIZE,epochs=NUM_EPOCHS,validation_data=(X_test,y_test))

model.save("lstm-gru_1.h5")
"""
# Training - Second pass
"""
#from tensorflow.keras import models
#NUM_EPOCHS_2 = 5
#model1 = models.load_model('lstm-gru_1.h5')
#history_2 = model1.fit(X_train,y_train,batch_size=BATCH_SIZE,epochs=NUM_EPOCHS_2,validation_data=(X_test,y_test))
#model1.save("lstm-gru_1.h5")
"""
# Metrics and analysis
"""
import matplotlib.pyplot as plt

epochs = range(1, NUM_EPOCHS+1)

plt.plot(epochs, history.history['categorical_accuracy'])
plt.plot(epochs, history.history['val_categorical_accuracy'])
plt.title('model categorical accuracy')
plt.ylabel('categorical accuracy')
plt.xlabel('epochs')
plt.legend(['train', 'test'], loc='upper left')
plt.xticks(epochs, epochs)
plt.show()

plt.plot(epochs, history.history['loss'])
plt.plot(epochs, history.history['val_loss'])
plt.title('model loss')
plt.xlabel('epochs')
plt.legend(['train', 'test'], loc='upper left')
plt.xticks(epochs, epochs)
plt.show()