{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.11.11"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":31040,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false},"papermill":{"default_parameters":{},"duration":72.227193,"end_time":"2025-05-06T23:11:31.723659","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2025-05-06T23:10:19.496466","version":"2.6.0"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"<div style=\"background: linear-gradient(90deg, \n              rgba(178, 34, 34, 1) 0%, \n              rgba(255, 215, 0, 1) 100%);\n            color: white;\n            text-align: center;\n            padding: 20px;\n            font-family: 'Arial', sans-serif;\n            font-size: 36px;\n            font-weight: bold;\n            border-radius: 10px;\n            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);\">\n    <span>🔢 FFN Foundations: Digit Recognition Challenge 🏆</span>\n</div>\n","metadata":{}},{"cell_type":"markdown","source":"## Import Libraries","metadata":{"papermill":{"duration":0.004151,"end_time":"2025-05-06T23:10:24.447070","exception":false,"start_time":"2025-05-06T23:10:24.442919","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, Flatten\nfrom tensorflow.keras.layers import Input\nimport warnings","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.execute_input":"2025-05-06T23:10:24.455455Z","iopub.status.busy":"2025-05-06T23:10:24.455022Z","iopub.status.idle":"2025-05-06T23:10:44.979143Z","shell.execute_reply":"2025-05-06T23:10:44.978019Z"},"papermill":{"duration":20.530495,"end_time":"2025-05-06T23:10:44.981100","exception":false,"start_time":"2025-05-06T23:10:24.450605","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"warnings.filterwarnings(\"ignore\", category=FutureWarning)","metadata":{"execution":{"iopub.execute_input":"2025-05-06T23:10:44.990436Z","iopub.status.busy":"2025-05-06T23:10:44.989773Z","iopub.status.idle":"2025-05-06T23:10:44.995075Z","shell.execute_reply":"2025-05-06T23:10:44.994012Z"},"papermill":{"duration":0.011447,"end_time":"2025-05-06T23:10:44.996639","exception":false,"start_time":"2025-05-06T23:10:44.985192","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Load and Prepare Data\n","metadata":{"papermill":{"duration":0.003232,"end_time":"2025-05-06T23:10:45.003526","exception":false,"start_time":"2025-05-06T23:10:45.000294","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# Load data (Pandas DataFrames)\ntrain = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')\ntest = pd.read_csv('/kaggle/input/digit-recognizer/test.csv')","metadata":{"execution":{"iopub.execute_input":"2025-05-06T23:10:45.011878Z","iopub.status.busy":"2025-05-06T23:10:45.011531Z","iopub.status.idle":"2025-05-06T23:10:50.187226Z","shell.execute_reply":"2025-05-06T23:10:50.186349Z"},"papermill":{"duration":5.181971,"end_time":"2025-05-06T23:10:50.189009","exception":false,"start_time":"2025-05-06T23:10:45.007038","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Separate features and labels\ny_train = train['label']\nx_train = train.drop('label', axis=1)  # Still a DataFrame here","metadata":{"execution":{"iopub.execute_input":"2025-05-06T23:10:50.199555Z","iopub.status.busy":"2025-05-06T23:10:50.199229Z","iopub.status.idle":"2025-05-06T23:10:50.319923Z","shell.execute_reply":"2025-05-06T23:10:50.319103Z"},"papermill":{"duration":0.128676,"end_time":"2025-05-06T23:10:50.321711","exception":false,"start_time":"2025-05-06T23:10:50.193035","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Normalization (converts to NumPy array automatically)\nx_train = x_train / 255.0  # Scale training data\ntest = test / 255.0        # Scale test data","metadata":{"execution":{"iopub.execute_input":"2025-05-06T23:10:50.330404Z","iopub.status.busy":"2025-05-06T23:10:50.330093Z","iopub.status.idle":"2025-05-06T23:10:50.446685Z","shell.execute_reply":"2025-05-06T23:10:50.445610Z"},"papermill":{"duration":0.122842,"end_time":"2025-05-06T23:10:50.448328","exception":false,"start_time":"2025-05-06T23:10:50.325486","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Reshape data from flat 784-pixel vectors to 28x28 images\nx_train = x_train.values.reshape(-1,28,28)  # Reshape training\ntest = test.values.reshape(-1,28,28)        # Reshape test","metadata":{"execution":{"iopub.execute_input":"2025-05-06T23:10:50.456757Z","iopub.status.busy":"2025-05-06T23:10:50.456405Z","iopub.status.idle":"2025-05-06T23:10:50.461301Z","shell.execute_reply":"2025-05-06T23:10:50.460375Z"},"papermill":{"duration":0.010929,"end_time":"2025-05-06T23:10:50.462904","exception":false,"start_time":"2025-05-06T23:10:50.451975","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Build FFNN Model\n","metadata":{"papermill":{"duration":0.003197,"end_time":"2025-05-06T23:10:50.469812","exception":false,"start_time":"2025-05-06T23:10:50.466615","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# Create a 5x5 grid of sample images with their labels\nplt.figure(figsize=(10,10))   # Set figure size\nfor i in range(25):           # Display first 25 images\n    plt.subplot(5,5,i+1)      # Create subplot\n    plt.imshow(x_train[i], cmap='gray')   # Show image in grayscale\n    plt.title(y_train[i])                 # Show corresponding label\n    plt.axis('off')","metadata":{"execution":{"iopub.execute_input":"2025-05-06T23:10:50.477840Z","iopub.status.busy":"2025-05-06T23:10:50.477481Z","iopub.status.idle":"2025-05-06T23:10:52.231731Z","shell.execute_reply":"2025-05-06T23:10:52.230783Z"},"papermill":{"duration":1.760472,"end_time":"2025-05-06T23:10:52.233566","exception":false,"start_time":"2025-05-06T23:10:50.473094","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Create sequential model (linear stack of layers)\nmodel = Sequential([\n    Input(shape=(28, 28)),        # Input layer expects 28x28 images\n    Flatten(),                    # Flatten 28x28 to 784-pixel vector\n    Dense(128, activation='relu'), # First hidden layer (128 neurons)\n    Dense(64, activation='relu'),  # Second hidden layer (64 neurons)\n    Dense(10, activation='softmax') # Output layer (10 classes, probabilities)\n])","metadata":{"execution":{"iopub.execute_input":"2025-05-06T23:10:52.243221Z","iopub.status.busy":"2025-05-06T23:10:52.242848Z","iopub.status.idle":"2025-05-06T23:10:52.335463Z","shell.execute_reply":"2025-05-06T23:10:52.334322Z"},"papermill":{"duration":0.099327,"end_time":"2025-05-06T23:10:52.337123","exception":false,"start_time":"2025-05-06T23:10:52.237796","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.compile(optimizer='adam',                           # Adam optimizer\n              loss='sparse_categorical_crossentropy',     # Loss function\n              metrics=['accuracy'])                       # Track accuracy during training","metadata":{"execution":{"iopub.execute_input":"2025-05-06T23:10:52.346406Z","iopub.status.busy":"2025-05-06T23:10:52.346100Z","iopub.status.idle":"2025-05-06T23:10:52.360463Z","shell.execute_reply":"2025-05-06T23:10:52.359678Z"},"papermill":{"duration":0.020732,"end_time":"2025-05-06T23:10:52.362009","exception":false,"start_time":"2025-05-06T23:10:52.341277","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Train Model","metadata":{"papermill":{"duration":0.003843,"end_time":"2025-05-06T23:10:52.370165","exception":false,"start_time":"2025-05-06T23:10:52.366322","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# Train model on training data with validation split\nhistory = model.fit(x_train, y_train, \n                   epochs=10,      # Number of training passes\n                   validation_split=0.2)  # 20% data for validation","metadata":{"execution":{"iopub.execute_input":"2025-05-06T23:10:52.379474Z","iopub.status.busy":"2025-05-06T23:10:52.379176Z","iopub.status.idle":"2025-05-06T23:11:26.505114Z","shell.execute_reply":"2025-05-06T23:11:26.504039Z"},"papermill":{"duration":34.132626,"end_time":"2025-05-06T23:11:26.506831","exception":false,"start_time":"2025-05-06T23:10:52.374205","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Plot Training History","metadata":{"papermill":{"duration":0.030241,"end_time":"2025-05-06T23:11:26.568935","exception":false,"start_time":"2025-05-06T23:11:26.538694","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# Plot training and validation accuracy over epochs\nplt.plot(history.history['accuracy'], label='accuracy')\nplt.plot(history.history['val_accuracy'], label='val_accuracy')\nplt.xlabel('Epoch')      \nplt.ylabel('Accuracy')\nplt.legend()","metadata":{"execution":{"iopub.execute_input":"2025-05-06T23:11:26.632593Z","iopub.status.busy":"2025-05-06T23:11:26.632215Z","iopub.status.idle":"2025-05-06T23:11:26.816095Z","shell.execute_reply":"2025-05-06T23:11:26.815179Z"},"papermill":{"duration":0.218061,"end_time":"2025-05-06T23:11:26.817711","exception":false,"start_time":"2025-05-06T23:11:26.599650","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Prediction and Submission:","metadata":{"papermill":{"duration":0.031481,"end_time":"2025-05-06T23:11:26.880931","exception":false,"start_time":"2025-05-06T23:11:26.849450","status":"completed"},"tags":[]}},{"cell_type":"code","source":"predictions = model.predict(test)\npredicted_labels = np.argmax(predictions, axis=1)","metadata":{"execution":{"iopub.execute_input":"2025-05-06T23:11:26.948021Z","iopub.status.busy":"2025-05-06T23:11:26.947661Z","iopub.status.idle":"2025-05-06T23:11:28.821163Z","shell.execute_reply":"2025-05-06T23:11:28.820110Z"},"papermill":{"duration":1.909545,"end_time":"2025-05-06T23:11:28.822992","exception":false,"start_time":"2025-05-06T23:11:26.913447","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = pd.DataFrame({\n    'ImageId': range(1, len(predicted_labels)+1),\n    'Label': predicted_labels\n})\nsubmission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.execute_input":"2025-05-06T23:11:28.892446Z","iopub.status.busy":"2025-05-06T23:11:28.891623Z","iopub.status.idle":"2025-05-06T23:11:28.924345Z","shell.execute_reply":"2025-05-06T23:11:28.923436Z"},"papermill":{"duration":0.069417,"end_time":"2025-05-06T23:11:28.926115","exception":false,"start_time":"2025-05-06T23:11:28.856698","status":"completed"},"tags":[]},"outputs":[],"execution_count":null}]}