{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.13.15","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":"markdown","source":"# Inference with my own trained weights: faithful ResNeXt50 (512 px, 15 epochs, no TTA)\n\nThis notebook predicts the test images with **one model that I trained myself**: ResNeXt50, fold 0, **512 px, 15 epochs, plain cross-entropy**. This is my closest replication of the 1st place team's ResNeXt training script (their settings, but fold 0 only). It does not use any of the winners' released weights, and it uses no test-time augmentation, as in the winners' ResNeXt inference.\n\n**Result:** Private score **0.8785** abd Public score **0.8790**. The validation accuracy of the same weights on fold 0 was 0.88210 (epoch 15). The leaderboard scores are slightly lower, which is expected because the best epoch was chosen on that same validation fold.\n\n| Weights | Validation | Private LB | Public LB |\n|---|---|---|---|\n| Baseline, 384 px, 8 epochs | 0.87388 | 0.8742 | 0.8706 |\n| Label smoothing, 384 px, 8 epochs | 0.87986 | 0.8779 | 0.8792 |\n| **Faithful, 512 px, 15 epochs (this notebook)** | **0.88210** | **0.8785** | **0.8790** |\n| Winners' full ensemble (`Final Version Inference`) | n/a | 0.9134 | 0.9143 |\n\nThe faithful model beat my 384 px baseline on both leaderboard splits. It was about level with label smoothing at 384 px, so I do not claim that the larger image size and longer training helped beyond that. These are single runs on one fold.\n\n**Code:** Same as `inference-own-resnext-384`, which explains it step by step, with two settings changed: `SIZE = 512`, to match the training image size, and the attached weights dataset (`cassava-resnext-fold0-512-faithful`).\n\n**Related notebooks:**\n- Training notebook for these weights: https://www.kaggle.com/code/ananyaamadhursharma/train-faithful-512-15ep\n- Baseline weights inference: https://www.kaggle.com/code/ananyaamadhursharma/inference-own-resnext-384\n- Full winning ensemble: https://www.kaggle.com/code/ananyaamadhursharma/final-version-inference","metadata":{}},{"cell_type":"code","source":"import os\n\nprint(\"Input folders:\", os.listdir(\"/kaggle/input\"))\nprint()\nfor root, dirs, files in os.walk(\"/kaggle/input\"):\n    for f in files:\n        if f.endswith(\".pth\"):\n            print(\"WEIGHTS:\", os.path.join(root, f))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-10-17T23:16:32.84261Z","iopub.execute_input":"2026-10-17T23:16:32.842928Z","iopub.status.idle":"2026-10-17T23:17:19.189689Z","shell.execute_reply.started":"2026-10-17T23:16:32.842899Z","shell.execute_reply":"2026-10-17T23:17:19.188328Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ====================================================\n# Inference with my own ResNeXt50 (label smoothing, 512 px)\n# ====================================================\nimport os, sys\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import DataLoader, Dataset\nfrom albumentations import Compose, Normalize, Resize\nfrom albumentations.pytorch import ToTensorV2\n\nsys.path.append('../input/pytorch-image-models/pytorch-image-models-master')\nimport timm\n\n# ---------------- settings ----------------\nWEIGHTS_PATH = \"/kaggle/input/datasets/ananyaamadhursharma/cassava-resnext-fold0-512-faithful/resnext50_32x4d_fold0_best.pth\"\nSIZE = 512\nUSE_TTA = False      # set to False to get the plain prediction\n\ncandidates = [\n    \"../input/cassava-leaf-disease-classification/test_images/\",\n    \"/kaggle/input/cassava-leaf-disease-classification/test_images/\",\n    \"/kaggle/input/competitions/cassava-leaf-disease-classification/test_images/\",\n]\nTEST_DIR = next(p for p in candidates if os.path.exists(p))\nprint(\"Using test folder:\", TEST_DIR)\n\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nprint(\"Device:\", device)\n\n# ---------------- model ----------------\nclass CustomResNext(nn.Module):\n    def __init__(self, model_name='resnext50_32x4d', pretrained=False):\n        super().__init__()\n        self.model = timm.create_model(model_name, pretrained=pretrained)\n        n_features = self.model.fc.in_features\n        self.model.fc = nn.Linear(n_features, 5)\n\n    def forward(self, x):\n        return self.model(x)\n\n# ---------------- dataset ----------------\nclass TestDataset(Dataset):\n    def __init__(self, files, transform=None):\n        self.files = files\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.files)\n\n    def __getitem__(self, idx):\n        image = cv2.imread(self.files[idx])\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        return self.transform(image=image)['image']\n\ntransform = Compose([\n    Resize(SIZE, SIZE),\n    Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n    ToTensorV2(),\n])\n\n# ---------------- load weights ----------------\nmodel = CustomResNext(pretrained=False)\nstate = torch.load(WEIGHTS_PATH, map_location=\"cpu\", weights_only=False)\nmodel.load_state_dict(state['model'])\nmodel.to(device)\nmodel.eval()\nprint(\"My trained weights loaded.\")\n\n# ---------------- predict with TTA ----------------\ndef predict_batch(x):\n    views = [x]\n    if USE_TTA:\n        views += [x.flip(3),            # horizontal flip\n                  x.flip(2),            # vertical flip\n                  x.transpose(2, 3)]    # transpose (swap height and width)\n    probs = [model(v).softmax(1) for v in views]\n    return torch.stack(probs).mean(0)\n\nimage_ids = sorted(os.listdir(TEST_DIR))\nfiles = [TEST_DIR + i for i in image_ids]\nloader = DataLoader(TestDataset(files, transform), batch_size=16,\n                    shuffle=False, num_workers=2, pin_memory=True)\n\nall_probs = []\nwith torch.no_grad():\n    for images in loader:\n        all_probs.append(predict_batch(images.to(device)).cpu().numpy())\nall_probs = np.concatenate(all_probs)\n\nsubmission = pd.DataFrame({\"image_id\": image_ids, \"label\": all_probs.argmax(1)})\nsubmission.to_csv(\"submission.csv\", index=False)\nprint(\"TTA used:\", USE_TTA)\nprint(submission.head())\nprint(\"Rows:\", len(submission))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-10-17T23:22:49.528396Z","iopub.execute_input":"2026-10-17T23:22:49.529392Z","iopub.status.idle":"2026-10-17T23:22:53.5788Z","shell.execute_reply.started":"2026-10-17T23:22:49.529358Z","shell.execute_reply":"2026-10-17T23:22:53.577878Z"}},"outputs":[],"execution_count":null}]}