{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":67836,"databundleVersionId":7527339,"sourceType":"competition"}],"dockerImageVersionId":31090,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Import and installs","metadata":{}},{"cell_type":"code","source":"\nimport os, time, random\nimport numpy as np\nimport pandas as pd\nimport cv2, torch\nfrom tqdm.auto import tqdm\nimport shutil as sh\n\nfrom IPython.display import Image, clear_output\nimport matplotlib.pyplot as plt\n%matplotlib inline","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-25T16:01:23.880735Z","iopub.execute_input":"2025-08-25T16:01:23.881242Z","iopub.status.idle":"2025-08-25T16:01:23.886137Z","shell.execute_reply.started":"2025-08-25T16:01:23.881218Z","shell.execute_reply":"2025-08-25T16:01:23.88554Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pip install ultralytics","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-25T16:01:23.894085Z","iopub.execute_input":"2025-08-25T16:01:23.894429Z","iopub.status.idle":"2025-08-25T16:01:27.292157Z","shell.execute_reply.started":"2025-08-25T16:01:23.894409Z","shell.execute_reply":"2025-08-25T16:01:27.291342Z"},"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-25T16:01:27.293853Z","iopub.execute_input":"2025-08-25T16:01:27.294075Z","iopub.status.idle":"2025-08-25T16:01:27.298403Z","shell.execute_reply.started":"2025-08-25T16:01:27.294054Z","shell.execute_reply":"2025-08-25T16:01:27.297714Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pip uninstall -y torchvision","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-25T16:01:27.29924Z","iopub.execute_input":"2025-08-25T16:01:27.299511Z","iopub.status.idle":"2025-08-25T16:01:28.483603Z","shell.execute_reply.started":"2025-08-25T16:01:27.299489Z","shell.execute_reply":"2025-08-25T16:01:28.482626Z"},"_kg_hide-input":true,"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pip install torchvision==0.21","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-25T16:01:28.484697Z","iopub.execute_input":"2025-08-25T16:01:28.484984Z","iopub.status.idle":"2025-08-25T16:01:32.465088Z","shell.execute_reply.started":"2025-08-25T16:01:28.484956Z","shell.execute_reply":"2025-08-25T16:01:32.464253Z"},"_kg_hide-input":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nprint(torch.__version__, torch.version.cuda)\nprint(torch.cuda.is_available())\nprint(torch.cuda.device_count())\nprint(torch.cuda.get_device_name(0) if torch.cuda.is_available() else \"No GPU\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-25T16:01:32.466918Z","iopub.execute_input":"2025-08-25T16:01:32.467153Z","iopub.status.idle":"2025-08-25T16:01:32.472527Z","shell.execute_reply.started":"2025-08-25T16:01:32.46713Z","shell.execute_reply":"2025-08-25T16:01:32.471909Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Traintestsplit +yolov8x\n\n### We are not training the model with full training data.\n\n### We will train on 70% of the dataset and test the model on the remaining 30%","metadata":{}},{"cell_type":"code","source":"import time\nstart_time = time.time()\n\nimport os\nimport shutil\nfrom glob import glob\nfrom sklearn.model_selection import StratifiedShuffleSplit\nimport numpy as np\nfrom collections import Counter\nimport yaml\n\ndef get_primary_class(label_path):\n    try:\n        with open(label_path, 'r') as f:\n            classes = [int(line.strip().split()[0]) for line in f.readlines()]\n        return max(set(classes), key=classes.count) if classes else -1\n    except:\n        return -1\n\ndef stratified_train_test_split(images_dir, labels_dir, output_dir, train_size=0.7, seed=42, class_names=None):\n    os.makedirs(output_dir, exist_ok=True)\n\n    # Collect images\n    exts = ('*.jpg', '*.jpeg', '*.png')\n    image_files = []\n    for e in exts:\n        image_files.extend(glob(os.path.join(images_dir, e)))\n    image_files = sorted(image_files)\n\n    data = []\n    labels = []\n    for img_path in image_files:\n        lbl_file = os.path.basename(img_path).replace('.jpg', '.txt').replace('.jpeg', '.txt').replace('.png', '.txt')\n        label_path = os.path.join(labels_dir, lbl_file)\n        label = get_primary_class(label_path)\n        if label != -1:\n            data.append(img_path)\n            labels.append(label)\n\n    data = np.array(data)\n    labels = np.array(labels)\n\n    counts = Counter(labels.tolist())\n    if len(counts) == 0:\n        raise RuntimeError(\"No labeled images found after parsing labels.\")\n\n    # Stratified train-test split\n    splitter = StratifiedShuffleSplit(n_splits=1, train_size=train_size, random_state=seed)\n    for train_idx, val_idx in splitter.split(data, labels):\n        for subset, idx in [('train', train_idx), ('val', val_idx)]:\n            img_out = os.path.join(output_dir, 'images', subset)\n            lbl_out = os.path.join(output_dir, 'labels', subset)\n            os.makedirs(img_out, exist_ok=True)\n            os.makedirs(lbl_out, exist_ok=True)\n            for i in idx:\n                img_path = data[i]\n                filename = os.path.basename(img_path)\n                lbl_path = os.path.join(labels_dir, filename.replace('.jpg', '.txt').replace('.jpeg', '.txt').replace('.png', '.txt'))\n                shutil.copy(img_path, os.path.join(img_out, filename))\n                if os.path.exists(lbl_path):\n                    shutil.copy(lbl_path, os.path.join(lbl_out, os.path.basename(lbl_path)))\n\n    # Create YOLO yaml file\n    yaml_content = {\n        'path': output_dir,\n        'train': 'images/train',\n        'val': 'images/val',\n        'names': {i: name for i, name in enumerate(class_names)} if class_names is not None else {}\n    }\n    yaml_path = os.path.join(output_dir, 'train_test_config.yaml')\n    with open(yaml_path, 'w') as f:\n        yaml.dump(yaml_content, f, default_flow_style=False)\n\n    print(f\"Stratified Train-Test split (train={train_size}, test={1-train_size}) created at: {output_dir}\")\n    return yaml_path\n\n\nyaml_path = stratified_train_test_split(\n    images_dir='/kaggle/input/dl-enigma-10-sust-cse-carnival-2024/dlenigma1/BadODD/images/train',\n    labels_dir='/kaggle/input/dl-enigma-10-sust-cse-carnival-2024/dlenigma1/BadODD/labels/train',\n    output_dir='/kaggle/working/BadODD_train_test',\n    train_size=0.7,\n    class_names=[\n        'auto_rickshaw','bicycle','bus','car','cart_vehicle','construction_vehicle',\n        'motorbike','person','priority_vehicle','three_wheeler','train','truck','wheelchair'\n    ]\n)\n\nfrom ultralytics import YOLO\nimport numpy as np\n\nprint(f\"\\n🚀 Training using {yaml_path} ...\")\nmodel = YOLO('yolov6n.pt')\n\nmodel.train(\n    data=yaml_path,\n    save=True,\n    epochs=50,\n    imgsz=640,\n    batch=4,\n    device=0,\n    workers=24,\n    optimizer='SGD',\n    patience=20,\n    cos_lr=True,\n    close_mosaic=50,\n    freeze=[0],\n    lr0=0.01,\n    lrf=0.01,\n    save_period=5,\n    project='runs/dlenigma',\n    name='DL_enigma_train_test',\n    exist_ok=True,\n    pretrained=True,\n    verbose=True,\n    seed=42,\n    val=True,\n    plots=True\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-25T16:13:52.343209Z","iopub.execute_input":"2025-08-25T16:13:52.343594Z","iopub.status.idle":"2025-08-25T16:19:38.195698Z","shell.execute_reply.started":"2025-08-25T16:13:52.343556Z","shell.execute_reply":"2025-08-25T16:19:38.185105Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Evaluate\nmetrics = model.val(data=yaml_path)\nf1_scores = metrics.box.f1\n\nprint(f\"mAP@0.5      : {metrics.box.map50:.4f}\")    \nprint(f\"mAP@0.5:0.95 : {metrics.box.map:.4f}\")      \nprint(f\"Precision    : {metrics.box.mp:.4f}\")\nprint(f\"Recall       : {metrics.box.mr:.4f}\")\nprint(f\"F1 Score (mean) : {np.mean(f1_scores):.4f}\")\nprint(f\"Per-class mAP@0.5 : {metrics.box.maps}\")\n\nend_time = time.time()\nprint(f\"Execution time: {end_time - start_time:.4f} seconds\")\n\n\n\n\nimport os\nimport matplotlib.pyplot as plt\n\n\n    # get metrics by validating again (to ensure metrics.save_dir exists for this fold)\nmetrics = model.val(data=yaml_path, verbose=False)  # or load from your saved results\nsave_dir = metrics.save_dir\nplot_files = [\n    \"BoxF1_curve.png\",\n    \"BoxPR_curve.png\",\n    \"BoxP_curve.png\",\n    \"BoxR_curve.png\",\n    \"confusion_matrix.png\",\n    \"confusion_matrix_normalized.png\"\n]\n\nfor file in plot_files:\n    path = os.path.join(save_dir, file)\n    if os.path.exists(path):\n        img = plt.imread(path)\n        plt.figure(figsize=(12, 12))\n        plt.imshow(img)\n        plt.axis('off')\n        plt.title(file)   # ✅ removed undefined `fold`\n        plt.show()\n    else:\n        print(f\"⚠️ {file} not found in {save_dir}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-25T16:02:02.220274Z","iopub.status.idle":"2025-08-25T16:02:02.220613Z","execution_failed":"2025-08-25T16:19:40.355Z"}},"outputs":[],"execution_count":null}]}