{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\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":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import torch\nimport numpy as np\nfrom torch.utils.data import DataLoader\nfrom torch.utils.data import Dataset\nfrom torchvision import transforms as torchtransforms\nimport cv2\nimport torch.nn as nn\nfrom tqdm import tqdm_notebook as tqdm\nimport torchvision\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport time","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nprint(device)\nmodelpath = \"/kaggle/input/se-resnext50-32x4d-fold2/se_resnext50_32x4d_fold2.pkl\"\nroot_path=\"/kaggle/input/bengaliai-cv19\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"simple_transform_valid = torchtransforms.Compose([\n    torchtransforms.ToTensor(),\n    torchtransforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n])","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\ndef crop_resize(img0, size=128, pad=16):\n    HEIGHT = 137\n    WIDTH = 236\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 - 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    #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 cv2.resize(img,(size,size))\nclass ClsTestDataset(Dataset):\n    def __init__(self, df, torchtransforms):\n        self.df = df\n        self.pathes = self.df.iloc[:,0].values\n        self.data = self.df.iloc[:, 1:].values\n        self.torchtransforms = torchtransforms\n\n    def __getitem__(self, idx):\n        HEIGHT = 137\n        WIDTH = 236\n        #row = self.df.iloc[idx].values\n        path = self.pathes[idx]\n        img = self.data[idx, :]\n        img = 255 - img.reshape(HEIGHT, WIDTH).astype(np.uint8)\n        #img = crop_resize(img, size=128)\n        #img = crop_resize(img)\n        img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)       \n        img = torchtransforms.ToPILImage()(img)\n        img = self.torchtransforms(img)\n        return path, img\n    def __len__(self):\n        return len(self.df)\n\ndef make_loader(\n        data_folder,\n        batch_size=64,\n        num_workers=2,\n        is_shuffle = False,\n):\n\n    image_dataset = ClsTestDataset(df = data_folder,\n                                    torchtransforms = simple_transform_valid)\n\n    return DataLoader(\n    image_dataset,\n    batch_size=batch_size,\n    num_workers=num_workers,\n    pin_memory=True,\n    shuffle=is_shuffle\n    )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from __future__ import print_function, division, absolute_import\nfrom collections import OrderedDict\nimport math\n\nimport torch.nn as nn\nfrom torch.utils import model_zoo\n__all__ = ['SENet', 'se_resnext50_32x4d']\nclass SEModule(nn.Module):\n\n    def __init__(self, channels, reduction):\n        super(SEModule, self).__init__()\n        self.avg_pool = nn.AdaptiveAvgPool2d(1)\n        self.fc1 = nn.Conv2d(channels, channels // reduction, kernel_size=1,\n                             padding=0)\n        self.relu = nn.ReLU(inplace=True)\n        self.fc2 = nn.Conv2d(channels // reduction, channels, kernel_size=1,\n                             padding=0)\n        self.sigmoid = nn.Sigmoid()\n\n    def forward(self, x):\n        module_input = x\n        x = self.avg_pool(x)\n        x = self.fc1(x)\n        x = self.relu(x)\n        x = self.fc2(x)\n        x = self.sigmoid(x)\n        return module_input * x\n\n\nclass Bottleneck(nn.Module):\n    \"\"\"\n    Base class for bottlenecks that implements `forward()` method.\n    \"\"\"\n    def forward(self, x):\n        residual = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n        out = self.relu(out)\n\n        out = self.conv3(out)\n        out = self.bn3(out)\n\n        if self.downsample is not None:\n            residual = self.downsample(x)\n\n        out = self.se_module(out) + residual\n        out = self.relu(out)\n\n        return out\n\n\nclass SEBottleneck(Bottleneck):\n    \"\"\"\n    Bottleneck for SENet154.\n    \"\"\"\n    expansion = 4\n\n    def __init__(self, inplanes, planes, groups, reduction, stride=1,\n                 downsample=None):\n        super(SEBottleneck, self).__init__()\n        self.conv1 = nn.Conv2d(inplanes, planes * 2, kernel_size=1, bias=False)\n        self.bn1 = nn.BatchNorm2d(planes * 2)\n        self.conv2 = nn.Conv2d(planes * 2, planes * 4, kernel_size=3,\n                               stride=stride, padding=1, groups=groups,\n                               bias=False)\n        self.bn2 = nn.BatchNorm2d(planes * 4)\n        self.conv3 = nn.Conv2d(planes * 4, planes * 4, kernel_size=1,\n                               bias=False)\n        self.bn3 = nn.BatchNorm2d(planes * 4)\n        self.relu = nn.ReLU(inplace=True)\n        self.se_module = SEModule(planes * 4, reduction=reduction)\n        self.downsample = downsample\n        self.stride = stride\n\n\nclass SEResNetBottleneck(Bottleneck):\n    \"\"\"\n    ResNet bottleneck with a Squeeze-and-Excitation module. It follows Caffe\n    implementation and uses `stride=stride` in `conv1` and not in `conv2`\n    (the latter is used in the torchvision implementation of ResNet).\n    \"\"\"\n    expansion = 4\n\n    def __init__(self, inplanes, planes, groups, reduction, stride=1,\n                 downsample=None):\n        super(SEResNetBottleneck, self).__init__()\n        self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False,\n                               stride=stride)\n        self.bn1 = nn.BatchNorm2d(planes)\n        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, padding=1,\n                               groups=groups, bias=False)\n        self.bn2 = nn.BatchNorm2d(planes)\n        self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False)\n        self.bn3 = nn.BatchNorm2d(planes * 4)\n        self.relu = nn.ReLU(inplace=True)\n        self.se_module = SEModule(planes * 4, reduction=reduction)\n        self.downsample = downsample\n        self.stride = stride\n\n\nclass SEResNeXtBottleneck(Bottleneck):\n    \"\"\"\n    ResNeXt bottleneck type C with a Squeeze-and-Excitation module.\n    \"\"\"\n    expansion = 4\n\n    def __init__(self, inplanes, planes, groups, reduction, stride=1,\n                 downsample=None, base_width=4):\n        super(SEResNeXtBottleneck, self).__init__()\n        width = math.floor(planes * (base_width / 64)) * groups\n        self.conv1 = nn.Conv2d(inplanes, width, kernel_size=1, bias=False,\n                               stride=1)\n        self.bn1 = nn.BatchNorm2d(width)\n        self.conv2 = nn.Conv2d(width, width, kernel_size=3, stride=stride,\n                               padding=1, groups=groups, bias=False)\n        self.bn2 = nn.BatchNorm2d(width)\n        self.conv3 = nn.Conv2d(width, planes * 4, kernel_size=1, bias=False)\n        self.bn3 = nn.BatchNorm2d(planes * 4)\n        self.relu = nn.ReLU(inplace=True)\n        self.se_module = SEModule(planes * 4, reduction=reduction)\n        self.downsample = downsample\n        self.stride = stride\n\n\nclass SENet(nn.Module):\n\n    def __init__(self, block, layers, groups, reduction, dropout_p=0.2,\n                 inplanes=128, input_3x3=True, downsample_kernel_size=3,\n                 downsample_padding=1, num_classes=1000):        \n        super(SENet, self).__init__()\n        self.inplanes = inplanes\n        if input_3x3:\n            layer0_modules = [\n                ('conv1', nn.Conv2d(3, 64, 3, stride=2, padding=1,\n                                    bias=False)),\n                ('bn1', nn.BatchNorm2d(64)),\n                ('relu1', nn.ReLU(inplace=True)),\n                ('conv2', nn.Conv2d(64, 64, 3, stride=1, padding=1,\n                                    bias=False)),\n                ('bn2', nn.BatchNorm2d(64)),\n                ('relu2', nn.ReLU(inplace=True)),\n                ('conv3', nn.Conv2d(64, inplanes, 3, stride=1, padding=1,\n                                    bias=False)),\n                ('bn3', nn.BatchNorm2d(inplanes)),\n                ('relu3', nn.ReLU(inplace=True)),\n            ]\n        else:\n            layer0_modules = [\n                ('conv1', nn.Conv2d(3, inplanes, kernel_size=7, stride=2,\n                                    padding=3, bias=False)),\n                ('bn1', nn.BatchNorm2d(inplanes)),\n                ('relu1', nn.ReLU(inplace=True)),\n            ]\n        # To preserve compatibility with Caffe weights `ceil_mode=True`\n        # is used instead of `padding=1`.\n        layer0_modules.append(('pool', nn.MaxPool2d(3, stride=2,\n                                                    ceil_mode=True)))\n        self.layer0 = nn.Sequential(OrderedDict(layer0_modules))\n        self.layer1 = self._make_layer(\n            block,\n            planes=64,\n            blocks=layers[0],\n            groups=groups,\n            reduction=reduction,\n            downsample_kernel_size=1,\n            downsample_padding=0\n        )\n        self.layer2 = self._make_layer(\n            block,\n            planes=128,\n            blocks=layers[1],\n            stride=2,\n            groups=groups,\n            reduction=reduction,\n            downsample_kernel_size=downsample_kernel_size,\n            downsample_padding=downsample_padding\n        )\n        self.layer3 = self._make_layer(\n            block,\n            planes=256,\n            blocks=layers[2],\n            stride=2,\n            groups=groups,\n            reduction=reduction,\n            downsample_kernel_size=downsample_kernel_size,\n            downsample_padding=downsample_padding\n        )\n        self.layer4 = self._make_layer(\n            block,\n            planes=512,\n            blocks=layers[3],\n            stride=2,\n            groups=groups,\n            reduction=reduction,\n            downsample_kernel_size=downsample_kernel_size,\n            downsample_padding=downsample_padding\n        )\n        self.avg_pool = nn.AvgPool2d(7, stride=1)\n        self.dropout = nn.Dropout(dropout_p) if dropout_p is not None else None\n        self.last_linear = nn.Linear(512 * block.expansion, num_classes)\n\n    def _make_layer(self, block, planes, blocks, groups, reduction, stride=1,\n                    downsample_kernel_size=1, downsample_padding=0):\n        downsample = None\n        if stride != 1 or self.inplanes != planes * block.expansion:\n            downsample = nn.Sequential(\n                nn.Conv2d(self.inplanes, planes * block.expansion,\n                          kernel_size=downsample_kernel_size, stride=stride,\n                          padding=downsample_padding, bias=False),\n                nn.BatchNorm2d(planes * block.expansion),\n            )\n\n        layers = []\n        layers.append(block(self.inplanes, planes, groups, reduction, stride,\n                            downsample))\n        self.inplanes = planes * block.expansion\n        for i in range(1, blocks):\n            layers.append(block(self.inplanes, planes, groups, reduction))\n\n        return nn.Sequential(*layers)\n\n    def features(self, x):\n        x = self.layer0(x)\n        x = self.layer1(x)\n        x = self.layer2(x)\n        x = self.layer3(x)\n        x = self.layer4(x)\n        return x\n\n    def logits(self, x):\n        x = self.avg_pool(x)\n        if self.dropout is not None:\n            x = self.dropout(x)\n        x = x.view(x.size(0), -1)\n        x = self.last_linear(x)\n        return x\n\n    def forward(self, x):\n        x = self.features(x)\n        x = self.logits(x)\n        return x\n    \ndef se_resnext50_32x4d(num_classes=1000, pretrained='imagenet'):\n    model = SENet(SEResNeXtBottleneck, [3, 4, 6, 3], groups=32, reduction=16,\n                  dropout_p=None, inplanes=64, input_3x3=False,\n                  downsample_kernel_size=1, downsample_padding=0,\n                  num_classes=num_classes)\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = se_resnext50_32x4d(pretrained=None)\nmodel.avg_pool = nn.AdaptiveAvgPool2d(1)\nmodel.last_linear = nn.Linear(model.last_linear.in_features, 186)\nmodelvalue = torch.load(modelpath, map_location='cuda:0')\nnewmodelvalue = {}\nfor kv in modelvalue:\n    newmodelvalue[kv[4:]]=modelvalue[kv]        \nmodel.load_state_dict(newmodelvalue)\n#model.load_state_dict(modelvalue)\nmodel = model.to(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def getmodeleval(model, dataloaders):\n    model.eval()\n    tbar = tqdm(dataloaders)\n    pathes=[]\n\n    alllogit1 = []\n    alllogit2 = []\n    alllogit3 = []\n    for path, img in tbar:\n        img = img.to(device)\n        pathes.extend(path)\n        with torch.no_grad():\n            output = model(img)\n        logit1, logit2, logit3 = output[:,: 168],\\\n                                    output[:,168: 168+11],\\\n                                    output[:,168+11:]\n        logit1 = F.softmax(logit1, dim=1).cpu().numpy()  # 对每一行进行softmax\n        logit2 = F.softmax(logit2, dim=1).cpu().numpy()\n        logit3 = F.softmax(logit3, dim=1).cpu().numpy()\n        alllogit1.extend(logit1.tolist())\n        alllogit2.extend(logit2.tolist())\n        alllogit3.extend(logit3.tolist())\n    alllogit1 = np.array(alllogit1)\n    alllogit2 = np.array(alllogit2)\n    alllogit3 = np.array(alllogit3)\n    \n    print(\"getmodeleval::alllogit1.shape\", alllogit1.shape)\n    print(\"getmodeleval::alllogit2.shape\", alllogit2.shape)\n    print(\"getmodeleval::alllogit3.shape\", alllogit3.shape)\n    return pathes, alllogit1, alllogit2, alllogit3","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"allpathes=[]\nallpreds_root = []\nallpreds_vowel = []\nallpreds_consonant = []\ntAllBegin = time.time()\nfor i in range(4):\n    test_csv = pd.read_parquet(os.path.join(root_path, f'test_image_data_{i}.parquet'))\n    tBegin = time.time()\n    dataloaders = make_loader(data_folder = test_csv,\n                                           batch_size=8,\n                                           num_workers = 2,\n                                           is_shuffle = False)\n    pathes, logit1, logit2, logit3 = getmodeleval(model, dataloaders)\n    preds_root = np.argmax(logit1, axis=1)# 其中，axis=1表示按行计算\n    preds_vowel = np.argmax(logit2, axis=1)# 其中，axis=1表示按行计算\n    preds_consonant = np.argmax(logit3, axis=1)# 其中，axis=1表示按行计算\n\n    allpathes.extend(pathes)\n    allpreds_root.extend(preds_root.tolist())\n    allpreds_vowel.extend(preds_vowel.tolist())\n    allpreds_consonant.extend(preds_consonant.tolist())\n    tEnd = time.time()\n    print(i, int(round(tEnd * 1000)) - int(round(tBegin * 1000)), \"ms\")\ntAllEnd = time.time()\nprint(len(allpathes), len(allpreds_root), len(allpreds_vowel), len(allpreds_consonant),  int(round(tAllEnd * 1000)) - int(round(tAllBegin * 1000)), \"ms\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(len(allpathes), len(allpreds_root), len(allpreds_vowel), len(allpreds_consonant))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"row_id=[]\ntarget=[]\nfor idx, image_id in enumerate(allpathes):\n    target.extend([allpreds_consonant[idx]])\n    target.extend([allpreds_root[idx]])\n    target.extend([allpreds_vowel[idx]])\n\n    row_id.extend([str(image_id) + '_consonant_diacritic'])\n    row_id.extend([str(image_id) + '_grapheme_root'])\n    row_id.extend([str(image_id) + '_vowel_diacritic'])\n\n#print(row_id)\n#print(target)\nsubmission_df = pd.read_csv(root_path + '/sample_submission.csv')\n#print(submission_df.shape)\n# print(len(target))\n# print(len(row_id))\n# print(target)\n# print(row_id)\nsubmission_df.target = np.hstack(np.array(target).astype(np.int))\n#submission_df['target'] = np.array(target).astype(np.int)\n#submission_df['row_id'] = row_id\nprint(submission_df.head(10))\nsubmission_df.to_csv('submission.csv', index=False)\nprint(\"================end ======================\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"A\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!nvidia-smi","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}