{"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-20T09:31:38.319402Z","iopub.execute_input":"2026-02-20T09:31:38.319939Z","iopub.status.idle":"2026-02-20T09:31:46.253282Z","shell.execute_reply.started":"2026-02-20T09:31:38.319913Z","shell.execute_reply":"2026-02-20T09:31:46.252589Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport cv2\nimport os\nfrom tqdm import tqdm\nimport matplotlib.pyplot as plt\n\nfrom sklearn.model_selection import train_test_split\nimport tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-20T09:31:46.254554Z","iopub.execute_input":"2026-02-20T09:31:46.254764Z","iopub.status.idle":"2026-02-20T09:31:46.259579Z","shell.execute_reply.started":"2026-02-20T09:31:46.254745Z","shell.execute_reply":"2026-02-20T09:31:46.259046Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df = pd.read_csv(\"/kaggle/input/aptos2019-blindness-detection/train.csv\")\ntrain_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-20T09:31:46.260504Z","iopub.execute_input":"2026-02-20T09:31:46.260767Z","iopub.status.idle":"2026-02-20T09:31:46.292663Z","shell.execute_reply.started":"2026-02-20T09:31:46.260743Z","shell.execute_reply":"2026-02-20T09:31:46.292108Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"IMG_SIZE = 224\n\nX = []\ny = []\n\nfor i in tqdm(range(len(train_df))):\n    img_name = train_df['id_code'][i] + \".png\"\n    label = train_df['diagnosis'][i]\n\n    img_path = \"/kaggle/input/aptos2019-blindness-detection/train_images/\" + img_name\n    img = cv2.imread(img_path)\n\n    if img is None:\n        continue\n\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))\n\n    X.append(img)\n    y.append(label)\n\nX = np.array(X)\ny = np.array(y)\n\nprint(\"Shape of X:\", X.shape)\nprint(\"Shape of y:\", y.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-20T09:31:46.293391Z","iopub.execute_input":"2026-02-20T09:31:46.293646Z","iopub.status.idle":"2026-02-20T09:37:37.127103Z","shell.execute_reply.started":"2026-02-20T09:31:46.293627Z","shell.execute_reply":"2026-02-20T09:37:37.126405Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X = X / 255.0","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-20T09:37:37.129077Z","iopub.execute_input":"2026-02-20T09:37:37.129651Z","iopub.status.idle":"2026-02-20T09:37:38.460938Z","shell.execute_reply.started":"2026-02-20T09:37:37.129626Z","shell.execute_reply":"2026-02-20T09:37:38.460134Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train, X_val, y_train, y_val = train_test_split(\n    X, y, test_size=0.2, stratify=y, random_state=42\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-20T09:37:38.461840Z","iopub.execute_input":"2026-02-20T09:37:38.462204Z","iopub.status.idle":"2026-02-20T09:37:39.761108Z","shell.execute_reply.started":"2026-02-20T09:37:38.462179Z","shell.execute_reply":"2026-02-20T09:37:39.760561Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\n\n# تأكدي من تعريف عدد الكلاسات (Classes)\nnum_classes = 5 \n\nmodel = tf.keras.Sequential([\n    # الطبقة الأولى\n    tf.keras.layers.Conv2D(128, (5,5), padding=\"same\", input_shape=(224,224,3), activation='relu'),\n    tf.keras.layers.MaxPooling2D(pool_size=(2,2)),\n    \n    # الطبقة الثانية\n    tf.keras.layers.Conv2D(128, (5,5), padding=\"same\", activation='relu'),\n    tf.keras.layers.MaxPooling2D(pool_size=(2,2)),\n    \n    # الطبقة الثالثة\n    tf.keras.layers.Conv2D(128, (5,5), padding=\"same\", activation='relu'),\n    tf.keras.layers.MaxPooling2D(pool_size=(2,2)),\n    \n    # الطبقة الرابعة\n    tf.keras.layers.Conv2D(128, (5,5), padding=\"same\", activation='relu'),\n    tf.keras.layers.MaxPooling2D(pool_size=(2,2)),\n    \n    # التحويل لمصفوفة أحادية\n    tf.keras.layers.Flatten(),\n    \n    # الطبقات الكثيفة (Dense)\n    tf.keras.layers.Dense(512, activation=\"selu\", kernel_initializer=\"lecun_normal\"), \n    tf.keras.layers.Dropout(0.5),\n    \n    tf.keras.layers.Dense(256, activation=\"selu\", kernel_initializer=\"lecun_normal\"), \n    tf.keras.layers.Dropout(0.5),\n    \n    tf.keras.layers.Dense(128, activation=\"selu\", kernel_initializer=\"lecun_normal\"), \n    tf.keras.layers.Dropout(0.5),\n    \n    # طبقة المخرجات\n    tf.keras.layers.Dense(num_classes, activation='softmax')\n])\n\n# الإعدادات (Compile)\nmodel.compile(\n    optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4, beta_1=0.9, beta_2=0.999),\n    loss=tf.keras.losses.SparseCategoricalCrossentropy(),\n    metrics=['accuracy']\n)\n\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-20T09:37:39.761977Z","iopub.execute_input":"2026-02-20T09:37:39.762210Z","iopub.status.idle":"2026-02-20T09:37:39.848587Z","shell.execute_reply.started":"2026-02-20T09:37:39.762190Z","shell.execute_reply":"2026-02-20T09:37:39.848059Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\n# تقسيم البيانات: 80% تدريب و 20% تحقق\nX_train, X_val, y_train, y_val = train_test_split(\n    X, y, \n    test_size=0.2, \n    random_state=42, \n    stratify=y  # لضمان توزيع نسب الأمراض بالتساوي في المجموعتين\n)\n\nprint(f\"عدد صور التدريب: {len(X_train)}\")\nprint(f\"عدد صور التحقق: {len(X_val)}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-20T09:37:39.849374Z","iopub.execute_input":"2026-02-20T09:37:39.849600Z","iopub.status.idle":"2026-02-20T09:37:41.120549Z","shell.execute_reply.started":"2026-02-20T09:37:39.849581Z","shell.execute_reply":"2026-02-20T09:37:41.119806Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\n\n# 1. تعريف التوقف المبكر لمراقبة خسارة التحقق (val_loss)\nearly_stopping = tf.keras.callbacks.EarlyStopping(\n    monitor='val_loss',      # مراقبة الخسارة في بيانات التحقق\n    patience=5,              # التوقف إذا لم يتحسن الموديل لمدة 5 دورات متتالية\n    restore_best_weights=True # استعادة أوزان الدورة التي حققت أفضل نتيجة\n)\n\n# 2. تعريف حفظ أفضل نسخة من الموديل تلقائياً\ncheckpoint = tf.keras.callbacks.ModelCheckpoint(\n    'best_model.h5', \n    monitor='val_accuracy', \n    save_best_only=True, \n    mode='max'\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-20T09:37:41.121770Z","iopub.execute_input":"2026-02-20T09:37:41.122012Z","iopub.status.idle":"2026-02-20T09:37:41.126552Z","shell.execute_reply.started":"2026-02-20T09:37:41.121991Z","shell.execute_reply":"2026-02-20T09:37:41.125824Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history = model.fit(\n    X_train, y_train,\n    validation_data=(X_val, y_val),\n    epochs=50,\n    batch_size=16,\n    callbacks=[early_stopping, checkpoint]\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-20T09:37:41.127387Z","iopub.execute_input":"2026-02-20T09:37:41.127585Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\nmodel.save('final_model.keras')\nprint(\"تم الحفظ\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# رسم منحنيات الأداء\nplt.figure(figsize=(12, 5))\n\n# منحنى الدقة\nplt.subplot(1, 2, 1)\nplt.plot(history.history['accuracy'], label='Train Accuracy', color='blue')\nplt.plot(history.history['val_accuracy'], label='Val Accuracy', color='orange')\nplt.title('Model Accuracy')\nplt.legend()\n\n# منحنى الخسارة\nplt.subplot(1, 2, 2)\nplt.plot(history.history['loss'], label='Train Loss', color='blue')\nplt.plot(history.history['val_loss'], label='Val Loss', color='orange')\nplt.title('Model Loss')\nplt.legend()\n\nplt.show()","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}