{"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":"markdown","source":"**if you want to see Train & Sumbission Pipeline's result, click the link below here**\n\n1. Train_Pipeline result => https://www.kaggle.com/code/qcqced/strip-ai-efficient-net-regnet-train-pipeline\n2. Submission_Pipeline result => https://www.kaggle.com/code/qcqced/strip-ai-submission-pipeline ","metadata":{}},{"cell_type":"markdown","source":"**Step 1. EDA**\n\n**Step 2. Convert Train Data to 1k(1024,1024) PNG (Use Rasterio Module)**\n\n**Step 3. Convert 1k(1024,1024) PNG Data (Step 2's Data) to No Unnecessary Background Image  \n(Use Seam Carving to remove \"Unnecessary Background\") => Use Rasterio NOT PIL, PIL has potential making kaggle notebook kernel die issue**\n\n**(Because Kaggle Notebook's Computing limits, you can see Step 3's Code & Result from this URL)** => https://www.kaggle.com/qcqced/strip-ai-remove-background-1k-png-image\n\n(Step 3's Idea from @yu4u Thanks yu4u!!, And want to see more detail, click the link below here) \n\n=> https://www.kaggle.com/code/ren4yu/mayo-clinic-removing-background-via-seam-carving\n\n=> https://github.com/yu4u/seam-carving","metadata":{}},{"cell_type":"code","source":"import seaborn as sns\nimport numpy as np \nimport pandas as pd \nimport os, sys, random, gc\nimport torch\nimport torch.nn as nn # neural network module\nimport torch.nn.functional as F # neural network module에서 자주 사용되는 함수\nimport torchvision\nimport matplotlib.pyplot as plt\nimport matplotlib as matp\nimport matplotlib.gridspec as gridspec \nimport cv2, math, shutil # OpenCV => cv2\nimport albumentations as Albu\nfrom torchvision import models\nfrom torchvision import transforms\nfrom albumentations.pytorch import ToTensorV2  \nfrom sklearn.model_selection import train_test_split\nfrom zipfile import ZipFile\nfrom torch.utils.data import Dataset, DataLoader\nfrom sklearn.metrics import roc_auc_score\nfrom tqdm.notebook import tqdm \nfrom transformers import get_cosine_schedule_with_warmup # 스케줄러\n%matplotlib inline","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-09-01T13:16:30.693432Z","iopub.execute_input":"2022-09-01T13:16:30.69394Z","iopub.status.idle":"2022-09-01T13:16:30.709883Z","shell.execute_reply.started":"2022-09-01T13:16:30.693888Z","shell.execute_reply":"2022-09-01T13:16:30.708265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Step 1. Data Upload & Check\n# Goal of Competition => 허혈성 뇌졸증의 원인이 되는 두 가지 혈전증을 병리적 이미지를 통해 분류\n# Evaluation of Competition => Binary Classification\n# CE => cardioembolic, 심인성 색전증\n# LAA => Large artery atherosclerosis, 큰동맥죽상경화증\ndata_path = '../input/mayo-clinic-strip-ai/'\n\nlabels = pd.read_csv(data_path + 'train.csv') # Train Data Set\ntest = pd.read_csv(data_path + 'test.csv')\nsubmission = pd.read_csv(data_path + 'sample_submission.csv')\n\nlabels, test, submission ","metadata":{"execution":{"iopub.status.busy":"2022-09-01T13:16:30.712171Z","iopub.execute_input":"2022-09-01T13:16:30.713078Z","iopub.status.idle":"2022-09-01T13:16:30.749399Z","shell.execute_reply.started":"2022-09-01T13:16:30.713032Z","shell.execute_reply":"2022-09-01T13:16:30.748224Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Center_id \nlabels['center_id'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-09-01T13:16:30.751011Z","iopub.execute_input":"2022-09-01T13:16:30.751668Z","iopub.status.idle":"2022-09-01T13:16:30.761262Z","shell.execute_reply.started":"2022-09-01T13:16:30.751627Z","shell.execute_reply":"2022-09-01T13:16:30.759799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# image_num => 1이상인 데이터 == 122개\nlabels.loc[labels['image_num'] >= 1], len(labels.loc[labels['image_num'] >= 1])","metadata":{"execution":{"iopub.status.busy":"2022-09-01T13:16:30.76323Z","iopub.execute_input":"2022-09-01T13:16:30.763631Z","iopub.status.idle":"2022-09-01T13:16:30.783215Z","shell.execute_reply.started":"2022-09-01T13:16:30.763592Z","shell.execute_reply":"2022-09-01T13:16:30.78162Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# label => (CE, LAA) == (547, 207)\nlabels.loc[labels['label'] == \"CE\"], len(labels.loc[labels['label'] == \"CE\"]) # CE => 547개\nlabels.loc[labels['label'] == \"LAA\"], len(labels.loc[labels['label'] == \"LAA\"]) # LAA => 207개","metadata":{"execution":{"iopub.status.busy":"2022-09-01T13:16:30.785212Z","iopub.execute_input":"2022-09-01T13:16:30.785729Z","iopub.status.idle":"2022-09-01T13:16:30.806351Z","shell.execute_reply.started":"2022-09-01T13:16:30.785684Z","shell.execute_reply":"2022-09-01T13:16:30.805211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.countplot(data=labels, x='label')","metadata":{"execution":{"iopub.status.busy":"2022-09-01T13:16:30.808256Z","iopub.execute_input":"2022-09-01T13:16:30.808977Z","iopub.status.idle":"2022-09-01T13:16:31.004364Z","shell.execute_reply.started":"2022-09-01T13:16:30.80893Z","shell.execute_reply":"2022-09-01T13:16:31.002584Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Label.value / 전체 모수 => (CE, LAA) == (72.5%, 27.5%)\n# labels.label.value_counts() / labels.shape[0] => 이 코드로 대체 가능.\nlen(labels.loc[labels['label'] == \"CE\"]) / len(labels['label']), len(labels.loc[labels['label'] == \"LAA\"]) / len(labels['label']) ","metadata":{"execution":{"iopub.status.busy":"2022-09-01T13:16:31.007057Z","iopub.execute_input":"2022-09-01T13:16:31.007622Z","iopub.status.idle":"2022-09-01T13:16:31.021531Z","shell.execute_reply.started":"2022-09-01T13:16:31.007574Z","shell.execute_reply":"2022-09-01T13:16:31.020308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels.patient_id.nunique() # 627명의 환자가 1개의 병리적 이미지를 가지고 있음 => 한 명의 환자가 CE, LAA에 모두 해당되는 Case가 존재할까??\nplt.figure(figsize=(10,5))\nsns.countplot(labels.groupby(\"patient_id\").image_num.size(), palette=\"Greens_r\")\nplt.xlabel(\"Number of images per patient\")\nplt.title(\"Max image number per patient in train\")","metadata":{"execution":{"iopub.status.busy":"2022-09-01T13:16:31.023184Z","iopub.execute_input":"2022-09-01T13:16:31.024261Z","iopub.status.idle":"2022-09-01T13:16:31.484862Z","shell.execute_reply.started":"2022-09-01T13:16:31.024215Z","shell.execute_reply":"2022-09-01T13:16:31.483306Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels.groupby(\"patient_id\").label.nunique().max() # 그런 환자는 없는 것으로 확인, 단순히 한 명의 환자가 가진 이미지가 여러 장일 수 있는 것.","metadata":{"execution":{"iopub.status.busy":"2022-09-01T13:16:31.486735Z","iopub.execute_input":"2022-09-01T13:16:31.487956Z","iopub.status.idle":"2022-09-01T13:16:31.501631Z","shell.execute_reply.started":"2022-09-01T13:16:31.487904Z","shell.execute_reply":"2022-09-01T13:16:31.500158Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Center와 Target의 관계성 => 특별한 관계는 없는 듯...?\nsns.set_style(style=\"darkgrid\")\nplt.figure(figsize=(15,8))\n\ngraph = sns.histplot(data=labels, x='center_id', hue='label', multiple='dodge', \n                     discrete=True, kde = True)\n\ngraph.set(xlim=(0,12), xticks=np.arange(0,12,1)) # x축 간격 설정\ngraph.set(ylim=(0,195), yticks=np.arange(0,195,15))\ngraph.set(xlabel=\"Center ID\", ylabel=\"Label Count\")\ngraph.set_title('Distribution of Labels by Center', fontsize=16)","metadata":{"execution":{"iopub.status.busy":"2022-09-01T13:16:31.503719Z","iopub.execute_input":"2022-09-01T13:16:31.505346Z","iopub.status.idle":"2022-09-01T13:16:32.02341Z","shell.execute_reply.started":"2022-09-01T13:16:31.505282Z","shell.execute_reply":"2022-09-01T13:16:32.022197Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Step 2. Target Data Check \nnum_img = 4\n\nCE = labels.loc[labels['label'] == \"CE\"]\nLAA = labels.loc[labels['label'] == \"LAA\"]\n\nlast_CE_img_id = CE['image_id'][-num_img:]\nlast_LAA_img_id = LAA['image_id'][-num_img:]\n\nCE_img_id = CE['image_id']\nLAA_img_id = LAA['image_id']\nlast_CE_img_id","metadata":{"execution":{"iopub.status.busy":"2022-09-01T13:16:32.024898Z","iopub.execute_input":"2022-09-01T13:16:32.025327Z","iopub.status.idle":"2022-09-01T13:16:32.039616Z","shell.execute_reply.started":"2022-09-01T13:16:32.025273Z","shell.execute_reply":"2022-09-01T13:16:32.038401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Image Visualization Function => CE와 LAA는 어떤 차이가 있을까??\nimport rasterio\nfrom rasterio.enums import Resampling\nfrom rasterio.transform import Affine\n\nimage_scalar = 0.1\n\ndef img_show(img_ids, rows=2, cols=2): # diseases_name => string type\n    matp.rc('font', size=10)\n    plt.figure(figsize=(40,40))\n    grid = gridspec.GridSpec(rows, cols)\n    \n    for idx, img_id in enumerate(img_ids):\n        img_path = f'{data_path}/train/{img_id}.tif'\n        img = rasterio.open(img_path)\n        image = img.read(out_shape=(img.count, int(img.height * image_scalar), int(img.width * image_scalar)),\n                         resampling=Resampling.bilinear).transpose(1,2,0) # imshow() => (너비, 높이, 채널) 순으로 매개변수를 요구하기 때문에 Transpose 필요함\n        print(image.shape)\n        print(type(image))\n        ax = plt.subplot(grid[idx])\n        ax.imshow(image)","metadata":{"execution":{"iopub.status.busy":"2022-09-01T13:16:32.041306Z","iopub.execute_input":"2022-09-01T13:16:32.041709Z","iopub.status.idle":"2022-09-01T13:16:32.051927Z","shell.execute_reply.started":"2022-09-01T13:16:32.041676Z","shell.execute_reply":"2022-09-01T13:16:32.05095Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_show(last_CE_img_id)","metadata":{"execution":{"iopub.status.busy":"2022-08-05T01:03:38.431947Z","iopub.execute_input":"2022-08-05T01:03:38.432317Z","iopub.status.idle":"2022-08-05T01:04:25.118545Z","shell.execute_reply.started":"2022-08-05T01:03:38.432285Z","shell.execute_reply":"2022-08-05T01:04:25.117468Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_show(last_LAA_img_id)","metadata":{"execution":{"iopub.status.busy":"2022-08-05T01:04:25.119941Z","iopub.execute_input":"2022-08-05T01:04:25.121663Z","iopub.status.idle":"2022-08-05T01:06:04.833671Z","shell.execute_reply.started":"2022-08-05T01:04:25.121623Z","shell.execute_reply":"2022-08-05T01:06:04.832829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"육안으로 확인하면 도저히 차이를 모르겠다.... 신경망이 알아서 패턴을 찾아주겠지??\n내 육안으로 패턴이 보이면 신경망을 쓸 필요가 없으니까~ ","metadata":{}},{"cell_type":"code","source":"# Convert Train image data file dir.\ndir_path = './convert_train'\nos.mkdir(dir_path)","metadata":{"execution":{"iopub.status.busy":"2022-09-01T13:16:32.053761Z","iopub.execute_input":"2022-09-01T13:16:32.054179Z","iopub.status.idle":"2022-09-01T13:16:32.066768Z","shell.execute_reply.started":"2022-09-01T13:16:32.054138Z","shell.execute_reply":"2022-09-01T13:16:32.065628Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Step 2.1 Tiff to Png \nimg_ids = labels['image_id']\nimage_scalar = 2048 # If you Want 1K => change this value to 1024\n\ndef convert_img(img_ids):\n    for img_id in tqdm(img_ids):\n        try:\n            img_path = f'{data_path}/train/{img_id}.tif'\n            image = rasterio.open(img_path)\n            image = image.read(out_shape=(image.count, int(image_scalar), int(image_scalar)),\n                             resampling=Resampling.bilinear)\n            with rasterio.open(f'./convert_train/{img_id}.png', 'w', driver='png', height = image.shape[1], width = image.shape[2], dtype = image.dtype, count=3) as images: # count => Image Channel 개수 (RGB의 경우 3개)\n                images.write(image)\n            #image.save(f'./convert_train/{img_id}.png', 'png')\n            # Image 용량이 너무 커서 Ram 커널 반복적으로 죽는 상황 발생 => @JIRKA BOROVEC님 코드 참조 => Garbage Collection 활용, 누수되는 Ram Memory 활용\n            del image\n            gc.collect()\n            \n        except OSError as e:\n            print(e)","metadata":{"execution":{"iopub.status.busy":"2022-09-01T13:16:32.068286Z","iopub.execute_input":"2022-09-01T13:16:32.069184Z","iopub.status.idle":"2022-09-01T13:16:32.078535Z","shell.execute_reply.started":"2022-09-01T13:16:32.069148Z","shell.execute_reply":"2022-09-01T13:16:32.077614Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Step 2.2 CE Image Convert to Png\nconvert_img(img_ids)","metadata":{"execution":{"iopub.status.busy":"2022-09-01T13:16:40.532781Z","iopub.execute_input":"2022-09-01T13:16:40.533296Z","iopub.status.idle":"2022-09-01T13:18:31.25533Z","shell.execute_reply.started":"2022-09-01T13:16:40.533257Z","shell.execute_reply":"2022-09-01T13:18:31.25341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Step 2.3 Convert PNG Image Data to Zip File\n!zip -r convert_train.zip ./*","metadata":{"execution":{"iopub.status.busy":"2022-07-28T15:23:11.946334Z","iopub.execute_input":"2022-07-28T15:23:11.94726Z","iopub.status.idle":"2022-07-28T15:23:28.063719Z","shell.execute_reply.started":"2022-07-28T15:23:11.947188Z","shell.execute_reply":"2022-07-28T15:23:28.062242Z"}},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Step 2.4 Converted PNG Image Check\nconvert_img = '../input/mayo-clinic-strip-ai-competition-1k-png-data/006388_0.png'\nconvert_img = cv2.imread(convert_img)\nconvert_img = cv2.cvtColor(convert_img, cv2.COLOR_BGR2RGB)\n\nmatp.rc('font', size=10)\nplt.figure(figsize=(20,30))\ngrid = gridspec.GridSpec(1, 1)\n\nax = plt.subplot(grid[0])\nax.imshow(convert_img)\n\nconvert_img.shape","metadata":{"execution":{"iopub.status.busy":"2022-07-28T16:12:08.487726Z","iopub.execute_input":"2022-07-28T16:12:08.488167Z","iopub.status.idle":"2022-07-28T16:12:09.09008Z","shell.execute_reply.started":"2022-07-28T16:12:08.488126Z","shell.execute_reply":"2022-07-28T16:12:09.089117Z"}},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Step 2.5 Converted PNG Image Name Check\ntest_img = '../input/mayo-clinic-strip-ai/train/fe0cca_0.tif'\ntest_img = cv2.imread(test_img)\ntest_img = cv2.cvtColor(test_img, cv2.COLOR_BGR2RGB)\n\nmatp.rc('font', size=10)\nplt.figure(figsize=(20,30))\ngrid = gridspec.GridSpec(1, 1)\n\nax = plt.subplot(grid[0])\nax.imshow(test_img)","metadata":{"execution":{"iopub.status.busy":"2022-07-28T16:00:24.445512Z","iopub.execute_input":"2022-07-28T16:00:24.445947Z","iopub.status.idle":"2022-07-28T16:01:28.42575Z","shell.execute_reply.started":"2022-07-28T16:00:24.445914Z","shell.execute_reply":"2022-07-28T16:01:28.424173Z"}},"execution_count":null,"outputs":[]}]}