{"cells":[{"metadata":{"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 in \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 \"../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# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"id":"O6nHyKlZdska","colab_type":"text"},"cell_type":"markdown","source":"###Importing libraries"},{"metadata":{"id":"8MD-2sh2jvqG","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":100},"outputId":"2a1f8fa1-79ac-48a7-9516-809660cd21b3","trusted":true},"cell_type":"code","source":"import tensorflow as tf\nimport seaborn as sns # seabonrn for visualization\nimport matplotlib.pyplot as plt # plots for visualization\nimport matplotlib.image as mpimg # to load image data\nfrom sklearn.model_selection import train_test_split # to split train.csv data for cross validation\nfrom sklearn.metrics import confusion_matrix # to construct confusion matrix\nimport itertools # has iterator functions for efficient looping\nfrom keras.utils.np_utils import to_categorical # convert to one-hot-encoding\nfrom keras.models import Sequential # to construct in CNN\nfrom keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D # Operations on CNN\nfrom keras.optimizers import RMSprop # RMSProp optimizer\nfrom keras.preprocessing.image import ImageDataGenerator # Image generator class\nfrom keras.callbacks import ReduceLROnPlateau # Reduce learning rate callback function","execution_count":null,"outputs":[]},{"metadata":{"id":"ZJH-nJeoig4j","colab_type":"text"},"cell_type":"markdown","source":"###Setting environment for visulaization"},{"metadata":{"id":"CJ6e7zhHiebs","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"%matplotlib inline\nsns.set()","execution_count":null,"outputs":[]},{"metadata":{"id":"kbEUManMdgzB","colab_type":"text"},"cell_type":"markdown","source":"###Loading the data set"},{"metadata":{"id":"Lk3ozPWvVmsi","colab_type":"code","outputId":"57145273-47ba-4973-cdcf-866388c342d1","colab":{"base_uri":"https://localhost:8080/","height":127},"trusted":true},"cell_type":"code","source":"# Load the data (images stored as pixel values)\ntrain = pd.read_csv(\"/kaggle/input/Kannada-MNIST/train.csv\")\ntest = pd.read_csv(\"/kaggle/input/Kannada-MNIST/test.csv\")\ntest.columns","execution_count":null,"outputs":[]},{"metadata":{"id":"dMxyzcshXREZ","colab_type":"code","outputId":"3e702222-207b-405d-bf67-fb7313dc6b33","colab":{"base_uri":"https://localhost:8080/","height":487},"trusted":true},"cell_type":"code","source":"Y = train[\"label\"] # target of train.csv data\nX = train.drop(labels = [\"label\"],axis = 1) # Drop 'label' column from train.csv data\ntestX = test.drop(labels = [\"id\"],axis = 1) # Drop 'id' column from test.csv data\ng = sns.countplot(Y) # display the distribution of digits in train.csv data\nY.value_counts().sort_values() # count the distribution of digits in train.csv data","execution_count":null,"outputs":[]},{"metadata":{"id":"AKBsJ-lIk3Ad","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"del train # delete train dataframe to free some space \n#del test # delete test dataframe to free some space","execution_count":null,"outputs":[]},{"metadata":{"id":"8xzfGlbSnrDw","colab_type":"text"},"cell_type":"markdown","source":"###Preprocessing"},{"metadata":{"id":"kg-dgRSaXTyK","colab_type":"code","outputId":"38d8b6c5-e8ce-492b-e7da-2b0ccbc6805c","colab":{"base_uri":"https://localhost:8080/","height":109},"trusted":true},"cell_type":"code","source":"#Check for null and missing values in train.csv data\nX.isnull().any().describe() # the result shows there is no null values","execution_count":null,"outputs":[]},{"metadata":{"id":"8X7ucScdZRyA","colab_type":"code","outputId":"bb1f8358-4711-4ecc-d038-b55f47e8a949","colab":{"base_uri":"https://localhost:8080/","height":109},"trusted":true},"cell_type":"code","source":"#Check for null and missing values in test.csv data\ntestX.isnull().any().describe() # the result shows there is no null values","execution_count":null,"outputs":[]},{"metadata":{"id":"p6JKrivLZkZM","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"X = X / 255.0 # Normalize train.csv data\ntestX = testX / 255.0 # Normalize test.csv the data","execution_count":null,"outputs":[]},{"metadata":{"id":"i45YyhImZtpS","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"# Reshape image in 3 dimensions (height = 28px, width = 28px , channel = 1)\nX = X.values.reshape(-1,28,28,1)\ntestX = testX.values.reshape(-1,28,28,1)","execution_count":null,"outputs":[]},{"metadata":{"id":"sOuWRWgYrszs","colab_type":"code","outputId":"05d37705-38b8-46a8-e4ea-4a1f83c087d9","colab":{"base_uri":"https://localhost:8080/","height":35},"trusted":true},"cell_type":"code","source":"X.shape #reshaped from \"42000 X 784\" to \"60000 X 28 X 28 X 1\"","execution_count":null,"outputs":[]},{"metadata":{"id":"5A65UDFRHb1X","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":35},"outputId":"5c7c232f-3b44-4e1f-8958-9a8865b1efa1","trusted":true},"cell_type":"code","source":"testX.shape","execution_count":null,"outputs":[]},{"metadata":{"id":"loWs6cUvZyft","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"Y = to_categorical(Y, num_classes = 10) # one hot encoding (example: 2 -> [0,0,1,0,0,0,0,0,0,0])","execution_count":null,"outputs":[]},{"metadata":{"id":"x4GAdj3psrKr","colab_type":"code","outputId":"5aa3e5a3-c6dc-447a-9ab1-ffb6b17aaca9","colab":{"base_uri":"https://localhost:8080/","height":146},"trusted":true},"cell_type":"code","source":"Y # display the encoded target column","execution_count":null,"outputs":[]},{"metadata":{"id":"wkW8gp4maGHM","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"X_train, X_val, Y_train, Y_val = train_test_split(X, Y, test_size = 0.2, shuffle=True) # Split the train and the validation set for cross validation","execution_count":null,"outputs":[]},{"metadata":{"id":"AaC-FM2utnzG","colab_type":"code","outputId":"f93589a0-80ae-433c-acfa-537d6106a1b9","colab":{"base_uri":"https://localhost:8080/","height":90},"trusted":true},"cell_type":"code","source":"# dimensions of the cross validation data\nprint(X_train.shape)\nprint(X_val.shape)\nprint(Y_train.shape)\nprint(Y_val.shape)","execution_count":null,"outputs":[]},{"metadata":{"id":"d7d1S9gXubEM","colab_type":"text"},"cell_type":"markdown","source":"###Display sample images from numpy array"},{"metadata":{"id":"9CGnNAJDaKz6","colab_type":"code","outputId":"69e080ac-2513-4a5d-dd64-a85418570c71","colab":{"base_uri":"https://localhost:8080/","height":268},"trusted":true},"cell_type":"code","source":"g = plt.imshow(X_train[0][:,:,0]) # first image","execution_count":null,"outputs":[]},{"metadata":{"id":"LfctP7O2uVsT","colab_type":"code","outputId":"f2dde9a6-5786-4f0d-a881-4781654cec7e","colab":{"base_uri":"https://localhost:8080/","height":268},"trusted":true},"cell_type":"code","source":"g = plt.imshow(X_train[1][:,:,0]) # second image","execution_count":null,"outputs":[]},{"metadata":{"id":"ojSwKHZ78z6q","colab_type":"text"},"cell_type":"markdown","source":"#Constructing the Convolutional Neural Network (CNN)\n#### [Conv2D(relu) -> Conv2D(relu) -> MaxPool2D -> Dropout] -> [Conv2D(relu) -> Conv2D(relu) -> MaxPool2D -> Dropout] ->\n####-> Flatten -> Dense -> Dropout -> Out"},{"metadata":{"id":"tkd4BM0faTIo","colab_type":"code","outputId":"f4dbfd43-8c70-4830-e14c-619db717e402","colab":{"base_uri":"https://localhost:8080/","height":276},"trusted":true},"cell_type":"code","source":"model = Sequential()\nmodel.add(Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same', activation ='relu',\n                 input_shape = (28,28,1))) # input 2D convolutional layer\nmodel.add(Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same', activation ='relu'))\nmodel.add(MaxPool2D(pool_size=(2,2))) # 2D max pooling\nmodel.add(Dropout(0.25)) # applies dropout to prevent overfitting\n\nmodel.add(Conv2D(filters = 64, kernel_size = (3,3),padding = 'Same', activation ='relu'))\nmodel.add(Conv2D(filters = 64, kernel_size = (3,3),padding = 'Same', activation ='relu'))\nmodel.add(MaxPool2D(pool_size=(2,2), strides=(2,2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Flatten()) # Flattens without affecting the size\nmodel.add(Dense(256, activation = \"relu\")) # dense layer of size 256 units\nmodel.add(Dropout(0.5))\nmodel.add(Dense(10, activation = \"softmax\")) # dense layer of size 10 to output the digit value","execution_count":null,"outputs":[]},{"metadata":{"id":"45rgWT1-ahRe","colab_type":"code","outputId":"8f472c51-824b-4bb8-e153-81fd845cc130","colab":{"base_uri":"https://localhost:8080/","height":110},"trusted":true},"cell_type":"code","source":"optimizer = RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0) # RMSprop optimizer divides the gradient by root mean square\nmodel.compile(optimizer = optimizer , loss = \"categorical_crossentropy\", metrics=[\"accuracy\"]) # Compile the model\nlearning_rate_reduction = ReduceLROnPlateau(monitor='val_accuracy', \n                                            patience=3, \n                                            factor=0.3, \n                                            verbose=1, \n                                            min_lr=0.00001) # reduces learning rate if the learning is stagnant","execution_count":null,"outputs":[]},{"metadata":{"id":"-5EQgNqFbOua","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"# Generate batches of tensor image data with real-time data augmentation\n# The data will be looped over (in batches).\n# With data augmentation to prevent overfitting (accuracy 0.99286)\ndatagen = ImageDataGenerator(\n        featurewise_center=False,  # set input mean to 0 over the dataset\n        samplewise_center=False,  # set each sample mean to 0\n        featurewise_std_normalization=False,  # divide inputs by std of the dataset\n        samplewise_std_normalization=False,  # divide each input by its std\n        zca_whitening=False,  # apply ZCA whitening\n        rotation_range=10,  # rotate images in the range (degrees, 0 to 180)\n        zoom_range = 0.1, # zoom image\n        width_shift_range=0.1,  # shift images horizontally (fraction of total width)\n        height_shift_range=0.1,  # shift images vertically (fraction of total height)\n        horizontal_flip=False,  # flip images horizontally\n        vertical_flip=False)  # flip images vertically\ndatagen.fit(X_train) # apply datagen augmentation to train.csv data","execution_count":null,"outputs":[]},{"metadata":{"id":"ilTosJ2obcET","colab_type":"code","outputId":"d8855049-f750-4cce-ecc9-8aafa186afdb","colab":{"base_uri":"https://localhost:8080/","height":1000},"trusted":true},"cell_type":"code","source":"# Fit the model\nepochs = 30\nbatch_size = 96\nhistory = model.fit_generator(datagen.flow(X_train,Y_train, batch_size=batch_size),\n                              epochs = epochs, validation_data = (X_val,Y_val),\n                              verbose = 2, steps_per_epoch=X_train.shape[0] // batch_size\n                              , callbacks=[learning_rate_reduction])","execution_count":null,"outputs":[]},{"metadata":{"id":"MoNRnYDWwdiS","colab_type":"text"},"cell_type":"markdown","source":"###Visualizing the model **loss** and **accuracy**"},{"metadata":{"id":"BVctXW7DyE8V","colab_type":"code","outputId":"6624b2ee-3487-4014-d684-20e82f9e055c","colab":{"base_uri":"https://localhost:8080/","height":35},"trusted":true},"cell_type":"code","source":"# list all data in history\nprint(history.history.keys())\n#history.history['loss']","execution_count":null,"outputs":[]},{"metadata":{"id":"ffKktKUlbm8-","colab_type":"code","outputId":"a8d6553e-f255-432d-d1e0-0d242176351f","colab":{"base_uri":"https://localhost:8080/","height":269},"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(2,1) # aligning two plots horizontally\nax[0].plot(history.history['loss'], label=\"Training loss\") \nax[0].plot(history.history['val_loss'],label=\"validation loss\")\nlegend = ax[0].legend(loc='best')\n\nax[1].plot(history.history['accuracy'], color='b', label=\"Training accuracy\")\nax[1].plot(history.history['val_accuracy'], color='r',label=\"Validation accuracy\")\nlegend = ax[1].legend(loc='best')","execution_count":null,"outputs":[]},{"metadata":{"id":"uqmkdlJE0X-Y","colab_type":"text"},"cell_type":"markdown","source":"###Making predictions on test.csv data"},{"metadata":{"id":"7Mxy0oRrdFjP","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"results = model.predict(testX) # predicting test.csv data\nresults = np.argmax(results,axis = 1) # select the index with maximum probability\nresults = pd.Series(results,name=\"label\")","execution_count":null,"outputs":[]},{"metadata":{"id":"l9U_5Ll2dQlY","colab_type":"code","outputId":"c3fc0662-9fa7-4861-de6b-d3c365048471","colab":{"base_uri":"https://localhost:8080/","height":35},"trusted":true},"cell_type":"code","source":"# creating submission file\n#submission = pd.concat([pd.Series(range(1,28001),name = \"ImageId\"),results],axis = 1) \nsubmission = pd.concat([test['id'],results],axis = 1) \nsubmission.to_csv(\"submission.csv\",index=False)\nprint('csv file ready for submission')","execution_count":null,"outputs":[]},{"metadata":{"id":"MyX7QNV-IfzP","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"colab":{"name":"kannada_mnist_using_CNN.ipynb","provenance":[],"toc_visible":true},"kernelspec":{"name":"python3","display_name":"Python 3"}},"nbformat":4,"nbformat_minor":1}