{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceType":"competition","sourceId":14774,"databundleVersionId":875431}],"dockerImageVersionId":31286,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"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":"2026-02-25T18:04:48.262938Z","iopub.execute_input":"2026-02-25T18:04:48.263286Z","iopub.status.idle":"2026-02-25T18:04:53.864936Z","shell.execute_reply.started":"2026-02-25T18:04:48.263258Z","shell.execute_reply":"2026-02-25T18:04:53.863959Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport cv2\nimport os\nimport numpy as np\nfrom sklearn.model_selection import train_test_split\n\n# المسارات\ncsv_path = '/kaggle/input/aptos2019-blindness-detection/train.csv'\nimg_path = '/kaggle/input/aptos2019-blindness-detection/train_images'\n\ndf = pd.read_csv(csv_path)\n\ndef prepare_images(df, img_path, img_size=224):\n    X, y = [], []\n    for idx, row in df.iterrows():\n        file_path = os.path.join(img_path, f\"{row['id_code']}.png\")\n        if os.path.exists(file_path):\n            img = cv2.imread(file_path)\n            img = cv2.resize(img, (img_size, img_size))\n            X.append(img)\n            y.append(row['diagnosis'])\n        if len(X) >= 2000: break \n    return np.array(X) / 255.0, np.array(y)\n\nX, y = prepare_images(df, img_path)\nX_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)\n\nprint(f\"✅ تم التحميل! تدريب: {len(X_train)}, تحقق: {len(X_val)}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-25T18:04:53.866839Z","iopub.execute_input":"2026-02-25T18:04:53.867350Z","iopub.status.idle":"2026-02-25T18:08:31.163944Z","shell.execute_reply.started":"2026-02-25T18:04:53.867315Z","shell.execute_reply":"2026-02-25T18:08:31.163034Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras import layers, models, optimizers\n\n# 1. تحميل الأساس (Base Model)\nbase_model = tf.keras.applications.EfficientNetB4(weights='imagenet', include_top=False, input_shape=(224, 224, 3))\nbase_model.trainable = True \n\n# 2. إضافة الطبقات المحسنة (لحل مشكلة الـ Overfitting)\nmodel_b4 = models.Sequential([\n    base_model,\n    layers.GlobalAveragePooling2D(),\n    layers.BatchNormalization(),\n    layers.Dropout(0.5), # هذا التعديل الأساسي لتقليل الفجوة بين الخطين\n    layers.Dense(512, activation='relu'),\n    layers.BatchNormalization(),\n    layers.Dropout(0.3),\n    layers.Dense(5, activation='softmax')\n])\n\n# 3. تجميع الموديل (Compiling)\nmodel_b4.compile(\n    optimizer=optimizers.Adam(learning_rate=1e-4), \n    loss='sparse_categorical_crossentropy', \n    metrics=['accuracy']\n)\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-25T19:22:12.109869Z","iopub.execute_input":"2026-02-25T19:22:12.110146Z","iopub.status.idle":"2026-02-25T19:22:14.102465Z","shell.execute_reply.started":"2026-02-25T19:22:12.110116Z","shell.execute_reply":"2026-02-25T19:22:14.101706Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.utils import class_weight\nimport numpy as np\n\n\nweights = class_weight.compute_class_weight('balanced', classes=np.unique(y_train), y=y_train)\nclass_weights_dict = dict(enumerate(weights))\n\n# 2. بدء التدريب\nhistory_b4 = model_b4.fit(\n    X_train, y_train,\n    epochs=15, \n    validation_data=(X_val, y_val),\n    class_weight=class_weights_dict,\n    batch_size=32\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-25T19:22:19.747608Z","iopub.execute_input":"2026-02-25T19:22:19.748208Z","iopub.status.idle":"2026-02-25T19:28:45.843153Z","shell.execute_reply.started":"2026-02-25T19:22:19.748177Z","shell.execute_reply":"2026-02-25T19:28:45.842210Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nplt.figure(figsize=(12, 5))\n# رسم الدقة\nplt.subplot(1, 2, 1)\nplt.plot(history_b4.history['accuracy'], label='Train Acc')\nplt.plot(history_b4.history['val_accuracy'], label='Val Acc')\nplt.title('Model Accuracy')\nplt.legend()\n\n# رسم الخسارة\nplt.subplot(1, 2, 2)\nplt.plot(history_b4.history['loss'], label='Train Loss')\nplt.plot(history_b4.history['val_loss'], label='Val Loss')\nplt.title('Model Loss')\nplt.legend()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-25T19:28:57.709111Z","iopub.execute_input":"2026-02-25T19:28:57.709688Z","iopub.status.idle":"2026-02-25T19:28:57.958159Z","shell.execute_reply.started":"2026-02-25T19:28:57.709658Z","shell.execute_reply":"2026-02-25T19:28:57.954187Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import confusion_matrix\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n# 1. حساب التوقعات\ny_pred = model_b4.predict(X_val)\ny_pred_classes = np.argmax(y_pred, axis=1)\n\n# 2. إنشاء مصفوفة الارتباك\ncm = confusion_matrix(y_val, y_pred_classes)\n\n# 3. رسم المصفوفة\nplt.figure(figsize=(10, 8))\nsns.heatmap(cm, annot=True, fmt='d', cmap='Blues',\n            xticklabels=['No DR', 'Mild', 'Moderate', 'Severe', 'Proliferative'],\n            yticklabels=['No DR', 'Mild', 'Moderate', 'Severe', 'Proliferative'])\n\nplt.title('Confusion Matrix - EfficientNetB4', fontsize=15)\nplt.ylabel('Actual Label ()', fontsize=12)\nplt.xlabel('Predicted Label ()', fontsize=12)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-25T19:29:10.103805Z","iopub.execute_input":"2026-02-25T19:29:10.104443Z","iopub.status.idle":"2026-02-25T19:29:34.729400Z","shell.execute_reply.started":"2026-02-25T19:29:10.104415Z","shell.execute_reply":"2026-02-25T19:29:34.728547Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import precision_score, recall_score, f1_score\nimport numpy as np\n\n# 1. استخراج التوقعات بناءً على الموديل الحالي\ny_pred = model_b4.predict(X_val)\ny_pred_classes = np.argmax(y_pred, axis=1)\n\n# 2. حساب القيم الثلاث (المتوسط العام للموديل Macro Average)\nprecision_val = precision_score(y_val, y_pred_classes, average='macro')\nrecall_val = recall_score(y_val, y_pred_classes, average='macro')\nf1_val = f1_score(y_val, y_pred_classes, average='macro')\n\nprint(\"📊 نتائج الأداء النهائية للموديل:\")\nprint(\"-\" * 35)\nprint(f\"🎯 Precision (الدقة المحددة): {precision_val*100:.2f}%\")\nprint(f\"🔍 Recall (الاستدعاء الطبي): {recall_val*100:.2f}%\")\nprint(f\"⚖️ F1-Score (التوازن العام): {f1_val*100:.2f}%\")\nprint(\"-\" * 35)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-25T19:29:41.685767Z","iopub.execute_input":"2026-02-25T19:29:41.686298Z","iopub.status.idle":"2026-02-25T19:29:43.276089Z","shell.execute_reply.started":"2026-02-25T19:29:41.686272Z","shell.execute_reply":"2026-02-25T19:29:43.275382Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_b4.save('/kaggle/working/EfficientB4_Final_97.keras')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-25T18:58:15.503280Z","iopub.execute_input":"2026-02-25T18:58:15.503700Z","iopub.status.idle":"2026-02-25T18:58:17.606423Z","shell.execute_reply.started":"2026-02-25T18:58:15.503671Z","shell.execute_reply":"2026-02-25T18:58:17.605801Z"}},"outputs":[],"execution_count":null}]}