{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.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":13836,"databundleVersionId":1718836,"sourceType":"competition"},{"sourceId":8090095,"sourceType":"datasetVersion","datasetId":4776156},{"sourceId":8127114,"sourceType":"datasetVersion","datasetId":4803163},{"sourceId":8127246,"sourceType":"datasetVersion","datasetId":4803262},{"sourceId":8127226,"sourceType":"datasetVersion","datasetId":4803248},{"sourceId":8105897,"sourceType":"datasetVersion","datasetId":4787525}],"dockerImageVersionId":30684,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\n\nimport pandas as pd\nimport torch\nfrom PIL import Image\nfrom torch.backends import cudnn\nfrom torch.utils.data import DataLoader\nfrom torchvision.datasets import VisionDataset\nfrom torchvision.transforms import InterpolationMode, v2","metadata":{"_uuid":"2a1116b9-fe56-44fc-8294-aece4ea9cd24","_cell_guid":"89f6bc60-d848-47bc-8717-75f68a416eac","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-16T01:49:12.878854Z","iopub.execute_input":"2024-04-16T01:49:12.879147Z","iopub.status.idle":"2024-04-16T01:49:19.825721Z","shell.execute_reply.started":"2024-04-16T01:49:12.879122Z","shell.execute_reply":"2024-04-16T01:49:19.824773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Basic experiment settings\ntorch.manual_seed(3407)\ntorch.cuda.manual_seed(3407)\n\n\ncudnn.deterministic = False\ncudnn.benchmark = True\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(device)\n\n# Declare directories\ntest_dir = \"/kaggle/input/cassava-leaf-disease-classification/test_images/\"\n\n# Experiment parameters\nmodel_a_img_size = 384\nmodel_b_img_size = 528\nmodel_c_img_size = 384\nbatch_size = 16\nnum_workers = 4\nnum_classes = 5\ntta = True\n\n# Currently testing vision transformers so check its architecture\nmodel_a = torch.load(\"/kaggle/input/vit-v1/vit_v1.pt\", map_location=device)\nmodel_b = torch.load(\n    \"/kaggle/input/efficient-net/efficient_net.pt\", map_location=device\n)\nmodel_c = torch.load(\n    \"/kaggle/input/vit-v6/vit_v6.pt\", map_location=device\n)\n# linear_head = torch.load(\"/kaggle/input/linear-head/linear_cls.pt\", map_location=device)","metadata":{"_uuid":"2af88e01-d432-4627-8e2a-cf5131201bd3","_cell_guid":"9245bc38-8faf-458b-9b13-2bb8b1d9c5d2","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-16T01:49:19.827660Z","iopub.execute_input":"2024-04-16T01:49:19.828256Z","iopub.status.idle":"2024-04-16T01:49:28.330865Z","shell.execute_reply.started":"2024-04-16T01:49:19.828198Z","shell.execute_reply":"2024-04-16T01:49:28.329774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Test dataset without labels\nclass CassavaDataset(VisionDataset):\n    \"\"\"Custom dataset for the Cassava data.\n\n    Args:\n        data_dir: base directory to the images.\n        img_label_df: dataframe containing image-label pairs.\n        transforms: set of transforms to be used.\n    \"\"\"\n\n    def __init__(\n        self,\n        data_dir,\n        model_a_size,\n        model_b_size,\n        model_c_size,\n        transform=None,\n        ttas=None,\n        img_size=384,\n    ):\n        super().__init__(root=data_dir)\n\n        self.transform = transform\n        self.images = os.listdir(data_dir)\n        self.ttas = ttas\n        self.cc = v2.CenterCrop((600, 600))\n        self.resize_model_a = v2.Resize(\n            (model_a_size, model_a_size), interpolation=InterpolationMode.BICUBIC\n        )\n        self.resize_model_b = v2.Resize(\n            (model_b_size, model_b_size), interpolation=InterpolationMode.BICUBIC\n        )\n        self.resize_model_c = v2.Resize(\n            (model_c_size, model_c_size), interpolation=InterpolationMode.BICUBIC\n        )\n\n    def __getitem__(self, idx):\n        filename = self.images[idx]\n        img = Image.open(os.path.join(self.root, filename))\n        img = self.cc(img)\n        model_a_img = self.resize_model_a(img)\n        model_b_img = self.resize_model_b(img)        \n        model_c_img = self.resize_model_c(img)\n\n\n        if self.ttas is not None and self.transform is not None:\n            model_a_img = [self.transform(t(model_a_img)) for t in self.ttas]\n            model_b_img = [self.transform(t(model_b_img)) for t in self.ttas]            \n            model_c_img = [self.transform(t(model_c_img)) for t in self.ttas]\n\n\n        elif self.transform:\n            model_a_img = self.transform(model_a_img)\n            model_b_img = self.transform(model_b_img)\n            model_c_img = self.transform(model_c_img)\n\n\n        return model_a_img, model_b_img, model_c_img, filename\n\n    def __len__(self):\n        return len(self.images)","metadata":{"_uuid":"aecdb304-f7b8-4233-850b-11151d18a688","_cell_guid":"f0880c0b-c114-4f1d-adea-e65f7865d9ee","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-16T01:49:28.332130Z","iopub.execute_input":"2024-04-16T01:49:28.332442Z","iopub.status.idle":"2024-04-16T01:49:28.345835Z","shell.execute_reply.started":"2024-04-16T01:49:28.332415Z","shell.execute_reply":"2024-04-16T01:49:28.344894Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create the set of transforms for test time\ntest_transforms = v2.Compose(\n    [\n        v2.ToImage(),\n        v2.ToDtype(torch.float32, scale=True),\n        v2.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n    ]\n)\n\nif tta:\n    ttas = [\n        #         v2.RandomResizedCrop((img_size, img_size), (0.5, 1)),\n        v2.RandomRotation(180),\n        v2.RandomVerticalFlip(1),\n        v2.RandomAffine(180),\n        v2.RandomPerspective(p=1),\n    ]\nelse:\n    ttas = None\n\n# Dataset and dataloader\ntest_dataset = CassavaDataset(\n    test_dir, model_a_img_size, model_b_img_size, model_c_img_size, transform=test_transforms, ttas=ttas\n)\n\ntest_loader = DataLoader(\n    test_dataset,\n    batch_size=batch_size,\n    shuffle=True,\n    num_workers=num_workers,\n    pin_memory=True,\n)\n\n# Adjust unnormalized outputs\nnormalizer = torch.nn.Softmax(dim=1)","metadata":{"_uuid":"f7ea70d1-b648-4bd9-9cc9-edec9e73d1ad","_cell_guid":"8e791330-9fdb-4598-ab28-e7dd1e5e86ed","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-16T01:49:28.347932Z","iopub.execute_input":"2024-04-16T01:49:28.348278Z","iopub.status.idle":"2024-04-16T01:49:28.363677Z","shell.execute_reply.started":"2024-04-16T01:49:28.348247Z","shell.execute_reply":"2024-04-16T01:49:28.362842Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Perform inference\nall_names = []\nall_preds = []\n\nmodel_a.eval()\nmodel_b.eval()\nmodel_c.eval()\n# linear_head.eval()\n\nwith torch.no_grad():\n    test_loss = 0\n\n    for batch_idx, (model_a_inputs, model_b_inputs, model_c_inputs, filenames) in enumerate(\n        test_loader\n    ):\n        batch_size = len(filenames)\n\n        if tta:\n            model_a_inputs, model_b_inputs, model_c_inputs, filenames = (\n                torch.cat(model_a_inputs, dim=0).to(device),\n                torch.cat(model_b_inputs, dim=0).to(device),\n                torch.cat(model_c_inputs, dim=0).to(device),\n                list(filenames),\n            )\n\n            model_a_outputs = model_a(model_a_inputs)\n            model_b_outputs = model_b(model_b_inputs)            \n            model_c_outputs = model_c(model_c_inputs)\n\n            # Find the average prediction logits by each model\n            model_a_batch_logits = torch.stack(\n                torch.split(model_a_outputs, batch_size), dim=0\n            )\n            model_a_mean_logits = torch.mean(model_a_batch_logits, dim=0)\n\n            model_b_batch_logits = torch.stack(\n                torch.split(model_b_outputs, batch_size), dim=0\n            )\n            model_b_mean_logits = torch.mean(model_b_batch_logits, dim=0)\n            \n            model_c_batch_logits = torch.stack(\n                torch.split(model_c_outputs, batch_size), dim=0\n            )\n            model_c_mean_logits = torch.mean(model_c_batch_logits, dim=0)\n\n            #             logit_inputs = torch.cat([model_a_mean_logits, model_b_mean_logits], dim=1)\n            #             outputs = linear_head(logit_inputs)\n\n            outputs = (model_a_mean_logits + model_b_mean_logits + model_c_mean_logits) / 3\n\n            mean_preds = normalizer(outputs)\n            pred_labels = torch.argmax(mean_preds, 1).tolist()\n\n        else:\n            # The same thing but without the troublesome stuff\n            model_a_inputs, model_b_inputs, model_c_inputs, filenames = (\n                model_a_inputs.to(device),\n                model_b_inputs.to(device),                \n                model_c_inputs.to(device),\n                list(filenames),\n            )\n\n            model_a_outputs = model_a(model_a_inputs)\n            model_b_outputs = model_b(model_b_inputs)\n            model_c_outputs = model_c(model_c_inputs)\n\n            #             logit_inputs = torch.cat([model_a_outputs, model_b_outputs], dim=1)\n            #             outputs = linear_head(logit_inputs)\n            outputs = (model_a_outputs + model_b_outputs + model_c_outputs) / 3\n\n            preds = normalizer(outputs)\n            pred_labels = torch.argmax(preds, 1).tolist()\n\n        all_names.extend(filenames)\n        all_preds.extend(pred_labels)","metadata":{"_uuid":"30055c7f-56d7-4527-a177-aefdc33316e5","_cell_guid":"e954d7d2-9583-4aff-9f72-0efca0ae5880","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-16T01:49:28.364878Z","iopub.execute_input":"2024-04-16T01:49:28.365327Z","iopub.status.idle":"2024-04-16T01:49:31.925401Z","shell.execute_reply.started":"2024-04-16T01:49:28.365298Z","shell.execute_reply":"2024-04-16T01:49:31.924087Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create submission\nmy_submission = pd.DataFrame({\"image_id\": all_names, \"label\": all_preds})\nmy_submission.to_csv(\"submission.csv\", index=False)\nmy_submission","metadata":{"_uuid":"a9e168fc-5e34-462d-9535-8b26c717b1c7","_cell_guid":"63d8cb6c-306a-4117-9633-344b9197fc9c","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-16T01:49:31.927071Z","iopub.execute_input":"2024-04-16T01:49:31.928027Z","iopub.status.idle":"2024-04-16T01:49:31.951183Z","shell.execute_reply.started":"2024-04-16T01:49:31.927978Z","shell.execute_reply":"2024-04-16T01:49:31.950291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"_uuid":"5e7c0112-4840-4037-aebf-ec36f55d6dae","_cell_guid":"4458e723-ffdd-47ce-b07b-9784b9be370c","collapsed":false,"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]}]}