{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.11.13"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":107469,"databundleVersionId":13058354,"isSourceIdPinned":false,"sourceType":"competition"},{"sourceId":12828558,"sourceType":"datasetVersion","datasetId":8112986},{"sourceId":12828606,"sourceType":"datasetVersion","datasetId":8113012},{"sourceId":530520,"sourceType":"modelInstanceVersion","isSourceIdPinned":false,"modelInstanceId":400308,"modelId":418553}],"dockerImageVersionId":31090,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true},"papermill":{"default_parameters":{},"duration":5855.468672,"end_time":"2025-08-19T22:36:07.617484","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2025-08-19T20:58:32.148812","version":"2.6.0"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install ultralytics > /dev/null","metadata":{"execution":{"iopub.execute_input":"2025-08-19T20:58:38.536003Z","iopub.status.busy":"2025-08-19T20:58:38.535687Z","iopub.status.idle":"2025-08-19T21:00:03.527651Z","shell.execute_reply":"2025-08-19T21:00:03.526564Z"},"papermill":{"duration":84.99852,"end_time":"2025-08-19T21:00:03.529281","exception":false,"start_time":"2025-08-19T20:58:38.530761","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"SEED = 58","metadata":{"execution":{"iopub.execute_input":"2025-08-19T21:00:03.537846Z","iopub.status.busy":"2025-08-19T21:00:03.537559Z","iopub.status.idle":"2025-08-19T21:00:03.541412Z","shell.execute_reply":"2025-08-19T21:00:03.540715Z"},"papermill":{"duration":0.009054,"end_time":"2025-08-19T21:00:03.542456","exception":false,"start_time":"2025-08-19T21:00:03.533402","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport cv2\nimport csv\nimport random\nimport shutil\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\nfrom tqdm import tqdm\nfrom pathlib import Path\nfrom ultralytics import YOLO","metadata":{"execution":{"iopub.execute_input":"2025-08-19T21:00:03.550206Z","iopub.status.busy":"2025-08-19T21:00:03.549660Z","iopub.status.idle":"2025-08-19T21:00:11.604800Z","shell.execute_reply":"2025-08-19T21:00:11.604149Z"},"papermill":{"duration":8.060487,"end_time":"2025-08-19T21:00:11.606205","exception":false,"start_time":"2025-08-19T21:00:03.545718","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model1_path = '/kaggle/input/best-models-to-learn/pytorch/default/4/0976soup.pt'\nmodel2_path = '/kaggle/input/best-models-to-learn/pytorch/default/4/0976cheeros.pt'\n\nmodel1 = YOLO(model1_path, verbose=False)\nmodel2 = YOLO(model2_path, verbose=False)\n\ntest_images_dir = '/kaggle/input/multi-class-object-detection-challenge/testImages/images'\nimage_files = [f for f in os.listdir(test_images_dir) if f.endswith(('.jpg', '.png'))]","metadata":{"execution":{"iopub.execute_input":"2025-08-19T21:00:11.614540Z","iopub.status.busy":"2025-08-19T21:00:11.614183Z","iopub.status.idle":"2025-08-19T21:00:15.669279Z","shell.execute_reply":"2025-08-19T21:00:15.668659Z"},"papermill":{"duration":4.060691,"end_time":"2025-08-19T21:00:15.670690","exception":false,"start_time":"2025-08-19T21:00:11.609999","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def find_image_file(base_path, base_name):\n    for ext in ['.jpg', '.jpeg', '.png']:\n        img_path = os.path.join(base_path, base_name + ext)\n        if os.path.exists(img_path):\n            return img_path\n\n    return None\n\ndef prepare_model_data(model_id, src_img_dirs, src_label_dirs, dest_dir, mode='train'):\n    os.makedirs(f\"{dest_dir}/{mode}/images\", exist_ok=True)\n    os.makedirs(f\"{dest_dir}/{mode}/labels\", exist_ok=True)\n\n    processed_files = 0\n    file_counter = 0\n\n    for src_img_dir, src_label_dir in zip(src_img_dirs, src_label_dirs):\n        if not os.path.exists(src_label_dir):\n            print(f\"No target in directory: {src_label_dir}\")\n            continue\n            \n        for label_file in tqdm(os.listdir(src_label_dir)):\n            if not label_file.endswith('.txt'):\n                continue\n                \n            base_name = os.path.splitext(label_file)[0]\n            img_path = find_image_file(src_img_dir, base_name)\n            \n            if not img_path:\n                print(f\"Image not found for {label_file}\")\n                continue\n\n            with open(os.path.join(src_label_dir, label_file)) as f:\n                lines = [line.strip() for line in f if line.strip()]\n            \n            filtered_lines = []\n            for line in lines:\n                parts = line.split()\n                if len(parts) < 5:\n                    continue\n                    \n                try:\n                    cls = int(float(parts[0]))  # Исправлено здесь\n                    if cls == model_id:\n                        new_cls = 0 if model_id == 1 else cls\n                        filtered_lines.append(f\"{new_cls} {' '.join(parts[1:])}\")\n                except ValueError:\n                    print(f\"Skipping invalid class value in {label_file}: {parts[0]}\")\n                    continue\n            \n            if filtered_lines:\n                file_counter += 1\n                file_ext = os.path.splitext(img_path)[1]\n                unique_name = f\"dataset_{os.path.basename(src_img_dir)}_{file_counter}{file_ext}\"\n                \n                shutil.copy(img_path, f\"{dest_dir}/{mode}/images/{unique_name}\")\n                label_name = unique_name.replace(file_ext, '.txt')\n\n                with open(f\"{dest_dir}/{mode}/labels/{label_name}\", 'w') as f:\n                    f.write('\\n'.join(filtered_lines))\n\n                processed_files += 1\n\nprint(\"Soup...\")\nprepare_model_data(\n    model_id=1,\n    src_img_dirs=[\n        \"/kaggle/input/chs-data/combined_data/train\"\n    ],\n    src_label_dirs=[\n        \"/kaggle/input/chs-data/combined_data/train\"\n    ],\n    dest_dir=\"/kaggle/working/model1_data\",\n    mode='train'\n)\n\nprepare_model_data(\n    model_id=1,\n    src_img_dirs=[\n        \"/kaggle/input/chs-data/combined_data/val\"\n    ],\n    src_label_dirs=[\n        \"/kaggle/input/chs-data/combined_data/val\"\n    ],\n    dest_dir=\"/kaggle/working/model1_data\",\n    mode='val'\n)","metadata":{"execution":{"iopub.execute_input":"2025-08-19T21:00:15.678840Z","iopub.status.busy":"2025-08-19T21:00:15.678598Z","iopub.status.idle":"2025-08-19T21:04:16.034928Z","shell.execute_reply":"2025-08-19T21:04:16.034073Z"},"papermill":{"duration":240.361858,"end_time":"2025-08-19T21:04:16.036187","exception":false,"start_time":"2025-08-19T21:00:15.674329","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model1_yaml = \"\"\"\npath: /kaggle/working/model1_data\ntrain: train/images\nval: val/images\n\nnames: { 0: 'Soup' }\nnc: 1\n\"\"\"\n\nwith open('/kaggle/working/model1.yaml', 'w') as f:\n    f.write(model1_yaml)","metadata":{"execution":{"iopub.execute_input":"2025-08-19T21:04:16.122251Z","iopub.status.busy":"2025-08-19T21:04:16.121986Z","iopub.status.idle":"2025-08-19T21:04:16.126598Z","shell.execute_reply":"2025-08-19T21:04:16.125791Z"},"papermill":{"duration":0.049177,"end_time":"2025-08-19T21:04:16.127998","exception":false,"start_time":"2025-08-19T21:04:16.078821","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model1.train(\n    data='/kaggle/working/model1.yaml',\n    epochs=21,\n    batch=8,\n    imgsz=704,\n    patience=11,\n    optimizer='SGD',\n    momentum=0.937,\n    lr0=0.001,\n    weight_decay=0.0005,\n    cos_lr=True,\n    save_period=1,\n    workers=8,\n    hsv_h=0.09,\n    hsv_s=0.3,\n    hsv_v=0.62,\n    flipud=0.52,\n    fliplr=0.26,\n    translate=0.2,\n    scale=0.15,\n    shear=0.018,\n    perspective=0.002,\n    mosaic=1.0,\n    mixup=0.2,\n    copy_paste=0.1,\n    seed=SEED\n)","metadata":{"execution":{"iopub.execute_input":"2025-08-19T21:04:16.215841Z","iopub.status.busy":"2025-08-19T21:04:16.215271Z","iopub.status.idle":"2025-08-19T21:31:04.358161Z","shell.execute_reply":"2025-08-19T21:31:04.357250Z"},"papermill":{"duration":1608.18864,"end_time":"2025-08-19T21:31:04.360937","exception":false,"start_time":"2025-08-19T21:04:16.172297","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"try:\n    shutil.rmtree('/kaggle/working/model1_data')\n    print(\"Папка успешно удалена\")\nexcept FileNotFoundError:\n    print(\"Папка не существует\")\nexcept Exception as e:\n    print(f\"Ошибка при удалении: {e}\")","metadata":{"execution":{"iopub.execute_input":"2025-08-19T21:31:04.868037Z","iopub.status.busy":"2025-08-19T21:31:04.867159Z","iopub.status.idle":"2025-08-19T21:31:06.535433Z","shell.execute_reply":"2025-08-19T21:31:06.534656Z"},"papermill":{"duration":1.921894,"end_time":"2025-08-19T21:31:06.537397","exception":false,"start_time":"2025-08-19T21:31:04.615503","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Soup...\")\nprepare_model_data(\n    model_id=1,\n    src_img_dirs=[\n        \"/kaggle/input/chs2-data/combined_data/train\"\n    ],\n    src_label_dirs=[\n        \"/kaggle/input/chs2-data/combined_data/train\"\n    ],\n    dest_dir=\"/kaggle/working/model1_data\",\n    mode='train'\n)\n\nprepare_model_data(\n    model_id=1,\n    src_img_dirs=[\n        \"/kaggle/input/chs2-data/combined_data/val\"\n    ],\n    src_label_dirs=[\n        \"/kaggle/input/chs2-data/combined_data/val\"\n    ],\n    dest_dir=\"/kaggle/working/model1_data\",\n    mode='val'\n)","metadata":{"execution":{"iopub.execute_input":"2025-08-19T21:31:07.046611Z","iopub.status.busy":"2025-08-19T21:31:07.046302Z","iopub.status.idle":"2025-08-19T21:34:45.281980Z","shell.execute_reply":"2025-08-19T21:34:45.281143Z"},"papermill":{"duration":218.485078,"end_time":"2025-08-19T21:34:45.283267","exception":false,"start_time":"2025-08-19T21:31:06.798189","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model1.train(\n    data='/kaggle/working/model1.yaml',\n    epochs=21,\n    batch=8,\n    imgsz=704,\n    patience=11,\n    optimizer='SGD',\n    momentum=0.937,\n    lr0=0.001,\n    weight_decay=0.0005,\n    cos_lr=True,\n    save_period=1,\n    workers=8,\n    hsv_h=0.09,\n    hsv_s=0.3,\n    hsv_v=0.62,\n    flipud=0.52,\n    fliplr=0.26,\n    translate=0.2,\n    scale=0.15,\n    shear=0.018,\n    perspective=0.002,\n    mosaic=1.0,\n    mixup=0.2,\n    copy_paste=0.1,\n    seed=SEED\n)","metadata":{"execution":{"iopub.execute_input":"2025-08-19T21:34:45.852228Z","iopub.status.busy":"2025-08-19T21:34:45.851610Z","iopub.status.idle":"2025-08-19T21:41:54.867832Z","shell.execute_reply":"2025-08-19T21:41:54.866912Z"},"papermill":{"duration":429.304537,"end_time":"2025-08-19T21:41:54.870925","exception":false,"start_time":"2025-08-19T21:34:45.566388","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"try:\n    shutil.rmtree('/kaggle/working/model1_data')\n    print(\"Папка успешно удалена\")\nexcept FileNotFoundError:\n    print(\"Папка не существует\")\nexcept Exception as e:\n    print(f\"Ошибка при удалении: {e}\")","metadata":{"execution":{"iopub.execute_input":"2025-08-19T21:41:55.639132Z","iopub.status.busy":"2025-08-19T21:41:55.638331Z","iopub.status.idle":"2025-08-19T21:41:57.465820Z","shell.execute_reply":"2025-08-19T21:41:57.464809Z"},"papermill":{"duration":2.182578,"end_time":"2025-08-19T21:41:57.467317","exception":false,"start_time":"2025-08-19T21:41:55.284739","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"cheerios...\")\nprepare_model_data(\n    model_id=0,\n    src_img_dirs=[\n        \"/kaggle/input/chs-data/combined_data/train\"\n    ],\n    src_label_dirs=[\n        \"/kaggle/input/chs-data/combined_data/train\"\n    ],\n    dest_dir=\"/kaggle/working/model2_data\",\n    mode='train'\n)\n\nprepare_model_data(\n    model_id=0,\n    src_img_dirs=[\n        \"/kaggle/input/chs-data/combined_data/val\"\n    ],\n    src_label_dirs=[\n        \"/kaggle/input/chs-data/combined_data/val\"\n    ],\n    dest_dir=\"/kaggle/working/model2_data\",\n    mode='val'\n)","metadata":{"execution":{"iopub.execute_input":"2025-08-19T21:41:58.238480Z","iopub.status.busy":"2025-08-19T21:41:58.238175Z","iopub.status.idle":"2025-08-19T21:44:57.194598Z","shell.execute_reply":"2025-08-19T21:44:57.193873Z"},"papermill":{"duration":179.37246,"end_time":"2025-08-19T21:44:57.195670","exception":false,"start_time":"2025-08-19T21:41:57.823210","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model2_yaml = \"\"\"\npath: /kaggle/working/model2_data\ntrain: train/images\nval: val/images\n\nnames: {0: 'cheerios'}\nnc: 1\n\"\"\"\n\nwith open('/kaggle/working/model2.yaml', 'w') as f:\n    f.write(model2_yaml)","metadata":{"execution":{"iopub.execute_input":"2025-08-19T21:44:58.034826Z","iopub.status.busy":"2025-08-19T21:44:58.034483Z","iopub.status.idle":"2025-08-19T21:44:58.039098Z","shell.execute_reply":"2025-08-19T21:44:58.038301Z"},"papermill":{"duration":0.393364,"end_time":"2025-08-19T21:44:58.040331","exception":false,"start_time":"2025-08-19T21:44:57.646967","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model2.train(\n    data='/kaggle/working/model2.yaml',\n    epochs=21,\n    batch=8,\n    imgsz=704,\n    patience=11,\n    optimizer='SGD',\n    momentum=0.937,\n    lr0=0.001,\n    weight_decay=0.0005,\n    cos_lr=True,\n    save_period=1,\n    workers=8,\n    # Augmentations\n    hsv_h=0.05,\n    hsv_s=1.0,\n    hsv_v=0.75,\n    flipud=0.1,\n    fliplr=0.6,\n    translate=0.01,\n    scale=0.095,\n    shear=0.02,\n    perspective=0.002,\n    mosaic=1.0,\n    mixup=0.2,\n    copy_paste=0.1,\n    seed=SEED\n)","metadata":{"execution":{"iopub.execute_input":"2025-08-19T21:44:58.831717Z","iopub.status.busy":"2025-08-19T21:44:58.831127Z","iopub.status.idle":"2025-08-19T22:01:52.868553Z","shell.execute_reply":"2025-08-19T22:01:52.867662Z"},"papermill":{"duration":1014.426858,"end_time":"2025-08-19T22:01:52.872650","exception":false,"start_time":"2025-08-19T21:44:58.445792","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"try:\n    shutil.rmtree('/kaggle/working/model2_data')\n    print(\"Папка успешно удалена\")\nexcept FileNotFoundError:\n    print(\"Папка не существует\")\nexcept Exception as e:\n    print(f\"Ошибка при удалении: {e}\")","metadata":{"execution":{"iopub.execute_input":"2025-08-19T22:01:53.968863Z","iopub.status.busy":"2025-08-19T22:01:53.968068Z","iopub.status.idle":"2025-08-19T22:01:55.824913Z","shell.execute_reply":"2025-08-19T22:01:55.823865Z"},"papermill":{"duration":2.359439,"end_time":"2025-08-19T22:01:55.826916","exception":false,"start_time":"2025-08-19T22:01:53.467477","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"cheerios...\")\nprepare_model_data(\n    model_id=0,\n    src_img_dirs=[\n        \"/kaggle/input/chs2-data/combined_data/train\"\n    ],\n    src_label_dirs=[\n        \"/kaggle/input/chs2-data/combined_data/train\"\n    ],\n    dest_dir=\"/kaggle/working/model2_data\",\n    mode='train'\n)\n\nprepare_model_data(\n    model_id=0,\n    src_img_dirs=[\n        \"/kaggle/input/chs2-data/combined_data/val\"\n    ],\n    src_label_dirs=[\n        \"/kaggle/input/chs2-data/combined_data/val\"\n    ],\n    dest_dir=\"/kaggle/working/model2_data\",\n    mode='val'\n)","metadata":{"execution":{"iopub.execute_input":"2025-08-19T22:01:56.894850Z","iopub.status.busy":"2025-08-19T22:01:56.894300Z","iopub.status.idle":"2025-08-19T22:04:37.550194Z","shell.execute_reply":"2025-08-19T22:04:37.549440Z"},"papermill":{"duration":161.154936,"end_time":"2025-08-19T22:04:37.551346","exception":false,"start_time":"2025-08-19T22:01:56.396410","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model2.train(\n    data='/kaggle/working/model2.yaml',\n    epochs=21,\n    batch=8,\n    imgsz=704,\n    patience=11,\n    optimizer='SGD',\n    momentum=0.937,\n    lr0=0.001,\n    weight_decay=0.0005,\n    cos_lr=True,\n    save_period=1,\n    workers=8,\n    # Augmentations\n    hsv_h=0.05,\n    hsv_s=1.0,\n    hsv_v=0.75,\n    flipud=0.1,\n    fliplr=0.6,\n    translate=0.01,\n    scale=0.095,\n    shear=0.02,\n    perspective=0.002,\n    mosaic=1.0,\n    mixup=0.2,\n    copy_paste=0.1,\n    seed=SEED\n)","metadata":{"execution":{"iopub.execute_input":"2025-08-19T22:04:38.680067Z","iopub.status.busy":"2025-08-19T22:04:38.679285Z","iopub.status.idle":"2025-08-19T22:31:03.620389Z","shell.execute_reply":"2025-08-19T22:31:03.619447Z"},"papermill":{"duration":1585.473619,"end_time":"2025-08-19T22:31:03.624158","exception":false,"start_time":"2025-08-19T22:04:38.150539","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def format_boxes(results, class_offset=0):\n    boxes = results.boxes\n    width, height = results.orig_shape[1], results.orig_shape[0]\n\n    if boxes is None or len(boxes) == 0:\n        return \"\"\n\n    parts = []\n    for box in boxes:\n        cls = int(box.cls.cpu().numpy()) + class_offset\n        conf = float(box.conf.cpu().numpy())\n        x_center_abs, y_center_abs, w_abs, h_abs = box.xywh[0].cpu().numpy()\n\n        x_center = x_center_abs / width\n        y_center = y_center_abs / height\n        w = w_abs / width\n        h = h_abs / height\n\n        parts.append(f\"{cls} {conf:.6f} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}\")\n\n    return \" \".join(parts)\n\noutput_rows = []\n\n# Inference on 2 models\nfor img_name in image_files:\n    img_path = os.path.join(test_images_dir, img_name)\n\n    results1 = model1.predict(img_path, conf=1e-10, verbose=False)[0]\n    results2 = model2.predict(img_path, conf=1e-10, verbose=False)[0]\n\n    pred_str1 = format_boxes(results1, class_offset=1)\n    pred_str2 = format_boxes(results2, class_offset=0)\n\n    combined_pred_str = (pred_str1 + \" \" + pred_str2).strip()\n    if combined_pred_str == \"\":\n        combined_pred_str = \"no boxes\"\n\n    image_id = os.path.splitext(img_name)[0]\n\n    output_rows.append({\n        \"image_id\": image_id,\n        \"prediction_string\": combined_pred_str\n    })","metadata":{"execution":{"iopub.execute_input":"2025-08-19T22:31:05.134120Z","iopub.status.busy":"2025-08-19T22:31:05.133506Z","iopub.status.idle":"2025-08-19T22:35:55.197701Z","shell.execute_reply":"2025-08-19T22:35:55.196938Z"},"papermill":{"duration":290.785691,"end_time":"2025-08-19T22:35:55.199530","exception":false,"start_time":"2025-08-19T22:31:04.413839","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## for clear submit","metadata":{"papermill":{"duration":0.717538,"end_time":"2025-08-19T22:35:56.711761","exception":false,"start_time":"2025-08-19T22:35:55.994223","status":"completed"},"tags":[]}},{"cell_type":"code","source":"work_dir = '/kaggle/working'\n\nfor filename in os.listdir(work_dir):\n    file_path = os.path.join(work_dir, filename)\n\n    try:\n        if os.path.isfile(file_path) or os.path.islink(file_path):\n            os.unlink(file_path)\n        elif os.path.isdir(file_path):\n            shutil.rmtree(file_path)\n    except Exception as e:\n        print(f'Error file: {file_path}. Cause: {e}')","metadata":{"execution":{"iopub.execute_input":"2025-08-19T22:35:58.305571Z","iopub.status.busy":"2025-08-19T22:35:58.305267Z","iopub.status.idle":"2025-08-19T22:36:00.611029Z","shell.execute_reply":"2025-08-19T22:36:00.610379Z"},"papermill":{"duration":3.107978,"end_time":"2025-08-19T22:36:00.612406","exception":false,"start_time":"2025-08-19T22:35:57.504428","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Save predictions to CSV for submission","metadata":{"papermill":{"duration":0.82418,"end_time":"2025-08-19T22:36:02.161413","exception":false,"start_time":"2025-08-19T22:36:01.337233","status":"completed"},"tags":[]}},{"cell_type":"code","source":"csv_path = \"submission.csv\"\nwith open(csv_path, 'w', newline='') as f:\n    writer = csv.DictWriter(f, fieldnames=[\"image_id\", \"prediction_string\"])\n    writer.writeheader()\n    writer.writerows(output_rows)","metadata":{"execution":{"iopub.execute_input":"2025-08-19T22:36:03.678605Z","iopub.status.busy":"2025-08-19T22:36:03.678022Z","iopub.status.idle":"2025-08-19T22:36:03.853159Z","shell.execute_reply":"2025-08-19T22:36:03.852561Z"},"papermill":{"duration":0.971357,"end_time":"2025-08-19T22:36:03.854429","exception":false,"start_time":"2025-08-19T22:36:02.883072","status":"completed"},"tags":[]},"outputs":[],"execution_count":null}]}