{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":14774,"databundleVersionId":875431,"sourceType":"competition"},{"sourceId":187731,"sourceType":"datasetVersion","datasetId":80814}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"Some good references:\n1. https://towardsdatascience.com/a-bunch-of-tips-and-tricks-for-training-deep-neural-networks-3ca24c31ddc8\n2. https://towardsdatascience.com/review-densenet-image-classification-b6631a8ef803","metadata":{}},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom matplotlib import pyplot as plt\nfrom sklearn.metrics import cohen_kappa_score\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import confusion_matrix, classification_report, balanced_accuracy_score\nfrom sklearn.utils.multiclass import unique_labels\nfrom sklearn.utils import class_weight\nimport cv2\nimport os\n\nprint(os.listdir(\"../input\"))\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2025-10-13T13:48:04.262718Z","iopub.execute_input":"2025-10-13T13:48:04.262971Z","iopub.status.idle":"2025-10-13T13:48:04.268623Z","shell.execute_reply.started":"2025-10-13T13:48:04.262930Z","shell.execute_reply":"2025-10-13T13:48:04.267878Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class QWKCallback(keras.callbacks.Callback):\n    def __init__(self, validation_data):\n        super(keras.callbacks.Callback, self).__init__()\n        self.X = validation_data[0]\n        self.Y = validation_data[1]\n        self.history = []\n        \n    def on_epoch_end(self, epoch, logs=None):\n        logs = logs or {}\n        pred = self.model.predict(self.X, verbose=0)\n        score = cohen_kappa_score(\n            np.argmax(self.Y, axis=1), \n            np.argmax(pred, axis=1), \n            labels=[0,1,2,3,4], \n            weights='quadratic'\n        )\n        print(f\"Epoch {epoch} : QWK: {score}\")\n        self.history.append(score)\n        if score >= max(self.history):\n            print(f'Saving checkpoint: {score}')\n            self.model.save('../working/DenseNet169_bestqwk.keras')\n","metadata":{"execution":{"iopub.status.busy":"2025-10-13T13:48:04.270018Z","iopub.execute_input":"2025-10-13T13:48:04.270324Z","iopub.status.idle":"2025-10-13T13:48:04.430196Z","shell.execute_reply.started":"2025-10-13T13:48:04.270301Z","shell.execute_reply":"2025-10-13T13:48:04.429366Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\ndef plot_confusion_matrix(y_true, y_pred, classes,\n                          normalize=False,\n                          title=None,\n                          cmap=plt.cm.Blues):\n    if not title:\n        if normalize:\n            title = 'Normalized confusion matrix'\n        else:\n            title = 'Confusion matrix, without normalization'\n\n    # Compute confusion matrix\n    cm = confusion_matrix(y_true, y_pred)\n    # Only use the labels that appear in the data\n    classes = classes[unique_labels(y_true, y_pred)]\n    if normalize:\n        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]\n        print(\"Normalized confusion matrix\")\n    else:\n        print('Confusion matrix, without normalization')\n\n    print(cm)\n\n    fig, ax = plt.subplots()\n    im = ax.imshow(cm, interpolation='nearest', cmap=cmap)\n    ax.figure.colorbar(im, ax=ax)\n    # We want to show all ticks...\n    ax.set(xticks=np.arange(cm.shape[1]),\n           yticks=np.arange(cm.shape[0]),\n           # ... and label them with the respective list entries\n           xticklabels=classes, yticklabels=classes,\n           title=title,\n           ylabel='True label',\n           xlabel='Predicted label')\n\n    # Rotate the tick labels and set their alignment.\n    plt.setp(ax.get_xticklabels(), rotation=45, ha=\"right\",\n             rotation_mode=\"anchor\")\n\n    # Loop over data dimensions and create text annotations.\n    fmt = '.2f' if normalize else 'd'\n    thresh = cm.max() / 2.\n    for i in range(cm.shape[0]):\n        for j in range(cm.shape[1]):\n            ax.text(j, i, format(cm[i, j], fmt),\n                    ha=\"center\", va=\"center\",\n                    color=\"white\" if cm[i, j] > thresh else \"black\")\n    fig.tight_layout()\n    return ax","metadata":{"execution":{"iopub.status.busy":"2025-10-13T13:48:04.431004Z","iopub.execute_input":"2025-10-13T13:48:04.431280Z","iopub.status.idle":"2025-10-13T13:48:04.446170Z","shell.execute_reply.started":"2025-10-13T13:48:04.431257Z","shell.execute_reply":"2025-10-13T13:48:04.445490Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def load_raw_images_df(data_frame,filenamecol,labelcol,img_size,n_classes):\n    n_images = len(data_frame)\n    X = np.empty((n_images,img_size,img_size,3))\n    Y = np.zeros((n_images,n_classes))\n    for index,entry in data_frame.iterrows():\n        Y[index,entry[labelcol]] = 1 # one hot encoding of the label\n        # Load the image and resize\n        img = cv2.imread(entry[filenamecol])\n        X[index,:] = cv2.resize(img, (img_size, img_size))\n        X[index,:] = X[index,:] / 255.0\n    return X,Y","metadata":{"execution":{"iopub.status.busy":"2025-10-13T13:48:04.446992Z","iopub.execute_input":"2025-10-13T13:48:04.447272Z","iopub.status.idle":"2025-10-13T13:48:04.465745Z","shell.execute_reply.started":"2025-10-13T13:48:04.447248Z","shell.execute_reply":"2025-10-13T13:48:04.465190Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"batch_size = 32\nimg_size = 224","metadata":{"execution":{"iopub.status.busy":"2025-10-13T13:48:04.466656Z","iopub.execute_input":"2025-10-13T13:48:04.466901Z","iopub.status.idle":"2025-10-13T13:48:04.482173Z","shell.execute_reply.started":"2025-10-13T13:48:04.466879Z","shell.execute_reply":"2025-10-13T13:48:04.481532Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\ntrain_raw_data = pd.read_csv(\"../input/aptos2019-blindness-detection/train.csv\")\n\n# Create a new column 'filename' by mapping the image paths\ntrain_raw_data[\"filename\"] = train_raw_data[\"id_code\"].map(lambda x: os.path.join(\"../input/aptos2019-blindness-detection/train_images\", x + \".png\"))\n\n# Display the distribution of classes using a histogram\ntrain_raw_data.diagnosis.hist()\nplt.figure(figsize=(8, 6))\nplt.hist(train_raw_data.diagnosis, bins=range(6), align='left', rwidth=0.8, color='skyblue', edgecolor='black')\nplt.xlabel('Diagnosis', fontsize=16, fontweight='bold')  # Increase font size and set bold font\nplt.ylabel('Frequency', fontsize=16, fontweight='bold')  # Increase font size and set bold font\nplt.title('Distribution of Classes', fontsize=18, fontweight='bold')  # Increase font size and set bold font\nplt.xticks(ticks=range(5), labels=range(5))  # Set the x-axis ticks to match the number of classes (assuming 5 classes)\nplt.grid(axis='y', linestyle='--', alpha=0.7)\nplt.tight_layout()\nplt.show()","metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","execution":{"iopub.status.busy":"2025-10-13T13:48:04.482894Z","iopub.execute_input":"2025-10-13T13:48:04.483163Z","iopub.status.idle":"2025-10-13T13:48:04.940624Z","shell.execute_reply.started":"2025-10-13T13:48:04.483126Z","shell.execute_reply":"2025-10-13T13:48:04.939892Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_raw_data[\"diagnosis\"].value_counts()","metadata":{"execution":{"iopub.status.busy":"2025-10-13T13:48:04.942760Z","iopub.execute_input":"2025-10-13T13:48:04.943040Z","iopub.status.idle":"2025-10-13T13:48:04.952506Z","shell.execute_reply.started":"2025-10-13T13:48:04.943023Z","shell.execute_reply":"2025-10-13T13:48:04.951789Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"label_title = {\"0\" : \"No DR\",\"1\" : \"Mild\",\"2\" : \"Moderate\",\"3\" :\"Severe\",\"4\" : \"Proliferative DR\"}\nclass_labels=[\"No DR\",\"Mild\",\"Moderate\",\"Severe\",\"Proliferative DR\"]","metadata":{"execution":{"iopub.status.busy":"2025-10-13T13:48:04.953189Z","iopub.execute_input":"2025-10-13T13:48:04.953420Z","iopub.status.idle":"2025-10-13T13:48:04.966233Z","shell.execute_reply.started":"2025-10-13T13:48:04.953385Z","shell.execute_reply":"2025-10-13T13:48:04.965562Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Create subplots with a 5x2 grid\nfig, ax = plt.subplots(2, 5, figsize=(10, 3))\nax = ax.flatten()\n\nfor i, (index, row) in enumerate(train_raw_data.iloc[0:10,:].iterrows()):\n    img = cv2.imread(os.path.join(\"../input/aptos2019-blindness-detection/train_images\", row[\"id_code\"] + \".png\"))\n    ax[i].imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))\n    ax[i].set_title(label_title[str(row[\"diagnosis\"])])\n    ax[i].axis('off')  # Hide axes\n    \nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2025-10-13T13:48:04.967005Z","iopub.execute_input":"2025-10-13T13:48:04.967191Z","iopub.status.idle":"2025-10-13T13:48:10.993497Z","shell.execute_reply.started":"2025-10-13T13:48:04.967177Z","shell.execute_reply":"2025-10-13T13:48:10.992659Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df,val_df = train_test_split(train_raw_data,random_state=42,shuffle=True,test_size=0.30)\ntrain_df.reset_index(drop=True,inplace=True)\nval_df.reset_index(drop=True,inplace=True)","metadata":{"execution":{"iopub.status.busy":"2025-10-13T13:48:10.994307Z","iopub.execute_input":"2025-10-13T13:48:10.994518Z","iopub.status.idle":"2025-10-13T13:48:11.004032Z","shell.execute_reply.started":"2025-10-13T13:48:10.994502Z","shell.execute_reply":"2025-10-13T13:48:11.003235Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def create_dataset_from_dataframe(df, img_size, batch_size, augment=False, shuffle=True):\n    \"\"\"Create tf.data.Dataset from DataFrame with images and labels\"\"\"\n    \n    def load_image(filepath, label):\n        # Read and decode image\n        img = tf.io.read_file(filepath)\n        img = tf.image.decode_png(img, channels=3)\n        img = tf.image.resize(img, [img_size, img_size])\n        img = tf.cast(img, tf.float32) / 255.0\n        return img, label\n    \n    # Prepare filepaths and labels\n    filepaths = df['filename'].values\n    labels = tf.keras.utils.to_categorical(df['diagnosis'].values, num_classes=5)\n    \n    # Create dataset\n    dataset = tf.data.Dataset.from_tensor_slices((filepaths, labels))\n    \n    if shuffle:\n        dataset = dataset.shuffle(buffer_size=len(df))\n    \n    dataset = dataset.map(load_image, num_parallel_calls=tf.data.AUTOTUNE)\n    dataset = dataset.batch(batch_size)\n    \n    # Add augmentation for training\n    if augment:\n        data_augmentation = tf.keras.Sequential([\n            keras.layers.RandomZoom(0.15),\n            keras.layers.RandomFlip(\"horizontal_and_vertical\"),\n            keras.layers.RandomRotation(0.1),\n        ])\n        dataset = dataset.map(lambda x, y: (data_augmentation(x, training=True), y))\n    \n    dataset = dataset.prefetch(tf.data.AUTOTUNE)\n    return dataset\n\n# Create datasets\ntrain_dataset = create_dataset_from_dataframe(train_df, img_size, batch_size, augment=True, shuffle=True)\nval_dataset = create_dataset_from_dataframe(val_df, img_size, batch_size, augment=False, shuffle=False)\n\n# For callbacks that need numpy arrays (like QWKCallback), create validation arrays\nX_val_list = []\nY_val_list = []\nfor images, labels in val_dataset:\n    X_val_list.append(images.numpy())\n    Y_val_list.append(labels.numpy())\nX_val = np.vstack(X_val_list)\nY_val = np.vstack(Y_val_list)\n","metadata":{"execution":{"iopub.status.busy":"2025-10-13T13:48:11.005083Z","iopub.execute_input":"2025-10-13T13:48:11.005344Z","iopub.status.idle":"2025-10-13T13:48:46.378867Z","shell.execute_reply.started":"2025-10-13T13:48:11.005327Z","shell.execute_reply":"2025-10-13T13:48:46.378279Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Extract labels for class weight computation\nall_labels = []\nfor _, labels in train_dataset:\n    all_labels.append(labels.numpy())\nall_labels = np.vstack(all_labels)\nY_train_labels = np.argmax(all_labels, axis=1)\n\nclass_weights = class_weight.compute_class_weight(\n    'balanced', \n    classes=np.unique(Y_train_labels), \n    y=Y_train_labels\n)\ncls_wt_dict = dict(enumerate(class_weights))\nprint(cls_wt_dict)\n","metadata":{"execution":{"iopub.status.busy":"2025-10-13T13:48:46.379617Z","iopub.execute_input":"2025-10-13T13:48:46.379831Z","iopub.status.idle":"2025-10-13T13:50:15.437149Z","shell.execute_reply.started":"2025-10-13T13:48:46.379815Z","shell.execute_reply":"2025-10-13T13:50:15.436337Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def mixup(images, labels, alpha=0.2):\n    \"\"\"Apply mixup augmentation\"\"\"\n    batch_size = tf.shape(images)[0]\n    indices = tf.random.shuffle(tf.range(batch_size))\n    \n    images2 = tf.gather(images, indices)\n    labels2 = tf.gather(labels, indices)\n    \n    # Sample lambda from Beta distribution - specify dtype=tf.float32\n    lam = tf.random.uniform([], 0, alpha, dtype=tf.float32)\n    \n    # Cast labels to float32 to ensure type consistency\n    labels = tf.cast(labels, tf.float32)\n    labels2 = tf.cast(labels2, tf.float32)\n    \n    # Mix images and labels - use 1.0 (float) instead of 1 (int)\n    images = images * lam + images2 * (1.0 - lam)\n    labels = labels * lam + labels2 * (1.0 - lam)\n    \n    return images, labels\n\n# Apply mixup to training dataset\ntrain_dataset = train_dataset.map(lambda x, y: mixup(x, y, alpha=0.2))\n","metadata":{"execution":{"iopub.status.busy":"2025-10-13T13:50:15.437897Z","iopub.execute_input":"2025-10-13T13:50:15.438136Z","iopub.status.idle":"2025-10-13T13:50:15.541641Z","shell.execute_reply.started":"2025-10-13T13:50:15.438120Z","shell.execute_reply":"2025-10-13T13:50:15.540929Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def buildModel():\n    DenseNet169_model = keras.applications.DenseNet169(\n        include_top=False,\n        weights='imagenet',\n        input_tensor=keras.layers.Input(shape=(img_size, img_size, 3))\n    )\n    \n    p = keras.layers.GlobalAveragePooling2D()(DenseNet169_model.output)\n    d11 = keras.layers.Dense(\n        units=256, \n        activation='relu',\n        kernel_regularizer=keras.regularizers.l2(0.0001)\n    )(p)\n    o1 = keras.layers.Dense(units=5, activation='softmax')(d11)\n    \n    model = keras.models.Model(inputs=DenseNet169_model.input, outputs=o1)\n    \n    # Updated optimizer syntax\n    adam = keras.optimizers.Adam()\n    model.compile(optimizer=adam, loss='categorical_crossentropy', metrics=['accuracy'])\n    print(model.summary())\n    return model\n","metadata":{"execution":{"iopub.status.busy":"2025-10-13T13:50:15.542436Z","iopub.execute_input":"2025-10-13T13:50:15.542638Z","iopub.status.idle":"2025-10-13T13:50:15.549430Z","shell.execute_reply.started":"2025-10-13T13:50:15.542623Z","shell.execute_reply":"2025-10-13T13:50:15.548534Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"mymodel = buildModel()","metadata":{"execution":{"iopub.status.busy":"2025-10-13T13:50:15.550207Z","iopub.execute_input":"2025-10-13T13:50:15.550459Z","iopub.status.idle":"2025-10-13T13:50:23.563965Z","shell.execute_reply.started":"2025-10-13T13:50:15.550443Z","shell.execute_reply":"2025-10-13T13:50:23.563294Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"EPOCHS = 16\nearlystop = keras.callbacks.EarlyStopping(patience=10)\n\n# Changed 'val_acc' to 'val_accuracy'\nlearning_rate_reduction = keras.callbacks.ReduceLROnPlateau(\n    monitor='val_accuracy',  # Changed from 'val_acc'\n    patience=2, \n    verbose=1, \n    factor=0.5, \n    min_lr=0.00001\n)\n\n# Changed to .keras format\ncheckpoint = keras.callbacks.ModelCheckpoint(\n    '../working/DenseNet169.keras',  # Changed from .h5\n    monitor='val_loss', \n    verbose=1, \n    save_best_only=True, \n    mode='min'\n)\n\nqwk = QWKCallback((X_val, Y_val))\nmycallbacks = [earlystop, learning_rate_reduction, checkpoint, qwk]\n","metadata":{"execution":{"iopub.status.busy":"2025-10-13T13:50:23.564697Z","iopub.execute_input":"2025-10-13T13:50:23.564904Z","iopub.status.idle":"2025-10-13T13:50:23.570082Z","shell.execute_reply.started":"2025-10-13T13:50:23.564888Z","shell.execute_reply":"2025-10-13T13:50:23.569338Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(qwk)","metadata":{"execution":{"iopub.status.busy":"2025-10-13T13:50:23.570703Z","iopub.execute_input":"2025-10-13T13:50:23.570903Z","iopub.status.idle":"2025-10-13T13:50:23.609770Z","shell.execute_reply.started":"2025-10-13T13:50:23.570886Z","shell.execute_reply":"2025-10-13T13:50:23.609233Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Warm up the model with class weights\nEPOCHS = 10\n\n# Use .fit() instead of .fit_generator()\nhistory = mymodel.fit(\n    train_dataset,\n    epochs=EPOCHS,\n    validation_data=val_dataset,\n    verbose=2, \n    callbacks=mycallbacks,\n    class_weight=cls_wt_dict\n)\n","metadata":{"execution":{"iopub.status.busy":"2025-10-13T13:50:23.610491Z","iopub.execute_input":"2025-10-13T13:50:23.610725Z","iopub.status.idle":"2025-10-13T14:17:42.054925Z","shell.execute_reply.started":"2025-10-13T13:50:23.610703Z","shell.execute_reply":"2025-10-13T14:17:42.054276Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"EPOCHS = 50\n\nhistory = mymodel.fit(\n    train_dataset,\n    epochs=EPOCHS,\n    validation_data=val_dataset,\n    verbose=2, \n    callbacks=mycallbacks\n)\n","metadata":{"execution":{"iopub.status.busy":"2025-10-13T14:17:42.057286Z","iopub.execute_input":"2025-10-13T14:17:42.057514Z","iopub.status.idle":"2025-10-13T15:06:30.888130Z","shell.execute_reply.started":"2025-10-13T14:17:42.057497Z","shell.execute_reply":"2025-10-13T15:06:30.887450Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Recommended for Keras 3.0+\nmymodel.save_weights(\"model.weights.h5\")\n","metadata":{"execution":{"iopub.status.busy":"2025-10-13T15:06:30.891009Z","iopub.execute_input":"2025-10-13T15:06:30.891205Z","iopub.status.idle":"2025-10-13T15:06:32.736914Z","shell.execute_reply.started":"2025-10-13T15:06:30.891190Z","shell.execute_reply":"2025-10-13T15:06:32.735756Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"Y_val_pred = mymodel.predict_on_batch(X_val)","metadata":{"execution":{"iopub.status.busy":"2025-10-13T15:06:32.738882Z","iopub.execute_input":"2025-10-13T15:06:32.739116Z","iopub.status.idle":"2025-10-13T15:07:59.674798Z","shell.execute_reply.started":"2025-10-13T15:06:32.739099Z","shell.execute_reply":"2025-10-13T15:07:59.673990Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"Y_val_pred_hot = np.argmax(Y_val_pred,axis=1)\nY_val_actual_hot = np.argmax(Y_val,axis=1)","metadata":{"execution":{"iopub.status.busy":"2025-10-13T15:07:59.691568Z","iopub.execute_input":"2025-10-13T15:07:59.691785Z","iopub.status.idle":"2025-10-13T15:07:59.696046Z","shell.execute_reply.started":"2025-10-13T15:07:59.691769Z","shell.execute_reply":"2025-10-13T15:07:59.695218Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plot_confusion_matrix(Y_val_actual_hot, Y_val_pred_hot, np.array(class_labels))","metadata":{"execution":{"iopub.status.busy":"2025-10-13T15:07:59.696852Z","iopub.execute_input":"2025-10-13T15:07:59.697418Z","iopub.status.idle":"2025-10-13T15:08:00.024485Z","shell.execute_reply.started":"2025-10-13T15:07:59.697396Z","shell.execute_reply":"2025-10-13T15:08:00.023903Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"report = classification_report(Y_val_actual_hot, Y_val_pred_hot)\nprint(\"Classification Report:\")\nprint(report)","metadata":{"execution":{"iopub.status.busy":"2025-10-13T15:08:00.025165Z","iopub.execute_input":"2025-10-13T15:08:00.025373Z","iopub.status.idle":"2025-10-13T15:08:00.037593Z","shell.execute_reply.started":"2025-10-13T15:08:00.025358Z","shell.execute_reply":"2025-10-13T15:08:00.036994Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history.history['val_loss']","metadata":{"execution":{"iopub.status.busy":"2025-10-13T15:08:00.038301Z","iopub.execute_input":"2025-10-13T15:08:00.038565Z","iopub.status.idle":"2025-10-13T15:08:00.043273Z","shell.execute_reply.started":"2025-10-13T15:08:00.038542Z","shell.execute_reply":"2025-10-13T15:08:00.042625Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history.history['val_accuracy']","metadata":{"execution":{"iopub.status.busy":"2025-10-13T15:08:00.044042Z","iopub.execute_input":"2025-10-13T15:08:00.044425Z","iopub.status.idle":"2025-10-13T15:08:00.056671Z","shell.execute_reply.started":"2025-10-13T15:08:00.044401Z","shell.execute_reply":"2025-10-13T15:08:00.055928Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(13, 7))\nplt.title(\"Loss Analysis\", fontsize=25, weight='bold', y=1.05)\nnumber_of_epochs = range(len(history.history['loss']))\nplt.plot(number_of_epochs, history.history['loss'], color='b', label=\"Training loss\", linewidth=3)\nplt.plot(number_of_epochs, history.history['val_loss'], color='g', label=\"Validation loss\", linewidth=3)\n\n\n\nplt.xlabel(\"Epochs Number\", size=20, weight='bold', y=1.05)\nplt.ylabel(\"Loss\", size=20, weight='bold', x=1.05)\nplt.xticks(size=15)\nplt.yticks(size=15)\nplt.legend()\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2025-10-13T15:08:00.057450Z","iopub.execute_input":"2025-10-13T15:08:00.057615Z","iopub.status.idle":"2025-10-13T15:08:00.237722Z","shell.execute_reply.started":"2025-10-13T15:08:00.057598Z","shell.execute_reply":"2025-10-13T15:08:00.236926Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(13, 7))\nplt.title(\"Accuracy Analysis \",fontsize=25,weight='bold',y=1.05)\nplt.plot(history.history['accuracy'], color='b', label=\"Training accuracy\")\nplt.plot(history.history['val_accuracy'], color='g',label=\"Validation accuracy\")\n\n    \nplt.xlabel(\"Epochs Number\",size=20,weight='bold',y=1.05)\nplt.ylabel(\"Accuracy\",size=20,weight='bold',x=1.05)\nplt.xticks(size =15)\nplt.yticks(size =15)\nplt.legend()\nplt.savefig(\"Accuracy   of achitechture\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2025-10-13T15:08:00.238645Z","iopub.execute_input":"2025-10-13T15:08:00.239424Z","iopub.status.idle":"2025-10-13T15:08:00.516895Z","shell.execute_reply.started":"2025-10-13T15:08:00.239395Z","shell.execute_reply":"2025-10-13T15:08:00.516192Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"weighted_accuracy = balanced_accuracy_score(Y_val_actual_hot, Y_val_pred_hot)\nprint(\"Weighted Accuracy:\", weighted_accuracy)","metadata":{"execution":{"iopub.status.busy":"2025-10-13T15:08:00.517749Z","iopub.execute_input":"2025-10-13T15:08:00.518038Z","iopub.status.idle":"2025-10-13T15:08:00.523534Z","shell.execute_reply.started":"2025-10-13T15:08:00.518012Z","shell.execute_reply":"2025-10-13T15:08:00.522755Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_data = pd.read_csv(\"../input/aptos2019-blindness-detection/test.csv\")\ntest_data[\"filename\"] = test_data[\"id_code\"].map(lambda x:x+\".png\")\ntest_data.head()","metadata":{"execution":{"iopub.status.busy":"2025-10-13T15:08:00.524333Z","iopub.execute_input":"2025-10-13T15:08:00.524993Z","iopub.status.idle":"2025-10-13T15:08:00.587147Z","shell.execute_reply.started":"2025-10-13T15:08:00.524966Z","shell.execute_reply":"2025-10-13T15:08:00.586562Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Recommended for Keras 3.0+ / TensorFlow 2.16+\nmymodel.save('my_model.keras')\n","metadata":{"execution":{"iopub.status.busy":"2025-10-13T16:51:23.328220Z","iopub.execute_input":"2025-10-13T16:51:23.328464Z","iopub.status.idle":"2025-10-13T16:51:23.348181Z","shell.execute_reply.started":"2025-10-13T16:51:23.328441Z","shell.execute_reply":"2025-10-13T16:51:23.347077Z"},"trusted":true},"outputs":[],"execution_count":null}]}