{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import sys\nsys.path.append('../input/timm-pytorch-image-models/pytorch-image-models-master')\n\nimport numpy as np\nimport pandas as pd\nimport os\nimport time\nimport math\nimport timm\n\nimport torch\nimport torch.nn as nn\nimport torchvision\nimport torchvision.transforms as transforms\nfrom torch.utils.data import Dataset, DataLoader\nimport torch.nn.functional as F\n\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import roc_auc_score, accuracy_score\nfrom PIL import Image\n\nnp.random.seed(42)\ntorch.manual_seed(42)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"TARGET_COLUMNS = ['ETT - Abnormal', 'ETT - Borderline', 'ETT - Normal',\n                 'NGT - Abnormal', 'NGT - Borderline', 'NGT - Incompletely Imaged', 'NGT - Normal', \n                 'CVC - Abnormal', 'CVC - Borderline', 'CVC - Normal',\n                 'Swan Ganz Catheter Present']\n\nDEBUG = False\n\nif DEBUG is False:\n    BATCH_SIZE = 3\n    EPOCHS = 3\n    AVERAGING_SIZE = 100\nelse:\n    BATCH_SIZE = 4\n    EPOCHS = 2\n    AVERAGING_SIZE = 20\n\nROOT_DIR = '/kaggle/input/ranzcr-clip-catheter-line-classification/test'\nOUTPUT_DIR = './'\nMODEL_PATH = '../input/efficientnet-b3-epoch-4-loss-01446-roc-09160pth/efficientnet_b3_epoch_4_loss_0.1446_roc_0.9160.pth'\nMODEL_NAME = 'efficientnet_b3'\nIMG_SIZE = 672*1.5\n\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\ndevice","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Load and configure data "},{"metadata":{},"cell_type":"markdown","source":"### Load DataFrame with labels of images"},{"metadata":{"trusted":true},"cell_type":"code","source":"imgs = []\nfor dirname, _, filenames in os.walk('../input/ranzcr-clip-catheter-line-classification/test'):\n    for filename in filenames:\n        imgs.append(filename)\n\n# Load DF with labels \ncols = {\"StudyInstanceUID\": imgs}\nfor col in TARGET_COLUMNS:\n    cols[col] = [0 for i in range(len(imgs))]\ntest_set_df = pd.DataFrame(cols)\nprint(test_set_df.columns)\n\nif DEBUG is True:\n    test_set_df = test_set_df.sample(200)\nelse:\n    test_set_df = test_set_df\n\n\ntest_set_df.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Create custom PyTorch dataset\n\nWe do this instead of using ImageFolder as we don't want to reorganize the input folder as it is given from Kaggle already loaded without any nesting, and we have more than one class for each image so we need custom dataset"},{"metadata":{"trusted":true},"cell_type":"code","source":"class RanzcrClipTestDataset(torch.utils.data.Dataset):\n    \"\"\"Face Landmarks dataset.\"\"\"\n\n    def __init__(self, labels_df, transform=None):\n        \"\"\"\n        Args:\n            labels_df (string): DataFrame with mapping of images to target\n            root_dir (string): Directory with all the images.\n            transform (callable, optional): Optional transform to be applied\n                on a sample.\n        \"\"\"\n        self.file_paths = [os.path.join(ROOT_DIR, uid) for uid in labels_df[\"StudyInstanceUID\"].values]\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.file_paths)\n\n    def __getitem__(self, idx):\n\n        # Read image as PIL\n        sample = Image.open(self.file_paths[idx]).convert('RGB')\n\n        # Run all given transformations on image\n        if self.transform:\n            sample = self.transform(sample)\n\n        return sample","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Transforms"},{"metadata":{"trusted":true},"cell_type":"code","source":"test_transforms = transforms.Compose([transforms.Resize((IMG_SIZE, IMG_SIZE)),\n                                      transforms.ToTensor(),\n                                      transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Split test dataset into train and test"},{"metadata":{"trusted":true},"cell_type":"code","source":"test_set = RanzcrClipTestDataset(labels_df=test_set_df, transform=test_transforms)\n\nprint(f'Test size: {len(test_set)}')\n\ntest_loader = torch.utils.data.DataLoader(test_set, batch_size=BATCH_SIZE*2, shuffle=False, num_workers=4, pin_memory=True, drop_last=False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Visualize some images"},{"metadata":{"trusted":true},"cell_type":"code","source":"def imshow(inp, title=None):\n    \"\"\"Imshow for Tensor.\"\"\"\n    inp = inp.numpy().transpose((1, 2, 0))\n    mean = np.array([0.485, 0.456, 0.406])\n    std = np.array([0.229, 0.224, 0.225])\n    inp = std * inp + mean\n    inp = np.clip(inp, 0, 1)\n    plt.imshow(inp)\n    if title is not None:\n        plt.title(title)\n    plt.pause(0.001)  # pause a bit so that plots are updated\n\n\n# Get a batch of training data\ninputs = next(iter(test_loader))\n\n# Make a grid from batch\nout = torchvision.utils.make_grid(inputs)\n\nimshow(out)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Training Code"},{"metadata":{"trusted":true},"cell_type":"code","source":"def inference(net):\n    \n    y_pred = []\n    y_prob = []\n    \n    # switch to evaluation mode\n    net.eval()\n    \n    start_time = time.time()\n    \n    with torch.no_grad():\n        for i, inputs in enumerate(test_loader, 0):\n\n            inputs = inputs.to(device)\n      \n            outputs = net(inputs)\n            \n            probs = outputs.sigmoid()\n            \n            for i in range(len(outputs)):\n                y_pred.append(np.round(probs[i].cpu().detach().numpy()))\n                y_prob.append(probs[i].cpu().detach().numpy())\n\n        y_pred = np.vstack(y_pred)\n        y_prob = np.vstack(y_prob)\n        \n        del inputs\n        torch.cuda.empty_cache()\n        \n        end_time = time.time()\n        print(f'[{i}] Elapsed {(end_time - start_time):.4f} ') \n        \n        return y_pred, y_prob\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class CustomPretrainedmModel(nn.Module):\n    def __init__(self, model_name=MODEL_NAME, pretrained=False):\n        super().__init__()\n        self.model = timm.create_model(model_name, pretrained=pretrained)\n        n_features = self.model.classifier.in_features\n        self.model.classifier = nn.Linear(n_features, len(TARGET_COLUMNS))\n\n    def forward(self, x):\n        x = self.model(x)\n        return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"checkpoint = torch.load(MODEL_PATH, map_location=device)\nmodel = CustomPretrainedmModel()\nmodel.to(device)\nmodel.load_state_dict(checkpoint['model'])\ny_pred, y_prob = inference(model)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_set_df.iloc[:, 1:] = y_prob\n\ntest_set_df[\"StudyInstanceUID\"] = test_set_df.StudyInstanceUID.str.replace('.jpg', '')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# dtypes = {col: 'int' for col in TARGET_COLUMNS}\n# test_set_df = test_set_df.astype(dtypes)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_set_df.sample(20)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_set_df.to_csv('./submission.csv', index=False)","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}