{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":30918,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Digit Recognizer with CNN (Keras + TensorFlow)\n\n#### This notebook presents a Convolutional Neural Network (CNN) solution for the Digit Recognizer competition. \n\n#### The objective is to accurately classify handwritten digits (0–9) from grayscale images, using pixel intensity data provided in the training set. The model is built using TensorFlow and Keras, and includes key steps such as data normalization, reshaping, one-hot encoding, and CNN architecture design. \n","metadata":{}},{"cell_type":"markdown","source":"# Import Libraries","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom   sklearn.model_selection import train_test_split\n\nimport tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, Dropout, Flatten\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D\nfrom tensorflow.keras.utils import to_categorical\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-03-27T19:53:28.316519Z","iopub.execute_input":"2025-03-27T19:53:28.319362Z","iopub.status.idle":"2025-03-27T19:53:28.337001Z","shell.execute_reply.started":"2025-03-27T19:53:28.319173Z","shell.execute_reply":"2025-03-27T19:53:28.335449Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Load the Datasets\n#### Load train.csv, test.csv and submission.csv","metadata":{}},{"cell_type":"code","source":"train = pd.read_csv(\"/kaggle/input/digit-recognizer/train.csv\")\ntest = pd.read_csv(\"/kaggle/input/digit-recognizer/test.csv\")\nsubmission = pd.read_csv(\"/kaggle/input/digit-recognizer/sample_submission.csv\")\n\nprint(\"Train shape:\", train.shape)\nprint(\"Test shape:\", test.shape)\ntrain.head()\n#test.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-27T19:53:28.339898Z","iopub.execute_input":"2025-03-27T19:53:28.340284Z","iopub.status.idle":"2025-03-27T19:53:33.253528Z","shell.execute_reply.started":"2025-03-27T19:53:28.340251Z","shell.execute_reply":"2025-03-27T19:53:33.252341Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Visualize sample digits in the dataset\n  \n####  Show first 10 images with their labels","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(10, 4))\nfor i in range(10):                                   # Loop through the first 10 rows of the training data.\n    plt.subplot(2, 5, i + 1)                          # Create a grid\n    pixels = train.iloc[i, 1:].values.reshape(28, 28) # For each image skip the label, get the 784 pixel values, make it a 2D image (from 1D row)   \n    plt.imshow(pixels, cmap='gray')                   # Show the image in grayscale \n    plt.title(f\"Label: {train.iloc[i, 0]}\")           # Show the actual digit above the image\n    plt.axis(\"off\") # Hide the axes\nplt.suptitle(\"Sample Digits\")\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-27T19:53:33.255729Z","iopub.execute_input":"2025-03-27T19:53:33.256262Z","iopub.status.idle":"2025-03-27T19:53:33.966491Z","shell.execute_reply.started":"2025-03-27T19:53:33.256208Z","shell.execute_reply":"2025-03-27T19:53:33.965449Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":" # Preprocess the Data\n#### Normalize pixel values, Reshape to (28, 28, 1), One-hot encode labels, Train/validation split","metadata":{}},{"cell_type":"code","source":"# Split features and target\nX = train.drop(\"label\", axis=1).values     # drop the label column and pick all other cols as features\ny = train[\"label\"].values \n\nX = X / 255.0                              # Normalize pixel values (0–1)\ntest = test / 255.0\n\nX = X.reshape(-1, 28, 28, 1)               # Reshape into 28x28 images\ntest = test.values.reshape(-1, 28, 28, 1)\n\ny_cat = to_categorical(y, num_classes=10) # Convert labels to one-hot encoding\nX_train, X_val, y_train, y_val = train_test_split(X, y_cat, test_size=0.1, random_state=42) # Split into train and test sets\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-27T19:53:33.968002Z","iopub.execute_input":"2025-03-27T19:53:33.968303Z","iopub.status.idle":"2025-03-27T19:53:35.742961Z","shell.execute_reply.started":"2025-03-27T19:53:33.968278Z","shell.execute_reply":"2025-03-27T19:53:35.741652Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":" # Build the CNN Model\n ### CNN Architecture (Keras Sequential API)","metadata":{}},{"cell_type":"code","source":"model = Sequential([\n            Conv2D(32, kernel_size=3, activation='relu', input_shape=(28, 28, 1)), # This tiny 3x3 square is what we call the receptive field\n            MaxPooling2D(pool_size=2),\n            Dropout(0.2),\n        \n            Conv2D(64, kernel_size=3, activation='relu'),\n            MaxPooling2D(pool_size=2),\n            Dropout(0.3),\n        \n            Flatten(),\n            Dense(128, activation='relu'),\n            Dropout(0.4),\n            Dense(10, activation='softmax')\n])\n\nmodel.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n#model.summary()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-27T19:53:35.744107Z","iopub.execute_input":"2025-03-27T19:53:35.744419Z","iopub.status.idle":"2025-03-27T19:53:35.849780Z","shell.execute_reply.started":"2025-03-27T19:53:35.744391Z","shell.execute_reply":"2025-03-27T19:53:35.848572Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":" # Dense Layers – The Classifier\n \n #### These are the fully connected layers that take all the features (patterns) learned by the convolutional part of the model and actually make a prediction.\n\n #### After the CNN extracts patterns, the Dense layers take over — They flatten the image, think about what they saw, and output a final prediction using probabilities.","metadata":{}},{"cell_type":"code","source":"Flatten(),                       # Turns the 2D image data into a 1D vector.\nDense(128, activation='relu'),   # Every value from Flatten() connects to each of the 128 neurons\nDropout(0.4),                    # Randomly disables 40% of neurons to prevent overfitting\nDense(10, activation='softmax')  # Final output layer — 10 neurons, one for each digit: 0, 1, 2, ..., 9","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-27T19:53:35.851081Z","iopub.execute_input":"2025-03-27T19:53:35.851505Z","iopub.status.idle":"2025-03-27T19:53:35.864041Z","shell.execute_reply.started":"2025-03-27T19:53:35.851463Z","shell.execute_reply":"2025-03-27T19:53:35.863092Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Train the Model\n#### We train for 10 epochs using Adam optimizer and batch size of 64.","metadata":{}},{"cell_type":"code","source":"history = model.fit(\n    X_train, y_train,\n    epochs=10,\n    validation_data=(X_val, y_val),\n    batch_size=64\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-27T19:53:35.864906Z","iopub.execute_input":"2025-03-27T19:53:35.865187Z","iopub.status.idle":"2025-03-27T19:56:44.947325Z","shell.execute_reply.started":"2025-03-27T19:53:35.865162Z","shell.execute_reply":"2025-03-27T19:56:44.946231Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":" # Predict on Test Data","metadata":{}},{"cell_type":"code","source":"\ny_pred = model.predict(test)        # Predict probabilities for test set\ny_final = np.argmax(y_pred, axis=1) # Take the digit with the highest probability","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-27T19:56:44.950141Z","iopub.execute_input":"2025-03-27T19:56:44.950490Z","iopub.status.idle":"2025-03-27T19:56:50.982919Z","shell.execute_reply.started":"2025-03-27T19:56:44.950460Z","shell.execute_reply":"2025-03-27T19:56:50.981766Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Create Submission File","metadata":{}},{"cell_type":"code","source":"submission[\"Label\"] = y_final\nsubmission.to_csv(\"submission.csv\", index=False)\nsubmission.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-27T19:56:50.984681Z","iopub.execute_input":"2025-03-27T19:56:50.985169Z","iopub.status.idle":"2025-03-27T19:56:51.026258Z","shell.execute_reply.started":"2025-03-27T19:56:50.985119Z","shell.execute_reply":"2025-03-27T19:56:51.025128Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Training graph\n\n#### The model shows strong learning progress across 10 epochs, with validation accuracy consistently above training accuracy. This indicates stable learning and no signs of overfitting.\n","metadata":{}},{"cell_type":"code","source":"plt.plot(history.history['accuracy'], label='Training Accuracy')\nplt.plot(history.history['val_accuracy'], label='Validation Accuracy')\nplt.title('Accuracy over Epochs')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-27T20:24:23.640679Z","iopub.execute_input":"2025-03-27T20:24:23.641138Z","iopub.status.idle":"2025-03-27T20:24:23.862618Z","shell.execute_reply.started":"2025-03-27T20:24:23.641105Z","shell.execute_reply":"2025-03-27T20:24:23.861235Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Conclusion\n\n#### This notebook implemented a CNN model using Keras to classify handwritten digits with high accuracy. The model achieved a validation accuracy of over 99%, with no overfitting observed during training. ","metadata":{}}]}