{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import torch.nn as nn\nimport torchvision\nimport torch\nimport pytorch_lightning as pl\nimport torch.nn.functional as F\n\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader, random_split\nfrom torchvision.models import resnet34\nimport pandas as pd\nimport os\nfrom torch.utils.data import Dataset\nfrom PIL import Image  \nfrom torchvision import transforms\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.model_selection import StratifiedKFold\n\nfrom torch.optim.lr_scheduler import ReduceLROnPlateau\nfrom torch.optim.lr_scheduler import OneCycleLR\n\nimport torchmetrics\nfrom torchmetrics.classification import MulticlassF1Score\n\nfrom pytorch_lightning import Trainer\nfrom pytorch_lightning.callbacks import ModelCheckpoint\nfrom pytorch_lightning.loggers import TensorBoardLogger\nfrom pytorch_lightning.callbacks import EarlyStopping\nfrom pytorch_lightning  import Trainer, seed_everything\n\nseed_everything(42, workers=True)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-10-29T19:44:01.800524Z","iopub.execute_input":"2023-10-29T19:44:01.801264Z","iopub.status.idle":"2023-10-29T19:44:01.812587Z","shell.execute_reply.started":"2023-10-29T19:44:01.80123Z","shell.execute_reply":"2023-10-29T19:44:01.811704Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data = pd.read_csv(\"/kaggle/input/UBC-OCEAN/train.csv\")\ntest_data =  pd.read_csv(\"/kaggle/input/UBC-OCEAN/test.csv\")\nimage_folder = r'/kaggle/input/UBC-OCEAN/train_thumbnails'\ntest_image_folder = r'/kaggle/input/UBC-OCEAN/test_thumbnails'","metadata":{"execution":{"iopub.status.busy":"2023-10-29T18:37:24.039974Z","iopub.execute_input":"2023-10-29T18:37:24.040857Z","iopub.status.idle":"2023-10-29T18:37:24.063016Z","shell.execute_reply.started":"2023-10-29T18:37:24.040823Z","shell.execute_reply":"2023-10-29T18:37:24.062112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class UBCModel(pl.LightningModule):\n\n    def __init__(self, steps_per_epoch, model_resnet):\n        super(UBCModel, self).__init__()\n        self.num_classes = 5\n        self.steps_per_epoch = steps_per_epoch\n\n        self.model = model_resnet \n        self.model.fc = nn.Linear(self.model.fc.in_features, self.num_classes)\n        \n        self.criterion = nn.CrossEntropyLoss()\n        self.f1 = MulticlassF1Score(num_classes=self.num_classes, average='macro')\n        self.accuracy = torchmetrics.Accuracy(num_classes=self.num_classes, task='multiclass')\n        self.precision = torchmetrics.Precision(average='macro', num_classes=self.num_classes, task='multiclass')\n        self.recall = torchmetrics.Recall(average='macro', num_classes=self.num_classes, task='multiclass')\n        \n    def forward(self, x):\n        x = self.model(x)\n        return x\n\n    def training_step(self, batch, batch_idx):\n        x, y = batch\n        y_pred = self(x)\n        loss = self.criterion(y_pred, y)\n        self.log('train_loss', loss)\n        self.log('train_f1', self.f1(y_pred, y))\n        return loss\n\n    def validation_step(self, batch, batch_idx):\n        x, y = batch\n        y_pred = self(x)\n        loss = self.criterion(y_pred, y)\n        self.log('val_loss', loss)\n        self.log('val_f1', self.f1(y_pred, y))\n        self.log('val_acc', self.accuracy(y_pred, y))\n        self.log('val_precision', self.precision(y_pred, y))\n        self.log('val_recall', self.recall(y_pred, y))\n    \n    def configure_optimizers(self):\n        optimizer = torch.optim.Adam(self.parameters(), lr=1e-5, weight_decay=1e-5)\n        scheduler = ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=2)\n        return {\n            'optimizer': optimizer,\n            'lr_scheduler': {\n                'scheduler': scheduler,\n                'interval': 'epoch',\n                'monitor': 'val_f1',\n                'frequency': 1,\n                'strict': True,\n            }\n        }","metadata":{"execution":{"iopub.status.busy":"2023-10-29T18:43:32.646121Z","iopub.execute_input":"2023-10-29T18:43:32.646863Z","iopub.status.idle":"2023-10-29T18:43:32.658914Z","shell.execute_reply.started":"2023-10-29T18:43:32.646834Z","shell.execute_reply":"2023-10-29T18:43:32.657953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def preprocess_dataframe(dataframe, image_folder, map_labels):\n    # Get a list of image files in the folder\n    image_files = os.listdir(image_folder)\n\n    # Create a set of image IDs from the image files\n    image_ids_in_folder = {int(filename.split('_')[0]) for filename in image_files}\n\n    # Filter the dataframe to keep only rows with image IDs present in the folder\n    dataframe_filtered = dataframe[dataframe['image_id'].isin(image_ids_in_folder)]\n    \n    # train_df, val_df = train_test_split(dataframe_filtered, test_size=0.2, stratify=dataframe_filtered.label)\n    \n    # dataframe = pd.get_dummies(dataframe_filtered, columns=['label'])\n    # val_op = pd.get_dummies(val_df, columns=['label'])\n    if map_labels:\n        label_mapping = {'HGSC': 0, 'LGSC': 1, 'EC': 2, 'CC': 3, 'MC': 4}\n\n        dataframe_filtered['label'] = dataframe_filtered['label'].map(label_mapping)\n    \n    return dataframe_filtered.reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2023-10-29T18:37:29.802371Z","iopub.execute_input":"2023-10-29T18:37:29.802727Z","iopub.status.idle":"2023-10-29T18:37:29.809481Z","shell.execute_reply.started":"2023-10-29T18:37:29.802698Z","shell.execute_reply":"2023-10-29T18:37:29.808446Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preprocess_data = preprocess_dataframe(train_data, image_folder, map_labels=True)\npreprocess_test_data = preprocess_dataframe(test_data, test_image_folder, map_labels=False)","metadata":{"execution":{"iopub.status.busy":"2023-10-29T18:37:33.672738Z","iopub.execute_input":"2023-10-29T18:37:33.673512Z","iopub.status.idle":"2023-10-29T18:37:33.794188Z","shell.execute_reply.started":"2023-10-29T18:37:33.673472Z","shell.execute_reply":"2023-10-29T18:37:33.793044Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class ImageClassificationDataModule(pl.LightningDataModule):\n    def __init__(self, custom_dataset, batch_size=32):\n        super().__init__()\n        self.custom_dataset = custom_dataset\n        self.batch_size = batch_size\n\n    def setup(self, stage=None):\n        num_data = len(self.custom_dataset)\n        train_size = int(0.8 * num_data)\n        val_size = num_data - train_size\n        self.train_data, self.val_data = random_split(self.custom_dataset, [train_size, val_size])\n\n    def train_dataloader(self):\n        return DataLoader(self.train_data, batch_size=self.batch_size, shuffle=True, num_workers=47)\n\n    def val_dataloader(self):\n        return DataLoader(self.val_data, batch_size=self.batch_size, num_workers=12)\n\nclass CustomCancerDataset(Dataset):\n    def __init__(self, metadata_df, image_folder, transform=None):\n        self.metadata_df = metadata_df\n        self.image_folder = image_folder\n        self.transform = transforms.Compose(\n                [transforms.Resize((224, 224)),\n                 transforms.ToTensor(), \n                 transforms.Normalize(mean=[0.48828688, 0.42932517, 0.49162089], std=[0.41380908, 0.37492874, 0.41795654])]\n            )\n\n    def __len__(self):\n        return len(self.metadata_df)\n\n    def __getitem__(self, idx):\n        image_ids = self.metadata_df.image_id[idx]  \n        image_name = os.path.join(self.image_folder, \"{}_thumbnail.png\".format(image_ids))\n        # print(image_name)\n        image = Image.open(image_name)\n        # label_CC  = self.metadata_df.label_CC[idx].astype(int)  \n        # label_EC  = self.metadata_df.label_EC[idx].astype(int)    \n        # label_HGSC  = self.metadata_df.label_HGSC[idx].astype(int)    \n        # label_LGSC  = self.metadata_df.label_LGSC[idx].astype(int)    \n        # label_MC  = self.metadata_df.label_MC[idx].astype(int)    \n        label = self.metadata_df.label[idx]\n        \n        if self.transform:\n            image = self.transform(image)\n\n        return image, torch.tensor(label, dtype=torch.long)","metadata":{"execution":{"iopub.status.busy":"2023-10-29T18:37:35.930468Z","iopub.execute_input":"2023-10-29T18:37:35.931328Z","iopub.status.idle":"2023-10-29T18:37:35.943347Z","shell.execute_reply.started":"2023-10-29T18:37:35.931294Z","shell.execute_reply":"2023-10-29T18:37:35.942349Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_resnet = resnet34()\nmodel_resnet.load_state_dict(torch.load('/kaggle/input/resnet34/resnet34.pth'))\n\nmodel = UBCModel(50, model_resnet)\n\n# from datasets import CustomCancerDataset\nimage_folder = r'/kaggle/input/UBC-OCEAN/train_thumbnails'\ncustom_dataset = CustomCancerDataset(metadata_df=preprocess_data, image_folder=image_folder)\n\ndata_module = ImageClassificationDataModule(custom_dataset, batch_size=32)","metadata":{"execution":{"iopub.status.busy":"2023-10-29T18:56:38.958328Z","iopub.execute_input":"2023-10-29T18:56:38.959015Z","iopub.status.idle":"2023-10-29T18:56:39.494498Z","shell.execute_reply.started":"2023-10-29T18:56:38.958981Z","shell.execute_reply":"2023-10-29T18:56:39.49371Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainer = pl.Trainer(\n    max_epochs=15, \n    accelerator = 'cuda',\n    log_every_n_steps=1)","metadata":{"execution":{"iopub.status.busy":"2023-10-29T18:57:03.974225Z","iopub.execute_input":"2023-10-29T18:57:03.975045Z","iopub.status.idle":"2023-10-29T18:57:04.312851Z","shell.execute_reply.started":"2023-10-29T18:57:03.975008Z","shell.execute_reply":"2023-10-29T18:57:04.3119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainer.fit(model, data_module)","metadata":{"execution":{"iopub.status.busy":"2023-10-29T18:57:15.564466Z","iopub.execute_input":"2023-10-29T18:57:15.564838Z","iopub.status.idle":"2023-10-29T19:05:17.415443Z","shell.execute_reply.started":"2023-10-29T18:57:15.56481Z","shell.execute_reply":"2023-10-29T19:05:17.414423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CustomTestCancerDataset(Dataset):\n    def __init__(self, metadata_df, image_folder, transform=None):\n        self.metadata_df = metadata_df\n        self.image_folder = image_folder\n        self.transform = transforms.Compose(\n                [transforms.Resize((224, 224)),\n                 transforms.ToTensor(), \n                 transforms.Normalize(mean=[0.48828688, 0.42932517, 0.49162089], std=[0.41380908, 0.37492874, 0.41795654])]\n            )\n\n    def __len__(self):\n        return len(self.metadata_df)\n\n    def __getitem__(self, idx):\n        image_ids = self.metadata_df.image_id[idx]  \n        image_name = os.path.join(self.image_folder, \"{}_thumbnail.png\".format(image_ids))\n        # print(image_name)\n        image = Image.open(image_name)\n        # label_CC  = self.metadata_df.label_CC[idx].astype(int)  \n        # label_EC  = self.metadata_df.label_EC[idx].astype(int)    \n        # label_HGSC  = self.metadata_df.label_HGSC[idx].astype(int)    \n        # label_LGSC  = self.metadata_df.label_LGSC[idx].astype(int)    \n        # label_MC  = self.metadata_df.label_MC[idx].astype(int)    \n#         label = self.metadata_df.label[idx]\n        \n        if self.transform:\n            image = self.transform(image)\n\n        return image","metadata":{"execution":{"iopub.status.busy":"2023-10-29T19:36:37.334956Z","iopub.execute_input":"2023-10-29T19:36:37.335691Z","iopub.status.idle":"2023-10-29T19:36:37.343442Z","shell.execute_reply.started":"2023-10-29T19:36:37.33566Z","shell.execute_reply":"2023-10-29T19:36:37.342456Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dataset = CustomTestCancerDataset(preprocess_test_data, image_folder=test_image_folder)\ntest_dataloader = DataLoader(test_dataset, batch_size=32, shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2023-10-29T19:36:47.675093Z","iopub.execute_input":"2023-10-29T19:36:47.675447Z","iopub.status.idle":"2023-10-29T19:36:47.681003Z","shell.execute_reply.started":"2023-10-29T19:36:47.675419Z","shell.execute_reply":"2023-10-29T19:36:47.680007Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.eval()\nlabel_mapping = {'HGSC': 0, 'LGSC': 1, 'EC': 2, 'CC': 3, 'MC': 4}\npredictions = []\n\nwith torch.no_grad():\n    for batch in test_dataloader:\n        inputs = batch  # If you don't have labels, you only need the input images.\n        outputs = model(inputs)\n        probabilities = F.softmax(outputs, dim=1)  # Assuming the output is a single tensor in a list\n        predicted_class_index = torch.argmax(probabilities, dim=1).item()\n        predicted_class_label = {v: k for k, v in label_mapping.items()}[predicted_class_index]\n        predictions.append(predicted_class_label)","metadata":{"execution":{"iopub.status.busy":"2023-10-29T20:15:11.268189Z","iopub.execute_input":"2023-10-29T20:15:11.269047Z","iopub.status.idle":"2023-10-29T20:15:11.520119Z","shell.execute_reply.started":"2023-10-29T20:15:11.269014Z","shell.execute_reply":"2023-10-29T20:15:11.519106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_df = pd.DataFrame()\npred_df['image_id'] = test_data['image_id']\npred_df['label'] = predictions","metadata":{"execution":{"iopub.status.busy":"2023-10-29T20:36:04.427304Z","iopub.execute_input":"2023-10-29T20:36:04.427933Z","iopub.status.idle":"2023-10-29T20:36:04.436455Z","shell.execute_reply.started":"2023-10-29T20:36:04.427902Z","shell.execute_reply":"2023-10-29T20:36:04.435489Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_df.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-10-29T20:36:46.326782Z","iopub.execute_input":"2023-10-29T20:36:46.327529Z","iopub.status.idle":"2023-10-29T20:36:46.334747Z","shell.execute_reply.started":"2023-10-29T20:36:46.327493Z","shell.execute_reply":"2023-10-29T20:36:46.333854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}