{"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":"!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,"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-08-09T07:36:32.349119Z","iopub.execute_input":"2021-08-09T07:36:32.349477Z","iopub.status.idle":"2021-08-09T07:37:43.051831Z","shell.execute_reply.started":"2021-08-09T07:36:32.3494Z","shell.execute_reply":"2021-08-09T07:37:43.050833Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# detection\n!pip install --no-deps ../input/siimwbf/ensemble_boxes-1.0.4-py3-none-any.whl\n\n# mmdet install\n!pip install ../input/mmdetectionv2130/src/addict-2.4.0-py3-none-any.whl\n!pip install ../input/mmdetectionv2130/src/yapf-0.31.0-py2.py3-none-any.whl\n!pip install ../input/mmdetectionv2130/src/mmcv_full-1.3.7-cp37-cp37m-manylinux1_x86_64.whl\n!rsync -a ../input/mmdetectionv2130/mmdetection ../\n!pip install ../input/mmdetectionv2130/src/mmpycocotools-12.0.3\n!pip install ../input/pycocotools202/pycocotools-2.0.2-cp37-cp37m-linux_x86_64.whl\n!cd ../mmdetection && pip install -e .\n\n\n!mkdir /workspace\n!rsync -a ../input/siim-mmdet /workspace\n!mv /workspace/siim-mmdet /workspace/customized_mmdetection","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:37:43.055505Z","iopub.execute_input":"2021-08-09T07:37:43.055796Z","iopub.status.idle":"2021-08-09T07:41:12.910886Z","shell.execute_reply.started":"2021-08-09T07:37:43.055766Z","shell.execute_reply":"2021-08-09T07:41:12.909623Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\n\nfrom PIL import Image\nimport pandas as pd\nfrom tqdm.auto import tqdm","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-08-09T07:41:12.916641Z","iopub.execute_input":"2021-08-09T07:41:12.918785Z","iopub.status.idle":"2021-08-09T07:41:12.932889Z","shell.execute_reply.started":"2021-08-09T07:41:12.918742Z","shell.execute_reply":"2021-08-09T07:41:12.932128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv('../input/siim-covid19-detection/sample_submission.csv')\nif df.shape[0] == 2477:\n    is_public = True\n    \n    fast_sub = True\n    if fast_sub:\n        fast_df = pd.DataFrame(([['00086460a852_study', 'negative 1 0 0 1 1'], \n                             ['000c9c05fd14_study', 'negative 1 0 0 1 1'], \n                             ['65761e66de9f_image', 'none 1 0 0 1 1'], \n                             ['51759b5579bc_image', 'none 1 0 0 1 1']]), \n                           columns=['id', 'PredictionString'])\n    \nelse:\n    fast_sub = False\n    is_public = False\n    sub_public = pd.read_csv('/kaggle/input/siim-public/sub145/sub.csv')\n    pub_ids = sub_public[\"id\"].values\n    \n    df = df[~df[\"id\"].isin(pub_ids)].reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:41:12.937759Z","iopub.execute_input":"2021-08-09T07:41:12.938269Z","iopub.status.idle":"2021-08-09T07:41:13.000409Z","shell.execute_reply.started":"2021-08-09T07:41:12.938226Z","shell.execute_reply":"2021-08-09T07:41:12.999513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# .dcm to .png","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\n\ndef read_xray(path, voi_lut = True, fix_monochrome = True):\n    # Original from: https://www.kaggle.com/raddar/convert-dicom-to-np-array-the-correct-way\n    dicom = pydicom.read_file(path)\n    \n    # VOI LUT (if available by DICOM device) is used to transform raw DICOM data to \n    # \"human-friendly\" view\n    if voi_lut:\n        data = apply_voi_lut(dicom.pixel_array, dicom)\n    else:\n        data = dicom.pixel_array\n               \n    # depending on this value, X-ray may look inverted - fix that:\n    if fix_monochrome and dicom.PhotometricInterpretation == \"MONOCHROME1\":\n        data = np.amax(data) - data\n        \n    data = data - np.min(data)\n    data = data / np.max(data)\n    data = (data * 255).astype(np.uint8)\n        \n    return data","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:41:13.001795Z","iopub.execute_input":"2021-08-09T07:41:13.002169Z","iopub.status.idle":"2021-08-09T07:41:13.164992Z","shell.execute_reply.started":"2021-08-09T07:41:13.002128Z","shell.execute_reply":"2021-08-09T07:41:13.164173Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def resize(array, size, keep_ratio=False, resample=Image.LANCZOS):\n    # Original from: https://www.kaggle.com/xhlulu/vinbigdata-process-and-resize-to-image\n    im = Image.fromarray(array)\n    \n    if keep_ratio:\n        im.thumbnail((size, size), resample)\n    else:\n        im = im.resize((size, size), resample)\n    \n    return im","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:41:13.166312Z","iopub.execute_input":"2021-08-09T07:41:13.166649Z","iopub.status.idle":"2021-08-09T07:41:13.171517Z","shell.execute_reply.started":"2021-08-09T07:41:13.166611Z","shell.execute_reply":"2021-08-09T07:41:13.170757Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"split = 'test'\nsave_dir = f'/kaggle/tmp/{split}/'","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:41:13.172743Z","iopub.execute_input":"2021-08-09T07:41:13.173187Z","iopub.status.idle":"2021-08-09T07:41:13.181922Z","shell.execute_reply.started":"2021-08-09T07:41:13.173149Z","shell.execute_reply":"2021-08-09T07:41:13.18114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_id = []\ndim0 = []\ndim1 = []\nsplits = []\n\n# image to study dict, key image_id: item study_id\ndict_image2study = {}\n\nimg_size = 640\n\nsave_dir = f'/kaggle/tmp/{split}/image/'\nos.makedirs(save_dir, exist_ok=True)\nif fast_sub:\n    xray = read_xray('../input/siim-covid19-detection/train/00086460a852/9e8302230c91/65761e66de9f.dcm')\n    im = resize(xray, size=img_size)  \n    im.save(os.path.join(save_dir,'65761e66de9f_image.png'))\n    image_id.append('65761e66de9f.dcm'.replace('.dcm', ''))\n    dim0.append(xray.shape[0])\n    dim1.append(xray.shape[1])\n    splits.append(split)\n    dict_image2study['65761e66de9f_image'] = '00086460a852' + '_study'\n    \n    xray = read_xray('../input/siim-covid19-detection/train/000c9c05fd14/e555410bd2cd/51759b5579bc.dcm')\n    im = resize(xray, size=img_size)  \n    im.save(os.path.join(save_dir, '51759b5579bc_image.png'))\n    image_id.append('51759b5579bc.dcm'.replace('.dcm', ''))\n    dim0.append(xray.shape[0])\n    dim1.append(xray.shape[1])\n    splits.append(split)\n    dict_image2study['51759b5579bc_image'] = '000c9c05fd14' + '_study'\nelse:\n    for dirname, _, filenames in tqdm(os.walk(f'../input/siim-covid19-detection/{split}')):\n        for file in filenames:\n            # set keep_ratio=True to have original aspect ratio\n            xray = read_xray(os.path.join(dirname, file))\n            im = resize(xray, size=img_size)  \n            im.save(os.path.join(save_dir, file.replace('.dcm', '_image.png')))\n            image_id.append(file.replace('.dcm', ''))\n            dim0.append(xray.shape[0])\n            dim1.append(xray.shape[1])\n            splits.append(split)\n            dict_image2study[file.replace('.dcm', '_image')] = dirname.split('/')[-2] + '_study'\nmeta = pd.DataFrame.from_dict({'image_id': image_id, 'dim0': dim0, 'dim1': dim1, 'split': splits})","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:41:13.186204Z","iopub.execute_input":"2021-08-09T07:41:13.186542Z","iopub.status.idle":"2021-08-09T07:41:14.135034Z","shell.execute_reply.started":"2021-08-09T07:41:13.186509Z","shell.execute_reply":"2021-08-09T07:41:14.134037Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# study predict","metadata":{}},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd\nif fast_sub:\n    df = fast_df.copy()\nelse:\n    df = pd.read_csv('../input/siim-covid19-detection/sample_submission.csv')\n    if is_public == False:\n        df = df[~df[\"id\"].isin(pub_ids)].reset_index(drop=True)\nid_laststr_list  = []\nfor i in range(df.shape[0]):\n    id_laststr_list.append(df.loc[i,'id'][-1])\ndf['id_last_str'] = id_laststr_list\n\nstudy_len = df[df['id_last_str'] == 'y'].shape[0]","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:41:14.137042Z","iopub.execute_input":"2021-08-09T07:41:14.137366Z","iopub.status.idle":"2021-08-09T07:41:14.15537Z","shell.execute_reply.started":"2021-08-09T07:41:14.137336Z","shell.execute_reply":"2021-08-09T07:41:14.154262Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install /kaggle/input/siim-rsna-library/timm/timm-0.4.9-py3-none-any.whl -q\nimport timm\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport random\nimport torch\nimport torch.nn.functional as F\nfrom torch import nn, optim\nfrom torch.utils.data import DataLoader, Dataset\nimport cv2\n\nimport albumentations\nfrom albumentations.pytorch import ToTensorV2","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:41:14.157365Z","iopub.execute_input":"2021-08-09T07:41:14.158509Z","iopub.status.idle":"2021-08-09T07:41:43.282069Z","shell.execute_reply.started":"2021-08-09T07:41:14.158468Z","shell.execute_reply":"2021-08-09T07:41:43.281217Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 8\nNTHREAD = 2\n\ndevice = \"cuda:0\" if torch.cuda.is_available() else \"cpu\"\nprint(device)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:41:43.28343Z","iopub.execute_input":"2021-08-09T07:41:43.283845Z","iopub.status.idle":"2021-08-09T07:41:43.311207Z","shell.execute_reply.started":"2021-08-09T07:41:43.283795Z","shell.execute_reply":"2021-08-09T07:41:43.310427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ==========================================================\n# Model\n# ==========================================================\n\nclass Net414(nn.Module):\n    def __init__(self, name=\"resnest101e\"):\n        super(Net414, self).__init__()\n        enet = timm.create_model(name, False, drop_path_rate=0.2)\n        self.b0 = nn.Sequential(\n            enet.conv_stem,\n            enet.bn1,\n            enet.act1,\n        )\n        self.b1 = enet.blocks[0]\n        self.b2 = enet.blocks[1]\n        self.b3 = enet.blocks[2]\n        self.b4 = enet.blocks[3]\n        self.b5 = enet.blocks[4]\n        self.b6 = enet.blocks[5]\n        self.b7 = enet.blocks[6]\n\n        self.after_blocks = nn.Sequential(\n            enet.conv_head,\n            enet.bn2,\n            enet.act2\n        )\n\n        self.global_pool = enet.global_pool\n        self.dropout = nn.Dropout(0.5)\n        self.myfc = nn.Linear(enet.classifier.in_features, 5)\n        # self.enet.classifier = nn.Identity()\n\n        # ===============================\n        # Mask netfork after b5\n        # ===============================\n        self.mask = nn.Sequential(\n            # nn.Conv2d(176, 128, kernel_size=3, padding=1),\n            nn.Conv2d(304, 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\n    def forward(self, x, is_mask=False):\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        x = self.b6(x)\n        # =================================\n        # Mask net\n        # =================================\n        mask = self.mask(x)\n\n        x = self.b7(x)\n\n        x = self.after_blocks(x)\n        x = self.global_pool(x)\n        h = self.myfc(self.dropout(x))\n        if is_mask:\n            return h, mask\n        else:\n            return h\n\n\nclass Net415(nn.Module):\n    def __init__(self, name=\"resnest101e\"):\n        super(Net415, self).__init__()\n        enet = timm.create_model(name, False, drop_path_rate=0.2)\n        self.b0 = nn.Sequential(\n            enet.conv_stem,\n            enet.bn1,\n            enet.act1,\n        )\n        self.b1 = enet.blocks[0]\n        self.b2 = enet.blocks[1]\n        self.b3 = enet.blocks[2]\n        self.b4 = enet.blocks[3]\n        self.b5 = enet.blocks[4]\n        self.b6 = enet.blocks[5]\n        self.b7 = enet.blocks[6]\n\n        self.after_blocks = nn.Sequential(\n            enet.conv_head,\n            enet.bn2,\n            enet.act2\n        )\n\n        self.global_pool = enet.global_pool\n        self.dropout = nn.Dropout(0.5)\n        self.myfc = nn.Linear(enet.classifier.in_features, 5)\n        # self.enet.classifier = nn.Identity()\n\n        # ===============================\n        # Mask netfork after b5\n        # ===============================\n        self.mask = nn.Sequential(\n            # nn.Conv2d(176, 128, kernel_size=3, padding=1),\n            nn.Conv2d(512, 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\n    def forward(self, x, is_mask=False):\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        x = self.b6(x)\n        x = self.b7(x)\n        \n        # =================================\n        # Mask net\n        # =================================\n        mask = self.mask(x)\n\n        x = self.after_blocks(x)\n        x = self.global_pool(x)\n        h = self.myfc(self.dropout(x))\n        if is_mask:\n            return h, mask\n        else:\n            return h\n\n\n\nclass Net416(nn.Module):\n    def __init__(self, name=\"resnest101e\"):\n        super(Net416, self).__init__()\n        enet = timm.create_model(name, False, drop_path_rate=0.2)\n        self.b0 = nn.Sequential(\n            enet.conv_stem,\n            enet.bn1,\n            enet.act1,\n        )\n        self.b1 = enet.blocks[0]\n        self.b2 = enet.blocks[1]\n        self.b3 = enet.blocks[2]\n        self.b4 = enet.blocks[3]\n        self.b5 = enet.blocks[4]\n        self.b6 = enet.blocks[5]\n        self.b7 = enet.blocks[6]\n\n        self.after_blocks = nn.Sequential(\n            enet.conv_head,\n            enet.bn2,\n            enet.act2\n        )\n\n        self.global_pool = enet.global_pool\n        self.dropout = nn.Dropout(0.5)\n        self.myfc = nn.Linear(enet.classifier.in_features, 5)\n        # self.enet.classifier = nn.Identity()\n\n        # ===============================\n        # Mask netfork\n        # ===============================\n        self.mask6 = nn.Sequential(\n            # nn.Conv2d(176, 128, kernel_size=3, padding=1),\n            nn.Conv2d(304, 128, kernel_size=3, padding=1),\n            # nn.Conv2d(512, 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        self.mask7 = nn.Sequential(\n            # nn.Conv2d(176, 128, kernel_size=3, padding=1),\n            # nn.Conv2d(304, 128, kernel_size=3, padding=1),\n            nn.Conv2d(512, 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\n    def forward(self, x, is_mask=False):\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        x = self.b6(x)\n        # =================================\n        # Mask net\n        # =================================\n        mask6 = self.mask6(x)\n\n        x = self.b7(x)\n        # =================================\n        # Mask net\n        # =================================\n        mask7 = self.mask7(x)\n\n        x = self.after_blocks(x)\n        x = self.global_pool(x)\n        h = self.myfc(self.dropout(x))\n        if is_mask:\n            return h, mask6, mask7\n        else:\n            return h\n\n\n\nclass Net417(nn.Module):\n    def __init__(self, name=\"resnest101e\"):\n        super(Net417, self).__init__()\n        enet = timm.create_model(name, False, drop_path_rate=0.2)\n        self.b0 = nn.Sequential(\n            enet.conv_stem,\n            enet.bn1,\n            enet.act1,\n        )\n        self.b1 = enet.blocks[0]\n        self.b2 = enet.blocks[1]\n        self.b3 = enet.blocks[2]\n        self.b4 = enet.blocks[3]\n        self.b5 = enet.blocks[4]\n        self.b6 = enet.blocks[5]\n        self.b7 = enet.blocks[6]\n\n        self.after_blocks = nn.Sequential(\n            enet.conv_head,\n            enet.bn2,\n            enet.act2\n        )\n\n        self.global_pool = enet.global_pool\n        self.dropout = nn.Dropout(0.5)\n        self.myfc = nn.Linear(enet.classifier.in_features, 5)\n        # self.enet.classifier = nn.Identity()\n\n        # ===============================\n        # Mask netfork\n        # ===============================\n        self.mask5 = nn.Sequential(\n            nn.Conv2d(176, 128, kernel_size=3, padding=1),\n            # nn.Conv2d(304, 128, kernel_size=3, padding=1),\n            # nn.Conv2d(512, 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        self.mask6 = nn.Sequential(\n            # nn.Conv2d(176, 128, kernel_size=3, padding=1),\n            nn.Conv2d(304, 128, kernel_size=3, padding=1),\n            # nn.Conv2d(512, 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        self.mask7 = nn.Sequential(\n            # nn.Conv2d(176, 128, kernel_size=3, padding=1),\n            # nn.Conv2d(304, 128, kernel_size=3, padding=1),\n            nn.Conv2d(512, 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\n    def forward(self, x, is_mask=False):\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        # =================================\n        # Mask net\n        # =================================\n        mask5 = self.mask5(x)\n\n        x = self.b6(x)\n        # =================================\n        # Mask net\n        # =================================\n        mask6 = self.mask6(x)\n\n        x = self.b7(x)\n        # =================================\n        # Mask net\n        # =================================\n        mask7 = self.mask7(x)\n\n        x = self.after_blocks(x)\n        x = self.global_pool(x)\n        h = self.myfc(self.dropout(x))\n        if is_mask:\n            return h, mask5, mask6, mask7\n        else:\n            return h\n\n\n\n\n\n\n\n\n        \nclass Net418(nn.Module):\n    def __init__(self, name=\"resnest101e\"):\n        super(Net418, self).__init__()\n        enet = timm.create_model(name, False, drop_path_rate=0.2)\n        self.b0 = nn.Sequential(\n            enet.conv_stem,\n            enet.bn1,\n            enet.act1,\n        )\n        self.b1 = enet.blocks[0]\n        self.b2 = enet.blocks[1]\n        self.b3 = enet.blocks[2]\n        self.b4 = enet.blocks[3]\n        self.b5 = enet.blocks[4]\n        self.b6 = enet.blocks[5]\n        self.b7 = enet.blocks[6]\n\n        self.after_blocks = nn.Sequential(\n            enet.conv_head,\n            enet.bn2,\n            enet.act2\n        )\n\n        self.global_pool = enet.global_pool\n        self.dropout = nn.Dropout(0.5)\n        self.myfc = nn.Linear(enet.classifier.in_features, 5)\n        # self.enet.classifier = nn.Identity()\n\n        # ===============================\n        # Mask netfork\n        # ===============================\n        self.mask = nn.Sequential(\n            # nn.Conv2d(176, 128, kernel_size=3, padding=1),\n            # nn.Conv2d(304, 128, kernel_size=3, padding=1),\n            nn.Conv2d(384, 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\n    def forward(self, x, is_mask=False):\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        x = self.b6(x)\n        # =================================\n        # Mask net\n        # =================================\n        mask = self.mask(x)\n        \n        x = self.b7(x)\n\n        x = self.after_blocks(x)\n        x = self.global_pool(x)\n        h = self.myfc(self.dropout(x))\n        if is_mask:\n            return h, mask\n        else:\n            return h\n\n\nclass Net419(nn.Module):\n    def __init__(self, name=\"resnest101e\"):\n        super(Net419, self).__init__()\n        enet = timm.create_model(name, False, drop_path_rate=0.2)\n        self.b0 = nn.Sequential(\n            enet.conv_stem,\n            enet.bn1,\n            enet.act1,\n        )\n        self.b1 = enet.blocks[0]\n        self.b2 = enet.blocks[1]\n        self.b3 = enet.blocks[2]\n        self.b4 = enet.blocks[3]\n        self.b5 = enet.blocks[4]\n        self.b6 = enet.blocks[5]\n        self.b7 = enet.blocks[6]\n\n        self.after_blocks = nn.Sequential(\n            enet.conv_head,\n            enet.bn2,\n            enet.act2\n        )\n\n        self.global_pool = enet.global_pool\n        self.dropout = nn.Dropout(0.5)\n        self.myfc = nn.Linear(enet.classifier.in_features, 5)\n        # self.enet.classifier = nn.Identity()\n\n        # ===============================\n        # Mask netfork\n        # ===============================\n        self.mask = nn.Sequential(\n            # nn.Conv2d(176, 128, kernel_size=3, padding=1),\n            # nn.Conv2d(304, 128, kernel_size=3, padding=1),\n            nn.Conv2d(640, 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\n    def forward(self, x, is_mask=False):\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        x = self.b6(x)\n        x = self.b7(x)\n        # =================================\n        # Mask net\n        # =================================\n        mask = self.mask(x)\n\n        x = self.after_blocks(x)\n        x = self.global_pool(x)\n        h = self.myfc(self.dropout(x))\n        if is_mask:\n            return h, mask\n        else:\n            return h\n        \n\n\nclass Net420(nn.Module):\n    def __init__(self, name=\"resnest101e\"):\n        super(Net420, self).__init__()\n        enet = timm.create_model(name, False, drop_path_rate=0.2)\n        self.b0 = nn.Sequential(\n            enet.conv_stem,\n            enet.bn1,\n            enet.act1,\n        )\n        self.b1 = enet.blocks[0]\n        self.b2 = enet.blocks[1]\n        self.b3 = enet.blocks[2]\n        self.b4 = enet.blocks[3]\n        self.b5 = enet.blocks[4]\n        self.b6 = enet.blocks[5]\n        self.b7 = enet.blocks[6]\n\n        self.after_blocks = nn.Sequential(\n            enet.conv_head,\n            enet.bn2,\n            enet.act2\n        )\n\n        self.global_pool = enet.global_pool\n        self.dropout = nn.Dropout(0.5)\n        self.myfc = nn.Linear(enet.classifier.in_features, 5)\n        # self.enet.classifier = nn.Identity()\n\n        # ===============================\n        # Mask netfork\n        # ===============================\n        self.mask6 = nn.Sequential(\n            # nn.Conv2d(176, 128, kernel_size=3, padding=1),\n            nn.Conv2d(384, 128, kernel_size=3, padding=1),\n            # nn.Conv2d(512, 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        self.mask7 = nn.Sequential(\n            # nn.Conv2d(176, 128, kernel_size=3, padding=1),\n            # nn.Conv2d(304, 128, kernel_size=3, padding=1),\n            nn.Conv2d(640, 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\n    def forward(self, x, is_mask=False):\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        x = self.b6(x)\n        # =================================\n        # Mask net\n        # =================================\n        mask6 = self.mask6(x)\n\n        x = self.b7(x)\n        # =================================\n        # Mask net\n        # =================================\n        mask7 = self.mask7(x)\n\n        x = self.after_blocks(x)\n        x = self.global_pool(x)\n        h = self.myfc(self.dropout(x))\n        if is_mask:\n            return h, mask6, mask7\n        else:\n            return h\n        \n        \n\nclass Net553(nn.Module):\n    def __init__(self, name=\"resnest101e\"):\n        super(Net553, self).__init__()\n        enet = timm.create_model(name, False, drop_path_rate=0.2)\n        self.b0 = nn.Sequential(\n            enet.conv_stem,\n            enet.bn1,\n            enet.act1,\n        )\n        self.b1 = enet.blocks[0]\n        self.b2 = enet.blocks[1]\n        self.b3 = enet.blocks[2]\n        self.b4 = enet.blocks[3]\n        self.b5 = enet.blocks[4]\n        self.b6 = enet.blocks[5]\n        self.b7 = enet.blocks[6]\n\n        self.after_blocks = nn.Sequential(\n            enet.conv_head,\n            enet.bn2,\n            enet.act2\n        )\n\n        self.global_pool = enet.global_pool\n        self.dropout = nn.Dropout(0.5)\n        self.myfc = nn.Linear(enet.classifier.in_features, 5)\n        # self.enet.classifier = nn.Identity()\n\n        # ===============================\n        # Mask netfork after b5\n        # ===============================\n        self.mask1 = nn.Sequential(\n            # nn.Conv2d(176, 128, kernel_size=3, padding=1),\n            # nn.Conv2d(304, 128, kernel_size=3, padding=1),\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        self.mask2 = nn.Sequential(\n            # nn.Conv2d(176, 128, kernel_size=3, padding=1),\n            # nn.Conv2d(304, 128, kernel_size=3, padding=1),\n            nn.Conv2d(384, 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        self.mask3 = nn.Sequential(\n            # nn.Conv2d(176, 128, kernel_size=3, padding=1),\n            # nn.Conv2d(304, 128, kernel_size=3, padding=1),\n            nn.Conv2d(640, 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\n    def forward(self, x, is_mask=False):\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        # =================================\n        # Mask net\n        # =================================\n        mask1 = self.mask1(x)\n\n        x = self.b6(x)\n        # =================================\n        # Mask net\n        # =================================\n        mask2 = self.mask2(x)\n\n        x = self.b7(x)\n        # =================================\n        # Mask net\n        # =================================\n        mask3 = self.mask3(x)\n\n        x = self.after_blocks(x)\n        x = self.global_pool(x)\n        h = self.myfc(self.dropout(x))\n        if is_mask:\n            return h, mask1, mask2, mask3\n        else:\n            return h\n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n\n\nclass Net604(nn.Module):\n    def __init__(self, name=\"resnest101e\"):\n        super(Net604, self).__init__()\n        swin = timm.create_model(name, False)\n\n        self.patch_embed = swin.patch_embed\n        self.pos_drop = swin.pos_drop\n        self.b0 = swin.layers[0]\n        self.b1 = swin.layers[1]\n        self.b2 = swin.layers[2]\n        self.b3 = swin.layers[3]\n        self.norm = swin.norm\n\n        self.global_pool = swin.avgpool\n        self.dropout = nn.Dropout(0.5)\n        self.myfc = nn.Linear(swin.head.in_features, 5)\n        # self.enet.classifier = nn.Identity()\n\n        # ===============================\n        # Mask netfork after layer16\n        # ===============================\n        self.mask = nn.Sequential(\n            nn.Conv2d(64, 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\n    def forward(self, x, is_mask=False):\n        x = self.patch_embed(x)\n        x = self.pos_drop(x)\n        x = self.b0(x)\n        x = self.b1(x)\n        x = self.b2(x)\n        x = self.b3(x)\n        x = self.norm(x)\n        # =================================\n        # Mask net\n        # =================================\n        # [bs, 144, 1024] -> [bs, 64, 48, 48]\n        bs = x.shape[0]\n        x_to_mask = x.view(bs, 12, 12, 4, 4, -1).view(bs, 48, 48, 64).permute(0, 3, 1, 2)\n        mask = self.mask(x_to_mask)\n        \n        x = self.global_pool(x.permute(0, 2, 1)).view(bs, -1)\n        h = self.myfc(self.dropout(x))\n        if is_mask:\n            return h, mask\n        else:\n            return h\n        \n\n\nclass Net605(nn.Module):\n    def __init__(self, name=\"resnest101e\"):\n        super(Net605, self).__init__()\n        swin = timm.create_model(name, False)\n\n        self.patch_embed = swin.patch_embed\n        self.pos_drop = swin.pos_drop\n        self.b0 = swin.layers[0]\n        self.b1 = swin.layers[1]\n        self.b2 = swin.layers[2]\n        self.b3 = swin.layers[3]\n        self.norm = swin.norm\n\n        self.global_pool = swin.avgpool\n        self.dropout = nn.Dropout(0.5)\n        self.myfc = nn.Linear(swin.head.in_features, 5)\n        # self.enet.classifier = nn.Identity()\n\n        # ===============================\n        # Mask netfork after layer16\n        # ===============================\n        self.mask = nn.Sequential(\n            nn.Conv2d(64, 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\n    def forward(self, x, is_mask=False):\n        x = self.patch_embed(x)\n        x = self.pos_drop(x)\n        x = self.b0(x)\n        x = self.b1(x)\n        x = self.b2(x)\n        # =================================\n        # Mask net\n        # =================================\n        # [bs, 144, 1024] -> [bs, 64, 48, 48]\n        bs = x.shape[0]\n        x_to_mask = x.view(bs, 12, 12, 4, 4, -1).view(bs, 48, 48, 64).permute(0, 3, 1, 2)\n        mask = self.mask(x_to_mask)\n\n        x = self.b3(x)\n        x = self.norm(x)\n        \n        x = self.global_pool(x.permute(0, 2, 1)).view(bs, -1)\n        h = self.myfc(self.dropout(x))\n        if is_mask:\n            return h, mask\n        else:\n            return h\n\n\n\n\nclass Net606(nn.Module):\n    def __init__(self, name=\"resnest101e\"):\n        super(Net606, self).__init__()\n        swin = timm.create_model(name, False)\n\n        self.patch_embed = swin.patch_embed\n        self.pos_drop = swin.pos_drop\n        self.b0 = swin.layers[0]\n        self.b1 = swin.layers[1]\n        self.b2 = swin.layers[2]\n        self.b3 = swin.layers[3]\n        self.norm = swin.norm\n\n        self.global_pool = swin.avgpool\n        self.dropout = nn.Dropout(0.5)\n        self.myfc = nn.Linear(swin.head.in_features, 5)\n        # self.enet.classifier = nn.Identity()\n\n        # ===============================\n        # Mask netfork after layer16\n        # ===============================\n        self.mask1 = nn.Sequential(\n            nn.Conv2d(64, 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        self.mask2 = nn.Sequential(\n            nn.Conv2d(64, 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\n    def forward(self, x, is_mask=False):\n        x = self.patch_embed(x)\n        x = self.pos_drop(x)\n        x = self.b0(x)\n        x = self.b1(x)\n        x = self.b2(x)\n        # =================================\n        # Mask net\n        # =================================\n        # [bs, 144, 1024] -> [bs, 64, 48, 48]\n        bs = x.shape[0]\n        x_to_mask = x.view(bs, 12, 12, 4, 4, -1).view(bs, 48, 48, 64).permute(0, 3, 1, 2)\n        mask1 = self.mask1(x_to_mask)\n\n        x = self.b3(x)\n        x = self.norm(x)\n\n        # =================================\n        # Mask net\n        # =================================\n        # [bs, 144, 1024] -> [bs, 64, 48, 48]\n        bs = x.shape[0]\n        x_to_mask = x.view(bs, 12, 12, 4, 4, -1).view(bs, 48, 48, 64).permute(0, 3, 1, 2)\n        mask2 = self.mask2(x_to_mask)\n        \n        x = self.global_pool(x.permute(0, 2, 1)).view(bs, -1)\n        h = self.myfc(self.dropout(x))\n        if is_mask:\n            return h, mask1, mask2\n        else:\n            return h","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:41:43.31333Z","iopub.execute_input":"2021-08-09T07:41:43.313747Z","iopub.status.idle":"2021-08-09T07:41:43.426981Z","shell.execute_reply.started":"2021-08-09T07:41:43.313669Z","shell.execute_reply":"2021-08-09T07:41:43.426091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ==========================================================\n# Dataset\n# ==========================================================\n\nclass CustomDataset(Dataset):\n    def __init__(self,\n                 df,\n                 image_size_list,\n                 mode=\"train\",\n                 clahe=False,\n                 mix=False,\n                 use_npy=True,\n                 ):\n\n        self.df = df.reset_index(drop=True)\n        self.image_size_list = image_size_list\n        self.transform = [albumentations.Compose([\n                                albumentations.Resize(i_s, i_s),\n                                ToTensorV2(p=1)\n                        ]) for i_s in image_size_list]\n\n        self.mode = mode\n        self.clahe = clahe\n        self.mix = mix\n        if self.clahe or self.mix:\n            self.clahe_transform = cv2.createCLAHE(clipLimit=10.0, tileGridSize=(16, 16))\n\n        self.cols = target_columns\n        self.use_npy = use_npy\n\n    def __len__(self):\n        return self.df.shape[0]\n\n    def __getitem__(self, index):\n        row = self.df.iloc[index]\n\n        if self.use_npy:\n            # images = np.load(row.npy_path)\n            images = cv2.imread(row)\n        else:\n            images = pydicom.read_file(row.dicom_path).pixel_array\n\n        if self.clahe:\n            single_channel = images[:, :, 0].astype(np.uint8)\n            single_channel = self.clahe_transform.apply(single_channel)\n            images = np.array([\n                single_channel,\n                single_channel,\n                single_channel\n            ]).transpose(1, 2, 0)\n        elif self.mix:\n            single_channel = images[:, :, 0].astype(np.uint8)\n            clahe_channel = self.clahe_transform.apply(single_channel)\n            hist_channel = cv2.equalizeHist(single_channel)\n            images = np.array([\n                single_channel,\n                clahe_channel,\n                hist_channel\n            ]).transpose(1, 2, 0)\n\n        return_dict = {}\n        for n_tf, i_s in enumerate(self.image_size_list):\n            return_dict[i_s] = self.transform[n_tf](image=images)['image'] / 255\n        return return_dict","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:41:43.428482Z","iopub.execute_input":"2021-08-09T07:41:43.428995Z","iopub.status.idle":"2021-08-09T07:41:43.442521Z","shell.execute_reply.started":"2021-08-09T07:41:43.428955Z","shell.execute_reply":"2021-08-09T07:41:43.441691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"study_sub_list = [\n\n\n    # prediction set\n    [\n        # backbone\n        Net414(\"tf_efficientnetv2_m_in21k\"),\n        \"tf_efficientnetv2_m_in21k\",\n        # img_size\n        512,\n        # weight list\n        [\n            \"/kaggle/input/weight-siim-rsna-v1/exp414/cv0_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v1/exp414/cv1_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v1/exp414/cv2_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v1/exp414/cv3_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v1/exp414/cv4_weight_checkpoint_best.pth\",\n        ],\n    ],\n\n#     # prediction set\n#     [\n#         # backbone\n#         Net415(\"tf_efficientnetv2_m_in21k\"),\n#         \"tf_efficientnetv2_m_in21k\",\n#         # img_size\n#         512,\n#         # weight list\n#         [\n#             \"/kaggle/input/weight-siim-rsna-v2/exp415/cv0_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp415/cv1_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp415/cv2_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp415/cv3_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp415/cv4_weight_checkpoint_best.pth\",\n#         ],\n#     ],\n\n#     # prediction set\n#     [\n#         # backbone\n#         Net416(\"tf_efficientnetv2_m_in21k\"),\n#         \"tf_efficientnetv2_m_in21k\",\n#         # img_size\n#         512,\n#         # weight list\n#         [\n#             \"/kaggle/input/weight-siim-rsna-v2/exp416/cv0_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp416/cv1_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp416/cv2_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp416/cv3_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp416/cv4_weight_checkpoint_best.pth\",\n#         ],\n#     ],\n\n    # prediction set\n    [\n        # backbone\n        Net417(\"tf_efficientnetv2_m_in21k\"),\n        \"tf_efficientnetv2_m_in21k\",\n        # img_size\n        512,\n        # weight list\n        [\n            \"/kaggle/input/weight-siim-rsna-v2/exp417/cv0_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v2/exp417/cv1_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v2/exp417/cv2_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v2/exp417/cv3_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v2/exp417/cv4_weight_checkpoint_best.pth\",\n        ],\n    ],\n\n\n\n    # ===========================================\n    # Eff v2 L\n    # ===========================================\n\n\n#     # prediction set\n#     [\n#         # backbone\n#         Net419(\"tf_efficientnetv2_l_in21k\"),\n#         \"tf_efficientnetv2_l_in21k\",\n#         # img_size\n#         512,\n#         # weight list\n#         [\n#             \"/kaggle/input/weight-siim-rsna-v2/exp419/cv0_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp419/cv1_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp419/cv2_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp419/cv3_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp419/cv4_weight_checkpoint_best.pth\",\n#         ],\n#     ],\n\n#     # prediction set\n#     [\n#         # backbone\n#         Net420(\"tf_efficientnetv2_l_in21k\"),\n#         \"tf_efficientnetv2_l_in21k\",\n#         # img_size\n#         512,\n#         # weight list\n#         [\n#             \"/kaggle/input/weight-siim-rsna-v2/exp420/cv0_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp420/cv1_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp420/cv2_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp420/cv3_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp420/cv4_weight_checkpoint_best.pth\",\n#         ],\n#     ],\n\n    # prediction set\n    [\n        # backbone\n        Net420(\"tf_efficientnetv2_l_in21k\"),\n        \"tf_efficientnetv2_l_in21k\",\n        # img_size\n        512,\n        # weight list\n        [\n            \"/kaggle/input/weight-siim-rsna-v3/exp520/cv0_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp520/cv1_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp520/cv2_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp520/cv3_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp520/cv4_weight_checkpoint_best.pth\",\n        ],\n    ],\n\n\n]","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:41:43.444213Z","iopub.execute_input":"2021-08-09T07:41:43.444595Z","iopub.status.idle":"2021-08-09T07:41:48.894758Z","shell.execute_reply.started":"2021-08-09T07:41:43.444559Z","shell.execute_reply":"2021-08-09T07:41:48.893891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# =============================================================================\n# predict def\n# =============================================================================\ndef predict(model_dict, test_loader, hflip=True, scale=False, scale_hflip=False):\n    pred_list1 = []\n    with torch.no_grad():\n        for images_all in tqdm(test_loader):\n\n            # each model\n            pred_list2 = []\n            for img_size, model_list in model_dict.items():\n                images = images_all[img_size].to(device)\n                bs = images.shape[0]\n                \n                for model in model_list:\n                    preds = model(images).cpu().detach()               \n                    pred_list2.append(preds.sigmoid())\n                \n                if hflip:\n                    for model in model_list:\n                        preds = model(images.flip(-1)).cpu().detach()\n                        pred_list2.append(preds.sigmoid())\n                        \n                if scale:\n                    for model in model_list:\n                        preds = model(F.interpolate(images, scale_factor=1.33, mode='bilinear', align_corners=False)).cpu().detach()\n                        pred_list2.append(preds.sigmoid())\n                        \n                if scale_hflip:\n                    for model in model_list:\n                        preds = model(F.interpolate(images.flip(-1), scale_factor=1.33, mode='bilinear', align_corners=False)).cpu().detach()\n                        pred_list2.append(preds.sigmoid())\n\n                    \n            # average prediction\n            pred_list1.append(torch.stack(pred_list2, 0).mean(0))\n\n        preds = torch.cat(pred_list1).numpy()\n    # torch.cuda.empty_cache()\n    return preds","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:41:48.896073Z","iopub.execute_input":"2021-08-09T07:41:48.896451Z","iopub.status.idle":"2021-08-09T07:41:48.907601Z","shell.execute_reply.started":"2021-08-09T07:41:48.896414Z","shell.execute_reply":"2021-08-09T07:41:48.906646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from copy import deepcopy\n\n# key: image size, value: model\nmodel_dict = {}\n\nimage_size_list = []\n\nfor model_set in tqdm(study_sub_list):\n    # 画像サイズをkey, modelのリストをvalueにする\n    # keyがまだない場合はからのリストを登録\n    model_dict.setdefault(model_set[2], [])\n    model_list = []\n    for ckpt in tqdm(model_set[3]):\n        model = model_set[0].to(device)\n        weight = torch.load(ckpt, map_location=device)\n        model.load_state_dict(weight[\"state_dict\"])\n        model.eval()\n        model_list.append(deepcopy(model))\n    model_dict[model_set[2]] += model_list\n    image_size_list.append(model_set[2])\n    \nimage_size_list = list(set(image_size_list))","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:41:48.908874Z","iopub.execute_input":"2021-08-09T07:41:48.90924Z","iopub.status.idle":"2021-08-09T07:42:56.599736Z","shell.execute_reply.started":"2021-08-09T07:41:48.909197Z","shell.execute_reply":"2021-08-09T07:42:56.598899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#load_dir = f\"/kaggle/input/{COMPETITION_NAME}/\"\nif fast_sub:\n    sub_df = fast_df.copy()\nelse:\n    sub_df = pd.read_csv('../input/siim-covid19-detection/sample_submission.csv')\n    if is_public == False:\n        sub_df = sub_df[~sub_df[\"id\"].isin(pub_ids)].reset_index(drop=True)\n\n\n# sub_df = sub_df[:study_len]\n# test_paths = f'/kaggle/tmp/{split}/study/' + sub_df['id'] +'.png'\n\n# まずはimageの数だけ予測する\nsub_df = sub_df[study_len:]\ntest_paths = f'/kaggle/tmp/{split}/image/' + sub_df['id'] +'.png'\n\n\n\nsub_df['negative'] = 0\nsub_df['typical'] = 0\nsub_df['indeterminate'] = 0\nsub_df['atypical'] = 0\n\ntarget_columns = sub_df.columns[2:]\n\n\ntest_loader = DataLoader(\n    CustomDataset(test_paths, image_size_list),\n    shuffle=False,\n    batch_size=BATCH_SIZE,\n    num_workers=NTHREAD,\n    pin_memory=True,\n)\n\nprediction_0 = predict(model_dict, test_loader)\nweight_0 = len(study_sub_list)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:42:56.601161Z","iopub.execute_input":"2021-08-09T07:42:56.601735Z","iopub.status.idle":"2021-08-09T07:43:00.606423Z","shell.execute_reply.started":"2021-08-09T07:42:56.601694Z","shell.execute_reply":"2021-08-09T07:43:00.60546Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"study_sub_list = [\n    \n    # prediction set\n    [\n        # backbone\n        Net418(\"tf_efficientnetv2_l_in21k\"),\n        \"tf_efficientnetv2_l_in21k\",\n        # img_size\n        512,\n        # weight list\n        [\n            \"/kaggle/input/weight-siim-rsna-v3/exp551/cv0_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp551/cv1_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp551/cv2_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp551/cv3_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp551/cv4_weight_checkpoint_best.pth\",\n        ],\n    ],\n\n    # prediction set\n    [\n        # backbone\n        Net419(\"tf_efficientnetv2_l_in21k\"),\n        \"tf_efficientnetv2_l_in21k\",\n        # img_size\n        512,\n        # weight list\n        [\n            \"/kaggle/input/weight-siim-rsna-v3/exp552/cv0_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp552/cv1_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp552/cv2_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp552/cv3_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp552/cv4_weight_checkpoint_best.pth\",\n        ],\n    ],\n\n    # prediction set\n    [\n        # backbone\n        Net553(\"tf_efficientnetv2_l_in21k\"),\n        \"tf_efficientnetv2_l_in21k\",\n        # img_size\n        512,\n        # weight list\n        [\n            \"/kaggle/input/weight-siim-rsna-v3/exp553/cv0_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp553/cv1_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp553/cv2_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp553/cv3_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp553/cv4_weight_checkpoint_best.pth\",\n        ],\n    ],\n\n]","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:43:00.608458Z","iopub.execute_input":"2021-08-09T07:43:00.608879Z","iopub.status.idle":"2021-08-09T07:43:08.541622Z","shell.execute_reply.started":"2021-08-09T07:43:00.60883Z","shell.execute_reply":"2021-08-09T07:43:08.540757Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# del first model_dict\ndel model_dict, test_loader\ntorch.cuda.empty_cache()\n\n# load second model_dict\n# key: image size, value: model\nmodel_dict = {}\n\nimage_size_list = []\n\nfor model_set in tqdm(study_sub_list):\n    # 画像サイズをkey, modelのリストをvalueにする\n    # keyがまだない場合はからのリストを登録\n    model_dict.setdefault(model_set[2], [])\n    model_list = []\n    for ckpt in tqdm(model_set[3]):\n        model = model_set[0].to(device)\n        weight = torch.load(ckpt, map_location=device)\n        model.load_state_dict(weight[\"state_dict\"])\n        model.eval()\n        model_list.append(deepcopy(model))\n    model_dict[model_set[2]] += model_list\n    image_size_list.append(model_set[2])\n    \nimage_size_list = list(set(image_size_list))\n\ntest_loader = DataLoader(\n    CustomDataset(test_paths, image_size_list),\n    shuffle=False,\n    batch_size=BATCH_SIZE,\n    num_workers=NTHREAD,\n    pin_memory=True,\n)\n\n# predict second model_dict\nprediction_1 = predict(model_dict, test_loader)\nweight_1 = len(study_sub_list)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:43:08.542939Z","iopub.execute_input":"2021-08-09T07:43:08.54326Z","iopub.status.idle":"2021-08-09T07:44:44.530731Z","shell.execute_reply.started":"2021-08-09T07:43:08.543225Z","shell.execute_reply":"2021-08-09T07:44:44.529334Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"study_sub_list = [\n    \n    # ===========================================\n    # Swin transformer\n    # ===========================================\n    \n    # prediction set\n    [\n        # backbone\n        Net604(\"swin_base_patch4_window12_384\"),\n        \"swin_base_patch4_window12_384\",\n        # img_size\n        384,\n        # weight list\n        [\n            \"/kaggle/input/weight-siim-rsna-v2/exp604/cv0_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v2/exp604/cv1_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v2/exp604/cv2_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v2/exp604/cv3_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v2/exp604/cv4_weight_checkpoint_best.pth\",\n        ],\n    ],\n    \n    \n    # prediction set\n    [\n        # backbone\n        Net605(\"swin_base_patch4_window12_384\"),\n        \"swin_base_patch4_window12_384\",\n        # img_size\n        384,\n        # weight list\n        [\n            \"/kaggle/input/weight-siim-rsna-v2/exp605/cv0_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v2/exp605/cv1_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v2/exp605/cv2_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v2/exp605/cv3_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v2/exp605/cv4_weight_checkpoint_best.pth\",\n        ],\n    ],\n\n\n#     # prediction set\n#     [\n#         # backbone\n#         Net606(\"swin_base_patch4_window12_384\"),\n#         \"swin_base_patch4_window12_384\",\n#         # img_size\n#         384,\n#         # weight list\n#         [\n#             \"/kaggle/input/weight-siim-rsna-v2/exp606/cv0_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp606/cv1_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp606/cv2_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp606/cv3_weight_checkpoint_best.pth\",\n#             \"/kaggle/input/weight-siim-rsna-v2/exp606/cv4_weight_checkpoint_best.pth\",\n#         ],\n#     ],\n\n    # ===========================================\n    # Pseudo labeling\n    # ===========================================\n    \n    # prediction set\n    [\n        # backbone\n        Net420(\"tf_efficientnetv2_l_in21k\"),\n        \"tf_efficientnetv2_l_in21k\",\n        # img_size\n        512,\n        # weight list\n        [\n            \"/kaggle/input/weight-siim-rsna-v2/exp720/cv0_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v2/exp720/cv1_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v2/exp720/cv2_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v2/exp720/cv3_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v2/exp720/cv4_weight_checkpoint_best.pth\",\n        ],\n    ],\n\n    \n]\n\n\n# del first model_dict\ndel model_dict, test_loader\ntorch.cuda.empty_cache()\n\n# load second model_dict\n# key: image size, value: model\nmodel_dict = {}\n\nimage_size_list = []\n\nfor model_set in tqdm(study_sub_list):\n    # 画像サイズをkey, modelのリストをvalueにする\n    # keyがまだない場合はからのリストを登録\n    model_dict.setdefault(model_set[2], [])\n    model_list = []\n    for ckpt in tqdm(model_set[3]):\n        model = model_set[0].to(device)\n        weight = torch.load(ckpt, map_location=device)\n        model.load_state_dict(weight[\"state_dict\"])\n        model.eval()\n        model_list.append(deepcopy(model))\n    model_dict[model_set[2]] += model_list\n    image_size_list.append(model_set[2])\n    \nimage_size_list = list(set(image_size_list))\n\ntest_loader = DataLoader(\n    CustomDataset(test_paths, image_size_list),\n    shuffle=False,\n    batch_size=BATCH_SIZE,\n    num_workers=NTHREAD,\n    pin_memory=True,\n)\n\n# predict second model_dict\nprediction_2 = predict(model_dict, test_loader)\nweight_2 = len(study_sub_list)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:44:44.532815Z","iopub.execute_input":"2021-08-09T07:44:44.533338Z","iopub.status.idle":"2021-08-09T07:45:59.509277Z","shell.execute_reply.started":"2021-08-09T07:44:44.533287Z","shell.execute_reply":"2021-08-09T07:45:59.507368Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"study_sub_list = [\n    \n    \n    # ===========================================\n    # Pseudo labeling\n    # ===========================================\n    \n    # prediction set\n    [\n        # backbone\n        Net418(\"tf_efficientnetv2_l_in21k\"),\n        \"tf_efficientnetv2_l_in21k\",\n        # img_size\n        512,\n        # weight list\n        [\n            \"/kaggle/input/weight-siim-rsna-v3/exp751/cv0_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp751/cv1_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp751/cv2_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp751/cv3_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp751/cv4_weight_checkpoint_best.pth\",\n        ],\n    ],\n    \n    # prediction set\n    [\n        # backbone\n        Net419(\"tf_efficientnetv2_l_in21k\"),\n        \"tf_efficientnetv2_l_in21k\",\n        # img_size\n        512,\n        # weight list\n        [\n            \"/kaggle/input/weight-siim-rsna-v3/exp752/cv0_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp752/cv1_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp752/cv2_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp752/cv3_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp752/cv4_weight_checkpoint_best.pth\",\n        ],\n    ],\n    \n    # prediction set\n    [\n        # backbone\n        Net553(\"tf_efficientnetv2_l_in21k\"),\n        \"tf_efficientnetv2_l_in21k\",\n        # img_size\n        512,\n        # weight list\n        [\n            \"/kaggle/input/weight-siim-rsna-v3/exp753/cv0_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp753/cv1_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp753/cv2_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp753/cv3_weight_checkpoint_best.pth\",\n            \"/kaggle/input/weight-siim-rsna-v3/exp753/cv4_weight_checkpoint_best.pth\",\n        ],\n    ],\n\n]\n\n\n# del first model_dict\ndel model_dict, test_loader\ntorch.cuda.empty_cache()\n\n# load second model_dict\n# key: image size, value: model\nmodel_dict = {}\n\nimage_size_list = []\n\nfor model_set in tqdm(study_sub_list):\n    # 画像サイズをkey, modelのリストをvalueにする\n    # keyがまだない場合はからのリストを登録\n    model_dict.setdefault(model_set[2], [])\n    model_list = []\n    for ckpt in tqdm(model_set[3]):\n        model = model_set[0].to(device)\n        weight = torch.load(ckpt, map_location=device)\n        model.load_state_dict(weight[\"state_dict\"])\n        model.eval()\n        model_list.append(deepcopy(model))\n    model_dict[model_set[2]] += model_list\n    image_size_list.append(model_set[2])\n    \nimage_size_list = list(set(image_size_list))\n\ntest_loader = DataLoader(\n    CustomDataset(test_paths, image_size_list),\n    shuffle=False,\n    batch_size=BATCH_SIZE,\n    num_workers=NTHREAD,\n    pin_memory=True,\n)\n\n# predict second model_dict\nprediction_3 = predict(model_dict, test_loader)\nweight_3 = len(study_sub_list)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:45:59.512587Z","iopub.execute_input":"2021-08-09T07:45:59.513045Z","iopub.status.idle":"2021-08-09T07:47:35.870706Z","shell.execute_reply.started":"2021-08-09T07:45:59.513001Z","shell.execute_reply":"2021-08-09T07:47:35.869495Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# average prediction\nweight_sum = weight_0 + weight_1 + weight_2 + weight_3\nw_0 = weight_0 / weight_sum\nw_1 = weight_1 / weight_sum\nw_2 = weight_2 / weight_sum\nw_3 = weight_3 / weight_sum\n\nprediction = w_0 * prediction_0 + w_1 * prediction_1 + w_2 * prediction_2 + w_3 * prediction_3\n\nprediction0 = prediction[:, :4]\nprediction0_study = prediction[:, 4:5]\n\nsub_df[target_columns] = prediction0","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:47:35.873705Z","iopub.execute_input":"2021-08-09T07:47:35.874083Z","iopub.status.idle":"2021-08-09T07:47:35.908085Z","shell.execute_reply.started":"2021-08-09T07:47:35.874038Z","shell.execute_reply":"2021-08-09T07:47:35.907167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# study prediction","metadata":{}},{"cell_type":"code","source":"# print(dict_image2study)\nsub_df_temp = sub_df.copy()\n\n# idをimage_idからstudy_idに変える\nsub_df_temp[\"id\"] = sub_df.id.map(dict_image2study)\nsub_df_temp = sub_df_temp.drop('PredictionString', axis=1)\nsub_df_temp = sub_df_temp.groupby('id').mean().reset_index()\nsub_df_temp[\"PredictionString\"] = \"none 1 0 0 1 1\"\nsub_df = sub_df_temp.loc[:, ['id', 'PredictionString', 'negative', 'typical', 'indeterminate', 'atypical']]\nsub_df","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:47:35.914399Z","iopub.execute_input":"2021-08-09T07:47:35.914703Z","iopub.status.idle":"2021-08-09T07:47:35.969788Z","shell.execute_reply.started":"2021-08-09T07:47:35.914668Z","shell.execute_reply":"2021-08-09T07:47:35.968687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df.columns = ['id', 'PredictionString1', 'negative', 'typical', 'indeterminate', 'atypical']\ndf = pd.merge(df, sub_df, on = 'id', how = 'left')\n\nfor i in range(study_len):\n    negative = df.loc[i,'negative']\n    typical = df.loc[i,'typical']\n    indeterminate = df.loc[i,'indeterminate']\n    atypical = df.loc[i,'atypical']\n    df.loc[i, 'PredictionString'] = f'negative {negative} 0 0 1 1 typical {typical} 0 0 1 1 indeterminate {indeterminate} 0 0 1 1 atypical {atypical} 0 0 1 1'\n\n\ndf_study = df[['id', 'PredictionString']]\n\n# # if study only\n# df_study.to_csv('submission.csv',index=False)\n# df_study","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:47:35.972121Z","iopub.execute_input":"2021-08-09T07:47:35.972509Z","iopub.status.idle":"2021-08-09T07:47:35.992658Z","shell.execute_reply.started":"2021-08-09T07:47:35.972469Z","shell.execute_reply":"2021-08-09T07:47:35.991646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Image prediction, none 2 classes","metadata":{}},{"cell_type":"code","source":"if fast_sub:\n    sub_df = fast_df.copy()\nelse:\n    sub_df = pd.read_csv('../input/siim-covid19-detection/sample_submission.csv')\n    if is_public == False:\n        sub_df = sub_df[~sub_df[\"id\"].isin(pub_ids)].reset_index(drop=True)\nsub_df = sub_df[study_len:]\nsub_df['none'] = 0\n\nlabel_cols = sub_df.columns[2]\n\nsub_df[label_cols] = prediction0_study\ndf_2class = sub_df.reset_index(drop=True)\ndf_2class","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:47:35.994095Z","iopub.execute_input":"2021-08-09T07:47:35.994471Z","iopub.status.idle":"2021-08-09T07:47:36.013409Z","shell.execute_reply.started":"2021-08-09T07:47:35.994432Z","shell.execute_reply":"2021-08-09T07:47:36.012595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Clear classification models","metadata":{}},{"cell_type":"code","source":"del model_dict, test_loader\n\ntorch.cuda.empty_cache()\n\nimport gc\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:47:36.014842Z","iopub.execute_input":"2021-08-09T07:47:36.015365Z","iopub.status.idle":"2021-08-09T07:47:36.545472Z","shell.execute_reply.started":"2021-08-09T07:47:36.015324Z","shell.execute_reply":"2021-08-09T07:47:36.544519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!nvidia-smi","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:47:36.546879Z","iopub.execute_input":"2021-08-09T07:47:36.547252Z","iopub.status.idle":"2021-08-09T07:47:37.377901Z","shell.execute_reply.started":"2021-08-09T07:47:36.547219Z","shell.execute_reply":"2021-08-09T07:47:37.376592Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# meta, create df\nここはmmdet, yolov5で共通","metadata":{}},{"cell_type":"code","source":"meta = meta[meta['split'] == 'test']\nif fast_sub:\n    test_df = fast_df.copy()\nelse:\n    test_df = pd.read_csv('../input/siim-covid19-detection/sample_submission.csv')\n    if is_public == False:\n        test_df = test_df[~test_df[\"id\"].isin(pub_ids)].reset_index(drop=True)\n\ntest_df = df[study_len:].reset_index(drop=True) \nmeta['image_id'] = meta['image_id'] + '_image'\nmeta.columns = ['id', 'dim0', 'dim1', 'split']\ntest_df = pd.merge(test_df, meta, on = 'id', how = 'left')","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:47:37.390784Z","iopub.execute_input":"2021-08-09T07:47:37.391151Z","iopub.status.idle":"2021-08-09T07:47:37.414735Z","shell.execute_reply.started":"2021-08-09T07:47:37.39111Z","shell.execute_reply":"2021-08-09T07:47:37.413728Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# yolov5 predict","metadata":{}},{"cell_type":"code","source":"import numpy as np, pandas as pd\nfrom glob import glob\nimport shutil, os\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import GroupKFold\nfrom tqdm.notebook import tqdm\nimport seaborn as sns\nimport torch\nimport warnings\nwarnings.simplefilter('ignore')\n\nfrom ensemble_boxes import *\n\n\ndef yolo2voc(image_height, image_width, bboxes):\n    \"\"\"\n    yolo => [xmid, ymid, w, h] (normalized)\n    voc  => [x1, y1, x2, y1]\n\n    \"\"\" \n    bboxes = bboxes.copy().astype(float) # otherwise all value will be 0 as voc_pascal dtype is np.int\n\n    bboxes[..., [0, 2]] = bboxes[..., [0, 2]]* image_width\n    bboxes[..., [1, 3]] = bboxes[..., [1, 3]]* image_height\n\n    bboxes[..., [0, 1]] = bboxes[..., [0, 1]] - bboxes[..., [2, 3]]/2\n    bboxes[..., [2, 3]] = bboxes[..., [0, 1]] + bboxes[..., [2, 3]]\n\n    return bboxes\n\n\ndef yolo2x1y1x2y2(bboxes):\n    bboxes = bboxes.copy().astype(float) # otherwise all value will be 0 as voc_pascal dtype is np.int\n    bboxes[..., [0, 1]] = bboxes[..., [0, 1]] - bboxes[..., [2, 3]]/2\n    bboxes[..., [2, 3]] = bboxes[..., [0, 1]] + bboxes[..., [2, 3]]\n\n    return bboxes\n\ndef x1y1x2y2_original_size(image_height, image_width, bboxes):\n    bboxes = bboxes.copy().astype(float) # otherwise all value will be 0 as voc_pascal dtype is np.int\n    bboxes[..., [0, 2]] = bboxes[..., [0, 2]]* image_width\n    bboxes[..., [1, 3]] = bboxes[..., [1, 3]]* image_height\n\n    return bboxes","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:47:37.416193Z","iopub.execute_input":"2021-08-09T07:47:37.416599Z","iopub.status.idle":"2021-08-09T07:47:38.470417Z","shell.execute_reply.started":"2021-08-09T07:47:37.416521Z","shell.execute_reply":"2021-08-09T07:47:38.4696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dim = 512 #1024, 256, 'original'\ntest_dir = f'/kaggle/tmp/{split}/image'\nweights_dir_list = glob('/kaggle/input/siim-rsne-weights-yolov5/*.pt')\n# weights_dir = '/kaggle/input/siim-rsne-weights-yolov5/kernel_best.pt'\n\nshutil.copytree('/kaggle/input/customized-yolov5', '/kaggle/working/yolov5')\nos.chdir('/kaggle/working/yolov5') # install dependencies","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:47:38.471722Z","iopub.execute_input":"2021-08-09T07:47:38.472067Z","iopub.status.idle":"2021-08-09T07:47:39.939022Z","shell.execute_reply.started":"2021-08-09T07:47:38.472031Z","shell.execute_reply":"2021-08-09T07:47:39.937895Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for weights_dir in weights_dir_list:\n    cmd = f\"\"\"python detect.py --weights {weights_dir}\\\n    --img 512\\\n    --conf 0.01\\\n    --iou 0.5\\\n    --source {test_dir}\\\n    --save-txt --save-conf\"\"\"\n    ! {cmd}","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-08-09T07:47:39.94343Z","iopub.execute_input":"2021-08-09T07:47:39.943836Z","iopub.status.idle":"2021-08-09T07:48:52.120341Z","shell.execute_reply.started":"2021-08-09T07:47:39.943797Z","shell.execute_reply":"2021-08-09T07:48:52.11923Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.cuda.empty_cache()\n\nimport gc\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:48:52.122334Z","iopub.execute_input":"2021-08-09T07:48:52.122751Z","iopub.status.idle":"2021-08-09T07:48:52.377471Z","shell.execute_reply.started":"2021-08-09T07:48:52.122707Z","shell.execute_reply":"2021-08-09T07:48:52.376473Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!nvidia-smi","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:48:52.378975Z","iopub.execute_input":"2021-08-09T07:48:52.379574Z","iopub.status.idle":"2021-08-09T07:48:53.143466Z","shell.execute_reply.started":"2021-08-09T07:48:52.379518Z","shell.execute_reply":"2021-08-09T07:48:53.142471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# mmdetection","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport torch\nfrom glob import glob\nimport sys\nimport shutil, os\nfrom tqdm import tqdm\nimport pickle\n\n\nimport cv2\n\nimport warnings\nwarnings.simplefilter('ignore')\n\nfrom ensemble_boxes import *\n\nsys.path.append('/kaggle/mmdetection/')\nimport mmcv\nfrom mmdet.apis import init_detector\nfrom mmdet.apis import inference_detector","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:48:53.146859Z","iopub.execute_input":"2021-08-09T07:48:53.147194Z","iopub.status.idle":"2021-08-09T07:49:11.877467Z","shell.execute_reply.started":"2021-08-09T07:48:53.14716Z","shell.execute_reply":"2021-08-09T07:49:11.876455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def x1y1x2y2_original_size(image_height, image_width, bboxes):\n    \"\"\"\n    yolo => [x1, y1, x2, y1] (normalized)\n    voc  => [x1, y1, x2, y2]\n\n    \"\"\" \n    bboxes = bboxes.copy().astype(float) # otherwise all value will be 0 as voc_pascal dtype is np.int\n\n    bboxes[..., [0, 2]] = bboxes[..., [0, 2]]* image_width\n    bboxes[..., [1, 3]] = bboxes[..., [1, 3]]* image_height\n    return bboxes","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:49:11.879008Z","iopub.execute_input":"2021-08-09T07:49:11.879387Z","iopub.status.idle":"2021-08-09T07:49:11.886517Z","shell.execute_reply.started":"2021-08-09T07:49:11.879344Z","shell.execute_reply":"2021-08-09T07:49:11.884896Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"exp_list = [\"exp006\", \"exp013\", \"exp016\"]\n\nmmdet_config = [\n    {\"config\": f\"/kaggle/input/siim-mmdet-weight/{e}/fold0.py\", \"weight\": glob(f'/kaggle/input/siim-mmdet-weight/{e}/cv*/*.pth')} for e in exp_list\n]\n\n\nmmdet_model_list = []\nfor mmdet_dic in mmdet_config:\n    cfg = mmdet_dic[\"config\"]\n    print(cfg)\n    print(f\"num of weight: {len(mmdet_dic['weight'])}\")\n    for w in mmdet_dic[\"weight\"]:\n        mmdet_model_list.append(init_detector(cfg, w, device))","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:49:11.88843Z","iopub.execute_input":"2021-08-09T07:49:11.888834Z","iopub.status.idle":"2021-08-09T07:51:41.704035Z","shell.execute_reply.started":"2021-08-09T07:49:11.888793Z","shell.execute_reply":"2021-08-09T07:51:41.703119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"result_mmdet_path = f'/kaggle/tmp/mmdet_result/'\nos.makedirs(result_mmdet_path, exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:51:41.707231Z","iopub.execute_input":"2021-08-09T07:51:41.707559Z","iopub.status.idle":"2021-08-09T07:51:41.713835Z","shell.execute_reply.started":"2021-08-09T07:51:41.707519Z","shell.execute_reply":"2021-08-09T07:51:41.71173Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# =============================================================\n# First prediction set\n# =============================================================\n\niou_thr = 0.5\n\ndevice = \"cuda:0\" if torch.cuda.is_available() else \"cpu\"\nprint(device)\n\n\nimage_ids = []\nPredictionStrings = []\n\nfrom time import time\ntime_wbf = []\ntime_mmdet_infer = []\n\n\nfor i in range(len(test_df)):\n    row = test_df.iloc[i]\n    image_id = row[\"id\"]\n    \n    width = row.dim1\n    height = row.dim0\n    \n    img_path = f'/kaggle/tmp/{split}/image/{image_id}.png'\n    img = mmcv.imread(img_path)\n    \n    # result; xmin, ymin, xmax, ymax, conf\n    boxes_list = []\n    scores_list = []\n    labels_list = []\n    \n    st = time()\n    for model in mmdet_model_list:\n        result = inference_detector(model, img)[0]\n        result = result[result[:, 4] >= 0.01]\n        boxes_list.append((result[:, :4] / 640).tolist())\n        scores_list.append(result[:, 4].tolist())\n        labels_list.append([1] * result.shape[0])\n    time_mmdet_infer.append(time() - st)\n\n    result = [boxes_list, scores_list, labels_list]\n    with open(result_mmdet_path + f\"{image_id}.pickle\", mode=\"wb\") as f:\n        pickle.dump(result, f)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:51:41.715397Z","iopub.execute_input":"2021-08-09T07:51:41.715912Z","iopub.status.idle":"2021-08-09T07:51:47.432677Z","shell.execute_reply.started":"2021-08-09T07:51:41.715873Z","shell.execute_reply":"2021-08-09T07:51:47.43171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'mean time of infer: {np.mean(time_mmdet_infer)} sec / image')\nprint(f'total time of infer: {np.sum(time_mmdet_infer) / 60} min')","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:51:47.43413Z","iopub.execute_input":"2021-08-09T07:51:47.43448Z","iopub.status.idle":"2021-08-09T07:51:47.442795Z","shell.execute_reply.started":"2021-08-09T07:51:47.434442Z","shell.execute_reply":"2021-08-09T07:51:47.441797Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del mmdet_model_list\n\ntorch.cuda.empty_cache()\n\nimport gc\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:51:47.444336Z","iopub.execute_input":"2021-08-09T07:51:47.444952Z","iopub.status.idle":"2021-08-09T07:51:47.980829Z","shell.execute_reply.started":"2021-08-09T07:51:47.444913Z","shell.execute_reply":"2021-08-09T07:51:47.979651Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# =============================================================\n# Second prediction set\n# =============================================================\n\nexp_list = [\"exp018\", \"exp022\"]\n\nmmdet_config = [\n    {\"config\": f\"/kaggle/input/siim-mmdet-weight/{e}/fold0.py\", \"weight\": glob(f'/kaggle/input/siim-mmdet-weight/{e}/cv*/*.pth')} for e in exp_list\n]\n\n\nmmdet_model_list = []\nfor mmdet_dic in mmdet_config:\n    cfg = mmdet_dic[\"config\"]\n    print(cfg)\n    print(f\"num of weight: {len(mmdet_dic['weight'])}\")\n    for w in mmdet_dic[\"weight\"]:\n        mmdet_model_list.append(init_detector(cfg, w, device))\n\n\nimage_ids = []\nPredictionStrings = []\n\ntime_wbf = []\ntime_mmdet_infer = []\n\n\nfor i in range(len(test_df)):\n    row = test_df.iloc[i]\n    image_id = row[\"id\"]\n    \n    width = row.dim1\n    height = row.dim0\n    \n    img_path = f'/kaggle/tmp/{split}/image/{image_id}.png'\n    img = mmcv.imread(img_path)\n    \n    # result; xmin, ymin, xmax, ymax, conf\n    boxes_list = []\n    scores_list = []\n    labels_list = []\n    \n    st = time()\n    for model in mmdet_model_list:\n        result = inference_detector(model, img)[0]\n        result = result[result[:, 4] >= 0.01]\n        boxes_list.append((result[:, :4] / 640).tolist())\n        scores_list.append(result[:, 4].tolist())\n        labels_list.append([1] * result.shape[0])\n    time_mmdet_infer.append(time() - st)\n    \n    # ==============================\n    # Add first result\n    # ==============================\n    with open(result_mmdet_path + f\"{image_id}.pickle\", mode=\"rb\") as f:\n        result_first = pickle.load(f)\n        \n    boxes_list_1, scores_list_1, labels_list_1 = result_first\n    boxes_list += boxes_list_1\n    scores_list += scores_list_1\n    labels_list += labels_list_1\n        \n    # ==========================================================================================\n    # Get Yolov5 Prediction\n    # ==========================================================================================\n    for f_p in glob(f'runs/detect/*/labels/{image_id}.txt'):\n        f = open(f_p, 'r')\n        data = np.array(f.read().replace('\\n', ' ').strip().split(' ')).astype(np.float32)\n        data = data.reshape(-1, 6)\n        data = data[:, [0, 5, 1, 2, 3, 4]]\n        bboxes = np.round(np.concatenate((data[:, :2], yolo2x1y1x2y2(data[:, 2:])), axis =1).reshape(-1), 12)\n\n        bboxes = bboxes.reshape(-1, 6)\n\n        boxes_list.append(bboxes[:, 2:].tolist())\n        scores_list.append(bboxes[:, 1].tolist())\n        labels_list.append(bboxes[:, 0].tolist())\n    \n    # wbf\n    st = time()\n    boxes, scores, labels = weighted_boxes_fusion(boxes_list, scores_list, labels_list,\n                                                  weights=None, iou_thr=iou_thr, skip_box_thr=0.0)\n    time_wbf.append(time() - st)\n    \n    # scoreを(1-none)倍する\n    score_calib = (1 - df_2class[df_2class[\"id\"] == image_id][\"none\"].values) ** 0.5\n#     print(f\"score_calib: {score_calib}\")\n#     print(f\"scores[:3]: {scores[:3]}\")\n    scores = scores * score_calib\n#     print(f\"calib, scores[:3]: {scores[:3]}\")\n    \n    boxes = x1y1x2y2_original_size(height, width, boxes)\n\n    bboxes = np.concatenate([labels[:, None], scores[:, None], boxes], -1).reshape(-1).astype(str)\n\n    image_ids.append(image_id)\n    \n    PredictionStrings.append(' '.join(bboxes))\n\n\npred_df = pd.DataFrame({'id':image_ids,\n                        'PredictionString':PredictionStrings})","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:51:47.983228Z","iopub.execute_input":"2021-08-09T07:51:47.983879Z","iopub.status.idle":"2021-08-09T07:52:30.454425Z","shell.execute_reply.started":"2021-08-09T07:51:47.983834Z","shell.execute_reply":"2021-08-09T07:52:30.453455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resized_img = cv2.resize(img, (height, width))\nret = np.zeros((boxes.shape[0], 5))\nret[:, :4] = boxes\nret[:, 4] = scores\n\nplt.figure()\nplt.imshow(mmdet_model_list[0].show_result(resized_img, [ret], score_thr=0.1, thickness=15, font_size=150))\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:52:30.456832Z","iopub.execute_input":"2021-08-09T07:52:30.457249Z","iopub.status.idle":"2021-08-09T07:52:32.50846Z","shell.execute_reply.started":"2021-08-09T07:52:30.457205Z","shell.execute_reply":"2021-08-09T07:52:32.507568Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del mmdet_model_list\n\ntorch.cuda.empty_cache()\n\nimport gc\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:52:32.509697Z","iopub.execute_input":"2021-08-09T07:52:32.510053Z","iopub.status.idle":"2021-08-09T07:52:32.864035Z","shell.execute_reply.started":"2021-08-09T07:52:32.510009Z","shell.execute_reply":"2021-08-09T07:52:32.863129Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = test_df.drop(['PredictionString'], axis=1)\nsub_df = pd.merge(test_df, pred_df, on = 'id', how = 'left').fillna(\"none 1 0 0 1 1\")\nsub_df = sub_df[['id', 'PredictionString']]\n\nfor i in range(sub_df.shape[0]):\n    if sub_df.loc[i,'PredictionString'] == \"none 1 0 0 1 1\":\n        continue\n    sub_df_split = sub_df.loc[i,'PredictionString'].split()\n    sub_df_list = []\n    for j in range(int(len(sub_df_split) / 6)):\n        sub_df_list.append('opacity')\n        sub_df_list.append(sub_df_split[6 * j + 1])\n        sub_df_list.append(sub_df_split[6 * j + 2])\n        sub_df_list.append(sub_df_split[6 * j + 3])\n        sub_df_list.append(sub_df_split[6 * j + 4])\n        sub_df_list.append(sub_df_split[6 * j + 5])\n    sub_df.loc[i,'PredictionString'] = ' '.join(sub_df_list)\n    \ntry:\n    sub_df['none'] = df_2class['none']\n    for i in range(sub_df.shape[0]):\n        if sub_df.loc[i,'PredictionString'] != 'none 1 0 0 1 1':\n            sub_df.loc[i,'PredictionString'] = sub_df.loc[i,'PredictionString'] + ' none ' + str(sub_df.loc[i,'none']) + ' 0 0 1 1'\nexcept:\n    df_study = df[['id', 'PredictionString']]\n    df_study['PredictionString'] = \"\"\n    print('No df_2class')\n    for i in range(sub_df.shape[0]):\n        if sub_df.loc[i,'PredictionString'] != 'none 1 0 0 1 1':\n            sub_df.loc[i,'PredictionString'] = sub_df.loc[i,'PredictionString']\n\nsub_df = sub_df[['id', 'PredictionString']]   \ndf_study = df_study[:study_len]\ndf_study = df_study.append(sub_df).reset_index(drop=True)\n\n\nif is_public == False:\n    df_study = pd.concat([df_study, sub_public], ignore_index=True)\n\ndf_study.to_csv('/kaggle/working/submission.csv',index = False)  \nshutil.rmtree('/kaggle/tmp/')\nshutil.rmtree('/workspace/')\nshutil.rmtree('/kaggle/working/yolov5')","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:52:32.865352Z","iopub.execute_input":"2021-08-09T07:52:32.865714Z","iopub.status.idle":"2021-08-09T07:52:33.80384Z","shell.execute_reply.started":"2021-08-09T07:52:32.865676Z","shell.execute_reply":"2021-08-09T07:52:33.802864Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_study","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:52:33.805192Z","iopub.execute_input":"2021-08-09T07:52:33.805644Z","iopub.status.idle":"2021-08-09T07:52:33.817702Z","shell.execute_reply.started":"2021-08-09T07:52:33.805512Z","shell.execute_reply":"2021-08-09T07:52:33.81671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!nvidia-smi","metadata":{"execution":{"iopub.status.busy":"2021-08-09T07:52:33.819178Z","iopub.execute_input":"2021-08-09T07:52:33.819722Z","iopub.status.idle":"2021-08-09T07:52:34.145835Z","shell.execute_reply.started":"2021-08-09T07:52:33.819682Z","shell.execute_reply":"2021-08-09T07:52:34.144747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}