{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":59093,"databundleVersionId":7469972,"sourceType":"competition"}],"dockerImageVersionId":31011,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:24:52.777514Z","iopub.status.idle":"2025-04-23T10:24:52.777797Z","shell.execute_reply.started":"2025-04-23T10:24:52.777638Z","shell.execute_reply":"2025-04-23T10:24:52.777650Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nfrom matplotlib import pyplot as plt\nimport cv2\nimport pandas as pd","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:24:55.291029Z","iopub.execute_input":"2025-04-23T10:24:55.291300Z","iopub.status.idle":"2025-04-23T10:24:55.564438Z","shell.execute_reply.started":"2025-04-23T10:24:55.291279Z","shell.execute_reply":"2025-04-23T10:24:55.563588Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def spectrogram_from_eeg(parquet_path, display=False):\n    \n    # LOAD MIDDLE 50 SECONDS OF EEG SERIES\n    eeg = pd.read_parquet(parquet_path)\n    middle = (len(eeg)-10_000)//2\n    eeg = eeg.iloc[middle:middle+10_000]\n    \n    # VARIABLE TO HOLD SPECTROGRAM\n    img = np.zeros((128,256,4),dtype='float32')\n    \n    if display: plt.figure(figsize=(10,7))\n    signals = []\n    for k in range(4):\n        COLS = FEATS[k]\n        \n        for kk in range(4):\n        \n            # COMPUTE PAIR DIFFERENCES\n            x = eeg[COLS[kk]].values - eeg[COLS[kk+1]].values\n\n            # FILL NANS\n            m = np.nanmean(x)\n            if np.isnan(x).mean()<1: x = np.nan_to_num(x,nan=m)\n            else: x[:] = 0\n\n            # DENOISE\n            if USE_WAVELET:\n                x = denoise(x, wavelet=USE_WAVELET)\n            signals.append(x)\n\n            # RAW SPECTROGRAM\n            mel_spec = librosa.feature.melspectrogram(y=x, sr=200, hop_length=len(x)//256, \n                  n_fft=1024, n_mels=128, fmin=0, fmax=20, win_length=128)\n\n            # LOG TRANSFORM\n            width = (mel_spec.shape[1]//32)*32\n            mel_spec_db = librosa.power_to_db(mel_spec, ref=np.max).astype(np.float32)[:,:width]\n\n            # STANDARDIZE TO -1 TO 1\n            mel_spec_db = (mel_spec_db+40)/40 \n            img[:,:,k] += mel_spec_db\n                \n        # AVERAGE THE 4 MONTAGE DIFFERENCES\n        img[:,:,k] /= 4.0\n        \n        if display:\n            plt.subplot(2,2,k+1)\n            plt.imshow(img[:,:,k],aspect='auto',origin='lower')\n            plt.title(f'EEG {eeg_id} - Spectrogram {NAMES[k]}')\n            \n    if display: \n        plt.show()\n        plt.figure(figsize=(10,5))\n        offset = 0\n        for k in range(4):\n            if k>0: offset -= signals[3-k].min()\n            plt.plot(range(10_000),signals[k]+offset,label=NAMES[3-k])\n            offset += signals[3-k].max()\n        plt.legend()\n        plt.title(f'EEG {eeg_id} Signals')\n        plt.show()\n        print(); print('#'*25); print()\n        \n    return img","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:24:52.781054Z","iopub.status.idle":"2025-04-23T10:24:52.781328Z","shell.execute_reply.started":"2025-04-23T10:24:52.781195Z","shell.execute_reply":"2025-04-23T10:24:52.781207Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"BASE_PATH = \"/kaggle/input/hms-harmful-brain-activity-classification\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:24:52.782562Z","iopub.status.idle":"2025-04-23T10:24:52.783077Z","shell.execute_reply.started":"2025-04-23T10:24:52.782928Z","shell.execute_reply":"2025-04-23T10:24:52.782944Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"os.listdir(BASE_PATH)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:24:52.784282Z","iopub.status.idle":"2025-04-23T10:24:52.784535Z","shell.execute_reply.started":"2025-04-23T10:24:52.784403Z","shell.execute_reply":"2025-04-23T10:24:52.784414Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"NAMES = ['LL','LP','RP','RR']\n\nFEATS = [['Fp1','F7','T3','T5','O1'],\n         ['Fp1','F3','C3','P3','O1'],\n         ['Fp2','F8','T4','T6','O2'],\n         ['Fp2','F4','C4','P4','O2']]\n\nimport pywt\nprint(\"The wavelet functions we can use:\")\nprint(pywt.wavelist())\n\nUSE_WAVELET = None #or \"db8\" or anything below\n\n# DENOISE FUNCTION\ndef maddest(d, axis=None):\n    return np.mean(np.absolute(d - np.mean(d, axis)), axis)\n\ndef denoise(x, wavelet='haar', level=1):    \n    coeff = pywt.wavedec(x, wavelet, mode=\"per\")\n    sigma = (1/0.6745) * maddest(coeff[-level])\n\n    uthresh = sigma * np.sqrt(2*np.log(len(x)))\n    coeff[1:] = (pywt.threshold(i, value=uthresh, mode='hard') for i in coeff[1:])\n\n    ret=pywt.waverec(coeff, wavelet, mode='per')\n    \n    return ret\n\nimport librosa","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:25:05.114259Z","iopub.execute_input":"2025-04-23T10:25:05.115081Z","iopub.status.idle":"2025-04-23T10:25:05.438470Z","shell.execute_reply.started":"2025-04-23T10:25:05.115048Z","shell.execute_reply":"2025-04-23T10:25:05.437722Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data = spectrogram_from_eeg(BASE_PATH+\"/train_eegs/\"+os.listdir(BASE_PATH+\"/train_eegs/\")[0])\ndata.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:25:40.568282Z","iopub.execute_input":"2025-04-23T10:25:40.568958Z","iopub.status.idle":"2025-04-23T10:25:54.488495Z","shell.execute_reply.started":"2025-04-23T10:25:40.568931Z","shell.execute_reply":"2025-04-23T10:25:54.487785Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def data_to_2d(data):\n    arr1 = data[:, :, 0]\n    arr2 = data[:, :, 0]\n    arr3 = data[:, :, 0]\n    arr4 = data[:, :, 0]\n        # İlk iki array'i yatay olarak birleştir\n    top_row = np.hstack((arr1, arr2))\n    \n    # Sonraki iki array'i yatay olarak birleştir\n    bottom_row = np.hstack((arr3, arr4))\n    \n    # İki satırı dikey olarak birleştir\n    result = np.vstack((top_row, bottom_row))\n    \n    # Sonuç boyutunu kontrol et\n    # print(result.shape)  # (256, 512)\n    return result","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:26:10.971464Z","iopub.execute_input":"2025-04-23T10:26:10.971802Z","iopub.status.idle":"2025-04-23T10:26:10.977049Z","shell.execute_reply.started":"2025-04-23T10:26:10.971732Z","shell.execute_reply":"2025-04-23T10:26:10.976299Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def np_array_from_eeg_id(eeg_id):\n    data = spectrogram_from_eeg(BASE_PATH+\"/train_eegs/\"+str(eeg_id)+\".parquet\")\n    return data_to_2d(data)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:25:56.520108Z","iopub.execute_input":"2025-04-23T10:25:56.520500Z","iopub.status.idle":"2025-04-23T10:25:56.524046Z","shell.execute_reply.started":"2025-04-23T10:25:56.520477Z","shell.execute_reply":"2025-04-23T10:25:56.523312Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"np_array_from_eeg_id(1628180742).shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:26:13.432237Z","iopub.execute_input":"2025-04-23T10:26:13.432496Z","iopub.status.idle":"2025-04-23T10:26:13.555083Z","shell.execute_reply.started":"2025-04-23T10:26:13.432478Z","shell.execute_reply":"2025-04-23T10:26:13.554262Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def visualize_eeg(eeg_id):\n    \n    plt.imshow(np_array_from_eeg_id(eeg_id), cmap='viridis', aspect='auto')  # İridis yerine Inferno paleti\n    plt.colorbar()  # Renk barı ekle\n    plt.title(\"Visualized Result Array with Iridis-like Palette\")\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:26:19.615889Z","iopub.execute_input":"2025-04-23T10:26:19.616421Z","iopub.status.idle":"2025-04-23T10:26:19.620858Z","shell.execute_reply.started":"2025-04-23T10:26:19.616390Z","shell.execute_reply":"2025-04-23T10:26:19.620012Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data_to_2d(data)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:36:20.477202Z","iopub.execute_input":"2025-04-23T10:36:20.477940Z","iopub.status.idle":"2025-04-23T10:36:20.483407Z","shell.execute_reply.started":"2025-04-23T10:36:20.477914Z","shell.execute_reply":"2025-04-23T10:36:20.482586Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"visualize_eeg(1628180742)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:26:30.238254Z","iopub.execute_input":"2025-04-23T10:26:30.238587Z","iopub.status.idle":"2025-04-23T10:26:30.727817Z","shell.execute_reply.started":"2025-04-23T10:26:30.238560Z","shell.execute_reply":"2025-04-23T10:26:30.727021Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def save_spectrogram_as_img(path):\n    #data =np.load(\"EEG_Spectrograms/1000913311.npy\")\n    data =np.load(path)\n    # Concatenate the 4 pictures in a 2x2 grid\n    concatenated_image = np.vstack((np.hstack((data[:, :, 0], data[:, :, 1])), \n                                    np.hstack((data[:, :, 2], data[:, :, 3]))))\n\n    # # Display the concatenated image\n    # plt.imshow(concatenated_image, cmap='gray')\n    # plt.axis('off')\n    # plt.show()\n\n    # Save the concatenated image with the same name as the numpy file\n    output_filename = path.split('/')[1].split('.')[0]\n    output_filename = \"images/\"+output_filename+\".jpg\"\n    cv2.imwrite(output_filename, concatenated_image * 255)  # Scale the image to 0-255 before saving","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:26:52.787086Z","iopub.execute_input":"2025-04-23T10:26:52.787800Z","iopub.status.idle":"2025-04-23T10:26:52.792345Z","shell.execute_reply.started":"2025-04-23T10:26:52.787768Z","shell.execute_reply":"2025-04-23T10:26:52.791645Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def get_img(id):\n    data = spectrogram_from_eeg(BASE_PATH + \"/train_eegs/\" +  f\"{id}.parquet\")\n    \n    # Concatenate the 4 pictures in a 2x2 grid\n    concatenated_image = np.vstack((\n        np.hstack((data[:, :, 0], data[:, :, 1])),\n        np.hstack((data[:, :, 2], data[:, :, 3]))\n    ))\n    \n    # Normalize to 0-255 and convert to uint8\n    normalized = cv2.normalize(concatenated_image, None, 0, 255, cv2.NORM_MINMAX)\n    normalized_uint8 = normalized.astype(np.uint8)\n    \n    # Apply viridis colormap\n    colored_img = cv2.applyColorMap(normalized_uint8, cv2.COLORMAP_VIRIDIS)\n    \n    return colored_img","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:46:52.298328Z","iopub.execute_input":"2025-04-23T10:46:52.299079Z","iopub.status.idle":"2025-04-23T10:46:52.303561Z","shell.execute_reply.started":"2025-04-23T10:46:52.299054Z","shell.execute_reply":"2025-04-23T10:46:52.302799Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"get_img(1628180742)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:48:17.976307Z","iopub.execute_input":"2025-04-23T10:48:17.976965Z","iopub.status.idle":"2025-04-23T10:48:18.102695Z","shell.execute_reply.started":"2025-04-23T10:48:17.976938Z","shell.execute_reply":"2025-04-23T10:48:18.101896Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"csv = pd.read_csv(BASE_PATH+\"/train.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:27:22.416875Z","iopub.execute_input":"2025-04-23T10:27:22.417533Z","iopub.status.idle":"2025-04-23T10:27:22.627284Z","shell.execute_reply.started":"2025-04-23T10:27:22.417510Z","shell.execute_reply":"2025-04-23T10:27:22.626674Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"unique_eeg_ids_df = csv.drop_duplicates(subset='eeg_id')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:27:26.783592Z","iopub.execute_input":"2025-04-23T10:27:26.784152Z","iopub.status.idle":"2025-04-23T10:27:26.796521Z","shell.execute_reply.started":"2025-04-23T10:27:26.784130Z","shell.execute_reply":"2025-04-23T10:27:26.795888Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"unique_eeg_ids_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:27:31.792202Z","iopub.execute_input":"2025-04-23T10:27:31.792895Z","iopub.status.idle":"2025-04-23T10:27:31.818063Z","shell.execute_reply.started":"2025-04-23T10:27:31.792870Z","shell.execute_reply":"2025-04-23T10:27:31.817464Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"unique_eeg_ids_df = unique_eeg_ids_df[['eeg_id', 'expert_consensus']]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:27:42.405390Z","iopub.execute_input":"2025-04-23T10:27:42.405694Z","iopub.status.idle":"2025-04-23T10:27:42.413729Z","shell.execute_reply.started":"2025-04-23T10:27:42.405673Z","shell.execute_reply":"2025-04-23T10:27:42.412784Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"unique_values = unique_eeg_ids_df['expert_consensus'].unique()\nprint(unique_values)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:27:46.695391Z","iopub.execute_input":"2025-04-23T10:27:46.695657Z","iopub.status.idle":"2025-04-23T10:27:46.702875Z","shell.execute_reply.started":"2025-04-23T10:27:46.695639Z","shell.execute_reply":"2025-04-23T10:27:46.702173Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"labels = {0:\"Seizure\",1:\"GPD\",2:\"LRDA\",3:\"LPD\",4:\"GRDA\",5:\"Other\"}","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:27:51.121706Z","iopub.execute_input":"2025-04-23T10:27:51.122003Z","iopub.status.idle":"2025-04-23T10:27:51.126015Z","shell.execute_reply.started":"2025-04-23T10:27:51.121983Z","shell.execute_reply":"2025-04-23T10:27:51.125280Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.applications import ResNet50\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, GlobalAveragePooling2D\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras import layers","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:27:57.104895Z","iopub.execute_input":"2025-04-23T10:27:57.105169Z","iopub.status.idle":"2025-04-23T10:28:10.211395Z","shell.execute_reply.started":"2025-04-23T10:27:57.105149Z","shell.execute_reply":"2025-04-23T10:28:10.210773Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.applications import DenseNet121\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import Dense, Dropout, GlobalAveragePooling2D, Input, Conv2D, BatchNormalization, Activation, Flatten, SpatialDropout2D\nfrom tensorflow.keras.optimizers import Adam\n\n\n# DenseNet121 modelini yükle\nbase_model = DenseNet121(weights='imagenet', include_top=False, input_tensor=Input(shape=(256, 512, 3)))\n\n# Base model'in ağırlıklarını dondur (transfer learning için)\nbase_model.trainable = False\n\n# Yeni katmanları ekle\nx = base_model.output\n\n# Ekstra 2D konvolüsyon katmanları ekleyelim\nx = Conv2D(256, (3, 3), padding='same')(x)\nx = BatchNormalization()(x)\nx = Activation('relu')(x)\nx = SpatialDropout2D(0.3)(x)\n\nx = Conv2D(128, (3, 3), padding='same')(x)\nx = BatchNormalization()(x)\nx = Activation('relu')(x)\n\n# Küresel ortalama havuzlama\nx = GlobalAveragePooling2D()(x)\n\n# Tam bağlı katmanlar\ndense_units = [512, 256]  # Daha esnek yapı\nfor units in dense_units:\n    x = Dense(units, activation='relu')(x)\n    x = Dropout(0.5)(x)\n\n# Çıkış katmanı (6 sınıf için softmax)\noutput = Dense(6, activation='softmax')(x)\n\n# Modeli oluştur\nmodel = Model(inputs=base_model.input, outputs=output)\n\n# Optimize edici ayarla (öğrenme oranını artırdık)\noptimizer = Adam(learning_rate=0.001)\n\n# Modeli derle\nmodel.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])\n\n# Model özetini yazdır\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:29:21.397073Z","iopub.execute_input":"2025-04-23T10:29:21.397796Z","iopub.status.idle":"2025-04-23T10:29:24.564889Z","shell.execute_reply.started":"2025-04-23T10:29:21.397773Z","shell.execute_reply":"2025-04-23T10:29:24.564220Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def convert_to_rgb(image):\n    # Tek kanal (grayscale) resmi 3 kanallı RGB'ye dönüştürme\n    return tf.image.grayscale_to_rgb(image)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:30:02.317844Z","iopub.execute_input":"2025-04-23T10:30:02.318121Z","iopub.status.idle":"2025-04-23T10:30:02.321916Z","shell.execute_reply.started":"2025-04-23T10:30:02.318102Z","shell.execute_reply":"2025-04-23T10:30:02.321155Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Invert the labels dictionary to map string labels to their numeric values\nlabel_map = {v: k for k, v in labels.items()}\n\n# Replace the string values in the expert_consensus column with their numeric values\nunique_eeg_ids_df['expert_consensus'] = unique_eeg_ids_df['expert_consensus'].map(label_map)\nunique_eeg_ids_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:30:14.980139Z","iopub.execute_input":"2025-04-23T10:30:14.980707Z","iopub.status.idle":"2025-04-23T10:30:14.992778Z","shell.execute_reply.started":"2025-04-23T10:30:14.980686Z","shell.execute_reply":"2025-04-23T10:30:14.991935Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:30:22.200251Z","iopub.execute_input":"2025-04-23T10:30:22.200998Z","iopub.status.idle":"2025-04-23T10:30:22.330515Z","shell.execute_reply.started":"2025-04-23T10:30:22.200975Z","shell.execute_reply":"2025-04-23T10:30:22.329947Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Önce eğitim ve geri kalan verileri (validasyon + test) ayıralım\ntrain_df, rest_df = train_test_split(unique_eeg_ids_df, test_size=0.3, random_state=42) # %30 test + validasyon\n\n# Geri kalan verileri validasyon ve test olarak ayıralım\nval_df, test_df = train_test_split(rest_df, test_size=1/3, random_state=42) # %30'un 1/3'ü test, 2/3'ü validasyon","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:30:26.738913Z","iopub.execute_input":"2025-04-23T10:30:26.739174Z","iopub.status.idle":"2025-04-23T10:30:26.747949Z","shell.execute_reply.started":"2025-04-23T10:30:26.739156Z","shell.execute_reply":"2025-04-23T10:30:26.747130Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import keras.utils\n\nclass EEGDataGenerator(keras.utils.Sequence):\n    \"\"\"\n    Data generator for EEG spectrograms for Keras.\n    Converts EEG IDs to spectrograms using the provided function and returns batches.\n    \"\"\"\n    \n    def __init__(self, dataframe, spectrogram_function, batch_size=32, \n                 shuffle=True, seed=None, is_test=False):\n        \"\"\"\n        Initialize the data generator.\n        \n        Args:\n            dataframe (pd.DataFrame): DataFrame containing 'eeg_id' and 'expert_consensus' columns\n            spectrogram_function (callable): Function that converts eeg_id to spectrogram array\n            batch_size (int): Size of batches to generate\n            shuffle (bool): Whether to shuffle the data after each epoch\n            seed (int): Random seed for reproducibility\n            is_test (bool): If True, don't return labels (for prediction)\n        \"\"\"\n        self.df = dataframe.copy()\n        self.batch_size = batch_size\n        self.spectrogram_function = spectrogram_function\n        self.shuffle = shuffle\n        self.seed = seed\n        self.is_test = is_test\n        \n        # Generate indices\n        self.indices = np.arange(len(self.df))\n        \n        # Class mapping if needed\n        self.classes = sorted(self.df['expert_consensus'].unique())\n        self.class_indices = {cls: i for i, cls in enumerate(self.classes)}\n        \n        # Initial shuffle\n        if self.shuffle:\n            np.random.seed(self.seed)\n            np.random.shuffle(self.indices)\n    \n    def __len__(self):\n        \"\"\"Denotes the number of batches per epoch\"\"\"\n        return int(np.ceil(len(self.df) / self.batch_size))\n    \n    def __getitem__(self, index):\n        \"\"\"Generate one batch of data\"\"\"\n        # Generate indices of the batch\n        batch_indices = self.indices[index * self.batch_size:(index + 1) * self.batch_size]\n        \n        # Get batch data\n        batch_df = self.df.iloc[batch_indices]\n        \n        # Generate spectrograms\n        batch_x = np.array([\n            self.spectrogram_function(eeg_id) \n            for eeg_id in batch_df['eeg_id']\n        ])\n        \n        if self.is_test:\n            return batch_x\n        \n        # Generate labels (one-hot encoded)\n        batch_y = np.array([\n            self.class_indices[label] \n            for label in batch_df['expert_consensus']\n        ])\n        \n        return batch_x, tf.keras.utils.to_categorical(batch_y, num_classes=len(self.classes))\n    \n    def on_epoch_end(self):\n        \"\"\"Updates indices after each epoch\"\"\"\n        if self.shuffle:\n            np.random.seed(self.seed)\n            np.random.shuffle(self.indices)\n\n\ndef create_eeg_generators(train_df, val_df, test_df, spectrogram_from_eeg, \n                          batch_size=32, seed=42):\n    \"\"\"\n    Create train, validation, and test generators for EEG data.\n    \n    Args:\n        train_df (pd.DataFrame): Training data with 'eeg_id' and 'expert_consensus' columns\n        val_df (pd.DataFrame): Validation data with 'eeg_id' and 'expert_consensus' columns\n        test_df (pd.DataFrame): Test data with 'eeg_id' column\n        spectrogram_from_eeg (callable): Function to convert eeg_id to spectrogram\n        batch_size (int): Batch size for generators\n        seed (int): Random seed for reproducibility\n        \n    Returns:\n        tuple: (train_generator, val_generator, test_generator)\n    \"\"\"\n    # Create generators\n    train_generator = EEGDataGenerator(\n        dataframe=train_df,\n        spectrogram_function=get_img,\n        batch_size=batch_size,\n        shuffle=True,\n        seed=seed,\n        is_test=False\n    )\n    \n    val_generator = EEGDataGenerator(\n        dataframe=val_df,\n        spectrogram_function=get_img,\n        batch_size=batch_size,\n        shuffle=False,\n        seed=seed,\n        is_test=False\n    )\n    \n    test_generator = EEGDataGenerator(\n        dataframe=test_df,\n        spectrogram_function=get_img,\n        batch_size=batch_size,\n        shuffle=False,\n        seed=seed,\n        is_test=True\n    )\n    \n    return train_generator, val_generator, test_generator","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:50:35.301663Z","iopub.execute_input":"2025-04-23T10:50:35.302267Z","iopub.status.idle":"2025-04-23T10:50:35.315394Z","shell.execute_reply.started":"2025-04-23T10:50:35.302242Z","shell.execute_reply":"2025-04-23T10:50:35.314685Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_generator, val_generator, test_generator = create_eeg_generators(train_df, val_df, test_df, get_img, \n                          batch_size=32, seed=42)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:50:38.843471Z","iopub.execute_input":"2025-04-23T10:50:38.844088Z","iopub.status.idle":"2025-04-23T10:50:38.850470Z","shell.execute_reply.started":"2025-04-23T10:50:38.844064Z","shell.execute_reply":"2025-04-23T10:50:38.849967Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.optimizers import Adam\n\n# Öğrenme oranını artır\nlearning_rate = 0.001  # Varsayılan 0.001, bunu artırdık\n\noptimizer = Adam(learning_rate=learning_rate)\n\n# Modeli yeniden derle\nmodel.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:50:40.760653Z","iopub.execute_input":"2025-04-23T10:50:40.760908Z","iopub.status.idle":"2025-04-23T10:50:40.770829Z","shell.execute_reply.started":"2025-04-23T10:50:40.760891Z","shell.execute_reply":"2025-04-23T10:50:40.770253Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nprint(\"GPU Available:\", tf.config.list_physical_devices('GPU'))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:50:56.366494Z","iopub.execute_input":"2025-04-23T10:50:56.366802Z","iopub.status.idle":"2025-04-23T10:50:56.370906Z","shell.execute_reply.started":"2025-04-23T10:50:56.366778Z","shell.execute_reply":"2025-04-23T10:50:56.370248Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Train the model\nhistory = model.fit(\n    train_generator,\n    validation_data=val_generator,\n    epochs=10\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T10:51:09.143662Z","iopub.execute_input":"2025-04-23T10:51:09.144405Z","iopub.status.idle":"2025-04-23T15:10:51.725389Z","shell.execute_reply.started":"2025-04-23T10:51:09.144373Z","shell.execute_reply":"2025-04-23T15:10:51.724843Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.save(\"densenet.h5\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T15:10:51.726563Z","iopub.execute_input":"2025-04-23T15:10:51.726836Z","iopub.status.idle":"2025-04-23T15:10:52.431170Z","shell.execute_reply.started":"2025-04-23T15:10:51.726812Z","shell.execute_reply":"2025-04-23T15:10:52.430580Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}