{"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":"%load_ext autoreload\n%autoreload 2\n\n!conda install '/kaggle/input/pydicom-conda-helper/libjpeg-turbo-2.1.0-h7f98852_0.tar.bz2' -y --offline\n!conda install '/kaggle/input/pydicom-conda-helper/libgcc-ng-9.3.0-h2828fa1_19.tar.bz2' -y --offline\n!conda install '/kaggle/input/pydicom-conda-helper/gdcm-2.8.9-py37h500ead1_1.tar.bz2' -y --offline\n!conda install '/kaggle/input/pydicom-conda-helper/conda-4.10.1-py37h89c1867_0.tar.bz2' -y --offline\n!conda install '/kaggle/input/pydicom-conda-helper/certifi-2020.12.5-py37h89c1867_1.tar.bz2' -y --offline\n!conda install '/kaggle/input/pydicom-conda-helper/openssl-1.1.1k-h7f98852_0.tar.bz2' -y --offline\n\n!pip install '/kaggle/input/kerasapplications' --no-deps\n!pip install '/kaggle/input/efficientnet-keras-source-code' --no-deps\n!pip install '/kaggle/input/effdet-latestvinbigdata-wbf-fused/ensemble_boxes-1.0.4-py3-none-any.whl' --no-deps\n\n## MMDetection compatible torch installation\n!pip install '/kaggle/input/pytorch-170-cuda-toolkit-110221/torch-1.7.0+cu110-cp37-cp37m-linux_x86_64.whl' --no-deps\n!pip install '/kaggle/input/pytorch-170-cuda-toolkit-110221/torchvision-0.8.1+cu110-cp37-cp37m-linux_x86_64.whl' --no-deps\n!pip install '/kaggle/input/pytorch-170-cuda-toolkit-110221/torchaudio-0.7.0-cp37-cp37m-linux_x86_64.whl' --no-deps\n\n## Compatible Cuda Toolkit installation\n!mkdir -p /kaggle/tmp && cp /kaggle/input/pytorch-170-cuda-toolkit-110221/cudatoolkit-11.0.221-h6bb024c_0 /kaggle/tmp/cudatoolkit-11.0.221-h6bb024c_0.tar.bz2 && conda install /kaggle/tmp/cudatoolkit-11.0.221-h6bb024c_0.tar.bz2 -y --offline\n\n## MMDetection Offline Installation\n!pip install '/kaggle/input/mmdetectionv2140/addict-2.4.0-py3-none-any.whl' --no-deps\n!pip install '/kaggle/input/mmdetectionv2140/yapf-0.31.0-py2.py3-none-any.whl' --no-deps\n!pip install '/kaggle/input/mmdetectionv2140/terminal-0.4.0-py3-none-any.whl' --no-deps\n!pip install '/kaggle/input/mmdetectionv2140/terminaltables-3.1.0-py3-none-any.whl' --no-deps\n!pip install '/kaggle/input/mmdetectionv2140/mmcv_full-1_3_8-cu110-torch1_7_0/mmcv_full-1.3.8-cp37-cp37m-manylinux1_x86_64.whl' --no-deps\n!pip install '/kaggle/input/mmdetectionv2140/pycocotools-2.0.2/pycocotools-2.0.2' --no-deps\n!pip install '/kaggle/input/mmdetectionv2140/mmpycocotools-12.0.3/mmpycocotools-12.0.3' --no-deps\n\n!cp -r /kaggle/input/mmdetectionv2140/mmdetection-2.14.0 /kaggle/working/\n!mv /kaggle/working/mmdetection-2.14.0 /kaggle/working/mmdetection\n%cd /kaggle/working/mmdetection\n!pip install -e . --no-deps\n%cd /kaggle/working/","metadata":{"papermill":{"duration":589.21781,"end_time":"2021-07-17T19:03:09.933611","exception":false,"start_time":"2021-07-17T18:53:20.715801","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-07T14:57:51.243978Z","iopub.execute_input":"2021-08-07T14:57:51.244446Z","iopub.status.idle":"2021-08-07T15:07:57.334268Z","shell.execute_reply.started":"2021-08-07T14:57:51.244344Z","shell.execute_reply":"2021-08-07T15:07:57.333258Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\nsys.path.append('/kaggle/working/mmdetection')\n\nimport os\nfrom PIL import Image\nimport pandas as pd\nfrom tqdm.auto import tqdm\nimport gc\nimport glob\nimport numpy as np","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","papermill":{"duration":0.104274,"end_time":"2021-07-17T19:03:10.131834","exception":false,"start_time":"2021-07-17T19:03:10.02756","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-07T15:07:57.336159Z","iopub.execute_input":"2021-08-07T15:07:57.336587Z","iopub.status.idle":"2021-08-07T15:07:57.523264Z","shell.execute_reply.started":"2021-08-07T15:07:57.336543Z","shell.execute_reply":"2021-08-07T15:07:57.522336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #00857e; font-family: Segoe UI; font-size: 1.8em; font-weight: 300;\">Create Study and Image Level Dataframes</span>","metadata":{"papermill":{"duration":0.092535,"end_time":"2021-07-17T19:03:10.317337","exception":false,"start_time":"2021-07-17T19:03:10.224802","status":"completed"},"tags":[]}},{"cell_type":"code","source":"sub_df = pd.read_csv('/kaggle/input/siim-covid19-detection/sample_submission.csv')\n\n# Form study and image dataframes\nsub_df['level'] = sub_df.id.map(lambda idx: idx[-5:])\nstudy_df = sub_df[sub_df.level=='study'].rename({'id':'study_id'}, axis=1)\nimage_df = sub_df[sub_df.level=='image'].rename({'id':'image_id'}, axis=1)\n\ndcm_path = glob.glob('/kaggle/input/siim-covid19-detection/test/**/*dcm', recursive=True)\ntest_meta = pd.DataFrame({'dcm_path':dcm_path})\ntest_meta['image_id'] = test_meta.dcm_path.map(lambda x: x.split('/')[-1].replace('.dcm', '')+'_image')\ntest_meta['study_id'] = test_meta.dcm_path.map(lambda x: x.split('/')[-3].replace('.dcm', '')+'_study')\n\nstudy_df = study_df.merge(test_meta, on='study_id', how='left')\nimage_df = image_df.merge(test_meta, on='image_id', how='left')\n\n# Remove duplicates study_ids from study_df\nstudy_df.drop_duplicates(subset=\"study_id\",keep='first', inplace=True)","metadata":{"papermill":{"duration":5.695531,"end_time":"2021-07-17T19:03:16.105354","exception":false,"start_time":"2021-07-17T19:03:10.409823","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-07T15:07:57.525185Z","iopub.execute_input":"2021-08-07T15:07:57.525594Z","iopub.status.idle":"2021-08-07T15:08:02.952118Z","shell.execute_reply.started":"2021-08-07T15:07:57.525565Z","shell.execute_reply":"2021-08-07T15:08:02.951196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #00857e; font-family: Segoe UI; font-size: 1.8em; font-weight: 300;\">Fast or Full Predictions</span>\n\nIn case of non-competetion submission commits, we run the notebook with just two images each for image level and study level inference from the public test data.","metadata":{"papermill":{"duration":0.154867,"end_time":"2021-07-17T19:03:16.415952","exception":false,"start_time":"2021-07-17T19:03:16.261085","status":"completed"},"tags":[]}},{"cell_type":"code","source":"fast_sub = False\n\nif sub_df.shape[0] == 2477:\n    fast_sub = True\n    study_df = study_df.sample(2)\n    image_df = image_df.sample(2)\n    \n    print(\"\\nstudy_df\")\n    display(study_df.head(2))\n    print(\"\\nimage_df\")\n    display(image_df.head(2))\n    print(\"\\ntest_meta\")\n    display(test_meta.head(2))","metadata":{"papermill":{"duration":0.28084,"end_time":"2021-07-17T19:03:16.86864","exception":false,"start_time":"2021-07-17T19:03:16.5878","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-07T15:08:02.953762Z","iopub.execute_input":"2021-08-07T15:08:02.954101Z","iopub.status.idle":"2021-08-07T15:08:03.018156Z","shell.execute_reply.started":"2021-08-07T15:08:02.954062Z","shell.execute_reply":"2021-08-07T15:08:03.017050Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\n\nSTUDY_DIMS = (768, 768)\nIMAGE_DIMS = (512, 512)\n\nstudy_dir = f'/kaggle/tmp/test/study/'\nos.makedirs(study_dir, exist_ok=True)\n\nimage_dir = f'/kaggle/tmp/test/image/'\nos.makedirs(image_dir, exist_ok=True)\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    return data\n\ndef 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    return im\n\nfor index, row in tqdm(study_df[['study_id', 'dcm_path']].iterrows(), total=study_df.shape[0]):\n    # set keep_ratio=True to have original aspect ratio\n    xray = read_xray(row['dcm_path'])\n    im = resize(xray, size=STUDY_DIMS[0])\n    im.save(os.path.join(study_dir, row['study_id']+'.png'))\n\nimage_df['dim0'] = -1\nimage_df['dim1'] = -1\n\nfor index, row in tqdm(image_df[['image_id', 'dcm_path', 'dim0', 'dim1']].iterrows(), total=image_df.shape[0]):\n    # set keep_ratio=True to have original aspect ratio\n    xray = read_xray(row['dcm_path'])\n    im = resize(xray, size=IMAGE_DIMS[0])  \n    im.save(os.path.join(image_dir, row['image_id']+'.png'))\n    image_df.loc[image_df.image_id==row.image_id, 'dim0'] = xray.shape[0]\n    image_df.loc[image_df.image_id==row.image_id, 'dim1'] = xray.shape[1]","metadata":{"papermill":{"duration":4.178244,"end_time":"2021-07-17T19:03:21.225656","exception":false,"start_time":"2021-07-17T19:03:17.047412","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-07T15:08:03.019749Z","iopub.execute_input":"2021-08-07T15:08:03.020155Z","iopub.status.idle":"2021-08-07T15:08:06.322571Z","shell.execute_reply.started":"2021-08-07T15:08:03.020115Z","shell.execute_reply":"2021-08-07T15:08:06.321450Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"study_df['image_path'] = study_dir+study_df['study_id']+'.png'\nimage_df['image_path'] = image_dir+image_df['image_id']+'.png'","metadata":{"execution":{"iopub.status.busy":"2021-08-07T15:08:06.324094Z","iopub.execute_input":"2021-08-07T15:08:06.324669Z","iopub.status.idle":"2021-08-07T15:08:06.373322Z","shell.execute_reply.started":"2021-08-07T15:08:06.324624Z","shell.execute_reply":"2021-08-07T15:08:06.372531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nimport tensorflow_hub as tfhub\n\nMODEL_ARCH = 'efficientnetv2-l-21k-ft1k'\n# Get the TensorFlow Hub model URL\nhub_type = 'feature_vector' # ['classification', 'feature_vector']\nMODEL_ARCH_PATH = f'/kaggle/input/efficientnetv2-tfhub-weight-files/tfhub_models/{MODEL_ARCH}/{hub_type}'\n\n# Custom wrapper class to load the right pretrained weights explicitly from the local directory\nclass KerasLayerWrapper(tfhub.KerasLayer):\n    def __init__(self, handle, **kwargs):\n        handle = tfhub.KerasLayer(tfhub.load(MODEL_ARCH_PATH))\n        super().__init__(handle, **kwargs)","metadata":{"papermill":{"duration":4.259738,"end_time":"2021-07-17T19:03:25.768808","exception":false,"start_time":"2021-07-17T19:03:21.50907","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-07T15:08:06.374612Z","iopub.execute_input":"2021-08-07T15:08:06.374985Z","iopub.status.idle":"2021-08-07T15:08:10.869370Z","shell.execute_reply.started":"2021-08-07T15:08:06.374951Z","shell.execute_reply":"2021-08-07T15:08:10.868386Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #00857e; font-family: Segoe UI; font-size: 1.8em; font-weight: 300;\">Predict Study Level</span>","metadata":{"papermill":{"duration":0.087465,"end_time":"2021-07-17T19:03:25.943841","exception":false,"start_time":"2021-07-17T19:03:25.856376","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def zoom(image):\n    p = tf.random.uniform([1], 0, 1)[0]\n    if p>tf.constant(0.5):\n        zoom = True\n    else:\n        zoom = False\n    if zoom:\n        batchedImage = tf.expand_dims(image, axis=0)\n        boxes = [[\n            tf.random.uniform([1], 0, 0.2)[0], \n            tf.random.uniform([1], 0, 0.2)[0], \n            tf.random.uniform([1], 0.8, 1.0)[0], \n            tf.random.uniform([1], 0.8, 1.0)[0]\n        ]]\n        box_indices = tf.constant([0])\n        crop_size = tf.constant(CURRENT_SHAPE)\n        croppedResized = tf.image.crop_and_resize(batchedImage, boxes, box_indices, crop_size)\n        croppedResized = tf.squeeze(croppedResized, axis=0)\n        return croppedResized\n    else:\n        return image","metadata":{"execution":{"iopub.status.busy":"2021-08-07T15:11:30.281750Z","iopub.execute_input":"2021-08-07T15:11:30.282087Z","iopub.status.idle":"2021-08-07T15:11:30.342079Z","shell.execute_reply.started":"2021-08-07T15:11:30.282057Z","shell.execute_reply":"2021-08-07T15:11:30.341201Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"MODEL_PATH = '/kaggle/input/siim-effnetv2-keras-study-train-tpu-cv0-805'\nCURRENT_SHAPE = STUDY_DIMS\ntest_paths = study_df.image_path.tolist()\nBATCH_SIZE = 16\n\ndef build_decoder(with_labels=True, target_size=(300, 300), ext='jpg'):\n    def decode(path):\n        file_bytes = tf.io.read_file(path)\n        if ext == 'png':\n            img = tf.image.decode_png(file_bytes, channels=3)\n        elif ext in ['jpg', 'jpeg']:\n            img = tf.image.decode_jpeg(file_bytes, channels=3)\n        else:\n            raise ValueError(\"Image extension not supported\")\n\n        img = tf.cast(img, tf.float32) / 255.0\n        img = tf.image.resize(img, target_size)\n\n        return img\n\n    def decode_with_labels(path, label):\n        return decode(path), label\n\n    return decode_with_labels if with_labels else decode\n\ndef build_augmenter(with_labels=True):\n    def augment(img):\n        img = tf.image.random_flip_left_right(img)\n#         img = tf.image.random_flip_up_down(img)\n        return img\n\n    def augment_with_labels(img, label):\n        return augment(img), label\n\n    return augment_with_labels if with_labels else augment\n\ndef build_dataset(paths, labels=None, bsize=32, cache=True,\n                  decode_fn=None, augment_fn=None,\n                  augment=True, repeat=True, shuffle=1024, \n                  cache_dir=\"\"):\n    if cache_dir != \"\" and cache is True:\n        os.makedirs(cache_dir, exist_ok=True)\n\n    if decode_fn is None:\n        decode_fn = build_decoder(labels is not None)\n\n    if augment_fn is None:\n        augment_fn = build_augmenter(labels is not None)\n\n    AUTO = tf.data.experimental.AUTOTUNE\n    slices = paths if labels is None else (paths, labels)\n\n    dset = tf.data.Dataset.from_tensor_slices(slices)\n    dset = dset.map(decode_fn, num_parallel_calls=AUTO)\n    dset = dset.cache(cache_dir) if cache else dset\n    dset = dset.map(augment_fn, num_parallel_calls=AUTO) if augment else dset\n    dset = dset.map(zoom, num_parallel_calls=AUTO) if augment else dset\n    dset = dset.repeat() if repeat else dset\n    dset = dset.shuffle(shuffle) if shuffle else dset\n    dset = dset.batch(bsize).prefetch(AUTO)\n\n    return dset\n\n# strategy = auto_select_accelerator()\n# BATCH_SIZE = strategy.num_replicas_in_sync * 16\n\nlabel_cols = ['negative', 'typical', 'indeterminate', 'atypical']\nstudy_df[label_cols] = 0\n\ntest_decoder = build_decoder(with_labels=False,\n                             target_size=(STUDY_DIMS[0],\n                                          STUDY_DIMS[0]), ext='png')\ntest_dataset = build_dataset(\n    test_paths, bsize=BATCH_SIZE, repeat=False, \n    shuffle=False, augment=True, cache=False,\n    decode_fn=test_decoder\n)\n\nwith tf.device('/device:GPU:0'):\n    models = []\n    models0 = tf.keras.models.load_model(f'{MODEL_PATH}/model0.h5',\n                                         custom_objects={'KerasLayer': KerasLayerWrapper})\n    models1 = tf.keras.models.load_model(f'{MODEL_PATH}/model1.h5',\n                                         custom_objects={'KerasLayer': KerasLayerWrapper})\n    models2 = tf.keras.models.load_model(f'{MODEL_PATH}/model2.h5',\n                                         custom_objects={'KerasLayer': KerasLayerWrapper})\n    models3 = tf.keras.models.load_model(f'{MODEL_PATH}/model3.h5',\n                                         custom_objects={'KerasLayer': KerasLayerWrapper})\n    models4 = tf.keras.models.load_model(f'{MODEL_PATH}/model4.h5',\n                                         custom_objects={'KerasLayer': KerasLayerWrapper})\n    models.append(models0)\n    models.append(models1)\n    models.append(models2)\n    models.append(models3)\n    models.append(models4)\n    \ndef getModelPreds(model, dataset, tta):\n    preds = sum([model.predict(dataset, verbose=1) for i in range(tta)])/tta\n    return preds\n\nstudy_df[label_cols] = sum([getModelPreds(model, test_dataset, 5) for model in models]) / len(models)\n\n# study_df[label_cols] = sum([model.predict(test_dataset, verbose=1) for model in models]) / len(models)\nstudy_df['PredictionString'] = study_df[label_cols].apply(lambda row: f'negative {row.negative} 0 0 1 1 typical {row.typical} 0 0 1 1 indeterminate {row.indeterminate} 0 0 1 1 atypical {row.atypical} 0 0 1 1', axis=1)\n\ndel models\ndel models0, models1, models2, models3, models4\ndel test_dataset, test_decoder\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-08-07T15:11:35.292899Z","iopub.execute_input":"2021-08-07T15:11:35.293245Z","iopub.status.idle":"2021-08-07T15:15:28.532756Z","shell.execute_reply.started":"2021-08-07T15:11:35.293199Z","shell.execute_reply":"2021-08-07T15:15:28.531930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #00857e; font-family: Segoe UI; font-size: 1.8em; font-weight: 300;\">Predict 2Class Image Level</span>\n\nUsing [@Alien](https://www.kaggle.com/h053473666) 2class model.","metadata":{"papermill":{"duration":0.096091,"end_time":"2021-07-17T19:04:41.039546","exception":false,"start_time":"2021-07-17T19:04:40.943455","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import efficientnet.tfkeras as efn\n\nMODEL_PATH = '/kaggle/input/siim-covid19-efnb7-train-fold0-5-2class'\nCURRENT_SHAPE = IMAGE_DIMS\n\ntest_paths = image_df.image_path.tolist()\nimage_df['none'] = 0\nlabel_cols = ['none']\n\ntest_decoder = build_decoder(with_labels=False,\n                             target_size=(IMAGE_DIMS[0],\n                                          IMAGE_DIMS[0]), ext='png')\ntest_dataset = build_dataset(\n    test_paths, bsize=BATCH_SIZE, repeat=False, \n    shuffle=False, augment=True, cache=False,\n    decode_fn=test_decoder\n)\n\nwith tf.device('/device:GPU:0'):\n    models = []\n    models0 = tf.keras.models.load_model(f'{MODEL_PATH}/model0.h5')\n    models1 = tf.keras.models.load_model(f'{MODEL_PATH}/model1.h5')\n    models2 = tf.keras.models.load_model(f'{MODEL_PATH}/model2.h5')\n    models3 = tf.keras.models.load_model(f'{MODEL_PATH}/model3.h5')\n    models4 = tf.keras.models.load_model(f'{MODEL_PATH}/model4.h5')\n    models.append(models0)\n    models.append(models1)\n    models.append(models2)\n    models.append(models3)\n    models.append(models4)\n\n\nimage_df[label_cols] = sum([getModelPreds(model, test_dataset, 5) for model in models]) / len(models)\n# image_df[label_cols] = sum([model.predict(test_dataset, verbose=1) for model in models]) / len(models)\n\ndel models\ndel models0, models1, models2, models3, models4\ndel test_dataset, test_decoder\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-08-07T15:15:38.103056Z","iopub.execute_input":"2021-08-07T15:15:38.103423Z","iopub.status.idle":"2021-08-07T15:17:43.425422Z","shell.execute_reply.started":"2021-08-07T15:15:38.103387Z","shell.execute_reply":"2021-08-07T15:17:43.424629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #00857e; font-family: Segoe UI; font-size: 1.8em; font-weight: 300;\">Predict Image Level</span>","metadata":{"papermill":{"duration":0.094734,"end_time":"2021-07-17T19:06:44.55103","exception":false,"start_time":"2021-07-17T19:06:44.456296","status":"completed"},"tags":[]}},{"cell_type":"code","source":"from numba import cuda\nimport torch\ncuda.select_device(0)\ncuda.close()\ncuda.select_device(0)","metadata":{"papermill":{"duration":2.426508,"end_time":"2021-07-17T19:06:47.070269","exception":false,"start_time":"2021-07-17T19:06:44.643761","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-07T15:17:48.805492Z","iopub.execute_input":"2021-08-07T15:17:48.805826Z","iopub.status.idle":"2021-08-07T15:17:54.465095Z","shell.execute_reply.started":"2021-08-07T15:17:48.805792Z","shell.execute_reply":"2021-08-07T15:17:54.464286Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm.notebook import tqdm\n\nimport torch\ndevice = torch.device(\"cuda\") if torch.cuda.is_available() else torch.device(\"cpu\")\nprint(device.type)\n\nimport torchvision\nprint(torch.__version__, torch.cuda.is_available())\n\n# Check mmcv installation\nfrom mmcv.ops import get_compiling_cuda_version, get_compiler_version\nprint(get_compiling_cuda_version())\nprint(get_compiler_version())\n\n# Check MMDetection installation\nfrom mmdet.apis import set_random_seed\n\n# Imports\nimport mmdet\nfrom mmdet.apis import set_random_seed\nfrom mmdet.datasets import build_dataset\nfrom mmdet.models import build_detector\n\nimport mmcv\nfrom mmcv import Config\nfrom mmcv.runner import load_checkpoint\nfrom mmcv.parallel import MMDataParallel\nfrom mmdet.apis import inference_detector, init_detector, show_result_pyplot\nfrom mmdet.apis import single_gpu_test\nfrom mmdet.datasets import build_dataloader, build_dataset","metadata":{"papermill":{"duration":24.187988,"end_time":"2021-07-17T19:07:11.351071","exception":false,"start_time":"2021-07-17T19:06:47.163083","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-07T15:17:54.466884Z","iopub.execute_input":"2021-08-07T15:17:54.467260Z","iopub.status.idle":"2021-08-07T15:18:19.131089Z","shell.execute_reply.started":"2021-08-07T15:17:54.467213Z","shell.execute_reply":"2021-08-07T15:18:19.130184Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\nimport matplotlib.pyplot as plt\n\nlabel2color = [[59, 238, 119]]\n\nviz_labels =  [\"Covid_Abnormality\"]\n\ndef plot_img(img, size=(18, 18), is_rgb=True, title=\"\", cmap=None):\n    plt.figure(figsize=size)\n    plt.imshow(img, cmap=cmap)\n    plt.suptitle(title)\n    plt.show()\n    \ndef plot_imgs(imgs, cols=2, size=10, is_rgb=True, title=\"\", cmap=None, img_size=None):\n    rows = len(imgs)//cols + 1\n    fig = plt.figure(figsize=(cols*size, rows*size))\n    for i, img in enumerate(imgs):\n        if img_size is not None:\n            img = cv2.resize(img, img_size)\n        fig.add_subplot(rows, cols, i+1)\n        plt.imshow(img, cmap=cmap)\n    plt.suptitle(title)\n    return fig\n    \ndef draw_bbox(image, box, label, color):   \n    alpha = 0.1\n    alpha_font = 0.6\n    thickness = 8\n    font_size = 2.0\n    font_weight = 1\n    overlay_bbox = image.copy()\n    overlay_text = image.copy()\n    output = image.copy()\n\n    text_width, text_height = cv2.getTextSize(label.upper(), cv2.FONT_HERSHEY_SIMPLEX, font_size, font_weight)[0]\n    cv2.rectangle(overlay_bbox, (box[0], box[1]), (box[2], box[3]),\n                color, -1)\n    cv2.addWeighted(overlay_bbox, alpha, output, 1 - alpha, 0, output)\n    cv2.rectangle(overlay_text, (box[0], box[1]-18-text_height), (box[0]+text_width+8, box[1]),\n                (0, 0, 0), -1)\n    cv2.addWeighted(overlay_text, alpha_font, output, 1 - alpha_font, 0, output)\n    cv2.rectangle(output, (box[0], box[1]), (box[2], box[3]),\n                    color, thickness)\n    cv2.putText(output, label.upper(), (box[0], box[1]-12),\n            cv2.FONT_HERSHEY_SIMPLEX, font_size, (255, 255, 255), font_weight, cv2.LINE_AA)\n    return output\n\ndef draw_bbox_small(image, box, label, color):   \n    alpha = 0.1\n    alpha_text = 0.3\n    thickness = 1\n    font_size = 0.4\n    overlay_bbox = image.copy()\n    overlay_text = image.copy()\n    output = image.copy()\n\n    text_width, text_height = cv2.getTextSize(label.upper(), cv2.FONT_HERSHEY_SIMPLEX, font_size, thickness)[0]\n    cv2.rectangle(overlay_bbox, (box[0], box[1]), (box[2], box[3]),\n                color, -1)\n    cv2.addWeighted(overlay_bbox, alpha, output, 1 - alpha, 0, output)\n    cv2.rectangle(overlay_text, (box[0], box[1]-7-text_height), (box[0]+text_width+2, box[1]),\n                (0, 0, 0), -1)\n    cv2.addWeighted(overlay_text, alpha_text, output, 1 - alpha_text, 0, output)\n    cv2.rectangle(output, (box[0], box[1]), (box[2], box[3]),\n                    color, thickness)\n    cv2.putText(output, label.upper(), (box[0], box[1]-5),\n            cv2.FONT_HERSHEY_SIMPLEX, font_size, (255, 255, 255), thickness, cv2.LINE_AA)\n    return output","metadata":{"papermill":{"duration":0.117768,"end_time":"2021-07-17T19:07:28.313348","exception":false,"start_time":"2021-07-17T19:07:28.19558","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-07T15:18:19.133186Z","iopub.execute_input":"2021-08-07T15:18:19.133553Z","iopub.status.idle":"2021-08-07T15:18:19.223405Z","shell.execute_reply.started":"2021-08-07T15:18:19.133519Z","shell.execute_reply":"2021-08-07T15:18:19.222479Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def getCascaderConfig(baseline_cfg_path):\n    cfg = Config.fromfile(baseline_cfg_path)\n\n    cfg.classes = (\"Covid_Abnormality\")\n    cfg.data.test.img_prefix = ''\n    cfg.data.test.classes = cfg.classes\n\n    # cfg.model.roi_head.bbox_head.num_classes = 1\n    # cfg.model.bbox_head.num_classes = 1\n    for head in cfg.model.roi_head.bbox_head:\n        head.num_classes = 1\n\n    # Set seed thus the results are more reproducible\n    cfg.seed = 211\n    set_random_seed(211, deterministic=False)\n    cfg.gpu_ids = [0]\n\n    cfg.data.test.pipeline=[\n                dict(type='LoadImageFromFile'),\n                dict(\n                    type='MultiScaleFlipAug',\n                    img_scale=(1333, 800),\n                    flip=False,\n                    transforms=[\n                        dict(type='Resize', keep_ratio=True),\n                        dict(type='RandomFlip', direction='horizontal'),\n                        dict(\n                            type='Normalize',\n                            mean=[123.675, 116.28, 103.53],\n                            std=[58.395, 57.12, 57.375],\n                            to_rgb=True),\n                        dict(type='Pad', size_divisor=32),\n                        dict(type='DefaultFormatBundle'),\n                        dict(type='Collect', keys=['img'])\n                    ])\n            ]\n\n    cfg.test_pipeline = [\n                dict(type='LoadImageFromFile'),\n                dict(\n                    type='MultiScaleFlipAug',\n                    img_scale=(1333, 800),\n                    flip=False,\n                    transforms=[\n                        dict(type='Resize', keep_ratio=True),\n                        dict(type='RandomFlip', direction='horizontal'),\n                        dict(\n                            type='Normalize',\n                            mean=[123.675, 116.28, 103.53],\n                            std=[58.395, 57.12, 57.375],\n                            to_rgb=True),\n                        dict(type='Pad', size_divisor=32),\n                        dict(type='DefaultFormatBundle'),\n                        dict(type='Collect', keys=['img'])\n                    ])\n            ]\n\n    # cfg.data.samples_per_gpu = 4\n    # cfg.data.workers_per_gpu = 4\n    # cfg.model.test_cfg.nms.iou_threshold = 0.3\n    cfg.model.test_cfg.rcnn.score_thr = 0.001\n    return cfg","metadata":{"execution":{"iopub.status.busy":"2021-08-07T15:18:19.225492Z","iopub.execute_input":"2021-08-07T15:18:19.225861Z","iopub.status.idle":"2021-08-07T15:18:19.306326Z","shell.execute_reply.started":"2021-08-07T15:18:19.225825Z","shell.execute_reply":"2021-08-07T15:18:19.305382Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from ensemble_boxes import weighted_boxes_fusion, nms\n\ndef mxmyToxyxy(boxes):\n    boxes[:, 0]-=boxes[:, 2]/2\n    boxes[:, 1]-=boxes[:, 3]/2\n    boxes[:, 2]+=boxes[:, 0]\n    boxes[:, 3]+=boxes[:, 1]\n    return boxes\n\ndef scaleBack(h, w, boxes):\n    boxes[:, 0]*=w\n    boxes[:, 2]*=w\n    boxes[:, 1]*=h\n    boxes[:, 3]*=h\n    boxes = np.round(boxes)\n    return boxes\n\ndef fuseBoxes(df, modelPreds, weights=None, iou_thr=0.65):\n    fusedBoxPreds = {}\n    for idx, row in df.iterrows():\n        image_id = row['image_id']\n        h = row['dim0']\n        w = row['dim1']\n        modelBoxPreds = []\n        modelConfidences = []\n        modelClasses = []\n        for model_preds in modelPreds:\n            if image_id in model_preds.keys():\n                boxes = model_preds[image_id][0]\n                confidences = model_preds[image_id][1]\n                classes = model_preds[image_id][2]\n                modelBoxPreds.append(boxes)\n                modelConfidences.append(confidences)\n                modelClasses.append(classes)\n\n        skip_box_thr = 0.0001\n        if weights==None:\n            weights = [1]*len(modelPreds)\n        fusedBoxes, fusedConfidences, fusedLabels = weighted_boxes_fusion(modelBoxPreds, modelConfidences, modelClasses, weights=weights, iou_thr=iou_thr, skip_box_thr=skip_box_thr)\n        fusedBoxPreds[image_id] = [fusedBoxes, fusedConfidences, fusedLabels]\n    return fusedBoxPreds\n\ndef fusedBoxesToPrediction(h, w, fusedBoxes, fusedConfidences, fusedLabels):\n    fusedBoxes = scaleBack(h, w, fusedBoxes)\n#     fusedLabels = np.array(['opacity']*len(fusedLabels))\n    predictionString = np.round(np.concatenate((np.expand_dims(fusedLabels, axis=1), np.expand_dims(fusedConfidences, axis=1), fusedBoxes), axis=-1).reshape(-1), 12).astype(str)\n    for idx in range(len(predictionString)):\n        predictionString[idx] = str(int(float(predictionString[idx]))) if idx%6!=1 else predictionString[idx]\n        predictionString[idx] = 'opacity' if idx%6==0 else predictionString[idx]\n    predictionString = ' '.join(predictionString)\n    if predictionString==\"\":\n        predictionString = \"none 1 0 0 1 1\"\n    return predictionString\n\ndef getPredDf(test_df, modelPreds):\n    image_ids = []\n    predictionStrings = []\n    for idx, row in test_df.iterrows():\n        image_id = row['image_id']\n        h = row['dim0']\n        w = row['dim1']\n        preds = modelPreds[image_id]\n        predictionString = fusedBoxesToPrediction(h, w, preds[0], preds[1], preds[2])\n        predictionStrings.append(predictionString)\n        image_ids.append(image_id)\n    pred_df = pd.DataFrame({'id':image_ids, 'PredictionString':predictionStrings})\n    return pred_df","metadata":{"execution":{"iopub.status.busy":"2021-08-07T15:18:19.307780Z","iopub.execute_input":"2021-08-07T15:18:19.308136Z","iopub.status.idle":"2021-08-07T15:18:19.405175Z","shell.execute_reply.started":"2021-08-07T15:18:19.308101Z","shell.execute_reply":"2021-08-07T15:18:19.404164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cascaderEnsemblePreds = []\nfor modelDirectory in glob.glob('/kaggle/input/cascadercnn-3folds/*'):\n    print(modelDirectory)\n    configFile = glob.glob(modelDirectory+\"/config*\")[0]\n    print\n    weightFile = glob.glob(modelDirectory+\"/fold*\")[0]\n    cfg = getCascaderConfig(configFile)\n    score_threshold = cfg.model.test_cfg.rcnn.score_thr\n    model = init_detector(cfg, weightFile, device='cuda:0')\n    \n    weightedBoxFusionData = {}\n    with torch.no_grad():\n        for index, row in tqdm(image_df.iterrows(), total=image_df.shape[0]):\n            original_H, original_W = (int(row.dim0), int(row.dim1))\n            predictions = inference_detector(model, row.image_path)\n            boxes, scores, labels = (list(), list(), list())\n\n            for k, cls_result in enumerate(predictions):\n    #             print(\"cls_result\", cls_result)\n                if cls_result.size != 0:\n                    if len(labels)==0:\n                        boxes = np.array(cls_result[:, :4])\n                        scores = np.array(cls_result[:, 4])\n                        labels = np.array([k]*len(cls_result[:, 4]))\n                    else:    \n                        boxes = np.concatenate((boxes, np.array(cls_result[:, :4])))\n                        scores = np.concatenate((scores, np.array(cls_result[:, 4])))\n                        labels = np.concatenate((labels, [k]*len(cls_result[:, 4])))\n\n            indexes = np.where(scores > score_threshold)\n            boxes = boxes[indexes]\n            scores = scores[indexes]\n            labels = labels[indexes]\n\n            if len(labels) != 0:\n                boxes[:, [0, 2]] /= IMAGE_DIMS[0]\n                boxes[:, [1, 3]] /= IMAGE_DIMS[1]\n            weightedBoxFusionData[row.image_id] = [boxes, scores, labels]\n    cascaderEnsemblePreds.append(weightedBoxFusionData)\n    del model\n    gc.collect()\nfusedCascaderPreds = fuseBoxes(image_df, cascaderEnsemblePreds)\ndetection_df = getPredDf(image_df, fusedCascaderPreds)","metadata":{"execution":{"iopub.status.busy":"2021-08-07T15:18:19.406627Z","iopub.execute_input":"2021-08-07T15:18:19.407062Z","iopub.status.idle":"2021-08-07T15:19:06.616068Z","shell.execute_reply.started":"2021-08-07T15:18:19.407024Z","shell.execute_reply":"2021-08-07T15:19:06.615227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# baseline_cfg_path = \"/kaggle/input/siim-mmdetection-cascadercnn-weight-bias/job4_cascade_rcnn_x101_32x4d_fpn_1x_fold0/job4_cascade_rcnn_x101_32x4d_fpn_1x_coco.py\"\n# cfg = getCascaderConfig(baseline_cfg_path)\n\n# WEIGHTS_FILE = '/kaggle/input/siim-mmdetection-cascadercnn-weight-bias/job4_cascade_rcnn_x101_32x4d_fpn_1x_fold0/epoch_10.pth'\n# model = init_detector(cfg, WEIGHTS_FILE, device='cuda:0')\n\n# viz_images = []\n# results = []\n# score_threshold = cfg.model.test_cfg.rcnn.score_thr\n\n# def format_pred(boxes: np.ndarray, scores: np.ndarray, labels: np.ndarray) -> str:\n#     pred_strings = []\n#     label_str = ['opacity']\n#     for label, score, bbox in zip(labels, scores, boxes):\n#         xmin, ymin, xmax, ymax = bbox.astype(np.int64)\n#         pred_strings.append(f\"{label_str[int(label)]} {score:.16f} {xmin} {ymin} {xmax} {ymax}\")\n#     return \" \".join(pred_strings)\n\n# model.to(device)\n# model.eval()\n\n# viz_images = []\n\n# with torch.no_grad():\n#     for index, row in tqdm(image_df.iterrows(), total=image_df.shape[0]):\n#         original_H, original_W = (int(row.dim0), int(row.dim1))\n#         predictions = inference_detector(model, row.image_path)\n#         boxes, scores, labels = (list(), list(), list())\n\n#         for k, cls_result in enumerate(predictions):\n# #             print(\"cls_result\", cls_result)\n#             if cls_result.size != 0:\n#                 if len(labels)==0:\n#                     boxes = np.array(cls_result[:, :4])\n#                     scores = np.array(cls_result[:, 4])\n#                     labels = np.array([k]*len(cls_result[:, 4]))\n#                 else:    \n#                     boxes = np.concatenate((boxes, np.array(cls_result[:, :4])))\n#                     scores = np.concatenate((scores, np.array(cls_result[:, 4])))\n#                     labels = np.concatenate((labels, [k]*len(cls_result[:, 4])))\n                    \n#             if fast_sub:\n#                 img_viz = cv2.imread(row.image_path)\n#                 for box, label, score in zip(boxes, labels, scores):\n#                     color = label2color[int(label)]\n#                     img_viz = draw_bbox_small(img_viz, box.astype(np.int32), f'opacity_{score:.4f}', color)\n#                 viz_images.append(img_viz)\n\n#         indexes = np.where(scores > score_threshold)\n# #         print(indexes)\n#         boxes = boxes[indexes]\n#         scores = scores[indexes]\n#         labels = labels[indexes]\n\n#         if len(labels) != 0:\n#             h_ratio = original_H/IMAGE_DIMS[0]\n#             w_ratio = original_W/IMAGE_DIMS[1]\n#             boxes[:, [0, 2]] *= w_ratio\n#             boxes[:, [1, 3]] *= h_ratio\n\n#             result = {\n#                 \"id\": row.image_id,\n#                 \"PredictionString\": format_pred(\n#                     boxes, scores, labels\n#                 ),\n#             }\n\n#             results.append(result)\n# del model\n# gc.collect()\n\n# detection_df = pd.DataFrame(results, columns=['id', 'PredictionString'])","metadata":{"papermill":{"duration":2.481425,"end_time":"2021-07-17T19:07:30.8895","exception":false,"start_time":"2021-07-17T19:07:28.408075","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-07T15:19:06.617478Z","iopub.execute_input":"2021-08-07T15:19:06.617829Z","iopub.status.idle":"2021-08-07T15:19:06.736401Z","shell.execute_reply.started":"2021-08-07T15:19:06.617794Z","shell.execute_reply":"2021-08-07T15:19:06.735351Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"detection_df = detection_df.merge(image_df[['image_id', 'none']].rename({'image_id':'id'}, axis=1),\n                                  on='id', how='left')\n\nfor i in range(detection_df.shape[0]):\n    if detection_df.loc[i,'PredictionString'] != 'none 1 0 0 1 1':\n        detection_df.loc[i,'PredictionString'] = detection_df.loc[i,'PredictionString'] + ' none ' + str(detection_df.loc[i,'none']) + ' 0 0 1 1'\ndetection_df = detection_df[['id', 'PredictionString']]\n\nresults_df = study_df[['study_id', 'PredictionString']].rename({'study_id':'id'}, axis=1)\nresults_df = results_df.append(detection_df[['id', 'PredictionString']])","metadata":{"papermill":{"duration":0.130739,"end_time":"2021-07-17T19:07:31.131057","exception":false,"start_time":"2021-07-17T19:07:31.000318","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-07T15:19:06.738765Z","iopub.execute_input":"2021-08-07T15:19:06.739346Z","iopub.status.idle":"2021-08-07T15:19:06.833198Z","shell.execute_reply.started":"2021-08-07T15:19:06.739306Z","shell.execute_reply":"2021-08-07T15:19:06.832395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df = pd.read_csv('/kaggle/input/siim-covid19-detection/sample_submission.csv')\nsub_df['PredictionString'] = np.nan\nsub_df = sub_df.set_index('id')\nresults_df = results_df.set_index('id')\nsub_df.update(results_df)\nsub_df = sub_df.reset_index()\nsub_df = sub_df.fillna(\"none 1 0 0 1 1\")\nsub_df.to_csv('/kaggle/working/submission.csv', index=False)\n\nif fast_sub:\n    display(sub_df.head(2))","metadata":{"papermill":{"duration":0.305787,"end_time":"2021-07-17T19:07:31.547349","exception":false,"start_time":"2021-07-17T19:07:31.241562","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-07T15:19:06.834707Z","iopub.execute_input":"2021-08-07T15:19:06.835108Z","iopub.status.idle":"2021-08-07T15:19:06.972893Z","shell.execute_reply.started":"2021-08-07T15:19:06.835067Z","shell.execute_reply":"2021-08-07T15:19:06.969764Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df = pd.read_csv('/kaggle/input/siim-covid19-detection/sample_submission.csv')\nsub_df['PredictionString'] = np.nan\n# sub_df = sub_df.set_index('id')\nsub_df.head(5)","metadata":{"execution":{"iopub.status.busy":"2021-08-07T15:19:06.974510Z","iopub.execute_input":"2021-08-07T15:19:06.974850Z","iopub.status.idle":"2021-08-07T15:19:07.128986Z","shell.execute_reply.started":"2021-08-07T15:19:06.974817Z","shell.execute_reply":"2021-08-07T15:19:07.127566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!rm -r /kaggle/working/mmdetection","metadata":{"papermill":{"duration":0.363451,"end_time":"2021-07-17T19:07:32.023003","exception":false,"start_time":"2021-07-17T19:07:31.659552","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-07T15:08:13.446214Z","iopub.status.idle":"2021-08-07T15:08:13.446857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style='text-align: center;'><span style=\"color: #000508; font-family: Segoe UI; font-size: 2.4em; font-weight: 300;\">HAVE A GREAT DAY!</span></p>\n\n<p style='text-align: center;'><span style=\"color: #000508; font-family: Segoe UI; font-size: 1.4em; font-weight: 300;\">Let me know if you have any suggestions!</span></p>","metadata":{}}]}