df_train = sessions_to_dataframe(training_sessions)
df_val = sessions_to_dataframe(validation_sessions)
df_train.head()

df_train = preprocess_data(df_train)
df_val = preprocess_data(df_val)
#### SPECIAL CASE #####
# There isnt any XButton data in the validation set so we better drop this column for the training set
# if we want to have the same number of features in both sets
df_train = df_train.drop(['XButton'], axis = 1)
#### SPECIAL CASE #####

df_train.head()

seq_size = 300

train_x, train_y = data_to_machine_learning_examples(df_train, seq_size)
print('[*] Generated traning examples {} and labels {}'.format(train_x.shape, train_y.shape))
val_x, val_y = data_to_machine_learning_examples(df_val, seq_size)
print('[*] Generated validation examples {} and labels {}'.format(val_x.shape, val_y.shape))

def print_model(model):
    print("[*] Sequential model created with the following layers:")
    for layer in model.layers:
        print("{:30}{} -> {}".format(layer.name, layer.input_shape, layer.output_shape)) 

from keras.models import load_model
from keras.callbacks import ModelCheckpoint
from keras.callbacks import ReduceLROnPlateau
from keras.callbacks import TensorBoard

epochs = 200
batch_size = 30
learning_rate = 0.0001
batch_norm_momentum = 0.2
n_classes = 10
data_point_dimensionality = 13

# model = load_model('model/model_18.h5')
model = create_model_paper(input_shape = (seq_size, data_point_dimensionality),
                     classes = n_classes,
                     batch_norm_momentum = batch_norm_momentum,
                     l2_regularization = 0.01)

optimizer = Adam(lr=learning_rate)    
model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])
    
cb_check = ModelCheckpoint('model/checkpoint', monitor='val_loss', verbose=1, period=30)
cb_reducelr = ReduceLROnPlateau(verbose=1)
cb_tensorboard = TensorBoard(log_dir='./logs', histogram_freq=30, write_graph=True)

hist = model.fit(train_x, train_y, 
                 batch_size, epochs, 2, 
                 validation_data=(val_x, val_y),
                 callbacks = [cb_reducelr])
#                  callbacks =[cb_check, cb_reducelr, cb_tensorboard])

plt.plot(hist.history['loss'])
plt.plot(hist.history['val_loss'])

plt.plot(hist.history['acc'])
plt.plot(hist.history['val_acc'])

"""
Explanation: Convert training sessions to labeled examples, each example will have a seq_size sequence size, we will include three features per data point, the timestamp, the x position and the y position. We will one-hot encode the labels, and shuffle all the data.
End of explanation
"""


from keras.models import load_model

model = load_model('model/model_18.h5')

def print_model(model):
    print("[*] Sequential model created with the following layers:")
    for layer in model.layers:
        print("{:30}{} -> {}".format(layer.name, layer.input_shape, layer.output_shape)) 



print_model(model)

from keras.models import Model

layer_name = 'global_average_pooling1d_1'
intermediate_layer_model = Model(inputs=model.input,
                                 outputs=model.get_layer(layer_name).output)

intermediate_output = intermediate_layer_model.predict(train_x)
y_data = model.predict(train_x)

intermediate_output.shape

y_data_nums = [np.argmax(row) for row in y_data]

from sklearn.manifold import TSNE

tsne_model = TSNE(n_components=2, random_state=0)
np.set_printoptions(suppress=True)
result = tsne_model.fit_transform(intermediate_output)

print(result)

import seaborn as sns
sns.set(style="white", color_codes=True)
g = sns.jointplot(x=result[:,0], y=result[:,1])

plt.figure(1, figsize=(12, 10))
plt.scatter(result[:,0], result[:,1], c=y_data_nums, cmap=plt.cm.get_cmap("jet"))
# plt.scatter(result[:,0], result[:,1])
plt.colorbar(ticks=range(10))
plt.clim(-0.5, 9.5)
plt.show()

"""
Explanation: TSNE
End of explanation
"""


