{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.10","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":26680,"databundleVersionId":2283525,"sourceType":"competition"},{"sourceId":1666454,"sourceType":"datasetVersion","datasetId":986800},{"sourceId":1874023,"sourceType":"datasetVersion","datasetId":1115512},{"sourceId":2437252,"sourceType":"datasetVersion","datasetId":1448714},{"sourceId":2442246,"sourceType":"datasetVersion","datasetId":1477894},{"sourceId":2474118,"sourceType":"datasetVersion","datasetId":1497242},{"sourceId":2475994,"sourceType":"datasetVersion","datasetId":1498367},{"sourceId":2477188,"sourceType":"datasetVersion","datasetId":1480885},{"sourceId":2477207,"sourceType":"datasetVersion","datasetId":1498283},{"sourceId":2479140,"sourceType":"datasetVersion","datasetId":1500322},{"sourceId":2490317,"sourceType":"datasetVersion","datasetId":1507512},{"sourceId":2490344,"sourceType":"datasetVersion","datasetId":1507534},{"sourceId":2490388,"sourceType":"datasetVersion","datasetId":1507546},{"sourceId":2490456,"sourceType":"datasetVersion","datasetId":1507428},{"sourceId":2946309,"sourceType":"datasetVersion","datasetId":1469190},{"sourceId":12070836,"sourceType":"datasetVersion","datasetId":277765},{"sourceId":63372526,"sourceType":"kernelVersion"},{"sourceId":65826175,"sourceType":"kernelVersion"},{"sourceId":68758414,"sourceType":"kernelVersion"}],"dockerImageVersionId":30121,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"<p style='text-align: center;'><span style=\"color: #000508; font-family: Segoe UI; font-size: 2.5em; font-weight: 350;\"> [Inference] Swin Transformer Object Detection (SOTA)</span></p>\n\n<br><br>\n<span style=\"color: #027fc1; font-family: Segoe UI; font-size: 1.9em; font-weight: 350;\">Highlights</span><br>\n\n<p style='text-align: left;'><span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em;font-weight: 350;\"> 👋 Big thanks to: </span></p>\n\n\n>  [Sreevishnu Damodaran for his great notebook](https://www.kaggle.com/sreevishnudamodaran/siim-effnetv2-l-cascadercnn-mmdetection-infer)<br>\n\n\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.8em;\">References:</span>\n\n- https://www.kaggle.com/h053473666/siim-cov19-efnb7-yolov5-infer\n- https://github.com/tensorflow/hub\n- https://github.com/open-mmlab/mmdetection\n- https://github.com/SwinTransformer/Swin-Transformer-Object-Detection","metadata":{"execution":{"iopub.status.busy":"2025-06-07T12:24:31.121195Z","iopub.execute_input":"2025-06-07T12:24:31.121579Z","iopub.status.idle":"2025-06-07T12:24:31.205113Z","shell.execute_reply.started":"2025-06-07T12:24:31.121489Z","shell.execute_reply":"2025-06-07T12:24:31.203864Z"}}},{"cell_type":"markdown","source":"<span style=\"color: #027fc1; font-family: Segoe UI; font-size: 1.9em; font-weight: 350;\">SWIN Transformer Object Detection</span>\n\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em; font-weight: 350;\">As you can guess SWIN is a Transformer Architecture.</span><br>\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em; font-weight: 350;\">Now SWIN ranks 6 place on COCO dataset.</span><br>\n\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em; font-weight: 350;\">You can check it [there](https://paperswithcode.com/sota/object-detection-on-coco).</span><br>","metadata":{}},{"cell_type":"markdown","source":"<span style=\"color: #027fc1; font-family: Segoe UI; font-size: 1.9em; font-weight: 350;\">Train SWIN Transformer 🤖</span>\n\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em; font-weight: 350;\">You can find implementation of SWIN Transformer Object Detection from Microsoft [here](https://github.com/SwinTransformer/Swin-Transformer-Object-Detection).</span><br>\n<br>\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em; font-weight: 350;\">It can be a bit tricky to understand 🤯 how to train SWIN Transformer for custom dataset if you didn't work with MM* repositories before ([mmsegmentattion](https://github.com/open-mmlab/mmsegmentation), [mmdetection](https://github.com/open-mmlab/mmdetection)).</span><br>\n<br>\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em; font-weight: 350;\">I have a repo with training and inference of SWIN Transformer Object Detection for custom dataset on [github](https://github.com/denred0/Swin-Transformer-Object-Detection). I hope it helps you. Anyway, If you have some questions you can write [me](https://www.kaggle.com/denispotapov) 🙂</span><br>\n\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em; font-weight: 350;\">Ok. For this task I trained SWIN Transformer with default settings. Used Cascade Mask R-CNN with SWIN-S backbone.</span><br>\n\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em; font-weight: 350;\">Now we are ready to write some code 🚀</span>","metadata":{}},{"cell_type":"markdown","source":"<span style=\"color: #027fc1; font-family: Segoe UI; font-size: 1.9em; font-weight: 350;\">Install Swin Transformer 🔧</span>\n\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em; font-weight: 350;\">Prepare our environment for SWIN Detection. I used torch 1.8 and cuda 11.1. </span><br>","metadata":{}},{"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!pip install '/kaggle/input/torch-distrib/torch-1.8.0cu111-cp37-cp37m-linux_x86_64.whl' --no-deps\n!pip install '/kaggle/input/torchvision090/torchvision-0.9.0cu111-cp37-cp37m-linux_x86_64.whl' --no-deps\n!pip install '/kaggle/input/torch-distrib/torchaudio-0.8.0-cp37-cp37m-linux_x86_64.whl' --no-deps\n\n## Compatible Cuda Toolkit installation\n!mkdir -p /kaggle/tmp && cp /kaggle/input/cudatoolkit1111/cudatoolkit-11.1.1-h6406543_8 /kaggle/tmp/cudatoolkit-11.1.1-h6406543_8.tar.bz2 && conda install /kaggle/tmp/cudatoolkit-11.1.1-h6406543_8.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/mmcv-full/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%cd /kaggle/working/","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2025-06-07T12:25:50.556625Z","iopub.execute_input":"2025-06-07T12:25:50.556973Z","iopub.status.idle":"2025-06-07T12:38:31.225743Z","shell.execute_reply.started":"2025-06-07T12:25:50.556940Z","shell.execute_reply":"2025-06-07T12:38:31.224786Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# copy libnvrtc-builtins.so.11.1.74. \n# I used this library for EfficientDet inference and decided to leave it here. \n# May be this library no need for Swin Transformer but I didn't test. \n%cd /usr/local/cuda-11.0/lib64\n!cp /kaggle/input/cudatoolkit1111/libnvrtc-builtins.so.11.1.74 .\n%cd /kaggle/working/","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:38:31.227493Z","iopub.execute_input":"2025-06-07T12:38:31.227863Z","iopub.status.idle":"2025-06-07T12:38:32.342377Z","shell.execute_reply.started":"2025-06-07T12:38:31.227819Z","shell.execute_reply":"2025-06-07T12:38:32.341508Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# install additional libraries\n!pip install '/kaggle/input/cython02924/Cython-0.29.24-cp37-cp37m-manylinux1_x86_64.whl' --no-deps\n!pip install '/kaggle/input/pytorchimagemodels/pytorch-image-models-master' --no-deps\n!pip install '/kaggle/input/pip-2121/pip-21.2.1-py3-none-any.whl' --no-deps","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:38:32.344164Z","iopub.execute_input":"2025-06-07T12:38:32.344416Z","iopub.status.idle":"2025-06-07T12:40:22.371239Z","shell.execute_reply.started":"2025-06-07T12:38:32.344388Z","shell.execute_reply":"2025-06-07T12:40:22.370422Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# copy Swin Transformer repo\nimport shutil\nshutil.copytree('/kaggle/input/swin-detection-repo/Swin-Transformer-Object-Detection-master', '/kaggle/working/Swin-Transformer-Object-Detection-master')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:40:22.372897Z","iopub.execute_input":"2025-06-07T12:40:22.373254Z","iopub.status.idle":"2025-06-07T12:40:25.429464Z","shell.execute_reply.started":"2025-06-07T12:40:22.373210Z","shell.execute_reply":"2025-06-07T12:40:25.428625Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# install Swin Transformer requirements\n!pip install -r ./Swin-Transformer-Object-Detection-master/requirements/build.txt","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:40:25.430425Z","iopub.execute_input":"2025-06-07T12:40:25.430640Z","iopub.status.idle":"2025-06-07T12:41:03.458084Z","shell.execute_reply.started":"2025-06-07T12:40:25.430619Z","shell.execute_reply":"2025-06-07T12:41:03.457330Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# install Swin Transformer\n!pip install -v -e ./Swin-Transformer-Object-Detection-master","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:41:03.459560Z","iopub.execute_input":"2025-06-07T12:41:03.459848Z","iopub.status.idle":"2025-06-07T12:41:46.270236Z","shell.execute_reply.started":"2025-06-07T12:41:03.459816Z","shell.execute_reply":"2025-06-07T12:41:46.269171Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<span style=\"color: #027fc1; font-family: Segoe UI; font-size: 1.9em; font-weight: 350;\">Install Apex for mixed precision 🔩</span>\n\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em; font-weight: 350;\">Swin Transformer need Apex. Apex is a librarry that uses float16 and float32 calculations together during training.<br> With mixed precision you can decrease GPU's usage and increase training speed without decreasing accuracy.</span><br>\n<br>\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em; font-weight: 350;\">Swin Transformer need a lot of GPU therefore It needs Apex.<br> I have 11GB GPU and I can train only with 2 images per batch.</span><br>\n<br>\n<br>\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em; font-weight: 350;\">Ok. Copy Apex repo and install it.</span>","metadata":{}},{"cell_type":"code","source":"shutil.copytree('/kaggle/input/apex-repo/apex-master', '/kaggle/working/apex-master')\n\n!pip install -v --no-cache-dir --global-option=\"--cpp_ext\" --global-option=\"--cuda_ext\" ./apex-master","metadata":{"_kg_hide-output":true,"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:41:46.271862Z","iopub.execute_input":"2025-06-07T12:41:46.272239Z","iopub.status.idle":"2025-06-07T12:45:22.467442Z","shell.execute_reply.started":"2025-06-07T12:41:46.272194Z","shell.execute_reply":"2025-06-07T12:45:22.466623Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import sys\nsys.path.append('/kaggle/working/Swin-Transformer-Object-Detection-master')\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":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:22.468943Z","iopub.execute_input":"2025-06-07T12:45:22.469319Z","iopub.status.idle":"2025-06-07T12:45:22.560589Z","shell.execute_reply.started":"2025-06-07T12:45:22.469267Z","shell.execute_reply":"2025-06-07T12:45:22.559815Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<span style=\"color: #027fc1; font-family: Segoe UI; font-size: 1.9em; font-weight: 350;\">Create Study and Image Level Dataframes</span>\n<br>\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em; font-weight: 350;\">I left this part without changes and big thanks [Sreevishnu Damodaran](https://www.kaggle.com/sreevishnudamodaran) for this.</span><br>\n\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em; font-weight: 350;\">You can scroll on Swin Transformer inference part.</span><br>","metadata":{}},{"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":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:22.562751Z","iopub.execute_input":"2025-06-07T12:45:22.563007Z","iopub.status.idle":"2025-06-07T12:45:39.759720Z","shell.execute_reply.started":"2025-06-07T12:45:22.562983Z","shell.execute_reply":"2025-06-07T12:45:39.758851Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<span style=\"color: #027fc1; font-family: Segoe UI; font-size: 1.9em; font-weight: 350;\">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":{}},{"cell_type":"code","source":"fast_sub = False","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:39.761563Z","iopub.execute_input":"2025-06-07T12:45:39.761889Z","iopub.status.idle":"2025-06-07T12:45:39.789447Z","shell.execute_reply.started":"2025-06-07T12:45:39.761862Z","shell.execute_reply":"2025-06-07T12:45:39.788631Z"}},"outputs":[],"execution_count":null},{"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":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:39.790591Z","iopub.execute_input":"2025-06-07T12:45:39.790835Z","iopub.status.idle":"2025-06-07T12:45:47.085234Z","shell.execute_reply.started":"2025-06-07T12:45:39.790811Z","shell.execute_reply":"2025-06-07T12:45:47.083782Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# nonresized images\nimage_dir_orig = f'/kaggle/tmp/test/image_orig/'\nos.makedirs(image_dir_orig, exist_ok=True)\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 = Image.fromarray(xray)  \n    im.save(os.path.join(image_dir_orig, row['image_id']+'.png'))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:47.086078Z","iopub.status.idle":"2025-06-07T12:45:47.086417Z","shell.execute_reply":"2025-06-07T12:45:47.086254Z"}},"outputs":[],"execution_count":null},{"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":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:47.087185Z","iopub.status.idle":"2025-06-07T12:45:47.087477Z","shell.execute_reply":"2025-06-07T12:45:47.087339Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<span style=\"color: #027fc1; font-family: Segoe UI; font-size: 1.9em; font-weight: 350;\">Custom Wrapper for Loading TFHub Model trained in TPU</span>\n\nSince the EffNetV2 Classifier models were trained on a TPU with the `tfhub.KerasLayer` formed with the handle argument as a GCS path, while loading the saved model for inference, the method tries to download the pre-trained weights from the definition of the layer from training i.e a GCS path.\n\nSince, inference notebooks don't have GCS and internet access, it is not possible to load the model without the pretrained weights explicitly loaded from the local directory.\n\nIf the models were trained on a GPU, we can use the cache location method to load the pre-trained weights by storing them in a cache folder with the hashed key of the model location, as the folder name. I tried this method here but, it doesn't seem to work as the model was trained with a GCS path defined in the `tfhub.KerasLayer` and the method kept on hitting the GCS path rather than loading the weights from the cache location.\n\nThe only solution was to create a wrapper class to correct the handle argument to load the right pretrained weights explicitly from the local directory.","metadata":{}},{"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":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:47.088444Z","iopub.status.idle":"2025-06-07T12:45:47.088746Z","shell.execute_reply":"2025-06-07T12:45:47.088607Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<span style=\"color: #027fc1; font-family: Segoe UI; font-size: 1.9em; font-weight: 350;\">Predict Study Level</span>","metadata":{}},{"cell_type":"code","source":"MODEL_PATH = '/kaggle/input/siim-effnetv2-keras-study-train-tpu-cv0-805'\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) / 355.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.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=False, 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\nstudy_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":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:47.089659Z","iopub.status.idle":"2025-06-07T12:45:47.089967Z","shell.execute_reply":"2025-06-07T12:45:47.089827Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<span style=\"color: #027fc1; font-family: Segoe UI; font-size: 1.9em; font-weight: 350;\">Predict 2Class Image Level</span>\n\nUsing [@Alien](https://www.kaggle.com/h053473666) 2class model.","metadata":{}},{"cell_type":"code","source":"import efficientnet.tfkeras as efn\n\nMODEL_PATH = '/kaggle/input/siim-covid19-efnb7-train-fold0-5-2class'\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=False, 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\nimage_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":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:47.090669Z","iopub.status.idle":"2025-06-07T12:45:47.090983Z","shell.execute_reply":"2025-06-07T12:45:47.090842Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<span style=\"color: #027fc1; font-family: Segoe UI; font-size: 1.9em; font-weight: 350;\">Swin Transformer Inference 🖼</span>","metadata":{}},{"cell_type":"code","source":"# clear GPU memory\nfrom numba import cuda\nimport torch\ncuda.select_device(0)\ncuda.close()\ncuda.select_device(0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:47.091893Z","iopub.status.idle":"2025-06-07T12:45:47.092198Z","shell.execute_reply":"2025-06-07T12:45:47.092049Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import mmdet\nfrom mmdet.apis import init_detector, inference_detector","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:47.092960Z","iopub.status.idle":"2025-06-07T12:45:47.093263Z","shell.execute_reply":"2025-06-07T12:45:47.093124Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# functions helpers\ndef yolo2voc(image_height, image_width, bboxes):\n    \"\"\"\n    yolo => [xmid, ymid, w, h] (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\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 get_all_files_in_folder(folder, types):\n    files_grabbed = []\n    for t in types:\n        files_grabbed.extend(folder.rglob(t))\n    files_grabbed = sorted(files_grabbed, key=lambda x: x)\n    return files_grabbed","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:47.093986Z","iopub.status.idle":"2025-06-07T12:45:47.094286Z","shell.execute_reply":"2025-06-07T12:45:47.094148Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from pathlib import Path\nfrom tqdm import tqdm\nimport cv2\nimport numpy as np\n\n# config file consist all settings for training and inference (augmentation, image resolution, scheduler, learning rate and so on.) \n# You can download it and check\nconfig_file = '/kaggle/input/swin-transformer-data/mask_rcnn_swin_small_patch4_window7_mstrain_480-800_adamw_3x_coco_without_mask_head.py'\n\n# weights\ncheckpoint_file = '/kaggle/input/swin-transformer-data/epoch_14.pth'\n\n# used nonresized images\nimages_dir = Path('/kaggle/tmp/test/image_orig/')\nimages_ext = ['*.png']\n\nconf_threshold = 0.001\n\ndevice = 'cuda:0'\nimage_ids = []\nPredictionStrings = []\n\n# init model\nmodel = init_detector(config_file, checkpoint_file, device=device)\n\n# get all images\nfiles = get_all_files_in_folder(images_dir, images_ext)\n\nfor file in tqdm(files):\n    image = cv2.imread(str(file), cv2.IMREAD_COLOR)\n\n    h, w = image.shape[:2]\n\n    # inference\n    result = inference_detector(model, file)\n\n    bboxes = result[0]\n    dect_results = []\n    boxes_valid = []\n    for box in bboxes:\n        if box[4] > conf_threshold:\n            boxes_valid.append(box)\n\n    if len(boxes_valid) > 0:\n        for box in boxes_valid:\n            wn = (box[2] - box[0]) / w\n            hn = (box[3] - box[1]) / h\n            x_center_norm = ((box[2] - box[0]) / 2 + box[0]) / w\n            y_center_norm = ((box[3] - box[1]) / 2 + box[1]) / h\n            label = 0\n            d = [label, box[4], x_center_norm, y_center_norm, wn, hn]\n            dect_results.append(d)\n\n    if len(dect_results):\n        data = np.array(dect_results)\n        bboxes = list(\n            np.round(np.concatenate((data[:, :2], np.round(yolo2voc(h, w, data[:, 2:]))), axis=1).reshape(-1),\n                     12).astype(str))\n        for idx in range(len(bboxes)):\n            bboxes[idx] = str(int(float(bboxes[idx]))) if idx % 6 != 1 else bboxes[idx]\n        PredictionStrings.append(' '.join(bboxes))\n        image_ids.append(file.stem)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:47.095085Z","iopub.status.idle":"2025-06-07T12:45:47.095381Z","shell.execute_reply":"2025-06-07T12:45:47.095243Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# check result\nPredictionStrings[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:47.096231Z","iopub.status.idle":"2025-06-07T12:45:47.096522Z","shell.execute_reply":"2025-06-07T12:45:47.096385Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\ndetection_df = pd.DataFrame({'id':image_ids, 'PredictionString':PredictionStrings})","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:47.097225Z","iopub.status.idle":"2025-06-07T12:45:47.097519Z","shell.execute_reply":"2025-06-07T12:45:47.097382Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%cd /kaggle/working/","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:47.098199Z","iopub.status.idle":"2025-06-07T12:45:47.098489Z","shell.execute_reply":"2025-06-07T12:45:47.098353Z"}},"outputs":[],"execution_count":null},{"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":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:47.099192Z","iopub.status.idle":"2025-06-07T12:45:47.099483Z","shell.execute_reply":"2025-06-07T12:45:47.099347Z"}},"outputs":[],"execution_count":null},{"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":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:47.100252Z","iopub.status.idle":"2025-06-07T12:45:47.100555Z","shell.execute_reply":"2025-06-07T12:45:47.100409Z"}},"outputs":[],"execution_count":null},{"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.tail(5)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:47.101214Z","iopub.status.idle":"2025-06-07T12:45:47.101509Z","shell.execute_reply":"2025-06-07T12:45:47.101371Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"shutil.rmtree('/kaggle/working/apex-master')\nshutil.rmtree('/kaggle/working/Swin-Transformer-Object-Detection-master')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T12:45:47.102194Z","iopub.status.idle":"2025-06-07T12:45:47.102487Z","shell.execute_reply":"2025-06-07T12:45:47.102350Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<span style=\"color: #027fc1; font-family: Segoe UI; font-size: 1.9em; font-weight: 350;\">Thank you for attention!</span>\n<br>\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em; font-weight: 350;\">If you have some questions or suggestions you can write them on comments 💬</span><br>\n\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em; font-weight: 350;\">If it was useful please upvote 👍</span><br>\n\n<span style=\"color: #027fc1; font-family: Segoe UI; font-size: 1.7em; font-weight: 350;\">Don't give up, keep trying! 💪</span>\n<br>","metadata":{}},{"cell_type":"markdown","source":"<span style=\"color: #027fc1; font-family: Segoe UI; font-size: 1.7em; font-weight: 350;\">My specs 💻</span>\n<br>\n\n* 1 CPU, 16 cores & 16GB Memory 💾\n* NVIDIA **GeForce RTX 2080 Ti** 🎮","metadata":{}}]}