{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceType":"competition","sourceId":21154,"databundleVersionId":1243559},{"sourceType":"datasetVersion","sourceId":16068089,"datasetId":10303816,"databundleVersionId":17036598}],"dockerImageVersionId":31328,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport warnings\nwarnings.filterwarnings(\"ignore\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-03T12:11:17.837954Z","iopub.execute_input":"2026-05-03T12:11:17.838237Z","iopub.status.idle":"2026-05-03T12:11:18.115214Z","shell.execute_reply.started":"2026-05-03T12:11:17.838215Z","shell.execute_reply":"2026-05-03T12:11:18.114313Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport io\nimport glob\nimport struct\nfrom multiprocessing import Pool, cpu_count\nfrom PIL import Image\nfrom tqdm import tqdm\n\nfrom tensorflow.core.example.example_pb2 import Example\n\n\n# ---- TFRecord Reader ----\ndef read_tfrecord(file_path):\n    with open(file_path, \"rb\") as f:\n        while True:\n            length_bytes = f.read(8)\n            if not length_bytes:\n                break\n\n            length = struct.unpack(\"<Q\", length_bytes)[0]\n            f.read(4)  # crc\n            data = f.read(length)\n            f.read(4)  # crc\n\n            yield data\n\n\n# ---- Parser ----\ndef parse_example(serialized):\n    example = Example()\n    example.ParseFromString(serialized)\n\n    features = example.features.feature\n\n    image = features[\"image\"].bytes_list.value[0]\n    label = features[\"class\"].int64_list.value[0]\n    img_id = features[\"id\"].bytes_list.value[0].decode()\n\n    return image, label, img_id\n\n\n# ---- Worker ----\ndef process_file(file_path):\n    local_count = 0\n\n    for record in read_tfrecord(file_path):\n        img_bytes, label, img_id = parse_example(record)\n\n        class_dir = os.path.join(OUTPUT_PATH, str(label))\n        os.makedirs(class_dir, exist_ok=True)\n\n        img = Image.open(io.BytesIO(img_bytes))\n        img.save(os.path.join(class_dir, f\"{img_id}.jpg\"))\n\n        local_count += 1\n\n    return local_count","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-03T12:11:18.116465Z","iopub.execute_input":"2026-05-03T12:11:18.116770Z","iopub.status.idle":"2026-05-03T12:11:46.935166Z","shell.execute_reply.started":"2026-05-03T12:11:18.116751Z","shell.execute_reply":"2026-05-03T12:11:46.934205Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"BASE_PATH = \"/kaggle/input/competitions/tpu-getting-started\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-03T12:11:46.936318Z","iopub.execute_input":"2026-05-03T12:11:46.936838Z","iopub.status.idle":"2026-05-03T12:11:46.941242Z","shell.execute_reply.started":"2026-05-03T12:11:46.936811Z","shell.execute_reply":"2026-05-03T12:11:46.940204Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from torchvision.datasets import ImageFolder\nfrom torchvision import transforms\nfrom torch.utils.data import DataLoader\n\nIMAGE_SIZE = 224\n\ntransform = transforms.Compose([\n    transforms.Resize((IMAGE_SIZE, IMAGE_SIZE)),\n    transforms.ToTensor(),\n    transforms.Normalize(\n        mean=[0.485, 0.456, 0.406],\n        std=[0.229, 0.224, 0.225]\n    )\n])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-03T12:11:46.942921Z","iopub.execute_input":"2026-05-03T12:11:46.943204Z","iopub.status.idle":"2026-05-03T12:11:53.573764Z","shell.execute_reply.started":"2026-05-03T12:11:46.943181Z","shell.execute_reply":"2026-05-03T12:11:53.573029Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import timm\nimport torch\nimport torch.nn as nn\n\nNUM_CLASSES = 104  # flower classes\n\ndef build_model(model_name=\"convnext_tiny\", pretrained=True):\n    model = timm.create_model(\n        model_name,\n        pretrained=pretrained,\n        num_classes=NUM_CLASSES\n    )\n    return model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-03T12:11:53.575755Z","iopub.execute_input":"2026-05-03T12:11:53.576201Z","iopub.status.idle":"2026-05-03T12:11:59.447823Z","shell.execute_reply.started":"2026-05-03T12:11:53.576180Z","shell.execute_reply":"2026-05-03T12:11:59.446956Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import cv2\nimport numpy as np\nimport os\n\nTEST_OUTPUT_PATH = \"/kaggle/output/test_images\"\nos.makedirs(TEST_OUTPUT_PATH, exist_ok=True)\n\nfrom tensorflow.core.example.example_pb2 import Example\n\ndef parse_test_example(serialized):\n    example = Example()\n    example.ParseFromString(serialized)\n\n    features = example.features.feature\n\n    image = features[\"image\"].bytes_list.value[0]\n    img_id = features[\"id\"].bytes_list.value[0].decode()\n\n    return image, img_id\n\ndef process_test_file(file_path):\n    count = 0\n\n    for record in read_tfrecord(file_path):\n        img_bytes, img_id = parse_test_example(record)\n\n        # fast decode\n        img_array = np.frombuffer(img_bytes, np.uint8)\n        img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)\n\n        cv2.imwrite(os.path.join(TEST_OUTPUT_PATH, f\"{img_id}.jpg\"), img)\n\n        count += 1\n\n    return count","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-03T12:11:59.448848Z","iopub.execute_input":"2026-05-03T12:11:59.449096Z","iopub.status.idle":"2026-05-03T12:11:59.456327Z","shell.execute_reply.started":"2026-05-03T12:11:59.449074Z","shell.execute_reply":"2026-05-03T12:11:59.455485Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"TEST_INPUT_PATH = BASE_PATH + \"/tfrecords-jpeg-224x224/test\"\n\nfiles_test = glob.glob(TEST_INPUT_PATH + \"/*.tfrec\")\n\nnum_workers = min(4, cpu_count())  # safer on Kaggle\n\nwith Pool(num_workers) as p:\n    results = list(tqdm(p.imap(process_test_file, files_test), total=len(files_test)))\n\nprint(f\"Total test images processed: {sum(results)}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-03T12:11:59.457862Z","iopub.execute_input":"2026-05-03T12:11:59.458484Z","iopub.status.idle":"2026-05-03T12:12:02.079163Z","shell.execute_reply.started":"2026-05-03T12:11:59.458424Z","shell.execute_reply":"2026-05-03T12:12:02.078183Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from torch.utils.data import Dataset\nfrom PIL import Image\nimport os\n\nclass TestDataset(Dataset):\n    def __init__(self, folder, transform=None):\n        self.paths = sorted([\n            os.path.join(folder, f)\n            for f in os.listdir(folder)\n            if f.endswith(\".jpg\")\n        ])\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.paths)\n\n    def __getitem__(self, idx):\n        path = self.paths[idx]\n        img = Image.open(path).convert(\"RGB\")\n\n        if self.transform:\n            img = self.transform(img)\n\n        img_id = os.path.basename(path).replace(\".jpg\", \"\")\n        return img, img_id","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-03T12:12:02.080967Z","iopub.execute_input":"2026-05-03T12:12:02.081360Z","iopub.status.idle":"2026-05-03T12:12:02.089199Z","shell.execute_reply.started":"2026-05-03T12:12:02.081330Z","shell.execute_reply":"2026-05-03T12:12:02.088208Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from torchvision.datasets import ImageFolder\nfrom torch.utils.data import DataLoader\n\ntest_dataset = TestDataset(\n    \"/kaggle/output/test_images\",\n    transform=transform\n)\n\ntest_loader = DataLoader(\n    test_dataset,\n    batch_size=64,\n    shuffle=False,\n    num_workers=2\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-03T12:12:02.090216Z","iopub.execute_input":"2026-05-03T12:12:02.090423Z","iopub.status.idle":"2026-05-03T12:12:02.146942Z","shell.execute_reply.started":"2026-05-03T12:12:02.090403Z","shell.execute_reply":"2026-05-03T12:12:02.145817Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\nmodel = build_model(model_name=\"efficientnet_b0\", pretrained=False);\n\nmodel.load_state_dict(torch.load(\n    \"/kaggle/input/datasets/sadiq18/petalstothemetalmodels/best_model_efficient_b0_ema.pth\",\n    map_location=device\n));\n\nmodel.to(device);","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-03T12:12:02.148296Z","iopub.execute_input":"2026-05-03T12:12:02.149174Z","iopub.status.idle":"2026-05-03T12:12:02.456666Z","shell.execute_reply.started":"2026-05-03T12:12:02.149140Z","shell.execute_reply":"2026-05-03T12:12:02.455830Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tqdm import tqdm","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-03T12:12:02.457537Z","iopub.execute_input":"2026-05-03T12:12:02.457792Z","iopub.status.idle":"2026-05-03T12:12:02.462055Z","shell.execute_reply.started":"2026-05-03T12:12:02.457770Z","shell.execute_reply":"2026-05-03T12:12:02.461028Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ids = []\npreds = []\n\nmodel.eval()\nwith torch.no_grad():\n    for images, img_ids in tqdm(test_loader):\n        images = images.to(device)\n\n        outputs = model(images)\n        pred = outputs.argmax(dim=1).cpu().numpy()\n\n        ids.extend(img_ids)\n        preds.extend(pred)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-03T12:12:02.463239Z","iopub.execute_input":"2026-05-03T12:12:02.463532Z","iopub.status.idle":"2026-05-03T12:17:32.487676Z","shell.execute_reply.started":"2026-05-03T12:12:02.463504Z","shell.execute_reply":"2026-05-03T12:17:32.486949Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\n\ndf = pd.DataFrame({\n    \"id\": ids,\n    \"label\": preds\n})\n\ndf.to_csv(\"submission.csv\", index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-03T12:17:32.488834Z","iopub.execute_input":"2026-05-03T12:17:32.489169Z","iopub.status.idle":"2026-05-03T12:17:32.511511Z","shell.execute_reply.started":"2026-05-03T12:17:32.489139Z","shell.execute_reply":"2026-05-03T12:17:32.510374Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-03T12:17:32.513937Z","iopub.execute_input":"2026-05-03T12:17:32.514201Z","iopub.status.idle":"2026-05-03T12:17:32.545758Z","shell.execute_reply.started":"2026-05-03T12:17:32.514180Z","shell.execute_reply":"2026-05-03T12:17:32.544832Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}