{"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\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 read-only \"../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\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch\nfrom torch.cuda.amp import autocast\nimport time\nfrom torch import nn\nfrom torch.nn.functional import dropout\nfrom tqdm import tqdm\nimport sys\nimport glob\nfrom collections import OrderedDict\nimport cv2\nfrom torch.utils.data import Dataset, DataLoader\nfrom matplotlib import pyplot as plt\nfrom albumentations import Compose, Normalize, Resize\nfrom albumentations.pytorch import ToTensor, ToTensorV2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sys.path.append('../input/timm-pytorch-image-models/pytorch-image-models-master')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import timm\nfrom timm.models.layers.adaptive_avgmax_pool import SelectAdaptivePool2d\nfrom timm.models.resnet import Bottleneck","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"testdir = \"../input/ranzcr-clip-catheter-line-classification/test\"\ndf = pd.read_csv(\"../input/ranzcr-clip-catheter-line-classification/sample_submission.csv\")\npublic_df = pd.read_csv(\"../input/ranzcrsubmissionfiles/PublicLB_A.csv\").iloc[50:]\n\nrun_df = df[~df[\"StudyInstanceUID\"].isin(public_df[\"StudyInstanceUID\"].values)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class InverseTestAugment():\n    def __init__(self):\n        transformation = [\n            Resize(256, 256),\n            Normalize(),\n            ToTensorV2()\n            ]\n\n        self.transform = Compose(transformation)\n\n    def __call__(self, image):\n        transformed = self.transform(image=image)\n        return transformed['image']\n\nclass ClassificationDataset(Dataset):\n    def __init__(self, dir_, names):\n        self.dir = dir_\n        self.names = names\n        self.transform = InverseTestAugment()\n    def __len__(self):\n        return len(self.names)\n\n    def __getitem__(self, idx):\n        image = cv2.imread(os.path.join(self.dir, self.names[idx] + \".jpg\"))\n        image = self.transform(image=image)\n        return image, self.names[idx] ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class CustomModel(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.model = timm.create_model(\"tf_efficientnet_b0_ns\", pretrained=False)\n        \n        n_features = self.model.classifier.in_features\n        self.model.global_pool = nn.Identity()\n        self.model.classifier = nn.Identity()\n        self.pooling = nn.AdaptiveAvgPool2d(1)\n        self.fc = nn.Linear(n_features, 5)\n\n    def forward(self, x):\n        with autocast():\n            bs = x.size(0)\n            features = self.model(x)\n            pooled_features = self.pooling(features).view(bs, -1)\n            output = self.fc(pooled_features)\n            return output","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = CustomModel().cuda()\nmodel.load_state_dict(torch.load(\"../input/ranzcr-images-error/inverse_model.pth\", \"cpu\"))\nmodel.eval()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_dataloader = DataLoader(ClassificationDataset(\"../input/ranzcr-clip-catheter-line-classification/test\", run_df[\"StudyInstanceUID\"].values), batch_size=16, pin_memory=True, shuffle=False, num_workers=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tbar = tqdm(test_dataloader)\npreds = []\nnames = []\nwith torch.no_grad():\n    for image, name in tbar:\n        image = image.cuda()\n        output = model(image)            \n        preds.append(output.cpu().numpy())\n        names.append(name)\n    preds = torch.argmax(torch.tensor(np.vstack(preds)), 1).numpy()\n    names = np.hstack(names)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"inverse_dict = {}\nfor n,p in zip(names, preds):\n    inverse_dict[n] = p","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"wfiles = sorted(glob.glob(\"../input/clip-weights/*.pth\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"wfiles","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"wfiles = [\n '../input/clip-weights/b6rf_fold0.pth',\n '../input/clip-weights/b6rf_fold1.pth',\n '../input/clip-weights/b6rf_fold2.pth',\n '../input/clip-weights/b6rf_fold3.pth',\n '../input/clip-weights/b6rf_fold4.pth',\n '../input/clip-weights/b7_fold0_1024_97188.pth',\n '../input/clip-weights/b7_fold0_1024_97363.pth',\n '../input/clip-weights/b7_fold1_1024_97092.pth',\n '../input/clip-weights/b7_fold1_1024_97213.pth',\n '../input/clip-weights/b7_fold2_1024_97135.pth',\n '../input/clip-weights/b7_fold2_1024_97165.pth',\n '../input/clip-weights/b7_fold3_1024_97326.pth',\n '../input/clip-weights/b7_fold3_1024_97388.pth',\n '../input/clip-weights/b7_fold4_1024_97500.pth',\n '../input/clip-weights/b7_fold4_1024_97587.pth']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i, wf in enumerate(wfiles):\n    pt = OrderedDict()\n    ckpt = torch.load(wf, \"cpu\").pop(\"state_dict\")\n    for k,v in ckpt.items():\n        pt[k[7:]] = v\n    wfiles[i] = pt","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class EfficientNet(nn.Module):\n    \"\"\"\n    EfficientNet B0-B8.\n    Args:\n        cfg (CfgNode): configs\n    \"\"\"\n    def __init__(self, model_name):\n        super(EfficientNet, self).__init__()\n        backbone = timm.create_model(\n            model_name=model_name,\n            pretrained=False,\n            in_chans=3,\n        )\n        self.conv_stem = backbone.conv_stem\n        self.bn1 = backbone.bn1\n        self.act1 = backbone.act1\n        ### Original blocks ###\n        for i in range(len((backbone.blocks))):\n            setattr(self, \"block{}\".format(str(i)), backbone.blocks[i])\n        self.conv_head = backbone.conv_head\n        self.bn2 = backbone.bn2\n        self.act2 = backbone.act2\n        self.global_pool = SelectAdaptivePool2d(pool_type=\"avg\")\n        self.num_features = backbone.num_features\n        self.bottleneck_b4 = Bottleneck(inplanes=self.block4[-1].bn3.num_features,\n                                        planes=int(self.block4[-1].bn3.num_features / 4))\n        self.bottleneck_b5 = Bottleneck(inplanes=self.block5[-1].bn3.num_features,\n                                        planes=int(self.block5[-1].bn3.num_features / 4))\n        self.fc_b4 = nn.Linear(self.block4[-1].bn3.num_features, 14)\n        self.fc_b5 = nn.Linear(self.block5[-1].bn3.num_features, 14)\n\n        self.fc = nn.Linear(self.num_features, 14)\n        del backbone\n\n    def _features(self, x):\n        x = self.conv_stem(x)\n        x = self.bn1(x)\n        x = self.act1(x)\n        x = self.block0(x)\n        x = self.block1(x)\n        x = self.block2(x)\n        x = self.block3(x)\n        x = self.block4(x); b4 = x\n        x = self.block5(x); b5 = x\n        x = self.block6(x)\n        x = self.conv_head(x)\n        x = self.bn2(x)\n        x = self.act2(x)\n        return b4,b5,x\n\n    def forward(self, x):\n        with autocast():\n            b4, b5, x = self._features(x)\n            x = self.global_pool(x)\n#             b4_logits = self.fc_b4(torch.flatten(self.global_pool(self.bottleneck_b4(b4)), 1))\n            b5_logits = self.fc_b5(torch.flatten(self.global_pool(self.bottleneck_b5(b5)), 1))\n            x = torch.flatten(x, 1)\n            logits = self.fc(x)\n            output = (torch.sigmoid(logits) + torch.sigmoid(b5_logits)) / 2.\n            return output","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(5):\n    exec(f\"modelb6_{i} = EfficientNet(\\\"tf_efficientnet_b6\\\").cuda()\")\n    exec(f\"modelb7a_{i} = EfficientNet(\\\"tf_efficientnet_b7\\\").cuda()\")\n    exec(f\"modelb7b_{i} = EfficientNet(\\\"tf_efficientnet_b7\\\").cuda()\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"models = []\nfor m in [\"b6\", \"b7a\", \"b7b\"]:\n    for i in range(5):\n        exec(f\"models.append(model{m}_{i})\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(len(models)):\n    models[i].load_state_dict(wfiles[i])\n    models[i].eval()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class to_tensor:\n    def __init__(self, size):\n        transformation = [\n            Resize(size, size),                         \n            Normalize(),\n            ToTensor()]\n        self.transform = Compose(transformation)\n\n    def __call__(self, x):\n        return self.transform(image=x)['image']\n\nclass CLiP(Dataset):\n    def __init__(self, df, testdir):\n        self.names = df[\"StudyInstanceUID\"].values\n        self.testdir = testdir\n        self.to_tensor_1024 = to_tensor(1024)\n        self.to_tensor_1344 = to_tensor(1344)\n        \n    def __getitem__(self, idx):\n        imgpath = os.path.join(self.testdir, self.names[idx] + \".jpg\")\n        imgstate = inverse_dict[self.names[idx]]            \n        imgraw = cv2.imread(imgpath)\n        if imgstate == 1:\n            imgraw = cv2.bitwise_not(imgraw)\n        elif imgstate == 4:\n            imgraw = imgraw[::-1,:,:]\n        img1024 = self.to_tensor_1024(cv2.resize(imgraw, (1024, 1024)))\n        img1344 = self.to_tensor_1344(cv2.resize(imgraw, (1504, 1504)))\n        \n        return img1024, img1344, self.names[idx]\n    \n    def __len__(self):\n        return len(self.names)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dataloader = DataLoader(CLiP(run_df, testdir), 8, shuffle=False, drop_last=False, num_workers=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"outputs = []\nnames = []\nfor i, (img1024, img1344, name) in tqdm(enumerate(dataloader)):\n    img1024 = img1024.cuda()\n    img1344 = img1344.cuda()\n    output = 0\n    with torch.no_grad():\n        \n        output += 0.3 * modelb7a_0(img1024)\n        output += 0.3 * modelb7a_1(img1024)\n        output += 0.3 * modelb7a_2(img1024)\n        output += 0.3 * modelb7a_3(img1024)\n        output += 0.3 * modelb7a_4(img1024)\n        \n        output += 0.3 * modelb7b_0(img1024)\n        output += 0.3 * modelb7b_1(img1024)\n        output += 0.3 * modelb7b_2(img1024)\n        output += 0.3 * modelb7b_3(img1024)\n        output += 0.3 * modelb7b_4(img1024)\n        \n        output += 0.4 * modelb6_0(img1344)\n        output += 0.4 * modelb6_1(img1344)\n        output += 0.4 * modelb6_2(img1344)\n        output += 0.4 * modelb6_3(img1344)\n        output += 0.4 * modelb6_4(img1344)\n    outputs.append(output.cpu().numpy())\n    names.append(name)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data = []\nif len(outputs) and len(names):\n    outputs = np.vstack(outputs)\n    names = np.hstack(names)\n    for output, name in zip(outputs, names):\n        data.append([name] + list(output[:-3] / 5.))\nsubmission = pd.DataFrame(data, columns=df.columns)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = pd.concat([public_df, submission])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.to_csv(\"submission.csv\", index=False)","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":4}