from __future__ import division
from __future__ import absolute_import
from __future__ import print_function
import numpy as np
np.random.seed(1337)  # for reproducibility

from keras.optimizers import SGD
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.layers.normalization import BatchNormalization
from keras.utils import np_utils
import keras
from PIL import Image
import glob
from sklearn import preprocessing

import cPickle
from make_dataset import *

from keras.models import model_from_json

class LossHistory(keras.callbacks.Callback):
    def on_train_begin(self, logs={}):
        self.losses = []
        self.e_losses=[]
        self.e_acc = []
        self.accu = []
    def on_batch_end(self, batch, logs={}):
        self.losses.append(logs.get('loss'))
        self.accu.append(logs.get('acc'))

    def on_epoch_end(self,epoch,logs={}):
        self.e_losses.append(logs.get('val_loss'))
        self.e_acc.append(logs.get('val_acc'))



X_train,X_test,y_train,y_test = get_data("/home/ubuntu/teste/training_POS","/home/ubuntu/teste/training_set")


print(X_train.shape[0], 'train samples')
print(X_test.shape[0], 'test samples')

print ("Creating CNN")
#Convolutional Neural Network initialization
modelo = Sequential()

modelo.add(Convolution2D(10,15,15,border_mode = 'valid',input_shape=(1,200,200)))
modelo.add(Activation('relu'))
modelo.add(MaxPooling2D(pool_size = (2,2)))
modelo.add(BatchNormalization())

modelo.add(Convolution2D(15,8,8))
modelo.add(Activation('relu'))
modelo.add(MaxPooling2D(pool_size = (2,2)))
modelo.add(BatchNormalization())

modelo.add(Convolution2D(20,8,8))
modelo.add(Activation('relu'))
modelo.add(MaxPooling2D(pool_size = (2,2)))
modelo.add(BatchNormalization())

modelo.add(Convolution2D(30,6,6))
modelo.add(Activation('relu'))
modelo.add(MaxPooling2D(pool_size = (2,2)))
modelo.add(BatchNormalization())

#modelo.add(Convolution2D(30,6,6))
#modelo.add(Activation('relu'))
#modelo.add(MaxPooling2D(pool_size = (2,2)))
#modelo.add(Dropout(0.5))



#Fully Connected network for classification
modelo.add(Flatten())

modelo.add(Dense(150))
modelo.add(Activation('relu'))
modelo.add(Dropout(0.5))
modelo.add(Dense(100))
modelo.add(Activation('relu'))
modelo.add(Dropout(0.5))
modelo.add(Dense(50))
modelo.add(Activation('relu'))
modelo.add(Dense(30))
modelo.add(Activation('relu'))
modelo.add(Dropout(0.5))
modelo.add(Dense(2))
modelo.add(Activation('softmax'))

print ("CNN Created!")

print ("\nCompiling model...")
#sgd = SGD(lr = 0.01, decay = 1e-6, momentum = 0.8, nesterov = True)
modelo.compile(loss = 'mse',optimizer = 'adadelta')
print ("\n Model compiled!")

history = LossHistory()

print ("\nTraining the model...")
modelo.fit(X_train,y_train,batch_size = 10, nb_epoch = 2000, show_accuracy = True, verbose = 1,callbacks = [history])
print ("Model trained")
score= modelo.evaluate(X_test,y_test,show_accuracy=True,verbose=0)
print('Test score:', score[0])
print('Test accuracy:', score[1])

f = file('history.save','wb')
cPickle.dump(history,f)
f.close()

#Saving shit
#json_string = modelo.to_json()
#model = model_from_json(json_string)
#modelo.save_weights('pesos.h5')


