
# Tento skript slouzi k vytvoreni a trenovani klasifikacnich CNN

import tensorflow as tf
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D
import os

import pickle
import numpy as np
from keras.utils import to_categorical

from keras.callbacks import EarlyStopping




nazev = "tucnak"                                # Název adresáře příslušné galerie dat


DATADIR = "./" + nazev


os.chdir(DATADIR)                               # Prepnuti do prislusneho adresare




pickle_in = open("X.pickle","rb")               # Otevreni souboru obsahujiciho dataset, nacteni dat do promenne, zavreni souboru
X = pickle.load(pickle_in)
pickle_in.close()

pickle_in = open("y.pickle","rb")
y = pickle.load(pickle_in)
pickle_in.close()


pickle_in = open("X_val.pickle","rb")
X_val = pickle.load(pickle_in)
pickle_in.close()

pickle_in = open("y_val.pickle","rb")
y_val = pickle.load(pickle_in)
pickle_in.close()



X = X/255.0                                     # Normalizace dat
y = to_categorical(y)                           # One hot encoding

X_val = X_val/255.0
y_val = to_categorical(y_val)




# Vytvoreni modelu CNN
model = Sequential()

model.add(Conv2D(filters=32, kernel_size=(3,3), input_shape=X.shape[1:]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(32, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))


model.add(Flatten())  # this converts our 3D feature maps to 1D feature vectors

model.add(Dense(512))
model.add(Dropout(0.2))
model.add(Dense(32))
model.add(Dropout(0.2))

model.add(Dense(2, activation='softmax'))

#TISK STRUKTURY MODELU s pripadnym presmerovanim do textoveho souboru
#print(model.summary())
'''
from contextlib import redirect_stdout
with open('struktura_cnn.txt', 'w') as f:
    with redirect_stdout(f):
        model.summary()
'''


model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

y = np.asarray(y)
y_val = np.asarray(y_val)

#es = EarlyStopping(monitor='val_loss', min_delta = 0, mode='auto', verbose=1, patience=8)      # Nastaveni parametru Early Stopping
 
his = model.fit(X, y,                                                                           # Volani trenovaci metody s nastavenymi parametry trenovani. Metoda vraci histori trenovani, cili prubeh chyby a presnosti behem tohoto procesu
        batch_size=64,
        validation_data=(X_val, y_val),
        epochs=6,
        ) #callbacks=[es]


print('accuracy: ', his.history['accuracy'])                                                    # Tisk accuracy



#uloz = input("Ulozit? [a]: ")
#if uloz == 'a':
nazev = nazev + "klas.h5"                           # Ukladani natrenovanych modelu. Nazev odvozen od nazvu vlastniho adresare
model.save(nazev)

pic_out = open("his.pickle","wb")                   # Ulozeni historie trenovani, uklada se loss a accuracy
pickle.dump(his.history, pic_out)
pic_out.close()

