{"cells":[{"metadata":{"_uuid":"31c22dcf-ffac-419c-a84f-ddb1a9bc8432","_cell_guid":"62c32159-12dd-4509-b7ee-8e9f144ef8f5","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)\nimport time, gc\nimport tensorflow as tf\nfrom PIL import Image\nprint(tf.__version__)\n\nfrom sklearn.model_selection import train_test_split\nfrom matplotlib import pyplot as plt\nimport matplotlib\nmatplotlib.use('Agg')\n\n# import the necessary keras and sklearn packages\n\nfrom sklearn.preprocessing import LabelBinarizer\nfrom sklearn.model_selection import train_test_split\n\nimport random\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":{"trusted":true},"cell_type":"code","source":"!ls /kaggle/input/","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from kaggle_datasets import KaggleDatasets\nGCS_DS_PATH = KaggleDatasets().get_gcs_path('bengaliai-cv19')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!gsutil ls $GCS_DS_PATH","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"GCS_DS_PATH1 = KaggleDatasets().get_gcs_path('bengaliaicv19feather')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!gsutil ls $GCS_DS_PATH1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install gcsfs","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"57908507-8451-4fff-81e7-f97e9499a2c1","_cell_guid":"7fc105f2-3d41-4cc4-9ed4-ef07599091d5","trusted":true},"cell_type":"code","source":"train_df_ = pd.read_csv('gs://kds-06929b980722279141ec67c5f76a6468a973cd72023b750636bda6c7/train.csv')\nclass_map_df = pd.read_csv('gs://kds-06929b980722279141ec67c5f76a6468a973cd72023b750636bda6c7/class_map.csv')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"f4075d0b-1dcc-4eb9-86d2-6e00c0176b85","_cell_guid":"57a607f3-328c-4a0c-8622-c01c25cdfab2","trusted":true},"cell_type":"code","source":"print(train_df_.head())","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3d1e4696-6774-4ae2-b3b4-d3657546aa9b","_cell_guid":"3cf8f6d2-48e7-4c0f-b6a4-f83dcdf41b1e","trusted":true},"cell_type":"code","source":"len(train_df_)","execution_count":0,"outputs":[]},{"metadata":{"_uuid":"4d737483-2b41-432a-8593-79acd85beb43","_cell_guid":"9dfb9b12-2417-47f8-bc0f-94b28f1da98d","trusted":true},"cell_type":"code","source":"print(class_map_df.head())","execution_count":0,"outputs":[]},{"metadata":{"_uuid":"c7686ae0-d352-44d3-b674-857a575b7e04","_cell_guid":"53c2da11-fc6e-4630-8da2-930befd54178","trusted":true},"cell_type":"code","source":"print(class_map_df.component_type.value_counts())","execution_count":0,"outputs":[]},{"metadata":{"_uuid":"5baa7c65-6b68-4bc4-a026-de71a57628ba","_cell_guid":"7096dc35-3f42-4831-8f8c-0ee24ee580d4","trusted":true},"cell_type":"code","source":"class_map_df_root = class_map_df[class_map_df.component_type=='grapheme_root']\nclass_map_df_vowel = class_map_df[class_map_df.component_type=='vowel_diacritic']\nclass_map_df_cons = class_map_df[class_map_df.component_type=='consonant_diacritic']","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"43aca8e6-41c4-46cb-8cb4-5563839c2c6a","_cell_guid":"ed4eeafe-39f6-46ab-80e5-5cd08c182122","trusted":true},"cell_type":"code","source":"graphemeLB = LabelBinarizer()\nvowelLB = LabelBinarizer()\nconsonantLB = LabelBinarizer()\n\ngraphemeLB.fit(class_map_df_root.label)\nvowelLB.fit(class_map_df_vowel.label)\nconsonantLB.fit(class_map_df_cons.label)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"012dc585-0f63-49a3-8cd9-4315215c1529","_cell_guid":"53379125-448d-4804-9d49-d2828b388117","trusted":true},"cell_type":"code","source":"print(len(vowelLB.classes_))\nprint(len(consonantLB.classes_))\nprint(len(graphemeLB.classes_))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a2dd85d7-00b4-4bd7-9314-389540b8f8de","_cell_guid":"65c164d5-8c46-45b5-bdfe-5dccf4325d6c","trusted":true},"cell_type":"code","source":"def read_data(nf):\n    nf=int(nf)\n    train_df = pd.read_parquet(f'gs://kds-06929b980722279141ec67c5f76a6468a973cd72023b750636bda6c7/train_image_data_{nf}.parquet')\n     #   f'gs://kds-87e1f7817c6764d20c2f2841fd9048ac1f7b9c89a1508dbd796f13b4/train_image_data_{nf}.feather')\n     #   f'/kaggle/input/bengaliaicv19feather/train_image_data_{nf}.feather')\n     #   f'gs://kds-06929b980722279141ec67c5f76a6468a973cd72023b750636bda6c7/train_image_data_{nf}.parquet'\n    return train_df","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e7f9384a-a630-4695-a48c-0104e71ab809","_cell_guid":"6c313ecf-ff17-426c-8f70-4bea4eca461c","trusted":true},"cell_type":"code","source":"def res_net_block_1(input_data, filters):\n  \n    x1 = tf.keras.layers.Conv2D(filters, 3, activation=tf.nn.relu, padding='same')(input_data)\n    x1 = tf.nn.leaky_relu(x1, alpha=0.01, name='Leaky_ReLU') \n    x2 = tf.keras.layers.BatchNormalization()(x1)\n    x2 = tf.keras.layers.Dropout(0.3)(x2)\n    \n    x3 = tf.keras.layers.Conv2D(filters, 5, activation=None, padding='same')(x2)\n    x3 = tf.nn.leaky_relu(x3, alpha=0.01, name='Leaky_ReLU') \n    x4 = tf.keras.layers.BatchNormalization()(x3)\n    x4 = tf.keras.layers.Dropout(0.3)(x4)\n  \n    x5 = tf.keras.layers.Conv2D(filters, 1, activation=None, padding='same')(input_data)\n    x5 = tf.nn.leaky_relu(x5, alpha=0.01, name='Leaky_ReLU') \n\n    x = tf.keras.layers.Add()([x4 , x5 ])\n    x = tf.keras.layers.Activation(tf.nn.relu)(x)\n    return x","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7d8347d0-6067-4b7e-afdc-bc6fb24a46e1","_cell_guid":"970c67fc-5e2b-41f7-ad4f-298995ff7774","trusted":true},"cell_type":"code","source":"def res_net_block_2(input_data, filters):\n  \n    x1 = tf.keras.layers.Conv2D(filters, 3, activation=tf.nn.relu, padding='same')(input_data)\n    x1 = tf.nn.leaky_relu(x1, alpha=0.01, name='Leaky_ReLU') \n    x2 = tf.keras.layers.BatchNormalization()(x1)\n    x2 = tf.keras.layers.Dropout(0.3)(x2)\n    \n    x3 = tf.keras.layers.Conv2D(filters, 5, activation=None, padding='same')(input_data)\n    x3 = tf.nn.leaky_relu(x3, alpha=0.01, name='Leaky_ReLU') \n    x4 = tf.keras.layers.BatchNormalization()(x3)\n    x4 = tf.keras.layers.Dropout(0.3)(x4)\n  \n    x5 = tf.keras.layers.Conv2D(filters, 1, activation=None, padding='same')(input_data)\n    x5 = tf.nn.leaky_relu(x5, alpha=0.01, name='Leaky_ReLU') \n\n    x = tf.keras.layers.Add()([x2 , x4 , x5 ])\n    x = tf.keras.layers.Activation(tf.nn.relu)(x)\n    return x","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e1b8d7d8-c172-42e1-b7a3-1b4015316cf6","_cell_guid":"e754830f-4b44-4a92-b358-f7fae8185e25","trusted":true},"cell_type":"code","source":"def resnet(inputsize,outputsize,depth,model_type):\n    inputs = tf.keras.layers.Input(shape=(inputsize,inputsize,1))\n    x = tf.keras.layers.Conv2D(32, (3,3), activation=tf.nn.relu)(inputs)\n    x = tf.nn.leaky_relu(x, alpha=0.01, name='Leaky_ReLU') \n    x = tf.keras.layers.Conv2D(64, (3,3), activation=tf.nn.relu)(x)\n    x = tf.nn.leaky_relu(x, alpha=0.01, name='Leaky_ReLU') \n    x = tf.keras.layers.MaxPooling2D(3)(x)\n    x = tf.keras.layers.Dropout(0.1)(x)\n    num_res_net_blocks = depth\n    for i in range(num_res_net_blocks):\n        x = res_net_block_2(x, 64)\n    x = tf.keras.layers.Conv2D(64, 3, activation=tf.nn.relu)(x)\n    x = tf.nn.leaky_relu(x, alpha=0.01, name='Leaky_ReLU') \n    x = tf.keras.layers.GlobalAveragePooling2D()(x)\n    x = tf.keras.layers.Dense(256, activation=tf.nn.relu)(x)\n    if (model_type != \"root\"):\n        x = tf.keras.layers.Dense(128, activation=tf.nn.relu)(x)\n        x = tf.keras.layers.Dense(64, activation=tf.nn.relu)(x)\n        x = tf.keras.layers.Dense(32, activation=tf.nn.relu)(x)\n    x = tf.keras.layers.Dropout(0.7)(x)\n    output = tf.keras.layers.Dense(outputsize, activation=tf.nn.softmax)(x)\n    model = tf.keras.models.Model(inputs, output)\n    return model\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"AUTO = tf.data.experimental.AUTOTUNE\ntry:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()  # TPU detection. No parameters necessary if TPU_NAME environment variable is set. On Kaggle this is always the case.\n    print('Running on TPU ', tpu.master())\nexcept ValueError:\n    tpu = None\n\nif tpu:\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    strategy = tf.distribute.experimental.TPUStrategy(tpu)\nelse:\n    strategy = tf.distribute.get_strategy() # default distribution strategy in Tensorflow. Works on CPU and single GPU.\n\nprint(\"REPLICAS: \", strategy.num_replicas_in_sync)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ResNet = True \nCNN = False\nwith strategy.scope():\n    model_root = resnet(96, 168,10,\"root\")  # Input imagesize, outputtensor size, depth\n    #model_vowel = resnet(96, 11,10,\"vowel\")\n    #model_consonant = resnet(96, 7,10,\"consonant\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a31a40c4-acd2-4728-96dd-c753967bef30","_cell_guid":"2bd37289-6661-452b-98f5-6174316e9268","trusted":true},"cell_type":"code","source":"tf.keras.utils.plot_model(model_root, to_file='model1.png')\n#tf.keras.utils.plot_model(model_vowel, to_file='model2.png')\n#tf.keras.utils.plot_model(model_consonant, to_file='model3.png')","execution_count":0,"outputs":[]},{"metadata":{"_uuid":"e309f43f-ef8e-4997-828b-edb57e74f544","_cell_guid":"d47f8630-fa27-497f-b587-152e29adbec0","trusted":true},"cell_type":"code","source":"EPOCHS = 2\nINIT_LR = 1e-3\nBS = 128\n# initialize the optimizer and compile the model\nprint(\"[INFO] compiling models...\")\nopt = tf.keras.optimizers.Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)\nmodel_root.compile(optimizer=opt, loss=\"categorical_crossentropy\", metrics=[\"accuracy\"])\n#model_vowel.compile(optimizer=opt, loss=\"categorical_crossentropy\", metrics=[\"accuracy\"])\n#model_consonant.compile(optimizer=opt, loss=\"categorical_crossentropy\", metrics=[\"accuracy\"])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"785e0d81-0674-4989-a72f-ef208d373fae","_cell_guid":"04bbd8b7-d02b-4365-ba74-9f625b9c3d84","trusted":true},"cell_type":"markdown","source":"## Read image data from feather format, binarize the labels, train on full data, create TF Dataset from images and labels, and do model.fit in a loop for the 4 sets of images"},{"metadata":{"_uuid":"76eb49dc-fba2-4ab5-b9b6-fc51bf969e45","_cell_guid":"69d5373b-e400-4f8e-aa6f-c1de85b4b1ef","trusted":true},"cell_type":"code","source":"histories = []\n\nes = tf.keras.callbacks.EarlyStopping(monitor='loss', patience=5)\n\nfor i in range(2):\n    print(\"iteration:\"+str(i))\n\n    graphemeLabels = []\n    vowelLabels = []\n    consonantLabels = []   \n    print(\"[INFO] reading train images and labels...\")\n    train_df = pd.merge(read_data(i), train_df_, on='image_id').drop(['image_id','grapheme'], axis=1)[1:1000]\n    graphemeLabels = train_df.grapheme_root\n    vowelLabels = train_df.vowel_diacritic\n    consonantLabels = train_df.consonant_diacritic\n\n    print(\"[INFO] binarizing labels...\")\n    graphemeLabels = graphemeLB.transform(np.array(graphemeLabels))\n    vowelLabels = vowelLB.transform(np.array(vowelLabels))\n    consonantLabels = consonantLB.transform(np.array(consonantLabels))\n\n    print(graphemeLabels.shape)\n    print(vowelLabels.shape)\n    print(consonantLabels.shape)\n\n    train_df=train_df.drop([\"consonant_diacritic\",\"grapheme_root\",\"vowel_diacritic\"],axis=1)\n    \n    print(\"[INFO] doing train test split...\")\n    (trainX, testX, trainGraphemeY, testGraphemeY,trainVowelY, testVowelY,trainConsonantY,testConsonantY) = train_test_split(train_df, graphemeLabels, vowelLabels,consonantLabels,test_size=0.01, random_state=42)\n   \n    del train_df\n    del graphemeLabels\n    del vowelLabels\n    del consonantLabels\n    gc.collect()\n\n    print(\"[INFO] creating train dataset...\")\n    trainX=np.array(trainX).reshape(-1,137,236,1)\n    print(trainX.shape)\n    resized_image=[]\n    for j in range(trainX.shape[0]):\n        resized_img = tf.image.resize(trainX[j],[96,96])\n        resized_img=np.array(resized_img)/255.\n        resized_image.append(resized_img)\n    resized_image = np.asarray(resized_image)\n    resized_image = tf.cast(resized_image, tf.int32)\n    trainGraphemeY = tf.cast(trainGraphemeY, tf.int32)\n    print(resized_image.shape)\n    del trainX\n    gc.collect()\n    \n    print(\"[INFO] Creating Augmented Images...\")\n    datagen = tf.keras.preprocessing.image.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=8,  # randomly rotate images in the range (degrees, 0 to 180)\n            zoom_range = 0.15, # Randomly zoom image \n            width_shift_range=0.15,  # randomly shift images horizontally (fraction of total width)\n            height_shift_range=0.15,  # randomly shift images vertically (fraction of total height)\n            horizontal_flip=False,  # randomly flip images\n            vertical_flip=False)  # randomly flip images\n\n    datagen.fit(resized_image)\n    datagen = datagen.flow(resized_image, trainGraphemeY, batch_size=BS)\n    \n    print(\"[INFO] Creating TF Dataset...\")\n    ds = tf.data.Dataset.from_generator(\n        lambda:datagen,\n    output_types=(tf.int32, tf.int32),\n    output_shapes=(resized_image.shape, trainGraphemeY.shape)\n    )  \n    \n    #filename = 'test.tfrecord'\n    #writer = tf.io.TFRecordWriter(filename)\n    #writer.write(ds)\n    \n    #dataset = tf.data.TFRecordDataset(ds)\n    \n    #print(\"[INFO] creating validation dataset...\")\n    #testX=np.array(testX).reshape(-1,137,236,1)\n    #print(testX.shape)\n    #resized_image_test=[]\n    #for i in range(len(testX)):\n    #    resized_img = tf.image.resize(testX[i],[96,96])\n    #    resized_img=np.array(resized_img)/255.\n    #    resized_image_test.append(resized_img)\n    #resized_image_test = np.asarray(resized_image_test)\n\n    #del testX\n    #gc.collect()\n\n    print(\"[INFO] Root Model.fit starting...\")\n\n    history = model_root.fit_generator(ds,\n                                      epochs = EPOCHS, \n                                      steps_per_epoch=resized_image.shape[0] // BS, \n                                      callbacks=[es],verbose=2)\n    #validation_data = (resized_image_test,testGraphemeY)\n    histories.append(history)\n    \n    #print(\"[INFO] Vowel Model.fit starting...\")\n    #history = model_vowel.fit_generator(datagen.flow(resized_image, trainVowelY, batch_size=BS),\n    #                                  epochs = EPOCHS, validation_data = (resized_image_test,testVowelY),\n    #                                  steps_per_epoch=resized_image.shape[0] // BS, \n    #                                  callbacks=[es],verbose=2)\n\n    #histories.append(history)\n    \n    #print(\"[INFO] Cons Model.fit starting...\")\n    #history = model_consonant.fit_generator(datagen.flow(resized_image, trainConsonantY, batch_size=BS),\n    #                                  epochs = EPOCHS, validation_data = (resized_image_test,testConsonantY),\n    #                                  steps_per_epoch=resized_image.shape[0] // BS, \n    #                                  callbacks=[es],verbose=2)\n\n    #histories.append(history)\n    \n    #del resized_image\n    #del resized_image_test\n    #gc.collect()","execution_count":null,"outputs":[]}],"metadata":{"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"}},"nbformat":4,"nbformat_minor":1}