{"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":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport argparse\nimport os\nimport matplotlib.pyplot as plt\nfrom matplotlib.pyplot import imshow\nimport scipy.io\nimport scipy.misc\nimport PIL\nfrom PIL import ImageFont, ImageDraw, Image\nimport tensorflow as tf\nfrom tensorflow.python.framework.ops import EagerTensor\nimport pydicom\nfrom tensorflow.keras.models import load_model\nimport sklearn\nfrom sklearn import preprocessing\nfrom sklearn.model_selection import train_test_split\nimport pydicom\nfrom tqdm import tqdm\nfrom shutil import copyfile\n\n%matplotlib inline","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-08-05T05:49:21.683731Z","iopub.execute_input":"2021-08-05T05:49:21.684311Z","iopub.status.idle":"2021-08-05T05:49:28.203379Z","shell.execute_reply.started":"2021-08-05T05:49:21.684191Z","shell.execute_reply":"2021-08-05T05:49:28.202307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> **This Competition we are participating for each family members who has lost their dear ones  due to COVID.** YOLOV5\n\nTo Develop this complete model. We are following below steps:\n\n1. Input (DICOM, CSV)\n2. Process Raw Input (Standardized Input CSV)\n3. Process Raw Image (As per Model YOLO Intake - Image Size, EPOC etc., If required Augment the data as data size is less. \n4. Create Model YOLO Input \n5. Configure YOLO\n6. Train YOLO Model ","metadata":{}},{"cell_type":"code","source":"# Prepare Input Path.\ntrain_study_path = '../input/siim-covid19-detection/train_study_level.csv' \ntrain_image_path = '../input/siim-covid19-detection/train_image_level.csv'\n\n# As per YOLO directory structure, Read from other user dataset or Create Directory to store resize images,rescale in different train and test directory\ntrain_resize_images = '/kaggle/working/datasetresize/images/train'\nval_resize_images = '/kaggle/working/datasetresize/images/val'\ntrain_resize_labels = '/kaggle/working/datasetresize/labels/train'\nval_resize_labels = '/kaggle/working/datasetresize/labels/val'\n\nyolo_dir =  '/kaggle/working/yolov5'\n\nos.makedirs(train_resize_images, exist_ok=True)\nos.makedirs(val_resize_images, exist_ok=True)\nos.makedirs(train_resize_labels, exist_ok=True)\nos.makedirs(val_resize_labels, exist_ok=True)\nos.makedirs(yolo_dir, exist_ok=True)\n\n# YOLO parameter\nTRAIN_PATH = train_resize_images\nIMG_SIZE = 512\nBATCH_SIZE = 64\nEPOCHS = 150","metadata":{"execution":{"iopub.status.busy":"2021-08-05T05:49:28.20528Z","iopub.execute_input":"2021-08-05T05:49:28.205736Z","iopub.status.idle":"2021-08-05T05:49:28.21574Z","shell.execute_reply.started":"2021-08-05T05:49:28.205692Z","shell.execute_reply":"2021-08-05T05:49:28.214319Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Read \"train_study_level.csv\"\ntrain_study_data =  pd.read_csv(train_study_path)\ntrain_study_data = train_study_data.rename(columns = {'Negative for Pneumonia': 'Negative', 'Typical Appearance': 'Typical','Indeterminate Appearance': 'Indeterminate','Atypical Appearance': 'Atypical'})\n# Mark the disease type in disease_type column (New) \ntrain_study_data['disease_type'] = 'Negative'\ntrain_study_data.loc[train_study_data['Typical'] == 1,'disease_type']  = 'Typical'\ntrain_study_data.loc[train_study_data['Indeterminate'] == 1,'disease_type']  = 'Indeterminate'\ntrain_study_data.loc[train_study_data['Atypical'] == 1,'disease_type']  = 'Atypical'\n\n# Read \"train_image_level.csv\" \ntrain_image_data =  pd.read_csv(train_image_path)\n\n# Merge both dataset based on Instance ID\ntrain_study_data['StudyInstanceUID'] = train_study_data['id'].apply(lambda x: x.replace('_study', ''))\ndel train_study_data['id']\ntrain_image_data = train_image_data.merge(train_study_data, on='StudyInstanceUID')\n\n# Encode/Respresent \"String\" to Numeric Integer for easy calculation\ntrain_image_data['disease_type_id'] = train_image_data['disease_type']\nlabel_encode = preprocessing.LabelEncoder()\nlabel_encode.fit(train_image_data['disease_type_id'])\ntrain_image_data['disease_type_id']=label_encode.transform(train_image_data['disease_type_id'])\n\ntrain_image_data['id_image'] = train_image_data['id']\ntrain_image_data['id'] = train_image_data['id'].apply(lambda x: x.replace('_image', ''))\n\n#train_image_data.to_csv(\"train_image_data.csv\")","metadata":{"execution":{"iopub.status.busy":"2021-08-05T05:49:28.21864Z","iopub.execute_input":"2021-08-05T05:49:28.219145Z","iopub.status.idle":"2021-08-05T05:49:28.347089Z","shell.execute_reply.started":"2021-08-05T05:49:28.219095Z","shell.execute_reply":"2021-08-05T05:49:28.34603Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load meta.csv file\nmeta_df = pd.read_csv('../input/siim-covid19-resized-to-512px-jpg/meta.csv')\ntrain_meta_df = meta_df.loc[meta_df.split == 'train']\ntrain_meta_df = train_meta_df.drop('split', axis=1)\ntrain_meta_df.columns = ['id', 'dim0', 'dim1']\n\n# Merge with meta_df\ntrain_image_data = train_image_data.merge(train_meta_df, on='id',how=\"left\")\ntrain_image_data['path'] = train_image_data.apply(lambda row: f'../input/siim-covid19-resized-to-512px-jpg/train/{row.id}.jpg', axis=1)\n\n# Get image level labels\ntrain_image_data['image_level'] = train_image_data.apply(lambda row: row.label.split(' ')[0], axis=1)\n\ntrain_image_data.loc[train_image_data['image_level'] == 'opacity', 'image_level_id'] = 0\ntrain_image_data.loc[train_image_data['image_level'] == 'none', 'image_level_id'] = 1\ntrain_image_data['image_level_id'] = train_image_data['image_level_id'].apply(np.int64)\n#train_image_data['image_level_id'] = labels_image_level\n\n# Write as csv file\ntrain_image_data.to_csv('train_image_data.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2021-08-05T05:49:28.348988Z","iopub.execute_input":"2021-08-05T05:49:28.349407Z","iopub.status.idle":"2021-08-05T05:49:28.752301Z","shell.execute_reply.started":"2021-08-05T05:49:28.349376Z","shell.execute_reply":"2021-08-05T05:49:28.751272Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create train and validation split.\ntrain_df, valid_df = train_test_split(train_image_data, test_size=0.2, random_state=42, stratify=train_image_data.image_level.values)\n\ntrain_df.loc[:, 'split'] = 'train'\nvalid_df.loc[:, 'split'] = 'valid'\n\ndata_split_df = pd.concat([train_df, valid_df]).reset_index(drop=True)\ndata_split_df.head(5)","metadata":{"execution":{"iopub.status.busy":"2021-08-05T05:49:28.753903Z","iopub.execute_input":"2021-08-05T05:49:28.754382Z","iopub.status.idle":"2021-08-05T05:49:28.817185Z","shell.execute_reply.started":"2021-08-05T05:49:28.754318Z","shell.execute_reply":"2021-08-05T05:49:28.816029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'Size of Split dataset (Train VS Val): {len(data_split_df)}, training images: {len(train_df)}. validation images: {len(valid_df)}')","metadata":{"execution":{"iopub.status.busy":"2021-08-05T05:49:28.819005Z","iopub.execute_input":"2021-08-05T05:49:28.819764Z","iopub.status.idle":"2021-08-05T05:49:28.826589Z","shell.execute_reply.started":"2021-08-05T05:49:28.819719Z","shell.execute_reply":"2021-08-05T05:49:28.825408Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Show visual progress bar and Move the images to relevant split folder in working .\nfor i in tqdm(range(len(data_split_df))):\n    row = data_split_df.loc[i]\n    if row.split == 'train':\n        copyfile(row.path, f'/kaggle/working/datasetresize/images/train/{row.id}.jpg')\n    else:\n        copyfile(row.path, f'/kaggle/working/datasetresize/images/val/{row.id}.jpg')\n","metadata":{"execution":{"iopub.status.busy":"2021-08-05T05:49:28.828299Z","iopub.execute_input":"2021-08-05T05:49:28.829154Z","iopub.status.idle":"2021-08-05T05:50:19.711621Z","shell.execute_reply.started":"2021-08-05T05:49:28.829109Z","shell.execute_reply":"2021-08-05T05:50:19.709582Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Get the raw bounding box by parsing the row value of the label column.\n# Ref: https://www.kaggle.com/yujiariyasu/plot-3positive-classes\ndef get_bbox(row):\n    bboxes = []\n    bbox = []\n    for i, l in enumerate(row.label.split(' ')):\n        if (i % 6 == 0) | (i % 6 == 1):\n            continue\n        bbox.append(float(l))\n        if i % 6 == 5:\n            bboxes.append(bbox)\n            bbox = []  \n            \n    return bboxes\n\n# Scale the bounding boxes according to the size of the resized image. \ndef scale_bbox(row, bboxes):\n    # Get scaling factor\n    scale_x = IMG_SIZE/row.dim1\n    scale_y = IMG_SIZE/row.dim0\n    \n    scaled_bboxes = []\n    for bbox in bboxes:\n        x = int(np.round(bbox[0]*scale_x, 4))\n        y = int(np.round(bbox[1]*scale_y, 4))\n        x1 = int(np.round(bbox[2]*(scale_x), 4))\n        y1= int(np.round(bbox[3]*scale_y, 4))\n\n        scaled_bboxes.append([x, y, x1, y1]) # xmin, ymin, xmax, ymax\n        \n    return scaled_bboxes\n\n# Convert the bounding boxes in YOLO format.\ndef get_yolo_format_bbox(img_w, img_h, bboxes):\n    yolo_boxes = []\n    for bbox in bboxes:\n        w = bbox[2] - bbox[0] # xmax - xmin\n        h = bbox[3] - bbox[1] # ymax - ymin\n        xc = bbox[0] + int(np.round(w/2)) # xmin + width/2\n        yc = bbox[1] + int(np.round(h/2)) # ymin + height/2\n        \n        yolo_boxes.append([xc/img_w, yc/img_h, w/img_w, h/img_h]) # x_center y_center width height\n    \n    return yolo_boxes","metadata":{"execution":{"iopub.status.busy":"2021-08-05T05:50:19.71551Z","iopub.execute_input":"2021-08-05T05:50:19.715907Z","iopub.status.idle":"2021-08-05T05:50:19.728733Z","shell.execute_reply.started":"2021-08-05T05:50:19.715868Z","shell.execute_reply":"2021-08-05T05:50:19.727277Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Write scaled boundary box in .txt for train and val folder in label folder\n# In case we have NONE as class we don't need to populate the boundary box .txt file\n# Show visual progress bar and Move the images to relevant split folder in working .\nfor i in tqdm(range(len(data_split_df))):\n    row = data_split_df.loc[i]\n    \n    if row.split == 'train':\n        # Get image id\n        img_id = row.id\n        # Get image-level label\n        label = row.image_level\n        if label=='opacity':\n            file_name = f'/kaggle/working/datasetresize/labels/train/{img_id}.txt'\n            # Get bboxes\n            bboxes = get_bbox(row)\n            # Scale bounding boxes\n            scale_bboxes = scale_bbox(row, bboxes)\n            # Format for YOLOv5\n            yolo_bboxes = get_yolo_format_bbox(IMG_SIZE, IMG_SIZE, scale_bboxes)\n\n            with open(file_name, 'w') as f:\n                for bbox in yolo_bboxes:\n                    bbox = [row.image_level_id] + bbox\n                    bbox = [str(i) for i in bbox]\n                    bbox = ' '.join(bbox)\n                    f.write(bbox)\n                    f.write('\\n')\n        \n    else:\n        # Get image id\n        img_id = row.id\n        # Get image-level label\n        label = row.image_level\n        if label=='opacity':\n            file_name = f'/kaggle/working/datasetresize/labels/val/{img_id}.txt'\n            # Get bboxes\n            bboxes = get_bbox(row)\n            # Scale bounding boxes\n            scale_bboxes = scale_bbox(row, bboxes)\n            # Format for YOLOv5\n            yolo_bboxes = get_yolo_format_bbox(IMG_SIZE, IMG_SIZE, scale_bboxes)\n\n            with open(file_name, 'w') as f:\n                for bbox in yolo_bboxes:\n                    bbox = [row.image_level_id] + bbox\n                    bbox = [str(i) for i in bbox]\n                    bbox = ' '.join(bbox)\n                    f.write(bbox)\n                    f.write('\\n')\n        ","metadata":{"execution":{"iopub.status.busy":"2021-08-05T05:50:19.731471Z","iopub.execute_input":"2021-08-05T05:50:19.731974Z","iopub.status.idle":"2021-08-05T05:50:23.633201Z","shell.execute_reply.started":"2021-08-05T05:50:19.731929Z","shell.execute_reply":"2021-08-05T05:50:23.631305Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Validation for image and corresponding boxes (txt)\nimport matplotlib.image as mpimg\n# Read Images\nimage = mpimg.imread('/kaggle/working/datasetresize/images/train/000a312787f2.jpg')  \n# Output Images\nplt.imshow(image)","metadata":{"execution":{"iopub.status.busy":"2021-08-05T05:50:23.635167Z","iopub.execute_input":"2021-08-05T05:50:23.635661Z","iopub.status.idle":"2021-08-05T05:50:23.911643Z","shell.execute_reply.started":"2021-08-05T05:50:23.635602Z","shell.execute_reply":"2021-08-05T05:50:23.910362Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lbdf = pd.read_csv('/kaggle/working/datasetresize/labels/train/000a312787f2.txt')\nprint(lbdf)","metadata":{"execution":{"iopub.status.busy":"2021-08-05T05:50:23.913268Z","iopub.execute_input":"2021-08-05T05:50:23.913761Z","iopub.status.idle":"2021-08-05T05:50:23.925196Z","shell.execute_reply.started":"2021-08-05T05:50:23.913715Z","shell.execute_reply":"2021-08-05T05:50:23.923831Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(lbdf.count)","metadata":{"execution":{"iopub.status.busy":"2021-08-05T05:50:23.927189Z","iopub.execute_input":"2021-08-05T05:50:23.928119Z","iopub.status.idle":"2021-08-05T05:50:23.938609Z","shell.execute_reply.started":"2021-08-05T05:50:23.928073Z","shell.execute_reply":"2021-08-05T05:50:23.937142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!git clone https://github.com/ultralytics/yolov5  # clone repo\n%cd yolov5\n# Install dependencies\n%pip install -qr requirements.txt  # install dependencies\n\n%cd ../\nimport torch\nprint(f\"Setup complete. Using torch {torch.__version__} ({torch.cuda.get_device_properties(0).name if torch.cuda.is_available() else 'CPU'})\")","metadata":{"execution":{"iopub.status.busy":"2021-08-05T05:50:23.940509Z","iopub.execute_input":"2021-08-05T05:50:23.943153Z","iopub.status.idle":"2021-08-05T05:50:39.593703Z","shell.execute_reply.started":"2021-08-05T05:50:23.942933Z","shell.execute_reply":"2021-08-05T05:50:39.592606Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Install W&B \n!pip install -q --upgrade wandb\n# Login \nimport wandb\n#wandb.login()\n\nfrom kaggle_secrets import UserSecretsClient\nuser_secrets = UserSecretsClient() \npersonal_key_for_api = user_secrets.get_secret(\"wandbpass\")\n! wandb login $personal_key_for_api","metadata":{"execution":{"iopub.status.busy":"2021-08-05T05:50:39.596881Z","iopub.execute_input":"2021-08-05T05:50:39.597254Z","iopub.status.idle":"2021-08-05T05:50:53.338792Z","shell.execute_reply.started":"2021-08-05T05:50:39.597222Z","shell.execute_reply":"2021-08-05T05:50:53.336189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create .yaml file \nimport yaml\n\n\ndata_yaml = dict(\n    #path = '/kaggle/working/datasetresize',\n    train = '../datasetresize/images/train',\n    val = '../datasetresize/images/val',\n    nc = 1,\n    names = ['opacity']\n)\n\n# Note that I am creating the file in the yolov5/data/ directory.\nwith open(f'yolov5/data/datageoai.yaml', 'w') as outfile:\n    yaml.dump(data_yaml, outfile, default_flow_style=True)\n    \n%cat yolov5/data/datageoai.yaml","metadata":{"execution":{"iopub.status.busy":"2021-08-05T05:50:53.340097Z","iopub.status.idle":"2021-08-05T05:50:53.340582Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd yolov5","metadata":{"execution":{"iopub.status.busy":"2021-08-05T05:50:53.341953Z","iopub.status.idle":"2021-08-05T05:50:53.342867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMG_SIZE = 512\nBATCH_SIZE = 64\nEPOCHS = 150\n\n!python train.py --img {IMG_SIZE} \\\n                     --batch {BATCH_SIZE} \\\n                     --epochs {EPOCHS} \\\n                     --data datageoai.yaml \\\n                     --weights yolov5s.pt \\\n                     --save_period 10\\\n                     --project yolov5-covid19-geoai-output\\\n                     --name yolov5s-e-150-img-512-btc-64-output","metadata":{"execution":{"iopub.status.busy":"2021-08-05T05:50:53.344355Z","iopub.status.idle":"2021-08-05T05:50:53.345197Z"},"trusted":true},"execution_count":null,"outputs":[]}]}