{"cells":[{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"%reload_ext autoreload\n%autoreload 2\n%matplotlib inline\n\nimport cv2\nfrom tqdm import tqdm_notebook as tqdm\nimport fastai\nfrom fastai.vision import *\nimport os\nfrom mish_activation import *\nimport warnings\nfrom albumentations import *\nfrom albumentations.pytorch import ToTensor\nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install /kaggle/input/needed-packages/efficientnet_pytorch-0.5.1/efficientnet_pytorch-0.5.1\n!pip install /kaggle/input/needed-packages/pretrainedmodels-0.7.4/pretrainedmodels-0.7.4","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"HEIGHT = 137\nWIDTH = 236\nSIZE = 224\nbs = 128\narch = models.resnet18\nMODEL = '/kaggle/input/grapheme-fast-ai-starter-using-resnet18/resnet18_model_fold_0.pth'\nnworkers = 2\n\nTEST = ['/kaggle/input/bengaliai-cv19/test_image_data_0.parquet',\n        '/kaggle/input/bengaliai-cv19/test_image_data_1.parquet',\n        '/kaggle/input/bengaliai-cv19/test_image_data_2.parquet',\n        '/kaggle/input/bengaliai-cv19/test_image_data_3.parquet']\n\nLABELS = '../input/bengaliai-cv19/train.csv'\nmodel_name = 'resnet34'\nsd_path = '/kaggle/input/bengalib0/2_13_r34.pth'\n\ndf = pd.read_csv(LABELS)\nnunique = list(df.nunique())[1:-1]","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-output":false,"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"from efficientnet_pytorch import EfficientNet\nimport pretrainedmodels\n'''model portion'''\nclass to3channels(nn.Module):\n    def __init__(self):\n        super().__init__()\n        pass \n    \n    def forward(self, x):\n        return torch.stack([x, x, x], dim=1)\n\nclass identity(nn.Module):\n    def __init__(self):\n        super().__init__()\n    \n    def forward(self, x):\n        return x\n\nclass add_tail(nn.Module):\n    def __init__(self, backbone, num_features):\n        super().__init__()\n        self.pre = to3channels()\n        self.backbone = backbone\n        self.fc1 = nn.Linear(num_features, 168)\n        self.fc2 = nn.Linear(num_features, 11)\n        self.fc3 = nn.Linear(num_features, 7)\n    \n    def forward(self, x):\n        x = self.backbone(self.pre(x))\n        return self.fc1(x), self.fc2(x), self.fc3(x)\n    \n# Define model from argument here\ndef get_model(model_name):\n    if 'efficientnet' in model_name:\n        backbone = EfficientNet.from_name(model_name, override_params={'num_classes': 1})\n        num_features = backbone._fc.weight.shape[1]\n        backbone._fc = identity()\n    else:\n        try:\n            backbone = pretrainedmodels.__dict__[model_name](pretrained=None)\n        except:\n            print('Available models are:', pretrainedmodels.model_names)\n            raise NotImplementedError\n        num_features = backbone.last_linear.weight.shape[1]\n        backbone.last_linear = identity()\n    return add_tail(backbone, num_features)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = get_model(model_name).cuda()\nmodel.load_state_dict(torch.load(sd_path, map_location='cuda'));\nmodel.eval();","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"HEIGHT = 137\nWIDTH = 236\nimport numpy as np\ndef 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\ndef crop_resize(image, pad=8, cols=None, rows=None, force_apply=False):\n    img0 = 255 - image\n    dx, dy = 5, 5\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    #cropping may cut too much, so we need to add it back\n    xmin = xmin - dx if (xmin > dx) else 0\n    ymin = ymin - dy if (ymin > dy) else 0\n    xmax = xmax + dx if (xmax < WIDTH - dx) else WIDTH\n    ymax = ymax + dy if (ymax < HEIGHT - dy) else HEIGHT\n    img = img0[ymin:ymax,xmin:xmax]\n    #remove lo intensity pixels as noise\n    img[img < 28] = 0\n    lx, ly = xmax-xmin,ymax-ymin\n    l = max(lx,ly)+pad\n    #make sure that the aspect ratio is kept in rescaling\n    img = np.pad(img, [((l-ly)//2,), ((l-lx)//2,)], mode='constant')\n    return {'image':img}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class GraphemeDataset(Dataset):\n    def __init__(self, df, transform):\n        self.df = df\n        self.transform = transform\n        self.data = self.df.iloc[:, 1:].values.reshape(-1, HEIGHT, WIDTH).astype(np.uint8)\n\n    def __len__(self):\n        return len(self.data)\n\n    def __getitem__(self, idx):\n        name = self.df.iloc[idx,0]\n        #normalize each image by its max val\n        img = self.data[idx].astype(np.uint8)\n        img = self.transform(image=img)['image']\n        return img, name\n\nfrom functools import partial\ntsfm = Compose([\n                partial(crop_resize),\n                Resize(SIZE, SIZE),\n                ToTensor()\n            ])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Prediction"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import gc\nrow_id,target = [],[]\nfor fname in TEST:\n    df = pd.read_parquet(fname)\n    ds = GraphemeDataset(df, tsfm)\n    dl = DataLoader(ds, batch_size=bs, num_workers=nworkers, shuffle=False)\n    with torch.no_grad():\n        for x,y in tqdm(dl):\n            x = x.cuda()\n            p1,p2,p3 = model(x)\n            p1 = p1.argmax(-1).view(-1).cpu()\n            p2 = p2.argmax(-1).view(-1).cpu()\n            p3 = p3.argmax(-1).view(-1).cpu()\n            for idx,name in enumerate(y):\n                row_id += [f'{name}_grapheme_root',f'{name}_vowel_diacritic',\n                           f'{name}_consonant_diacritic']\n                target += [p1[idx].item(),p2[idx].item(),p3[idx].item()]\n    del df, ds, dl\n    gc.collect()\n                \nsub_df = pd.DataFrame({'row_id': row_id, 'target': target})\nsub_df.to_csv('submission.csv', index=False)\nsub_df.head()","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}