{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"%load_ext autoreload\n%autoreload 2\n\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import pandas as pd\nimport torch\nimport matplotlib.pyplot as plt\nimport os\nimport random\nfrom torch.utils.data import Dataset, DataLoader\nimport torch.nn as nn\nfrom torchvision.transforms import transforms\nimport numpy as np\nimport torch.nn.functional as F\nimport torch.optim as optim\nfrom torchvision.models import resnext50_32x4d\nfrom torch.optim import lr_scheduler\nimport pyarrow.parquet as pq\nimport cv2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_path = '/kaggle/input/bengaliai-cv19/'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"HEIGHT = 137\nWIDTH = 236\nTARGET_SIZE = 64\nPADDING = 8","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def bbox(img):\n    rows = np.any(img, axis=1)\n    cols = np.any(img, axis=0)\n    rmin, rmax = np.where(rows)[0][[0, -1]]\n    cmin, cmax = np.where(cols)[0][[0, -1]]\n    return rmin, rmax, cmin, cmax\n\n\ndef crop_resize(img0, size=128, pad=8):\n    # crop a box around pixels large than the threshold\n    # some images contain line at the sides\n    ymin, ymax, xmin, xmax = bbox(img0[5:-5, 5:-5] > 80)\n\n    # cropping may cut too much, so we need to add it back\n    xmin = xmin - 13 if (xmin > 13) else 0\n    ymin = ymin - 10 if (ymin > 10) else 0\n    xmax = xmax + 13 if (xmax < WIDTH - 13) else WIDTH\n    ymax = ymax + 10 if (ymax < HEIGHT - 10) else HEIGHT\n    img = img0[ymin:ymax, xmin:xmax]\n\n    # remove lo intensity pixels as noise\n    img[img < 28] = 0\n    lx, ly = xmax - xmin, ymax - ymin\n    ls = max(lx, ly) + pad\n\n    # make sure that the aspect ratio is kept in rescaling\n    img = np.pad(img, [((ls - ly) // 2,), ((ls - lx) // 2,)], mode='constant')\n\n    return cv2.resize(img, (size, size))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class ToImage:\n    def __init__(self, df):\n        self.df = df\n        \n    def __call__(self,image_id):\n#         image_data = np.array(self.df.iloc[image_id][:].values, dtype=np.uint8)\n        image_data = self.df.iloc[image_id, :].values.reshape(HEIGHT, WIDTH).astype(np.uint8)\n        image_data = 255-image_data\n        image_data = (image_data*(255.0/image_data.max())).astype(np.uint8)\n        return torch.from_numpy(crop_resize(image_data, size=TARGET_SIZE, pad=PADDING)).float()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class BengaliDataset(Dataset):\n    def __init__(self, df, data, transform=None):\n        self.transform = transform\n        self.df = df\n        self.to_image = ToImage(data)\n        \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, idx):\n        if torch.is_tensor(idx):\n            idx = idx.tolist()\n        image = self.to_image(idx)\n        output = torch.tensor([])\n        \n        if self.transform:\n            image = self.transform(image)\n\n        sample = {'image': image.unsqueeze(0), 'output': output, 'df_idx' : self.df[idx]}\n\n        return sample","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class ModifiedResnext(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.arch = resnext50_32x4d()\n        f_features = self.arch.fc.in_features\n        \n        self.head_dropout = 0.1\n        \n        old_conv1 = self.arch.conv1\n        self.arch.conv1 = nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3, bias=False)\n        with torch.no_grad():\n            self.arch.conv1.weight = nn.Parameter(old_conv1.weight.data[:, 0, :, :].unsqueeze(1))        \n        \n        self.last = nn.Sequential(\n            nn.BatchNorm2d(f_features),\n            nn.ReLU()\n        )\n        \n        self.fc_graph = nn.Linear(f_features, 168)\n        self.fc_vowel = nn.Linear(f_features, 11)\n        self.fc_conso = nn.Linear(f_features, 7)   \n        \n    def forward_init_layers(self, x):\n        x = self.arch.conv1(x)\n        x = self.arch.bn1(x)\n        x = self.arch.relu(x)\n        x = self.arch.maxpool(x)\n\n        x = self.arch.layer1(x)\n        x = self.arch.layer2(x)\n        x = self.arch.layer3(x)\n        x = self.arch.layer4(x)\n\n        x = self.last(x)\n\n        return x\n        \n    def forward(self, x):\n        batch_size, C, H, W = x.shape\n        \n#         x = (x - MEAN) / (STD)\n        x = self.forward_init_layers(x)\n\n        x = F.adaptive_avg_pool2d(x, 1).reshape(batch_size, -1)\n        x = F.dropout(x, self.head_dropout, self.training)\n\n        fc_graph = self.fc_graph(x)\n        fc_vowel = self.fc_vowel(x)\n        fc_conso = self.fc_conso(x)\n\n        return fc_graph, fc_vowel, fc_conso","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"net = ModifiedResnext()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"net.load_state_dict(torch.load('../input/rexnet50-trained/network_29.pth', map_location=torch.device('cpu')))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"prefix = 'test_image_data_'\ndf_file = 'test.csv'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.read_csv(data_path + df_file)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.cuda.is_available()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"row_id = []\ntarget = []\n\nif torch.cuda.is_available():\n    net.cuda()\nnet.eval()\n\nfor i in range(4):\n    test_df = pq.read_pandas(data_path + f'{prefix}{i}.parquet').to_pandas()\n    test_data = test_df.iloc[:,1:]\n    test_df = test_df['image_id']\n    \n    bd_test = BengaliDataset(test_df, test_data)\n    test_batch = DataLoader(bd_test, batch_size=1)\n    \n    \n    for inp in test_batch:\n        if torch.cuda.is_available():\n            inp['image'] = inp['image'].cuda()\n        with torch.no_grad():\n            out = net(inp['image'])\n        (out_gr, out_vd, out_cd) = out\n                \n        t_idx = inp['df_idx'][0]\n\n        row_id.extend([f'{t_idx}_consonant_diacritic', f'{t_idx}_grapheme_root', f'{t_idx}_vowel_diacritic'])\n        target.extend([int(out_cd.argmax().cpu().detach().numpy()), int(out_gr.argmax().cpu().detach().numpy()), int(out_vd.argmax().cpu().detach().numpy())])\n        \n    print(f'Finished {prefix}{i}.parquet')\n    del test_df\n    del test_data\n    del bd_test\n    del test_batch","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df = pd.DataFrame({'row_id': row_id, 'target': target})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":1}