{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Digit Recgonizer\n\n## Introduction\n\nIn this notebook, we will build and train a Convolutional Neural Network (CNN) for the task of handwritten digit recognition using the famous MNIST dataset. The goal is to achieve high accuracy in classifying handwritten digits from 0 to 9.\n\nWe will go through various steps of the machine learning pipeline, including data loading, data visualization, data preprocessing, model building, training, evaluation, and prediction.\n\nLet's get started!","metadata":{}},{"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":{"execution":{"iopub.status.busy":"2023-10-03T21:08:20.091245Z","iopub.execute_input":"2023-10-03T21:08:20.091691Z","iopub.status.idle":"2023-10-03T21:08:20.109900Z","shell.execute_reply.started":"2023-10-03T21:08:20.091656Z","shell.execute_reply":"2023-10-03T21:08:20.108046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Import the necessary libraries \nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom PIL import Image\nimport plotly.express as px\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score, confusion_matrix\nimport tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, Flatten, Conv2D, MaxPooling2D\nfrom tensorflow.keras.utils import plot_model\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import LearningRateScheduler\nfrom tensorflow.keras.layers import Dropout\nfrom tensorflow.keras.callbacks import EarlyStopping","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:08:34.822709Z","iopub.execute_input":"2023-10-03T21:08:34.824051Z","iopub.status.idle":"2023-10-03T21:08:34.833807Z","shell.execute_reply.started":"2023-10-03T21:08:34.823987Z","shell.execute_reply":"2023-10-03T21:08:34.831213Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Exploary Data Analysis (EDA)","metadata":{}},{"cell_type":"code","source":"# Load the data\ntrain_data = pd.read_csv(\"/kaggle/input/digit-recognizer/train.csv\")\ntest_data = pd.read_csv(\"/kaggle/input/digit-recognizer/test.csv\")","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:08:37.892540Z","iopub.execute_input":"2023-10-03T21:08:37.894213Z","iopub.status.idle":"2023-10-03T21:08:42.240119Z","shell.execute_reply.started":"2023-10-03T21:08:37.894129Z","shell.execute_reply":"2023-10-03T21:08:42.238968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Size of the datasets\nprint(f\"Train Data Shape ==> {train_data.shape}\")\nprint(f\"Test Data Shape  ==> {test_data.shape}\")","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:08:42.242769Z","iopub.execute_input":"2023-10-03T21:08:42.243230Z","iopub.status.idle":"2023-10-03T21:08:42.250068Z","shell.execute_reply.started":"2023-10-03T21:08:42.243189Z","shell.execute_reply":"2023-10-03T21:08:42.248276Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data.head()","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:09:03.661131Z","iopub.execute_input":"2023-10-03T21:09:03.661582Z","iopub.status.idle":"2023-10-03T21:09:03.683099Z","shell.execute_reply.started":"2023-10-03T21:09:03.661550Z","shell.execute_reply":"2023-10-03T21:09:03.682062Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define the label counts\nlabel_counts = train_data['label'].value_counts()\nprint(label_counts)","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:09:04.370010Z","iopub.execute_input":"2023-10-03T21:09:04.370683Z","iopub.status.idle":"2023-10-03T21:09:04.378642Z","shell.execute_reply.started":"2023-10-03T21:09:04.370644Z","shell.execute_reply":"2023-10-03T21:09:04.376999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create an interactive vertical bar chart using Plotly\nfig = px.bar(y=label_counts.values, x=label_counts.index, labels={'x': 'Label', 'y': 'Count'},\n             text=label_counts.values, title='Label Distribution in the Training Data', orientation='v')\nfig.update_traces(texttemplate='%{text}', textposition='outside', marker_color=px.colors.qualitative.Plotly)\nfig.update_layout(xaxis_title='Label', yaxis_title='Count', showlegend=False)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:09:04.797441Z","iopub.execute_input":"2023-10-03T21:09:04.798725Z","iopub.status.idle":"2023-10-03T21:09:05.126413Z","shell.execute_reply.started":"2023-10-03T21:09:04.798669Z","shell.execute_reply":"2023-10-03T21:09:05.124980Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Visualize some digits\nplt.figure(figsize=(12, 6))\nfor i in range(10):\n    plt.subplot(2, 5, i+1)\n    plt.imshow(train_data.iloc[i, 1:].values.reshape(28, 28), cmap='gray')\n    plt.title(f\"Label: {train_data.iloc[i, 0]}\", pad=12)\n    plt.axis('off')\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:09:06.167853Z","iopub.execute_input":"2023-10-03T21:09:06.168968Z","iopub.status.idle":"2023-10-03T21:09:07.108667Z","shell.execute_reply.started":"2023-10-03T21:09:06.168862Z","shell.execute_reply":"2023-10-03T21:09:07.107259Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data Preprocessing","metadata":{}},{"cell_type":"code","source":"# Split the data into features and labels\nX = train_data.drop('label', axis=1).values.astype('float32')\ny = train_data['label'].values\n\n# Normalize the pixel values to [0, 1]\nX /= 255.0\n\n# Reshape the data to 28x28x1 (height, width, channels)\nX = X.reshape(-1, 28, 28, 1)\n\n# Convert labels to one-hot encoded vectors\ny = tf.keras.utils.to_categorical(y, num_classes=10)\n\n# Split the data into training and validation sets\nX_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:09:12.151342Z","iopub.execute_input":"2023-10-03T21:09:12.151839Z","iopub.status.idle":"2023-10-03T21:09:12.760737Z","shell.execute_reply.started":"2023-10-03T21:09:12.151800Z","shell.execute_reply":"2023-10-03T21:09:12.759280Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"X_train shape ==> {X_train.shape}\")\nprint(f\"X_val shape   ==> {X_val.shape}\")\nprint(f\"y_train shape ==> {y_train.shape}\")\nprint(f\"y_val shape   ==> {y_val.shape}\")","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:09:13.580966Z","iopub.execute_input":"2023-10-03T21:09:13.581365Z","iopub.status.idle":"2023-10-03T21:09:13.588216Z","shell.execute_reply.started":"2023-10-03T21:09:13.581336Z","shell.execute_reply":"2023-10-03T21:09:13.587103Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Building and Training the Model (Convolutional Neural Network - CNN)","metadata":{}},{"cell_type":"code","source":"# Create the CNN model\nmodel = Sequential()\nmodel.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Flatten())\nmodel.add(Dense(128, activation='relu'))\nmodel.add(Dense(10, activation='softmax'))\n\n# Compile the model\nmodel.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:09:51.789582Z","iopub.execute_input":"2023-10-03T21:09:51.789980Z","iopub.status.idle":"2023-10-03T21:09:51.989589Z","shell.execute_reply.started":"2023-10-03T21:09:51.789949Z","shell.execute_reply":"2023-10-03T21:09:51.988486Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Data Augmentation","metadata":{}},{"cell_type":"code","source":"# Create a data generator with random transformations\ndatagen = ImageDataGenerator(\n    rotation_range=10,\n    width_shift_range=0.1,\n    height_shift_range=0.1,\n    zoom_range=0.1,\n    horizontal_flip=False,\n    fill_mode='nearest'\n)\n\n# Fit the data generator on the training data\ndatagen.fit(X_train)\n\n# Use the data generator during training\nhistory = model.fit(datagen.flow(X_train, y_train, batch_size=128), epochs=10, validation_data=(X_val, y_val))","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:09:53.156260Z","iopub.execute_input":"2023-10-03T21:09:53.156718Z","iopub.status.idle":"2023-10-03T21:15:47.290501Z","shell.execute_reply.started":"2023-10-03T21:09:53.156683Z","shell.execute_reply":"2023-10-03T21:15:47.289049Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Learning Rate Scheduling","metadata":{}},{"cell_type":"code","source":"# Define a learning rate schedule function\ndef lr_schedule(epoch):\n    initial_lr = 0.001\n    if epoch < 5:\n        return initial_lr\n    else:\n        return initial_lr * tf.math.exp(0.1 * (5 - epoch))\n\n# Use the learning rate schedule during training\nlr_scheduler = LearningRateScheduler(lr_schedule)\nhistory = model.fit(X_train, y_train, batch_size=128, epochs=10, validation_data=(X_val, y_val), callbacks=[lr_scheduler])","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:15:47.293143Z","iopub.execute_input":"2023-10-03T21:15:47.293479Z","iopub.status.idle":"2023-10-03T21:19:09.392180Z","shell.execute_reply.started":"2023-10-03T21:15:47.293451Z","shell.execute_reply":"2023-10-03T21:19:09.390986Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Regularization (Dropout)","metadata":{}},{"cell_type":"code","source":"# Create the CNN model with dropout layers\nmodel = Sequential()\nmodel.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Flatten())\nmodel.add(Dense(128, activation='relu'))\nmodel.add(Dropout(0.5))  # Add dropout here\nmodel.add(Dense(10, activation='softmax'))\n\n# Compile the model\nmodel.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:19:09.394750Z","iopub.execute_input":"2023-10-03T21:19:09.395308Z","iopub.status.idle":"2023-10-03T21:19:09.487396Z","shell.execute_reply.started":"2023-10-03T21:19:09.395257Z","shell.execute_reply":"2023-10-03T21:19:09.485673Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Early Stopping","metadata":{}},{"cell_type":"code","source":"# Use early stopping during training\nearly_stopping = EarlyStopping(patience=3, restore_best_weights=True)\nhistory = model.fit(X_train, y_train, batch_size=128, epochs=50, validation_data=(X_val, y_val), callbacks=[early_stopping])","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:19:09.489347Z","iopub.execute_input":"2023-10-03T21:19:09.490382Z","iopub.status.idle":"2023-10-03T21:22:29.545640Z","shell.execute_reply.started":"2023-10-03T21:19:09.490342Z","shell.execute_reply":"2023-10-03T21:22:29.544287Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model Evaluation","metadata":{}},{"cell_type":"code","source":"# Smmary of the model\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:22:29.547385Z","iopub.execute_input":"2023-10-03T21:22:29.547762Z","iopub.status.idle":"2023-10-03T21:22:29.582846Z","shell.execute_reply.started":"2023-10-03T21:22:29.547729Z","shell.execute_reply":"2023-10-03T21:22:29.581459Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Evaluate the model\nval_loss, val_accuracy = model.evaluate(X_val, y_val)\nprint(f\"Validation Accuracy: {val_accuracy:.4f}\")","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:41:34.913077Z","iopub.execute_input":"2023-10-03T21:41:34.914643Z","iopub.status.idle":"2023-10-03T21:41:37.625756Z","shell.execute_reply.started":"2023-10-03T21:41:34.914601Z","shell.execute_reply":"2023-10-03T21:41:37.624261Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plot learning curves\nplt.figure(figsize=(6, 4))\nplt.plot(history.history['accuracy'], label='Training Accuracy')\nplt.plot(history.history['val_accuracy'], label='Validation Accuracy')\nplt.title('Model Accuracy')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:41:46.547462Z","iopub.execute_input":"2023-10-03T21:41:46.547847Z","iopub.status.idle":"2023-10-03T21:41:46.856361Z","shell.execute_reply.started":"2023-10-03T21:41:46.547817Z","shell.execute_reply":"2023-10-03T21:41:46.855174Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create the confusion matrix\ny_pred_val = np.argmax(model.predict(X_val), axis=1)\ncm = confusion_matrix(np.argmax(y_val, axis=1), y_pred_val)\n\n# Plot the confusion matrix\nplt.figure(figsize=(8, 6))\nsns.heatmap(cm, annot=True, fmt='d', cmap='Greens', cbar=False)\nplt.title('Confusion Matrix')\nplt.xlabel('Predicted Label')\nplt.ylabel('True Label')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:41:48.159725Z","iopub.execute_input":"2023-10-03T21:41:48.160173Z","iopub.status.idle":"2023-10-03T21:41:51.337644Z","shell.execute_reply.started":"2023-10-03T21:41:48.160141Z","shell.execute_reply":"2023-10-03T21:41:51.336278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Misclassified Examples","metadata":{}},{"cell_type":"code","source":"# Find misclassified examples\nmisclassified_idx = np.where(y_pred_val != np.argmax(y_val, axis=1))[0]\n\n# Count the number of misclassified examples\nnum_misclassified = len(misclassified_idx)\n\n# Print the count\nprint(f\"Number of Misclassified Examples: {num_misclassified}\")","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:41:51.339460Z","iopub.execute_input":"2023-10-03T21:41:51.339816Z","iopub.status.idle":"2023-10-03T21:41:51.346616Z","shell.execute_reply.started":"2023-10-03T21:41:51.339756Z","shell.execute_reply":"2023-10-03T21:41:51.345899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plot some misclassified examples\nplt.figure(figsize=(12, 6))\nfor i, idx in enumerate(misclassified_idx[:10]):\n    plt.subplot(2, 5, i + 1)\n    plt.imshow(X_val[idx].reshape(28, 28), cmap='gray')\n    plt.title(f\"True: {np.argmax(y_val[idx])}, Pred: {y_pred_val[idx]}\", pad=12)\n    plt.axis('off')\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:41:55.783002Z","iopub.execute_input":"2023-10-03T21:41:55.783680Z","iopub.status.idle":"2023-10-03T21:41:57.220504Z","shell.execute_reply.started":"2023-10-03T21:41:55.783632Z","shell.execute_reply":"2023-10-03T21:41:57.219639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Making Predictions and Generating Submission File","metadata":{}},{"cell_type":"code","source":"# Preprocess test data\nX_test = test_data.values.astype('float32')\nX_test /= 255.0\nX_test = X_test.reshape(-1, 28, 28, 1)\n\n# Make predictions\npredictions = model.predict(X_test)\ny_pred = np.argmax(predictions, axis=1)","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:41:59.158809Z","iopub.execute_input":"2023-10-03T21:41:59.159507Z","iopub.status.idle":"2023-10-03T21:42:09.814838Z","shell.execute_reply.started":"2023-10-03T21:41:59.159461Z","shell.execute_reply":"2023-10-03T21:42:09.813550Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"X_test shape ==> {X_test.shape}\")\nprint(f\"y_pred shape ==> {y_pred.shape}\")","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:42:09.817629Z","iopub.execute_input":"2023-10-03T21:42:09.818448Z","iopub.status.idle":"2023-10-03T21:42:09.825364Z","shell.execute_reply.started":"2023-10-03T21:42:09.818404Z","shell.execute_reply":"2023-10-03T21:42:09.823815Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Save the entire model to a file\nmodel.save('trained_model.keras')","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:42:09.827088Z","iopub.execute_input":"2023-10-03T21:42:09.827620Z","iopub.status.idle":"2023-10-03T21:42:09.875281Z","shell.execute_reply.started":"2023-10-03T21:42:09.827573Z","shell.execute_reply":"2023-10-03T21:42:09.874242Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Displaying Some Predicted Images","metadata":{}},{"cell_type":"code","source":"# Randomly select a few examples from the test set\nnum_examples_to_display = 10\nrandom_indices = np.random.choice(len(X_test), num_examples_to_display, replace=False)\nselected_images = X_test[random_indices]\nselected_labels_true = y_pred[random_indices]\n\n# Display the selected images along with their predicted labels\nplt.figure(figsize=(12, 6))\nfor i in range(num_examples_to_display):\n    plt.subplot(2, 5, i + 1)\n    plt.imshow(selected_images[i].reshape(28, 28), cmap='gray')\n    plt.title(f\"Predicted: {selected_labels_true[i]}\")\n    plt.axis('off')\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:42:22.104265Z","iopub.execute_input":"2023-10-03T21:42:22.104676Z","iopub.status.idle":"2023-10-03T21:42:23.035314Z","shell.execute_reply.started":"2023-10-03T21:42:22.104645Z","shell.execute_reply":"2023-10-03T21:42:23.034312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create submission file\nsubmission = pd.DataFrame({'ImageId': np.arange(1, len(y_pred)+1), 'Label': y_pred})\nsubmission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:42:23.036760Z","iopub.execute_input":"2023-10-03T21:42:23.038090Z","iopub.status.idle":"2023-10-03T21:42:23.081659Z","shell.execute_reply.started":"2023-10-03T21:42:23.038046Z","shell.execute_reply":"2023-10-03T21:42:23.079972Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def predict_user_image(file_path):\n    try:\n        # Load and preprocess the user-provided image\n        user_image = Image.open(file_path).convert('L')  # Convert to grayscale\n        user_image = user_image.resize((28, 28))  # Resize to 28x28 pixels\n        user_image = np.array(user_image)  # Convert to NumPy array\n\n        # Invert pixel values to get black background and white number\n        user_image = 255 - user_image\n\n        user_image = user_image.astype('float32') / 255.0  # Normalize (assuming you used this preprocessing before)\n        user_image = user_image.reshape(1, 28, 28, 1)  # Reshape to match the model's input shape\n\n        # Make predictions using the trained model\n        user_prediction = model.predict(user_image)\n        user_label = np.argmax(user_prediction)\n\n        # Display the user-provided image and the predicted label\n        plt.imshow(user_image.reshape(28, 28), cmap='gray')\n        plt.title(f\"Predicted: {user_label}\")\n        plt.axis('off')\n        plt.show()\n\n    except Exception as e:\n        print(\"Error: \", e)","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:42:23.610461Z","iopub.execute_input":"2023-10-03T21:42:23.611579Z","iopub.status.idle":"2023-10-03T21:42:23.618858Z","shell.execute_reply.started":"2023-10-03T21:42:23.611541Z","shell.execute_reply":"2023-10-03T21:42:23.617593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predict_user_image(\"/kaggle/input/images/0.jpg\")","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:42:24.606718Z","iopub.execute_input":"2023-10-03T21:42:24.607236Z","iopub.status.idle":"2023-10-03T21:42:24.864501Z","shell.execute_reply.started":"2023-10-03T21:42:24.607195Z","shell.execute_reply":"2023-10-03T21:42:24.863194Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predict_user_image(\"/kaggle/input/images/1.jpg\")","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:42:24.936871Z","iopub.execute_input":"2023-10-03T21:42:24.937376Z","iopub.status.idle":"2023-10-03T21:42:25.178671Z","shell.execute_reply.started":"2023-10-03T21:42:24.937340Z","shell.execute_reply":"2023-10-03T21:42:25.177529Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predict_user_image(\"/kaggle/input/images/2.jpg\")","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:42:25.589675Z","iopub.execute_input":"2023-10-03T21:42:25.590124Z","iopub.status.idle":"2023-10-03T21:42:25.816505Z","shell.execute_reply.started":"2023-10-03T21:42:25.590084Z","shell.execute_reply":"2023-10-03T21:42:25.815120Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predict_user_image(\"/kaggle/input/images/3.jpg\")","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:42:26.383053Z","iopub.execute_input":"2023-10-03T21:42:26.383493Z","iopub.status.idle":"2023-10-03T21:42:26.633117Z","shell.execute_reply.started":"2023-10-03T21:42:26.383456Z","shell.execute_reply":"2023-10-03T21:42:26.631637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predict_user_image(\"/kaggle/input/images/4.jpg\")","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:42:26.852484Z","iopub.execute_input":"2023-10-03T21:42:26.852876Z","iopub.status.idle":"2023-10-03T21:42:27.091720Z","shell.execute_reply.started":"2023-10-03T21:42:26.852848Z","shell.execute_reply":"2023-10-03T21:42:27.090578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predict_user_image(\"/kaggle/input/images/5.jpg\")","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:42:27.340517Z","iopub.execute_input":"2023-10-03T21:42:27.341594Z","iopub.status.idle":"2023-10-03T21:42:27.589188Z","shell.execute_reply.started":"2023-10-03T21:42:27.341548Z","shell.execute_reply":"2023-10-03T21:42:27.587870Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predict_user_image(\"/kaggle/input/images/6.jpg\")","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:42:28.131475Z","iopub.execute_input":"2023-10-03T21:42:28.132876Z","iopub.status.idle":"2023-10-03T21:42:28.367067Z","shell.execute_reply.started":"2023-10-03T21:42:28.132820Z","shell.execute_reply":"2023-10-03T21:42:28.365777Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predict_user_image(\"/kaggle/input/images/7.jpg\")","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:42:29.092870Z","iopub.execute_input":"2023-10-03T21:42:29.093304Z","iopub.status.idle":"2023-10-03T21:42:29.288782Z","shell.execute_reply.started":"2023-10-03T21:42:29.093272Z","shell.execute_reply":"2023-10-03T21:42:29.287616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predict_user_image(\"/kaggle/input/images/8.jpg\")","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:42:30.064409Z","iopub.execute_input":"2023-10-03T21:42:30.065044Z","iopub.status.idle":"2023-10-03T21:42:30.268081Z","shell.execute_reply.started":"2023-10-03T21:42:30.065010Z","shell.execute_reply":"2023-10-03T21:42:30.266993Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predict_user_image(\"/kaggle/input/images/9.jpg\")","metadata":{"execution":{"iopub.status.busy":"2023-10-03T21:42:31.023282Z","iopub.execute_input":"2023-10-03T21:42:31.023959Z","iopub.status.idle":"2023-10-03T21:42:31.189591Z","shell.execute_reply.started":"2023-10-03T21:42:31.023908Z","shell.execute_reply":"2023-10-03T21:42:31.188366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Conclusion\n\n- In this project, we successfully built and trained a CNN model for handwritten digit recognition. We performed data augmentation, implemented learning rate scheduling, applied dropout regularization, and used early stopping to prevent overfitting.\n\n- Our trained model achieved impressive accuracy on the validation set and was able to accurately predict digits from user-provided images as well.\n\n- We also analyzed misclassified examples and visualized the model's performance using confusion matrices and learning curves.\n\n- Overall, this project demonstrates the power of deep learning and CNNs in solving image classification tasks.\n\n\nThank you for following along and I hope to upvote it.\n\nMade by: **Abdelrahman Eldaba**","metadata":{}}]}