{"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":"!pip install 'git+https://github.com/facebookresearch/detectron2.git'","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-22T08:15:25.015677Z","iopub.execute_input":"2021-06-22T08:15:25.016141Z","iopub.status.idle":"2021-06-22T08:17:46.758622Z","shell.execute_reply.started":"2021-06-22T08:15:25.016059Z","shell.execute_reply":"2021-06-22T08:17:46.757631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!conda install gdcm -c conda-forge -y","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:17:46.760293Z","iopub.execute_input":"2021-06-22T08:17:46.760617Z","iopub.status.idle":"2021-06-22T08:18:39.755138Z","shell.execute_reply.started":"2021-06-22T08:17:46.760584Z","shell.execute_reply":"2021-06-22T08:18:39.754182Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from detectron2 import model_zoo\nfrom detectron2.engine import DefaultTrainer\nfrom detectron2.config import get_cfg\nfrom detectron2.utils.visualizer import Visualizer, ColorMode\nfrom detectron2.evaluation import DatasetEvaluator\n\nfrom detectron2.data import DatasetCatalog, MetadataCatalog\nfrom detectron2.data import build_detection_train_loader, build_detection_test_loader\nfrom detectron2.data import transforms as T\nfrom detectron2.data import detection_utils as utils\nfrom detectron2.utils.logger import setup_logger\nsetup_logger()\n\nimport os\nimport pandas as pd\nimport numpy as np\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nfrom tqdm import tqdm\nimport copy\nimport json\n\nimport torch\nfrom torch.utils.data import random_split","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:18:39.763583Z","iopub.execute_input":"2021-06-22T08:18:39.764029Z","iopub.status.idle":"2021-06-22T08:18:40.782319Z","shell.execute_reply.started":"2021-06-22T08:18:39.763981Z","shell.execute_reply":"2021-06-22T08:18:40.781468Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def 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\n\ndef load_data_dicts(path):\n    with open(path, 'r') as f:\n        data = json.load(f)\n        \n    for d in data:\n        if len(d['annotations']) > 0:\n            for idx in range(len(d['annotations'])):\n                d['annotations'][idx]['category_id'] -= 1\n    \n    return data","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:18:40.784632Z","iopub.execute_input":"2021-06-22T08:18:40.784990Z","iopub.status.idle":"2021-06-22T08:18:40.792051Z","shell.execute_reply.started":"2021-06-22T08:18:40.784962Z","shell.execute_reply":"2021-06-22T08:18:40.791225Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_path = '../input/covid-detectron2-preprocessing/train_data_dicts.json'\nval_path = '../input/covid-detectron2-preprocessing/val_data_dicts.json'\n\nDatasetCatalog.register('covid_train', lambda: load_data_dicts(train_path))\nDatasetCatalog.register('covid_val', lambda: load_data_dicts(val_path))","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:18:40.793132Z","iopub.execute_input":"2021-06-22T08:18:40.793556Z","iopub.status.idle":"2021-06-22T08:18:40.809178Z","shell.execute_reply.started":"2021-06-22T08:18:40.793523Z","shell.execute_reply":"2021-06-22T08:18:40.808315Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def custom_mapper(dataset_dict):\n    dataset_dict = copy.deepcopy(dataset_dict)\n    image = read_xray(dataset_dict['file_name'])\n\n    transform_list = [T.Resize((800,800)),\n                      T.RandomBrightness(0.8, 1.2),\n                      T.RandomFlip(prob=0.5, horizontal=False, vertical=True),\n                      T.RandomFlip(prob=0.5, horizontal=True, vertical=False)\n                      ]\n    image, transforms = T.apply_transform_gens(transform_list, image)\n    dataset_dict[\"image\"] = torch.as_tensor(np.expand_dims(image, axis=0).astype(\"float32\"))\n\n    annos = [\n        utils.transform_instance_annotations(obj, transforms, image.shape)\n        for obj in dataset_dict.pop(\"annotations\")\n    ]\n    instances = utils.annotations_to_instances(annos, image.shape)\n    dataset_dict[\"instances\"] = utils.filter_empty_instances(instances)\n    return dataset_dict","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:18:40.810719Z","iopub.execute_input":"2021-06-22T08:18:40.811148Z","iopub.status.idle":"2021-06-22T08:18:40.820563Z","shell.execute_reply.started":"2021-06-22T08:18:40.811110Z","shell.execute_reply":"2021-06-22T08:18:40.819522Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Trainer(DefaultTrainer):\n    @classmethod\n    def build_train_loader(cls, cfg):\n        return build_detection_train_loader(cfg, mapper=custom_mapper)","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:18:40.823026Z","iopub.execute_input":"2021-06-22T08:18:40.823515Z","iopub.status.idle":"2021-06-22T08:18:40.828962Z","shell.execute_reply.started":"2021-06-22T08:18:40.823477Z","shell.execute_reply":"2021-06-22T08:18:40.827928Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfg = get_cfg()\ncfg.merge_from_file(model_zoo.get_config_file(\"COCO-Detection/retinanet_R_50_FPN_3x.yaml\"))\ncfg.DATASETS.TRAIN = (\"covid_train\",)\ncfg.DATASETS.TEST = (\"covid_val\",)\ncfg.DATALOADER.NUM_WORKERS = 2\ncfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url(\"COCO-Detection/retinanet_R_50_FPN_3x.yaml\") \ncfg.SOLVER.IMS_PER_BATCH = 4\ncfg.SOLVER.BASE_LR = 0.00025  # pick a good LR\ncfg.SOLVER.MAX_ITER = 10000\ncfg.SOLVER.CHECKPOINT_PERIOD = 1000\ncfg.SOLVER.STEPS = []        # do not decay learning rate\ncfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = 256   \ncfg.MODEL.ROI_HEADS.NUM_CLASSES = 3 \n\nos.makedirs(cfg.OUTPUT_DIR, exist_ok=True)\ntrainer = Trainer(cfg) \ntrainer.resume_or_load(resume=False)\ntrainer.train()","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:18:40.832135Z","iopub.execute_input":"2021-06-22T08:18:40.832752Z"},"trusted":true},"execution_count":null,"outputs":[]}]}