{"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 # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-29T10:48:48.003782Z","iopub.execute_input":"2021-06-29T10:48:48.00441Z","iopub.status.idle":"2021-06-29T10:48:48.014079Z","shell.execute_reply.started":"2021-06-29T10:48:48.004358Z","shell.execute_reply":"2021-06-29T10:48:48.013249Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"How great is this that an MNIST-like dataset is available in Kannada Language! I was absolutely delighted when I came across it... I sincerely thank the dataset author [Vinay Uday Prabhu](https://www.kaggle.com/higgstachyon/datasets) sir for making such a creative and interesting dataset available to everyone.","metadata":{}},{"cell_type":"markdown","source":"# Reading the Data","metadata":{}},{"cell_type":"code","source":"test = pd.read_csv(\"../input/Kannada-MNIST/test.csv\")\ndata = pd.read_csv(\"../input/Kannada-MNIST/train.csv\")","metadata":{"execution":{"iopub.status.busy":"2021-06-29T10:48:50.479228Z","iopub.execute_input":"2021-06-29T10:48:50.479586Z","iopub.status.idle":"2021-06-29T10:48:54.787266Z","shell.execute_reply.started":"2021-06-29T10:48:50.479557Z","shell.execute_reply":"2021-06-29T10:48:54.786422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(data.head())","metadata":{"execution":{"iopub.status.busy":"2021-06-29T10:48:56.786738Z","iopub.execute_input":"2021-06-29T10:48:56.788311Z","iopub.status.idle":"2021-06-29T10:48:56.801047Z","shell.execute_reply.started":"2021-06-29T10:48:56.788257Z","shell.execute_reply":"2021-06-29T10:48:56.799935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"So, we see that we have 784 pixels, that is 28x28 pixel dataset. Here are the numbers for reference and understanding :\n\n![](https://d3i71xaburhd42.cloudfront.net/832f095f729a106fbd1cb11015851e0c86b4b805/2-TableI-1.png)","metadata":{}},{"cell_type":"markdown","source":"# Preparing the Data:","metadata":{}},{"cell_type":"code","source":"#assigning the training data\ntrain_y = data[\"label\"]\ntrain_x = data.drop([\"label\"], axis = 1)\n#we do the same operations on the test set as well\ntest_y = data[\"label\"]\ntest_x = data.drop([\"label\"], axis = 1)\n\n#Now we convert the dataframe into an array so we can reshape the data \ntrain_x = np.array(train_x).reshape(-1,28,28)\ntest_x = np.array(test_x).reshape(-1,28,28)\n#The -1 that we passed as the first parameter is the index of the last row\n#So, what numpy understands is to start from Row1 till the last Row.\n\n#reshaping the data\ntrain_x = train_x.reshape(-1, 28,28, 1)\ntest_x = test_x.reshape(-1, 28,28, 1)\n\n#We clean/normalize the data by dividing it by 255 because we want our values ranging between 0 to 1\n#It also GREATLY improves the accuracy at the end\ntrain_x = train_x/255\ntest_x = test_x/255","metadata":{"execution":{"iopub.status.busy":"2021-06-29T10:49:04.804797Z","iopub.execute_input":"2021-06-29T10:49:04.805227Z","iopub.status.idle":"2021-06-29T10:49:05.654211Z","shell.execute_reply.started":"2021-06-29T10:49:04.805191Z","shell.execute_reply":"2021-06-29T10:49:05.653142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Encoding the values with \"to_categorical\" from keras","metadata":{}},{"cell_type":"code","source":"from keras.utils.np_utils import to_categorical \ntrain_y = to_categorical(train_y, num_classes = 10)\ntest_y = to_categorical(test_y, num_classes = 10)","metadata":{"execution":{"iopub.status.busy":"2021-06-29T10:49:09.12854Z","iopub.execute_input":"2021-06-29T10:49:09.128917Z","iopub.status.idle":"2021-06-29T10:49:09.136659Z","shell.execute_reply.started":"2021-06-29T10:49:09.128886Z","shell.execute_reply":"2021-06-29T10:49:09.135455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_x.shape, train_y.shape","metadata":{"execution":{"iopub.status.busy":"2021-06-29T10:49:11.996727Z","iopub.execute_input":"2021-06-29T10:49:11.997293Z","iopub.status.idle":"2021-06-29T10:49:12.003639Z","shell.execute_reply.started":"2021-06-29T10:49:11.997236Z","shell.execute_reply":"2021-06-29T10:49:12.00286Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Plotting the Numbers","metadata":{}},{"cell_type":"code","source":"#Displaying the images\nimport matplotlib.pyplot as plt\nplt.figure()\nfor i in range(16):\n    plt.subplot(4,4,i+1)\n    plt.imshow(train_x[i], cmap = plt.cm.binary)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-06-29T10:49:14.020759Z","iopub.execute_input":"2021-06-29T10:49:14.021123Z","iopub.status.idle":"2021-06-29T10:49:15.380416Z","shell.execute_reply.started":"2021-06-29T10:49:14.021093Z","shell.execute_reply":"2021-06-29T10:49:15.379727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Making the Neural Network","metadata":{}},{"cell_type":"markdown","source":"Let's make a Convolutional Neural Network for the image classification task.","metadata":{}},{"cell_type":"markdown","source":"Since we have 10 outputs(numbers from 0-9) we will have 10 neurons in the output layer with **softmax** as the activation function.\n\nWe have 8 layers in our CNN - Input layer, 1st Convolutional layer, 1st pooling layer, 2nd Convolutional layer, 2nd pooling layer, Flattening layer, Hidden Layer and Output layer respectively.\n\n* If you want to read more about CNNs you can refer this link - [How Do Convolutional Layers Work in Deep Learning Neural Networks?](https://machinelearningmastery.com/convolutional-layers-for-deep-learning-neural-networks/)\n\n* Or for more comprehensive understanding you can also refer this link [A Comprehensive Guide to Convolutional Neural Networks — the ELI5 way](https://towardsdatascience.com/a-comprehensive-guide-to-convolutional-neural-networks-the-eli5-way-3bd2b1164a53), this really cleared all my doubts regarding CNNs.\n\n* So, in the input layer we provide the shape as a 3 dimentional tensor. The first two are the rows and columns obviously, and the third one is the colour channel, in case you're wondering, like 3 for (R,G,B), etc.","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers, models\nfrom keras.layers.advanced_activations import LeakyReLU","metadata":{"execution":{"iopub.status.busy":"2021-06-29T10:49:18.790466Z","iopub.execute_input":"2021-06-29T10:49:18.790948Z","iopub.status.idle":"2021-06-29T10:49:18.794479Z","shell.execute_reply.started":"2021-06-29T10:49:18.790918Z","shell.execute_reply":"2021-06-29T10:49:18.793564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = models.Sequential()\nmodel.add(layers.Conv2D(32, kernel_size = (3,3), activation = \"linear\", input_shape = (28, 28, 1), padding = \"same\"))\nmodel.add(LeakyReLU(alpha = 0.1))\nmodel.add(MaxPooling2D((2,2), padding = \"same\"))\nmodel.add(Conv2D(64, (3, 3), activation='linear',padding='same'))\nmodel.add(LeakyReLU(alpha=0.1))\nmodel.add(MaxPooling2D(pool_size=(2, 2),padding='same'))\nmodel.add(Conv2D(128, (3, 3), activation='linear',padding='same'))\nmodel.add(LeakyReLU(alpha=0.1))                  \nmodel.add(MaxPooling2D(pool_size=(2, 2),padding='same'))\nmodel.add(Flatten())\nmodel.add(Dense(128, activation='linear'))\nmodel.add(LeakyReLU(alpha=0.1))                  \nmodel.add(Dense(10, activation='softmax'))","metadata":{"execution":{"iopub.status.busy":"2021-06-29T10:49:21.545995Z","iopub.execute_input":"2021-06-29T10:49:21.546393Z","iopub.status.idle":"2021-06-29T10:49:21.622942Z","shell.execute_reply.started":"2021-06-29T10:49:21.546366Z","shell.execute_reply":"2021-06-29T10:49:21.622052Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Compiling the Model","metadata":{}},{"cell_type":"markdown","source":"The loss function used is categorical_crossentropy, the metrics used for evaluation are \"accuracy\", and the optimizer used is Adam. Other optimizers that you can experiment with are\n\n*     SGD\n*     RMSprop\n*     Adam\n*     Adadelta\n*     Adagrad\n*     Adamax\n*     Nadam\n*     Ftrl\n","metadata":{}},{"cell_type":"code","source":"model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adam(),metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2021-06-29T10:49:25.053646Z","iopub.execute_input":"2021-06-29T10:49:25.054004Z","iopub.status.idle":"2021-06-29T10:49:25.066811Z","shell.execute_reply.started":"2021-06-29T10:49:25.053964Z","shell.execute_reply":"2021-06-29T10:49:25.065903Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2021-06-29T10:49:27.184993Z","iopub.execute_input":"2021-06-29T10:49:27.18541Z","iopub.status.idle":"2021-06-29T10:49:27.197679Z","shell.execute_reply.started":"2021-06-29T10:49:27.185375Z","shell.execute_reply":"2021-06-29T10:49:27.196271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training the Model","metadata":{}},{"cell_type":"code","source":"train_model = model.fit(train_x, train_y, batch_size = 64, epochs = 10)","metadata":{"execution":{"iopub.status.busy":"2021-06-29T10:49:29.95988Z","iopub.execute_input":"2021-06-29T10:49:29.960266Z","iopub.status.idle":"2021-06-29T10:57:30.132619Z","shell.execute_reply.started":"2021-06-29T10:49:29.960233Z","shell.execute_reply":"2021-06-29T10:57:30.131872Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Predicting Test Data","metadata":{}},{"cell_type":"code","source":"test_x.shape, data.shape, train_x.shape","metadata":{"execution":{"iopub.status.busy":"2021-06-29T10:48:13.503341Z","iopub.execute_input":"2021-06-29T10:48:13.503686Z","iopub.status.idle":"2021-06-29T10:48:13.509767Z","shell.execute_reply.started":"2021-06-29T10:48:13.503657Z","shell.execute_reply":"2021-06-29T10:48:13.508796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#We split the training set provided into a validation set as well to determine overfitting or underfitting to evaluate the model\n#I have not done the evaluation step here, we'll just move on to prediction\npredicted_value = model.predict_classes(test_x)","metadata":{"execution":{"iopub.status.busy":"2021-06-29T11:02:18.241323Z","iopub.execute_input":"2021-06-29T11:02:18.241903Z","iopub.status.idle":"2021-06-29T11:02:36.225771Z","shell.execute_reply.started":"2021-06-29T11:02:18.241863Z","shell.execute_reply":"2021-06-29T11:02:36.224805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_x.shape","metadata":{"execution":{"iopub.status.busy":"2021-06-29T11:03:11.430869Z","iopub.execute_input":"2021-06-29T11:03:11.43149Z","iopub.status.idle":"2021-06-29T11:03:11.438556Z","shell.execute_reply.started":"2021-06-29T11:03:11.431436Z","shell.execute_reply":"2021-06-29T11:03:11.437813Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#our test set has 60000 rows, but does not include an ID column, so we will define it\nimageid = list(range(1,60001))\nsubmission = pd.DataFrame({\"id\": imageid, \"label\": predicted_value})\nsubmission.to_csv(\"submission.csv\", index = False)","metadata":{"execution":{"iopub.status.busy":"2021-06-29T11:03:22.754056Z","iopub.execute_input":"2021-06-29T11:03:22.754418Z","iopub.status.idle":"2021-06-29T11:03:22.900536Z","shell.execute_reply.started":"2021-06-29T11:03:22.754386Z","shell.execute_reply":"2021-06-29T11:03:22.899322Z"},"trusted":true},"execution_count":null,"outputs":[]}]}