{"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":"try:\n    import pylibjpeg\nexcept:\n    !mkdir -p /root/.cache/torch/hub/checkpoints/\n    !cp ../input/effdet-models/efficientnetv2_t_agc-3620981a.pth /root/.cache/torch/hub/checkpoints/\n    !pip install ../input/effdet-models/pydicom-2.3.0-py3-none-any.whl\n    !pip install ../input/effdet-models/pylibjpeg-1.4.0-py3-none-any.whl\n    !pip install ../input/effdet-models/pylibjpeg_libjpeg-1.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\n    !pip install ../input/effdet-models/python_gdcm-3.0.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\n    !pip install ../input/effdet-models/pycocotools-2.0.2-cp37-cp37m-linux_x86_64.whl\n#     !pip install ../input/rsna-2022-whl/torch-1.12.1-cp37-cp37m-manylinux1_x86_64.whl\n#     !pip install ../input/rsna-2022-whl/torchvision-0.13.1-cp37-cp37m-manylinux1_x86_64.whl","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:02.41214Z","iopub.execute_input":"2022-10-27T06:21:02.412756Z","iopub.status.idle":"2022-10-27T06:21:02.430981Z","shell.execute_reply.started":"2022-10-27T06:21:02.412719Z","shell.execute_reply":"2022-10-27T06:21:02.430091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport torch\n# import matplotlib.pyplot as plt\n# import seaborn as sns\n# import ast\nimport re\nimport sys\n\nimport pydicom as dicom\nimport pylibjpeg\n\neffdet_path = \"../input/effdet-models/effdet\"\nsys.path.append(effdet_path)\n\n\ntimm_path = \"../input/effdet-models/timm-pytorch-image-models\"\nsys.path.append(timm_path)\nimport timm\nfrom timm.data import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD\nimport matplotlib.pyplot as plt\n# from matplotlib import patches\n# import sklearn\nimport os\nfrom tqdm import tqdm\n\nomega_path = \"../input/effdet-models/omegaconf\"\nsys.path.append(omega_path)\nfrom omegaconf import OmegaConf\n\neffunet_path = \"../input/effdet-models/efficientunet-pytorch-0.0.6\"\nsys.path.append(effunet_path)\n\n# yolo_path = \"../input/effdet-models/yolov7\"\n# sys.path.append(yolo_path)\n\n# from effdet import create_model\n\nimport glob\n# import sklearn\nimport math\nimport random\nimport numpy as np\n\nfrom PIL import Image\n\n# import cv2\n# import albumentations as A\n# from albumentations.pytorch import ToTensorV2\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset, DataLoader\nfrom torch import optim\nfrom torchvision import transforms\n# import torchvision.models as models\nimport torchvision.transforms as T\nimport torchvision.transforms.functional as TF\n# from transformers import get_cosine_schedule_with_warmup\n\nimport warnings\n\nwarnings.filterwarnings('ignore')\n# from sklearn import metrics, model_selection, preprocessing\n\n# from sklearn.model_selection import GroupKFold\n\n\n# pos_weight = torch.tensor(pos_weight)\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\ndevice","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:02.4332Z","iopub.execute_input":"2022-10-27T06:21:02.433648Z","iopub.status.idle":"2022-10-27T06:21:02.453346Z","shell.execute_reply.started":"2022-10-27T06:21:02.433586Z","shell.execute_reply":"2022-10-27T06:21:02.452222Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n\nIMAGES_DIR='../input/rsna-2022-cervical-spine-fracture-detection/test_images'\nTRAIN_IMAGES_PATH='../input/rsna-2022-cervical-spine-fracture-detection/train_images'\nTEST_IMAGES_PATH='../input/rsna-2022-cervical-spine-fracture-detection/test_images'","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:02.455456Z","iopub.execute_input":"2022-10-27T06:21:02.455828Z","iopub.status.idle":"2022-10-27T06:21:02.465727Z","shell.execute_reply.started":"2022-10-27T06:21:02.455791Z","shell.execute_reply":"2022-10-27T06:21:02.4643Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# segmentation_checkpoint=\"../input/effdet-models/axial_segmentation_effseg_132508-epoch-100.pth\"\nsegmentation_checkpoint=\"../input/effdet-models/axial_segmentation_effseg_095521-epoch-51.pth\"\n\n\n# axial_det_checkpoint1=\"../input/effdet-models/axial_detection_effdet_134352-epoch-52.pth\"\naxial_det_checkpoint1=\"../input/effdet-models/axial_detection_effdet_151039-epoch-60.pth\"\n# axial_det_checkpoint2=\"../input/effdet-models/axial_detection_effdet_001015-epoch-150.pth\"\n# axial_yolo_checkpoint1=\"../input/effdet-models/yolo_custom4_epoch_099.pt\"","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:02.468796Z","iopub.execute_input":"2022-10-27T06:21:02.469116Z","iopub.status.idle":"2022-10-27T06:21:02.476052Z","shell.execute_reply.started":"2022-10-27T06:21:02.469091Z","shell.execute_reply":"2022-10-27T06:21:02.475154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from models.experimental import attempt_load\n# yolo_model = attempt_load(axial_yolo_checkpoint1, map_location=device)\n# yolo_model = yolo_model.eval()","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:02.479442Z","iopub.execute_input":"2022-10-27T06:21:02.479711Z","iopub.status.idle":"2022-10-27T06:21:02.488953Z","shell.execute_reply.started":"2022-10-27T06:21:02.479687Z","shell.execute_reply":"2022-10-27T06:21:02.488042Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # for test, use these\n# train_df = pd.read_csv('../input/rsna-2022-cervical-spine-fracture-detection/train.csv').set_index('StudyInstanceUID')\n\n# IMAGES_DIR='../input/rsna-2022-cervical-spine-fracture-detection/train_images'\n# TRAIN_IMAGES_PATH='../input/rsna-2022-cervical-spine-fracture-detection/train_images'\n# TEST_IMAGES_PATH='../input/rsna-2022-cervical-spine-fracture-detection/test_images'\n\n# test_slices = glob.glob(f'{TRAIN_IMAGES_PATH}/1.2.826.0.1.3680043.90*/*')\n# test_slices = [re.findall(f'{TRAIN_IMAGES_PATH}/(.*)/(.*).dcm', s)[0] for s in test_slices]\n# df_test_slices = pd.DataFrame(data=test_slices, columns=['StudyInstanceUID', 'Slice']).astype({'Slice': int})\n\n# df_test_slices\n\n# #test end\n\ntest_slices = glob.glob(f'{TEST_IMAGES_PATH}/*/*')\ntest_slices = [re.findall(f'{TEST_IMAGES_PATH}/(.*)/(.*).dcm', s)[0] for s in test_slices]\ndf_test_slices = pd.DataFrame(data=test_slices, columns=['StudyInstanceUID', 'Slice']).astype({'Slice': int})\ndf_test_slices","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:02.66273Z","iopub.execute_input":"2022-10-27T06:21:02.663415Z","iopub.status.idle":"2022-10-27T06:21:02.77458Z","shell.execute_reply.started":"2022-10-27T06:21:02.663379Z","shell.execute_reply":"2022-10-27T06:21:02.773594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test_slices = df_test_slices.set_index('StudyInstanceUID')\ndf_test_slices[\"Start\"] = df_test_slices.groupby('StudyInstanceUID').apply(lambda df: df.Slice.min())\n# df_test_slices[\"End\"] = df_test_slices.groupby('StudyInstanceUID').apply(lambda df: df.Slice.max())\ndf_test_slices = df_test_slices.sort_values(['StudyInstanceUID', 'Slice']).reset_index(drop=False)\ndf_test_slices","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:02.776394Z","iopub.execute_input":"2022-10-27T06:21:02.776717Z","iopub.status.idle":"2022-10-27T06:21:02.798491Z","shell.execute_reply.started":"2022-10-27T06:21:02.77668Z","shell.execute_reply":"2022-10-27T06:21:02.797599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rescale_img_to_hu(dcm_ds):\n    \"\"\"Rescales the image to Hounsfield unit.\n    \"\"\"\n    return dcm_ds.pixel_array * dcm_ds.RescaleSlope + dcm_ds.RescaleIntercept\n\ndef normalize_hu_t(data):\n    # normalize to 0-1\n    # return (data - data.min()) / data.max()\n    return np.clip(data, a_min=-2242., a_max=2242.) / 2242.\n\n\ndef load_dicom(path):\n    \"\"\"\n    This supports loading both regular and compressed JPEG images. \n    See the first sell with `pip install` commands for the necessary dependencies\n    \"\"\"\n    ds=dicom.dcmread(path) \n\n    img = rescale_img_to_hu(ds)\n\n    return img, ds.PixelSpacing[0]\n","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:02.801336Z","iopub.execute_input":"2022-10-27T06:21:02.801591Z","iopub.status.idle":"2022-10-27T06:21:02.807965Z","shell.execute_reply.started":"2022-10-27T06:21:02.801568Z","shell.execute_reply":"2022-10-27T06:21:02.806876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class DcmDataSet(torch.utils.data.Dataset):    \n    def __init__(self, df, path, image_size=512):\n        super().__init__()\n        self.df = df\n        self.path = path\n        \n        self.len = len(self.df)\n        self.image_size = image_size\n        \n        # 이걸 무조건 해야 덴다.\n        # 어떤 이미지들이 512 가 아니다. 그래서 여기서 일단 바까줘야 한다. \n        self.transform = T.Resize((image_size, image_size))\n        \n    def __getitem__(self, i):\n        \n        try:\n            s = self.df.iloc[i] # 지금꺼\n            gpath = os.path.join(self.path, s.StudyInstanceUID, f'{s.Slice}.dcm')\n            \n            g, pixel_spacing = load_dicom(gpath) \n            g = normalize_hu_t(g)\n            \n\n        except Exception as ex:\n            print(ex)\n            return None, None, None\n        \n        return self.transform(torch.as_tensor(g, dtype=torch.float).unsqueeze(0)), pixel_spacing, s.Slice == s.Start\n    def __len__(self):\n        return self.len\n\nds = DcmDataSet(df_test_slices, IMAGES_DIR)\n","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:02.811009Z","iopub.execute_input":"2022-10-27T06:21:02.811671Z","iopub.status.idle":"2022-10-27T06:21:02.82122Z","shell.execute_reply.started":"2022-10-27T06:21:02.811636Z","shell.execute_reply":"2022-10-27T06:21:02.820297Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 8\ndl = DataLoader(ds, batch_size=batch_size, shuffle=False, num_workers=min(os.cpu_count(), batch_size))\n\nx, pixel_spacings, is_start = next(iter(dl))\nprint(x.min(), x.max())\nprint(x.shape)\nprint(pixel_spacings, is_start)","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:02.823519Z","iopub.execute_input":"2022-10-27T06:21:02.823822Z","iopub.status.idle":"2022-10-27T06:21:03.296575Z","shell.execute_reply.started":"2022-10-27T06:21:02.823797Z","shell.execute_reply":"2022-10-27T06:21:03.294987Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from efficientunet import *\ndef get_axial_segmentation_model(checkpoint):\n    model = get_efficientunet_b5(out_channels=2, concat_input=True, pretrained=False)\n    \n    state = torch.load(checkpoint, map_location=torch.device(device))\n    model.load_state_dict(state[\"model\"])\n    model.eval()\n    return model.to(device)\n    \nseg_model = get_axial_segmentation_model(segmentation_checkpoint)","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:03.298688Z","iopub.execute_input":"2022-10-27T06:21:03.299047Z","iopub.status.idle":"2022-10-27T06:21:08.575555Z","shell.execute_reply.started":"2022-10-27T06:21:03.299013Z","shell.execute_reply":"2022-10-27T06:21:08.574561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from effdet import create_model\n\ndef get_axial_detection_model(checkpoint, image_size=512):\n    model = create_model('efficientdetv2_dt' , bench_task='predict' , num_classes=1 , image_size=(image_size, image_size), pretrained=False, max_det_per_image=1)\n\n    state = torch.load(checkpoint, map_location=torch.device(device))\n    model.load_state_dict(state[\"model\"])\n    \n    model = model.eval()\n    return model.to(device)\n\ndef get_axial_detection_models(checkpoints):\n    models = []\n    for checkpoint in checkpoints:\n        model = get_axial_detection_model(checkpoint)\n        models.append(model)\n    return models\n\neffdet_model = get_axial_detection_model(axial_det_checkpoint1, 768)\n# effdet_models = get_axial_detection_models([axial_det_checkpoint1])\n# effdet_models = get_axial_detection_models([axial_det_checkpoint1, axial_det_checkpoint2])","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:08.578619Z","iopub.execute_input":"2022-10-27T06:21:08.58054Z","iopub.status.idle":"2022-10-27T06:21:11.711529Z","shell.execute_reply.started":"2022-10-27T06:21:08.5805Z","shell.execute_reply":"2022-10-27T06:21:11.710524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# IMAGE_SIZES=[640, 512]\n# det_model_names=['yolo', 'effdet'] # effdet\n# det_models = [yolo_model] + effdet_models\n# det_models = [yolo_model]","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:11.713798Z","iopub.execute_input":"2022-10-27T06:21:11.714181Z","iopub.status.idle":"2022-10-27T06:21:11.719537Z","shell.execute_reply.started":"2022-10-27T06:21:11.71414Z","shell.execute_reply":"2022-10-27T06:21:11.718492Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_axial_boundary_from_segmentation(seg, pixel_spacing, throw=100, tol=0.2, max_mm=100):\n    \"\"\"\n    seg : H x W\n    \"\"\"\n    image_size = seg.shape[0]\n    min_size = min(image_size, max_mm / pixel_spacing)\n    \n    rows, columns = seg.nonzero(as_tuple=True)\n    rows.sort()\n    columns.sort()\n    \n    throw = min(len(rows) // 2, throw)\n    \n    if(len(rows)) == 0:\n        return torch.tensor([0, 0, image_size, image_size]).to(device)\n    \n    xmin, xmax = columns[throw], columns[-throw]\n    ymin, ymax = rows[throw], rows[-throw]\n    \n    w = (xmax - xmin) * (1 + tol)\n    h = (ymax - ymax) * (1 + tol)\n    new_size = max(w, h, min_size)\n    new_size = min(image_size, new_size)\n    \n    xcenter, ycenter = (xmax + xmin) / 2, (ymax + ymin) / 2\n    \n    xmin = torch.min(torch.tensor(image_size - new_size), xcenter - new_size / 2)\n    xmin = xmin.clip(min=0)\n    \n    ymin = torch.min(torch.tensor(image_size - new_size), ycenter - new_size / 2)\n    ymin = ymin.clip(min=0)\n    \n    return torch.stack([xmin, ymin, xmin + new_size, ymin + new_size])","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:11.720992Z","iopub.execute_input":"2022-10-27T06:21:11.721598Z","iopub.status.idle":"2022-10-27T06:21:11.732428Z","shell.execute_reply.started":"2022-10-27T06:21:11.721559Z","shell.execute_reply":"2022-10-27T06:21:11.731448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def predict_seg(x, model, seg_img_size=256):\n    \"\"\"\n    return: N x 1 x H x W\n    \"\"\"\n    x = TF.resize(x, (seg_img_size, seg_img_size))\n    logits = model(x)\n\n    classification_score, mse_score = logits.sigmoid().chunk(2, dim=1)\n    classification_pred = classification_score.gt(0.5).float()\n    pred = (classification_pred * mse_score)\n    \n    return pred","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:11.737358Z","iopub.execute_input":"2022-10-27T06:21:11.737635Z","iopub.status.idle":"2022-10-27T06:21:11.745724Z","shell.execute_reply.started":"2022-10-27T06:21:11.737611Z","shell.execute_reply":"2022-10-27T06:21:11.744882Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_axial_boundary_from_seg(segs, pixel_spacings, seg_img_size=256):\n    boundary_list = []\n    for i in range(segs.shape[0]):\n        seg = segs[i, 0, :, :]\n        \n        boundary = get_axial_boundary_from_segmentation(seg, pixel_spacings[i], throw=int(100. / 512. * seg_img_size), tol=0.2, max_mm=100. / 512. * seg_img_size)\n        boundary_list.append(boundary)\n    boundary_list = torch.stack(boundary_list, axis=0) * (512. / seg_img_size)\n    return boundary_list","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:11.747829Z","iopub.execute_input":"2022-10-27T06:21:11.748678Z","iopub.status.idle":"2022-10-27T06:21:11.755847Z","shell.execute_reply.started":"2022-10-27T06:21:11.74864Z","shell.execute_reply":"2022-10-27T06:21:11.754822Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# def convert_yolo_result(pred):\n# #     pred = model(x)[0]\n#     max_indices = torch.argmax(pred[:, :, 4], dim=1)\n#     max_values = pred[torch.arange(pred.shape[0]), max_indices, :] # N x 6\n    \n#     bboxes, scores = max_values[:, :4], max_values[:, 4]\n#     bboxes[:, 2] += bboxes[:, 0]\n#     bboxes[:, 3] += bboxes[:, 1]\n#     return bboxes, scores\n\ndef predict_det(x, model):\n    \n    pred_result = model(x) # N x 1 x 6\n    \n#     if isinstance(pred_result, tuple) is True:\n#         # yolo\n#         return convert_yolo_result(pred_result[0])\n#     else:\n    return pred_result[:, 0, :4], pred_result[:, 0, 4]\n        \n    \n    \ndef crop_resize_images(imgs_tensor, boundary_list, img_size=512):\n    croped_list = []\n    for i in range(imgs_tensor.shape[0]):\n        xmin, ymin, xmax, ymax = boundary_list[i, :]\n        xmin, ymin, xmax, ymax = int(xmin), int(ymin), int(xmax), int(ymax)\n        # print(xmin, ymin, xmax, ymax)\n        croped = TF.crop(imgs_tensor[i, :, :, :], top=ymin, left=xmin, height=ymax-ymin, width=xmax-xmin)\n        croped = TF.resize(croped, (img_size, img_size))\n        croped_list.append(croped)\n        \n    return torch.stack(croped_list, 0)\n\ndef get_original_bbox(bbox, boundary, image_size=512.):\n    scale = image_size / (boundary[:, [2]] - boundary[:, [0]])\n    \n    org_bbox = bbox / scale\n    org_bbox[:, 0] += boundary[:, 0]\n    org_bbox[:, 1] += boundary[:, 1]\n    org_bbox[:, 2] += boundary[:, 0]\n    org_bbox[:, 3] += boundary[:, 1]\n    \n    return org_bbox\n\n","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:11.757089Z","iopub.execute_input":"2022-10-27T06:21:11.757502Z","iopub.status.idle":"2022-10-27T06:21:11.769666Z","shell.execute_reply.started":"2022-10-27T06:21:11.757457Z","shell.execute_reply":"2022-10-27T06:21:11.768311Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_bbox_class(seg, bbox):\n    \"\"\"\n    label 은 0.125 의 단위로, \n    seg: H x W\n    bbox: [xmin, ymin, xmax, ymax]\n    \"\"\"\n    xmin, ymin, xmax, ymax = bbox.int()\n    area = seg[ymin:ymax, xmin:xmax]\n    \n    # print(area)\n    result = torch.mean(area[area>0])\n    result = torch.round(result / 0.125)\n    \n    return result","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:11.771391Z","iopub.execute_input":"2022-10-27T06:21:11.771816Z","iopub.status.idle":"2022-10-27T06:21:11.783287Z","shell.execute_reply.started":"2022-10-27T06:21:11.771782Z","shell.execute_reply":"2022-10-27T06:21:11.782469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_bbox_class_list(seg_list, seg_bboxes):\n    class_list = []\n    for i in range(seg_list.shape[0]):\n        class_index = get_bbox_class(seg_list[i, :, :], seg_bboxes[i, :])\n        class_list.append(class_index)\n        \n    return torch.stack(class_list)","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:11.784673Z","iopub.execute_input":"2022-10-27T06:21:11.785079Z","iopub.status.idle":"2022-10-27T06:21:11.794914Z","shell.execute_reply.started":"2022-10-27T06:21:11.785046Z","shell.execute_reply":"2022-10-27T06:21:11.793978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ndef get_class_score(scores, class_list, eps=1e-2):\n    result = scores.new_zeros((scores.shape[0], 8)) + eps\n    class_list = torch.nan_to_num(class_list).long()\n    result[torch.arange(scores.shape[0]), class_list] = scores\n    \n    return result\n\ndef check_detection_result(det_result, img_size=512., threshold=0.2):\n    # throw big bboxes\n    areas = (det_result[:, 2] - det_result[:, 0]) * (det_result[:, 3] - det_result[:, 1]) / (img_size * img_size)\n    # print(areas)\n    big_indices = torch.argwhere(areas > threshold)\n    det_result[big_indices, 4] = 0.\n    return det_result\n","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:11.796555Z","iopub.execute_input":"2022-10-27T06:21:11.796899Z","iopub.status.idle":"2022-10-27T06:21:11.807526Z","shell.execute_reply.started":"2022-10-27T06:21:11.796858Z","shell.execute_reply":"2022-10-27T06:21:11.806504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def cal_loss(prob, label):\n    \n    pos_weight = np.array([14, 2, 2, 2, 2, 2, 2, 2])\n    neg_weight = np.array([7, 1, 1, 1, 1, 1, 1, 1])\n    \n    score = pos_weight * label * np.log(prob) + neg_weight * (1 - label) * np.log(1 - prob)\n    \n    weight_total = pos_weight * label + neg_weight * (1 - label)\n    \n    return -score.sum(axis=1) / weight_total.sum(axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:11.809242Z","iopub.execute_input":"2022-10-27T06:21:11.809716Z","iopub.status.idle":"2022-10-27T06:21:11.818039Z","shell.execute_reply.started":"2022-10-27T06:21:11.809673Z","shell.execute_reply":"2022-10-27T06:21:11.817426Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def predict():\n    \n    with torch.no_grad():\n        predictions = []\n        \n#         tqdm_iter = tqdm(dl)\n\n        x0, _, _ = ds[0]\n        x1, _, _ = ds[1]\n        x0, x1 = x0.to(device), x1.to(device)\n        prev2 = torch.stack((x0, x1))\n#         print(prev2.shape)\n\n#         return\n        for x, pixel_spacings, is_starts in tqdm(dl):\n            \n            # x : N x 1 x 512 x 512\n            x = x.to(device)\n            \n            # (N+2), 1, 512, 512\n            x = torch.cat((prev2, x), dim=0)\n            \n            r = x[:-2, :, :, :]\n            g = x[1:-1, :, :, :]\n            b = x[2:, :, :, :]\n            \n            start_indices = torch.argwhere(is_starts)\n            r[start_indices, :, :, :] = b[start_indices, :, :, :]\n            g[start_indices, :, :, :] = b[start_indices, :, :, :]\n\n            prev2 = b[-2:, :, :, :]\n            \n            x = torch.cat((r, g, b), dim=1)\n            \n            batch_probs = x.new_zeros((x.shape[0], 8)) + 1e-3\n            \n            seg_result = predict_seg(x, seg_model)  # N x 1 x 256 x 256\n            \n            active_indices = seg_result.sum(axis=[1, 2, 3]).nonzero().reshape(-1)\n            if active_indices.numel() == 0:\n                predictions.append(batch_probs.cpu())\n                continue\n            \n#             tqdm_iter.set_description(f'{active_indices.numel()}')\n            if active_indices.numel() != batch_size:\n                x = x[active_indices, :, :, :]\n                seg_result = seg_result[active_indices, :, :, :]\n                pixel_spacings = pixel_spacings[active_indices]\n            \n            \n            axial_boundary = get_axial_boundary_from_seg(seg_result, pixel_spacings, seg_img_size=256)  # N x 4\n            \n#             for i, det_model in enumerate(det_models):\n                \n            croped_x = crop_resize_images(x, axial_boundary, 768)\n\n#             det_model_name = det_model_names[i]\n#             det_model_name = 'effdet'\n#             if det_model_name == 'yolo':\n#                 croped_x = croped_x * 0.5 + 0.5\n            bboxes, scores = predict_det(croped_x, effdet_model)\n\n            # unit 512 x 512\n            bboxes = get_original_bbox(bboxes, axial_boundary, 768) \n            class_list = get_bbox_class_list(seg_result[:, 0, :, :], bboxes / 2)\n            probs = get_class_score(scores, class_list) # N x 7\n\n            batch_probs[active_indices, :] = probs\n\n#             predictions.append(batch_probs / len(det_models))\n            predictions.append(batch_probs.cpu())\n        \n        return torch.concat(predictions).numpy()\npredictions = predict()\n# predictions","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:11.819497Z","iopub.execute_input":"2022-10-27T06:21:11.820154Z","iopub.status.idle":"2022-10-27T06:21:52.319855Z","shell.execute_reply.started":"2022-10-27T06:21:11.820119Z","shell.execute_reply":"2022-10-27T06:21:52.318634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_effnet_pred = pd.DataFrame(\n    data=predictions, columns=['patient_overall'] + [f'C{i}' for i in range(1, 8)]\n)\ndf_test_pred = pd.concat([df_test_slices, df_effnet_pred], axis=1).sort_values(['StudyInstanceUID', 'Slice'])\ndf_patient_pred = df_test_pred.groupby('StudyInstanceUID').apply(lambda df: df.max())\n\n# clip\nmin_clip_value = 0.01\nmax_clip_value = 0.02\n# min_clip_value = 0.001\n# max_clip_value = 0.024\ndf_patient_pred[[f'C{i}' for i in range(1, 8)]] = df_patient_pred[[f'C{i}' for i in range(1, 8)]].clip(lower=min_clip_value, upper=1-max_clip_value)\n\n# overall 를 max 로 정하기\ndf_patient_pred[\"patient_overall\"] = df_patient_pred[[f'C{i}' for i in range(1, 8)]].max(axis=1)\n\n#overall 를 1-neg 로 정하기\n# df_patient_pred[\"patient_overall\"] = np.clip(1 - (1 - df_patient_pred[[f'C{i}' for i in range(1, 8)]]).product(axis=1), a_min=clip_value, a_max=1-clip_value)\n\ndf_patient_pred = df_patient_pred[['patient_overall'] + [f'C{i}' for i in range(1, 8)]]\ndf_patient_pred","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:52.321552Z","iopub.execute_input":"2022-10-27T06:21:52.322731Z","iopub.status.idle":"2022-10-27T06:21:52.360612Z","shell.execute_reply.started":"2022-10-27T06:21:52.322688Z","shell.execute_reply":"2022-10-27T06:21:52.35952Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# prob = df_patient_pred.values\n# label = train_df.loc[df_patient_pred.index].values\n\n# losses = cal_loss(prob, label)\n# print(np.mean(losses))\n# list(losses)\n","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:52.362318Z","iopub.execute_input":"2022-10-27T06:21:52.362801Z","iopub.status.idle":"2022-10-27T06:21:52.367636Z","shell.execute_reply.started":"2022-10-27T06:21:52.362762Z","shell.execute_reply":"2022-10-27T06:21:52.366412Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# df = pd.read_csv('../input/rsna-2022-cervical-spine-fracture-detection/test.csv')\ndf_test = pd.read_csv(f'../input/rsna-2022-cervical-spine-fracture-detection/test.csv')\n\nif df_test.iloc[0].row_id == '1.2.826.0.1.3680043.10197_C1':\n    # test_images and test.csv are inconsistent in the dev dataset, fixing labels for the dev run.\n    df_test = pd.DataFrame({\n        \"row_id\": ['1.2.826.0.1.3680043.22327_C1', '1.2.826.0.1.3680043.25399_C1', '1.2.826.0.1.3680043.5876_patient_overall'],\n        \"StudyInstanceUID\": ['1.2.826.0.1.3680043.22327', '1.2.826.0.1.3680043.25399', '1.2.826.0.1.3680043.5876'],\n        \"prediction_type\": [\"C1\", \"C1\", \"patient_overall\"]}\n    )\n\ndf_test","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:52.369052Z","iopub.execute_input":"2022-10-27T06:21:52.370089Z","iopub.status.idle":"2022-10-27T06:21:52.388857Z","shell.execute_reply.started":"2022-10-27T06:21:52.370053Z","shell.execute_reply":"2022-10-27T06:21:52.387218Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_sub = df_test.copy()\ndf_sub = df_sub.set_index('StudyInstanceUID').join(df_patient_pred)\ndf_sub['fractured'] = df_sub.apply(lambda r: r[r.prediction_type], axis=1)\ndf_sub","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:52.390575Z","iopub.execute_input":"2022-10-27T06:21:52.391295Z","iopub.status.idle":"2022-10-27T06:21:52.411656Z","shell.execute_reply.started":"2022-10-27T06:21:52.391241Z","shell.execute_reply":"2022-10-27T06:21:52.410467Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_sub[['row_id', 'fractured']].to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-10-27T06:21:52.413677Z","iopub.execute_input":"2022-10-27T06:21:52.414055Z","iopub.status.idle":"2022-10-27T06:21:52.424101Z","shell.execute_reply.started":"2022-10-27T06:21:52.414023Z","shell.execute_reply":"2022-10-27T06:21:52.423002Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}