{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# GPU\n!nvidia-smi","metadata":{"execution":{"iopub.status.busy":"2021-08-09T13:59:41.347234Z","iopub.execute_input":"2021-08-09T13:59:41.347574Z","iopub.status.idle":"2021-08-09T13:59:42.021267Z","shell.execute_reply.started":"2021-08-09T13:59:41.347500Z","shell.execute_reply":"2021-08-09T13:59:42.020380Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport pandas as pd\n\nsample = pd.read_csv('../input/siim-covid19-detection/sample_submission.csv')\n\nif len(sample) == 2477:\n    sample.to_csv('submission.csv', index=False)\n    os._exit(00)","metadata":{"execution":{"iopub.status.busy":"2021-08-06T08:59:53.374989Z","iopub.execute_input":"2021-08-06T08:59:53.375346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\nsys.path.append('../input/timm126')\nsys.path.append('../input/timm126/timm126')\nsys.path.append('../input/timm413')\nsys.path.append('../input/timm413/timm413')\nfrom timm126 import timm as timm_126\nfrom timm413 import timm_new as timm_413\nprint(timm_126.__version__)\nprint(timm_413.__version__)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T13:59:44.741287Z","iopub.execute_input":"2021-08-09T13:59:44.741602Z","iopub.status.idle":"2021-08-09T13:59:48.832156Z","shell.execute_reply.started":"2021-08-09T13:59:44.741571Z","shell.execute_reply":"2021-08-09T13:59:48.831304Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# DICOM to PNG","metadata":{}},{"cell_type":"code","source":"# offline gdcm\n!conda install '/kaggle/input/pydicom-conda-helper/libjpeg-turbo-2.1.0-h7f98852_0.tar.bz2' -c conda-forge -y\n!conda install '/kaggle/input/pydicom-conda-helper/libgcc-ng-9.3.0-h2828fa1_19.tar.bz2' -c conda-forge -y\n!conda install '/kaggle/input/pydicom-conda-helper/gdcm-2.8.9-py37h500ead1_1.tar.bz2' -c conda-forge -y\n!conda install '/kaggle/input/pydicom-conda-helper/conda-4.10.1-py37h89c1867_0.tar.bz2' -c conda-forge -y\n!conda install '/kaggle/input/pydicom-conda-helper/certifi-2020.12.5-py37h89c1867_1.tar.bz2' -c conda-forge -y\n!conda install '/kaggle/input/pydicom-conda-helper/openssl-1.1.1k-h7f98852_0.tar.bz2' -c conda-forge -y","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-08-09T13:59:51.789587Z","iopub.execute_input":"2021-08-09T13:59:51.789994Z","iopub.status.idle":"2021-08-09T14:00:59.308358Z","shell.execute_reply.started":"2021-08-09T13:59:51.789957Z","shell.execute_reply":"2021-08-09T14:00:59.307284Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nfrom PIL import Image\nimport pandas as pd\nfrom tqdm.auto import tqdm\nimport numpy as np\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\n\n\ndef read_xray(path, voi_lut=True, fix_monochrome=True):\n    dicom = pydicom.read_file(path)\n    if voi_lut:\n        data = apply_voi_lut(dicom.pixel_array, dicom)\n    else:\n        data = dicom.pixel_array\n    if fix_monochrome and dicom.PhotometricInterpretation == \"MONOCHROME1\":\n        data = np.amax(data) - data\n    data = data - np.min(data)\n    data = data / np.max(data)\n    data = (data * 255).astype(np.uint8)\n    return data\n\n\ndef resize(array, size, keep_ratio=False, resample=Image.LANCZOS):\n    im = Image.fromarray(array)\n    if keep_ratio:\n        im.thumbnail((size, size), resample)\n    else:\n        im = im.resize((size, size), resample)\n    return im","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:01:31.680758Z","iopub.execute_input":"2021-08-09T14:01:31.681097Z","iopub.status.idle":"2021-08-09T14:01:31.961615Z","shell.execute_reply.started":"2021-08-09T14:01:31.681065Z","shell.execute_reply":"2021-08-09T14:01:31.960808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#public image_ids\npublic = pd.read_csv('../input/covid-public-test/sample_submission.csv')\npublic['type'] = public['id'].apply(lambda x: x[-5:])\npublic_image = public[public['type'] == 'image'].reset_index(drop=True)\npublic_image['image_id'] = public_image['id'].apply(lambda x: x[:-6])\npublic_image_ids = public_image['image_id'].to_list()","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:01:33.064616Z","iopub.execute_input":"2021-08-09T14:01:33.064969Z","iopub.status.idle":"2021-08-09T14:01:33.101751Z","shell.execute_reply.started":"2021-08-09T14:01:33.064938Z","shell.execute_reply":"2021-08-09T14:01:33.100981Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_id = []\ndim0 = []\ndim1 = []\nsz = 512\nsave_dir = f'/kaggle/tmp/test/'\nos.makedirs(save_dir, exist_ok=True)\n\nfor dirname, _, filenames in tqdm(os.walk(f'../input/siim-covid19-detection/test')):\n    for file in filenames:\n        if file[:-4] in public_image_ids:\n            continue\n        xray = read_xray(os.path.join(dirname, file))\n        im = resize(xray, size=sz)  \n        im.save(os.path.join(save_dir, file.replace('dcm', 'png')))\n        image_id.append(file.replace('.dcm', ''))\n        dim0.append(xray.shape[0])\n        dim1.append(xray.shape[1])","metadata":{"execution":{"iopub.status.busy":"2021-08-09T14:01:48.103362Z","iopub.execute_input":"2021-08-09T14:01:48.103702Z","iopub.status.idle":"2021-08-09T14:01:53.799954Z","shell.execute_reply.started":"2021-08-09T14:01:48.103651Z","shell.execute_reply":"2021-08-09T14:01:53.797676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta = pd.DataFrame.from_dict({'image_id': image_id, 'dim0': dim0, 'dim1': dim1})\nmeta.head()","metadata":{"execution":{"iopub.status.busy":"2021-08-06T09:04:28.407538Z","iopub.execute_input":"2021-08-06T09:04:28.407853Z","iopub.status.idle":"2021-08-06T09:04:28.416903Z","shell.execute_reply.started":"2021-08-06T09:04:28.407824Z","shell.execute_reply":"2021-08-06T09:04:28.416006Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# test image root path\n# all images: root + image_id +.png\nroot = '/kaggle/tmp/test'","metadata":{"execution":{"iopub.status.busy":"2021-08-05T15:52:05.978724Z","iopub.execute_input":"2021-08-05T15:52:05.979073Z","iopub.status.idle":"2021-08-05T15:52:05.985811Z","shell.execute_reply.started":"2021-08-05T15:52:05.979042Z","shell.execute_reply":"2021-08-05T15:52:05.984839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Detection","metadata":{}},{"cell_type":"code","source":"!pip install '/kaggle/input/pycocotools/pycocotools-2.0-cp37-cp37m-linux_x86_64.whl' --no-deps > /dev/null\n\nsys.path.append(\"/kaggle/input/timm-efficientdet-pytorch-fixdiv\")\nsys.path.append(\"/kaggle/input/omegaconf\")\nsys.path.append(\"/kaggle/input/weightedboxesfusion\")\n\nfrom ensemble_boxes import *\n\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n%matplotlib inline\nfrom sklearn.model_selection import StratifiedKFold\n\nimport math\nimport gc, os\nfrom datetime import datetime\nimport time\nimport random\nimport cv2\nfrom glob import glob\nimport pydicom\nfrom tqdm import tqdm\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nfrom skimage import exposure\nfrom bokeh.plotting import figure as bokeh_figure\nfrom bokeh.io import output_notebook, show, output_file\nfrom bokeh.models import ColumnDataSource, HoverTool, Panel\nfrom bokeh.models.widgets import Tabs\nfrom PIL import Image\nfrom sklearn import preprocessing\nfrom random import randint\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.data import DataLoader, Dataset\nfrom torch.utils.data.sampler import SequentialSampler, RandomSampler\nimport torch.optim as optim\n\nfrom effdet import get_efficientdet_config, EfficientDet, DetBenchTrain, DetBenchEval\nfrom effdet.efficientdet import HeadNet\n\nimport torchvision\nfrom torchvision import transforms\nimport albumentations as A\nfrom albumentations.pytorch.transforms import ToTensorV2\nfrom torch.optim.lr_scheduler import CosineAnnealingWarmRestarts\nfrom torch.optim.lr_scheduler import CosineAnnealingLR\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\ndevice = 'cuda:0' if torch.cuda.is_available() else 'cpu'\nprint(device)","metadata":{"execution":{"iopub.status.busy":"2021-08-05T15:52:09.289081Z","iopub.execute_input":"2021-08-05T15:52:09.289434Z","iopub.status.idle":"2021-08-05T15:52:33.706331Z","shell.execute_reply.started":"2021-08-05T15:52:09.289391Z","shell.execute_reply":"2021-08-05T15:52:33.705455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def seed_everything(seed):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n\nseed = 2020\nseed_everything(seed)\nNFOLDS = 5\n\n#ImageNet\nmean = np.array([[[0.485, 0.456, 0.406]]])\nstd = np.array([[[0.229, 0.224, 0.225]]])","metadata":{"execution":{"iopub.status.busy":"2021-08-05T15:52:33.709384Z","iopub.execute_input":"2021-08-05T15:52:33.70967Z","iopub.status.idle":"2021-08-05T15:52:33.720718Z","shell.execute_reply.started":"2021-08-05T15:52:33.70964Z","shell.execute_reply":"2021-08-05T15:52:33.719846Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"public = pd.read_csv('../input/covid-public-test/sample_submission.csv')\ntest = pd.read_csv('../input/siim-covid19-detection/sample_submission.csv')\n\n#submit\nif len(test) != 2477:\n    test = pd.concat([test, public]).reset_index(drop=True).drop_duplicates(keep=False).reset_index(drop=True)\n    \ntest['type'] = test['id'].apply(lambda x: x[-5:])\ntest_study = test[test['type'] == 'study'].reset_index(drop=True)\ntest_image = test[test['type'] == 'image'].reset_index(drop=True)\ntest_study['study_id'] = test_study['id'].apply(lambda x: x[:-6])\ntest_image['image_id'] = test_image['id'].apply(lambda x: x[:-6])\ntest_study = test_study.rename(columns={'PredictionString': 'PredictionString1'})\ntest_image = test_image.rename(columns={'PredictionString': 'PredictionString2'})\ntest_study_ = test_study.drop(['type', 'study_id'], axis=1)\ntmp = pd.DataFrame(columns=test_study.columns)\n\nfor i in tqdm(range(len(test_study))):\n    study_id = test_study.iloc[i, 3]\n    img_paths = glob(f'../input/siim-covid19-detection/test/{study_id}/*/*')\n    if len(img_paths) == 1:\n        img_path = img_paths[0]\n        image_id = img_path.split('/')[-1][:-4]\n        test_study.loc[i, 'image_id'] = image_id\n    else:\n        add_df = pd.concat([test_study.iloc[i:i+1]]*(len(img_paths)-1)).reset_index(drop=True)\n        for j in range(len(img_paths)):\n            if j == 0:\n                img_path = img_paths[j]\n                image_id = img_path.split('/')[-1][:-4]\n                test_study.loc[i, 'image_id'] = image_id\n            else:\n                img_path = img_paths[j]\n                image_id = img_path.split('/')[-1][:-4]\n                add_df.loc[j-1, 'image_id'] = image_id\n        tmp = tmp.append(add_df).reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2021-08-05T15:56:00.68107Z","iopub.execute_input":"2021-08-05T15:56:00.681446Z","iopub.status.idle":"2021-08-05T15:56:00.744659Z","shell.execute_reply.started":"2021-08-05T15:56:00.681411Z","shell.execute_reply":"2021-08-05T15:56:00.743783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test = pd.concat([test_study, tmp]).sort_values('id').reset_index(drop=True)\ntest = test.merge(meta, on='image_id').merge(test_image[['PredictionString2', 'image_id']], on='image_id')\ntest.head()","metadata":{"execution":{"iopub.status.busy":"2021-08-05T15:57:03.190382Z","iopub.execute_input":"2021-08-05T15:57:03.190762Z","iopub.status.idle":"2021-08-05T15:57:03.210878Z","shell.execute_reply.started":"2021-08-05T15:57:03.190726Z","shell.execute_reply":"2021-08-05T15:57:03.209902Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_valid_transforms():\n    return A.Compose([\n            A.Resize(height=sz, width=sz, p=1.0),\n            ToTensorV2(p=1.0),\n        ], p=1.0)\n\n\ndef collate_fn(batch):\n    return tuple(zip(*batch))\n\n\nclass COVIDDataset(Dataset):\n    def __init__(self, df, transforms=None):\n        super().__init__()\n        self.df = df\n        self.transforms = transforms\n\n    def __getitem__(self, index):\n        image_id = self.df.iloc[index, 4]\n        image = cv2.imread(f'{root}/{image_id}.png').astype(np.float32)\n        width = self.df.iloc[index, 6]\n        height = self.df.iloc[index, 5]\n        image /= 255.0\n        if self.transforms:\n            sample = {'image': image}\n            sample = self.transforms(**sample)\n            image = sample['image']\n        return image, image_id, width, height\n\n    def __len__(self):\n        return self.df.shape[0]","metadata":{"execution":{"iopub.status.busy":"2021-08-03T16:24:49.870495Z","iopub.execute_input":"2021-08-03T16:24:49.870963Z","iopub.status.idle":"2021-08-03T16:24:49.881298Z","shell.execute_reply.started":"2021-08-03T16:24:49.870933Z","shell.execute_reply":"2021-08-03T16:24:49.880084Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_net(checkpoint_path, model_name):\n    config = get_efficientdet_config(model_name)\n    net = EfficientDet(config, pretrained_backbone=False)\n    config.num_classes = 1\n    config.image_size = 512\n    net.class_net = HeadNet(config, num_outputs=config.num_classes, norm_kwargs=dict(eps=.001, momentum=.01))\n    checkpoint = torch.load(checkpoint_path)\n    net.load_state_dict(checkpoint['model_state_dict'])\n    del checkpoint\n    gc.collect()\n    net = DetBenchEval(net, config)\n    net.eval()\n    return net.cuda()\n\n\ndef make_predictions(images, score_threshold=0.001):\n    images = torch.stack(images).cuda().float()\n    predictions = []\n    with torch.no_grad():\n        det = net(images, torch.tensor([1]*images.shape[0]).float().cuda())\n        for i in range(images.shape[0]):\n            boxes = det[i].detach().cpu().numpy()[:,:4]    \n            scores = det[i].detach().cpu().numpy()[:,4]\n            indexes = np.where(scores > score_threshold)[0]\n            boxes = boxes[indexes]\n            boxes[:, 2] = boxes[:, 2] + boxes[:, 0]\n            boxes[:, 3] = boxes[:, 3] + boxes[:, 1]\n            predictions.append({\n                'boxes': boxes[indexes],\n                'scores': scores[indexes],\n            })\n    return [predictions]\n\n\ndef run_wbf(predictions, image_index, image_size=512, iou_thr=0.5, skip_box_thr=0.001, weights=None):\n    boxes = [(prediction[image_index]['boxes']/(image_size-1)).tolist()  for prediction in predictions]\n    scores = [prediction[image_index]['scores'].tolist()  for prediction in predictions]\n    labels = [np.ones(prediction[image_index]['scores'].shape[0]).tolist() for prediction in predictions]\n    boxes, scores, labels = non_maximum_weighted(boxes, scores, labels, iou_thr=iou_thr, skip_box_thr=skip_box_thr, weights=weights)\n    boxes = boxes*(image_size-1)\n    return boxes, scores, labels\n\n\ndef format_prediction_string(boxes, scores):\n    pred_strings = []\n    for j in zip(scores, boxes):\n        pred_strings.append(f\"opacity {j[0]} {j[1][0]} {j[1][1]} {j[1][2]} {j[1][3]}\")\n    return \" \".join(pred_strings)","metadata":{"execution":{"iopub.status.busy":"2021-08-03T16:24:50.05854Z","iopub.execute_input":"2021-08-03T16:24:50.058934Z","iopub.status.idle":"2021-08-03T16:24:50.076666Z","shell.execute_reply.started":"2021-08-03T16:24:50.058906Z","shell.execute_reply":"2021-08-03T16:24:50.07522Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset = COVIDDataset(\n    df=test,\n    transforms=get_valid_transforms()\n)\n\ndata_loader = DataLoader(\n    dataset,\n    batch_size=16,\n    shuffle=False,\n    num_workers=4,\n    drop_last=False,\n    collate_fn=collate_fn\n)","metadata":{"execution":{"iopub.status.busy":"2021-08-03T16:24:53.695671Z","iopub.execute_input":"2021-08-03T16:24:53.696068Z","iopub.status.idle":"2021-08-03T16:24:53.975145Z","shell.execute_reply.started":"2021-08-03T16:24:53.696028Z","shell.execute_reply":"2021-08-03T16:24:53.972852Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# EFD3 inference\nefd3 = test.copy()\nprint('<<<<<<<<<<EFD3>>>>>>>>>>')\nfor i in range(NFOLDS):\n    print(f'=====FOLD {i}=====')\n    net = load_net(checkpoint_path=f'../input/efd3ver001-weight/fold{i}-best.bin', model_name='tf_efficientdet_d3')\n    results = []\n    for images, image_ids, widths, heights in tqdm(data_loader):\n        predictions = make_predictions(images)\n        for j, image in enumerate(images):\n            boxes, scores, labels = run_wbf(predictions, image_index=j)\n            boxes = boxes.astype(np.float32).clip(min=0, max=sz)\n            boxes[:, 0] = boxes[:, 0] / sz \n            boxes[:, 1] = boxes[:, 1] / sz\n            boxes[:, 2] = boxes[:, 2] / sz\n            boxes[:, 3] = boxes[:, 3] / sz\n            result = {'PredictionString': format_prediction_string(boxes, scores)}\n            results.append(result)\n    efd3[f'PredictionString_{i}'] = np.nan\n    for k in tqdm(range(len(efd3))):\n        efd3.loc[k, f'PredictionString_{i}'] = f\" {results[k]['PredictionString']}\"  \n    del net, results\n    gc.collect()\n    \nefd3['id'] = efd3['image_id'].apply(lambda x: x + '_image')\nefd3.head()","metadata":{"execution":{"iopub.status.busy":"2021-08-03T12:58:38.375073Z","iopub.execute_input":"2021-08-03T12:58:38.375419Z","iopub.status.idle":"2021-08-03T12:58:49.261924Z","shell.execute_reply.started":"2021-08-03T12:58:38.375368Z","shell.execute_reply":"2021-08-03T12:58:49.260416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# EFD4 inference\nefd4 = test.copy()\nprint('<<<<<<<<<<EFD4>>>>>>>>>>')\nfor i in range(NFOLDS):\n    print(f'=====FOLD {i}=====')\n    net = load_net(checkpoint_path=f'../input/efd4ver002-weight/fold{i}-best.bin', model_name='tf_efficientdet_d4')\n    results = []\n    for images, image_ids, widths, heights in tqdm(data_loader):\n        predictions = make_predictions(images)\n        for j, image in enumerate(images):\n            boxes, scores, labels = run_wbf(predictions, image_index=j)\n            boxes = boxes.astype(np.float32).clip(min=0, max=sz)\n            boxes[:, 0] = boxes[:, 0] / sz \n            boxes[:, 1] = boxes[:, 1] / sz\n            boxes[:, 2] = boxes[:, 2] / sz\n            boxes[:, 3] = boxes[:, 3] / sz\n            result = {'PredictionString': format_prediction_string(boxes, scores)}\n            results.append(result)\n    efd4[f'PredictionString_{i}'] = np.nan\n    for k in tqdm(range(len(efd4))):\n        efd4.loc[k, f'PredictionString_{i}'] = f\" {results[k]['PredictionString']}\"  \n    del net, results\n    gc.collect()\n    \nefd4['id'] = efd4['image_id'].apply(lambda x: x + '_image')\nefd4.head()","metadata":{"execution":{"iopub.status.busy":"2021-07-26T13:27:12.584243Z","iopub.execute_input":"2021-07-26T13:27:12.58452Z","iopub.status.idle":"2021-07-26T13:27:12.596035Z","shell.execute_reply.started":"2021-07-26T13:27:12.584497Z","shell.execute_reply":"2021-07-26T13:27:12.595025Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# EFD5 inference\nefd5 = test.copy()\nprint('<<<<<<<<<<EFD5>>>>>>>>>>')\nfor i in range(NFOLDS):\n    print(f'=====FOLD {i}=====')\n    net = load_net(checkpoint_path=f'../input/efd5ver005-weight/fold{i}-best.bin', model_name='tf_efficientdet_d5')\n    results = []\n    for images, image_ids, widths, heights in tqdm(data_loader):\n        predictions = make_predictions(images)\n        for j, image in enumerate(images):\n            boxes, scores, labels = run_wbf(predictions, image_index=j)\n            boxes = boxes.astype(np.float32).clip(min=0, max=sz)\n            boxes[:, 0] = boxes[:, 0] / sz \n            boxes[:, 1] = boxes[:, 1] / sz\n            boxes[:, 2] = boxes[:, 2] / sz\n            boxes[:, 3] = boxes[:, 3] / sz\n            result = {'PredictionString': format_prediction_string(boxes, scores)}\n            results.append(result)\n    efd5[f'PredictionString_{i}'] = np.nan\n    for k in tqdm(range(len(efd5))):\n        efd5.loc[k, f'PredictionString_{i}'] = f\" {results[k]['PredictionString']}\"  \n    del net, results\n    gc.collect()\n    \nefd5['id'] = efd5['image_id'].apply(lambda x: x + '_image')\nefd5.head()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install ../input/pytorch-160-with-torchvision-070/torch-1.6.0cu101-cp37-cp37m-linux_x86_64.whl\n!pip install ../input/pytorch-160-with-torchvision-070/torchvision-0.7.0cu101-cp37-cp37m-linux_x86_64.whl","metadata":{"execution":{"iopub.status.busy":"2021-07-26T13:27:12.597613Z","iopub.execute_input":"2021-07-26T13:27:12.598084Z","iopub.status.idle":"2021-07-26T13:27:12.609664Z","shell.execute_reply.started":"2021-07-26T13:27:12.598044Z","shell.execute_reply":"2021-07-26T13:27:12.608684Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"public = pd.read_csv('../input/covid-public-test/sample_submission.csv')\ntest_df = pd.read_csv('../input/siim-covid19-detection/sample_submission.csv')\n\n#submit\nif len(test_df) != 2477:\n    test_df = pd.concat([test_df, public]).reset_index(drop=True).drop_duplicates(keep=False).reset_index(drop=True)\n    \ntest_df['type'] = test_df['id'].apply(lambda x: x[-5:])\ntest_df = test_df[test_df['type'] == 'image'].reset_index(drop=True)\nmeta['id'] = meta['image_id'] + '_image'\ntest_df = test_df.merge(meta, on='id', how='left')\ntest_df = test_df.drop(['type', 'image_id'], axis=1)\ntest_df['split'] = 'test'\ntest_df['fold'] = -1\nefd3 = test_df[['id']].merge(efd3, on='id')\nefd4 = test_df[['id']].merge(efd4, on='id')\nefd5 = test_df[['id']].merge(efd5, on='id')","metadata":{"execution":{"iopub.status.busy":"2021-07-26T13:27:12.611002Z","iopub.execute_input":"2021-07-26T13:27:12.611417Z","iopub.status.idle":"2021-07-26T13:27:12.667368Z","shell.execute_reply.started":"2021-07-26T13:27:12.611382Z","shell.execute_reply":"2021-07-26T13:27:12.666475Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df","metadata":{"execution":{"iopub.status.busy":"2021-07-26T13:27:12.668697Z","iopub.execute_input":"2021-07-26T13:27:12.669072Z","iopub.status.idle":"2021-07-26T13:27:12.689658Z","shell.execute_reply.started":"2021-07-26T13:27:12.669035Z","shell.execute_reply":"2021-07-26T13:27:12.688563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import shutil\ndim = 512\nNFOLDS = 5\ntest_dir = root\ntmp = pd.DataFrame(columns=test_df.columns)\niou_th = [0.60, 0.61, 0.61, 0.60, 0.60]\nconf_th = 0.001\nsTH = 0.001\nlTH = 0.362\nweights1 = [[1.2, 1.2, 1, 0.7], [1, 4, 2, 0], [1.1, 1.1, 1, 0.5], [1.5, 1.5, 1, 0.7], [1.5, 1.5, 1, 0.9]]\n\nfor i in range(NFOLDS):\n    print(f'==========FOLD{i}==========')\n    labels_dict = {}\n    scores_dict = {}\n    boxes_dict = {}\n    test_df_ = test_df.copy()\n    test_df_['PredictionString'] = ''\n    test_df_['fold'] = i\n    \n    #yolo inference\n    weights_dir = f'/kaggle/input/yolov5ver005-weight/fold{i}_best.pt'\n    shutil.copytree('/kaggle/input/yolov5-official-v31-dataset/yolov5/', f'/kaggle/working/yolov5/fold{i}')\n    os.chdir(f'/kaggle/working/yolov5/fold{i}')\n    !python detect.py --weights $weights_dir --img 512 --conf 0.001 --iou 0.5 --source $test_dir --save-txt --save-conf --exist-ok\n    \n    for j in tqdm(range(len(test_df_))):\n        image_id = test_df_.iloc[j, 0][:-6]\n        labels_dict[j] = []\n        scores_dict[j] = []\n        boxes_dict[j] = []\n        \n        #yolo\n        labels_list = []\n        scores_list = []\n        boxes_list = []\n        try:\n            f = open(f'/kaggle/working/yolov5/fold{i}/runs/detect/exp/labels/{image_id}.txt', 'r')\n            string = f.read().split(' ')\n            string.pop(0)\n            bbox_num = len(string) // 5\n\n            for k in range(bbox_num):\n                label = 0\n                xmid = float(string[0+5*k])\n                ymid = float(string[1+5*k])\n                w = float(string[2+5*k])\n                h = float(string[3+5*k])\n                xmin = xmid - w/2\n                xmax = xmid + w/2\n                ymin = ymid - h/2\n                ymax = ymid + h/2\n                score = float(string[4+5*k][:-3])\n                labels_list.append(label)\n                scores_list.append(score)\n                boxes_list.append([xmin, ymin, xmax, ymax])\n            labels_dict[j].append(labels_list)\n            scores_dict[j].append(scores_list)\n            boxes_dict[j].append(boxes_list)\n        except:\n            labels_dict[j].append([])\n            scores_dict[j].append([])\n            boxes_dict[j].append([])\n            \n        #EFD3\n        labels_list = []\n        scores_list = []\n        boxes_list = []\n        try:\n            string = efd3.loc[j, f'PredictionString_{i}'].split(' ')\n            string.pop(0)\n            bbox_num = len(string) // 6\n            for k in range(bbox_num):\n                label = 0\n                score = float(string[1+6*k])\n                xmin = float(string[2+6*k])\n                ymin = float(string[3+6*k])\n                xmax = float(string[4+6*k])\n                ymax = float(string[5+6*k])\n                labels_list.append(label)\n                scores_list.append(score)\n                boxes_list.append([xmin, ymin, xmax, ymax])\n            labels_dict[j].append(labels_list)\n            scores_dict[j].append(scores_list)\n            boxes_dict[j].append(boxes_list)\n        except:\n            labels_dict[j].append([])\n            scores_dict[j].append([])\n            boxes_dict[j].append([])\n            \n        #EFD4\n        labels_list = []\n        scores_list = []\n        boxes_list = []\n        try:\n            string = efd4.loc[j, f'PredictionString_{i}'].split(' ')\n            string.pop(0)\n            bbox_num = len(string) // 6\n            for k in range(bbox_num):\n                label = 0\n                score = float(string[1+6*k])\n                xmin = float(string[2+6*k])\n                ymin = float(string[3+6*k])\n                xmax = float(string[4+6*k])\n                ymax = float(string[5+6*k])\n                labels_list.append(label)\n                scores_list.append(score)\n                boxes_list.append([xmin, ymin, xmax, ymax])\n            labels_dict[j].append(labels_list)\n            scores_dict[j].append(scores_list)\n            boxes_dict[j].append(boxes_list)\n        except:\n            labels_dict[j].append([])\n            scores_dict[j].append([])\n            boxes_dict[j].append([])\n            \n        #EFD5\n        labels_list = []\n        scores_list = []\n        boxes_list = []\n        try:\n            string = efd5.loc[j, f'PredictionString_{i}'].split(' ')\n            string.pop(0)\n            bbox_num = len(string) // 6\n            for k in range(bbox_num):\n                label = 0\n                score = float(string[1+6*k])\n                xmin = float(string[2+6*k])\n                ymin = float(string[3+6*k])\n                xmax = float(string[4+6*k])\n                ymax = float(string[5+6*k])\n                labels_list.append(label)\n                scores_list.append(score)\n                boxes_list.append([xmin, ymin, xmax, ymax])\n            labels_dict[j].append(labels_list)\n            scores_dict[j].append(scores_list)\n            boxes_dict[j].append(boxes_list)\n        except:\n            labels_dict[j].append([])\n            scores_dict[j].append([])\n            boxes_dict[j].append([])\n    \n        #WBF per fold\n        print('=== WBF per fold ===')\n        width = test_df_.loc[j, 'dim1']\n        height = test_df_.loc[j, 'dim0']\n        boxes, scores, labels = weighted_boxes_fusion(\n            boxes_dict[j], \n            scores_dict[j], \n            labels_dict[j],\n            iou_thr=iou_th[i], \n            skip_box_thr=conf_th, \n            weights=weights1[i]\n        )\n        boxes[:, 0] = boxes[:, 0] * width\n        boxes[:, 1] = boxes[:, 1] * height\n        boxes[:, 2] = boxes[:, 2] * width\n        boxes[:, 3] = boxes[:, 3] * height\n    \n        if len(boxes) == 0:  #BBox_num == 0\n            continue\n        else:\n            box_num = len(boxes)\n            for b in range(box_num):\n                #small box removed\n                if ((boxes[b][2] - boxes[b][0]) * (boxes[b][3] - boxes[b][1])) / (width * height) < sTH:\n                    continue\n                \n                #large box removed\n                if ((boxes[b][2] - boxes[b][0]) * (boxes[b][3] - boxes[b][1])) / (width * height) > lTH:\n                    continue\n                \n                #edge box removed\n                if ((boxes[b][2] + boxes[b][0])/2 < width*0.05) | ((boxes[b][2] + boxes[b][0])/2 > width*0.95) | ((boxes[b][3] + boxes[b][1])/2 < height*0.05) | ((boxes[b][3] + boxes[b][1])/2 > height*0.95):\n                    continue\n                \n                #horizontal box removed\n                if (boxes[b][2] - boxes[b][0]) > width*0.6:\n                    continue\n                    \n                try:\n                    test_df_.loc[j, 'PredictionString'] += f'opacity {scores[b]} {int(boxes[b][0])} {int(boxes[b][1])} {int(boxes[b][2])} {int(boxes[b][3])} '\n                except:\n                    continue\n                    \n    tmp = tmp.append(test_df_, ignore_index=True)\n    del labels_dict, scores_dict, boxes_dict\n    gc.collect()","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-07-26T14:03:05.80549Z","iopub.execute_input":"2021-07-26T14:03:05.805845Z","iopub.status.idle":"2021-07-26T14:03:05.815213Z","shell.execute_reply.started":"2021-07-26T14:03:05.805809Z","shell.execute_reply":"2021-07-26T14:03:05.814408Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"shutil.rmtree('/kaggle/working/yolov5/fold0')\nshutil.rmtree('/kaggle/working/yolov5/fold1')\nshutil.rmtree('/kaggle/working/yolov5/fold2')\nshutil.rmtree('/kaggle/working/yolov5/fold3')\nshutil.rmtree('/kaggle/working/yolov5/fold4')\nos.chdir(f'/kaggle/working')","metadata":{"execution":{"iopub.status.busy":"2021-07-26T13:27:12.704148Z","iopub.execute_input":"2021-07-26T13:27:12.704779Z","iopub.status.idle":"2021-07-26T13:27:12.712677Z","shell.execute_reply.started":"2021-07-26T13:27:12.704726Z","shell.execute_reply":"2021-07-26T13:27:12.711707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tmp","metadata":{"execution":{"iopub.status.busy":"2021-07-26T13:27:12.71412Z","iopub.execute_input":"2021-07-26T13:27:12.71447Z","iopub.status.idle":"2021-07-26T13:27:12.720719Z","shell.execute_reply.started":"2021-07-26T13:27:12.714437Z","shell.execute_reply":"2021-07-26T13:27:12.719862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#tmp = pd.read_csv('../input/detection-final-sub-df/det_inf_per_fold.csv')\ntmp.to_csv('/kaggle/working/det_inf_per_fold.csv', index=False)\ndet_inf_per_fold = tmp","metadata":{"execution":{"iopub.status.busy":"2021-07-26T14:03:08.620378Z","iopub.execute_input":"2021-07-26T14:03:08.62073Z","iopub.status.idle":"2021-07-26T14:03:10.245116Z","shell.execute_reply.started":"2021-07-26T14:03:08.620699Z","shell.execute_reply":"2021-07-26T14:03:10.24424Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# WBF across folds\nweights2 = [1.5, 1, 1, 1.5, 2]  # 0.5982 / 0.5684 / 0.5637 / 0.5835 / 0.6316\nens_th = 0.65\nid_list = tmp.id.unique()\nlabels_dict = {}\nscores_dict = {}\nboxes_dict = {}\ntest_df['PredictionString'] = ''\n\nprint('=== WBF across folds ===')\nfor i in tqdm(range(len(id_list))):\n    image_id = id_list[i]\n    dfs = tmp[tmp['id'] == image_id].sort_values('fold').reset_index(drop=True)\n    width = dfs['dim1'].mean()\n    height = dfs['dim0'].mean()\n    labels_dict[i] = []\n    scores_dict[i] = []\n    boxes_dict[i] = []\n    \n    for j in range(NFOLDS):\n        labels_list = []\n        scores_list = []\n        boxes_list = []\n        try:\n            string = dfs[dfs['fold'] == j].iloc[0, 1].split(' ')\n            bbox_num = len(string) // 6\n            for k in range(bbox_num):\n                label = 0\n                score = float(string[1+6*k])\n                xmin = float(string[2+6*k]) / width\n                ymin = float(string[3+6*k]) / height\n                xmax = float(string[4+6*k]) / width\n                ymax = float(string[5+6*k]) / height\n                labels_list.append(label)\n                scores_list.append(score)\n                boxes_list.append([xmin, ymin, xmax, ymax])\n            labels_dict[i].append(labels_list)\n            scores_dict[i].append(scores_list)\n            boxes_dict[i].append(boxes_list)\n        except:\n            labels_dict[i].append([])\n            scores_dict[i].append([])\n            boxes_dict[i].append([])\n            \n    boxes, scores, labels = weighted_boxes_fusion(\n        boxes_dict[i], \n        scores_dict[i], \n        labels_dict[i],\n        iou_thr=ens_th, \n        skip_box_thr=conf_th, \n        weights=weights2\n    )\n  \n    boxes[:, 0] = boxes[:, 0] * width\n    boxes[:, 1] = boxes[:, 1] * height\n    boxes[:, 2] = boxes[:, 2] * width\n    boxes[:, 3] = boxes[:, 3] * height\n    \n    if len(boxes) == 0:  #BBox_num == 0\n        continue\n    else:\n        box_num = len(boxes)\n        for b in range(box_num):\n            #small box removed\n            if ((boxes[b][2] - boxes[b][0]) * (boxes[b][3] - boxes[b][1])) / (width * height) < sTH:\n                continue\n                \n            #large box removed\n            if ((boxes[b][2] - boxes[b][0]) * (boxes[b][3] - boxes[b][1])) / (width * height) > lTH:\n                continue\n                \n            #edge box removed\n            if ((boxes[b][2] + boxes[b][0])/2 < width*0.05) | ((boxes[b][2] + boxes[b][0])/2 > width*0.95) | ((boxes[b][3] + boxes[b][1])/2 < height*0.05) | ((boxes[b][3] + boxes[b][1])/2 > height*0.95):\n                continue\n                \n            #horizontal box removed\n            if (boxes[b][2] - boxes[b][0]) > width*0.6:\n                continue\n              \n            try:\n                index = test_df[test_df['id'] == image_id].index\n                test_df.loc[index, 'PredictionString'] += f'opacity {scores[b]} {int(boxes[b][0])} {int(boxes[b][1])} {int(boxes[b][2])} {int(boxes[b][3])} '\n            except:\n                continue\n                \ndel labels_dict, scores_dict, boxes_dict\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-07-26T14:29:27.74241Z","iopub.execute_input":"2021-07-26T14:29:27.742784Z","iopub.status.idle":"2021-07-26T14:29:31.006264Z","shell.execute_reply.started":"2021-07-26T14:29:27.742752Z","shell.execute_reply":"2021-07-26T14:29:31.004669Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df","metadata":{"execution":{"iopub.status.busy":"2021-07-26T14:29:33.69878Z","iopub.execute_input":"2021-07-26T14:29:33.699166Z","iopub.status.idle":"2021-07-26T14:29:33.718452Z","shell.execute_reply.started":"2021-07-26T14:29:33.699132Z","shell.execute_reply":"2021-07-26T14:29:33.717433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_image = test_df.drop('fold', axis=1)\ntest_image.head()","metadata":{"execution":{"iopub.status.busy":"2021-07-26T13:46:20.281526Z","iopub.execute_input":"2021-07-26T13:46:20.282004Z","iopub.status.idle":"2021-07-26T13:46:20.296305Z","shell.execute_reply.started":"2021-07-26T13:46:20.281964Z","shell.execute_reply":"2021-07-26T13:46:20.295404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_image.to_csv('public_image.csv', index=False)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Classification","metadata":{}},{"cell_type":"code","source":"public = pd.read_csv('../input/covid-public-test/sample_submission.csv')\ntest = pd.read_csv('../input/siim-covid19-detection/sample_submission.csv')\n\n#submit\nif len(test) != 2477:\n    test = pd.concat([test, public]).reset_index(drop=True).drop_duplicates(keep=False).reset_index(drop=True)\n\ntest['type'] = test['id'].apply(lambda x: x[-5:])\ntest_study = test[test['type'] == 'study'].reset_index(drop=True)\ntest_study['study_id'] = test_study['id'].apply(lambda x: x[:-6])\ntest_image = test_image[['id', 'PredictionString']]\ntest_image['image_id'] = test_image['id'].apply(lambda x: x[:-6])\n\ntmp = pd.DataFrame(columns=test_study.columns)\nfor i in tqdm(range(len(test_study))):\n    study_id = test_study.iloc[i, 3]\n    img_paths = glob(f'../input/siim-covid19-detection/test/{study_id}/*/*')\n    if len(img_paths) == 1:\n        img_path = img_paths[0]\n        image_id = img_path.split('/')[-1][:-4]\n        test_study.loc[i, 'image_id'] = image_id\n    else:\n        add_df = pd.concat([test_study.iloc[i:i+1]]*(len(img_paths)-1)).reset_index(drop=True)\n        for j in range(len(img_paths)):\n            if j == 0:\n                img_path = img_paths[j]\n                image_id = img_path.split('/')[-1][:-4]\n                test_study.loc[i, 'image_id'] = image_id\n            else:\n                img_path = img_paths[j]\n                image_id = img_path.split('/')[-1][:-4]\n                add_df.loc[j-1, 'image_id'] = image_id\n        tmp = tmp.append(add_df).reset_index(drop=True)\n        \ntest_study = pd.concat([test_study, tmp]).sort_values('id').reset_index(drop=True)\ntest = test_study.merge(test_image[['PredictionString', 'image_id']], on='image_id')","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:23:10.7452Z","iopub.execute_input":"2021-08-04T01:23:10.745643Z","iopub.status.idle":"2021-08-04T01:23:15.93987Z","shell.execute_reply.started":"2021-08-04T01:23:10.745605Z","shell.execute_reply":"2021-08-04T01:23:15.938894Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:23:17.242529Z","iopub.execute_input":"2021-08-04T01:23:17.242911Z","iopub.status.idle":"2021-08-04T01:23:17.262999Z","shell.execute_reply.started":"2021-08-04T01:23:17.242877Z","shell.execute_reply":"2021-08-04T01:23:17.26191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class COVIDDataset(Dataset):\n    def __init__(self, root, df, transform=None):\n        self.root = root\n        self.df = df\n        self.transform = transform\n    \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, idx):\n        image_id = self.df.iloc[idx, 4]\n        img = cv2.imread(f'{root}/{image_id}.png')\n        \n        if self.transform:  #input shape should be: (sz, sz, 3)\n            img = self.transform(image=img)['image']\n        \n        img = (img/255.0 - mean) / std  #Normalization\n        img = np.transpose(img, (2, 0, 1))  #shape(3, sz, sz)\n        img = torch.from_numpy(img)\n\n        return img","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def inference_fn1(data_loader, model, device):\n    model.eval()    \n    preds1 = []\n    preds2 = []\n    \n    for i, x in tqdm(enumerate(data_loader)):\n        img = x\n        img = img.to(device, dtype=torch.float)\n        \n        with torch.no_grad():\n            pred1, pred2, pred3 = model(img)\n            preds1.append(nn.Softmax()(pred1).detach().cpu().numpy())\n            preds2.append(nn.Sigmoid()(pred2).detach().cpu().numpy())\n            \n        del img, pred1, pred2, pred3\n        gc.collect()\n        \n    predictions1 = np.concatenate(preds1)\n    predictions2 = np.concatenate(preds2).reshape(-1, 1)\n    predictions = np.hstack([predictions1, predictions2])\n    \n    del preds1, preds2, predictions1, predictions2\n    gc.collect()\n    \n    return predictions\n\n\ndef inference_fn2(data_loader, model, device):\n    model.eval()    \n    preds1 = []\n    preds2 = []\n    \n    for i, x in tqdm(enumerate(data_loader)):\n        img = x\n        img = img.to(device, dtype=torch.float)\n        \n        with torch.no_grad():\n            pred1, pred2 = model(img)\n            preds1.append(nn.Softmax()(pred1[:, :4]).detach().cpu().numpy())\n            preds2.append(nn.Sigmoid()(pred1[:, 4]).detach().cpu().numpy())\n            \n        del img, pred1, pred2\n        gc.collect()\n        \n    predictions1 = np.concatenate(preds1)\n    predictions2 = np.concatenate(preds2).reshape(-1, 1)\n    predictions = np.hstack([predictions1, predictions2])\n    \n    del preds1, preds2, predictions1, predictions2\n    gc.collect()\n    \n    return predictions","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_class1 = 4\nnum_class2 = 1\n\nclass Model0(nn.Module):\n    def __init__(self):\n        super(Model0, self).__init__()\n        e = timm_413.create_model(\n            'efficientnet_b3',\n            pretrained=False, \n            drop_rate=0.3, \n            drop_path_rate=0.2\n            )\n        self.b0 = nn.Sequential(\n            e.conv_stem,\n            e.bn1,\n            e.act1\n        )\n        self.b1 = e.blocks[0]\n        self.b2 = e.blocks[1]\n        self.b3 = e.blocks[2]\n        self.b4 = e.blocks[3]\n        self.b5 = e.blocks[4]\n        self.b6 = e.blocks[5]\n        self.b7 = e.blocks[6]\n        self.b8 = nn.Sequential(\n            e.conv_head,\n            e.bn2,\n            e.act2\n        )\n        self.logit1 = nn.Linear(1536, 4)\n        self.logit2 = nn.Sequential(\n            nn.Softmax(),\n            nn.Linear(4, 4),\n            nn.ReLU(),\n            nn.Linear(4, 1)\n        )\n\n        self.mask = nn.Sequential(\n            nn.Conv2d(136, 128, kernel_size=3, padding=1),\n            nn.BatchNorm2d(128),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(128, 128, kernel_size=3, padding=1),\n            nn.BatchNorm2d(128),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(128, 1, kernel_size=1, padding=0)\n        )\n        \n    def forward(self, image):\n        batch_size = len(image)\n        x = 2 * image - 1\n        x = self.b0(x)\n        x = self.b1(x)\n        x = self.b2(x)\n        x = self.b3(x)\n        x = self.b4(x)\n        x = self.b5(x)\n        mask = self.mask(x)\n        x = self.b6(x)\n        x = self.b7(x)\n        x = self.b8(x)\n        x = F.adaptive_avg_pool2d(x, 1).reshape(batch_size, -1)\n        logit1 = self.logit1(x)\n        logit2 = self.logit2(logit1)\n        return logit1, logit2, mask\n\nclass Model1(nn.Module):\n    def __init__(self):\n        super(Model1, self).__init__()\n        #e = timm.create_model('tf_efficientnetv2_l', pretrained=True, in_chans=3)\n        e = Model_Y()\n        #e.load_state_dict(fix_key(torch.load(\"../data/efb3_chex_02_epoch{}_step{}.pth\".format(6,18685))))\n        e = e.model\n\n        self.b0 = nn.Sequential(\n            e.conv_stem,\n            e.bn1,\n            e.act1\n        )\n        self.b1 = e.blocks[0]\n        self.b2 = e.blocks[1]\n        self.b3 = e.blocks[2]\n        self.b4 = e.blocks[3]\n        self.b5 = e.blocks[4]\n        self.b6 = e.blocks[5]\n        self.b7 = e.blocks[6]\n        self.b8 = nn.Sequential(\n            e.conv_head,\n            e.bn2,\n            e.act2\n        )\n        self.logit1 = nn.Linear(1536, num_class1)\n        self.logit2 = nn.Sequential(\n            nn.Softmax(),\n            nn.Linear(num_class1, num_class1),\n            nn.ReLU(),\n            nn.Linear(num_class1, num_class2))\n        self.mask = nn.Sequential(\n            nn.Conv2d(136, 128, kernel_size=3, padding=1),\n            nn.BatchNorm2d(128),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(128, 128, kernel_size=3, padding=1),\n            nn.BatchNorm2d(128),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(128, 1, kernel_size=1, padding=0),\n        )\n\n    def forward(self, image):\n        batch_size = len(image)\n        x = 2 * image - 1\n        x = self.b0(x)\n        x = self.b1(x)\n        x = self.b2(x)\n        x = self.b3(x)\n        x = self.b4(x)\n        x = self.b5(x)\n        mask = self.mask(x)\n        x = self.b6(x)\n        x = self.b7(x)\n        x = self.b8(x)\n        x = F.adaptive_avg_pool2d(x, 1).reshape(batch_size, -1)\n        logit1 = self.logit1(x)\n        logit2 = self.logit2(logit1)\n        return logit1, logit2, mask\n\nclass Model_Y(nn.Module):\n    def __init__(self, out_size=14, pretrained=True):\n        super().__init__()\n        self.model = timm_413.create_model(\n            'efficientnet_b3',\n            pretrained=False, \n            drop_rate=0.3, \n            drop_path_rate=0.2\n            )\n        n_features = self.model.classifier.in_features\n        self.model.classifier = nn.Linear(1536, out_size)\n    def forward(self, x):\n        x = self.model(x)\n        return x\n\n\nclass Model2(nn.Module):\n    def __init__(self):\n        super(Model2, self).__init__()\n        e = timm_413.create_model(\n            'tf_efficientnetv2_l', \n            pretrained=False, \n            in_chans=3\n        )\n        self.b0 = nn.Sequential(\n            e.conv_stem,\n            e.bn1,\n            e.act1\n        )\n        self.b1 = e.blocks[0]\n        self.b2 = e.blocks[1]\n        self.b3 = e.blocks[2]\n        self.b4 = e.blocks[3]\n        self.b5 = e.blocks[4]\n        self.b6 = e.blocks[5]\n        self.b7 = e.blocks[6]\n        self.b8 = nn.Sequential(\n            e.conv_head,\n            e.bn2,\n            e.act2\n        )\n        self.logit = nn.Linear(1280, 5)\n        self.mask = nn.Sequential(\n            nn.Conv2d(224, 128, kernel_size=3, padding=1),\n            nn.BatchNorm2d(128),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(128, 128, kernel_size=3, padding=1),\n            nn.BatchNorm2d(128),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(128, 1, kernel_size=1, padding=0),\n        )\n        \n    def forward(self, image):\n        batch_size = len(image)\n        x = 2 * image - 1\n        x = self.b0(x)\n        x = self.b1(x)\n        x = self.b2(x)\n        x = self.b3(x)\n        x = self.b4(x)\n        x = self.b5(x)\n        mask = self.mask(x)\n        x = self.b6(x)\n        x = self.b7(x)\n        x = self.b8(x)\n        x = F.adaptive_avg_pool2d(x, 1).reshape(batch_size, -1)\n        logit = self.logit(x)\n        \n        return logit, mask\n    \nclass Model_3(nn.Module):\n    def __init__(self):\n        super(Model_3, self).__init__()\n        e = Model_X()\n        e = e.model\n\n        self.b0 = nn.Sequential(\n            e.conv_stem,\n            e.bn1,\n            e.act1\n        )\n        self.b1 = e.blocks[0]\n        self.b2 = e.blocks[1]\n        self.b3 = e.blocks[2]\n        self.b4 = e.blocks[3]\n        self.b5 = e.blocks[4]\n        self.b6 = e.blocks[5]\n        self.b7 = e.blocks[6]\n        self.b8 = nn.Sequential(\n            e.conv_head,\n            e.bn2,\n            e.act2\n        )\n        self.logit1 = nn.Linear(1280, 4)\n        self.logit2 = nn.Sequential(\n            nn.Softmax(),\n            nn.Linear(4, 4),\n            nn.ReLU(),\n            nn.Linear(4, 1))\n        self.mask = nn.Sequential(\n            nn.Conv2d(224, 128, kernel_size=3, padding=1),\n            nn.BatchNorm2d(128),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(128, 128, kernel_size=3, padding=1),\n            nn.BatchNorm2d(128),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(128, 1, kernel_size=1, padding=0),\n        )\n\n    def forward(self, image):\n        batch_size = len(image)\n        x = 2 * image - 1\n        x = self.b0(x)\n        x = self.b1(x)\n        x = self.b2(x)\n        x = self.b3(x)\n        x = self.b4(x)\n        x = self.b5(x)\n        mask = self.mask(x)\n        x = self.b6(x)\n        x = self.b7(x)\n        x = self.b8(x)\n        x = F.adaptive_avg_pool2d(x, 1).reshape(batch_size, -1)\n        logit1 = self.logit1(x)\n        logit2 = self.logit2(logit1)\n        return logit1, logit2, mask\n\nclass Model_X(nn.Module):\n    def __init__(self, out_size=14, model_name=\"tf_efficientnetv2_l\", pretrained=False):\n        super().__init__()\n        self.model = timm_413.create_model(model_name, pretrained=pretrained, in_chans=3)\n        n_features = self.model.classifier.in_features\n        self.model.classifier = nn.Sequential(\n            nn.Linear(n_features, out_size),\n        )\n    def forward(self, x):\n        x = self.model(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2021-08-03T12:04:22.781463Z","iopub.execute_input":"2021-08-03T12:04:22.781871Z","iopub.status.idle":"2021-08-03T12:04:22.865017Z","shell.execute_reply.started":"2021-08-03T12:04:22.781836Z","shell.execute_reply":"2021-08-03T12:04:22.862849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test['Negative'] = 0\ntest['Typical'] = 0\ntest['Indeterminate'] = 0\ntest['Atypical'] = 0\ntest['None'] = 0\ntarget_cols = test.columns[6:].to_list()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"det_inf_per_fold = det_inf_per_fold.rename(columns={'id': 'image_id'})\ndet_inf_per_fold['image_id'] = det_inf_per_fold['image_id'].apply(lambda x: x[:-6])\ndet_inf_per_fold.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_ds = COVIDDataset(root=root, df=test, transform=None)\ntest_dl = DataLoader(dataset=test_ds, batch_size=64, shuffle=False, num_workers=0)\nNFOLDS = 5\nall_predictions = 0\nnum_models = 7\n\nfor i in range(NFOLDS):\n    print(f'==========FOLD{i}==========')\n    predictions = 0\n    \n    model0 = Model0()\n    model0.load_state_dict(torch.load(f'../input/covid-5class-efb3-seg-512-weight-0703-5/0703_5_fold_{i}.pth'))\n    model0.to(device)\n    predictions += inference_fn1(test_dl, model0, device) / (NFOLDS * num_models)\n    del model0\n    gc.collect()\n    \n    model1 = Model1()\n    model1.load_state_dict(torch.load(f'../input/5cls-efb3-seg-512-chex-ep6-18685/model_1_fold_{i}.pth'))\n    model1.to(device)\n    predictions += inference_fn1(test_dl, model1, device) / (NFOLDS * num_models)\n    del model1\n    gc.collect()\n    \n    model2 = Model2()\n    model2.load_state_dict(torch.load(f'../input/covid-5class-efv2l-seg-512-weight-0630-1/0630_1_fold_{i}.pth'))\n    model2.to(device)\n    predictions += inference_fn2(test_dl, model2, device) / (NFOLDS * num_models)\n    del model2\n    gc.collect()\n    \n    model3 = Model_3()\n    model3.load_state_dict(torch.load(f'../input/5cls-efv2l-seg-512-chex-1ep/0630_1_fold_{i}.pth'))\n    model3.to(device)\n    predictions += inference_fn1(test_dl, model3, device) / (NFOLDS * num_models)\n    del model3\n    gc.collect()\n    \n    model4 = Model_3()\n    model4.load_state_dict(torch.load(f'../input/5cls-efv2l-in21k-seg-512-chex-ep6-18685/model_1_fold_{i}.pth'))\n    model4.to(device)\n    predictions += inference_fn1(test_dl, model4, device) / (NFOLDS * num_models)\n    del model4\n    gc.collect()\n    \n    model5 = Model1()\n    model5.load_state_dict(torch.load(f'../input/5cls-efb3-seg-focal-512-chex-ep6-18685/model_1_fold_{i}.pth'))\n    model5.to(device)\n    predictions += inference_fn1(test_dl, model5, device) / (NFOLDS * num_models)\n    del model5\n    gc.collect()\n    \n    from collections import OrderedDict\n    def fix_key(state_dict):\n        new_state_dict = OrderedDict()\n        for k, v in state_dict.items():\n            if k.startswith('module.'):\n                k = k[7:]\n            new_state_dict[k] = v\n        return new_state_dict\n    \n    model6 = Model1()\n    state_dict = torch.load(f'../input/5cls-efb3-seg-512-chex-ep6-18685-bs16/model_1_fold_{i}.pth')\n    state_dict =  fix_key(state_dict)\n    model6.load_state_dict(state_dict)\n    model6.to(device)\n    predictions += inference_fn1(test_dl, model6, device) / (NFOLDS * num_models)\n    del model6\n    gc.collect()\n    \n    #####################################################################\n    #Post-Processing\n    fold = det_inf_per_fold[det_inf_per_fold['fold'] == i].reset_index(drop=True)\n    fold = test.iloc[:, 4:5].merge(fold, on='image_id')\n    for j in tqdm(range(len(fold))):\n        confs = []\n        try:\n            string = fold.loc[j, 'PredictionString'].split(' ')\n            bbox_num = len(string) // 6\n            for b in range(bbox_num):\n                confs.append(float(string[6*b+1]))\n            max_conf = max(confs)\n            predictions[j, 0] *= (1 - max_conf)  #Negative\n            predictions[j, 4] *= (1 - max_conf)  #None\n        except:\n            continue     \n            \n    all_predictions += predictions\n    \ntest[target_cols] = all_predictions","metadata":{"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"nn_mean = test['Negative'] * 0.55 + test['None'] * 0.45\ntest['Negative'] = nn_mean\ntest['None'] = nn_mean\n\nw = 0.025\nfor i in tqdm(range(len(test))):\n    opacity = 1 - test.loc[i, 'None']\n    test.loc[i, 'Typical'] += opacity * w\n    test.loc[i, 'Indeterminate'] += opacity * w\n    test.loc[i, 'Atypical'] += opacity * w","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.head(10)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_image = test[['image_id', 'None', 'PredictionString_y']]\ntest_image = test_image.rename(columns={'image_id': 'id', 'PredictionString_y': 'PredictionString'})\ntest_image['id'] = test_image['id'].apply(lambda x: x + '_image')\n\nfor i in tqdm(range(len(test_image))):\n    none_conf = test_image.iloc[i, 1]\n    test_image.iloc[i, 2] += f' none {none_conf} 0 0 1 1'\n    \ntest_image = test_image.drop('None', axis=1)\ntest_image.head(10)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_study = test.drop(['type', 'study_id', 'image_id', 'PredictionString_x', 'PredictionString_y', 'None'], axis=1)\ntest_study = test_study.groupby('id').mean()\ntest_study['id'] = test_study.index\ntest_study = test_study.reset_index(drop=True).iloc[:, [4, 0, 1, 2, 3]]\ntest_study.head(10)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = [\"negative\", \"typical\", \"indeterminate\", \"atypical\"]\ndictionary = {\"negative\": 'Negative', \"typical\": 'Typical', \"indeterminate\": 'Indeterminate', \"atypical\": 'Atypical'}\ntest_study['PredictionString'] = np.nan\n\nfor i in tqdm(range(len(test_study))):\n    s = ''\n    for label in labels:\n        s += f\"{label} {test_study.loc[i, f'{dictionary[label]}']} 0 0 1 1\" + ' '\n    test_study.loc[i, 'PredictionString'] = s","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_study = test_study[['id', 'PredictionString']]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test = pd.concat([test_study, test_image]).reset_index(drop=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.head(20)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Submission","metadata":{}},{"cell_type":"code","source":"sample = pd.read_csv('../input/siim-covid19-detection/sample_submission.csv')\ntest_dict = dict(zip(test['id'], test['PredictionString']))\nsample['PredictionString'] = sample['id'].map(test_dict)\nsample.to_csv('submission.csv', index=False)","metadata":{},"execution_count":null,"outputs":[]}]}