{"cells":[{"metadata":{},"cell_type":"markdown","source":"Code of my basic CNN including additional information where needed. Keras website has a great explanation and documentation when you are getting started: https://keras.io/getting-started/sequential-model-guide/\n\nMost of the top 10 CNN kernels at Kaggle are the same so I tried focussing on additional explanations of the functions that I use and links that explain the functions further.\n\nhighly recommend also checking out Yassine's kernel as he does a great job of interpreting the results at of a CNN. https://www.kaggle.com/yassineghouzam/introduction-to-cnn-keras-0-997-top-6"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# import all of our packages\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential\nfrom keras.layers.normalization import BatchNormalization\nfrom keras.optimizers import Adam\nfrom keras.layers import Activation, Dense, Dropout, Flatten\nfrom keras.layers import Conv2D, MaxPool2D\nfrom keras.utils import np_utils \nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nfrom keras.callbacks import ReduceLROnPlateau","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"# import our dataset using the pandas read_csv option\ntest_import = pd.read_csv(\"../input/Kannada-MNIST/test.csv\");\ntrain_import = pd.read_csv(\"../input/Kannada-MNIST/train.csv\");","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# test the data for null values. notice how the functions are stacked. isnull() shows a 1 if its null. Any() checks which ones. \n# Describe shows it in a format thats easier to read (otherwise you would have to check the whole matrix if theres a 1 somewhere)\ntrain_import.isnull().any().describe()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# do this again for the training set\ntrain_import.isnull().any().describe()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# drop the label column from the dataset so we only keep the pixel information. The first column represents\n# the outcome (number between 0 and 10).\nX_train = train_import.drop('label', axis=1)\n# obtain the first column vector from the dataset and use it to label data as this is the outcome. (number between 0 and 10)\ny_train = train_import.iloc[:, 0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# check the histogram of distribution from our training set using the built in function hist(). Alternatively you could\n# use a library such as matplotlib.  We want to make sure that the distribution between numbers that we have examples of are\n# the same. Imagine if we had 1000 examples of the number 2 but only a couple for the number 3. Its just a quick check.\ny_train.hist()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_import = test_import.drop('id', axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# normalize the pixel intensity values. Great video on normalization: https://www.youtube.com/watch?v=FDCfw-YqWTE\nX_train = X_train / 255.0\ntest_import = test_import / 255.0\n\n# reshape it from a m * 728 matrix (m is number of examples) to a matrix of m * 28 * 28 where 1 is an additional channel.\n# usually you use this last channel for the RGB values but in this example its not needed\nX_train = X_train.values.reshape(-1,28,28,1)\ntest = test_import.values.reshape(-1,28,28,1)\n\n# Encode labels to one hot vectors (ex : 2 -> [0,0,1,0,0,0,0,0,0,0])\n# reason for this is that in a neural network each node in the output layer outputs 0 or 1.\n# more information about one hot encoder\n# https://hackernoon.com/what-is-one-hot-encoding-why-and-when-do-you-have-to-use-it-e3c6186d008f\nY_train =  np_utils.to_categorical(y_train, num_classes = 10)\n\n# split set into training and validation. \nX_train, X_val, Y_train, Y_val = train_test_split(X_train, Y_train, test_size=0.1, random_state=42)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# creating the model. Guide from Keras: https://keras.io/getting-started/sequential-model-guide/\n# more information about the activation functions relu vs softmax: https://github.com/Kulbear/deep-learning-nano-foundation/wiki/ReLU-and-Softmax-Activation-Functions\nmodel = Sequential()\nmodel.add(Conv2D(32, (5, 5), input_shape=(28,28,1), activation='relu'))\nmodel.add(MaxPool2D(pool_size=(2, 2)))\nmodel.add(Conv2D(32, (3, 3), activation='relu'))\nmodel.add(MaxPool2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.2))\nmodel.add(Flatten())\nmodel.add(Dense(128, activation='relu'))\nmodel.add(Dense(10, activation='softmax'))\n\nmodel.compile(loss='categorical_crossentropy', optimizer=Adam(), metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# create more sample images using ImageDataGenerator.This ensures we have more data to train on. More info about function here: https://keras.io/preprocessing/image/\nimagegen = ImageDataGenerator(\n        featurewise_center=False, \n        samplewise_center=False, \n        featurewise_std_normalization=False, \n        samplewise_std_normalization=False,\n        zca_whitening=False, \n        rotation_range=9, \n        zoom_range = 0.25,\n        width_shift_range=0.25,\n        height_shift_range=0.25, \n        horizontal_flip=False, \n        vertical_flip=False)\n\nimagegen.fit(X_train)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# set epochs (1 epoch = 1 run) higher for better result (set lower to save costs)\nepochs = 4\nbatch_size = 64","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# fit the model with generated images. Asign it to fitobj so we can later check on the data\nfitobj = model.fit_generator(imagegen.flow(X_train,Y_train, batch_size=batch_size),\n                              epochs = epochs, validation_data = (X_val,Y_val),\n                              verbose = 1, steps_per_epoch=X_train.shape[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"score = model.evaluate(X_val, Y_val, batch_size=30)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# review the model score\nscore","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# view history of model. It prints for every epoch so you can graph it out to see if you are actually improving\nfitobj.history\n\n# highly recommend to review your data afterward to see which examples were false positives but let's stick to the bare minimum\n# to get this kernel to run.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# predict results\nresults = model.predict(test)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"results = np.argmax(results,axis = 1)\nsubmission = pd.read_csv('../input/Kannada-MNIST/sample_submission.csv')\nsubmission['label'] = results\nsubmission.to_csv('submission.csv', index=False)\nsubmission.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# check if we have a bias towards a specific example in the results\nsubmission.hist()","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":1}