{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"mean = lambda l: sum(l) / len(l)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nfrom PIL import Image\nfrom skimage.filters import threshold_otsu\nfrom skimage.transform import AffineTransform, SimilarityTransform, warp, resize\nimport math\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.optim.lr_scheduler import OneCycleLR\nfrom torch.utils.data import Dataset, DataLoader, Subset, WeightedRandomSampler, TensorDataset\nfrom sklearn.model_selection import train_test_split\nfrom tqdm import notebook\nimport torchvision\nfrom torchvision import transforms\nfrom torchvision import models\nfrom collections import Counter\nfrom pathlib import Path\nfrom sklearn.metrics import confusion_matrix, recall_score\nimport seaborn as sn\n!pip install torchsummary\nimport torchsummary\n# !pip install torch-lr-finder\n# from torch_lr_finder import LRFinder\nimport copy\nimport math\nimport random\nfrom PIL.Image import BICUBIC\nimport json\n!pip install pretrainedmodels\nimport pretrainedmodels\n!pip install iterative-stratification\nfrom iterstrat.ml_stratifiers import MultilabelStratifiedShuffleSplit\n!pip install torchtoolbox\nfrom torchtoolbox.tools import mixup_data, mixup_criterion","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(*torch.__config__.show().split(\"\\n\"), sep=\"\\n\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.set_num_threads(2 if torch.cuda.is_available() else 4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.manual_seed(0)\nnp.random.seed(0)\nrandom.seed(0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"","_uuid":"","trusted":true},"cell_type":"code","source":"df_train = pd.read_csv('/kaggle/input/bengaliai-cv19/train.csv')\ndf_test = pd.read_csv('/kaggle/input/bengaliai-cv19/test.csv')\ndf_class = pd.read_csv('/kaggle/input/bengaliai-cv19/class_map.csv')\ndf_submission = pd.read_csv('/kaggle/input/bengaliai-cv19/sample_submission.csv')\ndf_auxtask_label = pd.read_csv('/kaggle/input/bhgd-aux-tasks/tasks.csv', names=['id', 'matra', 'up', 'conj', 'fg', 'sg'], skiprows=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def patch_label_with_corrected_label(df, cl):\n    for row in cl.itertuples(name=None):\n        df.at[row[1], 'grapheme_root'] = row[2]\n        df.at[row[1], 'vowel_diacritic'] = row[3]\n        df.at[row[1], 'consonant_diacritic'] = row[4]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_corrected_labels = pd.read_csv('/kaggle/input/bhgd-corrected-labels/corrected_labels.csv', names=['index', 'g', 'v', 'c'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(df_corrected_labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_corrected_labels.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# patch_label_with_corrected_label(df_train, df_corrected_labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"n_graphemes, n_vowel_diacs, n_consonant_diacs = len(set(df_train['grapheme_root'])), len(set(df_train['vowel_diacritic'])), len(set(df_train['consonant_diacritic']))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def make_tensordataset_from_npys(npy_locs, ids_file, lbl_df=None):\n    with open(ids_file) as f:\n        ids = json.load(f)\n    X = []\n    npy_locs = notebook.tqdm(npy_locs)\n    for npy_loc in npy_locs:\n        x = np.load(npy_loc)\n        X.append(x)\n    X = np.vstack(X)\n    X = X.reshape(-1, 1, 137, 236)\n    X = torch.from_numpy(X)\n    ids = dict((s,i) for (i,s) in enumerate(ids))\n    if lbl_df is None:\n        return TensorDataset(X)\n    else:\n        graphemes = torch.zeros(X.shape[0], dtype=torch.long)\n        vowel_diacs = torch.zeros(X.shape[0], dtype=torch.long)\n        consonant_diacs = torch.zeros(X.shape[0], dtype=torch.long)\n        for row in lbl_df.itertuples():\n            if row.image_id not in ids:\n                continue\n            idx = ids[row.image_id]\n            graphemes[idx] = row.grapheme_root\n            vowel_diacs[idx] = row.vowel_diacritic\n            consonant_diacs[idx] = row.consonant_diacritic\n        return TensorDataset(X, graphemes, vowel_diacs, consonant_diacs)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# def make_tensordataset_from_dfs(parquet_locs, label_loc=None):\n#     ids = []\n#     X = []\n#     parquet_locs = notebook.tqdm(parquet_locs)\n#     for parquet_loc in parquet_locs:\n#         df = pd.read_parquet(parquet_loc)\n#         ids.extend(df.image_id.tolist())\n#         x = df.iloc[:, 1:].to_numpy(dtype=np.uint8)\n#         del df\n#         X.append(x)\n#     X = np.vstack(X)\n#     X = X.reshape(-1, 1, 137, 236)\n#     X = torch.from_numpy(X)\n#     ids = dict((s,i) for (i,s) in enumerate(ids))\n#     if label_loc is None:\n#         return TensorDataset(X)\n#     else:\n#         graphemes = torch.zeros(X.shape[0], dtype=torch.long)\n#         vowel_diacs = torch.zeros(X.shape[0], dtype=torch.long)\n#         consonant_diacs = torch.zeros(X.shape[0], dtype=torch.long)\n#         lbl_df = pd.read_csv(label_loc)\n#         for row in lbl_df.itertuples():\n#             if row.image_id not in ids:\n#                 continue\n#             idx = ids[row.image_id]\n#             graphemes[idx] = row.grapheme_root\n#             vowel_diacs[idx] = row.vowel_diacritic\n#             consonant_diacs[idx] = row.consonant_diacritic\n#         return TensorDataset(X, graphemes, vowel_diacs, consonant_diacs)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# ds = make_tensordataset_from_dfs(\n#     ['/kaggle/input/bengaliai-cv19/train_image_data_{}.parquet'.format(i) for i in range(4)], \n#     '/kaggle/input/bengaliai-cv19/train.csv')","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":"ds = make_tensordataset_from_npys(\n    ['/kaggle/input/bangla-grapheme-npy/tr-ds-{}.npy'.format(i) for i in range(1, 5)],\n    '/kaggle/input/bangla-grapheme-npy/tr-ds-ids.json',\n    df_train)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"detensorify = lambda l : list(map(lambda t:t.item(), l))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = [detensorify(ds[i][1:]) for i in range(len(ds))]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = np.array(labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# class DatasetFromImg(Dataset):\n#     def __init__(self, img_dir, df):\n#         super(DatasetFromImg, self).__init__()\n#         self.img_dir = img_dir\n#         self.df = df\n        \n#     def __getitem__(self, index):\n#         img_fname = self.df.iloc[index].image_id + '.png'\n#         img = Image.open(self.img_dir + '/' + img_fname)\n#         g = self.df.iloc[index].grapheme_root\n#         v = self.df.iloc[index].vowel_diacritic\n#         c = self.df.iloc[index].consonant_diacritic\n#         return img, g, v, c\n    \n#     def __len__(self):\n#         return len(self.df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# ds = DatasetFromImg('/kaggle/input/grapheme-imgs-128x128', df_train)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class DatasetWithAuxiliaryTasks(Dataset):\n    def __init__(self, ds, auxilary_tasks):\n        super(DatasetWithAuxiliaryTasks, self).__init__()\n        self.auxilary_tasks = auxilary_tasks\n        self.ds = ds\n        self.ln = len(self.ds)\n        \n    def __getitem__(self, index):\n        img, g, v, c = ds[index]\n        aux_labels = [f(g, v, c) for f in self.auxilary_tasks]\n        return (img, g, v, c) + tuple(aux_labels)\n    \n    def __len__(self):\n        return self.ln","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"matra_label = df_auxtask_label.set_index('id')['matra'].to_dict()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fg_label = df_auxtask_label.set_index('id')['fg'].to_dict()\ng_to_fg = dict(((k, v) for v, k in  enumerate((set(fg_label.values())))))\nfg_label = dict(((k, g_to_fg[v]) for k, v in fg_label.items()))\nnum_fg = len(g_to_fg.keys())\ng_to_fg, num_fg","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sg_label = df_auxtask_label.set_index('id')['sg'].to_dict()\ng_to_sg = dict(((k, v) for v, k in  enumerate((set(sg_label.values())))))\nsg_label = dict(((k, g_to_sg[v]) for k, v in sg_label.items()))\nnum_sg = len(g_to_sg.keys())\ng_to_sg, num_sg","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"conj_label = df_auxtask_label.set_index('id')['conj'].to_dict()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"up_label = df_auxtask_label.set_index('id')['up'].to_dict()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def no_diac_task(g, v, c):\n    return 1 if g < 13 else 0\ndef matra_task(g, v, c):\n    return matra_label[g.item()]\ndef up_task(g, v, c):\n    return up_label[g.item()]\ndef conj_task(g, v, c):\n    return conj_label[g.item()]\ndef fg_task(g, v, c):\n    return fg_label[g.item()]\ndef sg_task(g, v, c):\n    return sg_label[g.item()]\naux_tasks = []#[no_diac_task, matra_task, up_task, conj_task, fg_task, sg_task]\nds_with_aux = DatasetWithAuxiliaryTasks(ds, aux_tasks)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class DatasetWithImageTransforms(Dataset):\n    def __init__(self, ds, transforms):\n        super(DatasetWithImageTransforms, self).__init__()\n        self.ds = ds\n        self.tr = transforms\n        self.nt = len(self.ds[0])\n        self.ln = len(self.ds)\n        \n    def __getitem__(self, index):\n        img, *rest = self.ds[index]\n        img = self.tr(img)\n        return (img,) + tuple(rest)\n    \n    def __len__(self):\n        return self.ln","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"detensorify = lambda l : list(map(lambda t:t.item(), l))\n\nlabels = [detensorify(ds[i][1:]) for i in range(len(ds))]\n\nlabels = np.array(labels)\n\nmsss = MultilabelStratifiedShuffleSplit(n_splits=1, test_size=0.01, random_state=42)\n\ntr_indices, va_indices = list(msss.split(list(range(len(ds))), labels))[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# tr_indices, va_indices = torch.load('/kaggle/input/bangla-handwritten-grapheme/tr_indices'), torch.load('/kaggle/input/bangla-handwritten-grapheme/va_indices')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.save(tr_indices, 'tr_indices')\ntorch.save(va_indices, 'va_indices')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# tr_indices, va_indices = train_test_split(\n#     list(range(len(ds))), \n#     test_size=0.10, \n#     train_size=0.90, \n#     random_state=42,\n#     stratify=labels[:,0]\n# )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tr_ds = Subset(ds_with_aux, tr_indices)\nva_ds = Subset(ds_with_aux, va_indices)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Returns binary image\ndef thresh(img):\n    thresh_val = int(threshold_otsu(img))\n    img = (img > thresh_val)\n    return img\n\n# For binary image\ndef bounding_box(img):\n    img = thresh(img).astype(np.uint8)\n    # find the min value of each column\n    col_min_val = np.min(img, axis=0)\n    # find the min value of each row\n    row_min_val = np.min(img, axis=1)\n    # argwhere finds the non-zero elements we want to find the zero elements (zeros are part of character)\n    col = np.argwhere(1 - col_min_val).flatten()\n    row = np.argwhere(1 - row_min_val).flatten()\n    return row.min(), row.max(), col.min(), col.max()\n\ndef scale_to_bb(img):\n    height = img.shape[0]\n    width = img.shape[1]\n    t, b, l, r = bounding_box(img)\n    box_width = r - l\n    box_height = b - t\n    t, l = max(0, t - 10), max(0, l - 10)\n    b, r = min(height, b + 10), min(width, r + 10)\n#     print(l, r, t, b)\n    img = resize(img[t:b, l:r], output_shape=(256, 256), preserve_range=True, order=3, cval=1.0)\n    return img\n\ndef random_scale(img):\n    height = img.shape[0]\n    width = img.shape[1]\n    t, b, l, r = bounding_box(img)\n    box_width = r - l\n    box_height = b - t\n    max_width_scale = (box_width + min(l, width - r)) / box_width\n    max_height_scale = (box_height + min(t, height - b)) / box_height\n    max_scale = min(max_width_scale, max_height_scale)\n    min_scale = min(1.0, 0.25 * max((height / box_height), (width / box_width)))\n    scale = random.uniform(min_scale, max_scale)\n    tfm = SimilarityTransform(\n        scale=(scale, scale),\n    )\n    img = warp(img, tfm.inverse, cval=1.0, order=3)\n    return img\n\ndef random_translate(img):\n    height = img.shape[0]\n    width = img.shape[1]\n    t, b, l, r = bounding_box(img)\n    box_width = r - l\n    box_height = b - t\n    translate_height = random.uniform(-t, height - b)\n    translate_width = random.uniform(-l, width - r)\n    tfm = SimilarityTransform(\n        translation=(translate_width, translate_height),\n    )\n    img = warp(img, tfm.inverse, cval=1.0, order=3)\n    return img\n\ndef random_rotate_and_shear(img):\n    max_theta = math.pi / 16\n    theta = random.uniform(-max_theta, max_theta)\n    max_shear_theta = math.pi / 8\n    shear_theta = random.uniform(-max_shear_theta, max_shear_theta)\n    tfm = AffineTransform(rotation=theta, shear=shear_theta)\n    img = warp(img, tfm.inverse, cval=1.0, order=3)\n    return img\n\ndef invert_color(t):\n    t.mul_(-1)\n    t.add_(255)\n    return t\n\ndef affine_transforms(img):\n    img = img.reshape(137, 236).numpy()\n    img = thresh(img).astype(np.float32)\n#     img = random_translate(random_scale(random_rotate_and_shear(img)))\n    img = random_translate(random_scale(img))\n    img = img.reshape(1, 137, 236)\n    return torch.from_numpy(img)\n\ndef tfms(img):\n    img = img.reshape(137, 236).numpy()\n    img = thresh(img).astype(np.float32)\n    img = scale_to_bb(img)\n    img = img.reshape(1, 256, 256)\n    return torch.from_numpy(img)\n\ndef va_tfms(img):\n    img = img.reshape(137, 236).numpy()\n    img = thresh(img).astype(np.float32)\n    img = img.reshape(1, 137, 236)\n    return torch.from_numpy(img)\n\naffine_transforms = transforms.Lambda(affine_transforms)\nmult = transforms.Lambda(lambda img: img * 255)\nto_float = transforms.Lambda(lambda img: img.float())\ninvert_color = transforms.Lambda(invert_color)\ntfms = transforms.Compose([\n#     transforms.RandomApply([\n        tfms,\n#         mult,\n#     ], p=0.90),\n    to_float,\n])\n\nva_tfms = transforms.Compose([\n    tfms,\n#     mult,\n    to_float,\n])\n\ntr_ds_tfms = DatasetWithImageTransforms(tr_ds, tfms)\nva_ds_tfms = DatasetWithImageTransforms(va_ds, va_tfms)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_from_ds(ds, idx, img_is_tensor=False):\n    img, g, v, c, *rest = ds[idx]\n    g, v, c = g.item(), v.item(), c.item()\n    if img_is_tensor:\n        print(img.shape)\n        img = img.flatten(end_dim=1)\n        print(img.shape)\n    plt.imshow(img, cmap='gray', vmin=0., vmax=1.0)\n    print(df_class[(df_class['label'] == g) & (df_class['component_type'] == 'grapheme_root')]['component'])\n    print(df_class[(df_class['label'] == v) & (df_class['component_type'] == 'vowel_diacritic')]['component'])\n    print(df_class[(df_class['label'] == c) & (df_class['component_type'] == 'consonant_diacritic')]['component'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"idx = random.randrange(len(ds_with_aux))\nplot_from_ds(ds_with_aux, idx, img_is_tensor=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"idx = random.randrange(len(tr_ds_tfms))\nidx","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_from_ds(tr_ds, idx, img_is_tensor=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_from_ds(tr_ds_tfms, idx, img_is_tensor=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tr_ds = tr_ds_tfms\nva_ds = va_ds_tfms","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(ds), len(tr_ds), len(va_ds)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(pretrainedmodels.model_names)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!ls /kaggle/input/pretrained-model-weights-pytorch","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# torchsummary.summary(model, input_size=(3,128,128))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class MultiTaskNN(nn.Module):\n    def __init__(self, base, task_predictors):\n        super(MultiTaskNN, self).__init__()\n        self.base = base\n        self.task_predictors = nn.ModuleList(task_predictors)\n        \n    def freeze(self):\n        for p in self.base.parameters():\n            p.requires_grad = False\n        \n    def unfreeze(self):\n        for p in self.base.parameters():\n            p.requires_grad = True\n        \n    def forward(self, x):\n        features = self.base(x)\n        preds = [predictor(features) for predictor in self.task_predictors]\n        return preds","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def make_linear_block(in_size, out_size):\n    block = nn.Sequential(\n        nn.Linear(in_size, out_size), \n#         nn.Dropout(0.5),\n        nn.ReLU(), \n        nn.BatchNorm1d(num_features=out_size),\n    )\n    nn.init.xavier_normal_(block[0].weight.data)\n    nn.init.zeros_(block[0].bias.data)\n    return block\n\nclass ResBlock(nn.Module):\n    def __init__(self, layer):\n        super(ResBlock, self).__init__()\n        self.layer = layer\n        \n    def forward(self, x):\n        return x + self.layer(x)\n\ndef make_ff_predictor(in_size, intermediate_size, out_size, layer_count, res_block=False):\n    if not res_block:\n        layers = [make_linear_block(in_size, intermediate_size)]\n    else:\n        layers = [ResBlock(make_linear_block(intermediate_size, intermediate_size))]\n    for i in range(layer_count):\n        if not res_block:\n            layers.append(make_linear_block(intermediate_size, intermediate_size))\n        else:\n            layers.append(ResBlock(make_linear_block(intermediate_size, intermediate_size)))\n    layers.append(nn.Linear(intermediate_size, out_size))\n    layers = nn.Sequential(*layers)\n    return layers\n\ndef make_squeeze_predictor(in_size, out_size):\n    return nn.Sequential(\n            nn.Dropout(p=0.5),\n            nn.Conv2d(in_size, out_size, kernel_size=(1, 1)),\n            nn.ReLU(),\n            nn.AdaptiveAvgPool2d(output_size=(1,1)),\n            nn.Flatten()\n        )\n\n# class MultiTaskNN(nn.Module):\n#     def __init__(self, n_classes_tasks, depth_tasks):\n#         super(MultiTaskNN, self).__init__()\n# #         base = models.squeezenet1_0(pretrained=True).features\n#         base = pretrainedmodels.__dict__['se_resnext101_32x4d']()\n#         # base.load_state_dict(torch.load('./pnasnet5large-bf079911.pth'))\n#         base.avg_pool = nn.AdaptiveAvgPool2d((1, 1))\n#         # base.dropout = nn.Identity()\n#         base.last_linear = nn.Identity()\n#         feature_size = 2048\n#         # base, feature_size = models.resnet18(pretrained=False), 512\n#         # base.load_state_dict(torch.load('./resnet18-5c106cde.pth'))\n# #         base = models.wide_resnet101_2(pretrained=True)\n#         # base.fc = nn.Identity()\n# #         base = models.densenet121(pretrained=True)\n# #         base.classifier = nn.Identity()\n#         self.base = base\n#         self.task_predictors = nn.ModuleList([\n#             make_ff_predictor(feature_size, 512, n_classes, depth) \n#             for n_classes, depth in zip(n_classes_tasks, depth_tasks)\n#         ])\n#         self.n_classes_tasks = n_classes_tasks\n#         self.depth_tasks = depth_tasks\n\n#     def convert_to_grayscale(self):\n#         with torch.no_grad():\n#             # conv1 = nn.Conv2d(3, 96, kernel_size=(3, 3), stride=(2, 2), bias=False)\n#             # conv1.weight.data = torch.sum(self.base.conv_0.conv.weight.data, dim=1, keepdim=True)\n#             # self.base.conv_0.conv = conv1\n#             conv1 = nn.Conv2d(1, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\n#             conv1.weight.data = torch.sum(self.base.layer0.conv1.weight.data, dim=1, keepdim=True)\n#             # self.base.conv1 = conv1\n#             self.base.layer0.conv1 = conv1\n# #             conv1.weight.data = torch.sum(self.base.features.conv0.weight.data, dim=1, keepdim=True)\n# #             self.base.features.conv0 = conv1\n            \n#     def freeze(self):\n#         for p in self.base.parameters():\n#             p.requires_grad = False\n#         # # unfreeze the bns\n#         # for param in self.named_parameters():\n#         #     if 'bn' in param[0]:\n#         #         param[1].requires_grad = True\n#         #     if 'downsample.1' in param[0]:\n#         #         param[1].requires_grad = True\n        \n#     def unfreeze(self):\n#         for p in self.base.parameters():\n#             p.requires_grad = True\n        \n#     def forward(self, x):\n#         features = self.base(x)\n#         preds = [predictor(features) for predictor in self.task_predictors]\n#         return preds","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def train_multi_task_batch(model, optimizer, criterions, mtl_criterion, device, batch, weight_update=True, with_mixup=False):\n    img, *labels = batch\n    img = img.to(device)\n#     img = img / 255.0\n    labels = list(map(lambda i: i.to(device), labels))\n    if with_mixup:\n        alpha = 0.1\n#         labels = list(map(lambda i: i.to(device), labels))\n        img, labels_a, labels_b, lam = mixup_data(img, torch.from_numpy(np.arange(len(labels[0]))), alpha)\n        labels_a, labels_b = [l[labels_a] for l in labels], [l[labels_b] for l in labels]\n        preds = model(img)\n        losses = tuple([mixup_criterion(criterion, pred, l_a, l_b, lam) for criterion, pred, l_a, l_b in zip(criterions, preds, labels_a, labels_b)])\n    else:\n        preds = model(img)\n        losses = tuple([criterion(pred, label) for criterion, pred, label in zip(criterions, preds, labels)])\n    mtl_loss = mtl_criterion(torch.stack(losses))\n    mtl_loss.backward()\n    if weight_update:\n        optimizer.step()\n        optimizer.zero_grad()\n    return (mtl_loss.item(),) + tuple(map(lambda l: l.item(), losses))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def validate_multi_task_batch(model, criterions, mtl_criterion, device, batch, collapse=True, pred_collapse=True):\n    with torch.no_grad():\n        img, *labels = batch\n        img = img.to(device)\n#         img = img / 255.0\n        preds = model(img)\n        labels = list(map(lambda i: i.to(device), labels))\n        losses = tuple([criterion(pred, label) for criterion, pred, label in zip(criterions, preds, labels)])\n        mtl_loss = mtl_criterion(torch.stack(losses))\n        if not collapse:\n            losses = (mtl_loss.tolist(),) + tuple(map(lambda l: l.tolist(), losses))\n        else:\n            losses = (mtl_loss.item(),) + tuple(map(lambda l: l.item(), losses))\n        if pred_collapse:\n            preds = tuple(map(lambda p: p.argmax(1).tolist(), preds))\n        else:\n            preds = tuple(map(lambda p: p.tolist(), preds))\n        trues = tuple(map(lambda l: l.tolist(), labels))\n        return losses, preds, trues","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class FocalLoss(nn.Module):\n    def __init__(self, alpha=1., gamma=1.):\n        super().__init__()\n        self.alpha = alpha\n        self.gamma = gamma\n\n    def forward(self, inputs, targets, **kwargs):\n        CE_loss = nn.CrossEntropyLoss(reduction='none')(inputs, targets)\n        pt = torch.exp(-CE_loss)\n        F_loss = self.alpha * ((1-pt)**self.gamma) * CE_loss\n        return F_loss.mean()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class LabelSmoothingLoss(nn.Module):\n    \"\"\"\n    Probability of correct class will be confidence.\n    \"\"\"\n    def __init__(self, confidence, n, reduction='mean'):\n        super().__init__()\n        # gamma is the probability of each incorrect class\n        self.gamma = (1 - confidence) / (n - 1)\n        self.n = n\n        self.logsoftmax = nn.LogSoftmax(dim=1)\n        self.nllloss = nn.NLLLoss(reduction=reduction)\n        self.reduction = reduction\n        \n    def forward(self, inputs, targets):\n        logp = self.logsoftmax(inputs)\n        ce_loss = self.nllloss(logp, targets)\n        if self.reduction == 'mean':\n            reg_loss = - torch.mean(logp)\n        else:\n            reg_loss = - torch.sum(logp, dim=1)\n        return (1 - self.n * self.gamma) * ce_loss + self.gamma * reg_loss","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class MultiTaskLoss(nn.Module):\n    def __init__(self, num_tasks, init_weight=None):\n        super(MultiTaskLoss, self).__init__()\n        self.n = num_tasks\n        if init_weight is None:\n            self.w = nn.Parameter(torch.zeros(self.n))\n        else:\n            self.w = nn.Parameter(torch.tensor(init_weight))\n            \n    def freeze(self):\n        for p in self.parameters():\n            p.requires_grad = False\n\n    def forward(self, losses):\n        return torch.sum(torch.exp(-2.0 * self.w) * losses) + torch.sum(self.w)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class MultiTaskSumLoss(nn.Module):\n    def __init__(self, num_tasks, init_weight=None, collapse=True):\n        super(MultiTaskSumLoss, self).__init__()\n        self.n = num_tasks\n        if init_weight is None:\n            self.w = nn.Parameter(torch.ones(self.n))\n        else:\n            self.w = nn.Parameter(torch.tensor(init_weight))\n        self.requires_grad = False\n        self.collapse = collapse\n        if not self.collapse:\n            self.w.data = self.w.data.reshape(-1, 1)\n\n    def forward(self, losses):\n        if not self.collapse:\n            return torch.sum(losses * self.w, dim=0)\n        else:\n            return torch.sum(losses * self.w)# - torch.sum(torch.sum(torch.log(self.w)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# LRFinder\ndef lr_finder(model, optimizer, criterions, mtl_criterion, device, dl, num_iter=10, start_lr=1e-4, end_lr=1.0, gradient_accumulation_step=1, with_mixup=False):\n    model_state =  copy.deepcopy(model.state_dict())\n    optim_state =  copy.deepcopy(optimizer.state_dict())\n    mtl_criterion_state = copy.deepcopy(mtl_criterion.state_dict())\n    for param in optimizer.param_groups:\n        param['lr'] = start_lr\n    gamma = (end_lr / start_lr) ** (1 / (num_iter * gradient_accumulation_step))\n    print(gamma, start_lr, end_lr)\n    lrf_sched = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma)\n    count = 0\n    lrf_losses = []\n    lrs = []\n    min_loss = math.inf\n    done = False\n    while not done:\n        batches = dl\n        batches = notebook.tqdm(tr_dl)\n        for batch in batches:\n            count += 1\n            weight_update = (count % gradient_accumulation_step) == (gradient_accumulation_step - 1)\n            losses = train_multi_task_batch(model, optimizer, criterions, mtl_criterion, device, batch, weight_update, with_mixup)\n            print(losses)\n            min_loss = min(min_loss, losses[0])\n            lrf_losses.append(losses)\n            if weight_update:\n                lrf_sched.step()\n            lrs.append([pg['lr'] for pg in optimizer.param_groups])\n            if num_iter * gradient_accumulation_step == count:# or losses[0] /10.0 > min_loss:\n                done = True\n                break\n    model.load_state_dict(model_state)\n    optimizer.load_state_dict(optim_state)\n    mtl_criterion.load_state_dict(mtl_criterion_state)\n    return lrf_losses, lrs","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"aux_depths = []#[3, 3, 3, 3, 4, 4]\naux_n = []#[2, 3, 2, 2, num_fg, num_sg]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"base, feature_size = models.resnet18(pretrained=True), 512\nbase.fc = nn.Identity()\nconv1 = nn.Conv2d(1, 96, kernel_size=(3, 3), stride=(2, 2), bias=False)\nconv1.weight.data = torch.sum(base.conv1.weight.data, dim=1, keepdim=True)\nbase.conv1 = conv1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"n_classes_tasks = [n_graphemes, n_vowel_diacs, n_consonant_diacs] + aux_n\n# depth_tasks = [2, 1, 1] + aux_depths\n# task_predictors = [\n#     make_ff_predictor(feature_size, 512, n_classes, depth) \n#     for n_classes, depth in zip(n_classes_tasks, depth_tasks)\n# ]\ntask_predictors = [nn.Linear(feature_size, n_classes, bias=False) for n_classes in n_classes_tasks]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = MultiTaskNN(base, task_predictors).to(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.load_state_dict(torch.load('/kaggle/input/bangla-handwritten-grapheme/model.pth', map_location=device), strict=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model.unfreeze()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tr_dl = DataLoader(tr_ds, batch_size=256, num_workers=2, pin_memory=True, shuffle=True, drop_last=True)\nva_dl = DataLoader(va_ds, batch_size=256, num_workers=2, pin_memory=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"g_criterion = nn.CrossEntropyLoss()#FocalLoss(gamma=2.0)\nv_criterion = nn.CrossEntropyLoss()#FocalLoss(gamma=2.0)\nc_criterion = nn.CrossEntropyLoss()#FocalLoss(gamma=2.0)\nnd_criterion = nn.CrossEntropyLoss()#FocalLoss(gamma=2.0)\nmatra_criterion = nn.CrossEntropyLoss()#FocalLoss(gamma=2.0)\nup_criterion = nn.CrossEntropyLoss()\nconj_criterion = nn.CrossEntropyLoss()\nfg_criterion = nn.CrossEntropyLoss()\nsg_criterion = nn.CrossEntropyLoss()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"criterions = (g_criterion, v_criterion, c_criterion)#, nd_criterion, matra_criterion, up_criterion, conj_criterion, fg_criterion, sg_criterion)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"num_tasks = len(criterions)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"gradient_accumulation_step = 1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mtl_criterion = MultiTaskSumLoss(num_tasks, np.array([1.0, 1.0, 1.0]) / gradient_accumulation_step).to(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# optimizer = optim.Adam([{'params': model.parameters()}, {'params': mtl_criterion.parameters()}])\n# optimizer = optim.SGD([{'params': model.parameters()}, {'params': mtl_criterion.parameters()}], lr=1e-2, momentum=0.9)\n# optimizer = optim.Adam(model.parameters(), lr=1e-5)\n# optimizer = optim.SGD(model.parameters(), lr=1e-2, momentum=0.9)\noptimizer = optim.Adam([{'params': model.base.parameters(), 'lr': 1e-4}, \n                        {'params': model.task_predictors[0].parameters(), 'lr': 1e-4},\n                        {'params': model.task_predictors[1].parameters(), 'lr': 1e-4},\n                        {'params': model.task_predictors[2].parameters(), 'lr': 1e-4},\n                        ])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# optimizer.load_state_dict(torch.load('/kaggle/input/bangla-handwritten-grapheme/optim.pth', map_location=device))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# optimizer.param_groups[0]['lr'] = 3e-4","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# lrf_losses, lrs = lr_finder(model, optimizer, criterions, mtl_criterion, device, tr_dl, \n#                             num_iter=10, start_lr=1e-5, end_lr=1e-2, gradient_accumulation_step=gradient_accumulation_step, with_mixup=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# skip_first = 0\n# skip_last = 1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plt.plot([t[0] for t in lrs[skip_first:-skip_last]])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plt.plot([t[0] for t in lrs[skip_first:-skip_last]], [t[1] for t in lrf_losses][skip_first:-skip_last])\n# plt.xscale('log')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# lr = 1e-6","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# lr = 1e-4\n# for param in optimizer.param_groups:param['lr'] = lr","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tr_losses = [[] for i in range(num_tasks + 1)]\nva_losses = [[] for i in range(num_tasks + 1)]\nva_scores = []\nmtl_weights = []","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tr_losses = torch.load('/kaggle/input/bangla-handwritten-grapheme/tr_losses')\nva_losses = torch.load('/kaggle/input/bangla-handwritten-grapheme/va_losses')\nva_scores = torch.load('/kaggle/input/bangla-handwritten-grapheme/va_scores')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"num_epochs = 5\nsteps_per_epoch = len(tr_dl) // gradient_accumulation_step\nsteps_per_epoch","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lr = 1e-3\nscheduler = OneCycleLR(optimizer, lr, epochs=num_epochs, steps_per_epoch=steps_per_epoch)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"epochs = range(num_epochs)\n# epochs = notebook.tqdm(range(num_epochs))\nfor epoch in epochs:\n    model.train()\n    count = 0\n    batches = tr_dl\n#     batches = notebook.tqdm(tr_dl)\n    batch_num = 0\n    for batch in batches:\n        weight_update = (batch_num % gradient_accumulation_step) == (gradient_accumulation_step - 1)\n        losses = train_multi_task_batch(model, optimizer, criterions, mtl_criterion, device, batch, weight_update, with_mixup=True)\n#         batches.set_description((\"{:0.4f} \" * (num_tasks + 1)).format(*losses))\n        if weight_update:\n            scheduler.step()\n        losses = (gradient_accumulation_step * losses[0],) + losses[1:]\n        for tr_loss, loss in zip(tr_losses, losses):\n            tr_loss.append(loss)\n        mtl_weights.append(mtl_criterion.w.tolist())\n        batch_num += 1\n\n    print(tuple(map(mean, [l[-steps_per_epoch:] for l in tr_losses])))\n    \n    model.eval()\n    va_batch_losses = [[] for i in range(num_tasks + 1)]\n    va_preds = [[] for i in range(num_tasks)]\n    va_trues = [[] for i in range(num_tasks)]\n    \n    batches = va_dl\n#     batches = notebook.tqdm(va_dl)\n    for batch in batches:\n        losses, preds, trues = validate_multi_task_batch(model, criterions, mtl_criterion, device, batch)\n        losses = (gradient_accumulation_step * losses[0],) + losses[1:]\n        for va_loss, loss in zip(va_batch_losses, losses):\n            va_loss.append(loss)\n        for va_pred, pred in zip(va_preds, preds):\n            va_pred.extend(pred)\n        for va_true, true in zip(va_trues, trues):\n            va_true.extend(true)\n        \n    avg_loss = tuple(map(mean, va_batch_losses))\n    for va_loss, loss in zip(va_losses, avg_loss):\n        va_loss.append(loss)\n    recalls = tuple(map(lambda true, pred: recall_score(true, pred, average='macro'), va_preds, va_trues))\n    g_rec, v_rec, c_rec, *rest = recalls\n    score = 0.5 * g_rec + 0.25 * v_rec + 0.25 * c_rec\n    va_scores.append((score,) + recalls)\n    print([loss[-1] for loss in va_losses])\n    print(va_scores[-1])\n    for i in range(1, num_tasks):\n        print(confusion_matrix(va_trues[i], va_preds[i]))\n    plt.figure(figsize = (20, 20))\n    sn.heatmap(np.log1p(confusion_matrix(va_trues[0], va_preds[0])))\n    plt.show()\n    plt.figure(figsize = (20, 20))\n    sn.heatmap(np.log1p(confusion_matrix(va_trues[-2], va_preds[-2])))\n    plt.show()\n    plt.figure(figsize = (20, 20))\n    sn.heatmap(np.log1p(confusion_matrix(va_trues[-1], va_preds[-1])))\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!nvidia-smi","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for losses in tr_losses:\n    plt.plot(losses)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for losses in va_losses:\n    plt.plot(losses[:])\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(va_scores[:])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.save(tr_losses, 'tr_losses')\ntorch.save(va_losses, 'va_losses')\ntorch.save(va_scores, 'va_scores')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model.eval()\n# va_batch_losses = [[] for i in range(num_tasks + 1)]\n# va_preds = [[] for i in range(num_tasks)]\n# va_trues = [[] for i in range(num_tasks)]\n\n# batches = va_dl\n# batches = notebook.tqdm(va_dl)\n# for batch in batches:\n#     losses, preds, trues = validate_multi_task_batch(model, criterions, mtl_criterion, device, batch)\n#     for va_loss, loss in zip(va_batch_losses, losses):\n#         va_loss.append(loss)\n#     for va_pred, pred in zip(va_preds, preds):\n#         va_pred.extend(pred)\n#     for va_true, true in zip(va_trues, trues):\n#         va_true.extend(true)\n        \n# recalls = tuple(map(lambda true, pred: recall_score(true, pred, average='macro'), va_preds, va_trues))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"recalls","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"detailed_recalls = tuple(map(lambda true, pred: recall_score(true, pred, average=None), va_preds, va_trues))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"idx = 0\nplt.hist(detailed_recalls[idx])\nlist(enumerate(detailed_recalls[idx])), min(detailed_recalls[idx])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"idx = 1\nplt.hist(detailed_recalls[idx])\nlist(enumerate(detailed_recalls[idx])), min(detailed_recalls[idx])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"idx = 2\nplt.hist(detailed_recalls[idx])\nlist(enumerate(detailed_recalls[idx])), min(detailed_recalls[idx])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# idx = 3\n# plt.hist(detailed_recalls[idx])\n# list(enumerate(detailed_recalls[idx])), min(detailed_recalls[idx])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# idx = 4\n# plt.hist(detailed_recalls[idx])\n# list(enumerate(detailed_recalls[idx])), min(detailed_recalls[idx])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# idx = 5\n# plt.hist(detailed_recalls[idx])\n# list(enumerate(detailed_recalls[idx])), min(detailed_recalls[idx])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# idx = 6\n# plt.hist(detailed_recalls[idx])\n# list(enumerate(detailed_recalls[idx])), min(detailed_recalls[idx])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# idx = 7\n# plt.hist(detailed_recalls[idx])\n# list(enumerate(detailed_recalls[idx])), min(detailed_recalls[idx])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# idx = 8\n# plt.hist(detailed_recalls[idx])\n# list(enumerate(detailed_recalls[idx])), min(detailed_recalls[idx])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!nvidia-smi ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_preds_losses(model, num_taks, device, dl):\n    model.eval()\n    criterions = [nn.CrossEntropyLoss(reduction='none') for i in range(num_tasks)]\n    mtl_criterion = MultiTaskSumLoss(num_tasks, collapse=False).to(device)\n    losses = [[] for i in range(num_tasks + 1)]\n    preds = [[] for i in range(num_tasks)]\n    trues = [[] for i in range(num_tasks)]\n    for batch in notebook.tqdm(dl):\n        batch_losses, batch_preds, batch_trues = validate_multi_task_batch(model, criterions, mtl_criterion, device, batch, collapse=False)\n        for loss, batch_loss in zip(losses, batch_losses):\n            loss.extend(batch_loss)\n        for pred, batch_pred in zip(preds, batch_preds):\n            pred.extend(batch_pred)\n        for true, batch_true in zip(trues, batch_trues):\n            true.extend(batch_true)\n    return losses, preds, trues","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# losses, preds, trues = get_preds_losses(model, num_tasks, device, DataLoader(DatasetWithImageTransforms(ds, va_tfms), batch_size=64, num_workers=0, pin_memory=True))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# loss_sorted_ids = sorted(list(range(len(losses[0]))), key=lambda i: losses[0][i], reverse=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_component(component_id, component_type):\n    return df_class[(df_class['label'] == component_id) & (df_class['component_type'] == component_type)]['component'].values[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_image_from_ds(ds, i, preds, losses):\n    print(i)\n    im, g, v, c, *rest_labels = ds[i]#map(lambda t: t.item(), va_ds[i])\n    g, v, c = g.item(), v.item(), c.item()\n    g_pred, v_pred, c_pred = preds[0][i], preds[1][i], preds[2][i]\n#     im = im.permute(1, 2, 0).reshape(137, 236)\n    im = im.flatten(end_dim=1)\n    plt.imshow(im, cmap='gray', vmin=0., vmax=1.)\n    plt.show()\n    print(g, get_component(g, 'grapheme_root'))\n    print(v, get_component(v, 'vowel_diacritic'))\n    print(c, get_component(c, 'consonant_diacritic'))\n    print(g_pred, get_component(g_pred, 'grapheme_root'))\n    print(v_pred, get_component(v_pred, 'vowel_diacritic'))\n    print(c_pred, get_component(c_pred, 'consonant_diacritic'))\n    print([l[i] for l in losses])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# ds = DatasetWithImageTransforms(ds, va_tfms)\n# count = 0\n# for i in loss_sorted_ids:\n#     print(count, i in va_indices)\n#     plot_image_from_ds(ds, i, preds, losses)\n#     count += 1\n#     if count == 2000 or losses[0][i] < 0.9:\n#         break","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plt.plot([losses[0][i] for i in loss_sorted_ids[:]])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# mean([losses[0][i] for i in loss_sorted_ids[:]])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# mean([losses[0][i] for i in loss_sorted_ids[2000:]])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# func(va_ds, loss_sorted_ids[50], preds, losses)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plt.plot(mtl_weights)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.save(model.state_dict(), 'model.pth')\ntorch.save(optimizer.state_dict(), 'optim.pth')","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}