{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train = pd.read_csv('/kaggle/input/vinbigdata-chest-xray-abnormalities-detection/train.csv')\ntrain","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test = pd.read_csv('/kaggle/input/vinbigdata-chest-xray-abnormalities-detection/sample_submission.csv')\ntest","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train[train['image_id'] =='9a5094b2563a1ef3ff50dc5c7ff71345']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pydicom\n\ndicom = pydicom.dcmread('/kaggle/input/vinbigdata-chest-xray-abnormalities-detection/test/74b23792db329cff5843e36efb8aa65a.dicom')\ndicom","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# pixel 값이 255를 넘어감\n\ndicom.pixel_array","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dicom.pixel_array.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image = dicom.pixel_array ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nplt.figure(figsize =(16,8))\n\nplt.imshow(image, cmap = 'gray')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"np.stack([image,image,image]).shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from torch.utils.data import Dataset, DataLoader\n\nclass Vinbigdataset (Dataset):\n    def __init__(self,dataframe, image_dir, transforms = None):\n        super().__init__()\n        self.image_ids = dataframe['image_id'].unique()\n        self.df = dataframe\n        self.image_dir = image_dir\n        self.transforms = transforms\n                \n    def __getitem__(self, index):\n        image_id = self.image_ids[index]\n        records = self.df[self.df['image_id']== image_id]\n        records = records.reset_index(drop = True)\n        dicom = pydicom.dcmread(self.image_dir + image_id + '.dicom')\n        image = dicom.pixel_array\n        # dicom 파일은 사람들이 움직이거나 하면 y 절편이 움직임 or 기울기가 변하게됌 --> 밝기에 영향을 줌 \n        \n        intercept = dicom.RescaleIntercept if 'RescaleIntercept' in dicom else 0\n        slope = dicom.RescaleSlope if 'RescaleSlope' in dicom else 1\n        \n        if slope != 1:\n            image = slope * image\n            image = image.astype(np.int16)\n        \n        image += np.int16(intercept)\n        \n        # 3채널로 변경, float32 는 메모리 줄이기위해 쓰는것\n        image = np.stack([image, image, image]).astype(np.float32)\n        # 표준화, dicom 파일은 경사 (y절편이) 제대로 안되어있으면 (ex) 사람이 움직이면) 사진의 밝기에 영향을줌 --> pixel 값의 최소값이 0 이아닐수도있음\n        image = image - image.min()\n        # 최대값으로 나눠서 0과1사이로 변환\n        image = image / image.max()\n        # 채널값을 뒤로 옮김 원랜 0,1,2 순\n        image = image.transpose(1,2,0)\n        if self.transforms:\n            sample = {'image' : image}\n            sample = self.transforms(**sample)\n            image = sample['image']\n        return image, image_id\n                   \n    def __len__(self):\n        return self.image_ids.shape[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from albumentations.pytorch.transforms import ToTensorV2\n\nimport albumentations as al","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_test_transform():\n    return al.Compose([ToTensorV2])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_dataset = Vinbigdataset(test, '/kaggle/input/vinbigdata-chest-xray-abnormalities-detection/test/', get_test_transform())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def collate_fn(batch):\n    return tuple(zip(*batch))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_data_loader = DataLoader(test_dataset, batch_size = 8, num_workers = 4, collate_fn = collate_fn)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 모델가져오기"},{"metadata":{"trusted":true},"cell_type":"code","source":"import torchvision","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# 학습할땐 pretrained = True 로 여기선 가중치를 가져올거기때문에\nmodel = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained = False, pretrained_backbone = False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# 맨마지막층 자체를 바꿔줘야함. 클래스 갯수로 (91 개 -->15개). 그래서 모델 추가\n\nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.roi_heads.box_predictor = FastRCNNPredictor(1024,15)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch\n\ndevice = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')\n\ndevice","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 다른사람 가중치 가져오기"},{"metadata":{"trusted":true},"cell_type":"code","source":"# 혹시 tensorflow h5 가져와도 되는지\n\nmodel.load_state_dict(torch.load('../input/fasterrcnn/fasterrcnn_resnet50_fpn.pth'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# 예측하기전에 고정시키겠다\nmodel.eval()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#gpu 로 돌리겠다\nmodel.to(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub = pd.read_csv('/kaggle/input/vinbigdata-chest-xray-abnormalities-detection/sample_submission.csv')\nsub","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def format_prediction_string(labels, boxes, scores):\n    pred_strings = []\n    for j in zip(labels, scores, boxes):\n        pred_strings.append(\"{0} {1:.4f} {2} {3} {4} {5}\".format(\n            j[0], j[1], j[2][0], j[2][1], j[2][2], j[2][3]))\n\n    return \" \".join(pred_strings)\n\ndetection_threshold = 0.5\nresults = []\n\n# gradient 를 업데이트 하지 않겠다. 예측이니깐\n\nwith torch.no_grad():\n    for images, image_ids in test_data_loader:\n        #gpu 로 환경을 바꿔줌\n        images = list(image.to(device) for image in images)\n        # predict 와 같은것\n        outputs = model(images)\n        for i, image in enumerate(images):\n            image_id = image_ids[i]\n            result = {\n                'image_id': image_id,\n                'PredictionString': '14 1.0 0 0 1 1'\n            }\n\n            boxes = outputs[i]['boxes'].data.cpu().numpy()\n            labels = outputs[i]['labels'].data.cpu().numpy()\n            scores = outputs[i]['scores'].data.cpu().numpy()\n            \n            if len(boxes) > 0:\n                # 정답 클래스가 0부터 들어가기때문 (0~14) 이 대회는 '질병이없다' 를 14 로 정해짐.\n                labels = labels - 1\n                labels[labels == -1] = 14\n                \n                # 일단은 0.5로. 최적화 해야되는부분\n                selected = scores >= detection_threshold\n                \n                boxes = boxes[selected].astype(np.int32)\n                scores = scores[selected]\n                labels = labels[selected]\n\n                if len(boxes) > 0:\n                    result = {\n                        'image_id': image_id,\n                        'PredictionString': format_prediction_string(labels, boxes, scores)}\n                    \n            results.append(result)           ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.DataFrame(results, columns=['image_id', 'PredictionString'])\ntest_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 과제 : 무엇때문에 오류가 나는지 찾아오기."},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}