{"cells":[{"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","scrolled":false,"trusted":true},"cell_type":"code","source":"train_set_signals = pd.read_csv(\"../input/train/subj1_series1_data.csv\")\ntrain_set_signals.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ce057d16a3a5ba83ff67bbacaad80bd4bad4f03d","trusted":true},"cell_type":"code","source":"eeg_channels = train_set_signals.columns.drop('id')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e6fdf2790a2ac641decf5989897373021f3b6555","scrolled":true,"trusted":true},"cell_type":"code","source":"train_set_labels = pd.read_csv(\"../input/train/subj1_series1_events.csv\")\ntrain_set_labels.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"5363122b47e28f5d0f7b8af774fcf8814cf71e57","trusted":true},"cell_type":"code","source":"labels = train_set_labels.columns.drop('id')\nprint(labels)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"5e8139f814555a91fb8a3d799ac46e73f302844a","scrolled":true,"trusted":true},"cell_type":"code","source":"axis = plt.gca()\ndownSampleToShow = 1\ntrain_set_signals[::downSampleToShow].plot(x=\"id\", y=\"P7\", ax=axis)\ntrain_set_signals[::downSampleToShow].plot(x=\"id\", y=\"TP10\", ax=axis, figsize=(10,5))\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"axis = plt.gca()\ndownSampleToShow = 64\ntrain_set_signals[::downSampleToShow].plot(x=\"id\", y=\"P7\", ax=axis)\ntrain_set_signals[::downSampleToShow].plot(x=\"id\", y=\"TP10\", ax=axis, figsize=(10,5))\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"97a4380554ed067d4c258b1288fb905d46230577","scrolled":true,"trusted":true},"cell_type":"code","source":"train_set_labels.plot(figsize=(10,5))\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"58286dcc970cdfdd6b548a8ea397a3c7cc200444","trusted":true},"cell_type":"code","source":"train_set_complete = pd.concat([train_set_signals,train_set_labels], axis=1)\ntrain_set_complete.insert(0, \"order\", range(0, len(train_set_complete)))\ntrain_set_complete.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6cbf2d4f8971f71ffbeffc8b2c1c9b8814710a9f","trusted":true},"cell_type":"code","source":"def highlight(indices,ax,color):\n    i=0\n    while i<len(indices):\n        ax.axvspan(indices[i]-0.5, indices[i]+0.5, facecolor=color, edgecolor='none', alpha=.35)\n        i+=1","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":false,"_kg_hide-output":false,"_uuid":"649de8bf9e30a6e6a8aad9628f01d1a45614d32f","trusted":true},"cell_type":"code","source":"secondsToShow = 5\nchannelsToShow = 3\nlabelsToShow = 6\n\nsample_set = train_set_complete[train_set_complete[\"order\"] < secondsToShow*500].drop(\"id\", axis=1).set_index(\"order\") #sample rate is 500hz \ncolors=[\"red\",\"blue\",\"yellow\",\"green\", \"purple\", \"black\"]\naxes = sample_set.plot(y=eeg_channels[:channelsToShow],subplots=True, figsize=(25,25))\nfor i in range(0, len(labels)):\n    print(labels[i], \"=\", colors[i])\n    \nfor axis in axes:    \n    colorindex = 0\n    for label in labels[:labelsToShow]:\n        highlight(sample_set[sample_set[label]==1].index, axis, colors[colorindex])        \n        colorindex = colorindex + 1\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Loading and preparation methods:**"},{"metadata":{"trusted":true},"cell_type":"code","source":"import math\nfrom sklearn.preprocessing import StandardScaler\n\ndef load_train_data(subject, series):\n    train_set_signals = pd.read_csv(f\"../input/train/subj{subject}_series{series}_data.csv\")\n    train_set_labels = pd.read_csv(f\"../input/train/subj{subject}_series{series}_events.csv\")\n    return train_set_signals, train_set_labels\n    \ndef load_all_test_data():\n    signals_dfs=[]\n    for i in range(1,13):\n        for j in range(9,11):            \n            signals = pd.read_csv(f\"../input/test/subj{i}_series{j}_data.csv\")\n            signals_dfs.append(signals)\n    return pd.concat(signals_dfs)       \n\ndef load_test_data(subject):\n    signals_dfs=[]    \n    for i in range(9,11):            \n        signals = pd.read_csv(f\"../input/test/subj{subject}_series{i}_data.csv\")\n        signals_dfs.append(signals)\n    return pd.concat(signals_dfs) \n\ndef prepare_labels(data):    \n    return data.drop(\"id\", axis=1)\n    \n# used\n# Standardize data by removing the mean and scaling to unit variance\ndef prepare_signals(data):\n    data = data.drop(\"id\", axis=1)\n    columns = data.columns    \n    scaler = StandardScaler() \n    data = np.asarray(data.astype(float))\n    data = scaler.fit_transform(data)\n    data = pd.DataFrame(data, columns=columns)   \n    return data\n\n#def convert_np_array_to_pandas(data, columns):\n#    data = pd.DataFrame(data, columns=columns)\n#    return data\n    \ndef load_train_data_prepared(subject, series):    \n    signals, labels = load_train_data(subject,series)    \n    return prepare_signals(signals), prepare_labels(labels)   \n\ndef split_data(data_to_split, percent):\n    percenttotrainon = percent\n    spliton = math.floor(float(len(data_to_split))*(percenttotrainon/float(100)))\n    return data_to_split.iloc[:spliton], data_to_split[spliton:]   \n\ndef load_mass_data_2D(fromsubj = 1, tosubj = 12, fromSerie = 1, toSerie = 8, look_back = 1, downsample = 1): \n    # default downsample = 1 means no downsampling\n    signals_dfs=[]\n    labels_dfs=[]\n    for j in range(fromsubj, tosubj+1): #we have 12 subjects\n        for i in range(fromSerie, toSerie+1): #we have 8 series availible for each subject\n            signals, labels = load_train_data_prepared(subject=j, series=i)\n            signals_dfs.append(signals)\n            labels_dfs.append(labels)        \n\n    signals_complete=pd.concat(signals_dfs)\n    labels_complete=pd.concat(labels_dfs)\n    \n    signalsDownsampled, labelsDownsampled = create_dataset(signals_complete.values[::downsample], labels_complete.values[::downsample], look_back)\n    return signalsDownsampled, labelsDownsampled\n\n#not done yet, todo or not todo?\ndef load_mass_data_2D_one_hot_encoding(fromsubj = 1, tosubj = 12, fromSerie = 1, toSerie = 8, look_back = 1, downsample = 1): \n    # default downsample = 1 means no downsampling\n    signals_dfs=[]\n    labels_dfs=[]\n    for j in range(fromsubj, tosubj+1): #we have 12 subjects\n        for i in range(fromSerie, toSerie+1): #we have 8 series availible for each subject\n            signals, labels = load_train_data_prepared(subject=j, series=i)\n            signals_dfs.append(signals)\n            labels_dfs.append(labels)        \n\n    signals_complete=pd.concat(signals_dfs)\n    labels_complete=pd.concat(labels_dfs)\n    \n    dataX, dataY = create_dataset(signals_complete.values[::downsample], labels_complete.values[::downsample], look_back)\n    \n    # map each single label to pair 0 => (1,0), 1 => (0, 1)\n    labels_one_hot_encode = np.zeros((len(dataY), 6, 2))\n    \n    for i in range(len(dataY)):\n        for j in range(6):\n            labels_one_hot_encode[i][j] = [1, 0] if (dataY[i][j] == 0) else [0, 1]\n    \n    return dataX, dataY\n\n\ndef load_mass_data_1D(fromsubj = 1, tosubj = 12, fromSerie = 1, toSerie = 8, downsample = 1): \n    # default downsample = 1 means no downsampling\n    signals_dfs=[]\n    labels_dfs=[]\n    for j in range(fromsubj, tosubj+1): #we have 12 subjects\n        for i in range(fromSerie, toSerie+1): #we have 8 series availible for each subject\n            signals, labels = load_train_data_prepared(subject=j, series=i)\n            signals_dfs.append(signals)\n            labels_dfs.append(labels)        \n\n    signals_complete=pd.concat(signals_dfs)\n    labels_complete=pd.concat(labels_dfs)\n    \n    dataX, dataY = signals_complete.values[::downsample], labels_complete.values[::downsample]\n    return dataX, dataY\n\ndef load_labels_header(): \n    signals, labels = load_train_data_prepared(1,1)\n    return labels.columns\n\n# used\n# Loads all test series for one subject\n# Returns test dataset, signal headers, ids\n# look back: x previous rows to be assign to every data row\n# serie: correct numbers for test-submit series are 9 and 10\ndef load_test_data_2D(subject, look_back, downsampling, serie):\n    if(serie < 9 or 10 < serie):\n        print(\" *** Test series for sumbmission are only 9 and 10 *** \")\n    signals_dfs=[]               \n    signals = pd.read_csv(f\"../input/test/subj{subject}_series{serie}_data.csv\")\n    signals_dfs.append(signals)\n    signals_data = pd.concat(signals_dfs)\n    ids = signals_data[\"id\"]\n    signals_data = prepare_signals(signals_data)\n    dataX = create_test_dataset(signals_data.values[::downsampling], look_back)\n    return dataX, signals_data.columns, ids\n\ndef create_dataset(dataset, labels, look_back=1):\n    dataX = []\n    dataY = labels[look_back:]\n    \n    for i in range(len(dataset)-look_back):\n        dataX.append(dataset[i:(i+look_back), ])\n    \n    return np.array(dataX), np.array(dataY)\n\n# used\n# To every data row assigns previous x rows (look back)\ndef create_test_dataset(dataset, look_back=1):\n    dataX = []\n    \n    for i in range(len(dataset)-look_back):\n        dataX.append(dataset[i:(i+look_back), ])\n    \n    return np.array(dataX)\n\ndef load_mass_data_subject(subject, fromseries, toseries): #we have 12 subjects\n    signals_dfs=[]\n    labels_dfs=[]\n    for i in range(fromseries,toseries+1): #we have 8 series availible for each subject        \n        signals, labels = load_train_data_prepared(subject, series=i)\n        signals_dfs.append(signals)\n        labels_dfs.append(labels)        \n\n    signals_complete=pd.concat(signals_dfs)\n    labels_complete=pd.concat(labels_dfs)\n    return signals_complete, labels_complete \n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"scaleOnes"},{"metadata":{"trusted":true},"cell_type":"code","source":"def scaleOnes(signals, labels, neighborhood_length):\n    appendSignals = []\n    appendLabels = []\n    sequence_of_ones_indexes = [] # sekvence jednicek co byly za sebou (jejich indexuu)\n    list_of_sequences_of_ones_indexes = [] # list takovych sekvencii\n    was_previous_label_one = False \n    # number of sequences of ones or zeroes\n    number_of_zeros = 0\n    number_of_ones = 0\n    \n    for j in range(0, len(signals)):\n        if(1 in labels[j]):\n            if(not was_previous_label_one):\n                if(len(sequence_of_ones_indexes) != 0):\n                    list_of_sequences_of_ones_indexes.append(sequence_of_ones_indexes)\n                sequence_of_ones_indexes = []\n                sequence_of_ones_indexes.append(j)\n            if(was_previous_label_one):\n                sequence_of_ones_indexes.append(j)\n            was_previous_label_one = True\n            number_of_ones = number_of_ones + 1\n        else:\n            was_previous_label_one = False\n            number_of_zeros = number_of_zeros + 1\n    list_of_sequences_of_ones_indexes.append(sequence_of_ones_indexes)\n    \n    scale_constant = 1\n    scale = int((number_of_zeros // number_of_ones) * scale_constant) + 1\n    print(\"scale: \", scale)\n    for s in range(0, scale):\n        for sequence in list_of_sequences_of_ones_indexes:\n            #pridavam okoli pred jednickama               \n            j = sequence[0]\n            k = sequence[-1]\n            for i in range(0, neighborhood_length):\n                appendSignals.append(signals[j - (neighborhood_length - i)])\n                appendLabels.append(labels[j - (neighborhood_length - i)])\n\n            for i in sequence:\n                appendSignals.append(signals[i])\n                appendLabels.append(labels[i])\n\n            #pridavam okoli za jednickama\n            if(len(signals) > k + neighborhood_length):\n                for i in range(0, neighborhood_length):\n                    appendSignals.append(signals[k + i])\n                    appendLabels.append(labels[k + i])\n\n    signalsToAppend = np.array(appendSignals)\n    labelsToAppend = np.array(appendLabels)\n\n    signals = np.concatenate([signals, signalsToAppend])\n    labels = np.concatenate([labels, labelsToAppend])\n    return signals, labels","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"validate and round"},{"metadata":{"trusted":true},"cell_type":"code","source":"def rd(x):\n    if(x > 0.58):\n        return 1\n    return 0\n\ndef rd_basic(x):\n    return round(x)\n\ndef validate(predictions, expected):\n    # whole vector predicted correctly \n    succesfullyPredictedVector = 0\n    #ones across all expected labels \n    totalOnes = 0\n    #zeros across all expected labels \n    totalZeros = 0\n    #ones correctly predicted across all labels\n    succesfullyPredictedOnes = 0\n    #ones correctly predicted across all labels\n    succesfullyPredictedZeros = 0\n    #ones expected, but not predicted - across all labels\n    notPredictedOnes = 0\n    totallyPredictedOnes = 1\n#    onesPredictedSucc = 0\n    \n    # counts labels from expected data\n    vectors_with_at_least_one = 0\n    # counts labels from expected data\n    multiple_ones_vectors = 0 \n\n    for i in range(0, len(expected)): \n        predicted_vector = list(map(rd, predictions[i]))\n        if(np.array_equal(predicted_vector,expected[i])):\n            succesfullyPredictedVector+=1\n\n        if 1 in expected[i]:\n            vectors_with_at_least_one += 1\n            ones_in_vector = 0\n            #print(\"expected\", expected[i], \"predicted\", predicted_vector)\n            \n            for j in range(0, len(expected[i])):\n                if(expected[i][j] == 1):\n                    totalOnes += 1\n                    ones_in_vector +=1\n                    if (predicted_vector[j] == expected[i][j]):\n                        succesfullyPredictedOnes +=1\n                    elif (expected[i][j] == 1):\n                        notPredictedOnes +=1\n                        \n                else:\n                    totalZeros += 1\n                    if (predicted_vector[j] == expected[i][j]):\n                        succesfullyPredictedZeros +=1\n                        \n            if(ones_in_vector > 1):\n                multiple_ones_vectors += 1\n\n        for k in range(0, len(predicted_vector)):\n            if (predicted_vector[k] == 1):\n                totallyPredictedOnes += 1  \n                \n    # Addition of +0.00001 to avoid division by zero\n    print(\"total acc on vectors: \", succesfullyPredictedVector/(len(predictions)+0.00001))\n    print(\"total acc on ones and zeros: \", (succesfullyPredictedOnes+succesfullyPredictedZeros)/(totalOnes+totalZeros+0.00001))\n    print(\"1s predicted correctly (out of total ones expected): \", succesfullyPredictedOnes, \"/\",totalOnes, \" = \", succesfullyPredictedOnes/(totalOnes+0.00001))\n#    print(\"ones predicted but not expected (out of total ones): \", totallyPredictedOnes - onesPredictedSucc, \"/\", totalOnes)\n#    print(\"1s predicted but not expected (in comparison with correctly predicted): \", totallyPredictedOnes - succesfullyPredictedOnes , \"/\", succesfullyPredictedOnes, \" = \", (totallyPredictedOnes - succesfullyPredictedOnes)/(succesfullyPredictedOnes+0.00001))\n    print(\"false positive ratio (false positives/actual negative events): \", totallyPredictedOnes - succesfullyPredictedOnes , \"/\", (len(expected)*6-totalOnes), \" = \", (totallyPredictedOnes - succesfullyPredictedOnes)/((len(expected)*6-totalOnes)+0.00001))\n#    false positive rate is calculated as the ratio between the number of negative events wrongly categorized as positive (false positives) and the total number of actual negative events \n    print(\"vectors with multiple 1s: \", multiple_ones_vectors)\n    print(\"total vectors with 1s: \", vectors_with_at_least_one)\n    print(\"total vectors: \", len(expected))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"validate_labels_separately"},{"metadata":{"trusted":true},"cell_type":"code","source":"def validate_labels_separately(predictions, expected):\n    # true positive = predicted 1 expected 1 \n    # true negative = predicted 0 expected 0 \n    # false positive = predicted 1 expected 0 \n    # false negative = predicted 0 expected 1 \n    \n    oneTruePositive = [0, 0, 0, 0, 0, 0]\n    zeroTrueNegative = [0, 0, 0, 0, 0, 0]\n    oneFalsePositive = [0, 0, 0, 0, 0, 0]\n    zeroFalseNegative = [0, 0, 0, 0, 0, 0]\n    onesExpected = [0, 0, 0, 0, 0, 0]\n    \n    for i in range(0, len(expected)): \n        predictionVec = np.array([rd(xi) for xi in predictions[i]])\n        for label in range(6):\n            if(predictionVec[label] == rd(expected[i, label])):\n                if(predictionVec[label] == 1):\n                    oneTruePositive[label] += 1\n                if(predictionVec[label] == 0):\n                    zeroTrueNegative[label] += 1\n            else:\n                if(predictionVec[label] == 1):\n                    oneFalsePositive[label] += 1\n                if(predictionVec[label] == 0):\n                    zeroFalseNegative[label] += 1\n            if(expected[i][label] == 1):\n                onesExpected[label] += 1\n            \n    # Addition of +0.00001 to avoid division by zero\n    for label in range(6):\n        print(\"             \")\n        print(\"label \", label)\n        print(\"total acc: \", (oneTruePositive[label] + zeroTrueNegative[label])/(len(predictions)))\n        print(\"true positive = predicted 1 expected 1: \", oneTruePositive[label], \" / \", (onesExpected[label]), \" = \", oneTruePositive[label]/(onesExpected[label]), \"(out of ones)\")\n        print(\"true negative = predicted 0 expected 0: \", zeroTrueNegative[label], \"/\", (len(predictions)-onesExpected[label]), \" = \", zeroTrueNegative[label]/(len(predictions)), \"(out of zeros)\")\n        print(\"false positive = predicted 1 expected 0: \", oneFalsePositive[label], \"/\", (len(predictions)), \" = \", oneFalsePositive[label]/(len(predictions)))\n        print(\"false negative = predicted 0 expected 1: \", zeroFalseNegative[label], \"/\", (len(predictions)), \" = \", zeroFalseNegative[label]/(len(predictions)))\n    print(\"             \")\n    print(\"Total summary\")\n    print(\"total acc: \", (np.sum(oneTruePositive) + np.sum(zeroTrueNegative))/(len(predictions)*6))\n    print(\"true positive = predicted 1 expected 1: \", np.sum(oneTruePositive)/(np.sum(onesExpected)))\n    print(\"true negative = predicted 0 expected 0: \", np.sum(zeroTrueNegative)/(len(predictions)*6-np.sum(onesExpected)))\n    print(\"false positive = predicted 1 expected 0: \", np.sum(oneFalsePositive)/(len(predictions)*6))\n    print(\"false negative = predicted 0 expected 1: \", np.sum(zeroFalseNegative)/(len(predictions)*6))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#https://sccn.ucsd.edu/wiki/Introduction_To_Modern_Brain-Computer_Interface_Design\n#https://hal.inria.fr/hal-01055103/file/lotte_EEGSignalProcessing.pdf","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":false},"cell_type":"markdown","source":"**CNN**"},{"metadata":{},"cell_type":"markdown","source":"**Predict**"},{"metadata":{"trusted":true},"cell_type":"code","source":"from __future__ import absolute_import, division, print_function, unicode_literals\nimport tensorflow as tf\nfrom tensorflow.keras import datasets, layers, models\n\ndef predict_single_label_mode(my_test_signals, models):\n    for i in range(len(models)):\n        result = models[i].predict(my_test_signals)\n        if(i == 0):\n            final_result = result\n        else:\n            final_result = np.append(final_result, result, axis = 0)\n    return final_result\n\n        \n# Returns np.array, the prediction on given signals\ndef predict_cnn(test_signals, models, mode):\n    nlenghtTest, nrowsTest, ncolsTest = test_signals.shape\n    test_signals_reshaped = test_signals.reshape(nlenghtTest, nrowsTest, ncolsTest, 1)\n    if(mode == Mode.single_label_mode):\n        for i in range(6):\n            result = models[i].predict(test_signals_reshaped)\n            if(i == 0):\n                final_result = result\n            else:\n                print(final_result.shape)\n                final_result = np.append(final_result, result, axis = 1)\n        return final_result\n    elif(mode == Mode.seven_labels):\n        for i in range(6):\n            result = models[i].predict(test_signals_reshaped)\n            result = np.delete(result, 0, axis = 1)\n            if(i == 0):\n                final_result = result\n            else:\n                final_result = np.append(final_result, result, axis = 1)\n        return final_result\n\n    else:\n        result = models.predict(test_signals_reshaped)\n        return result","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Highlight and Visualization**"},{"metadata":{"trusted":true},"cell_type":"code","source":"def highlight(indices,ax,color):\n    i=0\n    while i<len(indices):\n        ax.axvspan(indices[i]-0.5, indices[i]+0.5, facecolor=color, edgecolor='none', alpha=.4)\n        i+=1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport matplotlib.patches as mpatches\n\ndef vizualize_predictions(signals, predictions, expected, labelName, limit=2000): \n    #0-31\n    signalIndex = 10\n    \n    #TODO relevant only for multilabel predictions, else is always 0\n    labelIndex = 0\n                \n    signals = pd.DataFrame(data=np.array(signals))\n    axis = signals[signals.columns[signalIndex]].iloc[0:limit].plot(figsize=(20,4))  \n        \n    expected = pd.DataFrame(data = expected)    \n    predictions = pd.DataFrame(data = np.around(predictions))\n    \n    expectedCropped = expected.iloc[0:limit,]\n    predictionsCropped = predictions.iloc[0:limit,]\n    \n    highlight(expectedCropped[expectedCropped.iloc[:,labelIndex]==1].index, axis, \"red\")\n    highlight(predictionsCropped[predictionsCropped.iloc[:,labelIndex]==1].index, axis, \"black\")\n    \n    red_patch = mpatches.Patch(color='red', label='Expected event')\n    black_patch = mpatches.Patch(color='black', label='Predicted event')\n    plt.legend(handles=[red_patch, black_patch])\n\n    plt.title(labelName)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Upsampling result for submision**\n\n*upsample_result(..)*"},{"metadata":{"trusted":true},"cell_type":"code","source":"def upsample_result(results, multiplication_coefficient):\n    shape = results.shape\n    upsampled_result = np.zeros((shape[0] * multiplication_coefficient, shape[1]))\n    for i in range(len(results)):\n        for j in range(multiplication_coefficient):\n            upsampled_result[i * multiplication_coefficient + j] = results[i]\n    return upsampled_result","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Training**"},{"metadata":{"trusted":true},"cell_type":"code","source":"from __future__ import absolute_import, division, print_function, unicode_literals\nimport tensorflow as tf\nfrom tensorflow.keras import datasets, layers, models\nimport gc\nfrom enum import Enum\n\n# trains CNN with given train data\n# Returns void\n# trainon_signals: training data\n# trainon_labels: labels for training data\n# models: a list of CNN models (if single_label_mode is True), single CNN model (if single_label_mode is False)\n# epochs: number of training epochs for each model\n# single_label_mode: boolean decides if to train on each label separately or on all of them at once (as a single vector of length 6)\ndef train_cnn(trainon_signals, trainon_labels, models, epochs, mode, my_verbose):\n    data = trainon_signals\n    labels = trainon_labels\n    if(my_verbose):\n        verbose=1\n    else:\n        verbose=0\n    \n    nlenghtData, nrowsData, ncolsData = data.shape\n    data_single_label = data.reshape(nlenghtData, nrowsData, ncolsData, 1)\n    \n    if(mode == Mode.single_label_mode):\n        for i in range(6):\n            if(my_verbose):\n                print(\"Training model \", i)\n            labels_single_label = np.zeros((len(labels), 1))\n            for k in range(len(labels)):\n                labels_single_label[k][0] = labels[k][i]\n            models[i].fit(data_single_label, labels_single_label, epochs=epochs, batch_size=128, verbose=int(my_verbose))          \n    elif(mode == Mode.seven_labels):\n        for i in range(6):\n            if(my_verbose):\n                print(\"Training model \", i)\n            labels_single_label = np.zeros((len(labels), 2))\n            for k in range(len(labels)):\n                labels_single_label[k][0] = labels[k][i]\n            models[i].fit(data_single_label, labels_single_label, epochs=epochs, batch_size=128, verbose=int(my_verbose))\n    elif(mode == Mode.standard):\n        nlenghtData, nrowsData, ncolsData = data.shape\n        data = data.reshape(nlenghtData, nrowsData, ncolsData, 1)\n        # in case of single_label_mode == False, models is not a list but a single model\n        models.fit(data, labels, epochs=epochs, batch_size=128, verbose=int(my_verbose))\n        \n# used\n# popis....\n# look_back: history dimension of every row, number of previous rows appended before every data row\n# activation: function for every layer except last one\n# last_layer_activation\n# loss: function\n# output_length: size of the last layer\ndef cnn_model(look_back, activation, last_layer_activation, loss, output_length):\n    model = models.Sequential()\n    # 32 of eeg channels = input_shape == len(train_signals.columns)\n    channels = 32\n    # model.add(layers.Dropout(rate=0.1))       \n    model.add(layers.Conv2D(filters=192, kernel_size=(3,1), activation='relu', input_shape=(look_back, channels, 1)))\n    model.add(layers.MaxPooling2D((2,1)))\n    # filters=512\n    # model.add(layers.Conv2D(128, (3,1), activation='relu'))\n    # model.add(layers.MaxPooling2D((2,1)))\n\n    # model.add(layers.Dropout(rate=0.5))\n    model.add(layers.Flatten())\n    # model.add(layers.Dense(512, activation='relu'))\n    # https://developers.google.com/machine-learning/crash-course/multi-class-neural-networks/softmax\n    #model.add(layers.Dense(6, activation='relu'))\n    \n    # output_length == 6 if 6-labels, 1 if single labels\n    # last_layer_activation == softmax if 6-labels, sigmoid if single labels\n    model.add(layers.Dense(output_length, activation=last_layer_activation))\n    \n    # model.summary()\n    \n    # categorical cross entropy\n    # optimizer=tf.train.AdamOptimizer(learning_rate=0.001)\n    model.compile(optimizer='adam',\n                  loss=tf.losses.softmax_cross_entropy,\n                  #metrics=['cosine_similarity'])\n                  metrics=[\"accuracy\"])\n    # metrics=[\"categorical_accuracy\"])\n    return model\n\ndef printSubjectSerie(subject, serie):\n    if(True):\n        print(\"                                                                             \")\n        print(\"subject: \" + str(subject) + \"  |  serie: \" + str(serie))\n\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**cnn_submission_train_on_each_subject_separately**"},{"metadata":{"trusted":true},"cell_type":"code","source":"from __future__ import absolute_import, division, print_function, unicode_literals\nimport tensorflow as tf\nfrom tensorflow.keras import datasets, layers, models\nimport gc\nfrom enum import Enum\n    \n# scale_ones: multiplier for scaling of ones with neighborhood; no multiplication if False\ndef cnn_submission_train_on_each_subject_separately(trainEpochs, downsampling, look_back, activation, last_layer_activation, loss, scale_ones, mode, my_verbose, single_label_statistics, total_statistics):\n    results_ids=[]\n    results = np.zeros((1, 6))\n    # could be better bigger? this is just test value\n    # scaling_neighborhood_length = look_back + 2\n    scaling_neighborhood_length = 1\n    number_of_testing_serie = 8\n    start_subj = 1\n    # there is 13 subjects, default end_subj = 13\n    end_subj = 13\n    start_serie = 1\n    # training series: 1 to 7, testing serie: 8 \n    # for internal testing we use: last_serie = 9 - 1\n    last_serie = 9\n    test_signals = [None] * 2\n    test_header = [None] * 2\n    test_ids = [None] * 2\n    \n    submit = True\n    test_on_other_subjs = False\n    # we want only total_statistics, while testing on other subjects\n    single_label_statistics = not test_on_other_subjs and False\n\n\n    for i in range(start_subj, end_subj): # subjects\n        test_signals[0], test_header[0], test_ids[0] = load_test_data_2D(i, look_back, downsampling, 9)\n        test_signals[1], test_header[1], test_ids[1] = load_test_data_2D(i, look_back, downsampling, 10)\n        \n        # single_label_mode START ___________________________________________________________________________________________\n        if (mode == Mode.single_label_mode):\n            print(\"Mode.single_label_mode\")\n            models = list()\n            output_length = 1\n            for j in range(0, 6):\n                model = cnn_model(look_back, activation, last_layer_activation, loss, output_length)\n                models.append(model)\n            for serie in range(start_serie, last_serie): # all series for 1 subject\n                printSubjectSerie(i, serie)\n                train_signals, train_labels = load_mass_data_2D(i,i,serie,serie,look_back,downsampling)\n                if(scale_ones == True):\n                    train_signals, train_labels = scaleOnes(train_signals, train_labels, scaling_neighborhood_length)\n                train_cnn(train_signals, train_labels, models, trainEpochs, mode, my_verbose)\n                del train_signals\n                del train_labels\n                gc.collect()\n        # single_label_mode END ___________________________________________________________________________________________\n\n        # 6 labels standard START ----------------------------------------------------------------------------------------------\n        if(mode == Mode.standard):\n            print(Mode.standard)\n            output_length = 6\n            models = cnn_model(look_back, activation, last_layer_activation, loss, output_length)\n            for serie in range(start_serie, 9 - 1): # series for 1 subject; serie 8 is for testing\n                printSubjectSerie(i, serie)\n                train_signals, train_labels = load_mass_data_2D(i,i,serie,serie,look_back,downsampling)\n                if(scale_ones == True):\n                    train_signals, train_labels = scaleOnes(train_signals, train_labels, scaling_neighborhood_length)\n                train_cnn(train_signals, train_labels, models, trainEpochs, mode, my_verbose)            \n                del train_signals\n                del train_labels\n                gc.collect()\n        # 6 labels standard END  ----------------------------------------------------------------------------------------------\n        \n        \"\"\"\n        else:\n            print(\"no other then standard mode supported here\")\n            exit()\n        \"\"\"\n        \n        if(submit): #do/skip fitting\n            #fit START\n            for submission_serie_number in range(2):\n                print(submission_serie_number)\n                result = predict_cnn(test_signals[submission_serie_number], models, mode)\n                print(\"*** predicted ***\")\n                # padding\n                print(result.shape)\n                result = np.concatenate((np.zeros((look_back, 6)), result), axis=0)\n                print(result.shape)\n                # upsample\n                # multiplication_coefficient === downsampling\n                result = upsample_result(result, downsampling)\n                # append single result to all results\n                results = np.vstack((results, result))\n                results_ids.append(test_ids[submission_serie_number])\n            # fit END\n        \n        # My testing START\n        if(test_on_other_subjs):\n            # there is 13 subjects\n            test_on_subj_start = 1\n            test_on_subj_end = 13\n        else:\n            test_on_subj_start = i\n            test_on_subj_end = i+1\n            \n        for test_subj in range(test_on_subj_start, test_on_subj_end):\n            print(\"____________________________________\")\n            print(\"Test on subject \" + str(test_subj))\n            my_test_signals, my_test_labels = load_mass_data_2D(test_subj,test_subj,number_of_testing_serie,number_of_testing_serie,look_back,downsampling)\n\n            my_test_predictions = predict_cnn(my_test_signals, models, mode)\n            if(total_statistics):\n                validate(expected= my_test_labels, predictions= my_test_predictions)\n            if(single_label_statistics):\n                validate_labels_separately(expected= my_test_labels, predictions= my_test_predictions)\n\n        # my_test_signals_1D, my_test_labels = load_mass_data_1D(i,i,number_of_testing_serie,number_of_testing_serie,downsampling)\n        # vizualize predicstions\n        # for i in range(6):\n            # labelName= \"validation set: label \" + str(i)\n            # vizualize_predictions(signals = my_test_signals_1D, predictions = my_test_predictions[:, i], expected = my_test_labels[:, i], labelName=labelName, limit=2000)\n        # My testing END\n        \n    if(submit):\n        # upsample and submit START\n        # unset variables\n        # if this throws error: check if last_serie != start_serie\n        del models\n        del result\n        gc.collect()\n\n        submission_name = \"v-cnn-submission.csv\"\n        header = load_labels_header()\n        #print(header.values)\n        #print(results)\n        #print(results_ids)\n\n        # fix uneven data len START\n        # delete first default-dummy line that was added at creation of results\n        results = np.delete(results, 0, axis=0)\n        if(False): # debug print\n            print(\"before submission\")\n            # print(results_ids)\n            # print(\"______________________________\")\n            # print(type(results_ids))\n            # print(\"______________________________\")\n            print(\"len(results_ids[0]) \" + str(len(results_ids[0])))\n            print(\"len(results_ids[1]) \" + str(len(results_ids[1])))\n            print(\"______________________________\")\n            print(\"results.shape[0] \" + str(results.shape[0]))\n            print(\"______________________________\")\n        diff = results.shape[0]\n        for ids_column in range (len(results_ids)):\n            diff -= len(results_ids[ids_column])\n        print(\"______________________________\")\n        print(\"difference in expected submission len and my: \" + str(diff))\n        if(True and diff > 0):\n            for delete_index in range(diff):\n                results = np.delete(results, len(results)-1, axis=0)\n        # fix uneven data len END\n        submission = pd.DataFrame(columns=header.values, data=results, index=np.concatenate(results_ids))\n\n        #______________________________________________________TODO don't round the submission?\n        submission.to_csv(submission_name,index_label=\"id\",float_format='%.3f')\n        # upsample and submit END\n    print(\"---   Done!   ---\")\n\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**cnn_submission_train_on_all_subjects**"},{"metadata":{"trusted":true},"cell_type":"code","source":"from __future__ import absolute_import, division, print_function, unicode_literals\nimport tensorflow as tf\nfrom tensorflow.keras import datasets, layers, models\nimport gc\nfrom enum import Enum\n    \n# scale_ones: multiplier for scaling of ones with neighborhood; no multiplication if False\ndef cnn_submission_train_on_all_subjects(trainEpochs, downsampling, look_back, activation, last_layer_activation, loss, scale_ones, mode, my_verbose, single_label_statistics, total_statistics):\n    results_ids=[]\n    results = np.zeros((1, 6))\n    scaling_neighborhood_length = 1\n    number_of_testing_serie = 8\n    start_subj = 1\n    # there is 13 subjects, default end_subj = 13\n    end_subj = 13\n    start_serie = 1\n    # training series: 1 to 7, testing serie: 8 \n    # last_serie = 9 - 1\n    last_serie = 8\n    test_signals = [None] * 2\n    test_header = [None] * 2\n    test_ids = [None] * 2\n    \n    submit = True\n    \n    if(mode == Mode.standard):\n        print(Mode.standard)\n        output_length = 6\n        models = cnn_model(look_back, activation, last_layer_activation, loss, output_length)\n    else:\n        print(\"invalid mode; only valid mode is \" + Mode.standard)\n        exit()\n    \n    for i in range(start_subj, end_subj): # subjects\n        test_signals[0], test_header[0], test_ids[0] = load_test_data_2D(i, look_back, downsampling, 9)\n        test_signals[1], test_header[1], test_ids[1] = load_test_data_2D(i, look_back, downsampling, 10)\n        # 6 labels standard START ----------------------------------------------------------------------------------------------\n        for serie in range(start_serie, last_serie): # series for 1 subject; serie 8 is for testing\n            printSubjectSerie(i, serie)\n            train_signals, train_labels = load_mass_data_2D(i,i,serie,serie,look_back,downsampling)\n            if(scale_ones == True):\n                train_signals, train_labels = scaleOnes(train_signals, train_labels, scaling_neighborhood_length)\n            train_cnn(train_signals, train_labels, models, trainEpochs, mode, my_verbose)            \n            del train_signals\n            del train_labels\n            gc.collect()\n        # 6 labels standard END  ----------------------------------------------------------------------------------------------\n\n    if(submit):\n        # fit START\n        for submission_serie_number in range(2):\n            print(\"subject \" + str(i) + \" : serie \" + str(submission_serie_number))\n            result = predict_cnn(test_signals[submission_serie_number], models, mode)\n            print(\"*** predicted ***\")\n            # padding\n            result = np.concatenate((np.zeros((look_back, 6)), result), axis=0)\n            # upsample\n            # multiplication_coefficient === downsampling\n            result = upsample_result(result, downsampling)\n            # append single result to all results\n            results = np.vstack((results, result))\n            results_ids.append(test_ids[submission_serie_number])\n        # fit END\n\n    # My testing START\n    my_test_signals, my_test_labels = load_mass_data_2D(start_subj,end_subj-1,number_of_testing_serie,number_of_testing_serie,look_back,downsampling)\n\n    my_test_predictions = predict_cnn(my_test_signals, models, mode)\n    if(total_statistics):\n        validate(expected= my_test_labels, predictions= my_test_predictions)\n    if(single_label_statistics):\n        validate_labels_separately(expected= my_test_labels, predictions= my_test_predictions)\n\n#    my_test_signals_1D, my_test_labels = load_mass_data_1D(i,i,number_of_testing_serie,number_of_testing_serie,downsampling)\n    # My testing END\n    if(submit):\n        # upsample and submit START\n        # unset variables\n        del result\n        gc.collect()\n\n        submission_name = \"v-cnn-submission.csv\"\n        header = load_labels_header()\n\n        # fix uneven data len START\n        # delete first default-dummy line that was added at creation of results\n        results = np.delete(results, 0, axis=0)\n        if(False): # debug print\n            print(\"before submission\")\n            # print(results_ids)\n            # print(\"______________________________\")\n            # print(type(results_ids))\n            # print(\"______________________________\")\n            print(\"len(results_ids[0]) \" + str(len(results_ids[0])))\n            print(\"len(results_ids[1]) \" + str(len(results_ids[1])))\n            print(\"______________________________\")\n            print(\"results.shape[0] \" + str(results.shape[0]))\n            print(\"______________________________\")\n        diff = results.shape[0]\n        for ids_column in range (len(results_ids)):\n            diff -= len(results_ids[ids_column])\n        print(\"______________________________\")\n        print(\"difference in expected submission len and my: \" + str(diff))\n        if(True and diff > 0):\n            for delete_index in range(diff):\n                results = np.delete(results, len(results)-1, axis=0)\n        # fix uneven data len END\n        submission = pd.DataFrame(columns=header.values, data=results, index=np.concatenate(results_ids))\n\n        #______________________________________________________TODO don't round the submission?\n        submission.to_csv(submission_name,index_label=\"id\",float_format='%.3f')\n        # upsample and submit END\n    print(\"---   Done!   ---\")\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from __future__ import absolute_import, division, print_function, unicode_literals\nimport tensorflow as tf\nfrom tensorflow.keras import datasets, layers, models\nimport gc\nfrom enum import Enum\n\nclass Mode(Enum):\n    # six labels standard\n    standard = 1\n    # trains 6 separate models, each for one single label\n    single_label_mode = 2\n    # trains 6 models, f.e. for model/label-3 transforms labels as  001000 -> 10, 000001 -> 01, 000000 -> 01\n    seven_labels = 4\n    \nclass TrainOn(Enum):\n    #default\n    each_subject_separately = 1\n    all_subjects = 2\n\nmode = Mode.single_label_mode\ntrain_on = TrainOn.each_subject_separately\ntrainEpochs = 1\n# downsampling = 1 means no downsampling\ndownsampling = 20\nlook_back = 10\nactivation = tf.keras.activations.relu\n#last_layer_activation = tf.keras.activations.sigmoid\n#loss = tf.losses.mean_squared_error\nif(mode == Mode.single_label_mode):\n    last_layer_activation = tf.keras.activations.sigmoid\n    loss = tf.losses.sigmoid_cross_entropy\nelse:\n    last_layer_activation = tf.keras.activations.softmax\n    loss = tf.losses.softmax_cross_entropy\n# scale_ones: aktualne skaluju jednicky jedna ku jedne s nulama\n# boolean on/off\nscale_ones = False \nmy_verbose = False\nsingle_label_statistics = True\ntotal_statistics = True\n\nif(train_on == TrainOn.each_subject_separately):\n    cnn_submission_train_on_each_subject_separately(trainEpochs, downsampling, look_back, activation, last_layer_activation, loss, scale_ones, mode, my_verbose, single_label_statistics, total_statistics)\n\nif(train_on == TrainOn.all_subjects):\n    cnn_submission_train_on_all_subjects(trainEpochs, downsampling, look_back, activation, last_layer_activation, loss, scale_ones, mode, my_verbose, single_label_statistics, total_statistics)\n\n#model = cnn_model()\n#model.summary()","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.6.6"}},"nbformat":4,"nbformat_minor":1}