{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"dockerImageVersionId":28755,"isInternetEnabled":false,"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\n# import numpy as np # linear algebra\n# import 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\n# import os\n# for 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\n\n# # Use the kagglehub client library to attach Kaggle resources like competitions, datasets, and models to your session\n# # Learn more about kagglehub: https://github.com/Kaggle/kagglehub/blob/main/README.md\n\n# import kagglehub\n# # kagglehub.dataset_download('<owner>/<dataset-slug>')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import keras\nimport matplotlib.pyplot as plt\nimport pandas as pd\nimport numpy as np\nimport tensorflow as tf\nfrom keras import layers\nfrom sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay\nfrom sklearn.model_selection import train_test_split","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:44:50.602299Z","iopub.execute_input":"2026-07-10T22:44:50.602906Z","iopub.status.idle":"2026-07-10T22:44:50.607531Z","shell.execute_reply.started":"2026-07-10T22:44:50.602876Z","shell.execute_reply":"2026-07-10T22:44:50.606631Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"keras.utils.set_random_seed(42)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:45:00.559576Z","iopub.execute_input":"2026-07-10T22:45:00.559835Z","iopub.status.idle":"2026-07-10T22:45:00.566413Z","shell.execute_reply.started":"2026-07-10T22:45:00.559813Z","shell.execute_reply":"2026-07-10T22:45:00.565374Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load the data\ntrain = pd.read_csv(\"/kaggle/input/competitions/digit-recognizer/train.csv\")\ntest = pd.read_csv(\"/kaggle/input/competitions/digit-recognizer/test.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:45:03.717267Z","iopub.execute_input":"2026-07-10T22:45:03.718010Z","iopub.status.idle":"2026-07-10T22:45:06.664004Z","shell.execute_reply.started":"2026-07-10T22:45:03.717979Z","shell.execute_reply":"2026-07-10T22:45:06.662947Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# الطريقة الاحترافية الفائقة: سحب عمود التارجت وحذفه من الأصل في سطر واحد دون نسخ!\nY_train = train.pop(\"label\")\n\n# الآن أصبح المتغير train يحتوي على الصور فقط بدون عمود الـ label\nX_train = train","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:45:09.185257Z","iopub.execute_input":"2026-07-10T22:45:09.186148Z","iopub.status.idle":"2026-07-10T22:45:09.201528Z","shell.execute_reply.started":"2026-07-10T22:45:09.186115Z","shell.execute_reply":"2026-07-10T22:45:09.200361Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"Y_train.value_counts().plot(kind=\"bar\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:45:13.456355Z","iopub.execute_input":"2026-07-10T22:45:13.456973Z","iopub.status.idle":"2026-07-10T22:45:13.583710Z","shell.execute_reply.started":"2026-07-10T22:45:13.456943Z","shell.execute_reply":"2026-07-10T22:45:13.582831Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"Y_train.value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:45:20.212321Z","iopub.execute_input":"2026-07-10T22:45:20.212606Z","iopub.status.idle":"2026-07-10T22:45:20.220219Z","shell.execute_reply.started":"2026-07-10T22:45:20.212583Z","shell.execute_reply":"2026-07-10T22:45:20.219115Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train.isnull().any().describe()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:45:27.268282Z","iopub.execute_input":"2026-07-10T22:45:27.268917Z","iopub.status.idle":"2026-07-10T22:45:27.299231Z","shell.execute_reply.started":"2026-07-10T22:45:27.268888Z","shell.execute_reply":"2026-07-10T22:45:27.298555Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test.isnull().any().describe()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:45:30.323932Z","iopub.execute_input":"2026-07-10T22:45:30.324527Z","iopub.status.idle":"2026-07-10T22:45:30.337927Z","shell.execute_reply.started":"2026-07-10T22:45:30.324498Z","shell.execute_reply":"2026-07-10T22:45:30.336977Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Normalize the data\nX_train = X_train / 255.0\ntest = test / 255.0","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:45:35.092633Z","iopub.execute_input":"2026-07-10T22:45:35.092898Z","iopub.status.idle":"2026-07-10T22:45:35.200747Z","shell.execute_reply.started":"2026-07-10T22:45:35.092877Z","shell.execute_reply":"2026-07-10T22:45:35.200034Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train, X_val, Y_train, Y_val = train_test_split(\n    X_train, Y_train, test_size=0.1, random_state=42, stratify=Y_train\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:45:38.588508Z","iopub.execute_input":"2026-07-10T22:45:38.589092Z","iopub.status.idle":"2026-07-10T22:45:39.056329Z","shell.execute_reply.started":"2026-07-10T22:45:38.589065Z","shell.execute_reply":"2026-07-10T22:45:39.055446Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"Y_train = keras.ops.one_hot(Y_train, num_classes=10)\nY_val = keras.ops.one_hot(Y_val, num_classes=10)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:45:43.181247Z","iopub.execute_input":"2026-07-10T22:45:43.181856Z","iopub.status.idle":"2026-07-10T22:45:43.191671Z","shell.execute_reply.started":"2026-07-10T22:45:43.181816Z","shell.execute_reply":"2026-07-10T22:45:43.190724Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.imshow(X_train.to_numpy()[0].reshape(28, 28))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:45:47.427202Z","iopub.execute_input":"2026-07-10T22:45:47.427786Z","iopub.status.idle":"2026-07-10T22:45:47.609712Z","shell.execute_reply.started":"2026-07-10T22:45:47.427756Z","shell.execute_reply":"2026-07-10T22:45:47.608985Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"batch_size = 64  # تصغير الحجم قليلاً يعطي تحديثات أدق للأوزان\nepochs = 35","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:45:56.685895Z","iopub.execute_input":"2026-07-10T22:45:56.686576Z","iopub.status.idle":"2026-07-10T22:45:56.690016Z","shell.execute_reply.started":"2026-07-10T22:45:56.686546Z","shell.execute_reply":"2026-07-10T22:45:56.689259Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data_augmentation = keras.Sequential(\n    [\n        # 🌟 خطوة هامة جداً: إعادة تشكيل البيانات المفرودة إلى أبعاد صورة قبل التعديل العشوائي\n        layers.Reshape((28, 28, 1)),\n        # الآن طبقات الزيادة ستعمل بأمان وبدون أي أخطاء\n        layers.RandomRotation(\n            factor=8 / 360, fill_mode=\"constant\", fill_value=0.0\n        ),\n        layers.RandomZoom(\n            height_factor=0.08,\n            width_factor=0.08,\n            fill_mode=\"constant\",\n            fill_value=0.0,\n        ),\n        layers.RandomTranslation(\n            height_factor=0.08,\n            width_factor=0.08,\n            fill_mode=\"constant\",\n            fill_value=0.0,\n        ),\n    ]\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:45:59.867342Z","iopub.execute_input":"2026-07-10T22:45:59.867623Z","iopub.status.idle":"2026-07-10T22:45:59.885197Z","shell.execute_reply.started":"2026-07-10T22:45:59.867600Z","shell.execute_reply":"2026-07-10T22:45:59.884642Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_dataset = (\n    tf.data.Dataset.from_tensor_slices((X_train, Y_train))\n    .shuffle(buffer_size=2048)\n    .batch(batch_size)\n    # هنا يتم استدعاء دالة التعديل (التي تقوم بالـ Reshape الآن تلقائياً للتدريب)\n    .map(\n        lambda x, y: (data_augmentation(x, training=True), y),\n        num_parallel_calls=tf.data.AUTOTUNE,\n    )\n    .prefetch(tf.data.AUTOTUNE)\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:46:02.862228Z","iopub.execute_input":"2026-07-10T22:46:02.863027Z","iopub.status.idle":"2026-07-10T22:46:03.765334Z","shell.execute_reply.started":"2026-07-10T22:46:02.862996Z","shell.execute_reply":"2026-07-10T22:46:03.764750Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"val_dataset = (\n    tf.data.Dataset.from_tensor_slices((X_val, Y_val))\n    .batch(batch_size)\n    # إعادة تشكيل بيانات التحقق لتصبح 3D متوافقة مع مدخلات الـ CNN\n    .map(\n        lambda x, y: (layers.Reshape((28, 28, 1))(x), y),\n        num_parallel_calls=tf.data.AUTOTUNE,\n    )\n    .prefetch(tf.data.AUTOTUNE)\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:46:06.472070Z","iopub.execute_input":"2026-07-10T22:46:06.472816Z","iopub.status.idle":"2026-07-10T22:46:06.544793Z","shell.execute_reply.started":"2026-07-10T22:46:06.472774Z","shell.execute_reply":"2026-07-10T22:46:06.544153Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# ==========================================\n# 3. بنية الشبكة الاحترافية (Modern CNN Architecture)\n# ==========================================\nmodel = keras.Sequential(\n    [\n        # 1. استقبال المدخلات ثلاثية الأبعاد القادمة من الـ Dataset المعدل\n        keras.Input(shape=(28, 28, 1)),\n        # 2. خطوة التقييس (القسمة على 255) داخل النموذج لضمان الاستقلالية التامة\n        layers.Rescaling(scale=1.0 / 255.0),\n        # ------------------------------------------\n        # الكتلة الالتفافية الأولى (Block 1) - استخراج الميزات الأولية (الحواف والخطوط)\n        # ------------------------------------------\n        layers.Conv2D(64, kernel_size=(3, 3), padding=\"same\", use_bias=False),\n        layers.BatchNormalization(),  # تسريع التدريب وتثبيت الأوزان\n        layers.Activation(\"relu\"),\n        layers.Conv2D(64, kernel_size=(3, 3), padding=\"same\", use_bias=False),\n        layers.BatchNormalization(),\n        layers.Activation(\"relu\"),\n        layers.MaxPool2D(pool_size=(2, 2)),  # تقليص الأبعاد إلى 14x14\n        layers.Dropout(0.25),  # مكافحة الأوفرالفيتينج بنسبة 25%\n        # ------------------------------------------\n        # الكتلة الالتفافية الثانية (Block 2) - استخراج الميزات المعقدة (المنحنيات والزوايا)\n        # ------------------------------------------\n        layers.Conv2D(128, kernel_size=(3, 3), padding=\"same\", use_bias=False),\n        layers.BatchNormalization(),\n        layers.Activation(\"relu\"),\n        layers.Conv2D(128, kernel_size=(3, 3), padding=\"same\", use_bias=False),\n        layers.BatchNormalization(),\n        layers.Activation(\"relu\"),\n        layers.MaxPool2D(pool_size=(2, 2)),  # تقليص الأبعاد إلى 7x7\n        layers.Dropout(0.35),  # زيادة قوة إسقاط الخلايا لمنع الحفظ العشوائي\n        # ------------------------------------------\n        # الكتلة الالتفافية الثالثة (Block 3) - تعميق الفهم للميزات العالية المستوى\n        # ------------------------------------------\n        layers.Conv2D(256, kernel_size=(3, 3), padding=\"same\", use_bias=False),\n        layers.BatchNormalization(),\n        layers.Activation(\"relu\"),\n        # ------------------------------------------\n        # الرأس التصنيفي الحديث (Modern Classification Head)\n        # ------------------------------------------\n        # بديل Flatten الاحترافي؛ يمنع التضخم الهائل للأوزان ويحمي النموذج تماماً\n        layers.GlobalAveragePooling2D(),\n        layers.Dense(256, use_bias=False),\n        layers.BatchNormalization(),\n        layers.Activation(\"relu\"),\n        layers.Dropout(0.5),  # إسقاط 50% في الطبقة قبل الأخيرة لأعلى درجة تعميم\n        # الطبقة النهائية للتصنيف (10 فئات للأرقام من 0 إلى 9)\n        layers.Dense(10, activation=\"softmax\"),\n    ]\n)\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:46:11.137642Z","iopub.execute_input":"2026-07-10T22:46:11.137922Z","iopub.status.idle":"2026-07-10T22:46:11.264192Z","shell.execute_reply.started":"2026-07-10T22:46:11.137899Z","shell.execute_reply":"2026-07-10T22:46:11.263203Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# عرض ملخص المعمارية للتأكد من انسيابية الأبعاد وعدد الأوزان\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:46:20.821965Z","iopub.execute_input":"2026-07-10T22:46:20.822784Z","iopub.status.idle":"2026-07-10T22:46:20.853317Z","shell.execute_reply.started":"2026-07-10T22:46:20.822751Z","shell.execute_reply":"2026-07-10T22:46:20.852547Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"lr_schedule = keras.optimizers.schedules.CosineDecay(\n    initial_learning_rate=1e-3, decay_steps=epochs * len(train_dataset)\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:46:39.304092Z","iopub.execute_input":"2026-07-10T22:46:39.304617Z","iopub.status.idle":"2026-07-10T22:46:39.309737Z","shell.execute_reply.started":"2026-07-10T22:46:39.304589Z","shell.execute_reply":"2026-07-10T22:46:39.308994Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"optimizer = keras.optimizers.AdamW(learning_rate=lr_schedule, weight_decay=0.01)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:46:49.716239Z","iopub.execute_input":"2026-07-10T22:46:49.716990Z","iopub.status.idle":"2026-07-10T22:46:49.722438Z","shell.execute_reply.started":"2026-07-10T22:46:49.716959Z","shell.execute_reply":"2026-07-10T22:46:49.721587Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# دالة الخسارة للمصفوفات الموزعة مع ميزة تنعيم التسميات لمنع الأوفرالفيتينج\nloss_fn = keras.losses.CategoricalCrossentropy(label_smoothing=0.1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:47:05.380930Z","iopub.execute_input":"2026-07-10T22:47:05.381195Z","iopub.status.idle":"2026-07-10T22:47:05.385287Z","shell.execute_reply.started":"2026-07-10T22:47:05.381167Z","shell.execute_reply":"2026-07-10T22:47:05.384476Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.compile(optimizer=optimizer, loss=loss_fn, metrics=[\"accuracy\"])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:47:32.239017Z","iopub.execute_input":"2026-07-10T22:47:32.239612Z","iopub.status.idle":"2026-07-10T22:47:32.248341Z","shell.execute_reply.started":"2026-07-10T22:47:32.239579Z","shell.execute_reply":"2026-07-10T22:47:32.247757Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# إضافة مراقب لوقف التدريب إذا استقرت دقة التحقق ولم تعد ترتفع لمدة 5 دورات متتالية\nearly_stopping = keras.callbacks.EarlyStopping(\n    monitor=\"val_accuracy\", patience=5, restore_best_weights=True, verbose=1\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:50:10.266618Z","iopub.execute_input":"2026-07-10T22:50:10.267283Z","iopub.status.idle":"2026-07-10T22:50:10.271658Z","shell.execute_reply.started":"2026-07-10T22:50:10.267252Z","shell.execute_reply":"2026-07-10T22:50:10.270913Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history = model.fit(\n    train_dataset,\n    epochs=epochs,\n    validation_data=val_dataset,\n    callbacks=[early_stopping],  # تمرير المراقب هنا\n    verbose=1,\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:50:29.799031Z","iopub.execute_input":"2026-07-10T22:50:29.799345Z","iopub.status.idle":"2026-07-10T22:53:29.737002Z","shell.execute_reply.started":"2026-07-10T22:50:29.799318Z","shell.execute_reply":"2026-07-10T22:53:29.736310Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig, ax = plt.subplots(1, 2, figsize=(15, 5))\nax[0].plot(history.history[\"loss\"], label=\"Train Loss\", color=\"b\")\nax[0].plot(history.history[\"val_loss\"], label=\"Val Loss\", color=\"r\")\nax[0].legend()\nax[0].set_title(\"Loss Trajectory\")\n\nax[1].plot(history.history[\"accuracy\"], label=\"Train Acc\", color=\"b\")\nax[1].plot(history.history[\"val_accuracy\"], label=\"Val Acc\", color=\"r\")\nax[1].legend()\nax[1].set_title(\"Accuracy Trajectory\")\nplt.show()\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:55:14.166971Z","iopub.execute_input":"2026-07-10T22:55:14.167871Z","iopub.status.idle":"2026-07-10T22:55:14.423613Z","shell.execute_reply.started":"2026-07-10T22:55:14.167839Z","shell.execute_reply":"2026-07-10T22:55:14.422891Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"Y_pred = model.predict(val_dataset)\n\n# تحويل التوقعات إلى أرقام فئات (0-9)\nY_pred_classes = np.argmax(Y_pred, axis=1)\n\n# استخراج القيم الحقيقية (Y_true) مباشرة من الـ Y_val الأصلي المتوافق مع الترتيب\nY_true_classes = np.argmax(Y_val, axis=1)\n\n# حساب مصفوفة الارتباك\nconfusion_mtx = confusion_matrix(Y_true_classes, Y_pred_classes)\n\n# الرسم الاحترافي المباشر\nfig, ax = plt.subplots(figsize=(8, 8))\ndisp = ConfusionMatrixDisplay(\n    confusion_matrix=confusion_mtx, display_labels=range(10)\n)\ndisp.plot(ax=ax, cmap=plt.cm.Blues, values_format=\"d\")\n\nplt.title(\"Advanced Confusion Matrix\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T22:58:51.868984Z","iopub.execute_input":"2026-07-10T22:58:51.869768Z","iopub.status.idle":"2026-07-10T22:58:53.691981Z","shell.execute_reply.started":"2026-07-10T22:58:51.869736Z","shell.execute_reply":"2026-07-10T22:58:53.691319Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 1. تحويل مصفوفة test المفرودة إلى Dataset وتشكيلها ثلاثية الأبعاد تلقائياً لـ Keras 3\ntest_dataset = (\n    tf.data.Dataset.from_tensor_slices(test)\n    .batch(64)  # تشغيل التوقع على دفعات لتسريع العملية وحماية الذاكرة\n    .map(\n        lambda x: layers.Reshape((28, 28, 1))(x),\n        num_parallel_calls=tf.data.AUTOTUNE,\n    )\n    .prefetch(tf.data.AUTOTUNE)\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T23:01:37.892621Z","iopub.execute_input":"2026-07-10T23:01:37.893289Z","iopub.status.idle":"2026-07-10T23:01:38.353110Z","shell.execute_reply.started":"2026-07-10T23:01:37.893240Z","shell.execute_reply":"2026-07-10T23:01:38.352593Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 2. التوقع الاحترافي السريع عبر الـ Dataset الجديد\nresults = model.predict(test_dataset)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T23:01:41.902384Z","iopub.execute_input":"2026-07-10T23:01:41.903254Z","iopub.status.idle":"2026-07-10T23:01:45.435641Z","shell.execute_reply.started":"2026-07-10T23:01:41.903222Z","shell.execute_reply":"2026-07-10T23:01:45.434950Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"results = np.argmax(results, axis=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T23:02:19.087684Z","iopub.execute_input":"2026-07-10T23:02:19.087940Z","iopub.status.idle":"2026-07-10T23:02:19.092748Z","shell.execute_reply.started":"2026-07-10T23:02:19.087918Z","shell.execute_reply":"2026-07-10T23:02:19.091750Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 4. بناء ملف التسليم المتوافق مع شروط كاجل بدقة (ImageId يبدأ من 1 إلى 28000)\nresults = pd.Series(results, name=\"Label\")\nsubmission = pd.concat(\n    [pd.Series(range(1, 28001), name=\"ImageId\"), results], axis=1\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T23:02:26.343553Z","iopub.execute_input":"2026-07-10T23:02:26.344313Z","iopub.status.idle":"2026-07-10T23:02:26.350527Z","shell.execute_reply.started":"2026-07-10T23:02:26.344272Z","shell.execute_reply":"2026-07-10T23:02:26.349690Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission.to_csv(\"cnn_mnist_datagen.csv\", index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-10T23:02:45.990023Z","iopub.execute_input":"2026-07-10T23:02:45.990617Z","iopub.status.idle":"2026-07-10T23:02:46.022746Z","shell.execute_reply.started":"2026-07-10T23:02:45.990588Z","shell.execute_reply":"2026-07-10T23:02:46.022206Z"}},"outputs":[],"execution_count":null}]}