{"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 Recognition\n\n- Table of contents:\n\n>Introduction 🧐🛬\n\n> Import  necessary libraries  ⬇️ \n\n> Understanding data with vizualization 🤓📊\n\n> Seperating data into x(image_data) and y(label)  🌓\n  \n> Encoding labels\n\n> Building optimized CNN(convolutional neural network) model 🔬♻️\n\n> Testing 🔄\n\n> Vizualization 📊📈📉\n\n> Submission 🛫🚀\n \n","metadata":{}},{"cell_type":"markdown","source":"# Introduction\n**This is a \"Hello world\" project for understanding the simplest model of MNIST digit recognition data.The data is in a csv file as numbers so we need to change it to the image so then we can build our CNN model.I use tensorflow framework for this notebook.**","metadata":{}},{"cell_type":"markdown","source":"# Import libraries","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport pandas as pd \nimport seaborn as sns\nimport numpy as np\nfrom tensorflow import keras\nfrom sklearn.model_selection import train_test_split\nfrom keras.models import Sequential\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.layers import BatchNormalization,Conv2D,MaxPooling2D,Flatten\nfrom keras.layers import Dense,Dropout\nfrom keras.utils.np_utils import to_categorical\nfrom keras.callbacks import Callback\nrandom_seed=42","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-04-19T13:20:04.013827Z","iopub.execute_input":"2023-04-19T13:20:04.014280Z","iopub.status.idle":"2023-04-19T13:20:12.214917Z","shell.execute_reply.started":"2023-04-19T13:20:04.014201Z","shell.execute_reply":"2023-04-19T13:20:12.213905Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Understanding data","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv(\"../input/digit-recognizer/train.csv\")\ndf_test = pd.read_csv(\"../input/digit-recognizer/test.csv\")\ndf","metadata":{"execution":{"iopub.status.busy":"2023-04-19T13:20:12.216789Z","iopub.execute_input":"2023-04-19T13:20:12.217637Z","iopub.status.idle":"2023-04-19T13:20:17.275255Z","shell.execute_reply.started":"2023-04-19T13:20:12.217597Z","shell.execute_reply":"2023-04-19T13:20:17.274319Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print (\"data info : \")\nprint (f\" {df.info()} number of missing values :  {df.isna().sum().max()}\")","metadata":{"execution":{"iopub.status.busy":"2023-04-19T13:20:17.276700Z","iopub.execute_input":"2023-04-19T13:20:17.277332Z","iopub.status.idle":"2023-04-19T13:20:17.375134Z","shell.execute_reply.started":"2023-04-19T13:20:17.277288Z","shell.execute_reply":"2023-04-19T13:20:17.374114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vision = df['label']\nplt.figure(figsize=(12,9))\nsns.countplot(x=vision)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-04-19T13:20:17.377870Z","iopub.execute_input":"2023-04-19T13:20:17.378241Z","iopub.status.idle":"2023-04-19T13:20:17.635645Z","shell.execute_reply.started":"2023-04-19T13:20:17.378204Z","shell.execute_reply":"2023-04-19T13:20:17.634671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Divide data 2 pieces \n - X and Y","metadata":{}},{"cell_type":"code","source":"X = df.drop('label',axis=1).values\nY = df['label'].values\n\nX = X/255.0  # smaller values make model work efficient and fast\nX=X.astype('float32')\nY=Y.astype('float32')\n\n\nX = X.reshape(-1,28,28,1) # reshaping from  arrays to matrices\nY = to_categorical(Y)  # encoding from numbers to onehotencoding \n\n\nx_train,x_test,y_train,y_test = train_test_split(X,Y,test_size=0.2,random_state=42) # You can put any number for random_state=\n                                                                          #  _ it is for keeping the first selected values. ","metadata":{"execution":{"iopub.status.busy":"2023-04-19T13:20:17.636945Z","iopub.execute_input":"2023-04-19T13:20:17.637655Z","iopub.status.idle":"2023-04-19T13:20:18.184306Z","shell.execute_reply.started":"2023-04-19T13:20:17.637613Z","shell.execute_reply":"2023-04-19T13:20:18.183279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Image matrix\nimport random\ni=random.randint(0,len(y_train))\nplt.title(f\"this is {y_train[i]}\")\nplt.imshow(x_train[i],cmap='YlOrRd')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-04-19T13:20:18.185924Z","iopub.execute_input":"2023-04-19T13:20:18.186300Z","iopub.status.idle":"2023-04-19T13:20:18.384719Z","shell.execute_reply.started":"2023-04-19T13:20:18.186260Z","shell.execute_reply":"2023-04-19T13:20:18.383717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Data augmentation is used to avoid overfitting**","metadata":{}},{"cell_type":"markdown","source":"#data_aug  = keras.Sequential([\n  keras.layers.RandomFlip(\"horizontal_and_vertical\"),\n  keras.layers.RandomRotation(0.1),\n  keras.layers.RandomZoom(0.1),\n  keras.layers.RandomWidth(0.1),\n  keras.layers.RandomHeight(0.1)\n])","metadata":{"execution":{"iopub.status.busy":"2023-02-04T13:30:47.621128Z","iopub.execute_input":"2023-02-04T13:30:47.621529Z","iopub.status.idle":"2023-02-04T13:30:47.639798Z","shell.execute_reply.started":"2023-02-04T13:30:47.621496Z","shell.execute_reply":"2023-02-04T13:30:47.638946Z"}}},{"cell_type":"markdown","source":"# Model\n > The data is not so big so that I didn't use dropout to make it GPU work easier","metadata":{}},{"cell_type":"code","source":"model = Sequential()\n\nmodel.add(Conv2D(32,kernel_size=(5,5),padding='Same',activation='relu',input_shape=(28,28,1)))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(0.10))\n\nmodel.add(Conv2D(32,(5,5),padding='Same',activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D((2,2)))\nmodel.add(Dropout(0.10))\n\nmodel.add(Conv2D(64,(3,3),padding='Same',activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2,2),strides=(2,2)))\n\nmodel.add(Conv2D(64,(3,3),padding='Same',activation='relu'))\nmodel.add(BatchNormalization())\n\nmodel.add(Conv2D(128,(3,3),padding='Same',activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(0.2))\n\nmodel.add(Conv2D(128,(3,3),padding='Same',activation='relu'))\nmodel.add(MaxPooling2D((2,2)))\nmodel.add(BatchNormalization()),\n\nmodel.add(Conv2D(256,(3,3),padding='Same',activation='relu'))\nmodel.add(BatchNormalization())\n\nmodel.add(Conv2D(512,(3,3),padding='Same',activation='relu'))\nmodel.add(MaxPooling2D((2,2)))\nmodel.add(BatchNormalization()),\nmodel.add(Dropout(0.3))\n\nmodel.add(Flatten())\n\nmodel.add(Dense(256,activation='relu'))\nmodel.add(Dropout(0.2))\nmodel.add(Dense(128,activation='relu'))\nmodel.add(Dense(64,activation='relu'))\nmodel.add(Dense(32,activation='relu'))\nmodel.add(Dense(10,activation='softmax'))","metadata":{"execution":{"iopub.status.busy":"2023-04-19T13:20:18.386303Z","iopub.execute_input":"2023-04-19T13:20:18.386694Z","iopub.status.idle":"2023-04-19T13:20:22.824612Z","shell.execute_reply.started":"2023-04-19T13:20:18.386650Z","shell.execute_reply":"2023-04-19T13:20:22.823484Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optim = keras.optimizers.Adam(learning_rate=0.001,decay=0.0)\nmodel.compile(optimizer=optim,loss = 'categorical_crossentropy',metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-04-19T13:20:22.829097Z","iopub.execute_input":"2023-04-19T13:20:22.831655Z","iopub.status.idle":"2023-04-19T13:20:23.257096Z","shell.execute_reply.started":"2023-04-19T13:20:22.831616Z","shell.execute_reply":"2023-04-19T13:20:23.255927Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Callback** function is used to stop training if model has achieved the best result.","metadata":{}},{"cell_type":"code","source":"class myCallback(Callback):\n    def on_epoch_end(self,epoch,logs={}):\n        if (logs.get(\"loss\")<0.001):\n            print(\"\\n accuracy reached the highest point,cancelling session\")\n            self.model.stop_training=True\ncallback = myCallback()","metadata":{"execution":{"iopub.status.busy":"2023-04-19T13:20:23.261564Z","iopub.execute_input":"2023-04-19T13:20:23.262044Z","iopub.status.idle":"2023-04-19T13:20:23.274897Z","shell.execute_reply.started":"2023-04-19T13:20:23.262001Z","shell.execute_reply":"2023-04-19T13:20:23.273809Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":" > Here you can see that 10 epochs is enough to train","metadata":{}},{"cell_type":"code","source":"# model fitting \nhist = model.fit(x_train,y_train,epochs=100,callbacks=callback)","metadata":{"execution":{"iopub.status.busy":"2023-04-19T13:20:23.279830Z","iopub.execute_input":"2023-04-19T13:20:23.280565Z","iopub.status.idle":"2023-04-19T13:33:47.296408Z","shell.execute_reply.started":"2023-04-19T13:20:23.280525Z","shell.execute_reply":"2023-04-19T13:33:47.295316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2023-04-19T13:33:47.298012Z","iopub.execute_input":"2023-04-19T13:33:47.298427Z","iopub.status.idle":"2023-04-19T13:33:47.310069Z","shell.execute_reply.started":"2023-04-19T13:33:47.298384Z","shell.execute_reply":"2023-04-19T13:33:47.308834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Example test\npred = model.predict(x_test)\ny = y_test","metadata":{"execution":{"iopub.status.busy":"2023-04-19T13:33:47.311594Z","iopub.execute_input":"2023-04-19T13:33:47.312671Z","iopub.status.idle":"2023-04-19T13:33:48.254694Z","shell.execute_reply.started":"2023-04-19T13:33:47.312628Z","shell.execute_reply":"2023-04-19T13:33:48.251695Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"testing = df_test.values\ntesting= testing.reshape(-1,28,28,1)\ntest = testing/255.0\npredict = model.predict(test)\n\nsubmit = []\nfor i in predict:\n    submit.append(np.argmax(i))","metadata":{"execution":{"iopub.status.busy":"2023-04-19T13:33:48.263347Z","iopub.execute_input":"2023-04-19T13:33:48.264077Z","iopub.status.idle":"2023-04-19T13:33:51.513998Z","shell.execute_reply.started":"2023-04-19T13:33:48.264035Z","shell.execute_reply":"2023-04-19T13:33:51.512972Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.evaluate(x_test,y_test)","metadata":{"execution":{"iopub.status.busy":"2023-04-19T13:33:51.515507Z","iopub.execute_input":"2023-04-19T13:33:51.515900Z","iopub.status.idle":"2023-04-19T13:33:53.088218Z","shell.execute_reply.started":"2023-04-19T13:33:51.515860Z","shell.execute_reply":"2023-04-19T13:33:53.087244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import random\nx=random.randint(0,len(x_test))\ndef num(x):\n    lab=['zero','one','two','three','four','five','six','seven','eight','nine']\n    return lab[x]\nplt.figure(figsize=(10,30))\nplt.title(f'the image on index {x} is  - {num(submit[x])}')\nplt.imshow(test[x])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-04-19T13:33:53.089566Z","iopub.execute_input":"2023-04-19T13:33:53.089953Z","iopub.status.idle":"2023-04-19T13:33:53.328745Z","shell.execute_reply.started":"2023-04-19T13:33:53.089916Z","shell.execute_reply":"2023-04-19T13:33:53.327735Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nnum = pd.Series(range(1,28001),name = \"ImageId\")\nsbm = pd.Series(submit,name = \"Label\")\nsubmission= pd.concat([num,sbm],axis = 1)\nsubmission\nsubmission.to_csv(\"submission.csv\",index=False)\nprint(submission)","metadata":{"execution":{"iopub.status.busy":"2023-04-19T13:33:53.330036Z","iopub.execute_input":"2023-04-19T13:33:53.330401Z","iopub.status.idle":"2023-04-19T13:33:53.379881Z","shell.execute_reply.started":"2023-04-19T13:33:53.330364Z","shell.execute_reply":"2023-04-19T13:33:53.378780Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv(\"submission.csv\",index=False)","metadata":{"execution":{"iopub.status.busy":"2023-04-19T13:33:53.381335Z","iopub.execute_input":"2023-04-19T13:33:53.381677Z","iopub.status.idle":"2023-04-19T13:33:53.413491Z","shell.execute_reply.started":"2023-04-19T13:33:53.381641Z","shell.execute_reply":"2023-04-19T13:33:53.412525Z"},"trusted":true},"execution_count":null,"outputs":[]}]}