{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","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"},{"sourceId":6113,"sourceType":"modelInstanceVersion","modelInstanceId":4618,"modelId":2799},{"sourceId":6127,"sourceType":"modelInstanceVersion","modelInstanceId":4598,"modelId":2797}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install keras_cv==0.8.2 --no-deps\n!pip install tensorflow==2.15.0.post1 --no-deps\n!pip install keras==3.0.4 --no-deps\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-10-02T17:27:32.910878Z","iopub.execute_input":"2024-10-02T17:27:32.911250Z","iopub.status.idle":"2024-10-02T17:28:39.589946Z","shell.execute_reply.started":"2024-10-02T17:27:32.911211Z","shell.execute_reply":"2024-10-02T17:28:39.588953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nos.environ[\"KERAS_BACKEND\"] = \"jax\"\nimport keras_cv\nimport keras\nfrom keras import ops\nimport tensorflow as tf\nimport cv2\nimport pandas as pd\nimport numpy as np\nfrom glob import glob\nfrom tqdm.notebook import tqdm\nimport joblib\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2024-10-02T17:28:39.591959Z","iopub.execute_input":"2024-10-02T17:28:39.592311Z","iopub.status.idle":"2024-10-02T17:28:49.586144Z","shell.execute_reply.started":"2024-10-02T17:28:39.592275Z","shell.execute_reply":"2024-10-02T17:28:49.585346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BASE_PATH = \"/kaggle/input/hms-harmful-brain-activity-classification\"\n\nSPEC_DIR = \"/tmp/dataset/hms-hbac\"\nos.makedirs(SPEC_DIR+'/train_spectrograms', exist_ok=True)\nos.makedirs(SPEC_DIR+'/test_spectrograms', exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T17:28:49.587332Z","iopub.execute_input":"2024-10-02T17:28:49.588026Z","iopub.status.idle":"2024-10-02T17:28:49.593912Z","shell.execute_reply.started":"2024-10-02T17:28:49.587979Z","shell.execute_reply":"2024-10-02T17:28:49.592899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CFG:\n    verbose = 1  # Verbosity\n    seed = 42  # Random seed\n    preset = \"efficientnetv2_b2_imagenet\" \n    image_size = [400, 300]  # Input image size\n    epochs = 100 # Training epochs\n    batch_size = 64  # Batch size\n    lr_mode = \"cos\" # LR scheduler mode from one of \"cos\", \"step\", \"exp\"\n    drop_remainder = True  # Drop incomplete batches\n    num_classes = 6 # Number of classes in the dataset\n    fold = 0 # Which fold to set as validation data\n    class_names = ['Seizure', 'LPD', 'GPD', 'LRDA','GRDA', 'Other']\n    label2name = dict(enumerate(class_names))\n    name2label = {v:k for k, v in label2name.items()}","metadata":{"execution":{"iopub.status.busy":"2024-10-02T17:28:49.596730Z","iopub.execute_input":"2024-10-02T17:28:49.597466Z","iopub.status.idle":"2024-10-02T17:28:49.619370Z","shell.execute_reply.started":"2024-10-02T17:28:49.597407Z","shell.execute_reply":"2024-10-02T17:28:49.618489Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ndf = pd.read_csv(f'{BASE_PATH}/train.csv')\ndf['eeg_path'] = f'{BASE_PATH}/train_eegs/'+df['eeg_id'].astype(str)+'.parquet'\ndf['spec_path'] = f'{BASE_PATH}/train_spectrograms/'+df['spectrogram_id'].astype(str)+'.parquet'\ndf['spec2_path'] = f'{SPEC_DIR}/train_spectrograms/'+df['spectrogram_id'].astype(str)+'.npy'\ndf['class_name'] = df.expert_consensus.copy()\ndf['class_label'] = df.expert_consensus.map(CFG.name2label)\ndisplay(df.head(5))\n\n\ntest_df = pd.read_csv(f'{BASE_PATH}/test.csv')\ntest_df['eeg_path'] = f'{BASE_PATH}/test_eegs/'+test_df['eeg_id'].astype(str)+'.parquet'\ntest_df['spec_path'] = f'{BASE_PATH}/test_spectrograms/'+test_df['spectrogram_id'].astype(str)+'.parquet'\ntest_df['spec2_path'] = f'{SPEC_DIR}/test_spectrograms/'+test_df['spectrogram_id'].astype(str)+'.npy'\ndisplay(test_df.head(5))","metadata":{"execution":{"iopub.status.busy":"2024-10-02T17:28:49.620490Z","iopub.execute_input":"2024-10-02T17:28:49.620840Z","iopub.status.idle":"2024-10-02T17:28:50.188445Z","shell.execute_reply.started":"2024-10-02T17:28:49.620801Z","shell.execute_reply":"2024-10-02T17:28:50.187503Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# parquet ko npy mei convert \n\n\ndef process_spec(spec_id, split=\"train\"):\n    spec_path = f\"{BASE_PATH}/{split}_spectrograms/{spec_id}.parquet\"\n    spec = pd.read_parquet(spec_path)\n    spec = spec.fillna(0).values[:, 1:].T # fill NaN values with 0, transpose(Time, Freq) -> (Freq, Time)\n    spec = spec.astype(\"float32\")\n    np.save(f\"{SPEC_DIR}/{split}_spectrograms/{spec_id}.npy\", spec)\n\n#unique spec_ids of train and valid data\nspec_ids = df[\"spectrogram_id\"].unique()\n\n# Parallelize the processing using joblib for training data\n_ = joblib.Parallel(n_jobs=-1, backend=\"loky\")(\n    joblib.delayed(process_spec)(spec_id, \"train\")\n    for spec_id in tqdm(spec_ids, total=len(spec_ids))\n)\n\n#unique spec_ids of test data\ntest_spec_ids = test_df[\"spectrogram_id\"].unique()\n\n# Parallelize the processing using joblib for test data\n_ = joblib.Parallel(n_jobs=-1, backend=\"loky\")(\n    joblib.delayed(process_spec)(spec_id, \"test\")\n    for spec_id in tqdm(test_spec_ids, total=len(test_spec_ids))\n)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T17:28:50.189621Z","iopub.execute_input":"2024-10-02T17:28:50.189927Z","iopub.status.idle":"2024-10-02T17:31:53.281033Z","shell.execute_reply.started":"2024-10-02T17:28:50.189894Z","shell.execute_reply":"2024-10-02T17:31:53.279675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def build_augmenter(dim=CFG.image_size):\n    augmenters = [\n        keras_cv.layers.MixUp(alpha=2.0),\n        keras_cv.layers.RandomCutout(height_factor=(1.0, 1.0),\n                                     width_factor=(0.06, 0.1)), # freq-masking\n        keras_cv.layers.RandomCutout(height_factor=(0.06, 0.1),\n                                     width_factor=(1.0, 1.0)), # time-masking\n    ]\n    \n    def augment(img, label):\n        data = {\"images\":img, \"labels\":label}\n        for augmenter in augmenters:\n            if tf.random.uniform([]) < 0.5:\n                data = augmenter(data, training=True)\n        return data[\"images\"], data[\"labels\"]\n    \n    return augment\n\n\ndef build_decoder(with_labels=True, target_size=CFG.image_size, dtype=32):\n    def decode_signal(path, offset=None):\n        # Read .npy files and process the signal\n        file_bytes = tf.io.read_file(path)\n        sig = tf.io.decode_raw(file_bytes, tf.float32)\n        sig = sig[1024//dtype:]  # Remove header tag\n        sig = tf.reshape(sig, [400, -1])\n        \n        # Extract labeled subsample from full spectrogram using \"offset\"\n        if offset is not None: \n            offset = offset // 2  # Only odd values are given\n            sig = sig[:, offset:offset+300]\n            \n            # Pad spectrogram to ensure the same input shape of [400, 300]\n            pad_size = tf.math.maximum(0, 300 - tf.shape(sig)[1])\n            sig = tf.pad(sig, [[0, 0], [0, pad_size]])\n            sig = tf.reshape(sig, [400, 300])\n        \n        # Log spectrogram \n        sig = tf.clip_by_value(sig, tf.math.exp(-4.0), tf.math.exp(8.0)) # avoid 0 in log\n        sig = tf.math.log(sig)\n        \n        # Normalize spectrogram\n        sig -= tf.math.reduce_mean(sig)\n        sig /= tf.math.reduce_std(sig) + 1e-6\n        \n        # Mono channel to 3 channels to use \"ImageNet\" weights\n        sig = tf.tile(sig[..., None], [1, 1, 3])\n        return sig\n    \n    def decode_label(label):\n        label = tf.one_hot(label, CFG.num_classes)\n        label = tf.cast(label, tf.float32)\n        label = tf.reshape(label, [CFG.num_classes])\n        return label\n    \n    def decode_with_labels(path, offset=None, label=None):\n        sig = decode_signal(path, offset)\n        label = decode_label(label)\n        return (sig, label)\n    \n    return decode_with_labels if with_labels else decode_signal\n\n\ndef build_dataset(paths, offsets=None, labels=None, batch_size=32, cache=True,\n                  decode_fn=None, augment_fn=None,\n                  augment=False, repeat=True, shuffle=1024, \n                  cache_dir=\"\", drop_remainder=False):\n    if cache_dir != \"\" and cache is True:\n        os.makedirs(cache_dir, exist_ok=True)\n    \n    if decode_fn is None:\n        decode_fn = build_decoder(labels is not None)\n    \n    if augment_fn is None:\n        augment_fn = build_augmenter()\n    \n    AUTO = tf.data.experimental.AUTOTUNE\n    slices = (paths, offsets) if labels is None else (paths, offsets, labels)\n    \n    ds = tf.data.Dataset.from_tensor_slices(slices)\n    ds = ds.map(decode_fn, num_parallel_calls=AUTO)\n    ds = ds.cache(cache_dir) if cache else ds\n    ds = ds.repeat() if repeat else ds\n    if shuffle: \n        ds = ds.shuffle(shuffle, seed=CFG.seed)\n        opt = tf.data.Options()\n        opt.experimental_deterministic = False\n        ds = ds.with_options(opt)\n    ds = ds.batch(batch_size, drop_remainder=drop_remainder)\n    ds = ds.map(augment_fn, num_parallel_calls=AUTO) if augment else ds\n    ds = ds.prefetch(AUTO)\n    return ds","metadata":{"execution":{"iopub.status.busy":"2024-10-02T17:31:53.283344Z","iopub.execute_input":"2024-10-02T17:31:53.283930Z","iopub.status.idle":"2024-10-02T17:31:53.318013Z","shell.execute_reply.started":"2024-10-02T17:31:53.283867Z","shell.execute_reply":"2024-10-02T17:31:53.316770Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import StratifiedGroupKFold\n\nsgkf = StratifiedGroupKFold(n_splits=5, shuffle=True, random_state=CFG.seed)\n\ndf[\"fold\"] = -1\ndf.reset_index(drop=True, inplace=True)\nfor fold, (train_idx, valid_idx) in enumerate(\n    sgkf.split(df, y=df[\"class_label\"], groups=df[\"patient_id\"])\n):\n    df.loc[valid_idx, \"fold\"] = fold\ndf.groupby([\"fold\", \"class_name\"])[[\"eeg_id\"]].count().T\n","metadata":{"execution":{"iopub.status.busy":"2024-10-02T17:31:53.319631Z","iopub.execute_input":"2024-10-02T17:31:53.319993Z","iopub.status.idle":"2024-10-02T17:31:57.706406Z","shell.execute_reply.started":"2024-10-02T17:31:53.319955Z","shell.execute_reply":"2024-10-02T17:31:57.705385Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_df = df.groupby(\"spectrogram_id\").head(1).reset_index(drop=False)\ntrain_df = sample_df[sample_df.fold != CFG.fold]\nvalid_df = sample_df[sample_df.fold == CFG.fold]\nprint(f\"# Num Train: {len(train_df)} | Num Valid: {len(valid_df)}\")\n\n# Train\ntrain_paths = train_df.spec2_path.values\ntrain_offsets = train_df.spectrogram_label_offset_seconds.values.astype(int)\ntrain_labels = train_df.class_label.values\ntrain_ds = build_dataset(train_paths, train_offsets, train_labels, batch_size=CFG.batch_size,\n                         repeat=True, shuffle=True, augment=True, cache=True)\n\n# Valid\nvalid_paths = valid_df.spec2_path.values\nvalid_offsets = valid_df.spectrogram_label_offset_seconds.values.astype(int)\nvalid_labels = valid_df.class_label.values\nvalid_ds = build_dataset(valid_paths, valid_offsets, valid_labels, batch_size=CFG.batch_size,\n                         repeat=False, shuffle=False, augment=False, cache=False)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T17:31:57.707866Z","iopub.execute_input":"2024-10-02T17:31:57.708450Z","iopub.status.idle":"2024-10-02T17:32:00.866113Z","shell.execute_reply.started":"2024-10-02T17:31:57.708409Z","shell.execute_reply":"2024-10-02T17:32:00.864938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"imgs, tars = next(iter(train_ds))\n\nnum_imgs = 8\nplt.figure(figsize=(4*4, num_imgs//4*5))\nfor i in range(num_imgs):\n    plt.subplot(num_imgs//4, 4, i + 1)\n    img = imgs[i].numpy()[...,0]  \n    img -= img.min()\n    img /= img.max() + 1e-4\n    tar = CFG.label2name[np.argmax(tars[i].numpy())]\n    plt.imshow(img)\n    plt.title(f\"Target: {tar}\")\n    plt.axis('off')\n    \nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-02T17:32:00.870411Z","iopub.execute_input":"2024-10-02T17:32:00.870831Z","iopub.status.idle":"2024-10-02T17:32:03.478581Z","shell.execute_reply.started":"2024-10-02T17:32:00.870773Z","shell.execute_reply":"2024-10-02T17:32:03.477022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import math\ndef get_lr_callback(batch_size=8, mode='cos', epochs=10, plot=False):\n    lr_start, lr_max, lr_min = 5e-5, 6e-6 * batch_size, 1e-5\n    lr_ramp_ep, lr_sus_ep, lr_decay = 3, 0, 0.75\n\n    def lrfn(epoch):  # Learning rate update function\n        if epoch < lr_ramp_ep: lr = (lr_max - lr_start) / lr_ramp_ep * epoch + lr_start\n        elif epoch < lr_ramp_ep + lr_sus_ep: lr = lr_max\n        elif mode == 'exp': lr = (lr_max - lr_min) * lr_decay**(epoch - lr_ramp_ep - lr_sus_ep) + lr_min\n        elif mode == 'step': lr = lr_max * lr_decay**((epoch - lr_ramp_ep - lr_sus_ep) // 2)\n        elif mode == 'cos':\n            decay_total_epochs, decay_epoch_index = epochs - lr_ramp_ep - lr_sus_ep + 3, epoch - lr_ramp_ep - lr_sus_ep\n            phase = math.pi * decay_epoch_index / decay_total_epochs\n            lr = (lr_max - lr_min) * 0.5 * (1 + math.cos(phase)) + lr_min\n        return lr\n\n    if plot:  # Plot lr curve if plot is True\n        plt.figure(figsize=(10, 5))\n        plt.plot(np.arange(epochs), [lrfn(epoch) for epoch in np.arange(epochs)], marker='o')\n        plt.xlabel('epoch'); plt.ylabel('lr')\n        plt.title('LR Scheduler')\n        plt.show()\n    return keras.callbacks.LearningRateScheduler(lrfn, verbose=False) ","metadata":{"execution":{"iopub.status.busy":"2024-10-02T17:32:03.480345Z","iopub.execute_input":"2024-10-02T17:32:03.480805Z","iopub.status.idle":"2024-10-02T17:32:03.493809Z","shell.execute_reply.started":"2024-10-02T17:32:03.480761Z","shell.execute_reply":"2024-10-02T17:32:03.492608Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lr_cb = get_lr_callback(CFG.batch_size, mode=CFG.lr_mode, plot=True)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T17:32:03.495013Z","iopub.execute_input":"2024-10-02T17:32:03.495335Z","iopub.status.idle":"2024-10-02T17:32:03.817817Z","shell.execute_reply.started":"2024-10-02T17:32:03.495301Z","shell.execute_reply":"2024-10-02T17:32:03.816808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.applications import ResNet50\nfrom keras.layers import GlobalAveragePooling2D, Dense\nfrom keras.models import Model\nimport keras\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom sklearn.metrics import confusion_matrix\nimport numpy as np\n\n# Load the ResNet50 base model\nbase_model = ResNet50(weights='imagenet', include_top=False)\n\n# Add layers on top of the base model\nx = GlobalAveragePooling2D()(base_model.output)\nx = Dense(CFG.num_classes, activation='softmax')(x)\n\n# Define the final model\nmodel = Model(inputs=base_model.input, outputs=x)\n\n# Compile the model\nmodel.compile(optimizer=keras.optimizers.Adam(learning_rate=1e-4),\n              loss=keras.losses.KLDivergence(),\n              metrics=['accuracy'])\n\n# Learning rate callback\nlr_cb = get_lr_callback(CFG.batch_size, mode=CFG.lr_mode, plot=True)\n\n# Checkpoint callback to save the best model\nckpt_cb = keras.callbacks.ModelCheckpoint(f\"best_model_resnet_custom_fold{CFG.fold}.keras\",\n                                           monitor='val_loss',\n                                           save_best_only=True,\n                                           save_weights_only=False,\n                                           mode='min')\n\n# Train the model\nhistory = model.fit(train_ds,\n                    epochs=CFG.epochs,\n                    callbacks=[lr_cb, ckpt_cb],\n                    steps_per_epoch=len(train_df) // CFG.batch_size,\n                    validation_data=valid_ds,\n                    verbose=CFG.verbose)\n\n# Function to plot training history (accuracy and loss)\ndef plot_training_history(history):\n    # Get the accuracy and loss from the training history\n    acc = history.history['accuracy']\n    val_acc = history.history['val_accuracy']\n    loss = history.history['loss']\n    val_loss = history.history['val_loss']\n\n    epochs_range = range(len(acc))\n\n    # Plot training and validation accuracy\n    plt.figure(figsize=(12, 6))\n\n    plt.subplot(1, 2, 1)\n    plt.plot(epochs_range, acc, label='Training Accuracy')\n    plt.plot(epochs_range, val_acc, label='Validation Accuracy')\n    plt.legend(loc='lower right')\n    plt.title('Training and Validation Accuracy')\n\n    # Plot training and validation loss\n    plt.subplot(1, 2, 2)\n    plt.plot(epochs_range, loss, label='Training Loss')\n    plt.plot(epochs_range, val_loss, label='Validation Loss')\n    plt.legend(loc='upper right')\n    plt.title('Training and Validation Loss')\n\n    plt.show()\n\n# Call the function to plot the graphs\nplot_training_history(history)\n\n# Generate confusion matrix\ndef plot_confusion_matrix(model, valid_ds):\n    # Get the true labels and predictions\n    true_labels = []\n    predictions = []\n\n    # Iterate through validation data\n    for images, labels in valid_ds:\n        preds = model.predict(images)\n        predictions.extend(np.argmax(preds, axis=1))\n        true_labels.extend(np.argmax(labels, axis=1))\n\n    # Compute the confusion matrix\n    cm = confusion_matrix(true_labels, predictions)\n\n    # Plot the confusion matrix using seaborn\n    plt.figure(figsize=(10, 7))\n    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')\n    plt.xlabel('Predicted Labels')\n    plt.ylabel('True Labels')\n    plt.title('Confusion Matrix')\n    plt.show()\n\n# Call the function to plot the confusion matrix\nplot_confusion_matrix(model, valid_ds)\n","metadata":{"execution":{"iopub.status.busy":"2024-10-02T17:32:03.818974Z","iopub.execute_input":"2024-10-02T17:32:03.819313Z","iopub.status.idle":"2024-10-02T20:11:47.117207Z","shell.execute_reply.started":"2024-10-02T17:32:03.819277Z","shell.execute_reply":"2024-10-02T20:11:47.116115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from keras.applications import ResNet50\n# from keras.layers import GlobalAveragePooling2D, Dense\n# from keras.models import Model\n\n\n# base_model = ResNet50(weights='imagenet', include_top=False)\n\n# x = GlobalAveragePooling2D()(base_model.output)\n# x = Dense(CFG.num_classes, activation='softmax')(x)\n\n\n# model = Model(inputs=base_model.input, outputs=x)\n\n\n# model.compile(optimizer=keras.optimizers.Adam(learning_rate=1e-4),\n#               loss=keras.losses.KLDivergence(),\n#               metrics=['accuracy'])\n\n\n# lr_cb = get_lr_callback(CFG.batch_size, mode=CFG.lr_mode, plot=True)\n\n\n# ckpt_cb = keras.callbacks.ModelCheckpoint(f\"best_model_resnet_custom_fold{CFG.fold}.keras\",\n#                                            monitor='val_loss',\n#                                            save_best_only=True,\n#                                            save_weights_only=False,\n#                                            mode='min')\n\n# # Train the model\n# history = model.fit(train_ds,\n#                     epochs=CFG.epochs,\n#                     callbacks=[lr_cb, ckpt_cb],\n#                     steps_per_epoch=len(train_df) // CFG.batch_size,\n#                     validation_data=valid_ds,\n#                     verbose=CFG.verbose)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T20:11:47.118840Z","iopub.execute_input":"2024-10-02T20:11:47.119308Z","iopub.status.idle":"2024-10-02T20:11:47.124812Z","shell.execute_reply.started":"2024-10-02T20:11:47.119261Z","shell.execute_reply":"2024-10-02T20:11:47.123810Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.applications import MobileNet\nfrom keras.layers import GlobalAveragePooling2D, Dense\nfrom keras.models import Model\nimport keras\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom sklearn.metrics import confusion_matrix\nimport numpy as np\n\n# Load the MobileNet base model\nbase_model = MobileNet(weights='imagenet', include_top=False)\n\n# Add layers on top of the base model\nx = GlobalAveragePooling2D()(base_model.output)\nx = Dense(CFG.num_classes, activation='softmax')(x)\n\n# Define the final model\nmodel = Model(inputs=base_model.input, outputs=x)\n\n# Compile the model\nmodel.compile(optimizer=keras.optimizers.Adam(learning_rate=1e-4),\n              loss=keras.losses.KLDivergence(),\n              metrics=['accuracy'])\n\n# Learning rate callback\nlr_cb = get_lr_callback(CFG.batch_size, mode=CFG.lr_mode, plot=True)\n\n# Checkpoint callback to save the best model\nckpt_cb = keras.callbacks.ModelCheckpoint(f\"best_model_mobilenet_custom_fold{CFG.fold}.keras\",\n                                           monitor='val_loss',\n                                           save_best_only=True,\n                                           save_weights_only=False,\n                                           mode='min')\n\n# Train the model\nhistory = model.fit(train_ds,\n                    epochs=CFG.epochs,\n                    callbacks=[lr_cb, ckpt_cb],\n                    steps_per_epoch=len(train_df) // CFG.batch_size,\n                    validation_data=valid_ds,\n                    verbose=CFG.verbose)\n\n# Function to plot training history (accuracy and loss)\ndef plot_training_history(history):\n    # Get the accuracy and loss from the training history\n    acc = history.history['accuracy']\n    val_acc = history.history['val_accuracy']\n    loss = history.history['loss']\n    val_loss = history.history['val_loss']\n\n    epochs_range = range(len(acc))\n\n    # Plot training and validation accuracy\n    plt.figure(figsize=(12, 6))\n\n    plt.subplot(1, 2, 1)\n    plt.plot(epochs_range, acc, label='Training Accuracy')\n    plt.plot(epochs_range, val_acc, label='Validation Accuracy')\n    plt.legend(loc='lower right')\n    plt.title('Training and Validation Accuracy')\n\n    # Plot training and validation loss\n    plt.subplot(1, 2, 2)\n    plt.plot(epochs_range, loss, label='Training Loss')\n    plt.plot(epochs_range, val_loss, label='Validation Loss')\n    plt.legend(loc='upper right')\n    plt.title('Training and Validation Loss')\n\n    plt.show()\n\n# Call the function to plot the graphs\nplot_training_history(history)\n\n# Generate confusion matrix\ndef plot_confusion_matrix(model, valid_ds):\n    # Get the true labels and predictions\n    true_labels = []\n    predictions = []\n\n    # Iterate through validation data\n    for images, labels in valid_ds:\n        preds = model.predict(images)\n        predictions.extend(np.argmax(preds, axis=1))\n        true_labels.extend(np.argmax(labels, axis=1))\n\n    # Compute the confusion matrix\n    cm = confusion_matrix(true_labels, predictions)\n\n    # Plot the confusion matrix using seaborn\n    plt.figure(figsize=(10, 7))\n    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')\n    plt.xlabel('Predicted Labels')\n    plt.ylabel('True Labels')\n    plt.title('Confusion Matrix')\n    plt.show()\n\n# Call the function to plot the confusion matrix\nplot_confusion_matrix(model, valid_ds)\n","metadata":{"execution":{"iopub.status.busy":"2024-10-02T20:11:47.126444Z","iopub.execute_input":"2024-10-02T20:11:47.126824Z","iopub.status.idle":"2024-10-02T21:26:06.565697Z","shell.execute_reply.started":"2024-10-02T20:11:47.126790Z","shell.execute_reply":"2024-10-02T21:26:06.564535Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from keras.applications import MobileNet\n# from keras.layers import GlobalAveragePooling2D, Dense\n# from keras.models import Model\n\n\n# base_model = MobileNet(weights='imagenet', include_top=False)\n\n\n# x = GlobalAveragePooling2D()(base_model.output)\n# x = Dense(CFG.num_classes, activation='softmax')(x)\n\n\n# model = Model(inputs=base_model.input, outputs=x)\n\n\n# model.compile(optimizer=keras.optimizers.Adam(learning_rate=1e-4),\n#               loss=keras.losses.KLDivergence(),\n#               metrics=['accuracy'])\n\n\n# lr_cb = get_lr_callback(CFG.batch_size, mode=CFG.lr_mode, plot=True)\n\n\n# ckpt_cb = keras.callbacks.ModelCheckpoint(f\"best_model_mobilenet_custom_fold{CFG.fold}.keras\",\n#                                            monitor='val_loss',\n#                                            save_best_only=True,\n#                                            save_weights_only=False,\n#                                            mode='min')\n\n# history = model.fit(train_ds,\n#                     epochs=CFG.epochs,\n#                     callbacks=[lr_cb, ckpt_cb],\n#                     steps_per_epoch=len(train_df) // CFG.batch_size,\n#                     validation_data=valid_ds,\n#                     verbose=CFG.verbose)\n","metadata":{"execution":{"iopub.status.busy":"2024-10-02T21:26:06.567267Z","iopub.execute_input":"2024-10-02T21:26:06.567697Z","iopub.status.idle":"2024-10-02T21:26:06.574697Z","shell.execute_reply.started":"2024-10-02T21:26:06.567656Z","shell.execute_reply":"2024-10-02T21:26:06.573330Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# LOSS = keras.losses.KLDivergence()\n# from keras.applications import EfficientNetV2B2\n# from keras.layers import GlobalAveragePooling2D, Dense\n# from keras.models import Model\n# base_model = EfficientNetV2B2(weights='imagenet', include_top=False)\n\n# # Add custom classification head\n# x = GlobalAveragePooling2D()(base_model.output)\n# x = Dense(CFG.num_classes, activation='softmax')(x)\n# # Create the final model\n# model = Model(inputs=base_model.input, outputs=x)\n# # Compile the model\n# model.compile(optimizer=keras.optimizers.Adam(learning_rate=1e-4),\n#               loss=LOSS,\n#               metrics=['accuracy'])\n\n# # Model Checkpoint Callback\n# ckpt_cb = keras.callbacks.ModelCheckpoint(f\"best_model_efficientnet_custom_fold{CFG.fold}.keras\",\n#                                            monitor='val_loss',\n#                                            save_best_only=True,\n#                                            save_weights_only=False,\n#                                            mode='min')\n# # Train the model\n# history = model.fit(train_ds,\n#                     epochs=CFG.epochs,\n#                     callbacks=[lr_cb, ckpt_cb],\n#                     steps_per_epoch=len(train_df) // CFG.batch_size,\n#                     validation_data=valid_ds,\n#                     verbose=CFG.verbose)\n","metadata":{"execution":{"iopub.status.busy":"2024-10-02T21:26:06.576089Z","iopub.execute_input":"2024-10-02T21:26:06.576517Z","iopub.status.idle":"2024-10-02T21:26:06.593199Z","shell.execute_reply.started":"2024-10-02T21:26:06.576469Z","shell.execute_reply":"2024-10-02T21:26:06.592019Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}