### Load necessary libraries ###

import numpy as np
from sklearn.model_selection import KFold
from sklearn.metrics import accuracy_score

import tensorflow as tf
from tensorflow import keras

from sklearn.metrics import ConfusionMatrixDisplay

model = get_network()
model.summary()

### Train and evaluate via 10-Folds cross-validation ###
accuracies = []
folds = np.array(['fold1','fold2','fold3','fold4',
                  'fold5','fold6','fold7','fold8',
                  'fold9','fold10'])
load_dir = "UrbanSounds8K/processed/"
kf = KFold(n_splits=10)
for train_index, test_index in kf.split(folds):
    x_train, y_train = [], []
    for ind in train_index:
        # read features or segments of an audio file
        train_data = np.load("{0}/{1}.npz".format(load_dir,folds[ind]), 
                       allow_pickle=True)
        # for training stack all the segments so that they are treated as an example/instance
        features = np.concatenate(train_data["features"], axis=0) 
        labels = np.concatenate(train_data["labels"], axis=0)
        x_train.append(features)
        y_train.append(labels)

    # stack x,y pairs of all training folds 
    x_train = np.concatenate(x_train, axis = 0).astype(np.float32)
    y_train = np.concatenate(y_train, axis = 0).astype(np.float32)
    
    # for testing we will make predictions on each segment and average them to 
    # produce single label for an entire sound clip.
    test_data = np.load("{0}/{1}.npz".format(load_dir,
                   folds[test_index][0]), allow_pickle=True)
    x_test = test_data["features"]
    y_test = test_data["labels"]

    log_dir="logs/fit/" + folds[test_index][0]
    tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)

    model = get_network()
    model.fit(x_train, y_train, epochs = 20, batch_size = 64, verbose = 1, validation_split=0.2,
                use_multiprocessing=True, workers=8, callbacks=[tensorboard_callback])
    
    # evaluate on test set/fold
    y_true, y_pred = [], []
    for x, y in zip(x_test, y_test):
        # average predictions over segments of a sound clip
        avg_p = np.argmax(np.mean(model.predict(x), axis = 0))
        y_pred.append(avg_p) 
        # pick single label via np.unique for a sound clip
        y_true.append(np.unique(y)[0]) 
    accuracies.append(accuracy_score(y_true, y_pred))    
    print("Fold n accuracy: {0}".format(accuracy_score(y_true, y_pred)))

    cm = ConfusionMatrixDisplay.from_predictions(y_true, y_pred)
    cm.figure_.savefig('conf_mat_' + str(test_index) + '_acc_' + str(accuracy_score(y_true, y_pred)) + '.png',dpi=1000)    

print("Average 10 Folds Accuracy: {0}".format(np.mean(accuracies)))

[((17, 8, 19, 36), 'numpy.array', 'np.array', ({(17, 17, 19, 35): "['fold1', 'fold2', 'fold3', 'fold4', 'fold5', 'fold6', 'fold7', 'fold8',\n    'fold9', 'fold10']"}, {}), "(['fold1', 'fold2', 'fold3', 'fold4', 'fold5', 'fold6', 'fold7',\n    'fold8', 'fold9', 'fold10'])", True, 'import numpy as np\n'), ((21, 5, 21, 23), 'sklearn.model_selection.KFold', 'KFold', (), '', False, 'from sklearn.model_selection import KFold\n'), ((46, 27, 46, 92), 'tensorflow.keras.callbacks.TensorBoard', 'tf.keras.callbacks.TensorBoard', (), '', True, 'import tensorflow as tf\n'), ((63, 9, 63, 64), 'sklearn.metrics.ConfusionMatrixDisplay.from_predictions', 'ConfusionMatrixDisplay.from_predictions', ({(63, 49, 63, 55): 'y_true', (63, 57, 63, 63): 'y_pred'}, {}), '(y_true, y_pred)', False, 'from sklearn.metrics import ConfusionMatrixDisplay\n'), ((29, 19, 29, 65), 'numpy.concatenate', 'np.concatenate', (), '', True, 'import numpy as np\n'), ((30, 17, 30, 61), 'numpy.concatenate', 'np.concatenate', (), '', True, 'import numpy as np\n'), ((60, 22, 60, 52), 'sklearn.metrics.accuracy_score', 'accuracy_score', ({(60, 37, 60, 43): 'y_true', (60, 45, 60, 51): 'y_pred'}, {}), '(y_true, y_pred)', False, 'from sklearn.metrics import accuracy_score\n'), ((66, 46, 66, 65), 'numpy.mean', 'np.mean', ({(66, 54, 66, 64): 'accuracies'}, {}), '(accuracies)', True, 'import numpy as np\n'), ((35, 14, 35, 47), 'numpy.concatenate', 'np.concatenate', (), '', True, 'import numpy as np\n'), ((36, 14, 36, 47), 'numpy.concatenate', 'np.concatenate', (), '', True, 'import numpy as np\n'), ((61, 40, 61, 70), 'sklearn.metrics.accuracy_score', 'accuracy_score', ({(61, 55, 61, 61): 'y_true', (61, 63, 61, 69): 'y_pred'}, {}), '(y_true, y_pred)', False, 'from sklearn.metrics import accuracy_score\n'), ((59, 22, 59, 34), 'numpy.unique', 'np.unique', ({(59, 32, 59, 33): 'y'}, {}), '(y)', True, 'import numpy as np\n'), ((64, 69, 64, 99), 'sklearn.metrics.accuracy_score', 'accuracy_score', ({(64, 84, 64, 90): 'y_true', (64, 92, 64, 98): 'y_pred'}, {}), '(y_true, y_pred)', False, 'from sklearn.metrics import accuracy_score\n')]