{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","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":31089,"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)\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport matplotlib.image as mpimg\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":"2025-07-18T02:36:54.696687Z","iopub.execute_input":"2025-07-18T02:36:54.697014Z","iopub.status.idle":"2025-07-18T02:36:58.944155Z","shell.execute_reply.started":"2025-07-18T02:36:54.696983Z","shell.execute_reply":"2025-07-18T02:36:58.943149Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train = pd.read_csv(\"../input/digit-recognizer/train.csv\")\ntest = pd.read_csv(\"../input/digit-recognizer/test.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T02:40:00.019403Z","iopub.execute_input":"2025-07-18T02:40:00.019767Z","iopub.status.idle":"2025-07-18T02:40:05.170622Z","shell.execute_reply.started":"2025-07-18T02:40:00.019696Z","shell.execute_reply":"2025-07-18T02:40:05.169285Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T02:40:09.349322Z","iopub.execute_input":"2025-07-18T02:40:09.349647Z","iopub.status.idle":"2025-07-18T02:40:09.383483Z","shell.execute_reply.started":"2025-07-18T02:40:09.349623Z","shell.execute_reply":"2025-07-18T02:40:09.382648Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T02:40:12.669869Z","iopub.execute_input":"2025-07-18T02:40:12.670615Z","iopub.status.idle":"2025-07-18T02:40:12.686356Z","shell.execute_reply.started":"2025-07-18T02:40:12.670580Z","shell.execute_reply":"2025-07-18T02:40:12.685182Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#plot some graphs\nplt.figure(figsize=(8, 5))\nsns.countplot(x='label', data = train, palette='Dark2')\nplt.title('Train labels count')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T02:40:13.740247Z","iopub.execute_input":"2025-07-18T02:40:13.740620Z","iopub.status.idle":"2025-07-18T02:40:14.197933Z","shell.execute_reply.started":"2025-07-18T02:40:13.740590Z","shell.execute_reply":"2025-07-18T02:40:14.196908Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#first few train images with the label\nfig, ax = plt.subplots(figsize=(18, 8))\nfor ind, row in train[:8].iterrows():\n    plt.subplot(2, 4, ind+1)\n    plt.title(row[0])\n    img = row.to_numpy()[1:].reshape(28, 28)\n    fig.suptitle('Train images', fontsize=24)\n    plt.axis('off')\n    plt.imshow(img)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T02:40:17.121690Z","iopub.execute_input":"2025-07-18T02:40:17.122074Z","iopub.status.idle":"2025-07-18T02:40:17.777160Z","shell.execute_reply.started":"2025-07-18T02:40:17.122048Z","shell.execute_reply":"2025-07-18T02:40:17.776077Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#convert data into numpy arrays\nX = train.iloc[:, 1:].to_numpy()\nY = train['label'].to_numpy()\ntest = test.loc[:, :].to_numpy()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T02:40:43.608638Z","iopub.execute_input":"2025-07-18T02:40:43.609536Z","iopub.status.idle":"2025-07-18T02:40:43.615569Z","shell.execute_reply.started":"2025-07-18T02:40:43.609502Z","shell.execute_reply":"2025-07-18T02:40:43.614817Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#normalize the data\n\nX = X/255\ntest = test/255","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T02:40:46.093415Z","iopub.execute_input":"2025-07-18T02:40:46.093817Z","iopub.status.idle":"2025-07-18T02:40:46.417561Z","shell.execute_reply.started":"2025-07-18T02:40:46.093791Z","shell.execute_reply":"2025-07-18T02:40:46.416373Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# reshape dataset\n# ===============\n\n# shape of training and test dataset\nprint(X.shape)\nprint(test.shape)\n\n# reshape the dataframe to 3x3 matrix with 1 channel grey scale values\nX = X.reshape(-1,28,28,1)\ntest = test.reshape(-1,28,28,1)\n\n# shape of training and test dataset\nprint(X.shape)\nprint(test.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T02:40:51.639906Z","iopub.execute_input":"2025-07-18T02:40:51.640200Z","iopub.status.idle":"2025-07-18T02:40:51.646345Z","shell.execute_reply.started":"2025-07-18T02:40:51.640177Z","shell.execute_reply":"2025-07-18T02:40:51.645088Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# one hot encode target\n\nfrom tensorflow.keras.utils import to_categorical\n# shape and values of target\nprint(Y.shape)\nprint(Y[0])\n\n# convert Y_train to categorical by one-hot-encoding\ny_enc = to_categorical(Y, num_classes = 10)\n\n# shape and values of target\nprint(y_enc.shape)\nprint(y_enc[0])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T02:41:46.028610Z","iopub.execute_input":"2025-07-18T02:41:46.029517Z","iopub.status.idle":"2025-07-18T02:42:03.397953Z","shell.execute_reply.started":"2025-07-18T02:41:46.029489Z","shell.execute_reply":"2025-07-18T02:42:03.397191Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# train test split\n# ================\nfrom sklearn.model_selection import train_test_split\n# random seed\nrandom_seed = 2\n\n# train validation split\nX_train, X_val, y_train_enc, y_val_enc = train_test_split(X, y_enc, test_size=0.3)\n\n# shape\nfor i in [X_train, y_train_enc, X_val, y_val_enc]:\n    print(i.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T02:42:56.098950Z","iopub.execute_input":"2025-07-18T02:42:56.099298Z","iopub.status.idle":"2025-07-18T02:42:56.950913Z","shell.execute_reply.started":"2025-07-18T02:42:56.099273Z","shell.execute_reply":"2025-07-18T02:42:56.949783Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"INPUT_SHAPE = (28,28,1)\nOUTPUT_SHAPE = 10\nBATCH_SIZE = 128\nEPOCHS = 10\nVERBOSE = 2","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T02:43:48.541581Z","iopub.execute_input":"2025-07-18T02:43:48.541981Z","iopub.status.idle":"2025-07-18T02:43:48.547155Z","shell.execute_reply.started":"2025-07-18T02:43:48.541954Z","shell.execute_reply":"2025-07-18T02:43:48.545937Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPool2D, Dense, Flatten, Dropout, Input\n\nmodel = Sequential()\n\nmodel.add(Input(shape=INPUT_SHAPE))\n\nmodel.add(Conv2D(32, kernel_size=(3,3), activation='relu', input_shape=INPUT_SHAPE))\nmodel.add(MaxPool2D((2,2)))\n\nmodel.add(Conv2D(64, kernel_size=(3,3), activation='relu'))\nmodel.add(MaxPool2D((2,2)))\n\nmodel.add(Flatten())\n\nmodel.add(Dense(128, activation='relu'))\nmodel.add(Dropout(0.2))\n\nmodel.add(Dense(64, activation='relu'))\nmodel.add(Dropout(0.2))\n\nmodel.add(Dense(10, activation='softmax'))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T03:10:33.235789Z","iopub.execute_input":"2025-07-18T03:10:33.236155Z","iopub.status.idle":"2025-07-18T03:10:33.337140Z","shell.execute_reply.started":"2025-07-18T03:10:33.236129Z","shell.execute_reply":"2025-07-18T03:10:33.336243Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.compile(optimizer='adam', \n              loss='categorical_crossentropy', \n              metrics=['accuracy'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T03:11:14.111423Z","iopub.execute_input":"2025-07-18T03:11:14.111854Z","iopub.status.idle":"2025-07-18T03:11:14.134166Z","shell.execute_reply.started":"2025-07-18T03:11:14.111819Z","shell.execute_reply":"2025-07-18T03:11:14.132684Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T03:11:23.409121Z","iopub.execute_input":"2025-07-18T03:11:23.409450Z","iopub.status.idle":"2025-07-18T03:11:23.434650Z","shell.execute_reply.started":"2025-07-18T03:11:23.409429Z","shell.execute_reply":"2025-07-18T03:11:23.433750Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history = model.fit(X_train, y_train_enc,\n                    epochs=EPOCHS,\n                    batch_size=BATCH_SIZE,\n                    verbose=VERBOSE,\n                    validation_split=0.3)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T03:11:59.059998Z","iopub.execute_input":"2025-07-18T03:11:59.060353Z","iopub.status.idle":"2025-07-18T03:13:16.837203Z","shell.execute_reply.started":"2025-07-18T03:11:59.060331Z","shell.execute_reply":"2025-07-18T03:13:16.836319Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# model loss and accuracy on validation set\nmodel.evaluate(X_val, y_val_enc, verbose=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T03:13:58.973898Z","iopub.execute_input":"2025-07-18T03:13:58.974240Z","iopub.status.idle":"2025-07-18T03:14:01.109804Z","shell.execute_reply.started":"2025-07-18T03:13:58.974218Z","shell.execute_reply":"2025-07-18T03:14:01.109050Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import confusion_matrix, classification_report\n# predicted values\ny_pred_enc = model.predict(X_val)\n\n# actual\ny_act = [np.argmax(i) for i in y_val_enc]\n\n# decoding predicted values\ny_pred = [np.argmax(i) for i in y_pred_enc]\n\nprint(y_pred_enc[0])\nprint(y_act[0])\nprint(y_pred[0])\n\nprint(classification_report(y_act, y_pred))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T03:32:21.233978Z","iopub.execute_input":"2025-07-18T03:32:21.234313Z","iopub.status.idle":"2025-07-18T03:32:23.360277Z","shell.execute_reply.started":"2025-07-18T03:32:21.234289Z","shell.execute_reply":"2025-07-18T03:32:23.359515Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#model-2\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, GlobalAveragePooling2D, MaxPool2D, Dense, Flatten, Dropout, Input, BatchNormalization\nfrom tensorflow.keras.regularizers import l2 # For L2 regularization\n\nmodel2 = Sequential()\n\n# Input Layer\nmodel2.add(Input(shape=INPUT_SHAPE)) # Good practice to use Input layer explicitly\n\n# First Conv Block\nmodel2.add(Conv2D(32, kernel_size=(3,3), activation='relu', padding='same')) # Added padding='same'\nmodel2.add(BatchNormalization()) # Added Batch Normalization\nmodel2.add(MaxPool2D((2,2)))\nmodel2.add(Dropout(0.25)) # Slightly higher dropout after pooling\n\n# Second Conv Block\nmodel2.add(Conv2D(64, kernel_size=(3,3), activation='relu', padding='same'))\nmodel2.add(BatchNormalization())\nmodel2.add(MaxPool2D((2,2)))\nmodel2.add(Dropout(0.25)) # Slightly higher dropout after pooling\n\n# Optional: Third Conv Block for deeper features\nmodel2.add(Conv2D(128, kernel_size=(3,3), activation='relu', padding='same'))\nmodel2.add(BatchNormalization())\nmodel2.add(MaxPool2D((2,2))) # This will make the output very small for 28x28\nmodel2.add(Dropout(0.25))\n\n# Flatten or Global Average Pooling\n# model.add(Flatten()) # Use Flatten if you want more parameters in Dense layers\nmodel2.add(GlobalAveragePooling2D()) # Alternative to Flatten, reduces parameters\n\n# Dense Layers\nmodel2.add(Dense(128, activation='relu', kernel_regularizer=l2(0.001))) # Added L2 regularization\nmodel2.add(BatchNormalization()) # Batch Norm before dropout can be effective\nmodel2.add(Dropout(0.5)) # Increased dropout for the first dense layer\n\nmodel2.add(Dense(64, activation='relu', kernel_regularizer=l2(0.001))) # Added L2 regularization\nmodel2.add(BatchNormalization())\nmodel2.add(Dropout(0.3)) # Adjusted dropout\n\n# Output Layer\nmodel2.add(Dense(10, activation='softmax'))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T03:41:40.344854Z","iopub.execute_input":"2025-07-18T03:41:40.345200Z","iopub.status.idle":"2025-07-18T03:41:40.596732Z","shell.execute_reply.started":"2025-07-18T03:41:40.345176Z","shell.execute_reply":"2025-07-18T03:41:40.595803Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model2.compile(optimizer='adam', \n              loss='categorical_crossentropy', \n              metrics=['accuracy'])\n\nhistory2 = model2.fit(X_train, y_train_enc,\n                    epochs=EPOCHS,\n                    batch_size=BATCH_SIZE,\n                    verbose=VERBOSE,\n                    validation_split=0.3)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T03:42:35.705094Z","iopub.execute_input":"2025-07-18T03:42:35.705360Z","iopub.status.idle":"2025-07-18T03:46:27.273849Z","shell.execute_reply.started":"2025-07-18T03:42:35.705341Z","shell.execute_reply":"2025-07-18T03:46:27.273004Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import confusion_matrix, classification_report\n# predicted values\ny_pred_enc2 = model2.predict(X_val)\n\n# actual\ny_act = [np.argmax(i) for i in y_val_enc]\n\n# decoding predicted values\ny_pred2 = [np.argmax(i) for i in y_pred_enc2]\n\nprint(y_pred_enc2[0])\nprint(y_act[0])\nprint(y_pred2[0])\n\nprint(classification_report(y_act, y_pred2))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T03:48:19.442218Z","iopub.execute_input":"2025-07-18T03:48:19.442507Z","iopub.status.idle":"2025-07-18T03:48:23.769567Z","shell.execute_reply.started":"2025-07-18T03:48:19.442486Z","shell.execute_reply":"2025-07-18T03:48:23.768784Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(7, 7))\nsns.heatmap(confusion_matrix(y_act, y_pred), annot=True, \n            cbar=False, fmt='1d', cmap='Blues', ax=ax)\nax.set_title('Confusion Matrix', loc='left', fontsize=16)\nax.set_xlabel('Predicted')\nax.set_ylabel('Actual')\nplt.show()\n\nfig, ax = plt.subplots(figsize=(7, 7))\nsns.heatmap(confusion_matrix(y_act, y_pred2), annot=True, \n            cbar=False, fmt='1d', cmap='Blues', ax=ax)\nax.set_title('Confusion Matrix 2', loc='left', fontsize=16)\nax.set_xlabel('Predicted')\nax.set_ylabel('Actual')\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T03:49:58.289833Z","iopub.execute_input":"2025-07-18T03:49:58.290599Z","iopub.status.idle":"2025-07-18T03:49:58.937732Z","shell.execute_reply.started":"2025-07-18T03:49:58.290573Z","shell.execute_reply":"2025-07-18T03:49:58.936788Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_pred_enc = model2.predict(test)\n# decoding predicted values\ny_pred = [np.argmax(i) for i in y_pred_enc]\n\ny_pred[:5]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T03:55:28.672542Z","iopub.execute_input":"2025-07-18T03:55:28.672869Z","iopub.status.idle":"2025-07-18T03:55:36.921600Z","shell.execute_reply.started":"2025-07-18T03:55:28.672847Z","shell.execute_reply":"2025-07-18T03:55:36.920873Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"id_field=[]\nfor idx in range(1, len(y_pred)+1):\n    id_field.append(idx)\n\n#print(id_field[:10])\noutput = pd.DataFrame({'ImageId': id_field, 'Label': y_pred})\noutput.to_csv('submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T04:01:48.109615Z","iopub.execute_input":"2025-07-18T04:01:48.109950Z","iopub.status.idle":"2025-07-18T04:01:48.211538Z","shell.execute_reply.started":"2025-07-18T04:01:48.109925Z","shell.execute_reply":"2025-07-18T04:01:48.210658Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}