{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceType":"competition","sourceId":24800,"datasetId":1042002,"databundleVersionId":1831594},{"sourceType":"datasetVersion","sourceId":1800066,"datasetId":1069809,"databundleVersionId":1837523},{"sourceType":"datasetVersion","sourceId":1800777,"datasetId":1069787,"databundleVersionId":1838236}],"dockerImageVersionId":30034,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np, pandas as pd\nfrom glob import glob\nimport shutil, os\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import GroupKFold\nfrom tqdm.notebook import tqdm\nimport seaborn as sns","metadata":{"papermill":{"duration":0.926929,"end_time":"2021-01-01T09:44:54.403588","exception":false,"start_time":"2021-01-01T09:44:53.476659","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:06:42.875159Z","iopub.execute_input":"2025-01-02T09:06:42.875457Z","iopub.status.idle":"2025-01-02T09:06:43.68355Z","shell.execute_reply.started":"2025-01-02T09:06:42.875435Z","shell.execute_reply":"2025-01-02T09:06:43.682801Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Data Import\n1. We are working with a dataset of images resized to 256x256 due to limited computational resources.\n2. Basic preprocessing is applied to streamline the model training process.","metadata":{}},{"cell_type":"code","source":"train_df = pd.read_csv(f'../input/vinbigdata-256-image-dataset/vinbigdata/train.csv')\ntrain_df.head()","metadata":{"papermill":{"duration":0.262045,"end_time":"2021-01-01T09:44:54.691965","exception":false,"start_time":"2021-01-01T09:44:54.42992","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:06:43.685418Z","iopub.execute_input":"2025-01-02T09:06:43.685699Z","iopub.status.idle":"2025-01-02T09:06:43.859016Z","shell.execute_reply.started":"2025-01-02T09:06:43.685674Z","shell.execute_reply":"2025-01-02T09:06:43.858321Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df['image_path'] = f'/kaggle/input/vinbigdata-256-image-dataset/vinbigdata/train/'+train_df.image_id+('.jpg')\ntrain_df.head()","metadata":{"papermill":{"duration":0.086788,"end_time":"2021-01-01T09:44:54.805857","exception":false,"start_time":"2021-01-01T09:44:54.719069","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:06:43.860854Z","iopub.execute_input":"2025-01-02T09:06:43.861082Z","iopub.status.idle":"2025-01-02T09:06:43.917288Z","shell.execute_reply.started":"2025-01-02T09:06:43.86106Z","shell.execute_reply":"2025-01-02T09:06:43.916451Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## EDA\nWe observed that the dataset is highly imbalanced. Therefore, we applied an oversampling technique to balance the class distribution and ensure fair representation of all classes.","metadata":{}},{"cell_type":"code","source":"train_df['image_id'].value_counts()\n# Example:\n# f51434ef988e30a05f8b0986814d9485: 1444:\n# The image with this ID has 1444 bounding box annotations.\n# This means that there are 1444 objects or findings detected in this image.","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:06:43.918504Z","iopub.execute_input":"2025-01-02T09:06:43.918852Z","iopub.status.idle":"2025-01-02T09:06:43.940843Z","shell.execute_reply.started":"2025-01-02T09:06:43.918818Z","shell.execute_reply":"2025-01-02T09:06:43.939861Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# total number of images\ntrain_df['image_id'].nunique() ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:06:43.941983Z","iopub.execute_input":"2025-01-02T09:06:43.942328Z","iopub.status.idle":"2025-01-02T09:06:43.958357Z","shell.execute_reply.started":"2025-01-02T09:06:43.942293Z","shell.execute_reply":"2025-01-02T09:06:43.957581Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df['class_id'].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:06:43.959449Z","iopub.execute_input":"2025-01-02T09:06:43.959711Z","iopub.status.idle":"2025-01-02T09:06:43.965657Z","shell.execute_reply.started":"2025-01-02T09:06:43.959688Z","shell.execute_reply":"2025-01-02T09:06:43.964983Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Step 1: Calculate the maximum class count\nmax_count = train_df['class_id'].value_counts().max()\n\n# Step 2: Randomly oversample each class\ntrain_df = train_df.groupby('class_id').apply(lambda x: x.sample(max_count, replace=True, random_state=42)).reset_index(drop=True)\n\n# Step 3: Check the new class distribution\nprint(train_df['class_id'].value_counts())\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:06:43.966585Z","iopub.execute_input":"2025-01-02T09:06:43.966812Z","iopub.status.idle":"2025-01-02T09:06:44.223978Z","shell.execute_reply.started":"2025-01-02T09:06:43.96679Z","shell.execute_reply":"2025-01-02T09:06:44.223235Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Pre-Processing","metadata":{}},{"cell_type":"markdown","source":"\n## Remove class_id = 14\n\n1. The class_id=14 represent a class that is not relevant for training (\"No Finding\").\n2. Removing this class ensures that the model only focuses on the classes that are of interest, improving performance and reducing noise in training.\n\n## Impact on Training\n1. Excluding irrelevant or redundant classes reduces dataset complexity and improves model focus.\n2. Resetting the index ensures consistency in further processing steps (e.g., splitting the dataset or iterating through rows).","metadata":{"papermill":{"duration":0.027478,"end_time":"2021-01-01T09:44:54.861374","exception":false,"start_time":"2021-01-01T09:44:54.833896","status":"completed"},"tags":[]}},{"cell_type":"code","source":"train_df = train_df[train_df.class_id!=14].reset_index(drop = True)","metadata":{"papermill":{"duration":0.05543,"end_time":"2021-01-01T09:44:54.944088","exception":false,"start_time":"2021-01-01T09:44:54.888658","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:06:44.225036Z","iopub.execute_input":"2025-01-02T09:06:44.225248Z","iopub.status.idle":"2025-01-02T09:06:44.370749Z","shell.execute_reply.started":"2025-01-02T09:06:44.225227Z","shell.execute_reply":"2025-01-02T09:06:44.369807Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Pre-processing for Model Compatibility\n- YOLO models require bounding box coordinates to be in a normalized format instead of absolute pixel values. Therefore, we need to preprocess the data to ensure it is compatible with the YOLO model.","metadata":{"papermill":{"duration":0.027303,"end_time":"2021-01-01T09:44:54.999199","exception":false,"start_time":"2021-01-01T09:44:54.971896","status":"completed"},"tags":[]}},{"cell_type":"code","source":"\ntrain_df['x_min'] = train_df.apply(lambda row: (row.x_min)/row.width, axis =1)\ntrain_df['y_min'] = train_df.apply(lambda row: (row.y_min)/row.height, axis =1)\n\ntrain_df['x_max'] = train_df.apply(lambda row: (row.x_max)/row.width, axis =1)\ntrain_df['y_max'] = train_df.apply(lambda row: (row.y_max)/row.height, axis =1)\n\ntrain_df['x_mid'] = train_df.apply(lambda row: (row.x_max+row.x_min)/2, axis =1)\ntrain_df['y_mid'] = train_df.apply(lambda row: (row.y_max+row.y_min)/2, axis =1)\n\ntrain_df['w'] = train_df.apply(lambda row: (row.x_max-row.x_min), axis =1)\ntrain_df['h'] = train_df.apply(lambda row: (row.y_max-row.y_min), axis =1)\n\ntrain_df['area'] = train_df['w']*train_df['h']\ntrain_df.head()","metadata":{"papermill":{"duration":7.821668,"end_time":"2021-01-01T09:45:02.854149","exception":false,"start_time":"2021-01-01T09:44:55.032481","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:06:44.371919Z","iopub.execute_input":"2025-01-02T09:06:44.372149Z","iopub.status.idle":"2025-01-02T09:07:42.849537Z","shell.execute_reply.started":"2025-01-02T09:06:44.372127Z","shell.execute_reply":"2025-01-02T09:07:42.848793Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Feature and Label Extraction\n**Purpose:**   \nSelect the relevant features (x_min, y_min, x_max, etc.) and labels (class_id) for training the model.  \n**Explanation:**  \nThe features list includes bounding box coordinates, dimensions, and area, which are important for object detection models.\nX: A subset of the DataFrame containing the selected features.\ny: The target variable (class labels).\nThe shapes of X and y are printed to verify the data dimensions.\n","metadata":{}},{"cell_type":"code","source":"features = ['x_min', 'y_min', 'x_max', 'y_max', 'x_mid', 'y_mid', 'w', 'h', 'area']\nX = train_df[features]\ny = train_df['class_id']\nX.shape, y.shape","metadata":{"papermill":{"duration":0.040387,"end_time":"2021-01-01T09:45:02.923416","exception":false,"start_time":"2021-01-01T09:45:02.883029","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:42.850574Z","iopub.execute_input":"2025-01-02T09:07:42.850783Z","iopub.status.idle":"2025-01-02T09:07:42.880004Z","shell.execute_reply.started":"2025-01-02T09:07:42.850763Z","shell.execute_reply":"2025-01-02T09:07:42.879235Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Class Mapping\n**Purpose:**   \nMap class_id to their corresponding class_name and sort them.  \n**Explanation:**   \n1. Extracts unique pairs of class_id and class_name from the dataset.\n2. Sorts class names by their corresponding class_id.\n3. Converts all class names to strings to ensure consistency.","metadata":{}},{"cell_type":"code","source":"class_ids, class_names = list(zip(*set(zip(train_df.class_id, train_df.class_name))))\nclasses = list(np.array(class_names)[np.argsort(class_ids)])\nclasses = list(map(lambda x: str(x), classes))","metadata":{"papermill":{"duration":0.050418,"end_time":"2021-01-01T09:45:03.002944","exception":false,"start_time":"2021-01-01T09:45:02.952526","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:42.881123Z","iopub.execute_input":"2025-01-02T09:07:42.881456Z","iopub.status.idle":"2025-01-02T09:07:42.982003Z","shell.execute_reply.started":"2025-01-02T09:07:42.881422Z","shell.execute_reply":"2025-01-02T09:07:42.981125Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Cross-Validation with GroupKFold\n**Purpose:**  \nSplit the dataset into 5 folds for cross-validation while ensuring that data from the same group (rad_id) does not appear in both training and validation sets within the same fold.  \n- Avoids data leakage: Ensures the model doesn’t see information from the same group in both training and validation.\n- Improves generalization: Mimics real-world scenarios by validating on unseen groups.\n- Balanced splits: Creates validation folds with unique groups while maintaining a balance.","metadata":{"papermill":{"duration":0.052492,"end_time":"2021-01-01T09:47:56.110766","exception":false,"start_time":"2021-01-01T09:47:56.058274","status":"completed"},"tags":[]}},{"cell_type":"code","source":"gkf  = GroupKFold(n_splits = 5)\ntrain_df['fold'] = -1\nfor fold, (train_idx, val_idx) in enumerate(gkf.split(train_df, groups = train_df.image_id.tolist())):\n    # added one \"fold\" column at last\n    train_df.loc[val_idx, 'fold'] = fold\ntrain_df.head()","metadata":{"papermill":{"duration":0.134603,"end_time":"2021-01-01T09:47:56.297774","exception":false,"start_time":"2021-01-01T09:47:56.163171","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:42.983204Z","iopub.execute_input":"2025-01-02T09:07:42.983571Z","iopub.status.idle":"2025-01-02T09:07:43.452325Z","shell.execute_reply.started":"2025-01-02T09:07:42.983514Z","shell.execute_reply":"2025-01-02T09:07:43.45154Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fold","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:43.453251Z","iopub.execute_input":"2025-01-02T09:07:43.45346Z","iopub.status.idle":"2025-01-02T09:07:43.457967Z","shell.execute_reply.started":"2025-01-02T09:07:43.45344Z","shell.execute_reply":"2025-01-02T09:07:43.457142Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Organizing Dataset for YOLO\n \n**Prepare Data for YOLO Training:** \n\n- YOLO models require separate directories or lists of image paths for training and validation.\nThis step organizes the image paths for each fold.\nSupport Cross-Validation:\n\n- In cross-validation, different folds act as validation sets in each iteration. This code ensures the correct data split for the current fold.\nEnsure Data Integrity:\n\n- By splitting data based on folds, it avoids any overlap between training and validation sets.","metadata":{}},{"cell_type":"code","source":"train_files = []\nval_files   = []\n# Current fold is 4, fold 4 will be our validation set, and the rest will be our training set\nval_files += list(train_df[train_df.fold==fold].image_path.unique())\ntrain_files += list(train_df[train_df.fold!=fold].image_path.unique())\nlen(train_files), len(val_files)","metadata":{"papermill":{"duration":0.086817,"end_time":"2021-01-01T09:47:56.443789","exception":false,"start_time":"2021-01-01T09:47:56.356972","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:43.462602Z","iopub.execute_input":"2025-01-02T09:07:43.46293Z","iopub.status.idle":"2025-01-02T09:07:43.60207Z","shell.execute_reply.started":"2025-01-02T09:07:43.462897Z","shell.execute_reply":"2025-01-02T09:07:43.6012Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_files[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:43.603339Z","iopub.execute_input":"2025-01-02T09:07:43.603599Z","iopub.status.idle":"2025-01-02T09:07:43.608364Z","shell.execute_reply.started":"2025-01-02T09:07:43.603573Z","shell.execute_reply":"2025-01-02T09:07:43.60763Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# train test image labels\nos.makedirs('/kaggle/working/vinbigdata/labels/train', exist_ok = True)\nos.makedirs('/kaggle/working/vinbigdata/labels/val', exist_ok = True)\n\n# train test image paths\nos.makedirs('/kaggle/working/vinbigdata/images/train', exist_ok = True)\nos.makedirs('/kaggle/working/vinbigdata/images/val', exist_ok = True)\n\nlabel_dir = '/kaggle/input/vinbigdata-yolo-labels-dataset/labels'\nfor file in tqdm(train_files):\n    shutil.copy(file, '/kaggle/working/vinbigdata/images/train')\n    filename = file.split('/')[-1].split('.')[0]\n    shutil.copy(os.path.join(label_dir, filename+'.txt'), '/kaggle/working/vinbigdata/labels/train')\n    \nfor file in tqdm(val_files):\n    shutil.copy(file, '/kaggle/working/vinbigdata/images/val')\n    filename = file.split('/')[-1].split('.')[0]\n    shutil.copy(os.path.join(label_dir, filename+'.txt'), '/kaggle/working/vinbigdata/labels/val')","metadata":{"papermill":{"duration":124.654777,"end_time":"2021-01-01T09:50:01.331041","exception":false,"start_time":"2021-01-01T09:47:56.676264","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:43.609686Z","iopub.execute_input":"2025-01-02T09:07:43.610054Z","iopub.status.idle":"2025-01-02T09:07:43.742328Z","shell.execute_reply.started":"2025-01-02T09:07:43.610016Z","shell.execute_reply":"2025-01-02T09:07:43.740838Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Writing the Dataset Configuration to a YAML File","metadata":{"papermill":{"duration":0.055699,"end_time":"2021-01-01T09:50:01.82747","exception":false,"start_time":"2021-01-01T09:50:01.771771","status":"completed"},"tags":[]}},{"cell_type":"code","source":"from os import listdir\nfrom os.path import isfile, join\nimport yaml\n\ncwd = '/kaggle/working/'\n\nwith open(join( cwd , 'train.txt'), 'w') as f:\n    for path in glob('/kaggle/working/vinbigdata/images/train/*'):\n        f.write(path+'\\n')\n            \nwith open(join( cwd , 'val.txt'), 'w') as f:\n    for path in glob('/kaggle/working/vinbigdata/images/val/*'):\n        f.write(path+'\\n')\n\ndata = dict(\n    train =  join( cwd , 'train.txt') ,\n    val   =  join( cwd , 'val.txt' ),\n    nc    = 14,\n    names = classes\n    )\n\nwith open(join( cwd , 'vinbigdata.yaml'), 'w') as outfile:\n    yaml.dump(data, outfile, default_flow_style=False)\n\nf = open(join( cwd , 'vinbigdata.yaml'), 'r')\nprint('\\nyaml:')\nprint(f.read())","metadata":{"papermill":{"duration":0.113001,"end_time":"2021-01-01T09:50:01.996448","exception":false,"start_time":"2021-01-01T09:50:01.883447","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:43.743327Z","iopub.status.idle":"2025-01-02T09:07:43.743688Z","shell.execute_reply":"2025-01-02T09:07:43.743503Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print('Setup complete. Using torch %s %s' % (torch.__version__, torch.cuda.get_device_properties(0) if torch.cuda.is_available() else 'CPU'))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:43.744917Z","iopub.status.idle":"2025-01-02T09:07:43.745453Z","shell.execute_reply":"2025-01-02T09:07:43.745172Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from ultralytics import YOLO\n\n# Load a model\nmodel = YOLO(\"yolo11n.pt\")\n\n# Train the model\ntrain_results = model.train(\n    data=\"vinbigdata.yaml\",  # path to dataset YAML\n    epochs=5,  # number of training epochs\n    imgsz=256,  # training image size\n    device=\"cpu\",  # device to run on, i.e. device=0 or device=0,1,2,3 or device=cpu\n)\n\n# Evaluate model performance on the validation set\nmetrics = model.val()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:52.656674Z","iopub.execute_input":"2025-01-02T09:07:52.657003Z","iopub.status.idle":"2025-01-02T09:07:52.676882Z","shell.execute_reply.started":"2025-01-02T09:07:52.656968Z","shell.execute_reply":"2025-01-02T09:07:52.675623Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%cd {HOME}\n\n!yolo task=detect mode=train model=yolov8s.pt data={dataset.location}/data.yaml epochs=25 imgsz=800 plots=True","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:43.74996Z","iopub.status.idle":"2025-01-02T09:07:43.750542Z","shell.execute_reply":"2025-01-02T09:07:43.75023Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"break","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:43.751575Z","iopub.status.idle":"2025-01-02T09:07:43.752117Z","shell.execute_reply":"2025-01-02T09:07:43.751837Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Setting Up YOLOv5 Environment\n1. Initially our team wanted to use higher yolo model version, but unfortunately kaggle kernel only offer python3.7 which is not compatible with the current ultralytics requirements, hence we will be using yolo v5 for this assignment.\n2. ALso, due to the need to GPUS we are only limited to run this on kaggle.","metadata":{}},{"cell_type":"markdown","source":"# Class Distribution","metadata":{"papermill":{"duration":4.919442,"end_time":"2021-01-01T15:22:26.398681","exception":false,"start_time":"2021-01-01T15:22:21.479239","status":"completed"},"tags":[]}},{"cell_type":"code","source":"plt.figure(figsize = (20,20))\nplt.axis('off')\nplt.imshow(plt.imread('runs/train/exp/labels_correlogram.jpg'));","metadata":{"papermill":{"duration":6.511035,"end_time":"2021-01-01T15:22:37.753063","exception":false,"start_time":"2021-01-01T15:22:31.242028","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:43.753181Z","iopub.status.idle":"2025-01-02T09:07:43.753564Z","shell.execute_reply":"2025-01-02T09:07:43.753353Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize = (20,20))\nplt.axis('off')\nplt.imshow(plt.imread('runs/train/exp/labels.jpg'));","metadata":{"papermill":{"duration":5.977042,"end_time":"2021-01-01T15:22:48.614609","exception":false,"start_time":"2021-01-01T15:22:42.637567","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:43.754781Z","iopub.status.idle":"2025-01-02T09:07:43.755098Z","shell.execute_reply":"2025-01-02T09:07:43.754944Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Batch Image","metadata":{"papermill":{"duration":5.378338,"end_time":"2021-01-01T15:22:59.482837","exception":false,"start_time":"2021-01-01T15:22:54.104499","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nplt.figure(figsize = (15, 15))\nplt.imshow(plt.imread('runs/train/exp/train_batch0.jpg'))\n\nplt.figure(figsize = (15, 15))\nplt.imshow(plt.imread('runs/train/exp/train_batch1.jpg'))\n\nplt.figure(figsize = (15, 15))\nplt.imshow(plt.imread('runs/train/exp/train_batch2.jpg'))","metadata":{"papermill":{"duration":7.317416,"end_time":"2021-01-01T15:23:11.777544","exception":false,"start_time":"2021-01-01T15:23:04.460128","status":"completed"},"tags":[],"_kg_hide-input":true,"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:43.755879Z","iopub.status.idle":"2025-01-02T09:07:43.756237Z","shell.execute_reply":"2025-01-02T09:07:43.756045Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# GT Vs Pred","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(3, 2, figsize = (2*5,3*5), constrained_layout = True)\nfor row in range(3):\n    ax[row][0].imshow(plt.imread(f'runs/train/exp/test_batch{row}_labels.jpg'))\n    ax[row][0].set_xticks([])\n    ax[row][0].set_yticks([])\n    ax[row][0].set_title(f'runs/train/exp/test_batch{row}_labels.jpg', fontsize = 12)\n    \n    ax[row][1].imshow(plt.imread(f'runs/train/exp/test_batch{row}_pred.jpg'))\n    ax[row][1].set_xticks([])\n    ax[row][1].set_yticks([])\n    ax[row][1].set_title(f'runs/train/exp/test_batch{row}_pred.jpg', fontsize = 12)","metadata":{"papermill":{"duration":6.453975,"end_time":"2021-01-01T15:23:23.514717","exception":false,"start_time":"2021-01-01T15:23:17.060742","status":"completed"},"tags":[],"_kg_hide-input":true,"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:43.757038Z","iopub.status.idle":"2025-01-02T09:07:43.75735Z","shell.execute_reply":"2025-01-02T09:07:43.757197Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# (Loss, Map) Vs Epoch","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(30,15))\nplt.axis('off')\nplt.imshow(plt.imread('runs/train/exp/results.png'));","metadata":{"_kg_hide-input":true,"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:43.758267Z","iopub.status.idle":"2025-01-02T09:07:43.758674Z","shell.execute_reply":"2025-01-02T09:07:43.758435Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Confusion Matrix","metadata":{}},{"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,"_kg_hide-input":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:43.759489Z","iopub.status.idle":"2025-01-02T09:07:43.759916Z","shell.execute_reply":"2025-01-02T09:07:43.759717Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Inference","metadata":{"papermill":{"duration":4.941983,"end_time":"2021-01-01T15:23:33.765831","exception":false,"start_time":"2021-01-01T15:23:28.823848","status":"completed"},"tags":[]}},{"cell_type":"code","source":"!python detect.py --weights 'runs/train/exp/weights/best.pt'\\\n--img 640\\\n--conf 0.15\\\n--iou 0.5\\\n--source /kaggle/working/vinbigdata/images/val\\\n--exist-ok","metadata":{"_kg_hide-output":true,"papermill":{"duration":10.763143,"end_time":"2021-01-01T15:23:49.800461","exception":false,"start_time":"2021-01-01T15:23:39.037318","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:43.76083Z","iopub.status.idle":"2025-01-02T09:07:43.761191Z","shell.execute_reply":"2025-01-02T09:07:43.761005Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Inference Plot","metadata":{"papermill":{"duration":5.225725,"end_time":"2021-01-01T15:24:00.706026","exception":false,"start_time":"2021-01-01T15:23:55.480301","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nfrom mpl_toolkits.axes_grid1 import ImageGrid\nimport numpy as np\nimport random\nimport cv2\nfrom glob import glob\nfrom tqdm import tqdm\n\nfiles = glob('runs/detect/exp/*')\nfor _ 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":{"papermill":{"duration":5.31015,"end_time":"2021-01-01T15:24:11.211904","exception":false,"start_time":"2021-01-01T15:24:05.901754","status":"completed"},"tags":[],"trusted":true,"_kg_hide-input":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:43.762026Z","iopub.status.idle":"2025-01-02T09:07:43.762379Z","shell.execute_reply":"2025-01-02T09:07:43.762193Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"shutil.rmtree('/kaggle/working/vinbigdata')\nshutil.rmtree('runs/detect')\nfor file in (glob('runs/train/exp/**/*.png', recursive = True)+glob('runs/train/exp/**/*.jpg', recursive = True)):\n    os.remove(file)","metadata":{"papermill":{"duration":5.709202,"end_time":"2021-01-01T15:24:22.413173","exception":false,"start_time":"2021-01-01T15:24:16.703971","status":"completed"},"tags":[],"trusted":true,"_kg_hide-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2025-01-02T09:07:43.763236Z","iopub.status.idle":"2025-01-02T09:07:43.763623Z","shell.execute_reply":"2025-01-02T09:07:43.763406Z"}},"outputs":[],"execution_count":null}]}