{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import cv2\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport numpy as np\nimport pandas as pd\nfrom torchvision import models\nfrom torch.utils.data import Dataset, DataLoader\n\n\nclass APINet(nn.Module):\n    ''' Module of API_Net\n    There are some unused layers in it but to\n    prevent from errors of loading the weight\n    model, I kept them there.\n    '''\n\n    def __init__(self, out_channel):\n        super(APINet, self).__init__()\n        # use densenet121 as back bone\n        backbone = models.densenet121(pretrained=False)\n        backbone.features.conv0 = nn.Conv2d(1, 64, kernel_size=(7, 7),\n                                            stride=(2, 2), padding=(3, 3))\n        num_feature = backbone.classifier.in_features\n        layers = list(backbone.children())[:-1]\n        self.conv = nn.Sequential(*layers)\n\n        self.fc = nn.Linear(num_feature, out_channel)\n\n        # layers below are unused\n        embedding = 512\n        self.map = nn.Sequential(\n            nn.Linear(num_feature * 2, embedding),\n            nn.LeakyReLU(inplace=True),\n            nn.Linear(embedding, embedding),\n            nn.LeakyReLU(inplace=True),\n            nn.Linear(embedding, num_feature),\n        )\n        self.sigmoid = nn.Sigmoid()\n\n        self.criterion = nn.CrossEntropyLoss()\n        self.rank_criterion = nn.MarginRankingLoss(margin=0)\n        self.softmax_layer = nn.Softmax(dim=1)\n\n    def forward(self, images):\n        conv_out = self.conv(images)\n        pool_out = F.adaptive_avg_pool2d(conv_out, (1, 1)).squeeze()\n\n        return self.fc(pool_out)\n\n\nmat1 = np.arange(137)\nmat2 = np.arange(236)\n\n\ndef Allign(image):\n    ''' Allign words to the center of image '''\n    img1 = image.mean(axis=1)\n    img2 = image.mean(axis=0)\n    imgall = img1.mean()\n\n    mean_x = int((img1 * mat1).mean() / imgall)\n    mean_y = int((img2 * mat2).mean() / imgall)\n\n    _t = min(68, mean_x)\n    _b = min(69, 137 - mean_x)\n    _l = min(118, mean_y)\n    _r = min(118, 236 - mean_y)\n    # print(_t, _b, _l, _r)\n\n    zeros = np.zeros((137, 236))\n    zeros[68-_t:68 + _b, 118-_l:118 + _r] = \\\n        image[mean_x-_t:mean_x + _b, mean_y-_l:mean_y + _r]\n\n    return zeros[68 - 64: 68 + 64, 118 - 96: 118 + 96]\n\n\nclass GraphemeDataset(Dataset):\n    def __init__(self, images):\n        self.images = 255 - images.reshape(-1, 137, 236)\n\n    def __len__(self):\n        return len(self.images)\n\n    def __getitem__(self, idx):\n        image = self.images[idx] / 255\n        image = Allign(image) * 2 - 1\n        return image\n\n\ndef test():\n    model_root = APINet(168).cuda()\n    model_root = nn.DataParallel(model_root)\n    model_root.load_state_dict(torch.load(\n        '/kaggle/input/models/DenseNet121root_3.pth'))\n    model_root.eval()\n\n    model_vowel = APINet(11).cuda()\n    model_vowel = nn.DataParallel(model_vowel)\n    model_vowel.load_state_dict(torch.load(\n        '/kaggle/input/models/DenseNet121vowel_3.pth'))\n    model_vowel.eval()\n\n    model_consonant = APINet(7).cuda()\n    model_consonant = nn.DataParallel(model_consonant)\n    model_consonant.load_state_dict(torch.load(\n        '/kaggle/input/models/DenseNet121consonant.pth'))\n    model_consonant.eval()\n\n    predictions = []\n\n    for i in range(4):\n        print(i)\n        test = pd.read_parquet(\n            '/kaggle/input/bengaliai-cv19/test_image_data_%d.parquet' % i)\n        test_data = test.iloc[:, 1:].values\n        del test\n        test_image = GraphemeDataset(test_data)\n        test_loader = torch.utils.data.DataLoader(test_image,\n                                                  batch_size=256,\n                                                  shuffle=False,\n                                                  drop_last=False)\n\n        with torch.no_grad():\n            for data in test_loader:\n                data = data.cuda()\n                data = data.unsqueeze(1).float()\n\n                labels = np.zeros((data.shape[0] * 3, ), dtype=np.int)\n\n                vowel = model_vowel(data)\n                labels[2::3] = vowel.argmax(1).cpu().detach().numpy()\n                del vowel\n\n                root = model_root(data)\n                labels[1::3] = root.argmax(1).cpu().detach().numpy()\n                del root\n\n                consonant = model_consonant(data)\n                labels[::3] = consonant.argmax(1).cpu().detach().numpy()\n                del consonant\n\n                predictions.append(labels)\n                del data\n                del labels\n\n        del test_data\n        del test_image\n        del test_loader\n\n    submission = pd.read_csv(\n        '/kaggle/input/bengaliai-cv19/sample_submission.csv')\n    submission.target = np.hstack(predictions)\n    submission.head(10)\n    submission.to_csv('submission.csv', index=False)\n\n\ntest()\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","collapsed":true,"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":false},"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":4}