{"cells":[{"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","trusted":true},"cell_type":"code","source":"from tqdm.auto import tqdm\nfrom glob import glob\nimport time, gc\nimport cv2\nimport albumentations as A\n\nfrom tensorflow import keras\nimport matplotlib.image as mpimg\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Model\nfrom keras.models import clone_model\nfrom keras.layers import Dense,Conv2D,Flatten,MaxPool2D,Dropout,BatchNormalization, Input\nfrom keras.optimizers import Adam\nfrom keras.callbacks import ReduceLROnPlateau\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import confusion_matrix\nimport PIL.Image as Image, PIL.ImageDraw as ImageDraw, PIL.ImageFont as ImageFont\nfrom matplotlib import pyplot as plt\nimport seaborn as sns\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport numpy as np\n\ndef weights_init(m):\n    \"\"\"\n    Initialise weights of the model.\n    \"\"\"\n    if(type(m) == nn.ConvTranspose2d or type(m) == nn.Conv2d):\n        nn.init.normal_(m.weight.data, 0.0, 0.02)\n    elif(type(m) == nn.BatchNorm2d):\n        nn.init.normal_(m.weight.data, 1.0, 0.02)\n        nn.init.constant_(m.bias.data, 0)\n\nclass NormalNLLLoss:\n    \"\"\"\n    Calculate the negative log likelihood\n    of normal distribution.\n    This needs to be minimised.\n\n    Treating Q(cj | x) as a factored Gaussian.\n    \"\"\"\n    def __call__(self, x, mu, var):\n        \n        logli = -0.5 * (var.mul(2 * np.pi) + 1e-6).log() - (x - mu).pow(2).div(var.mul(2.0) + 1e-6)\n        nll = -(logli.sum(1).mean())\n\n        return nll\n\ndef noise_sample(n_dis_c, dis_c_dim, n_con_c, n_z, batch_size, device):\n    \"\"\"\n    Sample random noise vector for training.\n\n    INPUT\n    --------\n    n_dis_c : Number of discrete latent code.\n    dis_c_dim : Dimension of discrete latent code.\n    n_con_c : Number of continuous latent code.\n    n_z : Dimension of iicompressible noise.\n    batch_size : Batch Size\n    device : GPU/CPU\n    \"\"\"\n\n    z = torch.randn(batch_size, n_z, 1, 1, device=device)\n\n    idx = np.zeros((n_dis_c, batch_size))\n    if(n_dis_c != 0):\n        dis_c = torch.zeros(batch_size, n_dis_c, dis_c_dim, device=device)\n        \n        for i in range(n_dis_c):\n            idx[i] = np.random.randint(dis_c_dim, size=batch_size)\n            dis_c[torch.arange(0, batch_size), i, idx[i]] = 1.0\n\n        dis_c = dis_c.view(batch_size, -1, 1, 1)\n\n    if(n_con_c != 0):\n        # Random uniform between -1 and 1.\n        con_c = torch.rand(batch_size, n_con_c, 1, 1, device=device) * 2 - 1\n\n    noise = z\n    if(n_dis_c != 0):\n        noise = torch.cat((z, dis_c), dim=1)\n    if(n_con_c != 0):\n        noise = torch.cat((noise, con_c), dim=1)\n\n    return noise, idx","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Dictionary storing network parameters.\nparams = {\n    'batch_size': 128,# Batch size.\n    'num_epochs': 100,# Number of epochs to train for.\n    'learning_rate': 2e-4,# Learning rate.\n    'beta1': 0.5,\n    'beta2': 0.999,\n    'save_epoch' : 50,# After how many epochs to save checkpoints and generate test output.\n    'dataset' : 'MNIST'}# Dataset to use. Choose from {MNIST, SVHN, CelebA, FashionMNIST}. CASE MUST MATCH EXACTLY!!!!!","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Data Import"},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch\nimport torchvision.transforms as transforms\nimport torchvision.datasets as dsets\nimport pandas as pd\n# Directory containing the data.\nimport torch\nimport torchvision.transforms as transforms\nimport torchvision.datasets as dsets\n\nimport matplotlib.pyplot as plt\n\nimport numpy as np\nimport pandas as pd\nimport cv2\nfrom pathlib import Path\nimport PIL.Image as Image, PIL.ImageDraw as ImageDraw, PIL.ImageFont as ImageFont\nfrom tqdm.auto import tqdm","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"datadir = Path('/kaggle/input/bengaliai-cv19')\ntrain_df_ = pd.read_csv(datadir/'train.csv')\ntest_df_ = pd.read_csv(datadir/'test.csv')\nsample_sub_df = pd.read_csv(datadir/'sample_submission.csv')\nclass_map_df = pd.read_csv(datadir/'class_map.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df_.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df_.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_sub_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class_map_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(f'Size of training data: {train_df_.shape}')\nprint(f'Size of test data: {test_df_.shape}')\nprint(f'Size of class map: {class_map_df.shape}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"HEIGHT = 236\nWIDTH = 236","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_n(df, field, n, top=True):\n    top_graphemes = df.groupby([field]).size().reset_index(name='counts')['counts'].sort_values(ascending=not top)[:n]\n    top_grapheme_roots = top_graphemes.index\n    top_grapheme_counts = top_graphemes.values\n    top_graphemes = class_map_df[class_map_df['component_type'] == field].reset_index().iloc[top_grapheme_roots]\n    top_graphemes.drop(['component_type', 'label'], axis=1, inplace=True)\n    top_graphemes.loc[:, 'count'] = top_grapheme_counts\n    return top_graphemes\n\ndef image_from_char(char):\n    image = Image.new('RGB', (WIDTH, HEIGHT))\n    draw = ImageDraw.Draw(image)\n    myfont = ImageFont.truetype('/kaggle/input/banglafonts/SolaimanLipi.ttf', 120)\n    w, h = draw.textsize(char, font=myfont)\n    draw.text(((WIDTH - w) / 2,(HEIGHT - h) / 3), char, font=myfont)\n\n    return image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(f'Number of unique grapheme roots: {train_df_[\"grapheme_root\"].nunique()}')\nprint(f'Number of unique vowel diacritic: {train_df_[\"vowel_diacritic\"].nunique()}')\nprint(f'Number of unique consonant diacritic: {train_df_[\"consonant_diacritic\"].nunique()}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Most used top 10 Grapheme Roots in training set\ntop_10_roots = get_n(train_df_, 'grapheme_root', 10)\ntop_10_roots","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"f, ax = plt.subplots(2, 5, figsize=(16, 8))\nax = ax.flatten()\n\nfor i in range(10):\n    ax[i].imshow(image_from_char(top_10_roots['component'].iloc[i]), cmap='Greys')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Least used 10 Grapheme Roots in training set    \nbottom_10_roots = get_n(train_df_, 'grapheme_root', 10, False)\nbottom_10_roots","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"f, ax = plt.subplots(2, 5, figsize=(16, 8))\nax = ax.flatten()\n\nfor i in range(10):\n    ax[i].imshow(image_from_char(bottom_10_roots['component'].iloc[i]), cmap='Greys')    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Top 5 Vowel Diacritic in taining data\ntop_5_vowels = get_n(train_df_, 'vowel_diacritic', 5)\ntop_5_vowels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"f, ax = plt.subplots(1, 5, figsize=(16, 8))\nax = ax.flatten()\n\nfor i in range(5):\n    ax[i].imshow(image_from_char(top_5_vowels['component'].iloc[i]), cmap='Greys')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Top 5 Consonant Diacritic in training data\ntop_5_consonants = get_n(train_df_, 'consonant_diacritic', 5)\ntop_5_consonants","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"f, ax = plt.subplots(1, 5, figsize=(16, 8))\nax = ax.flatten()\n\nfor i in range(5):\n    ax[i].imshow(image_from_char(top_5_consonants['component'].iloc[i]), cmap='Greys')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df_ = train_df_.drop(['grapheme'], axis=1, inplace=False)\n    \ntrain_df_[['grapheme_root', 'vowel_diacritic', 'consonant_diacritic']] = train_df_[['grapheme_root', 'vowel_diacritic', 'consonant_diacritic']].astype('uint8')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"IMG_SIZE=28\nN_CHANNELS=1\n\nHEIGHT = 137\nWIDTH = 236\nSIZE = 28\nCROP_SIZE = 28","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def resize(df, size=28, need_progress_bar=True):\n    resized = {}\n    resize_size=28\n    if need_progress_bar:\n        for i in tqdm(range(df.shape[0])):\n            image=df.loc[df.index[i]].values.reshape(137,236)\n            _, thresh = cv2.threshold(image, 30, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)\n            contours, _ = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)[-2:]\n\n            idx = 0 \n            ls_xmin = []\n            ls_ymin = []\n            ls_xmax = []\n            ls_ymax = []\n            for cnt in contours:\n                idx += 1\n                x,y,w,h = cv2.boundingRect(cnt)\n                ls_xmin.append(x)\n                ls_ymin.append(y)\n                ls_xmax.append(x + w)\n                ls_ymax.append(y + h)\n            xmin = min(ls_xmin)\n            ymin = min(ls_ymin)\n            xmax = max(ls_xmax)\n            ymax = max(ls_ymax)\n\n            roi = image[ymin:ymax,xmin:xmax]\n            resized_roi = cv2.resize(roi, (resize_size, resize_size),interpolation=cv2.INTER_AREA)\n            resized[df.index[i]] = resized_roi.reshape(-1)\n    else:\n        for i in range(df.shape[0]):\n            #image = cv2.resize(df.loc[df.index[i]].values.reshape(137,236),(size,size),None,fx=0.5,fy=0.5,interpolation=cv2.INTER_AREA)\n            image=df.loc[df.index[i]].values.reshape(137,236)\n            _, thresh = cv2.threshold(image, 30, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)\n            contours, _ = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)[-2:]\n\n            idx = 0 \n            ls_xmin = []\n            ls_ymin = []\n            ls_xmax = []\n            ls_ymax = []\n            for cnt in contours:\n                idx += 1\n                x,y,w,h = cv2.boundingRect(cnt)\n                ls_xmin.append(x)\n                ls_ymin.append(y)\n                ls_xmax.append(x + w)\n                ls_ymax.append(y + h)\n            xmin = min(ls_xmin)\n            ymin = min(ls_ymin)\n            xmax = max(ls_xmax)\n            ymax = max(ls_ymax)\n\n            roi = image[ymin:ymax,xmin:xmax]\n            resized_roi = cv2.resize(roi, (resize_size, resize_size),interpolation=cv2.INTER_AREA)\n            resized[df.index[i]] = resized_roi.reshape(-1)\n    resized = pd.DataFrame(resized).T\n    return resized","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_dummies(df):\n    cols = []\n    for col in df:\n        cols.append(pd.get_dummies(df[col].astype(str)))\n    return pd.concat(cols, axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class MultiOutputDataGenerator(keras.preprocessing.image.ImageDataGenerator):\n\n    def flow(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        targets = None\n        target_lengths = {}\n        ordered_outputs = []\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            target_lengths[output] = target.shape[1]\n            ordered_outputs.append(output)\n\n\n        for flowx, flowy in super().flow(x, targets, batch_size=batch_size,\n                                         shuffle=shuffle):\n            target_dict = {}\n            i = 0\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","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(4):\n    train_df = pd.merge(pd.read_parquet(f'/kaggle/input/bengaliai-cv19/train_image_data_{i}.parquet'), train_df_, on='image_id').drop(['image_id'], axis=1)\n    # Visualize few samples of current training dataset\n    fig, ax = plt.subplots(nrows=3, ncols=4, figsize=(16, 8))\n    count=0\n    for row in ax:\n        for col in row:\n            col.imshow(resize(train_df.drop(['grapheme_root', 'vowel_diacritic', 'consonant_diacritic'], axis=1).iloc[[count]], need_progress_bar=False).values.reshape(IMG_SIZE, IMG_SIZE))\n            count += 1\n    plt.show()\n    \n    X_train = train_df.drop(['grapheme_root', 'vowel_diacritic', 'consonant_diacritic'], axis=1)\n    X_train = resize(X_train)/255\n    \n       # CNN takes images in shape `(batch_size, h, w, channels)`, so reshape the images\n    X_train = X_train.values.reshape(-1, N_CHANNELS, IMG_SIZE, IMG_SIZE)   #(-1, IMG_SIZE, IMG_SIZE, N_CHANNELS)\n    #X_train = np.expand_dims(X_train, axis=1)\n    Y_train_root = pd.get_dummies(train_df['grapheme_root']).values\n    Y_train_vowel = pd.get_dummies(train_df['vowel_diacritic']).values\n    Y_train_consonant = pd.get_dummies(train_df['consonant_diacritic']).values\n\n    print(f'Training images: {X_train.shape}')\n    print(f'Training labels root: {Y_train_root.shape}')\n    print(f'Training labels vowel: {Y_train_vowel.shape}')\n    print(f'Training labels consonants: {Y_train_consonant.shape}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_data(dataset, batch_size):\n\n    # Get MNIST dataset.\n    if dataset == 'MNIST':\n        dataset = X_train\n\n    # Create dataloader.\n    dataloader = torch.utils.data.DataLoader(dataset, \n                                            batch_size=batch_size, \n                                            shuffle=True)\n\n    return dataloader","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Model Declaration"},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\n\"\"\"\nArchitecture based on InfoGAN paper.\n\"\"\"\n\nclass Generator(nn.Module):\n    def __init__(self):\n        super().__init__()\n\n        self.tconv1 = nn.ConvTranspose2d(74, 1024, 1, 1, bias=False)\n        self.bn1 = nn.BatchNorm2d(1024)\n\n        self.tconv2 = nn.ConvTranspose2d(1024, 128, 7, 1, bias=False)\n        self.bn2 = nn.BatchNorm2d(128)\n\n        self.tconv3 = nn.ConvTranspose2d(128, 64, 4, 2, padding=1, bias=False)\n        self.bn3 = nn.BatchNorm2d(64)\n\n        self.tconv4 = nn.ConvTranspose2d(64, 1, 4, 2, padding=1, bias=False)\n\n    def forward(self, x):\n        x = F.relu(self.bn1(self.tconv1(x)))\n        x = F.relu(self.bn2(self.tconv2(x)))\n        x = F.relu(self.bn3(self.tconv3(x)))\n\n        img = torch.sigmoid(self.tconv4(x))\n\n        return img\n\nclass Discriminator(nn.Module):\n    def __init__(self):\n        super().__init__()\n\n        self.conv1 = nn.Conv2d(1, 64, 4, 2, 1)\n\n        self.conv2 = nn.Conv2d(64, 128, 4, 2, 1, bias=False)\n        self.bn2 = nn.BatchNorm2d(128)\n\n        self.conv3 = nn.Conv2d(128, 1024, 7, bias=False)\n        self.bn3 = nn.BatchNorm2d(1024)\n\n    def forward(self, x):\n        x = F.leaky_relu(self.conv1(x), 0.1, inplace=True)\n        x = F.leaky_relu(self.bn2(self.conv2(x)), 0.1, inplace=True)\n        x = F.leaky_relu(self.bn3(self.conv3(x)), 0.1, inplace=True)\n\n        return x\n\nclass DHead(nn.Module):\n    def __init__(self):\n        super().__init__()\n\n        self.conv = nn.Conv2d(1024, 1, 1)\n\n    def forward(self, x):\n        output = torch.sigmoid(self.conv(x))\n\n        return output\n\nclass QHead(nn.Module):\n    def __init__(self):\n        super().__init__()\n\n        self.conv1 = nn.Conv2d(1024, 128, 1, bias=False)\n        self.bn1 = nn.BatchNorm2d(128)\n\n        self.conv_disc = nn.Conv2d(128, 10, 1)\n        self.conv_mu = nn.Conv2d(128, 2, 1)\n        self.conv_var = nn.Conv2d(128, 2, 1)\n\n    def forward(self, x):\n        x = F.leaky_relu(self.bn1(self.conv1(x)), 0.1, inplace=True)\n\n        disc_logits = self.conv_disc(x).squeeze()\n\n        mu = self.conv_mu(x).squeeze()\n        var = torch.exp(self.conv_var(x).squeeze())\n\n        return disc_logits, mu, var","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torchvision.utils as vutils\nimport torchvision.transforms as transforms\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport matplotlib.animation as animation\nimport time\nimport random\n\n# Set random seed for reproducibility.\nseed = 1123\nrandom.seed(seed)\ntorch.manual_seed(seed)\nprint(\"Random Seed: \", seed)\n\n# Use GPU if available.\ndevice = torch.device(\"cuda:0\" if(torch.cuda.is_available()) else \"cpu\")\nprint(device, \" will be used.\\n\")\n\n#dataloader = get_data(params['dataset'], params['batch_size'])\ndataloader = get_data(params['dataset'], params['batch_size'])\n\n# Set appropriate hyperparameters depending on the dataset used.\n# The values given in the InfoGAN paper are used.\n# num_z : dimension of incompressible noise.\n# num_dis_c : number of discrete latent code used.\n# dis_c_dim : dimension of discrete latent code.\n# num_con_c : number of continuous latent code used.\nif(params['dataset'] == 'MNIST'):\n    params['num_z'] = 62\n    params['num_dis_c'] = 1\n    params['dis_c_dim'] = 10\n    params['num_con_c'] = 2\n\n# Plot the training images.\nsample_batch = next(iter(dataloader))\nplt.figure(figsize=(10, 10))\nplt.axis(\"off\")\nplt.imshow(np.transpose(np.squeeze(vutils.make_grid(\n        sample_batch[0].to(device)[ : 100], nrow=10, padding=2, normalize=True).cpu(), axis=2)))   ###############\nplt.savefig('Training Images {}'.format(params['dataset']))\nplt.close('all')\n\n# Initialise the network.\nnetG = Generator().to(device)\nnetG.apply(weights_init)\nprint(netG)\n\ndiscriminator = Discriminator().to(device)\ndiscriminator.apply(weights_init)\nprint(discriminator)\n\nnetD = DHead().to(device)\nnetD.apply(weights_init)\nprint(netD)\n\nnetQ = QHead().to(device)\nnetQ.apply(weights_init)\nprint(netQ)\n\n# Loss for discrimination between real and fake images.\ncriterionD = nn.BCELoss()\n# Loss for discrete latent code.\ncriterionQ_dis = nn.CrossEntropyLoss()\n# Loss for continuous latent code.\ncriterionQ_con = NormalNLLLoss()\n\n# Adam optimiser is used.\noptimD = optim.Adam([{'params': discriminator.parameters()}, {'params': netD.parameters()}], lr=params['learning_rate'], betas=(params['beta1'], params['beta2']))\noptimG = optim.Adam([{'params': netG.parameters()}, {'params': netQ.parameters()}], lr=params['learning_rate'], betas=(params['beta1'], params['beta2']))\n\n# Fixed Noise\nz = torch.randn(100, params['num_z'], 1, 1, device=device)\nfixed_noise = z\nif(params['num_dis_c'] != 0):\n    idx = np.arange(params['dis_c_dim']).repeat(10)\n    dis_c = torch.zeros(100, params['num_dis_c'], params['dis_c_dim'], device=device)\n    for i in range(params['num_dis_c']):\n        dis_c[torch.arange(0, 100), i, idx] = 1.0\n\n    dis_c = dis_c.view(100, -1, 1, 1)\n\n    fixed_noise = torch.cat((fixed_noise, dis_c), dim=1)\n\nif(params['num_con_c'] != 0):\n    con_c = torch.rand(100, params['num_con_c'], 1, 1, device=device) * 2 - 1\n    fixed_noise = torch.cat((fixed_noise, con_c), dim=1)\n\nreal_label = 1\nfake_label = 0\n\n# List variables to store results pf training.\nimg_list = []\nG_losses = []\nD_losses = []\n\nprint(\"-\"*25)\nprint(\"Starting Training Loop...\\n\")\nprint('Epochs: %d\\nDataset: {}\\nBatch Size: %d\\nLength of Data Loader: %d'.format(params['dataset']) % (params['num_epochs'], params['batch_size'], len(dataloader)))\nprint(\"-\"*25)\n\nstart_time = time.time()\niters = 0\n\nfor epoch in range(params['num_epochs']):\n    epoch_start_time = time.time()\n    \n    for i, (data) in enumerate(dataloader):          # for i, (data, _) in enumerate(dataloader,0):\n        # Get batch size\n        b_size = data.size(0)\n        # Transfer data tensor to GPU/CPU (device)\n        #data = data.transforms.ToTensor().to(device)\n        #real_data = data.to(device)\n        real_data = data.float().cuda()                  #to(device)\n\n        # Updating discriminator and DHead\n        optimD.zero_grad()\n        # Real data\n        label = torch.full((b_size, ), real_label, device=device)\n        output1 = discriminator(real_data)\n        probs_real = netD(output1).view(-1)\n        loss_real = criterionD(probs_real, label)\n        # Calculate gradients.\n        loss_real.backward()\n\n        # Fake data\n        label.fill_(fake_label)\n        noise, idx = noise_sample(params['num_dis_c'], params['dis_c_dim'], params['num_con_c'], params['num_z'], b_size, device)\n        fake_data = netG(noise)\n        output2 = discriminator(fake_data.detach())\n        probs_fake = netD(output2).view(-1)\n        loss_fake = criterionD(probs_fake, label)\n        # Calculate gradients.\n        loss_fake.backward()\n\n        # Net Loss for the discriminator\n        D_loss = loss_real + loss_fake\n        # Update parameters\n        optimD.step()\n\n        # Updating Generator and QHead\n        optimG.zero_grad()\n\n        # Fake data treated as real.\n        output = discriminator(fake_data)\n        label.fill_(real_label)\n        probs_fake = netD(output).view(-1)\n        gen_loss = criterionD(probs_fake, label)\n\n        q_logits, q_mu, q_var = netQ(output)\n        target = torch.LongTensor(idx).to(device)\n        # Calculating loss for discrete latent code.\n        dis_loss = 0\n        for j in range(params['num_dis_c']):\n            dis_loss += criterionQ_dis(q_logits[:, j*10 : j*10 + 10], target[j])\n\n        # Calculating loss for continuous latent code.\n        con_loss = 0\n        if (params['num_con_c'] != 0):\n            con_loss = criterionQ_con(noise[:, params['num_z']+ params['num_dis_c']*params['dis_c_dim'] : ].view(-1, params['num_con_c']), q_mu, q_var)*0.1\n\n        # Net loss for generator.\n        G_loss = gen_loss + dis_loss + con_loss\n        # Calculate gradients.\n        G_loss.backward()\n        # Update parameters.\n        optimG.step()\n\n        # Check progress of training.\n        if i != 0 and i%100 == 0:\n            print('[%d/%d][%d/%d]\\tLoss_D: %.4f\\tLoss_G: %.4f'\n                  % (epoch+1, params['num_epochs'], i, len(dataloader), \n                    D_loss.item(), G_loss.item()))\n\n        # Save the losses for plotting.\n        G_losses.append(G_loss.item())\n        D_losses.append(D_loss.item())\n\n        iters += 1\n\n    epoch_time = time.time() - epoch_start_time\n    print(\"Time taken for Epoch %d: %.2fs\" %(epoch + 1, epoch_time))\n    # Generate image after each epoch to check performance of the generator. Used for creating animated gif later.\n    with torch.no_grad():\n        gen_data = netG(fixed_noise).detach().cpu()\n    img_list.append(vutils.make_grid(gen_data, nrow=10, padding=2, normalize=True))\n\n    # Generate image to check performance of generator.\n    if((epoch+1) == 1 or (epoch+1) == params['num_epochs']/2 or (epoch+1) % 50 == 0 or (epoch+1) % params['save_epoch'] == 0):\n        with torch.no_grad():\n            gen_data = netG(fixed_noise).detach().cpu()\n        plt.figure(figsize=(10, 10))\n        plt.axis(\"off\")\n        plt.imshow(np.transpose(np.squeeze(vutils.make_grid(gen_data, nrow=10, padding=2, normalize=True), axis=2)))\n        plt.savefig(\"Epoch_%d {}\".format(params['dataset']) %(epoch+1))\n        plt.close('all')\n\n    # Save network weights.\n    if (epoch+1) % params['save_epoch'] == 0:\n        torch.save({\n            'netG' : netG.state_dict(),\n            'discriminator' : discriminator.state_dict(),\n            'netD' : netD.state_dict(),\n            'netQ' : netQ.state_dict(),\n            'optimD' : optimD.state_dict(),\n            'optimG' : optimG.state_dict(),\n            'params' : params\n            }, '/kaggle/working/model_epoch_%d_{}'.format(params['dataset']) %(epoch+1))\n\ntraining_time = time.time() - start_time\nprint(\"-\"*50)\nprint('Training finished!\\nTotal Time for Training: %.2fm' %(training_time / 60))\nprint(\"-\"*50)\n\n# Generate image to check performance of trained generator.\nwith torch.no_grad():\n    gen_data = netG(fixed_noise).detach().cpu()\nplt.figure(figsize=(10, 10))\nplt.axis(\"off\")\nplt.imshow(np.transpose(np.squeeze(vutils.make_grid(gen_data, nrow=10, padding=2, normalize=True), axis=2)))\nplt.savefig(\"Epoch_%d_{}\".format(params['dataset']) %(params['num_epochs']))\n\n# Save network weights.\ntorch.save({\n    'netG' : netG.state_dict(),\n    'discriminator' : discriminator.state_dict(),\n    'netD' : netD.state_dict(),\n    'netQ' : netQ.state_dict(),\n    'optimD' : optimD.state_dict(),\n    'optimG' : optimG.state_dict(),\n    'params' : params\n    }, '/kaggle/working/model_final_{}.pth'.format(params['dataset']))\n\n\n# Plot the training losses.\nplt.figure(figsize=(10,5))\nplt.title(\"Generator and Discriminator Loss During Training\")\nplt.plot(G_losses,label=\"G\")\nplt.plot(D_losses,label=\"D\")\nplt.xlabel(\"iterations\")\nplt.ylabel(\"Loss\")\nplt.legend()\nplt.savefig(\"Loss Curve {}\".format(params['dataset']))\n\n# Animation showing the improvements of the generator.\nfig = plt.figure(figsize=(10,10))\nplt.axis(\"off\")\nims = [[plt.imshow(np.transpose(i), animated=True)] for i in img_list]\nanim = animation.ArtistAnimation(fig, ims, interval=1000, repeat_delay=1000, blit=True)\nanim.save('infoGAN_{}.gif'.format(params['dataset']), dpi=80, writer='imagemagick')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"MNIST_Generator"},{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow\nimport torch\nimport torchvision.utils as vutils\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# Load the checkpoint file\nstate_dict = torch.load('/kaggle/working/model_final_{}.pth'.format(params['dataset']))\n\n# Set the device to run on: GPU or CPU.\ndevice = torch.device(\"cuda:0\" if(torch.cuda.is_available()) else \"cpu\")\n# Get the 'params' dictionary from the loaded state_dict.\nparams = state_dict['params']\n\n# Create the generator network.\nnetG = Generator().to(device)\n# Load the trained generator weights.\nnetG.load_state_dict(state_dict['netG'])\nprint(netG)\n\nc = np.linspace(-2, 2, 10).reshape(1, -1)\nc = np.repeat(c, 10, 0).reshape(-1, 1)\nc = torch.from_numpy(c).float().to(device)\nc = c.view(-1, 1, 1, 1)\n\nzeros = torch.zeros(100, 1, 1, 1, device=device)\n\n# Continuous latent code.\nc2 = torch.cat((c, zeros), dim=1)\nc3 = torch.cat((zeros, c), dim=1)\n\nidx = np.arange(10).repeat(10)\ndis_c = torch.zeros(100, 10, 1, 1, device=device)\ndis_c[torch.arange(0, 100), idx] = 1.0\n# Discrete latent code.\nc1 = dis_c.view(100, -1, 1, 1)\n\nz = torch.randn(100, 62, 1, 1, device=device)\n\n# To see variation along c2 (Horizontally) and c1 (Vertically)\nnoise1 = torch.cat((z, c1, c2), dim=1)\n# To see variation along c3 (Horizontally) and c1 (Vertically)\nnoise2 = torch.cat((z, c1, c3), dim=1)\n\n# Generate image.\nwith torch.no_grad():\n    generated_img1 = netG(noise1).detach().cpu()\n# Display the generated image.\nfig = plt.figure(figsize=(10, 10))\nplt.axis(\"off\")\nplt.imshow(np.transpose(np.squeeze(vutils.make_grid(generated_img1, nrow=10, padding=2, normalize=True), axis=2)))\nplt.show()\n\n# Generate image.\nwith torch.no_grad():\n    generated_img2 = netG(noise2).detach().cpu()\n# Display the generated image.\nfig = plt.figure(figsize=(10, 10))\nplt.axis(\"off\")\nplt.imshow(np.transpose(np.squeeze(vutils.make_grid(generated_img2, nrow=10, padding=2, normalize=True), axis=2)))\nplt.show()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch\nimport torchvision.utils as vutils\nimport numpy as np\nimport matplotlib.pyplot as plt\n\ndef genimg(load_path):\n    # Load the checkpoint file\n    state_dict = torch.load(load_path)\n    \n    # Set the device to run on: GPU or CPU.\n    device = torch.device(\"cuda:0\" if(torch.cuda.is_available()) else \"cpu\")\n    # Get the 'params' dictionary from the loaded state_dict.\n    params = state_dict['params']\n    \n    # Create the generator network.\n    netG = Generator().to(device)\n    # Load the trained generator weights.\n    netG.load_state_dict(state_dict['netG'])\n    print(netG)\n\n    c = np.linspace(-2, 2, 10).reshape(1, -1)\n    c = np.repeat(c, 10, 0).reshape(-1, 1)\n    c = torch.from_numpy(c).float().to(device)\n    c = c.view(-1, 1, 1, 1)\n\n    zeros = torch.zeros(100, 1, 1, 1, device=device)\n\n    # Continuous latent code.\n    c2 = torch.cat((c, zeros), dim=1)\n    c3 = torch.cat((zeros, c), dim=1)\n\n    idx = np.arange(10).repeat(10)\n    dis_c = torch.zeros(100, 10, 1, 1, device=device)\n    dis_c[torch.arange(0, 100), idx] = 1.0\n    # Discrete latent code.\n    c1 = dis_c.view(100, -1, 1, 1)\n\n    z = torch.randn(100, 62, 1, 1, device=device)\n\n    # To see variation along c2 (Horizontally) and c1 (Vertically)\n    noise1 = torch.cat((z, c1, c2), dim=1)\n    # To see variation along c3 (Horizontally) and c1 (Vertically)\n    noise2 = torch.cat((z, c1, c3), dim=1)\n\n    # Generate image.\n    with torch.no_grad():\n        generated_img1 = netG(noise1).detach().cpu()\n    with torch.no_grad():\n        generated_img2 = netG(noise2).detach().cpu()\n    \n    datagen = MultiOutputDataGenerator(\n        featurewise_center=False,  # set input mean to 0 over the dataset\n        samplewise_center=False,  # set each sample mean to 0\n        featurewise_std_normalization=False,  # divide inputs by std of the dataset\n        samplewise_std_normalization=False,  # divide each input by its std\n        zca_whitening=False,  # apply ZCA whitening\n        rotation_range=8,  # randomly rotate images in the range (degrees, 0 to 180)\n        zoom_range = 0.15, # Randomly zoom image \n        width_shift_range=0.15,  # randomly shift images horizontally (fraction of total width)\n        height_shift_range=0.15,  # randomly shift images vertically (fraction of total height)\n        horizontal_flip=False,  # randomly flip images\n        vertical_flip=False)  # randomly flip images\n    \n    for i in range(4):\n        train_df = pd.merge(pd.read_parquet(f'/kaggle/input/bengaliai-cv19/train_image_data_{i}.parquet'), train_df_, on='image_id').drop(['image_id'], axis=1)\n    \n        X_train = train_df.drop(['grapheme_root', 'vowel_diacritic', 'consonant_diacritic'], axis=1)\n        X_train = resize(X_train)/255\n    \n        # CNN takes images in shape `(batch_size, h, w, channels)`, so reshape the images\n        X_train = X_train.values.reshape(-1, IMG_SIZE, IMG_SIZE, N_CHANNELS)\n    \n        Y_train_root = pd.get_dummies(train_df['grapheme_root']).values\n        Y_train_vowel = pd.get_dummies(train_df['vowel_diacritic']).values\n        Y_train_consonant = pd.get_dummies(train_df['consonant_diacritic']).values\n\n        print(f'Training images: {X_train.shape}')\n        print(f'Training labels root: {Y_train_root.shape}')\n        print(f'Training labels vowel: {Y_train_vowel.shape}')\n        print(f'Training labels consonants: {Y_train_consonant.shape}')\n\n        # Divide the data into training and validation set\n        x_train, x_test, y_train_root, y_test_root, y_train_vowel, y_test_vowel, y_train_consonant, y_test_consonant = train_test_split(X_train, Y_train_root, Y_train_vowel, Y_train_consonant, test_size=0.08, random_state=666)\n        del train_df\n        del X_train\n        del Y_train_root, Y_train_vowel, Y_train_consonant\n    \n    datagen_1 = datagen.flow(x_train, {'dense_3': y_train_root, 'dense_4': y_train_vowel, 'dense_5': y_train_consonant}, batch_size=256)\n    \n    generated_img1_1 = datagen.flow(generated_img1)\n    generated_img2_1 = datagen.flow(generated_img2)\n    \n    return generated_img1, generated_img2, datagen_1, generated_img1_1, generated_img2_1","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Training"},{"metadata":{"trusted":true},"cell_type":"code","source":"IMG_SIZE = 28\nN_CHANNELS = 1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"inputs = Input(shape = (IMG_SIZE, IMG_SIZE, 1))\n\nmodel = Conv2D(filters=32, kernel_size=(3, 3), padding='SAME', activation='relu', input_shape=(IMG_SIZE, IMG_SIZE, 1))(inputs)\nmodel = Conv2D(filters=32, kernel_size=(3, 3), padding='SAME', activation='relu')(model)\nmodel = Conv2D(filters=32, kernel_size=(3, 3), padding='SAME', activation='relu')(model)\nmodel = BatchNormalization(momentum=0.15)(model)\nmodel = MaxPool2D(pool_size=(2, 2))(model)\nmodel = Conv2D(filters=32, kernel_size=(5, 5), padding='SAME', activation='relu')(model)\nmodel = Dropout(rate=0.3)(model)\n\nmodel = Conv2D(filters=64, kernel_size=(3, 3), padding='SAME', activation='relu')(model)\nmodel = Conv2D(filters=64, kernel_size=(3, 3), padding='SAME', activation='relu')(model)\nmodel = Conv2D(filters=64, kernel_size=(3, 3), padding='SAME', activation='relu')(model)\nmodel = BatchNormalization(momentum=0.15)(model)\nmodel = MaxPool2D(pool_size=(2, 2))(model)\nmodel = Conv2D(filters=64, kernel_size=(5, 5), padding='SAME', activation='relu')(model)\nmodel = BatchNormalization(momentum=0.15)(model)\nmodel = Dropout(rate=0.3)(model)\n\nmodel = Conv2D(filters=128, kernel_size=(3, 3), padding='SAME', activation='relu')(model)\nmodel = Conv2D(filters=128, kernel_size=(3, 3), padding='SAME', activation='relu')(model)\nmodel = Conv2D(filters=128, kernel_size=(3, 3), padding='SAME', activation='relu')(model)\nmodel = BatchNormalization(momentum=0.15)(model)\nmodel = MaxPool2D(pool_size=(2, 2))(model)\nmodel = Conv2D(filters=128, kernel_size=(5, 5), padding='SAME', activation='relu')(model)\nmodel = BatchNormalization(momentum=0.15)(model)\nmodel = Dropout(rate=0.3)(model)\n\nmodel = Conv2D(filters=256, kernel_size=(3, 3), padding='SAME', activation='relu')(model)\nmodel = Conv2D(filters=256, kernel_size=(3, 3), padding='SAME', activation='relu')(model)\nmodel = Conv2D(filters=256, kernel_size=(3, 3), padding='SAME', activation='relu')(model)\nmodel = BatchNormalization(momentum=0.15)(model)\nmodel = MaxPool2D(pool_size=(2, 2))(model)\nmodel = Conv2D(filters=256, kernel_size=(5, 5), padding='SAME', activation='relu')(model)\nmodel = BatchNormalization(momentum=0.15)(model)\nmodel = Dropout(rate=0.3)(model)\n\nmodel = Flatten()(model)\nmodel = Dense(1024, activation = \"relu\")(model)\nmodel = Dropout(rate=0.3)(model)\ndense = Dense(512, activation = \"relu\")(model)\n\nhead_root = Dense(168, activation = 'softmax')(dense)\nhead_vowel = Dense(11, activation = 'softmax')(dense)\nhead_consonant = Dense(7, activation = 'softmax')(dense)\n\nmodel = Model(inputs=inputs, outputs=[head_root, head_vowel, head_consonant])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Set a learning rate annealer. Learning rate will be half after 3 epochs if accuracy is not increased\nlearning_rate_reduction_root = ReduceLROnPlateau(monitor='dense_3_accuracy', \n                                            patience=3, \n                                            verbose=1,\n                                            factor=0.5, \n                                            min_lr=0.00001)\nlearning_rate_reduction_vowel = ReduceLROnPlateau(monitor='dense_4_accuracy', \n                                            patience=3, \n                                            verbose=1,\n                                            factor=0.5, \n                                            min_lr=0.00001)\nlearning_rate_reduction_consonant = ReduceLROnPlateau(monitor='dense_5_accuracy', \n                                            patience=3, \n                                            verbose=1,\n                                            factor=0.5, \n                                            min_lr=0.00001)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 256\nepochs = 40","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"histories = []\nfor i in range(4):\n    train_df = pd.merge(pd.read_parquet(f'/kaggle/input/bengaliai-cv19/train_image_data_{i}.parquet'), train_df_, on='image_id').drop(['image_id'], axis=1)\n    # Visualize few samples of current training dataset\n    fig, ax = plt.subplots(nrows=3, ncols=4, figsize=(16, 8))\n    count=0\n    for row in ax:\n        for col in row:\n            col.imshow(resize(train_df.drop(['grapheme_root', 'vowel_diacritic', 'consonant_diacritic'], axis=1).iloc[[count]], need_progress_bar=False).values.reshape(IMG_SIZE, IMG_SIZE))\n            count += 1\n    plt.show()\n    \n    X_train = train_df.drop(['grapheme_root', 'vowel_diacritic', 'consonant_diacritic'], axis=1)\n    X_train = resize(X_train)/255\n    \n    # CNN takes images in shape `(batch_size, h, w, channels)`, so reshape the images\n    X_train = X_train.values.reshape(-1, IMG_SIZE, IMG_SIZE, N_CHANNELS)\n    \n    Y_train_root = pd.get_dummies(train_df['grapheme_root']).values\n    Y_train_vowel = pd.get_dummies(train_df['vowel_diacritic']).values\n    Y_train_consonant = pd.get_dummies(train_df['consonant_diacritic']).values\n\n    print(f'Training images: {X_train.shape}')\n    print(f'Training labels root: {Y_train_root.shape}')\n    print(f'Training labels vowel: {Y_train_vowel.shape}')\n    print(f'Training labels consonants: {Y_train_consonant.shape}')\n\n    # Divide the data into training and validation set\n    x_train, x_test, y_train_root, y_test_root, y_train_vowel, y_test_vowel, y_train_consonant, y_test_consonant = train_test_split(X_train, Y_train_root, Y_train_vowel, Y_train_consonant, test_size=0.08, random_state=666)\n    #x_train = x_train.values.reshape(-1, N_CHANNELS, IMG_SIZE, IMG_SIZE)\n    del train_df\n    del X_train\n    del Y_train_root, Y_train_vowel, Y_train_consonant\n\n    # Data augmentation for creating more training data\n    datagen = MultiOutputDataGenerator(genimg('/kaggle/working/model_final_{}.pth'.format(params['dataset'])))\n      \n    \"\"\"\n    # Rescale -1 to 1\n    x_train = (x_train.astype(np.float32) - 127.5) / 127.5\n    x_train = np.expand_dims(x_train, axis=1) ####\n    y_train_root = y_train_root.reshape(-1, 1)\n    y_train_vowel = y_train_vowel.reshape(-1, 1)\n    y_train_consonant = y_train_consonant.reshape(-1, 1)\n\n    \"\"\"\n\n\n    # This will just calculate parameters required to augment the given data. This won't perform any augmentations\n    datagen.fit(x_train)\n\n    # Fit the model\n    history = model.fit_generator(datagen.flow(x_train, {'dense_3': y_train_root, 'dense_4': y_train_vowel, 'dense_5': y_train_consonant}, batch_size=batch_size),\n                              epochs = epochs, validation_data = (x_test, [y_test_root, y_test_vowel, y_test_consonant]), \n                              steps_per_epoch=x_train.shape[0] // batch_size, \n                              callbacks=[learning_rate_reduction_root, learning_rate_reduction_vowel, learning_rate_reduction_consonant])\n\n    histories.append(history)\n    \n    # Delete to reduce memory usage\n    del x_train\n    del x_test\n    del y_train_root\n    del y_test_root\n    del y_train_vowel\n    del y_test_vowel\n    del y_train_consonant\n    del y_test_consonant\n    gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%matplotlib inline\ndef plot_loss(his, epoch, title):\n    plt.style.use('ggplot')\n    plt.figure()\n    plt.plot(np.arange(0, epoch), his.history['loss'], label='train_loss')\n    plt.plot(np.arange(0, epoch), his.history['dense_3_loss'], label='train_root_loss')\n    plt.plot(np.arange(0, epoch), his.history['dense_4_loss'], label='train_vowel_loss')\n    plt.plot(np.arange(0, epoch), his.history['dense_5_loss'], label='train_consonant_loss')\n    \n    plt.plot(np.arange(0, epoch), his.history['val_dense_3_loss'], label='val_train_root_loss')\n    plt.plot(np.arange(0, epoch), his.history['val_dense_4_loss'], label='val_train_vowel_loss')\n    plt.plot(np.arange(0, epoch), his.history['val_dense_5_loss'], label='val_train_consonant_loss')\n    \n    plt.title(title)\n    plt.xlabel('Epoch #')\n    plt.ylabel('Loss')\n    plt.legend(loc='upper right')\n    plt.show()\n\ndef plot_acc(his, epoch, title):\n    plt.style.use('ggplot')\n    plt.figure()\n    plt.plot(np.arange(0, epoch), his.history['dense_3_accuracy'], label='train_root_acc')\n    plt.plot(np.arange(0, epoch), his.history['dense_4_accuracy'], label='train_vowel_accuracy')\n    plt.plot(np.arange(0, epoch), his.history['dense_5_accuracy'], label='train_consonant_accuracy')\n    \n    plt.plot(np.arange(0, epoch), his.history['val_dense_3_accuracy'], label='val_root_acc')\n    plt.plot(np.arange(0, epoch), his.history['val_dense_4_accuracy'], label='val_vowel_accuracy')\n    plt.plot(np.arange(0, epoch), his.history['val_dense_5_accuracy'], label='val_consonant_accuracy')\n    plt.title(title)\n    plt.xlabel('Epoch #')\n    plt.ylabel('Accuracy')\n    plt.legend(loc='upper right')\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for dataset in range(4):\n    plot_loss(histories[dataset], epochs, f'Training Dataset: {dataset}')\n    plot_acc(histories[dataset], epochs, f'Training Dataset: {dataset}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del histories\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds_dict = {\n    'grapheme_root': [],\n    'vowel_diacritic': [],\n    'consonant_diacritic': []\n    }","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"components = ['consonant_diacritic', 'grapheme_root', 'vowel_diacritic']\ntarget=[] # model predictions placeholder\nrow_id=[] # row_id place holder\nfor i in range(4):\n    df_test_img = pd.read_parquet('/kaggle/input/bengaliai-cv19/test_image_data_{}.parquet'.format(i)) \n    df_test_img.set_index('image_id', inplace=True)\n\n    X_test = resize(df_test_img, need_progress_bar=False)/255\n    X_test = X_test.values.reshape(-1, IMG_SIZE, IMG_SIZE, N_CHANNELS)\n    \n    preds = model.predict(X_test)\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_test_img.index.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_test_img\n    del X_test\n    gc.collect()\n\ndf_sample = pd.DataFrame({'row_id': row_id, 'target':target}, columns = ['row_id','target'])\ndf_sample.to_csv('submission.csv',index=False)\ndf_sample.head()","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.7.4"}},"nbformat":4,"nbformat_minor":4}