{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras import layers\nfrom pathlib import Path\nimport numpy as np\nimport cv2\nimport pandas as pd \nfrom tensorflow.keras.preprocessing.image import img_to_array, load_img\nimport h5py\nfrom keras.models import load_model\nimport csv\n\nprint(tf.__version__)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"image_size = 28\nPATH = '../input/Kannada-MNIST'\n\nrow_length = 28\ncolumn_length = 28\n\ntraining_size = 0.85\nvalidation_size = 0.10\ntest_size = 0.05","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"training_end_index_ratio = training_size\nvalidation_end_index_ratio = training_size + validation_size\n\ndf_train = pd.read_csv(PATH + \"/\" + \"train.csv\")\ndf_dig = pd.read_csv(PATH + \"/\" + \"Dig-MNIST.csv\")\n\ndf_train = df_train.sample(frac=1).reset_index(drop=True)\ndf_dig = df_dig.sample(frac=1).reset_index(drop=True)\n\ndf_train_train, df_train_validation, df_train_test = np.split(df_train, [int(training_end_index_ratio * len(df_train)), int(validation_end_index_ratio * len(df_train))])\ndf_dig_train, df_dig_validation, df_dig_test = np.split(df_dig, [int(training_end_index_ratio * len(df_dig)), int(validation_end_index_ratio * len(df_dig))])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_output_vector(category):\n  output_labels = np.zeros(10)\n  output_labels[int(category)] = 1\n  return np.array(output_labels, dtype=np.float32)\n\ndef get_formatted_labels(data_list):\n    labels = []\n    for i in range(0,len(data_list)):\n        labels.append(get_output_vector(data_list[i]))\n    return np.array(labels)\n\ndef convert_two_dimentional(single_list):\n  return single_list.reshape((image_size, image_size))\n\ndef convert_grey2rgb(two_list):\n  return cv2.merge([two_list, two_list, two_list])\n\ndef get_image(row):\n  return convert_grey2rgb(convert_two_dimentional(np.array(row, dtype=np.float32)))\n\ndef format_list_data(df_data_1, df_data_2):\n    data_1 = np.array(df_data_1.drop(columns=\"label\"))\n    data_2 = np.array(df_data_2.drop(columns=\"label\"))\n    list_data = []\n    for i in range(0,len(data_1)):\n        list_data.append(get_image(data_1[i]))\n    for i in range(0,len(data_2)):\n        list_data.append(get_image(data_2[i]))\n    return np.array(list_data, dtype=np.float32) / 255","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_train_data():\n    return format_list_data(df_train_train, df_dig_train), get_formatted_labels(np.append(df_train_train[\"label\"], df_dig_train[\"label\"]))\n\ndef get_validation_data():\n    return format_list_data(df_train_validation, df_dig_validation), get_formatted_labels(np.append(df_train_validation[\"label\"], df_dig_validation[\"label\"]))\n\ndef get_test_data():\n    return format_list_data(df_train_test, df_dig_test), get_formatted_labels(np.append(df_train_test[\"label\"], df_dig_test[\"label\"]))\n\ndef format_submission_data(df_data):\n    data = np.array(df_data.drop(columns=\"id\"))\n    list_data = []\n    for i in range(0,len(data)):\n        list_data.append(get_image(data[i]))\n    return np.array(list_data, dtype=np.float32) / 255\n\ndef get_submission_test_data():\n    df_test = pd.read_csv(PATH + \"/\" + \"test.csv\")\n    return format_submission_data(df_test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learning_rate = 0.001\nepochs = 20\nearly_stop_constant = 7\nbatch_size_32 = 32\nbatch_size_64 = 64\nbatch_size_128 = 128\noptimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)\nloss = tf.keras.losses.categorical_crossentropy\nmetrics = ['accuracy']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rotation_range=20,\n                                   width_shift_range=0.15,\n                                   height_shift_range=0.15,\n                                   zoom_range=0.20,\n                                   horizontal_flip=False)\n\nval_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rotation_range=20,\n                                   width_shift_range=0.15,\n                                   height_shift_range=0.15,\n                                   zoom_range=0.20,\n                                   horizontal_flip=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"REGULARIZATION_CONSTANT = 0\nDROPOUT_CONSTANT = 0.2\n\ninput_layer = tf.keras.Input(shape=(image_size, image_size, 3), name=\"Input_Layer\")\n\nx = tf.keras.layers.Conv2D(filters=64, \n                           kernel_size=(3,3), \n                           padding=\"same\", \n                           activation=tf.keras.activations.relu)(input_layer)\nx = tf.keras.layers.BatchNormalization()(x)\n\nx = tf.keras.layers.Conv2D(filters=64, \n                           kernel_size=(3,3), \n                           padding=\"same\",\n                           activation=tf.keras.activations.relu)(input_layer)\nx = tf.keras.layers.BatchNormalization()(x)\n\nx = tf.keras.layers.Conv2D(filters=64, \n                           kernel_size=(3,3), \n                           padding=\"same\",\n                           activation=tf.keras.activations.relu)(x)\nx = tf.keras.layers.BatchNormalization()(x)\nx = tf.keras.layers.MaxPool2D()(x)\nx = tf.keras.layers.Dropout(DROPOUT_CONSTANT)(x)\n\nx = tf.keras.layers.Conv2D(filters=128, \n                           kernel_size=(3,3), \n                           padding=\"same\", \n                           activation=tf.keras.activations.relu)(x)\nx = tf.keras.layers.BatchNormalization()(x)\n\nx = tf.keras.layers.Conv2D(filters=128, \n                           kernel_size=(3,3), \n                           padding=\"same\", \n                           activation=tf.keras.activations.relu)(x)\nx = tf.keras.layers.BatchNormalization()(x)\n\nx = tf.keras.layers.Conv2D(filters=128, \n                           kernel_size=(3,3), \n                           padding=\"same\", \n                           activation=tf.keras.activations.relu)(x)\nx = tf.keras.layers.BatchNormalization()(x)\nx = tf.keras.layers.MaxPool2D()(x)\nx = tf.keras.layers.Dropout(DROPOUT_CONSTANT)(x)\n\nx = tf.keras.layers.Conv2D(filters=256,\n                           kernel_size=(5,5), \n                           padding=\"same\", \n                           activation=tf.keras.activations.relu)(x)\nx = tf.keras.layers.BatchNormalization()(x)\nx = tf.keras.layers.MaxPool2D()(x)\nx = tf.keras.layers.Dropout(DROPOUT_CONSTANT)(x)\n\nx = tf.keras.layers.Flatten()(x)\n\nx = tf.keras.layers.Dense(units=1024, \n                          activation=tf.keras.activations.relu, \n                          name=\"Hidden_Layer_1\")(x)\nx = tf.keras.layers.Dropout(DROPOUT_CONSTANT)(x)\nx = tf.keras.layers.Dense(units=512, \n                          activation=tf.keras.activations.relu, \n                          name=\"Hidden_Layer_2\")(x)\nx = tf.keras.layers.Dropout(DROPOUT_CONSTANT)(x)\noutput_layer = tf.keras.layers.Dense(units=10, activation=tf.keras.activations.softmax)(x)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_model():\n    functional_model = tf.keras.Model(input_layer, output_layer)\n    functional_model.summary()\n    return functional_model\n\ndef exponential_lr_decay(epoch, initial_learningrate = 0.01):\n    k = 0.001\n    max_epoch_default_learningrate = 1\n    if(epoch <= max_epoch_default_learningrate):\n      return initial_learningrate\n    else:\n      return initial_learningrate * np.exp(-1 * k * epoch)\n\ncheckpoint = tf.keras.callbacks.ModelCheckpoint('my_model.h5', monitor='accuracy', save_best_only=True)\n\nlr = tf.keras.callbacks.ReduceLROnPlateau(monitor=\"accuracy\", \n                                            patience=3,\n                                            factor=0.5,\n                                            min_lr=0.000001)\n\nclass CustomCallback(tf.keras.callbacks.Callback):\n    \n    def __init__(self, test_data, test_label):\n        super(CustomCallback,self).__init__()\n        self.test_data = test_data\n        self.test_label = test_label\n    \n    def on_epoch_end(self, epoch, logs=None):\n        self.find_test_accuracy(self.test_data, self.test_label)\n\n    def is_equal(self, val1, val2):\n        return val1 == val2\n\n    def get_correct_count(self, y, yhat, current_count):\n        if self.is_equal(y, yhat):\n            return current_count + 1\n        else:\n            return current_count\n\n    def find_test_accuracy(self, test_data, test_labels):\n        yhat = np.argmax(self.model.predict(test_data), axis=1)\n        y = np.argmax(test_labels, axis=1)\n        correct_count = 0\n        assert len(yhat) == len(y)\n        for i in range(0,len(y)):\n            correct_count = self.get_correct_count(y[i], yhat[i], correct_count)\n        print(\"Test Data Accuracy: \" + str(correct_count * 100 / len(y)) + \"%\") \n\n        \ncallbacks = [lr, checkpoint]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"functional_model = get_model()\nfunctional_model.compile(optimizer=optimizer, loss=loss, metrics=metrics)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data, train_labels = get_train_data()\nvalidation_data, validation_labels = get_validation_data()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = functional_model.fit_generator(train_datagen.flow(x=train_data, y=train_labels, batch_size=128), \n                               epochs=30, \n                               callbacks=callbacks,\n                               validation_data=(validation_data, validation_labels))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def evaluate_test_data():\n    test_data, test_labels = get_test_data()\n    y = np.argmax(test_labels,axis=1)\n    yhat =  np.argmax(functional_model.predict(test_data),axis=1)\n    correct=0\n    for i in range(0,len(y)):\n        if y[i] == yhat[i]:\n            correct = correct + 1\n            \n    print(\"Test Accuracy: \" + str(correct * 100/ len(y)))\n    \nevaluate_test_data()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_data = get_submission_test_data()\nyhat =  np.argmax(functional_model.predict(test_data),axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_submission = pd.read_csv(PATH + \"/\" + \"sample_submission.csv\")\ndf_submission[\"label\"] = pd.Series(yhat)\ndf_submission.to_csv(\"submission.csv\", index=False)\ndf_submission.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"functional_model.save('my_model.h5')","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}