{"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":"markdown","source":"# BASELINE USING SMP U-Net\n","metadata":{"execution":{"iopub.status.busy":"2023-06-14T03:57:23.59868Z","iopub.execute_input":"2023-06-14T03:57:23.599101Z","iopub.status.idle":"2023-06-14T03:58:00.964865Z","shell.execute_reply.started":"2023-06-14T03:57:23.599065Z","shell.execute_reply":"2023-06-14T03:58:00.963349Z"}}},{"cell_type":"code","source":"!pip install segmentation_models_pytorch -q\n!pip install warmup_scheduler -q","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2023-07-17T06:58:14.463295Z","iopub.execute_input":"2023-07-17T06:58:14.463752Z","iopub.status.idle":"2023-07-17T06:58:44.754210Z","shell.execute_reply.started":"2023-07-17T06:58:14.463706Z","shell.execute_reply":"2023-07-17T06:58:44.753049Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Lets import the libraries","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport scipy as sp\nfrom sklearn.metrics import roc_auc_score, accuracy_score, f1_score, log_loss\nimport matplotlib.pyplot as plt\nimport sys\nimport os\nimport gc\nimport sys\nimport pickle\nimport warnings\nimport math\nimport time\nimport random\nimport argparse\nimport importlib\nfrom tqdm.auto import tqdm\nfrom functools import partial\n\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import DataLoader, Dataset\nfrom torch.cuda.amp import autocast, GradScaler\nfrom torch.optim import Adam, SGD, AdamW\nfrom torch.optim.lr_scheduler import CosineAnnealingWarmRestarts, CosineAnnealingLR, ReduceLROnPlateau\nimport segmentation_models_pytorch as smp\nfrom warmup_scheduler import GradualWarmupScheduler\nimport cv2\n\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nfrom albumentations import ImageOnlyTransform\n\nimport shutil\nfrom pathlib import Path\nfrom contextlib import contextmanager\nfrom collections import defaultdict, Counter\nimport datetime","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-07-17T06:58:44.756588Z","iopub.execute_input":"2023-07-17T06:58:44.757332Z","iopub.status.idle":"2023-07-17T06:58:51.418412Z","shell.execute_reply.started":"2023-07-17T06:58:44.757289Z","shell.execute_reply":"2023-07-17T06:58:51.417494Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nfrom torch.utils.data import DataLoader, Dataset\nimport cv2\nimport torch\nimport os\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nfrom albumentations import ImageOnlyTransform\nimport json\nfrom PIL import Image\nfrom IPython.display import IFrame\n","metadata":{"execution":{"iopub.status.busy":"2023-07-17T06:58:51.419728Z","iopub.execute_input":"2023-07-17T06:58:51.420101Z","iopub.status.idle":"2023-07-17T06:58:51.427455Z","shell.execute_reply.started":"2023-07-17T06:58:51.420063Z","shell.execute_reply":"2023-07-17T06:58:51.426144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import ssl\nssl._create_default_https_context = ssl._create_unverified_context","metadata":{"execution":{"iopub.status.busy":"2023-07-17T06:58:51.430218Z","iopub.execute_input":"2023-07-17T06:58:51.430768Z","iopub.status.idle":"2023-07-17T06:58:51.438391Z","shell.execute_reply.started":"2023-07-17T06:58:51.430732Z","shell.execute_reply":"2023-07-17T06:58:51.437456Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Configuration Class","metadata":{}},{"cell_type":"code","source":"class CFG:\n    # ============== comp exp name =============\n    comp_name = 'HuBMAP'\n    exp_name = 'resnet50'\n    comp_dir_path = '/kaggle/input/'\n    comp_folder_name = 'HuBMAP-Hacking-the-Human-Vasculature'\n    comp_dataset_path = f'{comp_dir_path}{comp_folder_name}/'\n\n    # ============== pred target =============\n    target_size = 1\n\n    # ============== model cfg =============\n    model_name = 'Unet'\n    backbone = 'resnet50' #'se_resnext50_32x4d'\n\n    in_chans = 3 # 65\n    # ============== training cfg =============\n    size = 512\n    tile_size = 512\n    stride = tile_size // 4\n\n    train_batch_size = 32 # 32\n    valid_batch_size = train_batch_size * 1\n    use_amp = True\n\n#     scheduler = 'GradualWarmupSchedulerV2' # 'GradualWarmupSchedulerV2' # 'CosineAnnealingLR'\n    epochs = 5 # 30\n\n    # adamW warmupあり\n    warmup_factor = 10\n    # lr = 1e-4 / warmup_factor\n    lr = 1e-4 / warmup_factor\n\n    # ============== fold =============\n\n\n    # objective_cv = 'binary'  # 'binary', 'multiclass', 'regression'\n    metric_direction = 'maximize'  # maximize, 'minimize'\n    # metrics = 'dice_coef'\n\n    # ============== fixed =============\n    pretrained = True\n    inf_weight = 'best'  # 'best'\n\n    min_lr = 1e-6\n    weight_decay = 1e-6\n    max_grad_norm = 1000\n\n    print_freq = 50\n    num_workers = 2\n\n    seed = 42\n\n    # ============== set dataset path =============\n    print('set dataset path')\n    train_dir = \"/kaggle/input/hubmap-hacking-the-human-vasculature/train\"\n    test_dir = \"/kaggle/input/hubmap-hacking-the-human-vasculature/test\"\n    labels_file = '../input/hubmap-hacking-the-human-vasculature/polygons.jsonl'\n\n    outputs_path = f'/kaggle/working/outputs/{comp_name}/{exp_name}/'\n\n    submission_dir = outputs_path + 'submissions/'\n    submission_path = submission_dir + f'submission_{exp_name}.csv'\n\n    model_dir = outputs_path + \\\n        f'{comp_name}-models/'\n\n    figures_dir = outputs_path + 'figures/'\n\n    log_dir = outputs_path + 'logs/'\n    log_path = log_dir + f'{exp_name}.txt'\n\n    # ============== augmentation =============\n    train_aug_list = [\n        A.Resize(size, 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(size * 0.3), max_height=int(size * 0.3), \n                        mask_fill_value=0, p=0.5),\n        A.Normalize(\n            mean= [0] * in_chans,\n            std= [1] * in_chans\n        ),\n        ToTensorV2(transpose_mask=True),\n    ]\n\n    valid_aug_list = [\n        A.Resize(size, size),\n        A.Normalize(\n            mean= [0] * in_chans,\n            std= [1] * in_chans\n        ),\n        ToTensorV2(transpose_mask=True),\n    ]","metadata":{"execution":{"iopub.status.busy":"2023-07-17T06:58:51.439765Z","iopub.execute_input":"2023-07-17T06:58:51.440316Z","iopub.status.idle":"2023-07-17T06:58:51.457473Z","shell.execute_reply.started":"2023-07-17T06:58:51.440284Z","shell.execute_reply":"2023-07-17T06:58:51.456227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class AverageMeter(object):\n    \"\"\"Computes and stores the average and current value\"\"\"\n\n    def __init__(self):\n        self.reset()\n\n    def reset(self):\n        self.val = 0\n        self.avg = 0\n        self.sum = 0\n        self.count = 0\n\n    def update(self, val, n=1):\n        self.val = val\n        self.sum += val * n\n        self.count += n\n        self.avg = self.sum / self.count","metadata":{"execution":{"iopub.status.busy":"2023-07-17T06:58:51.459130Z","iopub.execute_input":"2023-07-17T06:58:51.459618Z","iopub.status.idle":"2023-07-17T06:58:51.470856Z","shell.execute_reply.started":"2023-07-17T06:58:51.459587Z","shell.execute_reply":"2023-07-17T06:58:51.469983Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def init_logger(log_file):\n    from logging import getLogger, INFO, FileHandler, Formatter, StreamHandler\n    logger = getLogger(__name__)\n    logger.setLevel(INFO)\n    handler1 = StreamHandler()\n    handler1.setFormatter(Formatter(\"%(message)s\"))\n    handler2 = FileHandler(filename=log_file)\n    handler2.setFormatter(Formatter(\"%(message)s\"))\n    logger.addHandler(handler1)\n    logger.addHandler(handler2)\n    return logger\n\ndef set_seed(seed=None, cudnn_deterministic=True):\n    if seed is None:\n        seed = 310\n    \n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = cudnn_deterministic\n    torch.backends.cudnn.benchmark = False","metadata":{"execution":{"iopub.status.busy":"2023-07-17T06:58:51.472311Z","iopub.execute_input":"2023-07-17T06:58:51.472657Z","iopub.status.idle":"2023-07-17T06:58:51.481506Z","shell.execute_reply.started":"2023-07-17T06:58:51.472626Z","shell.execute_reply":"2023-07-17T06:58:51.480549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_dirs(cfg):\n    for dir in [cfg.model_dir, cfg.figures_dir, cfg.submission_dir, cfg.log_dir]:\n        os.makedirs(dir, exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2023-07-17T06:58:51.482980Z","iopub.execute_input":"2023-07-17T06:58:51.483323Z","iopub.status.idle":"2023-07-17T06:58:51.493091Z","shell.execute_reply.started":"2023-07-17T06:58:51.483292Z","shell.execute_reply":"2023-07-17T06:58:51.492289Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def cfg_init(cfg, mode='train'):\n    set_seed(cfg.seed)\n\n    if mode == 'train':\n        make_dirs(cfg)","metadata":{"execution":{"iopub.status.busy":"2023-07-17T06:58:51.494531Z","iopub.execute_input":"2023-07-17T06:58:51.494986Z","iopub.status.idle":"2023-07-17T06:58:51.502479Z","shell.execute_reply.started":"2023-07-17T06:58:51.494907Z","shell.execute_reply":"2023-07-17T06:58:51.501652Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfg_init(CFG)\n\nLogger = init_logger(log_file=CFG.log_path)\n\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')","metadata":{"execution":{"iopub.status.busy":"2023-07-17T06:58:51.506032Z","iopub.execute_input":"2023-07-17T06:58:51.506334Z","iopub.status.idle":"2023-07-17T06:58:51.540796Z","shell.execute_reply.started":"2023-07-17T06:58:51.506311Z","shell.execute_reply":"2023-07-17T06:58:51.540220Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Lets read the images","metadata":{}},{"cell_type":"code","source":"class hubmapDataset(Dataset):\n    \n    def __init__(self, cfg, transform = False):\n        \n        with open(cfg.labels_file, 'r') as json_file:\n            self.json_labels = [json.loads(line) for line in json_file]\n\n        self.image_dir = cfg.train_dir\n#         self.transform = transform\n        self.transform = transform\n\n    __len__ = lambda self : len(self.json_labels)    \n        \n    def __getitem__(self, idx):\n        \n        image_path = os.path.join(self.image_dir, f\"{self.json_labels[idx]['id']}.tif\")\n        image = Image.open(image_path)\n        image= np.array(image)\n                \n        mask = np.zeros((512, 512), dtype=np.float32)\n        \n        \n        labels = []\n        annotations = self.json_labels[idx]['annotations']\n        for annotation in annotations:\n            if annotation['type'] == 'blood_vessel':\n                labels.append(annotation['coordinates'])\n                \n        for vessel in labels:\n            mask = cv2.fillPoly(\n                            mask, pts=np.array(vessel),\n                            color=(255, 8, 8)\n                        )\n\n        if self.transform:\n            data = self.transform(image=image, mask=mask)\n        \n        image = data['image']\n        mask = data['mask']\n        \n\n        return image, mask","metadata":{"execution":{"iopub.status.busy":"2023-07-17T06:58:51.542073Z","iopub.execute_input":"2023-07-17T06:58:51.542394Z","iopub.status.idle":"2023-07-17T06:58:51.553811Z","shell.execute_reply.started":"2023-07-17T06:58:51.542365Z","shell.execute_reply":"2023-07-17T06:58:51.552712Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_transforms(data, cfg):\n    if data == 'train':\n        aug = A.Compose(cfg.train_aug_list)\n    elif data == 'valid':\n        aug = A.Compose(cfg.valid_aug_list)\n\n    # print(aug)\n    return aug\n","metadata":{"execution":{"iopub.status.busy":"2023-07-17T06:58:51.555374Z","iopub.execute_input":"2023-07-17T06:58:51.555726Z","iopub.status.idle":"2023-07-17T06:58:51.567036Z","shell.execute_reply.started":"2023-07-17T06:58:51.555693Z","shell.execute_reply":"2023-07-17T06:58:51.566217Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset = hubmapDataset(\n    CFG, transform=get_transforms(data='train', cfg=CFG))","metadata":{"execution":{"iopub.status.busy":"2023-07-17T06:58:51.568477Z","iopub.execute_input":"2023-07-17T06:58:51.568821Z","iopub.status.idle":"2023-07-17T06:58:56.103351Z","shell.execute_reply.started":"2023-07-17T06:58:51.568790Z","shell.execute_reply":"2023-07-17T06:58:56.102066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'image_shape={dataset[0][0].shape}')  \n\nprint(f'mask_shape={dataset[0][1].shape}')  \n","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:00:09.659603Z","iopub.execute_input":"2023-07-17T07:00:09.659956Z","iopub.status.idle":"2023-07-17T07:00:09.859452Z","shell.execute_reply.started":"2023-07-17T07:00:09.659926Z","shell.execute_reply":"2023-07-17T07:00:09.857406Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Lets make the Loader and Split into train_val ","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nfrom torch.utils.data import DataLoader","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:00:16.931292Z","iopub.execute_input":"2023-07-17T07:00:16.931629Z","iopub.status.idle":"2023-07-17T07:00:16.936527Z","shell.execute_reply.started":"2023-07-17T07:00:16.931602Z","shell.execute_reply":"2023-07-17T07:00:16.935106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**20% of the train is split into the validation set**","metadata":{}},{"cell_type":"code","source":"train_data, val_data = train_test_split(dataset, test_size=0.2, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:00:18.594036Z","iopub.execute_input":"2023-07-17T07:00:18.594680Z","iopub.status.idle":"2023-07-17T07:01:22.106947Z","shell.execute_reply.started":"2023-07-17T07:00:18.594646Z","shell.execute_reply":"2023-07-17T07:01:22.105841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del dataset\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:01:22.109223Z","iopub.execute_input":"2023-07-17T07:01:22.109631Z","iopub.status.idle":"2023-07-17T07:01:22.537425Z","shell.execute_reply.started":"2023-07-17T07:01:22.109590Z","shell.execute_reply":"2023-07-17T07:01:22.536262Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(train_data), len(val_data)","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:01:22.538922Z","iopub.execute_input":"2023-07-17T07:01:22.539477Z","iopub.status.idle":"2023-07-17T07:01:22.547361Z","shell.execute_reply.started":"2023-07-17T07:01:22.539443Z","shell.execute_reply":"2023-07-17T07:01:22.546381Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_loader = DataLoader(train_data,\n                          batch_size=CFG.train_batch_size, \n                          shuffle=True,drop_last=True)\nvalid_loader = DataLoader(val_data, batch_size=CFG.valid_batch_size,\n                         shuffle=False,\n                         drop_last=False)","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:01:22.550242Z","iopub.execute_input":"2023-07-17T07:01:22.550688Z","iopub.status.idle":"2023-07-17T07:01:22.556982Z","shell.execute_reply.started":"2023-07-17T07:01:22.550643Z","shell.execute_reply":"2023-07-17T07:01:22.555940Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del train_data","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:01:22.558639Z","iopub.execute_input":"2023-07-17T07:01:22.558964Z","iopub.status.idle":"2023-07-17T07:01:22.569084Z","shell.execute_reply.started":"2023-07-17T07:01:22.558932Z","shell.execute_reply":"2023-07-17T07:01:22.568152Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del val_data","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:01:22.570590Z","iopub.execute_input":"2023-07-17T07:01:22.570985Z","iopub.status.idle":"2023-07-17T07:01:22.577739Z","shell.execute_reply.started":"2023-07-17T07:01:22.570955Z","shell.execute_reply":"2023-07-17T07:01:22.577058Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:01:22.578840Z","iopub.execute_input":"2023-07-17T07:01:22.580128Z","iopub.status.idle":"2023-07-17T07:01:22.782077Z","shell.execute_reply.started":"2023-07-17T07:01:22.580104Z","shell.execute_reply":"2023-07-17T07:01:22.780968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Lets write the model","metadata":{}},{"cell_type":"code","source":"class CustomModel(nn.Module):\n    def __init__(self, cfg, weight=None):\n        super().__init__()\n        self.cfg = cfg\n\n        self.encoder = smp.Unet(\n            encoder_name=cfg.backbone, \n            encoder_weights=weight,\n            in_channels=cfg.in_chans,\n            classes=cfg.target_size,\n            activation=None,\n        )\n\n    def forward(self, image):\n        output = self.encoder(image)\n        # output = output.squeeze(-1)\n        return output\n\n\ndef build_model(cfg, weight=\"imagenet\"):\n    print('model_name', cfg.model_name)\n    print('backbone', cfg.backbone)\n\n    model = CustomModel(cfg, weight)\n\n    return model","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:01:22.784014Z","iopub.execute_input":"2023-07-17T07:01:22.784434Z","iopub.status.idle":"2023-07-17T07:01:22.793768Z","shell.execute_reply.started":"2023-07-17T07:01:22.784402Z","shell.execute_reply":"2023-07-17T07:01:22.792837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# can add schedulers","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:01:22.795100Z","iopub.execute_input":"2023-07-17T07:01:22.795543Z","iopub.status.idle":"2023-07-17T07:01:22.802825Z","shell.execute_reply.started":"2023-07-17T07:01:22.795494Z","shell.execute_reply":"2023-07-17T07:01:22.801914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch.nn as nn\nimport torch\nimport math\nimport time\nimport numpy as np\nimport torch\n\nfrom torch.optim.lr_scheduler import CosineAnnealingWarmRestarts, CosineAnnealingLR, ReduceLROnPlateau\nfrom warmup_scheduler import GradualWarmupScheduler\n\n\nclass GradualWarmupSchedulerV2(GradualWarmupScheduler):\n    \"\"\"\n    https://www.kaggle.com/code/underwearfitting/single-fold-training-of-resnet200d-lb0-965\n    \"\"\"\n    def __init__(self, optimizer, multiplier, total_epoch, after_scheduler=None):\n        super(GradualWarmupSchedulerV2, self).__init__(\n            optimizer, multiplier, total_epoch, after_scheduler)\n\n    def get_lr(self):\n        if self.last_epoch > self.total_epoch:\n            if self.after_scheduler:\n                if not self.finished:\n                    self.after_scheduler.base_lrs = [\n                        base_lr * self.multiplier for base_lr in self.base_lrs]\n                    self.finished = True\n                return self.after_scheduler.get_lr()\n            return [base_lr * self.multiplier for base_lr in self.base_lrs]\n        if self.multiplier == 1.0:\n            return [base_lr * (float(self.last_epoch) / self.total_epoch) for base_lr in self.base_lrs]\n        else:\n            return [base_lr * ((self.multiplier - 1.) * self.last_epoch / self.total_epoch + 1.) for base_lr in self.base_lrs]\n\ndef get_scheduler(cfg, optimizer):\n    scheduler_cosine = torch.optim.lr_scheduler.CosineAnnealingLR(\n        optimizer, cfg.epochs, eta_min=1e-7)\n    scheduler = GradualWarmupSchedulerV2(\n        optimizer, multiplier=10, total_epoch=1, after_scheduler=scheduler_cosine)\n\n    return scheduler\n\ndef scheduler_step(scheduler, avg_val_loss, epoch):\n    scheduler.step(epoch)","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:01:22.806692Z","iopub.execute_input":"2023-07-17T07:01:22.806973Z","iopub.status.idle":"2023-07-17T07:01:22.818827Z","shell.execute_reply.started":"2023-07-17T07:01:22.806950Z","shell.execute_reply":"2023-07-17T07:01:22.817944Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = build_model(CFG)\nmodel=model.to(device)\noptimizer = AdamW(model.parameters(), lr=CFG.lr)\nscheduler = get_scheduler(CFG, optimizer)","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:01:22.820039Z","iopub.execute_input":"2023-07-17T07:01:22.820945Z","iopub.status.idle":"2023-07-17T07:01:27.659921Z","shell.execute_reply.started":"2023-07-17T07:01:22.820913Z","shell.execute_reply":"2023-07-17T07:01:27.658973Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Losses","metadata":{}},{"cell_type":"code","source":"DiceLoss = smp.losses.DiceLoss(mode='binary')\nBCELoss = smp.losses.SoftBCEWithLogitsLoss()\n\nalpha = 0.5\nbeta = 1 - alpha\nTverskyLoss = smp.losses.TverskyLoss(\n    mode='binary', log_loss=False, alpha=alpha, beta=beta)\n\ndef criterion(y_pred, y_true):\n    # return 0.5 * BCELoss(y_pred, y_true) + 0.5 * DiceLoss(y_pred, y_true)\n#     return BCELoss(y_pred, y_true)\n    return 0.5 * BCELoss(y_pred, y_true) + 0.5 * TverskyLoss(y_pred, y_true)","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:01:27.661543Z","iopub.execute_input":"2023-07-17T07:01:27.661893Z","iopub.status.idle":"2023-07-17T07:01:27.668978Z","shell.execute_reply.started":"2023-07-17T07:01:27.661858Z","shell.execute_reply":"2023-07-17T07:01:27.668136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_fn(train_loader, model, criterion, optimizer, device):\n    model.train()\n\n    scaler = GradScaler(enabled=CFG.use_amp)\n    \n    losses = AverageMeter()\n\n    for step, (images, labels) in tqdm(enumerate(train_loader), total=len(train_loader)):\n        images = images.to(device)\n        labels = labels.to(device)\n        batch_size = labels.size(0)\n        labels = torch.unsqueeze(labels, dim=1)\n#         print(images.shape,labels.shape)\n\n        with autocast(CFG.use_amp):\n            y_preds = model(images)\n#             y_preds = torch.squeeze(y_preds, dim=1)\n#             print(y_preds.shape)\n            loss = criterion(y_preds, labels)\n\n        losses.update(loss.item(), batch_size)\n        scaler.scale(loss).backward()\n\n        grad_norm = torch.nn.utils.clip_grad_norm_(\n            model.parameters(), CFG.max_grad_norm)\n\n        scaler.step(optimizer)\n        scaler.update()\n        optimizer.zero_grad()\n        images.detach()\n        labels.detach()\n\n    return losses.avg","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:01:27.670846Z","iopub.execute_input":"2023-07-17T07:01:27.671628Z","iopub.status.idle":"2023-07-17T07:01:27.682900Z","shell.execute_reply.started":"2023-07-17T07:01:27.671595Z","shell.execute_reply":"2023-07-17T07:01:27.682032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def valid_fn(valid_loader, model, criterion, device):\n\n    model.eval()\n    losses = AverageMeter()\n\n    for step, (images, labels) in tqdm(enumerate(valid_loader), total=len(valid_loader)):\n        images = images.to(device)\n        labels = labels.to(device)\n        labels = torch.unsqueeze(labels, dim=1)\n        batch_size = labels.size(0)\n\n        with torch.no_grad():\n            y_preds = model(images)\n#             y_preds = torch.squeeze(y_preds, dim=1)\n            loss = criterion(y_preds, labels)\n        losses.update(loss.item(), batch_size)\n        \n        y_preds = torch.sigmoid(y_preds).to('cpu').numpy()\n        images.detach()\n        labels=labels.to('cpu').numpy()\n\n        \n    return losses.avg, y_preds ,labels","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:01:27.684509Z","iopub.execute_input":"2023-07-17T07:01:27.684839Z","iopub.status.idle":"2023-07-17T07:01:27.693737Z","shell.execute_reply.started":"2023-07-17T07:01:27.684809Z","shell.execute_reply":"2023-07-17T07:01:27.692745Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Metric for this compitition","metadata":{}},{"cell_type":"markdown","source":"****Average precission****","metadata":{}},{"cell_type":"code","source":"import torch\nfrom sklearn.metrics import average_precision_score\n\ndef calculate_average_precision(predicted_masks, true_masks):\n    \"\"\"\n    Calculates the average precision for a segmentation task.\n\n    Args:\n        predicted_masks (numpy.ndarray): Predicted masks with shape (N, H, W).\n        true_masks (torch.Tensor): True masks with shape (N, H, W) or (H, W).\n\n    Returns:\n        float: Average precision score.\n    \"\"\"\n#     if true_masks.dim() == 2:\n#         true_masks = true_masks.unsqueeze(0)  # Add a dimension for the number of samples\n\n    predicted_masks_2d = predicted_masks.reshape(predicted_masks.shape[0], -1)\n    true_masks_2d = true_masks.reshape(true_masks.shape[0], -1)\n\n    ap = average_precision_score(true_masks_2d, predicted_masks_2d, average='macro')\n    return ap\n\ndef calc_ap(true_masks, predicted_masks):\n    true_masks = true_masks.astype(int).flatten()\n    predicted_masks = predicted_masks.flatten()\n\n    best_th = 0\n    best_ap = 0\n    for th in np.array(range(10, 50+1, 5)) / 100:\n        \n        ap = calculate_average_precision(true_masks, (predicted_masks >= th).astype(int))\n        print(f'th: {th}, AvgP: {ap}')\n\n        if ap > best_ap:\n            best_ap = ap\n            best_th = th\n    \n    Logger.info(f'best_th: {best_th}, AvgP: {best_ap}')\n    return best_ap, best_th\n\n\ndef calc_cv(mask_gt, mask_pred):\n    best_ap, best_th = calc_ap(mask_gt, mask_pred)\n\n    return best_ap, best_th","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:01:27.695384Z","iopub.execute_input":"2023-07-17T07:01:27.695760Z","iopub.status.idle":"2023-07-17T07:01:27.707606Z","shell.execute_reply.started":"2023-07-17T07:01:27.695727Z","shell.execute_reply":"2023-07-17T07:01:27.706601Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training","metadata":{}},{"cell_type":"code","source":"if CFG.metric_direction == 'minimize':\n    best_score = np.inf\nelif CFG.metric_direction == 'maximize':\n    best_score = -1\n\nbest_loss = np.inf\n\nfor epoch in range(CFG.epochs):\n\n    start_time = time.time()\n\n    # train\n    avg_loss = train_fn(train_loader, model, criterion, optimizer, device)\n\n    # eval\n    avg_val_loss, mask_pred, valid_mask_gt  = valid_fn(\n        valid_loader, model, criterion, device)\n\n    scheduler_step(scheduler, avg_val_loss, epoch)\n\n    best_ap, best_th = calc_cv(valid_mask_gt, mask_pred)\n\n    # score = avg_val_loss\n    score = best_ap\n\n    elapsed = time.time() - start_time\n\n    Logger.info(\n        f'Epoch {epoch+1} - avg_train_loss: {avg_loss:.4f}  avg_val_loss: {avg_val_loss:.4f}  time: {elapsed:.0f}s')\n    # Logger.info(f'Epoch {epoch+1} - avgScore: {avg_score:.4f}')\n    Logger.info(\n        f'Epoch {epoch+1} - avgScore: {score:.4f}')\n\n    if CFG.metric_direction == 'minimize':\n        update_best = score < best_score\n    elif CFG.metric_direction == 'maximize':\n        update_best = score > best_score\n\n    if update_best:\n        best_loss = avg_val_loss\n        best_score = score\n\n        Logger.info(\n            f'Epoch {epoch+1} - Save Best Score: {best_score:.4f} Model')\n        Logger.info(\n            f'Epoch {epoch+1} - Save Best Loss: {best_loss:.4f} Model')\n        \n        torch.save({'model': model.state_dict(),\n                    'preds': mask_pred},\n                    CFG.model_dir + f'{CFG.backbone}_best.pth')","metadata":{"execution":{"iopub.status.busy":"2023-07-17T07:01:27.708867Z","iopub.execute_input":"2023-07-17T07:01:27.709305Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}