{"cells":[{"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 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":{},"cell_type":"markdown","source":"# Imports"},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport cv2\nimport matplotlib.pyplot as plt\n\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, Dense, MaxPool2D, Dropout, Flatten, Activation, MaxPooling2D, Input\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import Model\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"\n\n# Load Datasets"},{"metadata":{"trusted":true},"cell_type":"code","source":"ORIGINAL_IMG_HEIGHT = 137\nORIGINAL_IMG_WIDTH = 236\nIMG_SIZE = 128\nBASE_PATH='/kaggle/input/bengaliai-cv19/'\nEPOCHS = 15\nGRAPHME_CLASSES = 168\nVOWEL_CLASSES = 11\nCONSONENT_CLASSES = 7","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class_map_ds = pd.read_csv(BASE_PATH + 'class_map.csv')\nclass_map_ds.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.read_csv(BASE_PATH + 'test.csv')\ntest_df.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv(BASE_PATH + 'train.csv')\ntrain_df.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_image_files = ['train_image_data_0.parquet', 'train_image_data_1.parquet', 'train_image_data_2.parquet', 'train_image_data_3.parquet']","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Plotting"},{"metadata":{"trusted":true},"cell_type":"code","source":"def show_batch(images_array, labels_array = None, resize_shape = None):\n  plt.figure(figsize=(10,10))\n  for n in range(25):\n    ax = plt.subplot(5,5,n+1)\n    img = images_array[n]\n    if resize_shape is not None:\n        img = img.reshape(resize_shape)\n    plt.imshow(img)\n    if labels_array is not None:\n        plt.title(labels_array[n])\n    plt.axis('off')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def show_accuracy(history):\n    grapheme_op_acc = history.history['grapheme_op_accuracy']\n    vowel_op_acc = history.history['vowel_op_accuracy']\n    consonent_op_acc = history.history['consonent_op_accuracy']\n\n    grapheme_op_loss = history.history['grapheme_op_loss']\n    vowel_op_loss = history.history['vowel_op_loss']\n    consonent_op_loss = history.history['consonent_op_loss']\n    loss = history.history['loss']\n\n    val_grapheme_op_acc = history.history['val_grapheme_op_accuracy']\n    val_vowel_op_acc = history.history['val_vowel_op_accuracy']\n    val_consonent_op_acc = history.history['val_consonent_op_accuracy']\n\n    val_grapheme_op_loss = history.history['val_grapheme_op_loss']\n    val_vowel_op_loss = history.history['val_vowel_op_loss']\n    val_consonent_op_loss = history.history['val_consonent_op_loss']\n    val_loss = history.history['val_loss']\n\n    epochs_range = range(EPOCHS)\n\n    plt.figure(figsize=(20, 5))\n    \n    plt.subplot(1, 4, 1)\n    plt.plot(epochs_range, grapheme_op_acc, label='Grapheme accuracy')\n    plt.plot(epochs_range, vowel_op_acc, label='Vowel Accuracy')\n    plt.plot(epochs_range, consonent_op_acc, label='Consonent accuracy')\n    plt.legend(loc='lower right')\n    plt.title('Training Accuracy')\n\n    plt.subplot(1, 4, 2)\n    plt.plot(epochs_range, val_grapheme_op_acc, label='Val grapheme accuracy')\n    plt.plot(epochs_range, val_vowel_op_acc, label='Val vowel Accuracy')\n    plt.plot(epochs_range, val_consonent_op_acc, label='Val consonent accuracy')\n    plt.legend(loc='lower right')\n    plt.title('Validation Accuracy')\n\n    plt.subplot(1, 4, 3)\n    plt.plot(epochs_range, val_grapheme_op_acc, label='Grapheme loss')\n    plt.plot(epochs_range, val_vowel_op_acc, label='Vowel loss')\n    plt.plot(epochs_range, val_consonent_op_acc, label='Consonent loss')\n    plt.plot(epochs_range, loss, label='Training Loss')\n    plt.legend(loc='upper right')\n    plt.title('Training Loss')\n\n    plt.subplot(1, 4, 4)\n    plt.plot(epochs_range, val_grapheme_op_loss, label='Val grapheme loss')\n    plt.plot(epochs_range, val_vowel_op_loss, label='Val vowel loss')\n    plt.plot(epochs_range, val_consonent_op_loss, label='Val consonent loss')\n    plt.plot(epochs_range, val_loss, label='Validation Loss')\n    plt.legend(loc='upper right')\n    plt.title('Validation Loss')\n\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Prepare Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"def split(df):\n    non_image_coiumn = ['grapheme_root', 'vowel_diacritic', 'consonant_diacritic']\n    X_train, X_val, y_train, y_val =  train_test_split(\n        df.drop(non_image_coiumn, axis=1), \n        df.loc[:, non_image_coiumn],\n        test_size=0.25, \n        random_state=42\n      )\n    X_val, X_test, y_val, y_test =  train_test_split(\n        X_val, \n        y_val,\n        test_size=0.2, \n        random_state=42\n      )\n    return X_train, X_val, X_test, y_train, y_val, y_test","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def input_pipeline(file_name):\n    df = pd.merge(\n            pd.read_parquet(BASE_PATH + file_name), \n            train_df,\n            on='image_id'\n          ).drop(['image_id', 'grapheme'], axis=1)\n\n    return split(df=df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def resize_images(images):\n    return [cv2.resize(image, (IMG_SIZE, IMG_SIZE)) for image in images]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_train_test_data(file_name):\n    X_train, X_val, X_test, y_train, y_val, y_test = input_pipeline(file_name)\n    X_train = X_train.to_numpy(dtype='f').reshape(X_train.shape[0],ORIGINAL_IMG_HEIGHT, ORIGINAL_IMG_WIDTH)\n    X_val = X_val.to_numpy(dtype='f').reshape(X_val.shape[0],ORIGINAL_IMG_HEIGHT, ORIGINAL_IMG_WIDTH)\n    X_test = X_test.to_numpy(dtype='f').reshape(X_test.shape[0],ORIGINAL_IMG_HEIGHT, ORIGINAL_IMG_WIDTH)\n    X_train = resize_images(X_train)\n    X_val = resize_images(X_val)\n    X_test = resize_images(X_test)\n    y_train = y_train.to_numpy()\n    y_val = y_val.to_numpy()\n    y_test = y_test.to_numpy()\n    return X_train, X_val, X_test, y_train, y_val, y_test","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# CNN: Lenet"},{"metadata":{"trusted":true},"cell_type":"code","source":"inp = Input(shape=(IMG_SIZE, IMG_SIZE, 1))\nx = Conv2D(16, 3, padding='same', activation='relu')(inp)\nx = MaxPooling2D()(x)\nx = Dropout(0.2)(x)\nx = Conv2D(32, 3, padding='same', activation='relu')(x)\nx = MaxPooling2D()(x)\nx = Conv2D(64, 3, padding='same', activation='relu')(x)\nx = MaxPooling2D()(x)\nx = Dropout(0.2)(x)\nx = Flatten()(x)\n\n\ngrapme_op = Dense(GRAPHME_CLASSES, activation='softmax', name='grapheme_op')(x)\nvowel_op = Dense(VOWEL_CLASSES, activation='softmax', name='vowel_op')(x)\nconsonent_op = Dense(CONSONENT_CLASSES, activation='softmax', name='consonent_op')(x)\n\nmodel = Model(inputs=inp, outputs=[grapme_op, vowel_op, consonent_op])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"losses = {\n\t'grapheme_op': 'sparse_categorical_crossentropy',\n\t'vowel_op': 'sparse_categorical_crossentropy',\n    'consonent_op': 'sparse_categorical_crossentropy'\n}\nlossWeights = {\n    'grapheme_op': 1.0, \n    'vowel_op': 1.0, \n    'consonent_op': 1.0\n}\nmetrices = {\n    'grapheme_op': 'accuracy', \n    'vowel_op': 'accuracy', \n    'consonent_op': 'accuracy'\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer='adam',\n              loss=losses,\n              loss_weights=lossWeights,\n              metrics=metrices)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"histories = []\n\ny_test_graphemes = []\ny_test_vowels = []\ny_test_consonents = []\n\npred_graphemes = []\npred_vowels = []\npred_consonents = []","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def index_of_max(arr):\n    ind = np.where(arr == np.max(arr))\n    return ind[0][0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for file in train_image_files:\n    X_train, X_val, X_test, y_train, y_val, y_test = get_train_test_data(file_name=file)\n\n    X_train = np.expand_dims(X_train, axis=-1)\n    X_val = np.expand_dims(X_val, axis=-1)\n    X_test = np.expand_dims(X_test, axis=-1)\n    \n    y_train_grapheme = y_train[:, 0]\n    y_train_vowel = y_train[:, 1]\n    y_train_consonent = y_train[:, 2]\n\n    y_val_grapheme = y_val[:, 0]\n    y_val_vowel = y_val[:, 1]\n    y_val_consonent = y_val[:, 2]\n\n    train_op = {\n        'grapheme_op': y_train_grapheme, \n        'vowel_op': y_train_vowel, \n        'consonent_op': y_train_consonent\n    }\n\n    val_op = {\n        'grapheme_op': y_val_grapheme, \n        'vowel_op': y_val_vowel, \n        'consonent_op': y_val_consonent\n    }\n\n    history = model.fit(\n          X_train,\n          train_op,\n          validation_data=(X_val, val_op),\n          epochs=EPOCHS\n        )\n\n    y_test_grapheme = y_test[:, 0]\n    y_test_vowel = y_test[:, 1]\n    y_test_consonent = y_test[:, 2]\n\n    pred = model.predict(X_test)\n    pred_grapheme = [index_of_max(item) for item in pred[0]]\n    pred_vowel = [index_of_max(item) for item in pred[1]]\n    pred_consonent = [index_of_max(item) for item in pred[2]]\n\n    histories.append(history)\n    \n    y_test_graphemes.append(y_test_grapheme)\n    y_test_vowels.append(y_test_vowel)\n    y_test_consonents.append(y_test_consonent)\n\n    pred_graphemes.append(pred_grapheme)\n    pred_vowels.append(pred_vowel)\n    pred_consonents.append(pred_consonent)\n      \n    del X_train\n    del X_val\n    del y_train\n    del y_val\n    del y_train_grapheme\n    del y_train_vowel \n    del y_train_consonent\n    del y_val_grapheme\n    del y_val_vowel \n    del y_val_consonent","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for history in histories:\n  show_accuracy(history)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Metrices"},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(len(train_image_files)):\n  print('After trainining with : ', train_image_files[i])\n\n  true_labels = y_test_graphemes[i]\n  predict_labels = pred_graphemes[i]\n  print('Grapheme Accuracy Score :',accuracy_score(true_labels, predict_labels))\n\n  true_labels = y_test_vowels[i]\n  predict_labels = pred_vowels[i]\n  print('Vowel Accuracy Score :',accuracy_score(true_labels, predict_labels))\n\n  true_labels = y_test_consonents[i]\n  predict_labels = pred_consonents[i]\n  print('Consonent Accuracy Score :',accuracy_score(true_labels, predict_labels))\n\n  print('********************************************************************')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Predictions"},{"metadata":{"trusted":true},"cell_type":"code","source":"test_image_files = ['test_image_data_0.parquet', 'test_image_data_1.parquet', 'test_image_data_2.parquet', 'test_image_data_3.parquet']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_image_df = None\n\nfor files in test_image_files:\n  df = pd.read_parquet(BASE_PATH + files)\n  if test_image_df is None:\n    test_image_df = df\n  else:\n    test_image_df = pd.concat([test_image_df, df], ignore_index=True)\n  \n  del df\n\ntest_image_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_image_df = test_image_df.drop(['image_id'], axis = 'columns')\ntest_image_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_images = test_image_df.to_numpy(dtype='f').reshape(test_image_df.shape[0],ORIGINAL_IMG_HEIGHT, ORIGINAL_IMG_WIDTH)\ntest_images = resize_images(test_images)\ntest_images = np.expand_dims(test_images, axis=-1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred = model.predict(test_images)\npred_grapheme = [index_of_max(item) for item in pred[0]]\npred_vowel = [index_of_max(item) for item in pred[1]]\npred_consonent = [index_of_max(item) for item in pred[2]]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"result = []\nfor i in range(len(test_images)):\n  result.append(pred_grapheme[i])\n  result.append(pred_vowel[i])\n  result.append(pred_consonent[i])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df.drop(['component'], axis=1)\ntest_df['component'] = result \ntest_df.head()","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}