{"cells":[{"metadata":{},"cell_type":"markdown","source":"Hello there, in this notebook will are going to study how to recognise the digit using Convolutional Neural Networks(CNN or ConvNet) which is simply a class of deep neural networks, most commonly applied to analyzing visual imagery.This notebook is absolutely for beginner with no prior knowledge of Convulational Nerual Network.So let's get started..."},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Here we are importing all the libraries we needed to import.Tensorflow libraray is used for numerical computation and large-scale machine learning.Also,with few lines of code only you can build your own nerual network.Now we will use pandas library is to read train, test and sample submission csv file."},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import tensorflow as tf\nimport pandas as pd\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Now I have read csv files and stored it into train, x_test and submit pandas DataFrame"},{"metadata":{"trusted":true},"cell_type":"code","source":"train = pd.read_csv('../input/digit-recognizer/train.csv')\nx_test = pd.read_csv('../input/digit-recognizer/test.csv')\nsubmit = pd.read_csv('../input/digit-recognizer/sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Here we are separating columns, x_train which will contain all the features except 'label' columns and y_train which will be our answers will only contain 'label' coulums and for this purpose we will use 'loc' function. "},{"metadata":{"trusted":true},"cell_type":"code","source":"x_train = train.loc[:,train.columns!='label']\ny_train = train.loc[:,train.columns=='label']\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"You'll notice that all of the values in the number are between 0 and 255. If we are training a neural network, for various reasons it's easier if we treat all values as between 0 and 1, a process called 'normalizing'...and fortunately in Python it's easy to normalize a list like this without looping. You do it like this:"},{"metadata":{"trusted":true},"cell_type":"code","source":"x_train = x_train/255.0\nx_test = x_test/255.0","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"When you trained for extra epochs you had an issue where your loss might change. It might have taken a bit of time for you to wait for the training to do that, and you might have thought 'wouldn't it be nice if I could stop the training when I reach a desired value?' -- i.e. 95% accuracy might be enough for you, and if you reach that after 3 epochs, why sit around waiting for it to finish a lot more epochs....So how would you fix that? Like any other program...you have callbacks! Let's see them in action..."},{"metadata":{"trusted":true},"cell_type":"code","source":"class Mycallbacks(tf.keras.callbacks.Callback):\n    def on_epoch_end(self,epoch,log={}):\n        if(log.get('accuracy')>0.995):\n            print(\"\\nReached 99.5% accuracy so stopped training\")\n            self.model.stop_training = True\n            \ncallback = Mycallbacks()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Here we will split our data in train and test set using below code"},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nx_train1,x_test1,y_train1,y_test1 = train_test_split(x_train,y_train,test_size=0.3,random_state=10)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Down below we are define our CNN model with two Conv2D and two MaxPooling2D layers one after one and then we flatten it so that we will get single dimension array which then pass to first Dense layer with 512 neurons in it and then finally to our output layer."},{"metadata":{"trusted":true},"cell_type":"code","source":"cnn_model = tf.keras.models.Sequential([\n    tf.keras.layers.Conv2D(64,(3,3),activation='relu',input_shape=(28,28,1)),\n    tf.keras.layers.MaxPooling2D(2,2),\n    tf.keras.layers.Conv2D(64,(3,3),activation='relu'),\n    tf.keras.layers.MaxPooling2D(2,2),\n    tf.keras.layers.Flatten(),\n    tf.keras.layers.Dense(512,activation='relu'),\n    tf.keras.layers.Dense(10,activation='softmax')\n])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"The next thing to do, now the model is defined, is to actually build it. You do this by compiling it with an optimizer and loss function as before -- and then you train it by calling *cnn_model.fit * asking it to fit your training data to your training labels -- i.e. have it figure out the relationship between the training data and its actual labels, so in future if you have data that looks like the training data, then it can make a prediction for what that data would look like.Also as our input_shape is of 28x28 so we will reshape our array.'cnn_model.summary()' will display summary of our model as shown below:"},{"metadata":{"trusted":true},"cell_type":"code","source":"cnn_model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])\n#x_train1.shape\nx_train1 = np.array(x_train1).reshape(29400,28,28,1)\n#y_train1.shape\ncnn_model.summary()\ncnn_model.fit(x_train1,np.array(y_train1),epochs=10)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"To use callback function you can change our fit function to:\ncnn_model.fit(x_train1,np.array(y_train1),epochs=10,callbacks=[callback])"},{"metadata":{},"cell_type":"markdown","source":"Once it's done training -- you should see an accuracy value at the end of the final epoch. It might look something like 0.9975. This tells you that your neural network is about 91% accurate in classifying the training data. I.E., it figured out a pattern match between the image and the labels that worked 99% of the time. \nBut how would it work with unseen data? That's why we have the test images data . We can call cnn_model.evaluate, and pass in the two sets, and it will report back the loss for each and also input_shape is 28x28 so we will reshape our input array. Let's give it a try:"},{"metadata":{"trusted":true},"cell_type":"code","source":"#x_test1.shape\nx_test1  = np.array(x_test1).reshape(12600,28,28,1)\ncnn_model.evaluate(x_test1,y_test1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Now our model is train and tested with 99% train set accuracy and 98% test set accuracy, so we are left to predict our actual test data we have asked for.Code is as below:"},{"metadata":{"trusted":true},"cell_type":"code","source":"x_test  = np.array(x_test).reshape(28000,28,28,1)\n#x_test.shape\ny_test = cnn_model.predict(x_test)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Here, argmax function of numpy library will given index of maximum value and we will loop through all our prediction"},{"metadata":{"trusted":true},"cell_type":"code","source":"mysub = list(np.argmax(y_test[i]) for i in range(0,len(y_test)))\narr = np.array(mysub)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We changed the value of 'Label' columns of submit DataFrame with our predicted values"},{"metadata":{"trusted":true},"cell_type":"code","source":"submit['Label']= arr","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Here we will create DataFrame and store in submission.csv with no indexes and header which will be same as column name sof submit DataFrame  "},{"metadata":{"trusted":true},"cell_type":"code","source":"df  = pd.DataFrame(submit)\ndf.to_csv('submission.csv',index=False,header=True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Thank you for reading till the end and hope you got an idea of Convulational Nerual Network .I am also beginner like you so if you find some easy way do reach me out in comments. Do share this notebook with friends circle because Sharing is Caring :) Thank you Again..."},{"metadata":{},"cell_type":"markdown","source":""},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}