{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceType":"competition","sourceId":4104,"databundleVersionId":46661},{"sourceType":"datasetVersion","sourceId":265751,"datasetId":110097,"databundleVersionId":277918},{"sourceType":"datasetVersion","sourceId":2269470,"datasetId":1366461,"databundleVersionId":2310528}],"dockerImageVersionId":30163,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import torch\n\ntorch.cuda.is_available()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-05T19:25:00.580002Z","iopub.execute_input":"2026-03-05T19:25:00.580288Z","iopub.status.idle":"2026-03-05T19:25:00.586504Z","shell.execute_reply.started":"2026-03-05T19:25:00.580251Z","shell.execute_reply":"2026-03-05T19:25:00.585738Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport glob\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport tensorflow.keras.backend as K\nimport itertools\nimport seaborn as sns\nfrom tensorflow.keras.applications import ResNet50\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.losses import SparseCategoricalCrossentropy\nfrom tensorflow.keras.layers import Dense, Flatten\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.callbacks import EarlyStopping\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.data import Dataset\nfrom skimage.io import imread\nfrom sklearn.metrics import *\nfrom sklearn.model_selection import *\nfrom skimage.io import *\nfrom glob import glob\nimport warnings\n\n\nwarnings.filterwarnings('ignore')\nprint(\"Necessary modules have been imported\")\n","metadata":{"execution":{"iopub.status.busy":"2026-03-05T19:26:14.260503Z","iopub.execute_input":"2026-03-05T19:26:14.260832Z","iopub.status.idle":"2026-03-05T19:26:21.092210Z","shell.execute_reply.started":"2026-03-05T19:26:14.260794Z","shell.execute_reply":"2026-03-05T19:26:21.091265Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\ndef parse_image(filename, label):\n    image = tf.io.read_file(filename)\n    image = tf.image.decode_jpeg(image, channels=3)\n    image = tf.image.resize(image, [224, 224])\n    image = image / 255.0\n    return image, label\n\n\ndef load_dataset(file_paths, labels, batch_size=32):\n    dataset = Dataset.from_tensor_slices((file_paths, labels))\n    dataset = dataset.map(parse_image, num_parallel_calls=tf.data.AUTOTUNE)\n    dataset = dataset.shuffle(buffer_size=len(file_paths)).batch(batch_size)\n    dataset = dataset.prefetch(buffer_size=tf.data.AUTOTUNE)\n    return dataset\n","metadata":{"execution":{"iopub.status.busy":"2026-03-05T19:26:55.031984Z","iopub.execute_input":"2026-03-05T19:26:55.032621Z","iopub.status.idle":"2026-03-05T19:26:55.038342Z","shell.execute_reply.started":"2026-03-05T19:26:55.032586Z","shell.execute_reply":"2026-03-05T19:26:55.037590Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Importing labels","metadata":{}},{"cell_type":"code","source":"\n!unzip -o ../input/diabetic-retinopathy-detection/trainLabels.csv.zip\ntrainLabels = pd.read_csv(\"./trainLabels.csv\")\n","metadata":{"execution":{"iopub.status.busy":"2026-03-05T19:26:58.827187Z","iopub.execute_input":"2026-03-05T19:26:58.827458Z","iopub.status.idle":"2026-03-05T19:26:59.971409Z","shell.execute_reply.started":"2026-03-05T19:26:58.827427Z","shell.execute_reply":"2026-03-05T19:26:59.970454Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!apt install p7zip-full -y\n!7z x ../input/diabetic-retinopathy-detection/train.zip.001 \"-i!train/11*.jpeg\" -y \n# restrict extracted file to about 100 for the disk restriction\n!mkdir data\n!mv train data/train_11\n","metadata":{"execution":{"iopub.status.busy":"2026-03-05T19:27:03.632772Z","iopub.execute_input":"2026-03-05T19:27:03.633799Z","iopub.status.idle":"2026-03-05T19:27:36.389251Z","shell.execute_reply.started":"2026-03-05T19:27:03.633732Z","shell.execute_reply":"2026-03-05T19:27:36.388300Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 獲取所有圖像文件路徑\nfile_paths = glob(\"./data/train_11/*.jpeg\")\n\n# 假設file_paths包含圖像的完整路徑，從中提取圖像的基礎名稱\nfile_basenames = [os.path.basename(f).replace(\".jpeg\", \"\") for f in file_paths]\n\n# 根據文件名來篩選出對應的標籤\nfiltered_labels = trainLabels[trainLabels['image'].isin(file_basenames)]['level'].values\n\n# 確認file_paths與filtered_labels的數量相同\nprint(f\"Number of image files: {len(file_paths)}\")\nprint(f\"Number of filtered labels: {len(filtered_labels)}\")\n\n# 加載數據集\ndataset = load_dataset(file_paths, filtered_labels)","metadata":{"execution":{"iopub.status.busy":"2026-03-05T19:27:45.265337Z","iopub.execute_input":"2026-03-05T19:27:45.266027Z","iopub.status.idle":"2026-03-05T19:27:50.738234Z","shell.execute_reply.started":"2026-03-05T19:27:45.265990Z","shell.execute_reply":"2026-03-05T19:27:50.737382Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nprint(\"GPU Available:\", torch.cuda.is_available())\n\nimport os\nimport glob\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\nimport tensorflow.keras.backend as K\nimport warnings\n\nfrom tensorflow.keras.applications import ResNet50\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.losses import SparseCategoricalCrossentropy\nfrom tensorflow.keras.layers import Dense, Flatten\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.callbacks import EarlyStopping\nfrom tensorflow.data import Dataset\nfrom sklearn.model_selection import train_test_split\n\nwarnings.filterwarnings('ignore')\n\nprint(\"Necessary modules have been imported\")\n\n############################################################\n# IMAGE PARSING FUNCTION\n############################################################\n\ndef parse_image(filename, label):\n    \n    image = tf.io.read_file(filename)\n    image = tf.image.decode_jpeg(image, channels=3)\n    \n    image = tf.image.resize(image, [224,224])\n    image = image / 255.0\n    \n    return image, label\n\n############################################################\n# DATASET LOADER\n############################################################\n\ndef load_dataset(file_paths, labels, batch_size=32):\n    \n    dataset = Dataset.from_tensor_slices((file_paths, labels))\n    \n    dataset = dataset.map(parse_image,\n                          num_parallel_calls=tf.data.AUTOTUNE)\n    \n    dataset = dataset.shuffle(buffer_size=len(file_paths))\n    \n    dataset = dataset.batch(batch_size)\n    \n    dataset = dataset.prefetch(buffer_size=tf.data.AUTOTUNE)\n    \n    return dataset\n\n############################################################\n# EXTRACT LABEL CSV\n############################################################\n\n!unzip -o ../input/diabetic-retinopathy-detection/trainLabels.csv.zip\n\ntrainLabels = pd.read_csv(\"trainLabels.csv\")\n\n############################################################\n# INSTALL 7ZIP\n############################################################\n\n!apt install p7zip-full -y\n\n############################################################\n# EXTRACT SMALL SUBSET OF IMAGES\n############################################################\n\n!7z x ../input/diabetic-retinopathy-detection/train.zip.001 \"-i!train/11*.jpeg\" -y\n\n############################################################\n# MOVE IMAGES\n############################################################\n\n!mkdir -p data\n!mv train data/train_11\n\n############################################################\n# GET IMAGE PATHS\n############################################################\n\nfile_paths = glob.glob(\"./data/train_11/*.jpeg\")\n\nprint(\"Total images extracted:\", len(file_paths))\n\n############################################################\n# MATCH LABELS WITH FILENAMES\n############################################################\n\nfile_basenames = [os.path.basename(f).replace(\".jpeg\",\"\") for f in file_paths]\n\nfiltered_df = trainLabels[trainLabels['image'].isin(file_basenames)]\n\nfiltered_df = filtered_df.set_index(\"image\").loc[file_basenames]\n\nlabels = filtered_df[\"level\"].values\n\nprint(\"Matched labels:\", len(labels))\n\n############################################################\n# TRAIN VALIDATION SPLIT\n############################################################\n\ntrain_paths, val_paths, train_labels, val_labels = train_test_split(\n    file_paths,\n    labels,\n    test_size=0.2,\n    random_state=42\n)\n\n############################################################\n# CREATE DATASETS\n############################################################\n\ntrain_dataset = load_dataset(train_paths, train_labels)\nval_dataset = load_dataset(val_paths, val_labels)\n\n############################################################\n# BUILD MODEL\n############################################################\n\nbase_model = ResNet50(\n    weights=\"imagenet\",\n    include_top=False,\n    input_shape=(224,224,3)\n)\n\nbase_model.trainable = False\n\nmodel = Sequential([\n    base_model,\n    Flatten(),\n    Dense(128, activation=\"relu\"),\n    Dense(5, activation=\"softmax\")\n])\n\n############################################################\n# COMPILE MODEL\n############################################################\n\nmodel.compile(\n    optimizer=Adam(learning_rate=0.0001),\n    loss=SparseCategoricalCrossentropy(),\n    metrics=[\"accuracy\"]\n)\n\n############################################################\n# TRAIN MODEL\n############################################################\n\nearly_stop = EarlyStopping(\n    monitor=\"val_loss\",\n    patience=3,\n    restore_best_weights=True\n)\n\nhistory = model.fit(\n    train_dataset,\n    validation_data=val_dataset,\n    epochs=10,\n    callbacks=[early_stop]\n)\n\n############################################################\n# SAVE MODEL\n############################################################\n\nmodel.save(\"retinopathy_model.h5\")\n\nprint(\"Training complete\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-05T19:31:27.973540Z","iopub.execute_input":"2026-03-05T19:31:27.973893Z","iopub.status.idle":"2026-03-05T19:34:02.055172Z","shell.execute_reply.started":"2026-03-05T19:31:27.973855Z","shell.execute_reply":"2026-03-05T19:34:02.054173Z"}},"outputs":[],"execution_count":null}]}