{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":45867,"databundleVersionId":6924515,"sourceType":"competition"},{"sourceId":7165012,"sourceType":"datasetVersion","datasetId":4138888},{"sourceId":7165713,"sourceType":"datasetVersion","datasetId":4139395},{"sourceId":7174946,"sourceType":"datasetVersion","datasetId":4146055},{"sourceId":7232062,"sourceType":"datasetVersion","datasetId":4187613}],"dockerImageVersionId":30615,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Version update:         \n                                           \n**1.Version 1: [0.27]**                                        \nModel: siamese                                             \nData processing: Random match pair(neg-pos + pos-pos)                    \nBackbone: Efficientnet                                                                     \nEmbedding: Gem pooling + FC                                   \nClassifier: Gem pooling + FC+FC                                                               \nMetric: Balance accuracy                                                            \nTraining image-size: 256           \nmargin : 0.5                             \nLoss: Generalized Contrastive Learning loss + Crossentropy loss(+ Class-weight)                \n                         \n**2.Version 2: [0.3]**  \nSame as version 1 but remove fc layer (before : gem pooling+ fc ---> Gem pooling )                                       \n**2.Version 3: [0.29]**                              \nSame as version 2 but remove few last layer + train fold 0                 \nNotebook: https://www.kaggle.com/code/bhuynguyn/ubc-train-with-efficientnetv2-l-in21ft1k?scriptVersionId=154333460        ","metadata":{}},{"cell_type":"code","source":"import os\nimport gc\nimport cv2\nimport math\nimport copy\nimport time\nimport random\nimport glob\nfrom PIL import Image\nfrom matplotlib import pyplot as plt\n\n# For data manipulation\nimport numpy as np\nimport pandas as pd\n\n# Pytorch Imports\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nfrom torch.optim import lr_scheduler\nfrom torch.utils.data import Dataset, DataLoader\nfrom torch.cuda import amp\nimport torchvision\n\n# Utils\nimport joblib\nfrom tqdm import tqdm\nfrom collections import defaultdict\n\n# Sklearn Imports\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.model_selection import StratifiedKFold\n\n# For Image Models\nimport timm\n\n# Albumentations for augmentations\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\n\n# For colored terminal text\nfrom colorama import Fore, Back, Style\nb_ = Fore.BLUE\nsr_ = Style.RESET_ALL\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\n# For descriptive error messages\nos.environ['CUDA_LAUNCH_BLOCKING'] = \"1\"","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-12-18T17:12:07.771997Z","iopub.execute_input":"2023-12-18T17:12:07.7725Z","iopub.status.idle":"2023-12-18T17:12:07.784631Z","shell.execute_reply.started":"2023-12-18T17:12:07.772464Z","shell.execute_reply":"2023-12-18T17:12:07.783698Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from albumentations import (\n    Compose, OneOf, Normalize, Resize, RandomResizedCrop, RandomCrop, HorizontalFlip, VerticalFlip, \n    RandomBrightness, RandomContrast, RandomBrightnessContrast, Rotate, ShiftScaleRotate, Cutout, \n    IAAAdditiveGaussianNoise, Transpose\n    )\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2","metadata":{"execution":{"iopub.status.busy":"2023-12-18T17:13:01.100873Z","iopub.execute_input":"2023-12-18T17:13:01.101307Z","iopub.status.idle":"2023-12-18T17:13:01.109124Z","shell.execute_reply.started":"2023-12-18T17:13:01.101276Z","shell.execute_reply":"2023-12-18T17:13:01.107535Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"CONFIG = {\n    \"seed\": 42,\n    \"img_size\": 256,\n    \"model_name\": 'tf_efficientnetv2_m',#\"tf_efficientnet_b0_ns\",\n    \"num_classes\": 5,\n    \"valid_batch_size\": 4,\n    \"device\": torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\"),\n}\n\ndef set_seed(seed=42):\n    '''Sets the seed of the entire notebook so results are the same every time we run.\n    This is for REPRODUCIBILITY.'''\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    # When running on the CuDNN backend, two further options must be set\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n    # Set a fixed value for the hash seed\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    \nset_seed(CONFIG['seed'])\nROOT_DIR = '/kaggle/input/UBC-OCEAN'\nTEST_DIR = '/kaggle/input/UBC-OCEAN/test_thumbnails' #'/kaggle/working/test_thumbnails'#'/kaggle/input/UBC-OCEAN/test_thumbnails'\nEVALUATION_DIR ='/kaggle/input/UBC-OCEAN/train_images'\nLABEL_ENCODER_BIN ='/kaggle/input/efficiennet-siamese-data/label_encoder.pkl'\n\ndef get_test_file_path(image_id):\n    return f\"{TEST_DIR}/{image_id}_thumbnail.png\"\n\ndf = pd.read_csv(f\"{ROOT_DIR}/test.csv\")\ndf['file_path'] = df['image_id'].apply(get_test_file_path)\ndf['label'] = 0 # dummy\n\n# encoder = joblib.load( LABEL_ENCODER_BIN )\ndf_sub = pd.read_csv(f\"{ROOT_DIR}/sample_submission.csv\")\ndf_sub\n# ======================================================Dataset=================================================#\nclass UBCDataset(Dataset):\n    def __init__(self,df,transforms=None):\n        self.df=df\n        self.label=self.df.label\n        self.transform =transforms\n    def __len__(self):\n        return len(self.df)\n    def __getitem__(self,idx):\n\n        image1=cv2.imread(self.df.file_path.iloc[idx])\n        image1= cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)\n        \n        if self.transform:\n            image1 = self.transform(image=image1)['image']\n\n        return {\n            'image': image1}\n    \n#================================================================Augmentation=======================================#\ndata_transforms = {\n    \"train\": A.Compose([\n#         A.Resize(CONFIG['img_size'], CONFIG['img_size']),\n        RandomCrop(CONFIG['img_size'], CONFIG['img_size']),\n        A.HorizontalFlip(p=0.5),\n        A.VerticalFlip(p=0.5),\n        A.RandomBrightnessContrast(p=0.75),\n        A.ShiftScaleRotate(p=0.75),\n        A.OneOf([\n                A.GaussNoise(var_limit=[10, 50]),\n                A.GaussianBlur(),\n                A.MotionBlur(),\n                ], p=0.4),\n        A.GridDistortion(num_steps=5, distort_limit=0.3, p=0.5),\n        A.CoarseDropout(max_holes=1, max_width=int(CONFIG['img_size'] * 0.13), max_height=int(CONFIG['img_size'] * 0.13), \n                        mask_fill_value=0, p=0.5),\n        A.Normalize(\n                mean=[0.485, 0.456, 0.406], \n                std=[0.229, 0.224, 0.225], \n                max_pixel_value=255.0, \n                p=1.0\n            ),\n        ToTensorV2()], p=1.),\n    \n    \"valid\": A.Compose([\n#         A.Resize(CONFIG['img_size'], CONFIG['img_size']),\n        RandomCrop(CONFIG['img_size'], CONFIG['img_size']),\n        A.Normalize(\n                mean=[0.485, 0.456, 0.406], \n                std=[0.229, 0.224, 0.225], \n                max_pixel_value=255.0, \n                p=1.0\n            ),\n        ToTensorV2()], p=1.)\n}\n#=================================================Create inference dataset/dataloader===============================#\ntest_dataset = UBCDataset(df, transforms=data_transforms[\"valid\"])\ntest_loader = DataLoader(test_dataset, batch_size=CONFIG['valid_batch_size'],num_workers=2, shuffle=False, pin_memory=True)","metadata":{"execution":{"iopub.status.busy":"2023-12-18T17:13:18.246262Z","iopub.execute_input":"2023-12-18T17:13:18.246705Z","iopub.status.idle":"2023-12-18T17:13:18.310409Z","shell.execute_reply.started":"2023-12-18T17:13:18.246668Z","shell.execute_reply":"2023-12-18T17:13:18.309224Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class GeM(nn.Module):\n    def __init__(self, p=3, eps=1e-6):\n        super(GeM, self).__init__()\n        self.p = nn.Parameter(torch.ones(1)*p)\n        self.eps = eps\n\n    def forward(self, x):\n        return self.gem(x, p=self.p, eps=self.eps)\n        \n    def gem(self, x, p=3, eps=1e-6):\n        return F.avg_pool2d(x.clamp(min=eps).pow(p), (x.size(-2), x.size(-1))).pow(1./p)\n        \n    def __repr__(self):\n        return self.__class__.__name__ + \\\n                '(' + 'p=' + '{:.4f}'.format(self.p.data.tolist()[0]) + \\\n                ', ' + 'eps=' + str(self.eps) + ')'\n    \nclass UBCModel(nn.Module):\n    def __init__(self, model_name, num_classes, pretrained=True, checkpoint_path=None):\n        super(UBCModel, self).__init__()\n        self.model = timm.create_model(model_name, pretrained=pretrained)\n        if model_name == 'tf_efficientnetv2_m':\n            in_features = 512 #self.model.classifier.in_features\n            self.model.conv_head = nn.Identity()\n            self.model.bn2 = nn.Identity()\n            self.model.classifier = nn.Identity()\n            self.model.global_pool = nn.Identity()\n        self.pooling = GeM()\n#         self.fc = nn.Linear(in_features, 512)\n        self.linear = nn.Sequential(nn.Linear(in_features, num_classes))\n        self.softmax = nn.Softmax(dim=1)\n\n    def forward(self, images):\n        features = self.model(images)\n        pooled_features = self.pooling(features).flatten(1)\n#         pooled_features = self.fc(pooled_features)\n        output = self.linear(pooled_features)\n        return pooled_features,output\n\n    \nmodel = UBCModel(CONFIG['model_name'], CONFIG['num_classes'],pretrained=False) #, checkpoint_path=CONFIG['checkpoint_path']\nmodel.load_state_dict(torch.load('/kaggle/input/efficientnet-siamese/Acc0.74_Loss0.6874_epoch24.bin',map_location=CONFIG[\"device\"]))\nmodel.to(CONFIG['device'])\nprint('ok')","metadata":{"execution":{"iopub.status.busy":"2023-12-18T17:13:51.715422Z","iopub.execute_input":"2023-12-18T17:13:51.71592Z","iopub.status.idle":"2023-12-18T17:13:55.19058Z","shell.execute_reply.started":"2023-12-18T17:13:51.715883Z","shell.execute_reply":"2023-12-18T17:13:55.189166Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# preds = []\n# with torch.no_grad():\n#     bar = tqdm(enumerate(test_loader), total=len(test_loader))\n#     for step, data in bar:        \n#         images = data['image'].to(CONFIG[\"device\"], dtype=torch.float)        \n#         batch_size = images.size(0)\n#         _,outputs = model(images)\n#         print(model.softmax(outputs))\n#         _, predicted = torch.max(model.softmax(outputs), 1)\n#         print(predicted)\n#         preds.append( predicted.detach().cpu().numpy() )\n# preds = np.concatenate(preds).flatten()\n# pred_labels = encoder.inverse_transform(preds)","metadata":{"execution":{"iopub.status.busy":"2023-12-11T10:44:19.051538Z","iopub.execute_input":"2023-12-11T10:44:19.052267Z","iopub.status.idle":"2023-12-11T10:44:20.310165Z","shell.execute_reply.started":"2023-12-11T10:44:19.052228Z","shell.execute_reply":"2023-12-11T10:44:20.309Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = []\nwith torch.no_grad():\n    bar = tqdm(enumerate(test_loader), total=len(test_loader))\n    for step, data in bar:        \n        images = data['image'].to(CONFIG[\"device\"], dtype=torch.float)  \n        batch_size = images.size(0)\n        _,outputs= model(images)\n        outputs = torch.softmax(outputs,dim=-1)\n        print(outputs)\n        _, predicted = torch.max(outputs, 1)\n        predictions.extend(predicted.cpu().numpy())","metadata":{"execution":{"iopub.status.busy":"2023-12-18T17:14:03.36317Z","iopub.execute_input":"2023-12-18T17:14:03.363607Z","iopub.status.idle":"2023-12-18T17:14:04.400932Z","shell.execute_reply.started":"2023-12-18T17:14:03.363574Z","shell.execute_reply":"2023-12-18T17:14:04.399415Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Convert numerical labels to original string labels\nlabel_map = {\n    0: \"HGSC\",\n    1: \"EC\",\n    2: \"CC\",\n    3: \"LGSC\",\n    4: \"MC\",\n}\npredictions = [label_map[p] for p in predictions]\n\ndf_sub[\"label\"] = predictions #pred_labels\ndf_sub.to_csv(\"submission.csv\", index=False)\ndf_sub","metadata":{"execution":{"iopub.status.busy":"2023-12-18T17:14:16.26202Z","iopub.execute_input":"2023-12-18T17:14:16.262457Z","iopub.status.idle":"2023-12-18T17:14:16.289323Z","shell.execute_reply.started":"2023-12-18T17:14:16.26242Z","shell.execute_reply":"2023-12-18T17:14:16.287973Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# df_sub[\"label\"] = pred_labels\n# df_sub.to_csv(\"submission.csv\", index=False)\n# df_sub","metadata":{"execution":{"iopub.status.busy":"2023-12-11T10:44:28.908696Z","iopub.execute_input":"2023-12-11T10:44:28.909161Z","iopub.status.idle":"2023-12-11T10:44:28.934522Z","shell.execute_reply.started":"2023-12-11T10:44:28.90912Z","shell.execute_reply":"2023-12-11T10:44:28.933073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}