{"cells":[{"metadata":{"id":"53Lj-ngQzE-R","colab_type":"text"},"cell_type":"markdown","source":"# Bengali.AI Handwritten Grapheme Classification\n---\nAuthor: Bhaveshkumar Thaker\n\n---\n---\nPublic Score: 0.9490\n\n---\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F1095143%2Fa9a48686e3f385d9456b59bf2035594c%2Fdesc.png?generation=1576531903599785&alt=media)\n\nBengali is the 5th most spoken language in the world with hundreds of million of speakers. It’s the official language of Bangladesh and the second most spoken language in India. Considering its reach, there’s significant business and educational interest in developing AI that can optically recognize images of the language handwritten. This challenge hopes to improve on approaches to Bengali recognition.\n\nOptical character recognition is particularly challenging for Bengali. While Bengali has 49 letters (to be more specific 11 vowels and 38 consonants) in its alphabet, there are also 18 potential diacritics, or accents. This means that there are many more graphemes, or the smallest units in a written language. The added complexity results in ~13,000 different grapheme variations (compared to English’s 250 graphemic units).\n\n## Classify the components of handwritten Bengali\nThis dataset contains images of individual hand-written Bengali characters. Bengali characters (graphemes) are written by combining three components: a grapheme_root, vowel_diacritic, and consonant_diacritic. Your challenge is to classify the components of the grapheme in each image. There are roughly 10,000 possible graphemes, of which roughly 1,000 are represented in the training set. The test set includes some graphemes that do not exist in train but has no new grapheme components. It takes a lot of volunteers filling out sheets like this to generate a useful amount of real data; focusing the problem on the grapheme components rather than on recognizing whole graphemes should make it possible to assemble a Bengali OCR system without handwriting samples for all 10,000 graphemes.\n\n## Files\n**train.csv**\nimage_id: the foreign key for the parquet files\n\n*   `grapheme_root`: the first of the three target classes\n*   `vowel_diacritic`: the second target class\n*   `consonant_diacritic`: the third target class\n*   `grapheme`: the complete character. Provided for informational purposes only, you should not need to use this.\n\n**(train/test).parquet**\nEach parquet file contains tens of thousands of 137x236 grayscale images. The images have been provided in the parquet format for I/O and space efficiency. Each row in the parquet files contains an `image_id` column, and the flattened image.\n\n**class_map.csv**\nMaps the class labels to the actual Bengali grapheme components."},{"metadata":{"id":"28uQMmaizS_9","colab_type":"text"},"cell_type":"markdown","source":"# Setup notebook"},{"metadata":{"id":"9X2fzknGysur","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"#%%\nimport time\nnotebookstart = time.time()\n\nimport warnings\nwarnings.filterwarnings('ignore')","execution_count":null,"outputs":[]},{"metadata":{"id":"dbX_hn9UzeAF","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"#%%\nrunningOnColab = False\nrunningOnKaggle = True\nrunningLocal = False","execution_count":null,"outputs":[]},{"metadata":{"id":"hyKFlj39zg5N","colab_type":"text"},"cell_type":"markdown","source":"## Connect to Google Drive or Kaggle if require"},{"metadata":{"id":"IrJdKv97zgZv","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":129},"outputId":"71f6f24f-db9f-4c6a-c071-de6c0fe60a74","executionInfo":{"status":"ok","timestamp":1580881588467,"user_tz":-330,"elapsed":57105,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nroot_dir = ''\n'''\ntry:\n    from google.colab import drive, files\n    drive.mount('/content/drive')\n    root_dir = '/content/drive/My Drive/Colab Notebooks/tensorflow-2-projects/'\n\n    # To upload kaggle.json to mounted directory\n    # files.upload();\n\n    # Create directory for kaggle.json key file and copy file\n    get_ipython().system('mkdir -p ~/.kaggle')\n    # In my case, 'Colab Notebooks' directory already contains my kaggle.json\n    get_ipython().system(\"cp '{root_dir}../kaggle.json' ~/.kaggle/\")\n\n    # Change the permission\n    get_ipython().system('chmod 600 ~/.kaggle/kaggle.json')\nexcept:\n    print('No GOOGLE DRIVE connection. Using local dataset(s).')\n'''","execution_count":null,"outputs":[]},{"metadata":{"id":"9yrDioYXzocj","colab_type":"text"},"cell_type":"markdown","source":"## Install libraries"},{"metadata":{"id":"fcfjE-2nzo2y","colab_type":"text"},"cell_type":"markdown","source":"## Import libraries"},{"metadata":{"id":"0OO6wHnZzuaO","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":54},"outputId":"31fc9654-6a80-4ab4-d5d2-4e1ee470d44d","executionInfo":{"status":"ok","timestamp":1580881588475,"user_tz":-330,"elapsed":55490,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nif runningOnColab == True:\n    print('Enabling TensorFlow 2.x')\n    get_ipython().run_line_magic('tensorflow_version', '2.x')","execution_count":null,"outputs":[]},{"metadata":{"id":"_GGjTHIFzxCJ","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"#%%\nimport os, sys, random, gc, shutil\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mimage\nimport matplotlib.colors as mcolors\nimport seaborn as sns\n\nimport cv2\n\nimport tensorflow as tf\n\nfrom collections import defaultdict\nfrom PIL import Image, ImageFont\nfrom skimage.transform import resize\nfrom zipfile import ZipFile\nfrom matplotlib import font_manager as fm\nfrom tqdm.autonotebook import trange, tqdm\n\nfrom sklearn.model_selection import train_test_split, KFold, StratifiedKFold","execution_count":null,"outputs":[]},{"metadata":{"id":"kSQT8t0Kz3Fg","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":72},"outputId":"afdfd717-dd3d-489e-b94d-8e3b34c97287","executionInfo":{"status":"ok","timestamp":1580881590644,"user_tz":-330,"elapsed":57234,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nprint(tf.version.VERSION)\nprint('GPU is', 'available' if\n      tf.config.experimental.list_physical_devices('GPU') else 'NOT AVAILABLE')\ndevice_name = tf.test.gpu_device_name()\nprint('Found GPU at: {}'.format(device_name))","execution_count":null,"outputs":[]},{"metadata":{"id":"1g74Tkpzz5C4","colab_type":"text"},"cell_type":"markdown","source":"## Setup defaults"},{"metadata":{"id":"DXONXXkHz3q4","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":35},"outputId":"4d2fbedc-c5f0-4e86-e2cc-e0cb8b240dfd","executionInfo":{"status":"ok","timestamp":1580881590646,"user_tz":-330,"elapsed":56841,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nseed = 321\nrandom.seed(seed)\nnp.random.seed(seed)\ntf.random.set_seed(seed)\n\n# Config the matplotlib backend as plotting inline in IPython\nget_ipython().run_line_magic('matplotlib', 'inline')\n\nplt.figure(figsize=(14, 11))\nplt.style.use('seaborn')\n\ncolors = mcolors.TABLEAU_COLORS\nsns.set(\n    rc={\n        'figure.figsize': (14, 11),\n        'figure.facecolor': 'whitesmoke',\n        'axes.facecolor': 'whitesmoke',\n        'grid.color': 'slategrey',\n    })\nsns.color_palette(palette=list(colors.values()));","execution_count":null,"outputs":[]},{"metadata":{"id":"o6-fX6kB0Aap","colab_type":"text"},"cell_type":"markdown","source":"# Download and load data"},{"metadata":{"id":"wW0mQQRjz-bR","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"#%%\nif runningOnKaggle == True:\n    root_dir = '/kaggle/input'\n    for dirname, _, filenames in os.walk(root_dir):\n        for filename in filenames:\n            print(os.path.join(dirname, filename))\n\n    root_dir = '/kaggle/input/bengaliai-cv19'\nelse:\n    root_dir = ''","execution_count":null,"outputs":[]},{"metadata":{"id":"PCtJ3K3O0Drm","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":697},"outputId":"21aabbe3-7287-4126-d5c4-1a61bb56b7d4","executionInfo":{"status":"ok","timestamp":1580881645069,"user_tz":-330,"elapsed":110616,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nif runningOnColab == True:\n    get_ipython().system('kaggle competitions download -c bengaliai-cv19')","execution_count":null,"outputs":[]},{"metadata":{"id":"fZ4dwQvV0F9W","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":72},"outputId":"24dc294e-315c-40d2-c519-b6be42fd04ed","executionInfo":{"status":"ok","timestamp":1580881648285,"user_tz":-330,"elapsed":113683,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nif runningOnColab == True:\n    get_ipython().system('kaggle datasets download -d kaushal2896/bengali-fonts')","execution_count":null,"outputs":[]},{"metadata":{"id":"-_pNTw3S0IHz","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":72},"outputId":"e485c0a2-2a80-4839-a54e-80bee27317b6","executionInfo":{"status":"ok","timestamp":1580881651655,"user_tz":-330,"elapsed":116883,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nif runningOnColab == True:\n    get_ipython().system('kaggle datasets download -d kaushal2896/kalpurush-fonts')","execution_count":null,"outputs":[]},{"metadata":{"id":"Qe7a_ZiS0IWL","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":288,"referenced_widgets":["626fa84301eb4da98995565a616c754c","81cb316536424fbc89dc9e2b01f5a2c3","c56bca8fafdf47c491e73e026bfd8cbe","71349168841a403c8d8159ba13f2b217","e56311bef34e404ab31c5b9785cb342c","9d4a05d781f1449588099469889cf370","32d259535a294bd18ae7f4504d873627","fbbd6ffc34d446af9e23095475d7b5c8"]},"outputId":"055e1e7a-41a2-40bb-9155-a3720ae5626a","executionInfo":{"status":"ok","timestamp":1580881734415,"user_tz":-330,"elapsed":199455,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nif runningOnColab == True:\n    if os.path.exists('train.csv'):\n        print('Zip file is extracted already')\n    else:\n        print('Extracting the Zip file(s) ...')\n        for file in tqdm(os.listdir()):\n            if file.endswith('.zip'):\n                with ZipFile(file, 'r') as datazipfile:\n                    datazipfile.extractall()\n                    datazipfile.close()\n                    print(f'{file} Zip file extracted successfully')","execution_count":null,"outputs":[]},{"metadata":{"id":"Yamh0COC0IE7","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":35},"outputId":"a322ec5a-6caf-4921-80ba-033133bfe2a2","executionInfo":{"status":"ok","timestamp":1580881734422,"user_tz":-330,"elapsed":199292,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nif runningOnKaggle == True:\n    bengalifont = ImageFont.truetype(\n        '/kaggle/input/kalpurush-fonts/kalpurush-2.ttf')\n    fontproperties = fm.FontProperties(\n        fname='/kaggle/input/kalpurush-fonts/kalpurush-2.ttf')\n    print(fontproperties.get_name())\nelse:\n    bengalifont = ImageFont.truetype(root_dir + 'kalpurush-2.ttf')\n    fontproperties = fm.FontProperties(fname=root_dir + 'kalpurush-2.ttf')\n    print(fontproperties.get_name())","execution_count":null,"outputs":[]},{"metadata":{"id":"ba8IXccL0Tf1","colab_type":"text"},"cell_type":"markdown","source":"### Load the data"},{"metadata":{"id":"Bjq1wzXv0U5D","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"#%%\ndf_traincsv = pd.read_csv(os.path.join(root_dir, 'train.csv'))","execution_count":null,"outputs":[]},{"metadata":{"id":"EZ5lLSXt0XK6","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"#%%\ndf_classmap = pd.read_csv(os.path.join(root_dir, 'class_map.csv'))","execution_count":null,"outputs":[]},{"metadata":{"id":"WsBUsE790bgQ","colab_type":"text"},"cell_type":"markdown","source":"## Data insights"},{"metadata":{"id":"wLxgjGqK0cvG","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":35},"outputId":"ac2fc3de-0de9-4cc2-ccad-c456decdfbab","executionInfo":{"status":"ok","timestamp":1580881734431,"user_tz":-330,"elapsed":198310,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\ndf_traincsv.shape","execution_count":null,"outputs":[]},{"metadata":{"id":"mdutKQo80ibx","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":363},"outputId":"be35f836-2792-48d5-869b-834af223d663","executionInfo":{"status":"ok","timestamp":1580881734434,"user_tz":-330,"elapsed":198125,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\ndf_traincsv.head(10)","execution_count":null,"outputs":[]},{"metadata":{"id":"r0QdbeSA0igv","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":72},"outputId":"d677ecc9-d4eb-45cf-f2f7-9c9d4e8619f7","executionInfo":{"status":"ok","timestamp":1580881734436,"user_tz":-330,"elapsed":197859,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nprint(\n    f'Number of unique grapheme_root: {df_traincsv[\"grapheme_root\"].nunique()}'\n)\nprint(\n    f'Number of unique vowel_diacritic: {df_traincsv[\"vowel_diacritic\"].nunique()}'\n)\nprint(\n    f'Number of unique consonant_diacritic: {df_traincsv[\"consonant_diacritic\"].nunique()}'\n)","execution_count":null,"outputs":[]},{"metadata":{"id":"LbrlSm_a0ijS","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":35},"outputId":"cab98975-9958-4b8d-f7d9-666ae2eebf8b","executionInfo":{"status":"ok","timestamp":1580881734437,"user_tz":-330,"elapsed":197668,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\ndf_classmap.shape","execution_count":null,"outputs":[]},{"metadata":{"id":"c0JM5UNP0iot","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":520},"outputId":"f0384664-9898-4ad4-e3a9-52e6b35a2f18","executionInfo":{"status":"ok","timestamp":1580881734439,"user_tz":-330,"elapsed":197439,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\ndf_classmap.head(15)","execution_count":null,"outputs":[]},{"metadata":{"id":"ctHTmleS0isV","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":520},"outputId":"52b73783-05d4-4440-bfc9-122363b80b8f","executionInfo":{"status":"ok","timestamp":1580881734440,"user_tz":-330,"elapsed":197255,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\ndf_classmap.tail(15)","execution_count":null,"outputs":[]},{"metadata":{"id":"o_xDYEXk0imc","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":329},"outputId":"0faa5327-0104-4896-a6ca-3d3ade6aa20c","executionInfo":{"status":"ok","timestamp":1580881734441,"user_tz":-330,"elapsed":197031,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\ndf_classmap.loc[df_classmap['component_type'] == 'grapheme_root',\n                'component'].values","execution_count":null,"outputs":[]},{"metadata":{"id":"XHm0fFav0ifN","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":54},"outputId":"4a804f5a-ddd4-4365-d5b5-33254d42e3f1","executionInfo":{"status":"ok","timestamp":1580881734443,"user_tz":-330,"elapsed":196818,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\ndf_classmap.loc[df_classmap['component_type'] == 'vowel_diacritic',\n                'component'].values","execution_count":null,"outputs":[]},{"metadata":{"id":"JHExAJSP0vgI","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":35},"outputId":"ec64f662-06de-4f6f-c500-8dcb43421c9b","executionInfo":{"status":"ok","timestamp":1580881734445,"user_tz":-330,"elapsed":196701,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\ndf_classmap.loc[df_classmap['component_type'] == 'consonant_diacritic',\n                'component'].values","execution_count":null,"outputs":[]},{"metadata":{"id":"sG6F4HJf00Dk","colab_type":"text"},"cell_type":"markdown","source":"## Plot data insights"},{"metadata":{"id":"QkM1s5OM0vnV","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":690},"outputId":"217cfe46-076c-4814-c85b-bf8a72a028b4","executionInfo":{"status":"ok","timestamp":1580881735255,"user_tz":-330,"elapsed":197153,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nsns.countplot(x=df_classmap['component_type'])\nplt.xticks(\n    np.arange(3), ('grapheme_root', 'vowel_diacritic', 'consonant_diacritic'))\nplt.title('Bengali Language Component Type(s) - Distribution', fontsize=18)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"abdBYVJA0vle","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":686},"outputId":"8ef47450-58db-428e-f3ae-27410ed51aef","executionInfo":{"status":"ok","timestamp":1580884842125,"user_tz":-330,"elapsed":1882,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nsns.countplot(\n    y=df_traincsv['grapheme_root'],\n    order=df_traincsv['grapheme_root'].value_counts().index[:40],\n    orient='h',\n    palette=sns.color_palette())\nplt.xticks(rotation=45)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"AgdUXO420vjQ","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":691},"outputId":"9df19eb5-0f40-4348-facd-d59fd84710a5","executionInfo":{"status":"ok","timestamp":1580884814068,"user_tz":-330,"elapsed":1869,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nsns.countplot(\n    y=df_traincsv['vowel_diacritic'],\n    order=df_traincsv['vowel_diacritic'].value_counts().index[:15],\n    orient='h',\n    palette=sns.color_palette())\nplt.xticks(rotation=45)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"3_Wmf4Vx0vdN","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":696},"outputId":"8dc5c17d-35d8-4099-feaf-ad75fc46a79e","executionInfo":{"status":"ok","timestamp":1580881737577,"user_tz":-330,"elapsed":198782,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nsns.countplot(\n    y=df_traincsv['consonant_diacritic'],\n    order=df_traincsv['consonant_diacritic'].value_counts().index[:10],\n    orient='h')\nplt.xticks(rotation=45)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"ZtvJabWW1AkG","colab_type":"text"},"cell_type":"markdown","source":"# Data preprocessing"},{"metadata":{"id":"KsWsJ3py1Cut","colab_type":"text"},"cell_type":"markdown","source":"## Check for missing data"},{"metadata":{"id":"RDFcekVz1FrJ","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":127},"outputId":"8e98fc6f-ecb9-42fd-b65d-c0909d937fbe","executionInfo":{"status":"ok","timestamp":1580881737590,"user_tz":-330,"elapsed":197964,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\ndf_traincsv.isnull().sum(axis=0)","execution_count":null,"outputs":[]},{"metadata":{"id":"ldDoxr7i1F39","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":90},"outputId":"f256662f-fa16-4c7a-cee9-3d6088354491","executionInfo":{"status":"ok","timestamp":1580881737595,"user_tz":-330,"elapsed":197723,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\ndf_classmap.isnull().sum(axis=0)","execution_count":null,"outputs":[]},{"metadata":{"id":"eMz_ooUi1Jah","colab_type":"text"},"cell_type":"markdown","source":"## Drop non-required data column(s)"},{"metadata":{"id":"FvkMFJRL1K4l","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":35},"outputId":"52b90c0d-5006-4da5-d517-2c55d9493166","executionInfo":{"status":"ok","timestamp":1580881737599,"user_tz":-330,"elapsed":197281,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\ndf_traincsv.drop(labels=['image_id',  'grapheme'], axis=1, inplace=True)\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"id":"RfG4gUsX1Olp","colab_type":"text"},"cell_type":"markdown","source":"# Build and train the model"},{"metadata":{"id":"ZjZAe16n1QCt","colab_type":"text"},"cell_type":"markdown","source":"## Define defaults"},{"metadata":{"id":"9pFuhAQ21SyN","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"#%%\nORIGINAL_IMAGE_HEIGHT = 137\nORIGINAL_IMAGE_WIDTH = 236\n\nIMAGE_SIZE = 64\n\nNO_OF_CHANNELS = 1","execution_count":null,"outputs":[]},{"metadata":{"id":"5pYRlTQR1X8f","colab_type":"text"},"cell_type":"markdown","source":"## Define generic methods"},{"metadata":{"id":"jR-hh_i01ayY","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"#%%\ndef sizeof_fmt(num, suffix='B'):\n    ''' by Fred Cirera,  https://stackoverflow.com/a/1094933/1870254, modified'''\n    for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']:\n        if abs(num) < 1024.0:\n            return \"%3.1f %s%s\" % (num, unit, suffix)\n        num /= 1024.0\n    return \"%.1f %s%s\" % (num, 'Yi', suffix)\n\n\ndef merge_dict(dict_list):\n    dd = defaultdict(list)\n    for d in dict_list:\n        for key, value in d.items():\n            if not hasattr(value, '__iter__'):\n                value = (value, )\n            [dd[key].append(v) for v in value]\n    return dict(dd)","execution_count":null,"outputs":[]},{"metadata":{"id":"rM9u_Sdr1a2C","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":214,"referenced_widgets":["44b498203a7a4fffbc0424444925be48","7dbb093a4ba442e882a84ff9f2c852fc","be62fb683331453c9141b2f85e760ffa","3db0a33c599a43969674938aa75681f2","8cd5f33c984747f6ae09a4f2a56d8dcc","d7560d3dfe1647a983d1173a723676d7","a529e8b5c33442c593c8a1e02504df22","3dff13b9a7f5489db0d857d61b5bffb8","5fe5d96a33604348bfbff037390b4775","3855a8ca131244ddbdf42d3d92c48ace","be7688b0a03f47ad8767b28eca85cfc4","7aaacacd96834f3ab2bf0e09775e6d81","e1fcb64d27534200b7ff30d9f8a6623d","4fda7d7816144d08bc8960922ab8d996","aeb1008aa30f4ba28ad400509be26fca","3ca6bbcf3d0a4576837c071a81868787","dff4eb2249ee485694fb5df92f2a9dc3","3be63e32732643e48f14c12578ca9ed8","2e2456d3f30a40e59a2cf11d7aa8bfeb","61f2fd01fb1d420ab79d26610eb00099","07aa4684c4e84f50ab587363348c7163","097496ea233f41f6a79dceb2a3e7c0ed","92b48a06b475443b9d45482c917c431d","5671c51f2bf94cd18fb08327cbc80704","36efd9d6525f42dd96f688f8a31f52fc","4694cd38d765444d9c8a7825b45c4adc","c13e145493904a578d4a632ee28028b4","3b57736a93c74099a81743a55326bfd6","86d02fad8e0f495eb26936b135018f9c","1b968b5e0b2d44fdb195562555e4beef","76ac0bae99ad44d1b60a288f5a71ff04","9cae9118c25e4d21b52c31640ad43152","f8a12abbd1464995a48379fd0257eeed","95211a3d4d984691a03e6c076eb7d5c6","71bc73bae20d4c239008878bc46749b3","eabfb3fab44e453f94f8b654c643e5da","7286a83ade6844d4b82d8e36e070b31d","ce106f75acd54f1b8fd233839aaebb31","ff77cd177e9b466fb31a8ce5cc451949","46756b1134f34ddcbe3927c715dd98b5"]},"outputId":"b0e13b5f-0b60-45eb-c3ca-971df67158e0","executionInfo":{"status":"ok","timestamp":1580881933555,"user_tz":-330,"elapsed":391500,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nclass AllImageDataReader():\n    def __init__(self):\n        pass\n\n    def getImages(in_image_height,\n                  in_image_width,\n                  out_image_size=128,\n                  n_channels=3,\n                  return_index=False):\n        df_trainimagedata = np.empty(\n            (0, IMAGE_SIZE, IMAGE_SIZE, 1), dtype=np.uint8)\n        for i in tqdm(range(4), desc='Reading parquet'):\n            if return_index == True:\n                df_imagedata_tmp = pd.read_parquet(\n                    os.path.join(root_dir,\n                                 'train_image_data_{}.parquet'.format(i)))\n                df_indexdata_tmp = df_imagedata_tmp.pop('image_id')\n            else:\n                df_imagedata_tmp = pd.read_parquet(\n                    os.path.join(root_dir,\n                                 'train_image_data_{}.parquet'.format(i)),\n                    columns=[str(x) for x in range(32332)])\n            df_imagedata_tmp = 255 - df_imagedata_tmp.values.reshape(\n                -1, in_image_height, in_image_width).astype(np.uint8)\n            imgarr_tmp = []\n            for row in tqdm(\n                    range(df_imagedata_tmp.shape[0]), desc='Loading images'):\n                imgarr = cv2.resize(\n                    df_imagedata_tmp[row], (out_image_size, out_image_size),\n                    interpolation=cv2.INTER_CUBIC)\n                imgarr[imgarr < 28] = 0\n                imgarr_tmp.append(imgarr)\n            df_trainimagedata = np.vstack(\n                (df_trainimagedata,\n                 np.asarray(imgarr_tmp, dtype=np.uint8).reshape(\n                     -1, out_image_size, out_image_size, n_channels)))\n            del imgarr_tmp\n            del df_imagedata_tmp\n            gc.collect()\n\n        print(\n            f'Returning images of shape {df_trainimagedata.shape}, type {type(df_trainimagedata)} of {df_trainimagedata.dtype}'\n        )\n        if return_index == True:\n            return df_indexdata_tmp, df_trainimagedata\n        else:\n            return df_trainimagedata\n\n\ndf_trainimagedata = AllImageDataReader.getImages(\n    in_image_height=ORIGINAL_IMAGE_HEIGHT,\n    in_image_width=ORIGINAL_IMAGE_WIDTH,\n    out_image_size=IMAGE_SIZE,\n    n_channels=NO_OF_CHANNELS,\n    return_index=False)\n\nY_consonant_diacritic = tf.keras.utils.to_categorical(\n    df_traincsv['consonant_diacritic'], 7)\nY_grapheme_root = tf.keras.utils.to_categorical(df_traincsv['grapheme_root'],\n                                                168)\nY_vowel_diacritic = tf.keras.utils.to_categorical(\n    df_traincsv['vowel_diacritic'], 11)","execution_count":null,"outputs":[]},{"metadata":{"id":"KEE05Xnk2kmk","colab_type":"text"},"cell_type":"markdown","source":"*   [ImageDataGenerator for multiple output and single input](https://github.com/keras-team/keras/issues/12639#issuecomment-506338552)\n*   [How to use fit_generator with multiple outputs of different type](https://stackoverflow.com/a/41872896)"},{"metadata":{"id":"rw8IuUGd1bAs","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"#%%\nclass MultiOutputDataGenerator(\n        tf.keras.preprocessing.image.ImageDataGenerator):\n    def flow(\n            self,\n            x,\n            y=None,\n            batch_size=32,\n            shuffle=True,\n            sample_weight=None,\n            seed=None,\n            save_to_dir=None,\n            save_prefix='',\n            save_format='png',\n            subset=None,\n    ):\n\n        targets = None\n        target_lengths = {}\n        ordered_outputs = []\n\n        for (output, target) in y.items():\n            if targets is None:\n                targets = target\n            else:\n                targets = np.concatenate((targets, target), axis=1)\n\n            target_lengths[output] = target.shape[1]\n            ordered_outputs.append(output)\n\n        for (flowx, flowy) in super().flow(\n                x, targets, batch_size=batch_size, shuffle=shuffle):\n\n            target_dict = {}\n            i = 0\n\n            for output in ordered_outputs:\n                target_length = target_lengths[output]\n                target_dict[output] = flowy[:, i:i + target_length]\n                i += target_length\n\n            yield (flowx, target_dict)\n\n\ndatagenerator = MultiOutputDataGenerator(\n    width_shift_range=0.1,\n    height_shift_range=0.1,\n    zoom_range=0.1,\n    rotation_range=20,\n    shear_range=0.1,\n    fill_mode=\"nearest\")","execution_count":null,"outputs":[]},{"metadata":{"id":"bzevg5bg1bEg","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":1000},"outputId":"05dfdd41-e63e-4eb7-ffda-1a71f92fd1b9","executionInfo":{"status":"ok","timestamp":1580881937513,"user_tz":-330,"elapsed":394345,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nclass ConvolutionModelGenerator():\n    def __init__(self):\n        pass\n\n    def buildModel(image_size=128, n_channels=1):\n        base_model_input = tf.keras.layers.Input(\n            shape=(image_size, image_size, n_channels))\n        base_model = tf.keras.layers.Conv2D(\n            filters=64, kernel_size=(3, 3), padding='same',\n            activation='relu')(base_model_input)\n        base_model = tf.keras.layers.ZeroPadding2D((1, 1))(base_model)\n        base_model = tf.keras.layers.Conv2D(\n            filters=64, kernel_size=(3, 3), padding='same',\n            activation='relu')(base_model)\n        base_model = tf.keras.layers.BatchNormalization(\n            momentum=0.15)(base_model)\n        base_model = tf.keras.layers.MaxPool2D(pool_size=(2, 2))(base_model)\n        base_model = tf.keras.layers.Conv2D(\n            filters=64, kernel_size=(3, 3), padding='same',\n            activation='relu')(base_model)\n        base_model = tf.keras.layers.Dropout(rate=0.35)(base_model)\n\n        base_model = tf.keras.layers.Conv2D(\n            filters=128, kernel_size=(3, 3), padding='same',\n            activation='relu')(base_model)\n        base_model = tf.keras.layers.ZeroPadding2D((1, 1))(base_model)\n        base_model = tf.keras.layers.Conv2D(\n            filters=128, kernel_size=(3, 3), padding='same',\n            activation='relu')(base_model)\n        base_model = tf.keras.layers.BatchNormalization(\n            momentum=0.15)(base_model)\n        base_model = tf.keras.layers.MaxPool2D(pool_size=(2, 2))(base_model)\n        base_model = tf.keras.layers.Conv2D(\n            filters=128, kernel_size=(3, 3), padding='same',\n            activation='relu')(base_model)\n        base_model = tf.keras.layers.BatchNormalization(\n            momentum=0.15)(base_model)\n        base_model = tf.keras.layers.Dropout(rate=0.35)(base_model)\n\n        base_model = tf.keras.layers.Conv2D(\n            filters=256, kernel_size=(3, 3), padding='same',\n            activation='relu')(base_model)\n        base_model = tf.keras.layers.ZeroPadding2D((1, 1))(base_model)\n        base_model = tf.keras.layers.Conv2D(\n            filters=256, kernel_size=(3, 3), padding='same',\n            activation='relu')(base_model)\n        base_model = tf.keras.layers.BatchNormalization(\n            momentum=0.15)(base_model)\n        base_model = tf.keras.layers.MaxPool2D(pool_size=(2, 2))(base_model)\n        base_model = tf.keras.layers.Conv2D(\n            filters=256, kernel_size=(3, 3), padding='same',\n            activation='relu')(base_model)\n        base_model = tf.keras.layers.BatchNormalization(\n            momentum=0.15)(base_model)\n        base_model = tf.keras.layers.Dropout(rate=0.35)(base_model)\n\n        base_model = tf.keras.layers.Conv2D(\n            filters=512, kernel_size=(3, 3), padding='same',\n            activation='relu')(base_model)\n        base_model = tf.keras.layers.ZeroPadding2D((1, 1))(base_model)\n        base_model = tf.keras.layers.Conv2D(\n            filters=512, kernel_size=(3, 3), padding='same',\n            activation='relu')(base_model)\n        base_model = tf.keras.layers.BatchNormalization(\n            momentum=0.15)(base_model)\n        base_model = tf.keras.layers.MaxPool2D(pool_size=(2, 2))(base_model)\n        base_model = tf.keras.layers.Conv2D(\n            filters=512, kernel_size=(3, 3), padding='same',\n            activation='relu')(base_model)\n        base_model = tf.keras.layers.BatchNormalization(\n            momentum=0.15)(base_model)\n        base_model = tf.keras.layers.Dropout(rate=0.35)(base_model)\n\n        base_model = tf.keras.layers.Conv2D(\n            filters=512, kernel_size=(3, 3), padding='same',\n            activation='relu')(base_model)\n        base_model = tf.keras.layers.ZeroPadding2D((1, 1))(base_model)\n        base_model = tf.keras.layers.Conv2D(\n            filters=512, kernel_size=(3, 3), padding='same',\n            activation='relu')(base_model)\n        base_model = tf.keras.layers.BatchNormalization(\n            momentum=0.15)(base_model)\n        base_model = tf.keras.layers.MaxPool2D(pool_size=(2, 2))(base_model)\n        base_model = tf.keras.layers.Conv2D(\n            filters=512, kernel_size=(3, 3), padding='same',\n            activation='relu')(base_model)\n        base_model = tf.keras.layers.BatchNormalization(\n            momentum=0.15)(base_model)\n        base_model = tf.keras.layers.Dropout(rate=0.35)(base_model)\n\n        base_model = tf.keras.layers.Flatten()(base_model)\n        base_model = tf.keras.layers.Dense(2048, activation=\"relu\")(base_model)\n        base_model = tf.keras.layers.Dropout(rate=0.35)(base_model)\n        base_model = tf.keras.layers.Dense(1024, activation=\"relu\")(base_model)\n        base_model = tf.keras.layers.Dropout(rate=0.35)(base_model)\n        base_model = tf.keras.layers.Dense(512, activation=\"relu\")(base_model)\n\n        prediction_layer_consonant_diacritic = tf.keras.layers.Dense(\n            units=7, activation='softmax',\n            name='consonant_diacritic')(base_model)\n        prediction_layer_grapheme_root = tf.keras.layers.Dense(\n            units=168, activation='softmax', name='grapheme_root')(base_model)\n        prediction_layer_vowel_diacritic = tf.keras.layers.Dense(\n            units=11, activation='softmax', name='vowel_diacritic')(base_model)\n\n        model = tf.keras.models.Model(\n            inputs=base_model_input,\n            outputs=[\n                prediction_layer_consonant_diacritic,\n                prediction_layer_grapheme_root,\n                prediction_layer_vowel_diacritic\n            ])\n\n        model.compile(\n            optimizer='adam',\n            loss='categorical_crossentropy',\n            metrics=['accuracy'])\n\n        plot_model = tf.keras.utils.plot_model(\n            model,\n            to_file='model.png',\n            show_shapes=True,\n            show_layer_names=True,\n            rankdir='TB',\n            expand_nested=True,\n            dpi=96)\n\n        return model, model.summary(), plot_model\n\n\n(model, summary, plot) = ConvolutionModelGenerator.buildModel(\n    image_size=IMAGE_SIZE, n_channels=NO_OF_CHANNELS)","execution_count":null,"outputs":[]},{"metadata":{"id":"Vy4TrMo61bHv","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":1000},"outputId":"9f476400-23f4-4282-b918-49229f57b331","executionInfo":{"status":"ok","timestamp":1580881937516,"user_tz":-330,"elapsed":393698,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nplot","execution_count":null,"outputs":[]},{"metadata":{"id":"sgvU2pLM1lrK","colab_type":"text"},"cell_type":"markdown","source":"## Verify data"},{"metadata":{"id":"g5_8DtWx1bbu","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":815},"outputId":"f94cfdd5-a01f-4815-95d0-3c7c58a98b05","executionInfo":{"status":"ok","timestamp":1580883436570,"user_tz":-330,"elapsed":5085,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nno_of_images = 7\nrandomint = [\n    random.randrange(0, df_trainimagedata.shape[0])\n    for iter in range(no_of_images * no_of_images)\n]\n\nfor i in range(no_of_images * no_of_images):\n    plt.subplot(no_of_images, no_of_images, i + 1)\n    plt.imshow(X=df_trainimagedata[randomint[i]].reshape((IMAGE_SIZE,\n                                                          IMAGE_SIZE)))\n    gr = df_classmap.loc[(df_classmap['component_type'] == 'grapheme_root') & (\n        df_classmap['label'] == df_traincsv.iloc[randomint[i]]['grapheme_root']\n    )]['component'].values[0]\n    vd = df_classmap.loc[\n        (df_classmap['component_type'] == 'vowel_diacritic')\n        & (df_classmap['label'] == df_traincsv.iloc[randomint[i]]\n           ['vowel_diacritic'])]['component'].values[0]\n    cd = df_classmap.loc[\n        (df_classmap['component_type'] == 'consonant_diacritic')\n        & (df_classmap['label'] == df_traincsv.iloc[randomint[i]]\n           ['consonant_diacritic'])]['component'].values[0]\n    plt.title(f'{gr}  {vd}  {cd}', fontproperties=fontproperties, fontsize=18)\n    plt.grid(False)\n    plt.xticks([])\n    plt.yticks([])\n\nplt.tight_layout()\nplt.show()\n\ndel (no_of_images, randomint, gr, vd, cd, i)\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"id":"BbwY6CJ41zaA","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":201},"outputId":"efc13c51-a8a8-4d1a-db1f-11057dabf8fc","executionInfo":{"status":"ok","timestamp":1580883449537,"user_tz":-330,"elapsed":932,"user":{"displayName":"Bhaveshkumar Thaker","photoUrl":"https://lh3.googleusercontent.com/a-/AAuE7mDAExgnuCZlL1B0T3HawXo0LsyIEHAy-Z8uB2EYCg=s64","userId":"15066255094363934356"}},"trusted":true},"cell_type":"code","source":"#%%\nfor name, size in sorted(\n    ((name, sys.getsizeof(value)) for name, value in globals().items()),\n        key=lambda x: -x[1])[:10]:\n    print(\"{:>30}: {:>8}\".format(name, sizeof_fmt(size)))","execution_count":null,"outputs":[]},{"metadata":{"id":"JEtHom1x2yHO","colab_type":"text"},"cell_type":"markdown","source":"## Training the model in KFold"},{"metadata":{"id":"pVOpODHG24g6","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"#%%\nn_splits = 3\nepochs = 100\nbatch_size = 128\n\nhistories = []\n\nmodel_name = 'bengaliai_classification_model.h5'\n\nmodelcheckpoint = tf.keras.callbacks.ModelCheckpoint(\n    filepath=model_name,\n    monitor='val_grapheme_root_accuracy',\n    save_best_only=True,\n    save_weights_only=False,\n    verbose=1)\nearly_stopping = tf.keras.callbacks.EarlyStopping(\n    monitor='val_grapheme_root_accuracy',\n    patience=2,\n    restore_best_weights=True)\nreduceLR_grapheme_root = tf.keras.callbacks.ReduceLROnPlateau(\n    monitor='grapheme_root_accuracy',\n    patience=2,\n    verbose=1,\n    factor=0.15,\n    min_lr=1e-5)  #0.00001\nreduceLR_vowel_diacritic = tf.keras.callbacks.ReduceLROnPlateau(\n    monitor='vowel_diacritic_accuracy',\n    patience=2,\n    verbose=1,\n    factor=0.15,\n    min_lr=1e-5)\nreduceLR_consonant_diacritic = tf.keras.callbacks.ReduceLROnPlateau(\n    monitor='consonant_diacritic_accuracy',\n    patience=2,\n    verbose=1,\n    factor=0.15,\n    min_lr=1e-5)\n\nfor train_index, test_index in tqdm(\n        KFold(n_splits, random_state=seed).split(df_trainimagedata),\n        total=n_splits,\n        desc=\"KFold\"):\n    x_train, x_test = df_trainimagedata[train_index], df_trainimagedata[\n        test_index]\n    cd_train, cd_test = Y_consonant_diacritic[\n        train_index], Y_consonant_diacritic[test_index]\n    gr_train, gr_test = Y_grapheme_root[train_index], Y_grapheme_root[\n        test_index]\n    vd_train, vd_test = Y_vowel_diacritic[train_index], Y_vowel_diacritic[\n        test_index]\n\n    history = model.fit(\n        datagenerator.flow(\n            x_train, {\n                'consonant_diacritic': cd_train,\n                'grapheme_root': gr_train,\n                'vowel_diacritic': vd_train\n            },\n            batch_size=batch_size,\n            seed=seed),\n        epochs=epochs,\n        steps_per_epoch=x_train.shape[0] // batch_size,\n        validation_data=(x_test, [cd_test, gr_test, vd_test]),\n        callbacks=[\n            modelcheckpoint, early_stopping, reduceLR_grapheme_root,\n            reduceLR_vowel_diacritic, reduceLR_consonant_diacritic\n        ],\n        verbose=2)\n    histories.append(history)\n\n    del (x_train, cd_train, gr_train, vd_train, x_test, cd_test, gr_test,\n         vd_test)\n    gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#%%\nhistory_list = [histories[x].history for x in range(len(histories))]\nfinalhistory = merge_dict(history_list)\npd.DataFrame(finalhistory).to_csv('history.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#%%\ndel (df_trainimagedata)\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"id":"5_5aNgl63t5V","colab_type":"text"},"cell_type":"markdown","source":"## Plot model performances"},{"metadata":{"id":"jRbA-SQM3yQg","colab_type":"text"},"cell_type":"markdown","source":"### Plot model loss performances"},{"metadata":{"id":"_h8gWrvh33V6","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"#%%\nplt.subplot(2, 2, 1)\nplt.plot(finalhistory['loss'])\nplt.plot(finalhistory['val_loss'])\nplt.title('Model Loss', fontsize=18)\nplt.ylabel('Loss')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Validation'], loc='upper right')\n\nplt.subplot(2, 2, 2)\nplt.plot(finalhistory['grapheme_root_loss'])\nplt.plot(finalhistory['val_grapheme_root_loss'])\nplt.title('Model Loss (grapheme_root)', fontsize=18)\nplt.ylabel('Loss')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Validation'], loc='upper right')\n\nplt.subplot(2, 2, 3)\nplt.plot(finalhistory['vowel_diacritic_loss'])\nplt.plot(finalhistory['val_vowel_diacritic_loss'])\nplt.title('Model Loss (vowel_diacritic)', fontsize=18)\nplt.ylabel('Loss')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Validation'], loc='upper right')\n\nplt.subplot(2, 2, 4)\nplt.plot(finalhistory['consonant_diacritic_loss'])\nplt.plot(finalhistory['val_consonant_diacritic_loss'])\nplt.title('Model Loss (consonant_diacritic)', fontsize=18)\nplt.ylabel('Loss')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Validation'], loc='upper right')\n\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"bHi9m21F33nk","colab_type":"text"},"cell_type":"markdown","source":"### Plot model accuracy performances"},{"metadata":{"id":"612h-k4336t1","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"#%%\nplt.subplot(2, 2, 1)\nplt.plot(finalhistory['grapheme_root_accuracy'])\nplt.plot(finalhistory['val_grapheme_root_accuracy'])\nplt.title('Model Accuracy (grapheme_root)', fontsize=18)\nplt.ylabel('Accuracy')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Validation'], loc='upper left')\n\nplt.subplot(2, 2, 2)\nplt.plot(finalhistory['vowel_diacritic_accuracy'])\nplt.plot(finalhistory['val_vowel_diacritic_accuracy'])\nplt.title('Model Accuracy (vowel_diacritic)', fontsize=18)\nplt.ylabel('Accuracy')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Validation'], loc='upper left')\n\nplt.subplot(2, 2, 3)\nplt.plot(finalhistory['consonant_diacritic_accuracy'])\nplt.plot(finalhistory['val_consonant_diacritic_accuracy'])\nplt.title('Model Accuracy (consonant_diacritic)', fontsize=18)\nplt.ylabel('Accuracy')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Validation'], loc='upper left')\n\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"Ewy_8pou4Cmx","colab_type":"text"},"cell_type":"markdown","source":"# Load best model and make predictions"},{"metadata":{"id":"H_7NcBBr4G8C","colab_type":"text"},"cell_type":"markdown","source":"## Load best model"},{"metadata":{"id":"GKnU51r64Kjr","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"#%%\nif runningOnKaggle == True:\n    model_name = '/kaggle/input/bengaliai-grapheme-classification-64x64-kfold/bengaliai_classification_model_64_conv_allimgatonce_v10.h5'\n\n\nmodel = tf.keras.models.load_model(model_name)","execution_count":null,"outputs":[]},{"metadata":{"id":"7f7fttfC4LEz","colab_type":"text"},"cell_type":"markdown","source":"## Load test data"},{"metadata":{"id":"VZsr5bqP4NVD","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"#%%\nclass ImageDataReader():\n    def __init__(self):\n        pass\n\n    def getImages(filepath,\n                  in_image_height,\n                  in_image_width,\n                  out_image_size=128,\n                  n_channels=3,\n                  return_index=False):\n        df_imagedata = np.empty(\n            (0, out_image_size, out_image_size, n_channels), dtype=np.uint8)\n        if return_index == True:\n            df_imagedata_tmp = pd.read_parquet(filepath)\n            df_indexdata = df_imagedata_tmp.pop('image_id')\n        else:\n            df_imagedata_tmp = pd.read_parquet(\n                filepath, columns=[str(x) for x in range(32332)])\n        df_imagedata_tmp = 255 - df_imagedata_tmp.values.reshape(\n            -1, in_image_height, in_image_width).astype(np.uint8)\n        imgarr_tmp = []\n        for row in tqdm(\n                range(df_imagedata_tmp.shape[0]), desc='Loading images'):\n            imgarr = cv2.resize(\n                df_imagedata_tmp[row], (out_image_size, out_image_size),\n                interpolation=cv2.INTER_CUBIC)\n            imgarr[imgarr < 28] = 0\n            imgarr_tmp.append(imgarr)\n        df_imagedata = np.vstack(\n            (df_imagedata, np.asarray(imgarr_tmp, dtype=np.uint8).reshape(\n                -1, out_image_size, out_image_size, n_channels)))\n        del imgarr_tmp\n        del df_imagedata_tmp\n        gc.collect()\n\n        print(\n            f'Returning images of shape {df_imagedata.shape}, type {type(df_imagedata)} of {df_imagedata.dtype}'\n        )\n\n        if return_index == True:\n            return df_indexdata, df_imagedata\n        else:\n            return df_imagedata","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Submit predictions"},{"metadata":{"id":"Nt3k7sxEBTUj","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"#%%\npreds_dict = {\n    'consonant_diacritic': [],\n    'grapheme_root': [],\n    'vowel_diacritic': []\n}\ncomponents = ['consonant_diacritic', 'grapheme_root', 'vowel_diacritic']\n\ntarget = []  # model predictions placeholder\nrow_id = []  # row_id place holder\n\nfor i in trange(4):\n    df_testindexdata, df_testimagedata = ImageDataReader.getImages(\n        filepath=os.path.join(root_dir,\n                              'test_image_data_{}.parquet'.format(i)),\n        in_image_height=ORIGINAL_IMAGE_HEIGHT,\n        in_image_width=ORIGINAL_IMAGE_WIDTH,\n        out_image_size=IMAGE_SIZE,\n        n_channels=NO_OF_CHANNELS,\n        return_index=True)\n\n    preds = model.predict(df_testimagedata)\n\n    for i, p in enumerate(preds_dict):\n        preds_dict[p] = np.argmax(preds[i], axis=1)\n\n    for k, id in enumerate(df_testindexdata.values):\n        for i, comp in enumerate(components):\n            id_sample = id + '_' + comp\n            row_id.append(id_sample)\n            target.append(preds_dict[comp][k])\n    del df_testindexdata\n    del df_testimagedata\n    gc.collect()\n\ndf_sample = pd.DataFrame(\n    {\n        'row_id': row_id,\n        'target': target\n    }, columns=['row_id', 'target'])\ndf_sample.to_csv('submission.csv', index=False)\ndf_sample.head(12)","execution_count":null,"outputs":[]},{"metadata":{"id":"n16iZDSS3Cyo","colab_type":"code","colab":{},"trusted":true},"cell_type":"code","source":"#%%\nprint(\"Notebook Runtime: %0.2f Minutes\" % ((time.time() - notebookstart) / 60))","execution_count":null,"outputs":[]}],"metadata":{"colab":{"name":"bengaliai-v11-forkaggleupload.ipynb","provenance":[],"collapsed_sections":[],"toc_visible":true,"authorship_tag":"ABX9TyN2dfa+Qht3tB3gi1vzSLU2"},"kernelspec":{"name":"python3","display_name":"Python 3"},"widgets":{"application/vnd.jupyter.widget-state+json":{"626fa84301eb4da98995565a616c754c":{"model_module":"@jupyter-widgets/controls","model_name":"HBoxModel","state":{"_view_name":"HBoxView","_dom_classes":[],"_model_name":"HBoxModel","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.5.0","box_style":"","layout":"IPY_MODEL_81cb316536424fbc89dc9e2b01f5a2c3","_model_module":"@jupyter-widgets/controls","children":["IPY_MODEL_c56bca8fafdf47c491e73e026bfd8cbe","IPY_MODEL_71349168841a403c8d8159ba13f2b217"]}},"81cb316536424fbc89dc9e2b01f5a2c3":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"c56bca8fafdf47c491e73e026bfd8cbe":{"model_module":"@jupyter-widgets/controls","model_name":"IntProgressModel","state":{"_view_name":"ProgressView","style":"IPY_MODEL_e56311bef34e404ab31c5b9785cb342c","_dom_classes":[],"description":"","_model_name":"IntProgressModel","bar_style":"success","max":17,"_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":17,"_view_count":null,"_view_module_version":"1.5.0","orientation":"horizontal","min":0,"description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_9d4a05d781f1449588099469889cf370"}},"71349168841a403c8d8159ba13f2b217":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","state":{"_view_name":"HTMLView","style":"IPY_MODEL_32d259535a294bd18ae7f4504d873627","_dom_classes":[],"description":"","_model_name":"HTMLModel","placeholder":"​","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":"100% 17/17 [01:22&lt;00:00,  4.84s/it]","_view_count":null,"_view_module_version":"1.5.0","description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_fbbd6ffc34d446af9e23095475d7b5c8"}},"e56311bef34e404ab31c5b9785cb342c":{"model_module":"@jupyter-widgets/controls","model_name":"ProgressStyleModel","state":{"_view_name":"StyleView","_model_name":"ProgressStyleModel","description_width":"","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","bar_color":null,"_model_module":"@jupyter-widgets/controls"}},"9d4a05d781f1449588099469889cf370":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"32d259535a294bd18ae7f4504d873627":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","state":{"_view_name":"StyleView","_model_name":"DescriptionStyleModel","description_width":"","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","_model_module":"@jupyter-widgets/controls"}},"fbbd6ffc34d446af9e23095475d7b5c8":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"44b498203a7a4fffbc0424444925be48":{"model_module":"@jupyter-widgets/controls","model_name":"HBoxModel","state":{"_view_name":"HBoxView","_dom_classes":[],"_model_name":"HBoxModel","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.5.0","box_style":"","layout":"IPY_MODEL_7dbb093a4ba442e882a84ff9f2c852fc","_model_module":"@jupyter-widgets/controls","children":["IPY_MODEL_be62fb683331453c9141b2f85e760ffa","IPY_MODEL_3db0a33c599a43969674938aa75681f2"]}},"7dbb093a4ba442e882a84ff9f2c852fc":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"be62fb683331453c9141b2f85e760ffa":{"model_module":"@jupyter-widgets/controls","model_name":"IntProgressModel","state":{"_view_name":"ProgressView","style":"IPY_MODEL_8cd5f33c984747f6ae09a4f2a56d8dcc","_dom_classes":[],"description":"Reading parquet","_model_name":"IntProgressModel","bar_style":"success","max":4,"_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":4,"_view_count":null,"_view_module_version":"1.5.0","orientation":"horizontal","min":0,"description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_d7560d3dfe1647a983d1173a723676d7"}},"3db0a33c599a43969674938aa75681f2":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","state":{"_view_name":"HTMLView","style":"IPY_MODEL_a529e8b5c33442c593c8a1e02504df22","_dom_classes":[],"description":"","_model_name":"HTMLModel","placeholder":"​","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":"100% 4/4 [03:17&lt;00:00, 48.15s/it]","_view_count":null,"_view_module_version":"1.5.0","description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_3dff13b9a7f5489db0d857d61b5bffb8"}},"8cd5f33c984747f6ae09a4f2a56d8dcc":{"model_module":"@jupyter-widgets/controls","model_name":"ProgressStyleModel","state":{"_view_name":"StyleView","_model_name":"ProgressStyleModel","description_width":"initial","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","bar_color":null,"_model_module":"@jupyter-widgets/controls"}},"d7560d3dfe1647a983d1173a723676d7":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"a529e8b5c33442c593c8a1e02504df22":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","state":{"_view_name":"StyleView","_model_name":"DescriptionStyleModel","description_width":"","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","_model_module":"@jupyter-widgets/controls"}},"3dff13b9a7f5489db0d857d61b5bffb8":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"5fe5d96a33604348bfbff037390b4775":{"model_module":"@jupyter-widgets/controls","model_name":"HBoxModel","state":{"_view_name":"HBoxView","_dom_classes":[],"_model_name":"HBoxModel","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.5.0","box_style":"","layout":"IPY_MODEL_3855a8ca131244ddbdf42d3d92c48ace","_model_module":"@jupyter-widgets/controls","children":["IPY_MODEL_be7688b0a03f47ad8767b28eca85cfc4","IPY_MODEL_7aaacacd96834f3ab2bf0e09775e6d81"]}},"3855a8ca131244ddbdf42d3d92c48ace":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"be7688b0a03f47ad8767b28eca85cfc4":{"model_module":"@jupyter-widgets/controls","model_name":"IntProgressModel","state":{"_view_name":"ProgressView","style":"IPY_MODEL_e1fcb64d27534200b7ff30d9f8a6623d","_dom_classes":[],"description":"Loading images","_model_name":"IntProgressModel","bar_style":"success","max":50210,"_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":50210,"_view_count":null,"_view_module_version":"1.5.0","orientation":"horizontal","min":0,"description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_4fda7d7816144d08bc8960922ab8d996"}},"7aaacacd96834f3ab2bf0e09775e6d81":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","state":{"_view_name":"HTMLView","style":"IPY_MODEL_aeb1008aa30f4ba28ad400509be26fca","_dom_classes":[],"description":"","_model_name":"HTMLModel","placeholder":"​","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":"100% 50210/50210 [00:14&lt;00:00, 3569.85it/s]","_view_count":null,"_view_module_version":"1.5.0","description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_3ca6bbcf3d0a4576837c071a81868787"}},"e1fcb64d27534200b7ff30d9f8a6623d":{"model_module":"@jupyter-widgets/controls","model_name":"ProgressStyleModel","state":{"_view_name":"StyleView","_model_name":"ProgressStyleModel","description_width":"initial","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","bar_color":null,"_model_module":"@jupyter-widgets/controls"}},"4fda7d7816144d08bc8960922ab8d996":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"aeb1008aa30f4ba28ad400509be26fca":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","state":{"_view_name":"StyleView","_model_name":"DescriptionStyleModel","description_width":"","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","_model_module":"@jupyter-widgets/controls"}},"3ca6bbcf3d0a4576837c071a81868787":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"dff4eb2249ee485694fb5df92f2a9dc3":{"model_module":"@jupyter-widgets/controls","model_name":"HBoxModel","state":{"_view_name":"HBoxView","_dom_classes":[],"_model_name":"HBoxModel","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.5.0","box_style":"","layout":"IPY_MODEL_3be63e32732643e48f14c12578ca9ed8","_model_module":"@jupyter-widgets/controls","children":["IPY_MODEL_2e2456d3f30a40e59a2cf11d7aa8bfeb","IPY_MODEL_61f2fd01fb1d420ab79d26610eb00099"]}},"3be63e32732643e48f14c12578ca9ed8":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"2e2456d3f30a40e59a2cf11d7aa8bfeb":{"model_module":"@jupyter-widgets/controls","model_name":"IntProgressModel","state":{"_view_name":"ProgressView","style":"IPY_MODEL_07aa4684c4e84f50ab587363348c7163","_dom_classes":[],"description":"Loading images","_model_name":"IntProgressModel","bar_style":"success","max":50210,"_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":50210,"_view_count":null,"_view_module_version":"1.5.0","orientation":"horizontal","min":0,"description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_097496ea233f41f6a79dceb2a3e7c0ed"}},"61f2fd01fb1d420ab79d26610eb00099":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","state":{"_view_name":"HTMLView","style":"IPY_MODEL_92b48a06b475443b9d45482c917c431d","_dom_classes":[],"description":"","_model_name":"HTMLModel","placeholder":"​","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":"100% 50210/50210 [00:15&lt;00:00, 3148.84it/s]","_view_count":null,"_view_module_version":"1.5.0","description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_5671c51f2bf94cd18fb08327cbc80704"}},"07aa4684c4e84f50ab587363348c7163":{"model_module":"@jupyter-widgets/controls","model_name":"ProgressStyleModel","state":{"_view_name":"StyleView","_model_name":"ProgressStyleModel","description_width":"initial","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","bar_color":null,"_model_module":"@jupyter-widgets/controls"}},"097496ea233f41f6a79dceb2a3e7c0ed":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"92b48a06b475443b9d45482c917c431d":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","state":{"_view_name":"StyleView","_model_name":"DescriptionStyleModel","description_width":"","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","_model_module":"@jupyter-widgets/controls"}},"5671c51f2bf94cd18fb08327cbc80704":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"36efd9d6525f42dd96f688f8a31f52fc":{"model_module":"@jupyter-widgets/controls","model_name":"HBoxModel","state":{"_view_name":"HBoxView","_dom_classes":[],"_model_name":"HBoxModel","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.5.0","box_style":"","layout":"IPY_MODEL_4694cd38d765444d9c8a7825b45c4adc","_model_module":"@jupyter-widgets/controls","children":["IPY_MODEL_c13e145493904a578d4a632ee28028b4","IPY_MODEL_3b57736a93c74099a81743a55326bfd6"]}},"4694cd38d765444d9c8a7825b45c4adc":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"c13e145493904a578d4a632ee28028b4":{"model_module":"@jupyter-widgets/controls","model_name":"IntProgressModel","state":{"_view_name":"ProgressView","style":"IPY_MODEL_86d02fad8e0f495eb26936b135018f9c","_dom_classes":[],"description":"Loading images","_model_name":"IntProgressModel","bar_style":"success","max":50210,"_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":50210,"_view_count":null,"_view_module_version":"1.5.0","orientation":"horizontal","min":0,"description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_1b968b5e0b2d44fdb195562555e4beef"}},"3b57736a93c74099a81743a55326bfd6":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","state":{"_view_name":"HTMLView","style":"IPY_MODEL_76ac0bae99ad44d1b60a288f5a71ff04","_dom_classes":[],"description":"","_model_name":"HTMLModel","placeholder":"​","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":"100% 50210/50210 [00:33&lt;00:00, 1479.33it/s]","_view_count":null,"_view_module_version":"1.5.0","description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_9cae9118c25e4d21b52c31640ad43152"}},"86d02fad8e0f495eb26936b135018f9c":{"model_module":"@jupyter-widgets/controls","model_name":"ProgressStyleModel","state":{"_view_name":"StyleView","_model_name":"ProgressStyleModel","description_width":"initial","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","bar_color":null,"_model_module":"@jupyter-widgets/controls"}},"1b968b5e0b2d44fdb195562555e4beef":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"76ac0bae99ad44d1b60a288f5a71ff04":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","state":{"_view_name":"StyleView","_model_name":"DescriptionStyleModel","description_width":"","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","_model_module":"@jupyter-widgets/controls"}},"9cae9118c25e4d21b52c31640ad43152":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"f8a12abbd1464995a48379fd0257eeed":{"model_module":"@jupyter-widgets/controls","model_name":"HBoxModel","state":{"_view_name":"HBoxView","_dom_classes":[],"_model_name":"HBoxModel","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.5.0","box_style":"","layout":"IPY_MODEL_95211a3d4d984691a03e6c076eb7d5c6","_model_module":"@jupyter-widgets/controls","children":["IPY_MODEL_71bc73bae20d4c239008878bc46749b3","IPY_MODEL_eabfb3fab44e453f94f8b654c643e5da"]}},"95211a3d4d984691a03e6c076eb7d5c6":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"71bc73bae20d4c239008878bc46749b3":{"model_module":"@jupyter-widgets/controls","model_name":"IntProgressModel","state":{"_view_name":"ProgressView","style":"IPY_MODEL_7286a83ade6844d4b82d8e36e070b31d","_dom_classes":[],"description":"Loading images","_model_name":"IntProgressModel","bar_style":"success","max":50210,"_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":50210,"_view_count":null,"_view_module_version":"1.5.0","orientation":"horizontal","min":0,"description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_ce106f75acd54f1b8fd233839aaebb31"}},"eabfb3fab44e453f94f8b654c643e5da":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","state":{"_view_name":"HTMLView","style":"IPY_MODEL_ff77cd177e9b466fb31a8ce5cc451949","_dom_classes":[],"description":"","_model_name":"HTMLModel","placeholder":"​","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":"100% 50210/50210 [00:35&lt;00:00, 1420.51it/s]","_view_count":null,"_view_module_version":"1.5.0","description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_46756b1134f34ddcbe3927c715dd98b5"}},"7286a83ade6844d4b82d8e36e070b31d":{"model_module":"@jupyter-widgets/controls","model_name":"ProgressStyleModel","state":{"_view_name":"StyleView","_model_name":"ProgressStyleModel","description_width":"initial","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","bar_color":null,"_model_module":"@jupyter-widgets/controls"}},"ce106f75acd54f1b8fd233839aaebb31":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"ff77cd177e9b466fb31a8ce5cc451949":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","state":{"_view_name":"StyleView","_model_name":"DescriptionStyleModel","description_width":"","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","_model_module":"@jupyter-widgets/controls"}},"46756b1134f34ddcbe3927c715dd98b5":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}}}}},"nbformat":4,"nbformat_minor":1}