{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":24800,"databundleVersionId":1831594,"sourceType":"competition"},{"sourceId":1810938,"sourceType":"datasetVersion","datasetId":1075803}],"dockerImageVersionId":30683,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"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\n# for 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","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-09-08T17:45:25.308946Z","iopub.execute_input":"2024-09-08T17:45:25.30935Z","iopub.status.idle":"2024-09-08T17:45:25.315194Z","shell.execute_reply.started":"2024-09-08T17:45:25.309306Z","shell.execute_reply":"2024-09-08T17:45:25.314287Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Display generic output messages\n!pip install colorama\n\n# Library for visualizing bounding boxes\n!pip install bbox-visualizer\n\n# Install ONNX library, will be used to convert from pytorch model to a tf model\n!pip install onnx onnxruntime onnxsim onnx-tf","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:45:25.316863Z","iopub.execute_input":"2024-09-08T17:45:25.31712Z","iopub.status.idle":"2024-09-08T17:46:01.040637Z","shell.execute_reply.started":"2024-09-08T17:45:25.317098Z","shell.execute_reply":"2024-09-08T17:46:01.039389Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import bbox_visualizer as bbv\nimport cv2\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport shutil, os\nimport tensorflow as tf\nimport yaml\n\nfrom colorama import Fore, Back, Style\nfrom IPython.display import Image, display, clear_output\nfrom sklearn.model_selection import GroupShuffleSplit \nfrom tqdm.notebook import tqdm\nfrom typing import List","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:46:01.042879Z","iopub.execute_input":"2024-09-08T17:46:01.043195Z","iopub.status.idle":"2024-09-08T17:46:01.051695Z","shell.execute_reply.started":"2024-09-08T17:46:01.043164Z","shell.execute_reply":"2024-09-08T17:46:01.050807Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !rm -rf /kaggle/working/data\n!mkdir -p /kaggle/working/data","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:46:01.052713Z","iopub.execute_input":"2024-09-08T17:46:01.052963Z","iopub.status.idle":"2024-09-08T17:46:02.053646Z","shell.execute_reply.started":"2024-09-08T17:46:01.05294Z","shell.execute_reply":"2024-09-08T17:46:02.052353Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!cp -r /kaggle/input/vinbigdata-chest-xray-resized-png-1024x1024/* /kaggle/working/data/","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:46:02.056392Z","iopub.execute_input":"2024-09-08T17:46:02.056738Z","iopub.status.idle":"2024-09-08T17:48:53.645508Z","shell.execute_reply.started":"2024-09-08T17:46:02.056707Z","shell.execute_reply":"2024-09-08T17:48:53.644278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!cp /kaggle/input/vinbigdata-chest-xray-abnormalities-detection/train.csv /kaggle/working/data/","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:48:53.647167Z","iopub.execute_input":"2024-09-08T17:48:53.647598Z","iopub.status.idle":"2024-09-08T17:48:54.711441Z","shell.execute_reply.started":"2024-09-08T17:48:53.647554Z","shell.execute_reply":"2024-09-08T17:48:54.709988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!cp /kaggle/input/lastpt/last.pt /kaggle/working/last.pt","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:48:54.714974Z","iopub.execute_input":"2024-09-08T17:48:54.716023Z","iopub.status.idle":"2024-09-08T17:48:56.628073Z","shell.execute_reply.started":"2024-09-08T17:48:54.715966Z","shell.execute_reply":"2024-09-08T17:48:56.626843Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Clone the YoloV9 repository, install the libray, and obtain the model\n!git clone https://github.com/WongKinYiu/yolov9.git\n!wget https://github.com/WongKinYiu/yolov9/releases/download/v0.1/yolov9-e.pt","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:48:56.629617Z","iopub.execute_input":"2024-09-08T17:48:56.629931Z","iopub.status.idle":"2024-09-08T17:48:59.617644Z","shell.execute_reply.started":"2024-09-08T17:48:56.6299Z","shell.execute_reply":"2024-09-08T17:48:59.616708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!wget https://github.com/WongKinYiu/yolov9/releases/download/v0.1/yolov9-c.pt","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:48:59.619019Z","iopub.execute_input":"2024-09-08T17:48:59.619339Z","iopub.status.idle":"2024-09-08T17:49:01.458143Z","shell.execute_reply.started":"2024-09-08T17:48:59.619308Z","shell.execute_reply":"2024-09-08T17:49:01.457144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!wget https://github.com/WongKinYiu/yolov9/releases/download/v0.1/gelan-c.pt","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:49:01.459582Z","iopub.execute_input":"2024-09-08T17:49:01.4599Z","iopub.status.idle":"2024-09-08T17:49:03.12447Z","shell.execute_reply.started":"2024-09-08T17:49:01.459868Z","shell.execute_reply":"2024-09-08T17:49:03.123545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install -r /kaggle/working/yolov9/requirements.txt","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:49:03.129249Z","iopub.execute_input":"2024-09-08T17:49:03.129582Z","iopub.status.idle":"2024-09-08T17:49:15.787363Z","shell.execute_reply.started":"2024-09-08T17:49:03.12955Z","shell.execute_reply":"2024-09-08T17:49:15.786279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMAGE_SIZE = 1024\nTRAIN_IMAGES_DIRECTORY = '/kaggle/working/data/train/'\nTEST_IMAGES_DIRECTORY = '/kaggle/working/data/test/'\n\nTRAIN_IMAGES_PATH_REFACTORED = '/kaggle/working/refactored_data/images/train/'\nTRAIN_LABELS_PATH_REFACTORED = '/kaggle/working/refactored_data/labels/train/'\nVALID_IMAGES_PATH_REFACTORED = '/kaggle/working/refactored_data/images/val/'\nVALID_LABELS_PATH_REFACTORED = '/kaggle/working/refactored_data/labels/val/'","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:49:15.788949Z","iopub.execute_input":"2024-09-08T17:49:15.789336Z","iopub.status.idle":"2024-09-08T17:49:15.796913Z","shell.execute_reply.started":"2024-09-08T17:49:15.789287Z","shell.execute_reply":"2024-09-08T17:49:15.79603Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_csv('data/train.csv')\ntrain_df","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:49:15.798255Z","iopub.execute_input":"2024-09-08T17:49:15.798631Z","iopub.status.idle":"2024-09-08T17:49:15.928073Z","shell.execute_reply.started":"2024-09-08T17:49:15.798599Z","shell.execute_reply":"2024-09-08T17:49:15.927086Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = train_df[train_df.class_id!=14].reset_index(drop = True) ","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:49:15.929252Z","iopub.execute_input":"2024-09-08T17:49:15.929626Z","iopub.status.idle":"2024-09-08T17:49:15.940689Z","shell.execute_reply.started":"2024-09-08T17:49:15.929593Z","shell.execute_reply":"2024-09-08T17:49:15.939807Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:49:15.942222Z","iopub.execute_input":"2024-09-08T17:49:15.94286Z","iopub.status.idle":"2024-09-08T17:49:15.96076Z","shell.execute_reply.started":"2024-09-08T17:49:15.942828Z","shell.execute_reply":"2024-09-08T17:49:15.959798Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_meta_df = pd.read_csv('/kaggle/working/data/train_meta.csv')\ntrain_df = train_df.merge(train_meta_df, on='image_id')\ntrain_df","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:49:15.962054Z","iopub.execute_input":"2024-09-08T17:49:15.962359Z","iopub.status.idle":"2024-09-08T17:49:16.013609Z","shell.execute_reply.started":"2024-09-08T17:49:15.962335Z","shell.execute_reply":"2024-09-08T17:49:16.012752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#x_min, y_min, x_max, y_max normalization값으로 update\ntrain_df['x_min'] = train_df.apply(lambda row: (row.x_min) /row.dim0, axis =1)\ntrain_df['y_min'] = train_df.apply(lambda row: (row.y_min) /row.dim1, axis =1)\n\ntrain_df['x_max'] = train_df.apply(lambda row: (row.x_max) /row.dim0, axis =1)\ntrain_df['y_max'] = train_df.apply(lambda row: (row.y_max) /row.dim1, axis =1)\n#x_mid, y_mid가 추가\n# train_df['x_mid'] = train_df.apply(lambda row: (row.x_min + row.x_max)/2,axis =1)\n# train_df['y_mid'] = train_df.apply(lambda row: (row.y_min + row.y_max)/2, axis =1)\n# #normalization된 width & height 추가\n# train_df['w'] = train_df.apply(lambda row: (row.x_max - row.x_min), axis = 1)\n# train_df['h'] = train_df.apply(lambda row: (row.y_max - row.y_min), axis = 1)\n# #area 추가\n# train_df['area'] = train_df['w']*train_df['h']\ntrain_df","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:49:16.014771Z","iopub.execute_input":"2024-09-08T17:49:16.015234Z","iopub.status.idle":"2024-09-08T17:49:19.552642Z","shell.execute_reply.started":"2024-09-08T17:49:16.01521Z","shell.execute_reply":"2024-09-08T17:49:19.551767Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install ensemble_boxes\nfrom ensemble_boxes import *\nfrom ensemble_boxes import weighted_boxes_fusion\nimport numpy as np","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:49:19.553885Z","iopub.execute_input":"2024-09-08T17:49:19.55425Z","iopub.status.idle":"2024-09-08T17:49:31.378143Z","shell.execute_reply.started":"2024-09-08T17:49:19.554216Z","shell.execute_reply":"2024-09-08T17:49:31.377184Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_id_df = train_df[['image_id']]\n\n# Loại bỏ các bản sao để chỉ giữ lại các giá trị duy nhất\nunique_class_id_df = class_id_df.drop_duplicates()","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:49:31.379613Z","iopub.execute_input":"2024-09-08T17:49:31.379931Z","iopub.status.idle":"2024-09-08T17:49:31.391416Z","shell.execute_reply.started":"2024-09-08T17:49:31.379898Z","shell.execute_reply":"2024-09-08T17:49:31.390469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"unique_class_id_df","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:49:31.394253Z","iopub.execute_input":"2024-09-08T17:49:31.394555Z","iopub.status.idle":"2024-09-08T17:49:31.407323Z","shell.execute_reply.started":"2024-09-08T17:49:31.394529Z","shell.execute_reply":"2024-09-08T17:49:31.406486Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\nimport numpy as np\nimport pandas as pd\nfrom collections import Counter\n\n# Thay đổi giá trị tùy chỉnh nếu cần\niou_thr = 0.4\nskip_box_thr = 0.0001\nviz_images = []\nsigma = 0.1\nnew_data = []\n\nfor i, img_id in enumerate(unique_class_id_df['image_id']):\n    # Đọc ảnh và chuẩn bị các annotations\n    img_annotations = train_df[train_df['image_id'] == img_id]\n    boxes_viz = img_annotations[['x_min', 'y_min', 'x_max', 'y_max']].to_numpy().tolist()\n    labels_viz = img_annotations['class_id'].to_numpy().tolist()\n    \n    boxes_list = []\n    scores_list = []\n    labels_list = []\n    weights = []\n\n    boxes_single = []\n    labels_single = []\n    \n    cls_ids = img_annotations['class_id'].unique().tolist()\n    count_dict = Counter(img_annotations['class_id'].tolist())\n\n    for cid in cls_ids:\n        if count_dict[cid] == 1:\n            labels_single.append(cid)\n            boxes_single.append(\n                img_annotations[img_annotations.class_id == cid][['x_min', 'y_min', 'x_max', 'y_max']].to_numpy().squeeze().tolist()\n            )\n        else:\n            cls_list = img_annotations[img_annotations.class_id == cid]['class_id'].tolist()\n            labels_list.append(cls_list)\n            bbox = img_annotations[img_annotations.class_id == cid][['x_min', 'y_min', 'x_max', 'y_max']].to_numpy()\n            bbox = bbox / [1024, 1024, 1024, 1024]  # Normalize bounding boxes\n            bbox = np.clip(bbox, 0, 1)\n            boxes_list.append(bbox.tolist())\n            scores_list.append(np.ones(len(cls_list)).tolist())\n            weights.append(1)\n\n    if boxes_list:  # Kiểm tra nếu danh sách không rỗng\n        try:\n            # Perform WBF\n            boxes, scores, box_labels = weighted_boxes_fusion(\n                boxes_list, scores_list, labels_list, weights=weights,\n                iou_thr=iou_thr, skip_box_thr=skip_box_thr\n            )\n        except Exception as e:\n            print(f\"Error during weighted_boxes_fusion: {e}\")\n            continue\n        \n        # Convert bounding boxes to original scale\n        boxes = boxes * [1024, 1024, 1024, 1024]\n        boxes = boxes.round(1).tolist()\n        box_labels = box_labels.astype(int).tolist()\n\n        # Append single boxes (those with a single bbox per label)\n        boxes.extend(boxes_single)\n        box_labels.extend(labels_single)\n\n        # Ghi vào new_data\n        for box, label in zip(boxes, box_labels):\n            new_data.append({\n                'image_id': img_id,\n                'class_id': label,\n                'x_min': box[0],\n                'y_min': box[1],\n                'x_max': box[2],\n                'y_max': box[3]\n            })\n\n# Tạo DataFrame mới từ new_data\nnew_df = pd.DataFrame(new_data)\n","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:49:31.408566Z","iopub.execute_input":"2024-09-08T17:49:31.408873Z","iopub.status.idle":"2024-09-08T17:50:23.79962Z","shell.execute_reply.started":"2024-09-08T17:49:31.408848Z","shell.execute_reply":"2024-09-08T17:50:23.798792Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:50:23.800712Z","iopub.execute_input":"2024-09-08T17:50:23.800989Z","iopub.status.idle":"2024-09-08T17:50:23.81675Z","shell.execute_reply.started":"2024-09-08T17:50:23.800964Z","shell.execute_reply":"2024-09-08T17:50:23.815869Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Tạo từ điển ánh xạ từ class_id đến class_name\nclass_id_to_name = dict(zip(train_df['class_id'], train_df['class_name']))\n\n# Thêm cột class_name vào new_df dựa trên class_id\nnew_df['class_name'] = new_df['class_id'].map(class_id_to_name)\n\n# Kiểm tra new_df sau khi thêm cột\nnew_df\n","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:50:23.817904Z","iopub.execute_input":"2024-09-08T17:50:23.818217Z","iopub.status.idle":"2024-09-08T17:50:23.848322Z","shell.execute_reply.started":"2024-09-08T17:50:23.818188Z","shell.execute_reply":"2024-09-08T17:50:23.847505Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"new_df['x_center'] = (new_df['x_max'] + new_df['x_min']) / 2\nnew_df['y_center'] = (new_df['y_max'] + new_df['y_min']) / 2\nnew_df['w'] = (new_df['x_max'] - new_df['x_min'])\nnew_df['h'] = (new_df['y_max'] - new_df['y_min'])\n\n    # Training/validation splitting\nsplitter = GroupShuffleSplit(test_size=0.1)\nsplit = splitter.split(new_df, groups=new_df['image_id'])\ntrain_inds, valid_inds = next(split)\n\nvalid_df = new_df.iloc[valid_inds]\ntrain_df = new_df.iloc[train_inds]\n\n    # Create images and labels directories for both training and validation\nfor folder in [\n    TRAIN_IMAGES_PATH_REFACTORED,\n    TRAIN_LABELS_PATH_REFACTORED,\n    VALID_IMAGES_PATH_REFACTORED,\n    VALID_LABELS_PATH_REFACTORED,\n]:\n    os.makedirs(folder, exist_ok=True)\n\n    # Copy training images to its designated directory, and create a txt file for each image denoting its classes and their positions\nfor image in tqdm(new_df['image_id'].unique()):\n    records = train_df[new_df['image_id'] == image]\n    attributes = records[['class_id', 'x_center', 'y_center', 'w', 'h']].values\n    attributes = np.array(attributes)\n    np.savetxt(\n        os.path.join(\n            TRAIN_LABELS_PATH_REFACTORED,\n            f'{image}.txt'\n        ),\n        attributes,\n        fmt=['%d', '%f', '%f', '%f', '%f']\n    )\n    shutil.copy(\n        os.path.join(\n            TRAIN_IMAGES_DIRECTORY,\n            f'{image}.png'\n        ),\n        TRAIN_IMAGES_PATH_REFACTORED\n    )\n\n    # Copy validation images to its designated directory, and create a txt file for each image denoting its classes and their positions\nfor image in tqdm(valid_df['image_id'].unique()):\n    records = valid_df[valid_df['image_id'] == image]\n    attributes = records[['class_id', 'x_center', 'y_center', 'w', 'h']].values\n    attributes = np.array(attributes)\n    np.savetxt(\n        os.path.join(\n            VALID_LABELS_PATH_REFACTORED,\n            f'{image}.txt'\n        ),\n        attributes,\n        fmt=['%d', '%f', '%f', '%f', '%f']\n    )\n    shutil.copy(\n        os.path.join(\n            TRAIN_IMAGES_DIRECTORY,\n            f'{image}.png'\n        ),\n        VALID_IMAGES_PATH_REFACTORED\n    )\n# Order the classes based on the class ID numerical value (in an ascending order)\nclass_ids, class_names = list(zip(*set(zip(new_df['class_id'], new_df['class_name']))))\nclasses = list(np.array(class_names)[np.argsort(class_ids)])\nclasses = list(map(lambda x: str(x), classes))\n\n# Store a list containing the path of each training image in a TXT file\nwith open('train.txt', 'w') as f:\n    for path in os.listdir(TRAIN_IMAGES_PATH_REFACTORED):\n        f.write(f'{TRAIN_IMAGES_PATH_REFACTORED}{path}\\n')\n# Store a list containing the path of each validation image in a TXT file\nwith open('valid.txt', 'w') as f:\n    for path in os.listdir(VALID_IMAGES_PATH_REFACTORED):\n        f.write(f'{VALID_IMAGES_PATH_REFACTORED}{path}\\n')\n# Create a dictionary containing the necessary configurations to run YOLO\ndata = dict(\n    train='train.txt',\n    val='valid.txt',\n    nc=14,\n    names=classes\n)\n# Store the configurations in a YAML file, to be absorbed later by YOLO\nwith open('yolo.yaml', 'w') as outfile:\n    yaml.dump(data, outfile, default_flow_style=False)\n# return [pd.read_csv('/kaggle/working/data/train.csv'), train_df]","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:50:23.849695Z","iopub.execute_input":"2024-09-08T17:50:23.849962Z","iopub.status.idle":"2024-09-08T17:50:55.137212Z","shell.execute_reply.started":"2024-09-08T17:50:23.849939Z","shell.execute_reply":"2024-09-08T17:50:55.13651Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# raw_df, preprocessed_df = prime_dataset()","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:50:55.138219Z","iopub.execute_input":"2024-09-08T17:50:55.138506Z","iopub.status.idle":"2024-09-08T17:50:55.142551Z","shell.execute_reply.started":"2024-09-08T17:50:55.138464Z","shell.execute_reply":"2024-09-08T17:50:55.141618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip uninstall -y wandb","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:50:55.143685Z","iopub.execute_input":"2024-09-08T17:50:55.143995Z","iopub.status.idle":"2024-09-08T17:50:57.03486Z","shell.execute_reply.started":"2024-09-08T17:50:55.14397Z","shell.execute_reply":"2024-09-08T17:50:57.033744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# rm -rf /kaggle/output/yolov7.pt","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:50:57.036671Z","iopub.execute_input":"2024-09-08T17:50:57.037578Z","iopub.status.idle":"2024-09-08T17:50:57.041664Z","shell.execute_reply.started":"2024-09-08T17:50:57.037531Z","shell.execute_reply":"2024-09-08T17:50:57.040729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!cp /kaggle/working/valid.txt /kaggle/working/yolov9/valid.txt\n!cp /kaggle/working/train.txt /kaggle/working/yolov9/train.txt","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:50:57.043045Z","iopub.execute_input":"2024-09-08T17:50:57.043471Z","iopub.status.idle":"2024-09-08T17:50:59.028416Z","shell.execute_reply.started":"2024-09-08T17:50:57.043438Z","shell.execute_reply":"2024-09-08T17:50:59.027183Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rm -rf /kaggle/working/yolov9/runs","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:50:59.033701Z","iopub.execute_input":"2024-09-08T17:50:59.033995Z","iopub.status.idle":"2024-09-08T17:51:00.046433Z","shell.execute_reply.started":"2024-09-08T17:50:59.033964Z","shell.execute_reply":"2024-09-08T17:51:00.045336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_model(\n        train_step: int = 2,  # Chọn lần huấn luyện (1 cho lần 1, 2 cho lần 2)\n        visualize: bool = False,\n        export_as_onnx: bool = False,\n        export_as_tf: bool = False,\n        export_as_tflite: bool = False,\n        conf_thres: float = 0.3,\n        iou_thres: float = 0.4,\n):\n # Cấu hình kích thước ảnh đầu vào\n\n    if train_step == 1:\n        # Train lần 1\n        print(\"Training lần 1...\")\n        !torchrun --nproc_per_node=2 --master_port 9527 /kaggle/working/yolov9/train_dual.py --device 0,1 --sync-bn --img {IMAGE_SIZE} --cfg /kaggle/working/yolov9/models/detect/yolov9-c.yaml --batch-size 8 --epochs 20 --data yolo.yaml --weights /kaggle/working/yolov9-c.pt --hyp /kaggle/working/yolov9/data/hyps/hyp.scratch-high.yaml --min-items 0 --close-mosaic 15\n\n        # Lưu trọng số sau lần train 1 vào /kaggle/outputs\n        print(\"Lưu mô hình sau lần 1...\")\n        !cp /kaggle/working/yolov9/runs/train/exp/weights/last.pt /kaggle/outputs/yolov9-c-lan1.pt\n\n        print(\"Đã hoàn thành lần huấn luyện 1. Lưu mô hình và dừng lại.\")\n\n        return  # Dừng lại ngay sau khi huấn luyện lần 1 hoàn thành\n\n    elif train_step == 2:\n        # Load mô hình từ lần train 1 và tiếp tục train lần 2\n        print(\"Training lần 2...\")\n        !torchrun --nproc_per_node=2 --master_port 9527 /kaggle/working/yolov9/train_dual.py --device 0,1 --sync-bn --img {IMAGE_SIZE} --cfg /kaggle/working/yolov9/models/detect/yolov9-c.yaml --batch-size 8 --epochs 30 --data yolo.yaml --weights /kaggle/working/last.pt\n\n\n\n    if visualize:\n        # Visualize các kết quả sau lần huấn luyện\n        plt.rcParams.update({\n            'figure.figsize': (15, 8),\n            'axes.spines.left': False,\n            'axes.spines.right': False,\n            'axes.spines.bottom': False,\n            'axes.spines.top': False,\n            'xtick.bottom': False,\n            'xtick.labelbottom': False,\n            'ytick.labelleft': False,\n            'ytick.left': False,\n        })\n\n        for img_name in ['results.png', 'PR_curve.png', 'confusion_matrix.png']:\n            img_path = f'runs/train/exp/{img_name}'\n            plt.figure(figsize=(15, 8))\n            plt.imshow(plt.imread(img_path))\n            plt.title(f\"{img_name} (conf_thres={conf_thres}, iou_thres={iou_thres})\")\n            plt.axis('off')\n\n        plt.rcParams.update(plt.rcParamsDefault)\n        plt.rcParams.update({'figure.figsize': (15, 8)})\n\n    if export_as_onnx or export_as_tf or export_as_tflite:\n        print(\"Exporting mô hình...\")\n        !python yolov9/export.py --weights yolov9-c.pt --img-size {IMAGE_SIZE} {IMAGE_SIZE} --max-wh {IMAGE_SIZE} --grid --end2end --simplify\n\n        if export_as_tf or export_as_tflite:\n            !onnx-tf convert -i yolov9.onnx -o ./\n\n            if export_as_tflite:\n                converter = tf.lite.TFLiteConverter.from_saved_model('./')\n                tflite_model = converter.convert()\n                with open('yolov9.tflite', 'wb') as f:\n                    f.write(tflite_model)\n","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:51:00.047929Z","iopub.execute_input":"2024-09-08T17:51:00.048221Z","iopub.status.idle":"2024-09-08T17:51:00.092551Z","shell.execute_reply.started":"2024-09-08T17:51:00.048192Z","shell.execute_reply":"2024-09-08T17:51:00.09155Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_model()","metadata":{"execution":{"iopub.status.busy":"2024-09-08T17:51:00.093599Z","iopub.execute_input":"2024-09-08T17:51:00.093869Z"},"trusted":true},"execution_count":null,"outputs":[]}]}