{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","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":952401,"sourceType":"datasetVersion","datasetId":517172}],"dockerImageVersionId":31090,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:29:33.712935Z","iopub.execute_input":"2025-07-15T06:29:33.713193Z","iopub.status.idle":"2025-07-15T06:29:55.644949Z","shell.execute_reply.started":"2025-07-15T06:29:33.713172Z","shell.execute_reply":"2025-07-15T06:29:55.644268Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport os\nimport shutil\n\n# Paths\ncsv_path = \"/kaggle/input/aptos2019-blindness-detection/train.csv\"\nimg_folder = \"/kaggle/input/aptos2019-blindness-detection/train_images\"\noutput_folder = \"/kaggle/working/aptos_cleaned\"\n\n# Class labels mapping\nlabel_map = {\n    0: \"No_DR\",\n    1: \"Mild\",\n    2: \"Moderate\",\n    3: \"Severe\",\n    4: \"Proliferate_DR\"\n}\n\n# Load CSV\ndf = pd.read_csv(csv_path)\n\n# Create class folders\nfor class_name in label_map.values():\n    os.makedirs(os.path.join(output_folder, class_name), exist_ok=True)\n\n# Copy images to class folders\nfor _, row in df.iterrows():\n    img_file = row['id_code'] + \".png\"\n    label = row['diagnosis']\n    class_name = label_map[label]\n\n    src_path = os.path.join(img_folder, img_file)\n    dst_path = os.path.join(output_folder, class_name, img_file)\n\n    if os.path.exists(src_path):\n        shutil.copy2(src_path, dst_path)\n\nprint(\"✅ Images copied to class folders successfully!\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:33:53.280573Z","iopub.execute_input":"2025-07-15T06:33:53.281027Z","iopub.status.idle":"2025-07-15T06:36:08.008254Z","shell.execute_reply.started":"2025-07-15T06:33:53.281005Z","shell.execute_reply":"2025-07-15T06:36:08.007500Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import shutil\nimport os\n\n# Source folders\nold_dataset = \"/kaggle/input/diabetic-retinopathy-224x224-gaussian-filtered/gaussian_filtered_images\"\nnew_dataset = \"/kaggle/working/aptos_cleaned\"\n\n# Combined target\ncombined_folder = \"/kaggle/working/combined_data\"\nos.makedirs(combined_folder, exist_ok=True)\n\n# Classes\nclasses = [\"No_DR\", \"Mild\", \"Moderate\", \"Severe\", \"Proliferate_DR\"]\n\nfor cls in classes:\n    os.makedirs(os.path.join(combined_folder, cls), exist_ok=True)\n\n    # Move old data\n    old_cls_path = os.path.join(old_dataset, cls)\n    if os.path.exists(old_cls_path):\n        for file in os.listdir(old_cls_path):\n            src = os.path.join(old_cls_path, file)\n            dst = os.path.join(combined_folder, cls, f\"old_{file}\")\n            shutil.copyfile(src, dst)\n\n    # Move new data\n    new_cls_path = os.path.join(new_dataset, cls)\n    if os.path.exists(new_cls_path):\n        for file in os.listdir(new_cls_path):\n            src = os.path.join(new_cls_path, file)\n            dst = os.path.join(combined_folder, cls, f\"new_{file}\")\n            shutil.copyfile(src, dst)\n\nprint(\"✅ Combined dataset created!\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:37:31.183400Z","iopub.execute_input":"2025-07-15T06:37:31.184168Z","iopub.status.idle":"2025-07-15T06:37:58.454786Z","shell.execute_reply.started":"2025-07-15T06:37:31.184142Z","shell.execute_reply":"2025-07-15T06:37:58.454048Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\ncombined_path = \"/kaggle/working/combined_data\"\nfor cls in os.listdir(combined_path):\n    cls_path = os.path.join(combined_path, cls)\n    print(f\"{cls} 📁 => {len(os.listdir(cls_path))} images\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:40:55.570787Z","iopub.execute_input":"2025-07-15T06:40:55.571112Z","iopub.status.idle":"2025-07-15T06:40:55.578366Z","shell.execute_reply.started":"2025-07-15T06:40:55.571089Z","shell.execute_reply":"2025-07-15T06:40:55.577818Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport cv2\nimport random\n\nfolder = \"/kaggle/working/combined_data/Mild\"\nimg_name = random.choice(os.listdir(folder))\nimg_path = os.path.join(folder, img_name)\n\nimg = cv2.imread(img_path)\nimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\nplt.imshow(img)\nplt.title(f\"Class: Mild | Image: {img_name}\")\nplt.axis('off')\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:44:22.050889Z","iopub.execute_input":"2025-07-15T06:44:22.051192Z","iopub.status.idle":"2025-07-15T06:44:23.100982Z","shell.execute_reply.started":"2025-07-15T06:44:22.051171Z","shell.execute_reply":"2025-07-15T06:44:23.100138Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport numpy as np\nimport tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import GlobalAveragePooling2D, Dropout, Dense, BatchNormalization\nfrom tensorflow.keras.applications import EfficientNetB7\nfrom tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping\nfrom sklearn.utils import class_weight\n\n# ✅ Paths & Config\ndata_dir = \"/kaggle/working/combined_data\"\nIMG_SIZE = 224\nBATCH_SIZE = 32\nEPOCHS = 8\n\n# ✅ Data Generators with Augmentation\ntrain_datagen = ImageDataGenerator(\n    validation_split=0.2,\n    rescale=1./255,\n    horizontal_flip=True,\n    zoom_range=0.2,\n    shear_range=0.2,\n    rotation_range=20\n)\n\ntrain_generator = train_datagen.flow_from_directory(\n    data_dir,\n    target_size=(IMG_SIZE, IMG_SIZE),\n    batch_size=BATCH_SIZE,\n    class_mode='categorical',\n    subset='training',\n    shuffle=True\n)\n\nval_generator = train_datagen.flow_from_directory(\n    data_dir,\n    target_size=(IMG_SIZE, IMG_SIZE),\n    batch_size=BATCH_SIZE,\n    class_mode='categorical',\n    subset='validation',\n    shuffle=False\n)\n\n# ✅ Model Architecture\nbase_model = EfficientNetB7(include_top=False, weights='imagenet', input_shape=(IMG_SIZE, IMG_SIZE, 3))\nx = base_model.output\nx = GlobalAveragePooling2D()(x)\nx = BatchNormalization()(x)\nx = Dropout(0.5)(x)\nx = Dense(256, activation='relu')(x)\nx = BatchNormalization()(x)\nx = Dropout(0.3)(x)\noutput = Dense(5, activation='softmax')(x)\n\nmodel = Model(inputs=base_model.input, outputs=output)\nmodel.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n\n# ✅ Handle Class Imbalance\nlabels = train_generator.classes\nclass_weights = class_weight.compute_class_weight(\n    class_weight='balanced',\n    classes=np.unique(labels),\n    y=labels\n)\nclass_weights_dict = dict(enumerate(class_weights))\nprint(\"✅ Class weights applied:\", class_weights_dict)\n\n# ✅ Callbacks\ncheckpoint = ModelCheckpoint(\"retina_model_best.keras\", monitor='val_accuracy', save_best_only=True, verbose=1)\nreduce_lr = ReduceLROnPlateau(monitor='val_loss', patience=2, factor=0.2, verbose=1)\nearly_stop = EarlyStopping(monitor='val_loss', patience=3, restore_best_weights=True)\n\n# ✅ Train\nhistory = model.fit(\n    train_generator,\n    validation_data=val_generator,\n    epochs=EPOCHS,\n    callbacks=[checkpoint, reduce_lr, early_stop],\n    class_weight=class_weights_dict\n)\n\n# ✅ Save clean weights\nmodel.load_weights(\"retina_model_best.keras\")\nmodel.save_weights(\"/kaggle/working/retina_dr_model_b7_weights_only_final.weights.h5\")\nprint(\"✅ .weights.h5 file saved successfully!\")\n\n# Optional: ✅ Export to TFLite\n# converter = tf.lite.TFLiteConverter.from_keras_model(model)\n# tflite_model = converter.convert()\n# with open(\"/kaggle/working/retina_model.tflite\", \"wb\") as f:\n#     f.write(tflite_model)\n# print(\"✅ .tflite model exported successfully!\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T06:44:31.075214Z","iopub.execute_input":"2025-07-15T06:44:31.075510Z","iopub.status.idle":"2025-07-15T07:45:37.839920Z","shell.execute_reply.started":"2025-07-15T06:44:31.075477Z","shell.execute_reply":"2025-07-15T07:45:37.839143Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\n\n# ⚒️ Rebuild model architecture\ndef build_model():\n    base_model = EfficientNetB7(include_top=False, weights=None, input_shape=(224, 224, 3))\n    x = base_model.output\n    x = GlobalAveragePooling2D()(x)\n    x = BatchNormalization()(x)\n    x = Dropout(0.5)(x)\n    x = Dense(256, activation='relu')(x)\n    x = BatchNormalization()(x)\n    x = Dropout(0.3)(x)\n    output = Dense(5, activation='softmax')(x)\n    return Model(inputs=base_model.input, outputs=output)\n\n# 🔄 Build & load weights\nmodel = build_model()\nmodel.load_weights(\"/kaggle/working/retina_dr_model_b7_weights_only_final.weights.h5\")\nprint(\"✅ Model rebuilt and weights loaded\")\n\n# 🎯 Convert to TFLite\nconverter = tf.lite.TFLiteConverter.from_keras_model(model)\ntflite_model = converter.convert()\n\n# 💾 Save the TFLite model\ntflite_path = \"/kaggle/working/retina_model.tflite\"\nwith open(tflite_path, \"wb\") as f:\n    f.write(tflite_model)\n\nprint(f\"✅ .tflite model saved at: {tflite_path}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T07:50:44.241386Z","iopub.execute_input":"2025-07-15T07:50:44.242137Z","iopub.status.idle":"2025-07-15T07:53:26.513241Z","shell.execute_reply.started":"2025-07-15T07:50:44.242108Z","shell.execute_reply":"2025-07-15T07:53:26.512530Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import zipfile\n\n# 📦 Zip the TFLite and Weights file\nwith zipfile.ZipFile(\"/kaggle/working/retina_model_files_final.zip\", 'w') as zipf:\n    zipf.write(\"/kaggle/working/retina_dr_model_b7_weights_only_final.weights.h5\")\n    zipf.write(\"/kaggle/working/retina_model.tflite\")\n\nprint(\"✅ Final zip created\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T07:54:01.115451Z","iopub.execute_input":"2025-07-15T07:54:01.115770Z","iopub.status.idle":"2025-07-15T07:54:04.210769Z","shell.execute_reply.started":"2025-07-15T07:54:01.115750Z","shell.execute_reply":"2025-07-15T07:54:04.210099Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\nimport os\n\nos.makedirs(\"/kaggle/working/output\", exist_ok=True)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T08:01:47.250506Z","iopub.execute_input":"2025-07-15T08:01:47.251317Z","iopub.status.idle":"2025-07-15T08:01:47.255309Z","shell.execute_reply.started":"2025-07-15T08:01:47.251295Z","shell.execute_reply":"2025-07-15T08:01:47.254473Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import shutil\n\nshutil.rmtree(\"/kaggle/working/aptos_cleaned\", ignore_errors=True)\nshutil.rmtree(\"/kaggle/working/combined_data\", ignore_errors=True)\nshutil.rmtree(\"/kaggle/working/Mild\", ignore_errors=True)\nshutil.rmtree(\"/kaggle/working/Moderate\", ignore_errors=True)\nshutil.rmtree(\"/kaggle/working/No_DR\", ignore_errors=True)\nshutil.rmtree(\"/kaggle/working/Severe\", ignore_errors=True)\nshutil.rmtree(\"/kaggle/working/Proliferate_DR\", ignore_errors=True)\n\nprint(\"✅ Unused folders removed. You should have enough space now.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T08:04:19.935226Z","iopub.execute_input":"2025-07-15T08:04:19.935548Z","iopub.status.idle":"2025-07-15T08:04:21.821601Z","shell.execute_reply.started":"2025-07-15T08:04:19.935522Z","shell.execute_reply":"2025-07-15T08:04:21.820700Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os, shutil\n\nos.makedirs(\"/kaggle/working/output\", exist_ok=True)\n\nfiles_to_copy = [\n    \"/kaggle/working/retina_dr_model_b7_weights_only_final.weights.h5\",\n    \"/kaggle/working/retina_model.tflite\",\n    \"/kaggle/working/retina_model_best.keras\",\n    \"/kaggle/working/retina_model_files_final.zip\"\n]\n\nfor file in files_to_copy:\n    shutil.copy(file, \"/kaggle/working/output\")\n\nprint(\"✅ All files copied to /kaggle/working/output/\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-15T08:04:54.686168Z","iopub.execute_input":"2025-07-15T08:04:54.686675Z","iopub.status.idle":"2025-07-15T08:04:57.826109Z","shell.execute_reply.started":"2025-07-15T08:04:54.686634Z","shell.execute_reply":"2025-07-15T08:04:57.825120Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}