{"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":"code","source":"import numpy as np\nimport pandas as pd\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nfrom tensorflow import keras\nfrom tensorflow.keras import layers, models\nfrom keras.callbacks import EarlyStopping\n\nfrom sklearn.model_selection import train_test_split","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:01:39.924075Z","iopub.execute_input":"2023-04-21T08:01:39.924615Z","iopub.status.idle":"2023-04-21T08:01:49.446935Z","shell.execute_reply.started":"2023-04-21T08:01:39.924585Z","shell.execute_reply":"2023-04-21T08:01:49.445835Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Having a look at training data","metadata":{}},{"cell_type":"code","source":"train_df = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:01:49.449136Z","iopub.execute_input":"2023-04-21T08:01:49.449858Z","iopub.status.idle":"2023-04-21T08:01:52.428194Z","shell.execute_reply.started":"2023-04-21T08:01:49.449828Z","shell.execute_reply":"2023-04-21T08:01:52.427141Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:01:52.429698Z","iopub.execute_input":"2023-04-21T08:01:52.430158Z","iopub.status.idle":"2023-04-21T08:01:52.458794Z","shell.execute_reply.started":"2023-04-21T08:01:52.430118Z","shell.execute_reply":"2023-04-21T08:01:52.457691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Get the label counts from the DataFrame\nlabel_counts = train_df['label'].value_counts()\n\n# Create a bar chart\nplt.bar(label_counts.index, label_counts.values)\n\n# Set labels and title\nplt.xlabel('Label')\nplt.ylabel('Count')\nplt.title('Distribution of Labels')\n\n# Set x-axis ticks\nplt.xticks(list(label_counts.index))\n\n# Show the plot\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:46:17.031145Z","iopub.execute_input":"2023-04-21T08:46:17.032148Z","iopub.status.idle":"2023-04-21T08:46:17.243146Z","shell.execute_reply.started":"2023-04-21T08:46:17.032109Z","shell.execute_reply":"2023-04-21T08:46:17.242168Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**The dataset seems pretty well balanced with similar number of image data for each numbers from 0 to 9. The digit 1 has the highest number of image data while digit 5 has the lowest.**","metadata":{}},{"cell_type":"code","source":"def image_row_reshaper(df, row_number, visualize=False, test_df = False):\n    '''\n        Parameters:\n            df --> Pandas dataframe type\n            row_number --> row index (For example: 0, 1, 2, 3, etc.)\n            visualize --> If True then displays the raw data into 28 by 28 pixels image.\n                          If False then returns '28 by 28 pixels reshaped image data' and 'corresponding label'\n    '''\n    raw_image_data = df.loc[row_number,] #Taking user given image from the dataframe\n    \n    if test_df == False:\n        image_label = raw_image_data[0] #This is the label of the current particular image\n        filtered_image_data = raw_image_data[1:] #taking data after the first value as the first value is label\n    else:\n        filtered_image_data = raw_image_data\n        \n    reshaped_image_data = filtered_image_data.values.reshape((28,28)) #Reshaping the image into 28 by 28 pixes\n    \n    if visualize==True:\n        plt.imshow(reshaped_image_data, cmap='gray')\n        if test_df == False:\n            plt.title(f'Label: {image_label}')\n        plt.show()\n    else:\n        return reshaped_image_data, image_label","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:08:07.820578Z","iopub.execute_input":"2023-04-21T08:08:07.821535Z","iopub.status.idle":"2023-04-21T08:08:07.829789Z","shell.execute_reply.started":"2023-04-21T08:08:07.821481Z","shell.execute_reply":"2023-04-21T08:08:07.828528Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_row_reshaper(train_df, 3, visualize=True)\nimage_row_reshaper(train_df, 4, visualize=True)\nimage_row_reshaper(train_df, 7, visualize=True)","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:07:03.081927Z","iopub.execute_input":"2023-04-21T08:07:03.082318Z","iopub.status.idle":"2023-04-21T08:07:03.641102Z","shell.execute_reply.started":"2023-04-21T08:07:03.082283Z","shell.execute_reply":"2023-04-21T08:07:03.640131Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.shape","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:01:53.064520Z","iopub.execute_input":"2023-04-21T08:01:53.064866Z","iopub.status.idle":"2023-04-21T08:01:53.074270Z","shell.execute_reply.started":"2023-04-21T08:01:53.064829Z","shell.execute_reply":"2023-04-21T08:01:53.072266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**If you want to see other training data image, uncomment the code below and just replace '_' with a number from 0 (inclusive) to 41999 (inclusive).**","metadata":{}},{"cell_type":"code","source":"# image_row_reshaper(train_df, _, visualize=True)","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:01:53.075461Z","iopub.execute_input":"2023-04-21T08:01:53.075806Z","iopub.status.idle":"2023-04-21T08:01:53.082420Z","shell.execute_reply.started":"2023-04-21T08:01:53.075771Z","shell.execute_reply":"2023-04-21T08:01:53.081281Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Transforming data","metadata":{}},{"cell_type":"code","source":"def dataframe_formatter(df, isTest=False):\n    \n    if isTest==False:\n        y = df['label'] # extracting just the labels into a scalar form\n        X = train_df.loc[:,'pixel0':'pixel783'] # extracting just the pixels data\n        X = X.apply(lambda x: x/255) # normalizing the values between 0 and 1\n        X = X.values.reshape(-1, 28, 28, 1)\n        return X, y\n        \n    elif isTest==True:\n        X = df\n        X = X.apply(lambda x: x/255) # normalizing the values between 0 and 1\n        X = X.values.reshape(-1, 28, 28, 1)\n        return X","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:01:53.084267Z","iopub.execute_input":"2023-04-21T08:01:53.084611Z","iopub.status.idle":"2023-04-21T08:01:53.091998Z","shell.execute_reply.started":"2023-04-21T08:01:53.084575Z","shell.execute_reply":"2023-04-21T08:01:53.091139Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train, y_train = dataframe_formatter(train_df, isTest=False)","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:01:53.096403Z","iopub.execute_input":"2023-04-21T08:01:53.096980Z","iopub.status.idle":"2023-04-21T08:01:53.595449Z","shell.execute_reply.started":"2023-04-21T08:01:53.096941Z","shell.execute_reply":"2023-04-21T08:01:53.594401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Split the data into a train and validation set\nX_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2, random_state=13)","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:01:53.596880Z","iopub.execute_input":"2023-04-21T08:01:53.597898Z","iopub.status.idle":"2023-04-21T08:01:53.972342Z","shell.execute_reply.started":"2023-04-21T08:01:53.597856Z","shell.execute_reply":"2023-04-21T08:01:53.971226Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Building model","metadata":{}},{"cell_type":"code","source":"model = models.Sequential(\n    [\n        layers.Conv2D(20, (3, 3), activation='relu', input_shape=(28, 28, 1)),\n        layers.MaxPooling2D((2, 2)),\n        layers.Conv2D(32, (3, 3), activation='relu'),\n        layers.MaxPooling2D((2, 2)),\n        layers.Conv2D(32, (2, 2), activation='relu'),\n        layers.MaxPooling2D((2, 2)),\n        layers.Flatten(),\n        layers.Dense(units=200, activation='relu'),\n        layers.Dropout(0.2),\n        layers.Dense(units=10, activation='sigmoid')\n    ]\n)\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:10:06.049758Z","iopub.execute_input":"2023-04-21T08:10:06.050681Z","iopub.status.idle":"2023-04-21T08:10:06.169653Z","shell.execute_reply.started":"2023-04-21T08:10:06.050625Z","shell.execute_reply":"2023-04-21T08:10:06.168846Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(\n    optimizer='adam',\n    loss='sparse_categorical_crossentropy',\n    metrics=['accuracy']\n)","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:10:18.675114Z","iopub.execute_input":"2023-04-21T08:10:18.675817Z","iopub.status.idle":"2023-04-21T08:10:18.689609Z","shell.execute_reply.started":"2023-04-21T08:10:18.675780Z","shell.execute_reply":"2023-04-21T08:10:18.688544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Early stopping in case of 3 bad epochs\nstop_training = EarlyStopping(monitor='val_loss', patience=3)","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:10:20.671546Z","iopub.execute_input":"2023-04-21T08:10:20.672493Z","iopub.status.idle":"2023-04-21T08:10:20.677870Z","shell.execute_reply.started":"2023-04-21T08:10:20.672443Z","shell.execute_reply":"2023-04-21T08:10:20.676438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train the model with 20 epochs\nmodel.fit(\n    X_train,\n    y_train,\n    epochs=20,\n    validation_data=(X_val, y_val),\n    callbacks=stop_training\n)","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:10:22.864690Z","iopub.execute_input":"2023-04-21T08:10:22.865305Z","iopub.status.idle":"2023-04-21T08:11:00.625767Z","shell.execute_reply.started":"2023-04-21T08:10:22.865267Z","shell.execute_reply":"2023-04-21T08:11:00.624804Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Importing test data","metadata":{}},{"cell_type":"code","source":"test_df = pd.read_csv('/kaggle/input/digit-recognizer/test.csv')","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:02:35.774467Z","iopub.execute_input":"2023-04-21T08:02:35.774829Z","iopub.status.idle":"2023-04-21T08:02:38.865259Z","shell.execute_reply.started":"2023-04-21T08:02:35.774791Z","shell.execute_reply":"2023-04-21T08:02:38.864193Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df.shape","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:02:38.866954Z","iopub.execute_input":"2023-04-21T08:02:38.867370Z","iopub.status.idle":"2023-04-21T08:02:38.875235Z","shell.execute_reply.started":"2023-04-21T08:02:38.867327Z","shell.execute_reply":"2023-04-21T08:02:38.874234Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_test = dataframe_formatter(test_df, isTest=True)","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:02:38.876762Z","iopub.execute_input":"2023-04-21T08:02:38.878778Z","iopub.status.idle":"2023-04-21T08:02:39.146413Z","shell.execute_reply.started":"2023-04-21T08:02:38.878739Z","shell.execute_reply":"2023-04-21T08:02:39.145359Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_test.shape","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:02:39.147789Z","iopub.execute_input":"2023-04-21T08:02:39.148462Z","iopub.status.idle":"2023-04-21T08:02:39.155261Z","shell.execute_reply.started":"2023-04-21T08:02:39.148422Z","shell.execute_reply":"2023-04-21T08:02:39.154266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Submission","metadata":{}},{"cell_type":"markdown","source":"**Creating a submission file for the competition**","metadata":{}},{"cell_type":"code","source":"# Perform predictions for all rows of X_test at once\npredictions = model.predict(X_test, verbose=0)\n\n# Get the predicted class labels by finding the indices of the maximum values\npredicted_labels = np.argmax(predictions, axis=-1)\n","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:36:28.326004Z","iopub.execute_input":"2023-04-21T08:36:28.326608Z","iopub.status.idle":"2023-04-21T08:36:30.699812Z","shell.execute_reply.started":"2023-04-21T08:36:28.326561Z","shell.execute_reply":"2023-04-21T08:36:30.698731Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.read_csv('/kaggle/input/digit-recognizer/sample_submission.csv')\nsubmission.shape","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:38:13.756082Z","iopub.execute_input":"2023-04-21T08:38:13.756794Z","iopub.status.idle":"2023-04-21T08:38:13.784422Z","shell.execute_reply.started":"2023-04-21T08:38:13.756757Z","shell.execute_reply":"2023-04-21T08:38:13.783265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission['Label'] = list(predicted_labels)","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:38:44.343317Z","iopub.execute_input":"2023-04-21T08:38:44.343771Z","iopub.status.idle":"2023-04-21T08:38:44.369619Z","shell.execute_reply.started":"2023-04-21T08:38:44.343733Z","shell.execute_reply":"2023-04-21T08:38:44.368642Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:38:45.495144Z","iopub.execute_input":"2023-04-21T08:38:45.495925Z","iopub.status.idle":"2023-04-21T08:38:45.508166Z","shell.execute_reply.started":"2023-04-21T08:38:45.495891Z","shell.execute_reply":"2023-04-21T08:38:45.506954Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Save DataFrame to CSV\nsubmission.to_csv('submission.csv', index=False)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Testing Model Visually","metadata":{}},{"cell_type":"code","source":"def test_model(row):\n    image_row_reshaper(test_df, row, visualize=True, test_df = True)\n    print(f'Predicted Label: {predicted_labels[row]}')","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:41:08.040700Z","iopub.execute_input":"2023-04-21T08:41:08.041062Z","iopub.status.idle":"2023-04-21T08:41:08.046448Z","shell.execute_reply.started":"2023-04-21T08:41:08.041030Z","shell.execute_reply":"2023-04-21T08:41:08.045117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# call the function using this way:\n# test_model(row) where row can be any values from 0 to 28000 only!\n\ntest_model(0)","metadata":{"execution":{"iopub.status.busy":"2023-04-21T08:43:50.441048Z","iopub.execute_input":"2023-04-21T08:43:50.441942Z","iopub.status.idle":"2023-04-21T08:43:50.630947Z","shell.execute_reply.started":"2023-04-21T08:43:50.441891Z","shell.execute_reply":"2023-04-21T08:43:50.629421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**You can change the value of int passed to test_model function in above cell to check other test images visually!**","metadata":{}}]}