{"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":"!git clone https://github.com/ultralytics/yolov5.git","metadata":{"execution":{"iopub.status.busy":"2023-04-13T12:46:55.871807Z","iopub.execute_input":"2023-04-13T12:46:55.872226Z","iopub.status.idle":"2023-04-13T12:46:58.76821Z","shell.execute_reply.started":"2023-04-13T12:46:55.872102Z","shell.execute_reply":"2023-04-13T12:46:58.767379Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport os\nimport numpy as np\nimport shutil\nimport yaml\nimport matplotlib.pyplot as plt\nimport random\nimport cv2\n\nfrom sklearn import model_selection\nfrom tqdm import tqdm\nfrom glob import glob","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-04-13T12:46:58.771663Z","iopub.execute_input":"2023-04-13T12:46:58.771935Z","iopub.status.idle":"2023-04-13T12:46:59.624769Z","shell.execute_reply.started":"2023-04-13T12:46:58.771907Z","shell.execute_reply":"2023-04-13T12:46:59.623816Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"size = 1024\nTRAIN_LABELS_PATH = './vinbigdata/labels/train'\nVAL_LABELS_PATH = './vinbigdata/labels/val'\nTRAIN_IMAGES_PATH = './vinbigdata/images/train' #12000\nVAL_IMAGES_PATH = './vinbigdata/images/val' #3000\nExternal_DIR = f'../input/vinbigdata-{size}-image-dataset/vinbigdata/train' # 15000\nos.makedirs(TRAIN_LABELS_PATH, exist_ok = True)\nos.makedirs(VAL_LABELS_PATH, exist_ok = True)\nos.makedirs(TRAIN_IMAGES_PATH, exist_ok = True)\nos.makedirs(VAL_IMAGES_PATH, exist_ok = True)","metadata":{"execution":{"iopub.status.busy":"2023-04-13T12:46:59.626048Z","iopub.execute_input":"2023-04-13T12:46:59.626445Z","iopub.status.idle":"2023-04-13T12:46:59.632889Z","shell.execute_reply.started":"2023-04-13T12:46:59.626408Z","shell.execute_reply":"2023-04-13T12:46:59.631811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"original_df = pd.read_csv('../input/vinbigdata-chest-xray-abnormalities-detection/train.csv')\nnumber_of_imageids = len(original_df['image_id'].values)\nprint(f'Total number of image_ids (train + validation) {number_of_imageids}')\n\nnumber_of_images = len(os.listdir('../input/vinbigdata-chest-xray-abnormalities-detection/train'))\nprint(f'Total number of images (train + validation) {number_of_images}')\n\nnumber_of_labels = len(os.listdir('../input/vinbigdata-yolo-labels-dataset/labels'))\nprint(f'Total number of labels (train + validation) {number_of_labels}')","metadata":{"execution":{"iopub.status.busy":"2023-04-13T12:46:59.634367Z","iopub.execute_input":"2023-04-13T12:46:59.634968Z","iopub.status.idle":"2023-04-13T12:47:02.44595Z","shell.execute_reply.started":"2023-04-13T12:46:59.634932Z","shell.execute_reply":"2023-04-13T12:47:02.444938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv(f'../input/vinbigdata-{size}-image-dataset/vinbigdata/train.csv')\nnumber_of_images = len(df['image_id'].values)\nprint(f'Total number of image ids (train + validation) {number_of_images}')\n\ndf = df[df.class_id!=14].reset_index(drop = True)\nnumber_of_images = len(df['image_id'].values)\nprint(f'Total number of image ids after dropping normal images (train + validation) {number_of_images}')\n\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2023-04-13T12:47:02.44971Z","iopub.execute_input":"2023-04-13T12:47:02.449973Z","iopub.status.idle":"2023-04-13T12:47:02.74457Z","shell.execute_reply.started":"2023-04-13T12:47:02.449945Z","shell.execute_reply":"2023-04-13T12:47:02.743673Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = df.drop(columns=['class_name', 'rad_id', 'x_min', 'x_max', 'y_min', 'y_max', 'width', 'height', 'class_id']) # we only need image ids, labels are pre-made\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2023-04-13T12:47:02.747609Z","iopub.execute_input":"2023-04-13T12:47:02.747919Z","iopub.status.idle":"2023-04-13T12:47:02.759448Z","shell.execute_reply.started":"2023-04-13T12:47:02.747888Z","shell.execute_reply":"2023-04-13T12:47:02.758478Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train, df_valid = model_selection.train_test_split(df, test_size=0.15, random_state=42, shuffle=True)","metadata":{"execution":{"iopub.status.busy":"2023-04-13T12:47:02.761246Z","iopub.execute_input":"2023-04-13T12:47:02.761623Z","iopub.status.idle":"2023-04-13T12:47:02.771122Z","shell.execute_reply.started":"2023-04-13T12:47:02.761589Z","shell.execute_reply":"2023-04-13T12:47:02.770467Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"number_of_images = len(df_train['image_id'].values)\nprint(f'Total number of training image_ids {number_of_images}')\n\nnumber_of_images = len(df_valid['image_id'].values)\nprint(f'Total number of validation image_ids {number_of_images}')\n","metadata":{"execution":{"iopub.status.busy":"2023-04-13T12:47:02.7724Z","iopub.execute_input":"2023-04-13T12:47:02.773057Z","iopub.status.idle":"2023-04-13T12:47:02.78514Z","shell.execute_reply.started":"2023-04-13T12:47:02.773019Z","shell.execute_reply":"2023-04-13T12:47:02.784353Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# need to delete duplicate image ids, len(labels) should be equal len(df.imageids.values), ","metadata":{"execution":{"iopub.status.busy":"2023-04-13T12:47:02.786743Z","iopub.execute_input":"2023-04-13T12:47:02.787244Z","iopub.status.idle":"2023-04-13T12:47:02.794059Z","shell.execute_reply.started":"2023-04-13T12:47:02.787189Z","shell.execute_reply":"2023-04-13T12:47:02.79345Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'Total number of training images {len(df_train.image_id.unique())}')\nprint(f'Total number of validation images {len(df_valid.image_id.unique())}')","metadata":{"execution":{"iopub.status.busy":"2023-04-13T12:47:02.796003Z","iopub.execute_input":"2023-04-13T12:47:02.796629Z","iopub.status.idle":"2023-04-13T12:47:02.811864Z","shell.execute_reply.started":"2023-04-13T12:47:02.796594Z","shell.execute_reply":"2023-04-13T12:47:02.811021Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def preproccess_data(df, labels_path, images_path):\n    for img_id in tqdm(df.image_id.unique()):\n        shutil.copy(os.path.join('../input/vinbigdata-yolo-labels-dataset/labels', f\"{img_id}\"+'.txt'), labels_path)\n        shutil.copy(os.path.join(f'/kaggle/input/vinbigdata-{size}-image-dataset/vinbigdata/train', f\"{img_id}.png\"), images_path)","metadata":{"execution":{"iopub.status.busy":"2023-04-13T12:47:02.813375Z","iopub.execute_input":"2023-04-13T12:47:02.813863Z","iopub.status.idle":"2023-04-13T12:47:02.819253Z","shell.execute_reply.started":"2023-04-13T12:47:02.81383Z","shell.execute_reply":"2023-04-13T12:47:02.818261Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preproccess_data(df_train, TRAIN_LABELS_PATH, TRAIN_IMAGES_PATH)\npreproccess_data(df_valid, VAL_LABELS_PATH, VAL_IMAGES_PATH)","metadata":{"execution":{"iopub.status.busy":"2023-04-13T12:47:02.820674Z","iopub.execute_input":"2023-04-13T12:47:02.821251Z","iopub.status.idle":"2023-04-13T12:49:05.490662Z","shell.execute_reply.started":"2023-04-13T12:47:02.821197Z","shell.execute_reply":"2023-04-13T12:49:05.489511Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# check that data was preprocessed correctly\nprint(len(os.listdir(TRAIN_LABELS_PATH)))\nprint(len(os.listdir(TRAIN_IMAGES_PATH)))\n\nprint(len(os.listdir(VAL_LABELS_PATH)))\nprint(len(os.listdir(VAL_IMAGES_PATH)))","metadata":{"execution":{"iopub.status.busy":"2023-04-13T12:49:05.494591Z","iopub.execute_input":"2023-04-13T12:49:05.497148Z","iopub.status.idle":"2023-04-13T12:49:05.536124Z","shell.execute_reply.started":"2023-04-13T12:49:05.497093Z","shell.execute_reply":"2023-04-13T12:49:05.535029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# credit / source https://www.kaggle.com/awsaf49/vinbigdata-cxr-ad-yolov5-14-class-train\nclasses = [ 'Aortic enlargement',\n            'Atelectasis',\n            'Calcification',\n            'Cardiomegaly',\n            'Consolidation',\n            'ILD',\n            'Infiltration',\n            'Lung Opacity',\n            'Nodule/Mass',\n            'Other lesion',\n            'Pleural effusion',\n            'Pleural thickening',\n            'Pneumothorax',\n            'Pulmonary fibrosis']\n\ndata = dict(\n    train =  '../vinbigdata/images/train',\n    val   =  '../vinbigdata/images/val',\n    nc    = 14,\n    names = classes\n    )\n\nwith open('./yolov5/vinbigdata.yaml', 'w') as outfile:\n    yaml.dump(data, outfile, default_flow_style=False)\n    \nf = open('./yolov5/vinbigdata.yaml', 'r')\nprint('\\nyaml:')\nprint(f.read())","metadata":{"execution":{"iopub.status.busy":"2023-04-13T12:49:05.541823Z","iopub.execute_input":"2023-04-13T12:49:05.547883Z","iopub.status.idle":"2023-04-13T12:49:05.569524Z","shell.execute_reply.started":"2023-04-13T12:49:05.547829Z","shell.execute_reply":"2023-04-13T12:49:05.568598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd ./yolov5\n!pip install -q -U -r requirements.txt\n!pip install -q pycocotools>=2.0 seaborn>=0.11.0 thop","metadata":{"execution":{"iopub.status.busy":"2023-04-13T12:49:05.570999Z","iopub.execute_input":"2023-04-13T12:49:05.571658Z","iopub.status.idle":"2023-04-13T12:51:57.266895Z","shell.execute_reply.started":"2023-04-13T12:49:05.571622Z","shell.execute_reply":"2023-04-13T12:51:57.265871Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!WANDB_MODE=\"dryrun\" python train.py --img 1024 --batch 2 --epochs 20 --data ./vinbigdata.yaml --cfg models/yolov5x.yaml --weights yolov5x.pt \n# setting cache will make it run out of memory, max batch size 4 for 1024\n#!WANDB_MODE=\"dryrun\" python train.py --img 640 --batch 16 --epochs 30 --data ./vinbigdata.yaml --cfg models/yolov5x.yaml --weights yolov5x.pt","metadata":{"execution":{"iopub.status.busy":"2023-04-13T12:51:57.268716Z","iopub.execute_input":"2023-04-13T12:51:57.269066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = pd.read_csv(f'/kaggle/input/vinbigdata-{size}-image-dataset/vinbigdata/test.csv')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dir = f'/kaggle/input/vinbigdata-{size}-image-dataset/vinbigdata/test'\nweights_dir = './runs/train/exp/weights/best.pt'\nos.listdir('./runs/train/exp/weights')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!python detect.py --weights $weights_dir\\\n--img 640\\\n--conf 0.005\\\n--iou 0.45\\\n--source $test_dir\\\n--save-txt --save-conf --exist-ok","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# credit / source https://www.kaggle.com/awsaf49/vinbigdata-cxr-ad-yolov5-14-class-infer\ndef yolo2voc(image_height, image_width, bboxes):\n    \"\"\"\n    yolo => [xmid, ymid, w, h] (normalized)\n    voc  => [x1, y1, x2, y1]\n    \n    \"\"\" \n    bboxes = bboxes.copy().astype(float) # otherwise all value will be 0 as voc_pascal dtype is np.int\n    \n    bboxes[..., [0, 2]] = bboxes[..., [0, 2]]* image_width\n    bboxes[..., [1, 3]] = bboxes[..., [1, 3]]* image_height\n    \n    bboxes[..., [0, 1]] = bboxes[..., [0, 1]] - bboxes[..., [2, 3]]/2\n    bboxes[..., [2, 3]] = bboxes[..., [0, 1]] + bboxes[..., [2, 3]]\n    \n    return bboxes","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(glob('runs/detect/exp/labels/*txt'))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# credit / source https://www.kaggle.com/awsaf49/vinbigdata-cxr-ad-yolov5-14-class-infer\nimage_ids = []\nPredictionStrings = []\n\ndef process_submission():\n    for file_path in tqdm(glob('runs/detect/exp/labels/*txt')):\n        image_id = file_path.split('/')[-1].split('.')[0] # extract image id\n        w, h = test_df.loc[test_df.image_id==image_id,['width', 'height']].values[0] #  get the weight & height from  the test df\n        f = open(file_path, 'r')  # open the label text file\n        data = np.array(f.read().replace('\\n', ' ').strip().split(' ')).astype(np.float32).reshape(-1, 6) # move all the labels to the same line..?\n        data = data[:, [0, 5, 1, 2, 3, 4]]\n        bboxes = list(np.round(np.concatenate((data[:, :2], np.round(yolo2voc(h, w, data[:, 2:]))), axis =1).reshape(-1), 1).astype(str))\n        for idx in range(len(bboxes)):\n            bboxes[idx] = str(int(float(bboxes[idx]))) if idx%6!=1 else bboxes[idx] # 6 is the length of  the prediction string, so..?\n        image_ids.append(image_id)\n        PredictionStrings.append(' '.join(bboxes))\n\n    # credit / source: https://www.kaggle.com/awsaf49/vinbigdata-cxr-ad-yolov5-14-class-infer\n    pred_df = pd.DataFrame({'image_id':image_ids,\n                            'PredictionString':PredictionStrings})\n    sub_df = pd.merge(test_df, pred_df, on = 'image_id', how = 'left').fillna(\"14 1 0 0 1 1\")\n    sub_df = sub_df[['image_id', 'PredictionString']]\n    sub_df.to_csv('/kaggle/working/submission_3.csv',index = False)\n    sub_df.tail()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !pip uninstall pandas\n!pip install -q pandas==1.1.5","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"process_submission()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"files = glob('runs/detect/exp/*png')\nfrom mpl_toolkits.axes_grid1 import ImageGrid\n\ndef plot_sample_images():\n    for _ in range(3):\n        row = 4\n        col = 4\n        grid_files = random.sample(files, row*col)\n        images     = []\n        for image_path in tqdm(grid_files):\n            img          = cv2.cvtColor(cv2.imread(image_path), cv2.COLOR_BGR2RGB)\n            images.append(img)\n\n        fig = plt.figure(figsize=(col*5, row*5))\n        grid = ImageGrid(fig, 111,  # similar to subplot(111)\n                         nrows_ncols=(col, row),  # creates 2x2 grid of axes\n                         axes_pad=0.05,  # pad between axes in inch.\n                         )\n\n        for ax, im in zip(grid, images):\n            # Iterating over the grid returns the Axes.\n            ax.imshow(im)\n            ax.set_xticks([])\n            ax.set_yticks([])\n        plt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install -q Pillow==4.0.0\n!pip install -q PIL\n!pip install -q image","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_sample_images()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(30,15))\nplt.axis('off')\nplt.imshow(plt.imread('runs/train/exp/confusion_matrix.png'));","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(30,15))\nplt.axis('off')\nplt.imshow(plt.imread('runs/train/exp/results.png'));","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pwd","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# load yolo submission\nyolo = pd.read_csv('../submission_3.csv')\neffnetb6 = pd.read_csv('/kaggle/input/vinbigdata-2class-prediction/2-cls test pred.csv') # AUC:0.98\npred = pd.merge(yolo, effnetb6, on = 'image_id', how = 'left')\nlow_thr  = 0.08\nhigh_thr = 0.95","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def filter_2cls(row, low_thr=low_thr, high_thr=high_thr):\n    prob = row['target']\n    if prob<low_thr:\n        ## Less chance of having any disease\n        row['PredictionString'] = '14 1 0 0 1 1'\n    elif low_thr<=prob<high_thr:\n        ## More change of having any diesease\n        row['PredictionString']+=f' 14 {prob} 0 0 1 1'\n    elif high_thr<=prob:\n        ## Good chance of having any disease so believe in object detection model\n        row['PredictionString'] = row['PredictionString']\n    else:\n        raise ValueError('Prediction must be from [0-1]')\n    return row","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = pred.apply(filter_2cls, axis=1)\nsub[['image_id', 'PredictionString']].to_csv('../submission.csv',index = False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}