{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"subfile_path = '../input/ranzcr-pytorch-training/submission.csv'","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Summary\nHi, Kagglers. This is a public benchmark with resnet200d using `image_size = 512`. Since it's only the beginning of the competition, I feel like giving an idea of what can be achieved with solely images. Weights are available [here](https://www.kaggle.com/underwearfitting/resnet200d-baseline-benchmark-public). Training Notebook for a single fold is available [here](https://www.kaggle.com/underwearfitting/single-fold-training-of-resnet200d-lb0-965).\n\nTraining details:\n- batch_size = 64\n- image_size = 512\n- lr = 3e-5\n- scheduler: CosineAnnealingLR\n- epochs = 30 with 1 epoch warmup at lr/10\n- augmentations: \n```\ntransforms_train = albumentations.Compose([\n     albumentations.RandomResizedCrop(image_size, image_size, scale=(0.9, 1), p=1), \n     albumentations.HorizontalFlip(p=0.5),\n     albumentations.ShiftScaleRotate(p=0.5),\n     albumentations.HueSaturationValue(hue_shift_limit=10, sat_shift_limit=10, val_shift_limit=10, p=0.7),\n     albumentations.RandomBrightnessContrast(brightness_limit=(-0.2,0.2), contrast_limit=(-0.2, 0.2), p=0.7),\n     albumentations.CLAHE(clip_limit=(1,4), p=0.5),\n     albumentations.OneOf([\n         albumentations.OpticalDistortion(distort_limit=1.0),\n         albumentations.GridDistortion(num_steps=5, distort_limit=1.),\n         albumentations.ElasticTransform(alpha=3),\n     ], p=0.2),\n     albumentations.OneOf([\n         albumentations.GaussNoise(var_limit=[10, 50]),\n         albumentations.GaussianBlur(),\n         albumentations.MotionBlur(),\n         albumentations.MedianBlur(),\n     ], p=0.2),\n    albumentations.Resize(image_size, image_size),\n    albumentations.OneOf([\n    \tJpegCompression(),\n    \tDownscale(scale_min=0.1, scale_max=0.15),\n    ], p=0.2),\n    IAAPiecewiseAffine(p=0.2),\n    IAASharpen(p=0.2),\n    albumentations.Cutout(max_h_size=int(image_size * 0.1), max_w_size=int(image_size * 0.1), num_holes=5, p=0.5),\n    albumentations.Normalize(),\n])\n```\n- hardware: RTX3090 x 2"},{"metadata":{},"cell_type":"markdown","source":"## Version Notes\n* v1: 0.965lb, TTA hflip\n* v2: 0.964lb, no TTA\n* v3: bug fixes"},{"metadata":{},"cell_type":"markdown","source":"## Configuration"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import pandas as pd\nbatch_size = 1\nimage_size = 512\ntta = True\nsubmit = True\nenet_type = ['resnet200d'] * 5\n# model_path = ['../input/resnet200d-baseline-benchmark-public/resnet200d_fold0_cv953.pth',\n#               '../input/resnet200d-baseline-benchmark-public/resnet200d_fold1_cv955.pth',\n#               '../input/resnet200d-baseline-benchmark-public/resnet200d_fold2_cv955.pth',\n#               '../input/resnet200d-baseline-benchmark-public/resnet200d_fold3_cv957.pth',\n#               '../input/resnet200d-baseline-benchmark-public/resnet200d_fold4_cv954.pth']\n# you can save GPU quota using fast sub attached in the last markdown file\nfast_sub = True\n# fast_sub_path = '../input/baselinemean-average/submission.csv'\nfast_sub_path = subfile_path","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Imports"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import os\nimport sys\n# sys.path.append('../input/pytorch-image-models/pytorch-image-models-master')\n# sys.path.append('../input/timm-pytorch-image-models/pytorch-image-models-master')\nimport numpy as np\nDEBUG = False\nimport time\nimport cv2\nimport PIL.Image\nfrom sklearn.metrics import accuracy_score\nfrom tqdm.notebook import tqdm\nimport torch\nfrom torch.utils.data import DataLoader, Dataset\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torchvision\nimport torchvision.transforms as transforms\nimport torch.optim as optim\nfrom torch.optim.lr_scheduler import CosineAnnealingLR\nimport albumentations\nfrom tqdm.notebook import tqdm\nimport matplotlib.pyplot as plt\n%matplotlib inline\nimport seaborn as sns\nfrom pylab import rcParams\nimport timm\nfrom albumentations import *\nfrom albumentations.pytorch import ToTensorV2\ndevice = torch.device('cuda') if not DEBUG else torch.device('cpu')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"class RANZCRResNet200D(nn.Module):\n    def __init__(self, model_name='resnet200d', out_dim=11, pretrained=False):\n        super().__init__()\n        self.model = timm.create_model(model_name, pretrained=False)\n        n_features = self.model.fc.in_features\n        self.model.global_pool = nn.Identity()\n        self.model.fc = nn.Identity()\n        self.pooling = nn.AdaptiveAvgPool2d(1)\n        self.fc = nn.Linear(n_features, out_dim)\n\n    def forward(self, x):\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":{},"cell_type":"markdown","source":"## Transforms"},{"metadata":{"trusted":true},"cell_type":"code","source":"# transforms_test = albumentations.Compose([\n#     Resize(image_size, image_size),\n#     Normalize(\n#          mean=[0.485, 0.456, 0.406],\n#          std=[0.229, 0.224, 0.225],\n#      ),\n#     ToTensorV2()\n# ])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Dataset"},{"metadata":{"trusted":true},"cell_type":"code","source":"class RANZCRDataset(Dataset):\n    def __init__(self, df, mode, transform=None):\n        \n        self.df = df.reset_index(drop=True)\n        self.mode = mode\n        self.transform = transform\n        self.labels = df[target_cols].values\n        \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, index):\n        row = self.df.loc[index]\n        img = cv2.imread(row.file_path)\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        \n        if self.transform is not None:\n            res = self.transform(image=img)\n            img = res['image']\n        label = torch.tensor(self.labels[index]).float()\n        if self.mode == 'test':\n            return img\n        else:\n            return img, label","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# test = pd.read_csv('../input/ranzcr-clip-catheter-line-classification/sample_submission.csv')\n# test['file_path'] = test.StudyInstanceUID.apply(lambda x: os.path.join('../input/ranzcr-clip-catheter-line-classification/test', f'{x}.jpg'))\n# target_cols = test.iloc[:, 1:12].columns.tolist()\n\n# test_dataset = RANZCRDataset(test, 'test', transform=transforms_test)\n# test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False,  num_workers=24)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Utils"},{"metadata":{"trusted":true},"cell_type":"code","source":"def inference_func(test_loader):\n    model.eval()\n    bar = tqdm(test_loader)\n    LOGITS = []\n    PREDS = []\n    \n    with torch.no_grad():\n        for batch_idx, images in enumerate(bar):\n            x = images.to(device)\n            logits = model(x)\n            LOGITS.append(logits.cpu())\n            PREDS += [logits.sigmoid().detach().cpu()]\n        PREDS = torch.cat(PREDS).cpu().numpy()\n        LOGITS = torch.cat(LOGITS).cpu().numpy()\n    return PREDS\n\ndef tta_inference_func(test_loader):\n    model.eval()\n    bar = tqdm(test_loader)\n    PREDS = []\n    LOGITS = []\n\n    with torch.no_grad():\n        for batch_idx, images in enumerate(bar):\n            x = images.to(device)\n            x = torch.stack([x,x.flip(-1)],0) # hflip\n            x = x.view(-1, 3, image_size, image_size)\n            logits = model(x)\n            logits = logits.view(batch_size, 2, -1).mean(1)\n            PREDS += [logits.sigmoid().detach().cpu()]\n            LOGITS.append(logits.cpu())\n        PREDS = torch.cat(PREDS).cpu().numpy()\n        \n    return PREDS","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Submission"},{"metadata":{"trusted":true},"cell_type":"code","source":"# if submit:\n#     test_preds = []\n#     for i in range(len(enet_type)):\n#         if enet_type[i] == 'resnet200d':\n#             print('resnet200d loaded')\n#             model = RANZCRResNet200D(enet_type[i], out_dim=len(target_cols))\n#             model = model.to(device)\n#         model.load_state_dict(torch.load(model_path[i], map_location='cuda:0'))\n#         if tta:\n#             test_preds += [tta_inference_func(test_loader)]\n#         else:\n#             test_preds += [inference_func(test_loader)]\n\n#     submission = pd.read_csv('../input/ranzcr-clip-catheter-line-classification/sample_submission.csv')\n#     submission[target_cols] = np.mean(test_preds, axis=0)\n#     submission.to_csv('submission.csv', index=False)\n# else:\n#     pd.read_csv('../input/ranzcr-clip-catheter-line-classification/sample_submission.csv').to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Bonus: fast sub, save GPU quota\nYou can use the following to submit .csv to predict public test set only."},{"metadata":{"trusted":true},"cell_type":"code","source":"# https://www.kaggle.com/underwearfitting/inference-public-only-fast/output#1006689 @paulo pinto\nif fast_sub:\n    pd.read_csv('../input/ranzcr-clip-catheter-line-classification/sample_submission.csv',usecols=[0],index_col=0).join(pd.read_csv(fast_sub_path).set_index('StudyInstanceUID')).fillna(0).to_csv('submission.csv')","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}