{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"dockerImageVersionId":28755,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom pathlib import Path\nfrom PIL import Image\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:27:57.118249Z","iopub.execute_input":"2026-08-10T10:27:57.119179Z","iopub.status.idle":"2026-08-10T10:27:57.124868Z","shell.execute_reply.started":"2026-08-10T10:27:57.119124Z","shell.execute_reply":"2026-08-10T10:27:57.123687Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls {data_dir}","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:27:57.205229Z","iopub.execute_input":"2026-08-10T10:27:57.205575Z","iopub.status.idle":"2026-08-10T10:27:57.388901Z","shell.execute_reply.started":"2026-08-10T10:27:57.205546Z","shell.execute_reply":"2026-08-10T10:27:57.387525Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data_dir='/kaggle/input/competitions/imaterialist-fashion-2019-FGVC6'\nout_dir=\"/kaggle/working/\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:27:57.391494Z","iopub.execute_input":"2026-08-10T10:27:57.391862Z","iopub.status.idle":"2026-08-10T10:27:57.397478Z","shell.execute_reply.started":"2026-08-10T10:27:57.391816Z","shell.execute_reply":"2026-08-10T10:27:57.396397Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# EDA","metadata":{}},{"cell_type":"code","source":"try:\n    df=pd.read_csv(f\"{data_dir}/train.csv\")\nexcept:\n    print('error')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:27:57.399192Z","iopub.execute_input":"2026-08-10T10:27:57.399534Z","iopub.status.idle":"2026-08-10T10:28:23.658089Z","shell.execute_reply.started":"2026-08-10T10:27:57.399499Z","shell.execute_reply":"2026-08-10T10:28:23.657220Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:23.660875Z","iopub.execute_input":"2026-08-10T10:28:23.662719Z","iopub.status.idle":"2026-08-10T10:28:23.736287Z","shell.execute_reply.started":"2026-08-10T10:28:23.662073Z","shell.execute_reply":"2026-08-10T10:28:23.735164Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:23.738973Z","iopub.execute_input":"2026-08-10T10:28:23.739300Z","iopub.status.idle":"2026-08-10T10:28:23.746049Z","shell.execute_reply.started":"2026-08-10T10:28:23.739266Z","shell.execute_reply":"2026-08-10T10:28:23.745059Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:23.747286Z","iopub.execute_input":"2026-08-10T10:28:23.747690Z","iopub.status.idle":"2026-08-10T10:28:23.857027Z","shell.execute_reply.started":"2026-08-10T10:28:23.747661Z","shell.execute_reply":"2026-08-10T10:28:23.856214Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import json\nwith open(f\"{data_dir}/label_descriptions.json\") as f:\n    label_desc = json.load(f)\n\ncategories = {c[\"id\"]: c[\"name\"] for c in label_desc[\"categories\"]}\nprint(f\"Total categories: {len(categories)}\")\nprint(categories)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:23.858078Z","iopub.execute_input":"2026-08-10T10:28:23.858512Z","iopub.status.idle":"2026-08-10T10:28:23.870002Z","shell.execute_reply.started":"2026-08-10T10:28:23.858483Z","shell.execute_reply":"2026-08-10T10:28:23.868937Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(sorted(df[\"ClassId\"].unique()))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:23.871251Z","iopub.execute_input":"2026-08-10T10:28:23.871632Z","iopub.status.idle":"2026-08-10T10:28:23.914993Z","shell.execute_reply.started":"2026-08-10T10:28:23.871590Z","shell.execute_reply":"2026-08-10T10:28:23.914242Z"},"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(max(map(int, \"_\".join(df[\"ClassId\"]).split(\"_\"))))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:23.916024Z","iopub.execute_input":"2026-08-10T10:28:23.916294Z","iopub.status.idle":"2026-08-10T10:28:24.025941Z","shell.execute_reply.started":"2026-08-10T10:28:23.916269Z","shell.execute_reply":"2026-08-10T10:28:24.025210Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### remove attributes","metadata":{}},{"cell_type":"code","source":"df[\"category\"] = df[\"ClassId\"].str.split(\"_\").str[0].astype(int)\ndf.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:24.026927Z","iopub.execute_input":"2026-08-10T10:28:24.027263Z","iopub.status.idle":"2026-08-10T10:28:24.564014Z","shell.execute_reply.started":"2026-08-10T10:28:24.027234Z","shell.execute_reply":"2026-08-10T10:28:24.563190Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"counts = df[\"category\"].value_counts().sort_index()\ncounts.index = [categories[i] for i in counts.index]\nprint(counts)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:24.565404Z","iopub.execute_input":"2026-08-10T10:28:24.565751Z","iopub.status.idle":"2026-08-10T10:28:24.580108Z","shell.execute_reply.started":"2026-08-10T10:28:24.565716Z","shell.execute_reply":"2026-08-10T10:28:24.579191Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"save_dir = f\"{out_dir}/figures\"\nos.makedirs(save_dir, exist_ok=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:24.581340Z","iopub.execute_input":"2026-08-10T10:28:24.581652Z","iopub.status.idle":"2026-08-10T10:28:24.595452Z","shell.execute_reply.started":"2026-08-10T10:28:24.581623Z","shell.execute_reply":"2026-08-10T10:28:24.594436Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(12, 8))\ncounts.plot(kind=\"bar\")\nplt.xticks(rotation=90)\nplt.xlabel(\"Category\")\nplt.ylabel(\"Count\")\nplt.title(\"Category Distribution\")\nplt.tight_layout()\nplt.savefig(f\"{save_dir}/original_class_histogram.png\",dpi=300)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:24.596647Z","iopub.execute_input":"2026-08-10T10:28:24.596949Z","iopub.status.idle":"2026-08-10T10:28:26.011685Z","shell.execute_reply.started":"2026-08-10T10:28:24.596924Z","shell.execute_reply":"2026-08-10T10:28:26.010727Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Class Filtering and Merging","metadata":{}},{"cell_type":"code","source":"supercats = set(c.get(\"supercategory\", \"\") for c in label_desc[\"categories\"])\nprint(supercats)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:26.015700Z","iopub.execute_input":"2026-08-10T10:28:26.016014Z","iopub.status.idle":"2026-08-10T10:28:26.021938Z","shell.execute_reply.started":"2026-08-10T10:28:26.015986Z","shell.execute_reply":"2026-08-10T10:28:26.021182Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for c in label_desc[\"categories\"]:\n    print(c[\"id\"], c[\"name\"], \"->\", c.get(\"supercategory\"))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:26.023123Z","iopub.execute_input":"2026-08-10T10:28:26.023433Z","iopub.status.idle":"2026-08-10T10:28:26.041254Z","shell.execute_reply.started":"2026-08-10T10:28:26.023407Z","shell.execute_reply":"2026-08-10T10:28:26.040443Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### remove parts and keep clothing items ","metadata":{}},{"cell_type":"code","source":"drop_supercats = {\"garment parts\", \"closures\", \"decorations\"}\nkeep_ids = {c[\"id\"] for c in label_desc[\"categories\"] \n            if c.get(\"supercategory\") not in drop_supercats and c[\"name\"] != \"umbrella\"}\n\ndf_clean = df[df[\"category\"].isin(keep_ids)].copy()\n\nprint(f\"before count {len(df)} after: {len(df_clean)}\")\nprint(df[\"category\"].nunique(), df_clean[\"category\"].nunique())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:26.042581Z","iopub.execute_input":"2026-08-10T10:28:26.042962Z","iopub.status.idle":"2026-08-10T10:28:26.107487Z","shell.execute_reply.started":"2026-08-10T10:28:26.042931Z","shell.execute_reply":"2026-08-10T10:28:26.106263Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"counts_clean = df_clean[\"category\"].value_counts().sort_index()\ncounts_clean.index = [categories[i] for i in counts_clean.index]\nprint(counts_clean)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:26.108667Z","iopub.execute_input":"2026-08-10T10:28:26.108977Z","iopub.status.idle":"2026-08-10T10:28:26.119437Z","shell.execute_reply.started":"2026-08-10T10:28:26.108950Z","shell.execute_reply":"2026-08-10T10:28:26.118470Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(12, 8))\ncounts_clean.plot(kind=\"bar\")\nplt.xticks(rotation=90)\nplt.xlabel(\"Category\")\nplt.ylabel(\"Count\")\nplt.title(\"Category Distribution without parts\")\nplt.tight_layout()\nplt.savefig(f\"{save_dir}/class_histogram_no_parts.png\", dpi=300)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:26.120658Z","iopub.execute_input":"2026-08-10T10:28:26.121082Z","iopub.status.idle":"2026-08-10T10:28:27.163052Z","shell.execute_reply.started":"2026-08-10T10:28:26.121044Z","shell.execute_reply":"2026-08-10T10:28:27.162198Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Merge small classes ","metadata":{}},{"cell_type":"code","source":"merge_map = {\n    \"vest\": \"jacket\",\n    \"cape\": \"coat\",\n    \"leg warmer\": \"tights, stockings\"\n}\nid_to_name=categories\ndf_clean['category'] = df_clean['category'].map(id_to_name).replace(merge_map)\nprint(f\"class count:{len(df_clean['category'].unique())}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:27.164259Z","iopub.execute_input":"2026-08-10T10:28:27.164581Z","iopub.status.idle":"2026-08-10T10:28:27.216543Z","shell.execute_reply.started":"2026-08-10T10:28:27.164543Z","shell.execute_reply":"2026-08-10T10:28:27.215585Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"counts_clean = df_clean[\"category\"].value_counts().sort_index()\nprint(counts_clean)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:27.217630Z","iopub.execute_input":"2026-08-10T10:28:27.217936Z","iopub.status.idle":"2026-08-10T10:28:27.234161Z","shell.execute_reply.started":"2026-08-10T10:28:27.217901Z","shell.execute_reply":"2026-08-10T10:28:27.233373Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(12, 8))\ncounts_clean.plot(kind=\"bar\")\nplt.xticks(rotation=90)\nplt.xlabel(\"Category\")\nplt.ylabel(\"Count\")\nplt.title(\"Category Distribution without parts\")\nplt.tight_layout()\nplt.savefig(f\"{save_dir}/class_histogram_no_parts_merge.png\",dpi=300)\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:27.235279Z","iopub.execute_input":"2026-08-10T10:28:27.235627Z","iopub.status.idle":"2026-08-10T10:28:28.234333Z","shell.execute_reply.started":"2026-08-10T10:28:27.235599Z","shell.execute_reply":"2026-08-10T10:28:28.233389Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_clean.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:28.235905Z","iopub.execute_input":"2026-08-10T10:28:28.236394Z","iopub.status.idle":"2026-08-10T10:28:28.242284Z","shell.execute_reply.started":"2026-08-10T10:28:28.236343Z","shell.execute_reply":"2026-08-10T10:28:28.241352Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"final_classes = sorted(df_clean[\"category\"].unique())\nclass_to_id = {name: idx for idx, name in enumerate(final_classes)}\nid_to_class = {idx: name for name, idx in class_to_id.items()}\n\nprint(class_to_id)\n\nimport json\nwith open(\"/kaggle/working/class_map.json\", \"w\") as f:\n    json.dump({\"class_to_id\": class_to_id, \"id_to_class\": id_to_class}, f, indent=2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:28.243609Z","iopub.execute_input":"2026-08-10T10:28:28.243935Z","iopub.status.idle":"2026-08-10T10:28:28.272751Z","shell.execute_reply.started":"2026-08-10T10:28:28.243898Z","shell.execute_reply":"2026-08-10T10:28:28.271831Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_clean[\"label_id\"] = df_clean[\"category\"].map(class_to_id)\nprint(df_clean[[\"category\", \"label_id\"]].drop_duplicates())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:28.273963Z","iopub.execute_input":"2026-08-10T10:28:28.274357Z","iopub.status.idle":"2026-08-10T10:28:28.314919Z","shell.execute_reply.started":"2026-08-10T10:28:28.274305Z","shell.execute_reply":"2026-08-10T10:28:28.313980Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_clean.to_csv(f'/{out_dir}/train_clean.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:28.315942Z","iopub.execute_input":"2026-08-10T10:28:28.316264Z","iopub.status.idle":"2026-08-10T10:28:59.353770Z","shell.execute_reply.started":"2026-08-10T10:28:28.316226Z","shell.execute_reply":"2026-08-10T10:28:59.351581Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Train  Val  Test Split\n### split by Imageid to prevent data leakage","metadata":{}},{"cell_type":"code","source":"image_ids = df_clean[\"ImageId\"].unique()\nnp.random.seed(42)\nnp.random.shuffle(image_ids)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:59.357042Z","iopub.execute_input":"2026-08-10T10:28:59.358456Z","iopub.status.idle":"2026-08-10T10:28:59.397489Z","shell.execute_reply.started":"2026-08-10T10:28:59.358393Z","shell.execute_reply":"2026-08-10T10:28:59.396445Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"n = len(image_ids)\nprint(n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:59.398848Z","iopub.execute_input":"2026-08-10T10:28:59.399170Z","iopub.status.idle":"2026-08-10T10:28:59.405129Z","shell.execute_reply.started":"2026-08-10T10:28:59.399132Z","shell.execute_reply":"2026-08-10T10:28:59.404030Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_ids = image_ids[:int(n*0.8)]\nval_ids = image_ids[int(n*0.8):int(n*0.9)]\ntest_ids = image_ids[int(n*0.9):]\n\nprint(f\"train 80% : {len(train_ids)} \\n val 10%: {len(val_ids)} \\n test 10%: {len(test_ids)}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:59.406551Z","iopub.execute_input":"2026-08-10T10:28:59.406922Z","iopub.status.idle":"2026-08-10T10:28:59.427246Z","shell.execute_reply.started":"2026-08-10T10:28:59.406880Z","shell.execute_reply":"2026-08-10T10:28:59.426122Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"splits = {\n    'train': train_ids.tolist(),\n    'val': val_ids.tolist(),\n    'test': test_ids.tolist()\n}\n\nwith open(f'/{out_dir}/splits.json', 'w') as f:\n    json.dump(splits, f)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:59.428429Z","iopub.execute_input":"2026-08-10T10:28:59.428842Z","iopub.status.idle":"2026-08-10T10:28:59.477312Z","shell.execute_reply.started":"2026-08-10T10:28:59.428786Z","shell.execute_reply":"2026-08-10T10:28:59.476355Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df = df_clean[df_clean['ImageId'].isin(train_ids)]\nval_df = df_clean[df_clean['ImageId'].isin(val_ids)]\ntest_df = df_clean[df_clean['ImageId'].isin(test_ids)]\n\ntrain_df.to_csv(f'/{out_dir}/train.csv', index=False)\nval_df.to_csv(f'/{out_dir}/val.csv', index=False)\ntest_df.to_csv(f'/{out_dir}/test.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:28:59.478568Z","iopub.execute_input":"2026-08-10T10:28:59.478942Z","iopub.status.idle":"2026-08-10T10:29:26.668264Z","shell.execute_reply.started":"2026-08-10T10:28:59.478903Z","shell.execute_reply":"2026-08-10T10:29:26.667240Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Decoding","metadata":{}},{"cell_type":"code","source":"def rle_decode(rle_string, height, width):\n    nums = rle_string.split()\n    nums = [int(n) for n in nums]\n    starts = nums[0::2]   \n    lengths = nums[1::2]  \n    starts = np.array(starts) - 1\n    ends = starts + np.array(lengths)\n    mask = np.zeros(height * width, dtype=np.uint8)\n    for s, e in zip(starts, ends):\n        mask[s:e] = 1\n    mask = mask.reshape((height, width), order='F')\n\n    return mask","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:29:26.669993Z","iopub.execute_input":"2026-08-10T10:29:26.670420Z","iopub.status.idle":"2026-08-10T10:29:26.679730Z","shell.execute_reply.started":"2026-08-10T10:29:26.670378Z","shell.execute_reply":"2026-08-10T10:29:26.678688Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"row = df_clean.iloc[0]\nmask = rle_decode(row['EncodedPixels'], row['Height'], row['Width'])\n\nimg_path = f\"/{data_dir}/train/{row['ImageId']}\"\nimage = Image.open(img_path)\n\nfig, ax = plt.subplots(1, 3, figsize=(15, 5))\n\nax[0].imshow(image)\nax[0].set_title('Original image')\nax[0].axis('off')\n\nax[1].imshow(mask, cmap='gray')\nax[1].set_title(f\"Decoded mask — {row['category']}\")\nax[1].axis('off')\n\nax[2].imshow(image)\nax[2].imshow(mask, cmap='jet', alpha=0.5)  \nax[2].set_title('Overlay')\nax[2].axis('off')\nplt.savefig(f\"{save_dir}/decoded_mask.png\",dpi=300)\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:29:26.680931Z","iopub.execute_input":"2026-08-10T10:29:26.681254Z","iopub.status.idle":"2026-08-10T10:29:48.172324Z","shell.execute_reply.started":"2026-08-10T10:29:26.681225Z","shell.execute_reply":"2026-08-10T10:29:48.171090Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(f\"Total images: {len(image_ids)}\")\nprint(f\"Total object rows: {len(df_clean)}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:29:48.173731Z","iopub.execute_input":"2026-08-10T10:29:48.174003Z","iopub.status.idle":"2026-08-10T10:29:48.178995Z","shell.execute_reply.started":"2026-08-10T10:29:48.173976Z","shell.execute_reply":"2026-08-10T10:29:48.178146Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def build_maskrcnn_target(image_id, df):\n    rows = df[df['ImageId'] == image_id]\n    height = rows.iloc[0]['Height']\n    width = rows.iloc[0]['Width']\n\n    masks = []\n    boxes = []\n    labels = []\n\n    for _, row in rows.iterrows():\n        obj_mask = rle_decode(row['EncodedPixels'], height, width)\n        masks.append(obj_mask)\n\n        ys, xs = np.where(obj_mask == 1)\n        boxes.append([xs.min(), ys.min(), xs.max(), ys.max()])\n\n        labels.append(row['label_id'])\n\n    return {\n        'masks': np.stack(masks),          # shape becomes [N, H, W]\n        'boxes': np.array(boxes),\n        'labels': np.array(labels),\n    }","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:29:48.180402Z","iopub.execute_input":"2026-08-10T10:29:48.180858Z","iopub.status.idle":"2026-08-10T10:29:48.197803Z","shell.execute_reply.started":"2026-08-10T10:29:48.180819Z","shell.execute_reply":"2026-08-10T10:29:48.196742Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"shutil.make_archive(\n    save_dir,  \n    \"zip\",                         \n    save_dir  \n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-10T10:30:05.422609Z","iopub.execute_input":"2026-08-10T10:30:05.422985Z","iopub.status.idle":"2026-08-10T10:30:05.557492Z","shell.execute_reply.started":"2026-08-10T10:30:05.422953Z","shell.execute_reply":"2026-08-10T10:30:05.556590Z"}},"outputs":[],"execution_count":null}]}