{"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":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-05-17T14:49:18.364746Z","iopub.execute_input":"2023-05-17T14:49:18.365166Z","iopub.status.idle":"2023-05-17T14:49:23.46621Z","shell.execute_reply.started":"2023-05-17T14:49:18.365132Z","shell.execute_reply":"2023-05-17T14:49:23.465091Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls /kaggle/input/gradienterbalance","metadata":{"execution":{"iopub.status.busy":"2023-05-17T14:48:55.966145Z","iopub.execute_input":"2023-05-17T14:48:55.966556Z","iopub.status.idle":"2023-05-17T14:48:57.101006Z","shell.execute_reply.started":"2023-05-17T14:48:55.96652Z","shell.execute_reply":"2023-05-17T14:48:57.099773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1. bubble detection","metadata":{}},{"cell_type":"markdown","source":"# 1.1 check data","metadata":{}},{"cell_type":"code","source":"!ls /kaggle/input/gradienterbalance/bubble\n","metadata":{"execution":{"iopub.status.busy":"2023-05-17T05:25:20.294588Z","iopub.execute_input":"2023-05-17T05:25:20.295427Z","iopub.status.idle":"2023-05-17T05:25:21.420909Z","shell.execute_reply.started":"2023-05-17T05:25:20.295388Z","shell.execute_reply":"2023-05-17T05:25:21.41965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1.2 model weight train","metadata":{}},{"cell_type":"markdown","source":"# 1.2.1 install and import toolbox","metadata":{}},{"cell_type":"code","source":"# !pip list","metadata":{"execution":{"iopub.status.busy":"2023-05-17T05:25:23.608011Z","iopub.execute_input":"2023-05-17T05:25:23.609243Z","iopub.status.idle":"2023-05-17T05:25:23.617022Z","shell.execute_reply.started":"2023-05-17T05:25:23.609197Z","shell.execute_reply":"2023-05-17T05:25:23.615961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install albumentations==0.4.6\n!pip install segmentation_models_pytorch\n!pip install scipy scikit-image==0.19.3","metadata":{"execution":{"iopub.status.busy":"2023-05-17T05:25:24.352057Z","iopub.execute_input":"2023-05-17T05:25:24.352915Z","iopub.status.idle":"2023-05-17T05:25:59.03082Z","shell.execute_reply.started":"2023-05-17T05:25:24.352867Z","shell.execute_reply":"2023-05-17T05:25:59.029526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport cv2\nimport time\nimport sys\nimport numpy as np\nfrom torch.optim.lr_scheduler import ReduceLROnPlateau\nimport torch\nimport torch.nn as nn\nfrom torch.nn import functional as F\nimport torch.optim as optim\nimport torch.backends.cudnn as cudnn\nfrom torch.utils.data import DataLoader, Dataset\nfrom matplotlib import pyplot as plt\nfrom albumentations import (Resize, RandomCrop,VerticalFlip, HorizontalFlip, Normalize, Compose)\nfrom albumentations.pytorch import ToTensorV2\nimport torch.nn.functional as F\nfrom torch.autograd import Variable\nfrom sklearn.model_selection import train_test_split\nfrom PIL import Image\nfrom glob import glob\nimport segmentation_models_pytorch as smp","metadata":{"execution":{"iopub.status.busy":"2023-05-17T05:26:20.709555Z","iopub.execute_input":"2023-05-17T05:26:20.71068Z","iopub.status.idle":"2023-05-17T05:26:20.71952Z","shell.execute_reply.started":"2023-05-17T05:26:20.710635Z","shell.execute_reply":"2023-05-17T05:26:20.718512Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1.2.2 load image toolbox","metadata":{}},{"cell_type":"code","source":"def provider(\n    image_path,\n    phase,\n    mean=None,\n    std=None,\n    batch_size=8,\n    num_workers=0,\n):\n\n    image_list = glob(os.path.join(image_path, \"*\"))\n    train_idx, val_idx = train_test_split(\n        range(len(image_list)), random_state=4396, test_size=0.1\n    )\n    \n    index = train_idx if phase == \"train\" else val_idx\n    dataset = BubbleDataset(index, image_list, phase=phase)\n\n    dataloader = DataLoader(\n        dataset,\n        batch_size=batch_size,\n        num_workers=num_workers,\n        pin_memory=True,\n        shuffle=True,   \n    )\n    return dataloader","metadata":{"execution":{"iopub.status.busy":"2023-05-17T05:39:18.441386Z","iopub.execute_input":"2023-05-17T05:39:18.44183Z","iopub.status.idle":"2023-05-17T05:39:18.45175Z","shell.execute_reply.started":"2023-05-17T05:39:18.441788Z","shell.execute_reply":"2023-05-17T05:39:18.450599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1.2.3 transform and extend image dataset","metadata":{}},{"cell_type":"code","source":"def get_transforms(phase, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)):\n    list_transforms = []\n    if phase == \"train\":\n        list_transforms.extend(\n            [\n                HorizontalFlip(),\n                VerticalFlip()\n            ]\n        )\n    list_transforms.extend(\n        [\n            Resize(256, 256, interpolation=Image.BILINEAR),\n            Normalize(mean=mean, std=std, p=1),\n            ToTensorV2(),\n        ]\n    )\n    list_trfms = Compose(list_transforms)\n    return list_trfms\n\nclass BubbleDataset(Dataset):\n    def __init__(self, idx, image_list, phase=\"train\"):\n        assert phase in (\"train\", \"val\", \"test\")\n        self.idx = idx\n        self.image_list = image_list\n        self.phase = phase\n\n        self.transform = get_transforms(phase)\n\n    def __getitem__(self, index):\n        real_idx = self.idx[index]\n        image_path = os.path.join(self.image_list[real_idx], \"img.png\")\n        mask_path = os.path.join(self.image_list[real_idx], \"label.png\")\n\n        image = cv2.imread(image_path)\n        mask = cv2.imread(mask_path)\n\n\n        augmented = self.transform(image=image, mask=mask/128)\n\n        return augmented[\"image\"], augmented[\"mask\"][:, :, 2], image_path\n\n    def __len__(self):\n        return len(self.idx)","metadata":{"execution":{"iopub.status.busy":"2023-05-17T05:39:23.652563Z","iopub.execute_input":"2023-05-17T05:39:23.652947Z","iopub.status.idle":"2023-05-17T05:39:23.665153Z","shell.execute_reply.started":"2023-05-17T05:39:23.652918Z","shell.execute_reply":"2023-05-17T05:39:23.664164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1.2.4 evaluation function","metadata":{}},{"cell_type":"code","source":"def predict(X, threshold):\n    '''X is sigmoid output of the model'''\n    X_p = np.copy(X)\n    preds = (X_p > threshold).astype('uint8')\n    return preds\n\ndef metric(probability, truth, threshold=0.5, reduction='none'):\n    '''Calculates dice of positive and negative images seperately'''\n    '''probability and truth must be torch tensors'''\n    batch_size = len(truth)\n    with torch.no_grad():\n        probability = probability.contiguous().view(batch_size, -1)\n        truth = truth.contiguous().view(batch_size, -1)\n        assert(probability.shape == truth.shape)\n\n        p = (probability > threshold).float()\n        t = (truth > 0.5).float()\n\n        t_sum = t.sum(-1)\n        p_sum = p.sum(-1)\n        neg_index = torch.nonzero(t_sum == 0)\n        pos_index = torch.nonzero(t_sum >= 1)\n\n        dice_neg = (p_sum == 0).float()\n        dice_pos = 2 * (p*t).sum(-1)/((p+t).sum(-1))\n\n        dice_neg = dice_neg[neg_index]\n        dice_pos = dice_pos[pos_index]\n        dice = torch.cat([dice_pos, dice_neg])\n\n        dice_neg = np.nan_to_num(dice_neg.mean().item(), 0)\n        dice_pos = np.nan_to_num(dice_pos.mean().item(), 0)\n        dice = dice.mean().item()\n\n        num_neg = len(neg_index)\n        num_pos = len(pos_index)\n\n    return dice, dice_neg, dice_pos, num_neg, num_pos\n\nclass Meter:\n    '''A meter to keep track of iou and dice scores throughout an epoch'''\n    def __init__(self, phase, epoch):\n        self.base_threshold = 0.5 # <<<<<<<<<<< here's the threshold\n        self.base_dice_scores = []\n        self.dice_neg_scores = []\n        self.dice_pos_scores = []\n        self.iou_scores = []\n\n    def update(self, targets, outputs):\n        probs = torch.sigmoid(outputs)\n        dice, dice_neg, dice_pos, _, _ = metric(probs, targets, self.base_threshold)\n        self.base_dice_scores.append(dice)\n        self.dice_pos_scores.append(dice_pos)\n        self.dice_neg_scores.append(dice_neg)\n        preds = predict(probs, self.base_threshold)\n        iou = compute_iou_batch(preds, targets, classes=[1])\n        self.iou_scores.append(iou)\n\n    def get_metrics(self):\n        dice = np.mean(self.base_dice_scores)\n        dice_neg = np.mean(self.dice_neg_scores)\n        dice_pos = np.mean(self.dice_pos_scores)\n        dices = [dice, dice_neg, dice_pos]\n        iou = np.nanmean(self.iou_scores)\n        return dices, iou\n\ndef epoch_log(phase, epoch, epoch_loss, meter, start):\n    '''logging the metrics at the end of an epoch'''\n    dices, iou = meter.get_metrics()\n    dice, dice_neg, dice_pos = dices\n    print(\"Loss: %0.6f | IoU: %0.4f | dice: %0.4f | dice_neg: %0.4f | dice_pos: %0.4f\" % (epoch_loss, iou, dice, dice_neg, dice_pos))\n    return dice, iou\n\ndef compute_ious(pred, label, classes, ignore_index=255, only_present=True):\n    '''computes iou for one ground truth mask and predicted mask'''\n    pred[label == ignore_index] = 0\n    ious = []\n    for c in classes:\n        label_c = label == c\n        if only_present and np.sum(label_c) == 0:\n            ious.append(np.nan)\n            continue\n        pred_c = pred == c\n        intersection = np.logical_and(pred_c, label_c).sum()\n        union = np.logical_or(pred_c, label_c).sum()\n        if union != 0:\n            ious.append(intersection / union)\n    return ious if ious else [1]\n\ndef compute_iou_batch(outputs, labels, classes=None):\n    '''computes mean iou for a batch of ground truth masks and predicted masks'''\n    ious = []\n    preds = np.copy(outputs) # copy is imp\n    labels = np.array(labels) # tensor to np\n    \n    for pred, label in zip(preds, labels):\n        ious.append(np.nanmean(compute_ious(pred, label, classes)))\n    iou = np.nanmean(ious)\n    return iou","metadata":{"execution":{"iopub.status.busy":"2023-05-17T05:39:25.12006Z","iopub.execute_input":"2023-05-17T05:39:25.120438Z","iopub.status.idle":"2023-05-17T05:39:25.14319Z","shell.execute_reply.started":"2023-05-17T05:39:25.120406Z","shell.execute_reply":"2023-05-17T05:39:25.142187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1.2.5 trainning model definition","metadata":{}},{"cell_type":"code","source":"class Trainer(object):\n    '''This class takes care of training and validation of our model'''\n    def __init__(self, model):\n        self.num_workers = 2\n        self.batch_size = {\"train\": 32, \"val\":4}\n        self.accumulation_steps = 32 // self.batch_size['train']\n        self.lr = 1e-3\n        self.num_epochs = 100\n        self.best_loss = float(\"inf\")\n        self.best_dice = float(0)\n        self.phases = [\"train\", \"val\"]\n        self.device = torch.device(\"cuda\")\n        #torch.set_default_tensor_type(\"torch.cuda.FloatTensor\")\n        self.net = model\n        self.criterion = nn.BCEWithLogitsLoss()\n        self.optimizer = optim.Adam(self.net.parameters(), lr=self.lr)\n        self.scheduler = ReduceLROnPlateau(self.optimizer, mode=\"min\", patience=4, verbose=True)\n        self.net = self.net.to(self.device)\n        cudnn.benchmark = True\n        self.dataloaders = {\n            phase: provider(\n                image_path=image_path,\n                phase=phase,\n                mean=(0.485, 0.456, 0.406),\n                std=(0.229, 0.224, 0.225),\n                batch_size=self.batch_size[phase],\n                num_workers=self.num_workers,\n            )\n            for phase in self.phases\n        }\n        self.losses = {phase: [] for phase in self.phases}\n        self.iou_scores = {phase: [] for phase in self.phases}\n        self.dice_scores = {phase: [] for phase in self.phases}\n        \n    def forward(self, images, targets):\n        images = images.to(self.device)\n        masks = targets.to(self.device).unsqueeze(dim=1)\n        outputs = self.net(images)\n        loss = self.criterion(outputs, masks)\n        \n        return loss, outputs\n\n    def iterate(self, epoch, phase):\n        if not epoch % 20:\n            sys.stdout.flush()\n        meter = Meter(phase, epoch)\n        start = time.strftime(\"%H:%M:%S\")\n        print(f\"Starting epoch: {epoch} | phase: {phase} | ⏰: {start}\")\n        batch_size = self.batch_size[phase]\n        self.net.train(phase == \"train\")\n        dataloader = self.dataloaders[phase]\n        running_loss = 0.0\n        total_batches = len(dataloader)\n        self.optimizer.zero_grad()\n        for itr, batch in enumerate(dataloader): \n            images, targets, image_path = batch\n\n            loss, outputs = self.forward(images, targets)\n            loss = loss / self.accumulation_steps\n\n            if phase == \"train\":\n                loss.backward()\n                if (itr + 1 ) % self.accumulation_steps == 0:\n                    self.optimizer.step()\n                    self.optimizer.zero_grad()\n                    \n            else:\n\n                batch_preds = torch.sigmoid(outputs.squeeze(1))\n\n                batch_preds = batch_preds.detach().cpu().numpy()\n                im = cv2.imread(image_path[0])\n                im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)\n                im = cv2.resize(im, (256, 256)).transpose((2, 0, 1))\n                            \n                \n            running_loss += loss.item()\n            outputs = outputs.detach().squeeze(dim=1).cpu()\n            meter.update(targets, outputs)\n             \n        # vis.close()  \n        epoch_loss = (running_loss * self.accumulation_steps) / total_batches\n        dice, iou = epoch_log(phase, epoch, epoch_loss, meter, start)\n        self.losses[phase].append(epoch_loss)\n        self.dice_scores[phase].append(dice)\n        self.iou_scores[phase].append(iou)\n        torch.cuda.empty_cache()\n        \n        return epoch_loss, dice\n\n    def start(self, modelpath, encoder_name):\n        for epoch in range(self.num_epochs):\n            self.iterate(epoch, \"train\")\n            state = {\n                \"epoch\": epoch,\n                \"best_loss\": self.best_loss,\n                \"state_dict\": self.net.state_dict(),\n                \"optimizer\": self.optimizer.state_dict(),\n            }\n            val_loss, dice = self.iterate(epoch, \"val\")\n\n            self.scheduler.step(val_loss)\n            \n            if val_loss < self.best_loss:\n                print(\"******** New optimal found, saving state ********\")\n                state[\"best_loss\"] = self.best_loss = val_loss\n                self.best_dice = dice\n                torch.save(state, os.path.join(modelpath, encoder_name+\".pth\"))\n            print()","metadata":{"execution":{"iopub.status.busy":"2023-05-17T05:39:26.636364Z","iopub.execute_input":"2023-05-17T05:39:26.636839Z","iopub.status.idle":"2023-05-17T05:39:26.660305Z","shell.execute_reply.started":"2023-05-17T05:39:26.636806Z","shell.execute_reply":"2023-05-17T05:39:26.659054Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1.2.6 weight trainning procedure","metadata":{}},{"cell_type":"code","source":"!rm -rf /kaggle/working/bubble_model_zoo","metadata":{"execution":{"iopub.status.busy":"2023-05-17T06:36:53.118024Z","iopub.execute_input":"2023-05-17T06:36:53.118394Z","iopub.status.idle":"2023-05-17T06:36:54.286574Z","shell.execute_reply.started":"2023-05-17T06:36:53.118358Z","shell.execute_reply":"2023-05-17T06:36:54.285162Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_path = \"/kaggle/input/914bubble/bubblelabel/\"\n#image_path = \"/kaggle/input/gradienterbalance/bubble/\"\nos.system(\"mkdir \"+'/kaggle/working/bubble_model_zoo/')\nencoders = ['vgg16'] #'vgg11','vgg11_bn','vgg13','vgg13_bn',,'vgg16_bn','vgg19','vgg19_bn'\nfor encoder in encoders:\n    print(encoder)\n    modelunet = smp.Unet(encoder_name=encoder, encoder_weights='imagenet', classes=1, activation=None)\n    model_trainer = Trainer(modelunet)\n    model_trainer.start('/kaggle/working/bubble_model_zoo/',encoder)\n    del modelunet\n    torch.cuda.empty_cache()","metadata":{"execution":{"iopub.status.busy":"2023-05-17T06:37:02.955413Z","iopub.execute_input":"2023-05-17T06:37:02.956193Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls /kaggle/working/model_zoo","metadata":{"execution":{"iopub.status.busy":"2023-05-17T12:47:28.384585Z","iopub.execute_input":"2023-05-17T12:47:28.386248Z","iopub.status.idle":"2023-05-17T12:47:29.369312Z","shell.execute_reply.started":"2023-05-17T12:47:28.386205Z","shell.execute_reply":"2023-05-17T12:47:29.36798Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1.3 image test","metadata":{}},{"cell_type":"markdown","source":"# 1.3.1 import toolboxs","metadata":{}},{"cell_type":"code","source":"import os\nimport time\nimport numpy as np\nfrom torch.optim.lr_scheduler import ReduceLROnPlateau,CosineAnnealingLR\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.backends.cudnn as cudnn\nfrom torch.utils.data import DataLoader, Dataset\nfrom matplotlib import pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfrom PIL import Image\nfrom glob import glob\nimport sys\nfrom torch.utils.data import DataLoader, Dataset\nfrom albumentations import (Resize, RandomCrop,VerticalFlip, HorizontalFlip, Normalize, Compose, Crop, PadIfNeeded, RandomBrightness, Rotate)\nfrom albumentations.pytorch import ToTensorV2\nimport cv2\nfrom torch.nn import functional as F\nfrom tqdm import tqdm\nimport segmentation_models_pytorch as smp","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1.3.2 image load toolbox","metadata":{}},{"cell_type":"code","source":"###########################################################################\ndef provider(\n    image_path,\n    phase,\n    mean=None,\n    std=None,\n    batch_size=8,\n    num_workers=0,\n):\n    assert phase in (\"train\", \"val\", \"test\")\n\n    image_list = glob(os.path.join(image_path, \"*\"))\n    print(\"total images: {}\".format(len(image_list)))\n\n    index = range(len(image_list))\n\n    dataset = BubbleDataset(index, image_list, phase=phase)\n\n    dataloader = DataLoader(\n        dataset,\n        batch_size=batch_size,\n        num_workers=num_workers,\n        pin_memory=False,\n        shuffle=False,\n    )\n    return dataloader","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1.3.3 transform and enhance image data","metadata":{}},{"cell_type":"code","source":"###############################################################################\ndef get_transforms(phase, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)):\n    list_transforms = []\n    list_transforms.extend(\n        [\n            Resize(128, 256, interpolation=Image.BILINEAR),\n            Normalize(mean=mean, std=std, p=1),\n            ToTensorV2(),\n        ]\n    )\n    list_trfms = Compose(list_transforms)\n    return list_trfms\n\n###############################################################################\nclass BubbleDataset(Dataset):\n    def __init__(self, idx, image_list, phase=\"train\"):\n        assert phase in ( \"test\")\n        self.idx = idx\n        self.image_list = image_list\n        self.phase = phase\n\n        self.transform = get_transforms(phase)\n\n    def __getitem__(self, index):\n        real_idx = self.idx[index]\n        image_path = self.image_list[real_idx]\n\n        image = cv2.imread(image_path)\n        image = image[120:120+1920, :, :]\n        augmented = self.transform(image=image)\n\n        return augmented[\"image\"], image_path\n\n    def __len__(self):\n        return len(self.idx)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1.3.4 test model definition","metadata":{}},{"cell_type":"code","source":"class Tester(object):\n    '''This class takes care of training and validation of our model'''\n    def __init__(self, model):\n        self.num_workers = 2\n        self.batch_size = {\"test\":128}\n        self.phases = [\"test\"]\n        self.device = torch.device(\"cuda\")\n        self.net = model\n\n        self.net = self.net.to(self.device)\n        cudnn.benchmark = True\n        self.dataloaders = {\n            phase: provider(\n                image_path=image_path,\n                phase=phase,\n                mean=(0.485, 0.456, 0.406),\n                std=(0.229, 0.224, 0.225),\n                batch_size=self.batch_size[phase],\n                num_workers=self.num_workers,\n            )\n            for phase in self.phases\n        }\n        self.losses = {phase: [] for phase in self.phases}\n\n    def forward(self, images):\n        images = images.to(self.device)\n        outputs = self.net(images)\n\n        return  outputs\n\n\n    def iterate(self, phase, outputpath):\n        start = time.strftime(\"%H:%M:%S\")\n        print(f\"Starting epoch: 0 | phase: {phase} | ⏰: {start}\")\n        self.net.train(phase == \"train\")\n        dataloader = self.dataloaders[phase]\n        for batch in tqdm(dataloader):\n            images, pathes = batch\n\n            with torch.no_grad():\n                outputs = self.forward(images)            \n            batch_preds = torch.sigmoid(outputs)  \n            for ii in range(batch_preds.shape[0]):\n                numpy_output = batch_preds[ii].squeeze(0).detach().cpu().numpy()\n                segimg = cv2.resize(np.where(numpy_output > 0.5, 255, 0).astype(\"uint8\"), (3840, 2160))                \n                segname = os.path.basename(pathes[ii])[:-4]\n                cv2.imwrite(outputpath+\"/\"+segname+\".png\", segimg)\n\n    def start(self, outputpath):\n        self.iterate(\"test\", outputpath)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1.3.5 test image by different trained models","metadata":{}},{"cell_type":"code","source":"from tqdm import tqdm\nimage_path = \"/kaggle/input/p24testimage/\"\nmodel_path = \"/kaggle/working/bubble_model_zoo/\"\nsmpsegpath = \"/kaggle/working/bubbleseg/\"\n\nos.system(\"mkdir \"+smpsegpath)\nencoders = ['vgg16']\nfor encoder in encoders:\n    modeltest = smp.Unet(encoder_name=encoder, encoder_weights='imagenet', classes=1, activation=None)\n    state = torch.load(model_path+encoder+'.pth', map_location=lambda storage, loc: storage)\n    modeltest.load_state_dict(state[\"state_dict\"])\n    os.system(f\"mkdir {os.path.join(smpsegpath, encoder)}\")\n    model_test = Tester(modeltest)\n    model_test.start(os.path.join(smpsegpath, encoder))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1.4 show segmentation result","metadata":{}},{"cell_type":"code","source":"srcimgpath = \"/kaggle/input/p24testimage/\"\nsegimgpath = \"/kaggle/working/bubbleseg/\"\nimfiles = os.listdir(srcimgpath)\nimfiles.sort()\nfor encoder in encoders:\n    segimgpath = os.path.join(smpsegpath, encoder)    \n    for idx, imfile in enumerate(imfiles):\n        if not (idx % 50):\n            srcimg = cv2.imread(srcimgpath+imfile)\n            print(segimgpath+encoder+\"/\"+imfile)\n            segimg = cv2.imread(segimgpath+\"/\"+imfile)\n            plt.figure(figsize=(40, 40))\n            plt.subplot(1, 3, 1), plt.imshow(srcimg[:, :, ::-1])\n            plt.subplot(1, 3, 2), plt.imshow(segimg)\n            plt.subplot(1, 3, 3), plt.imshow(srcimg[:, :, ::-1]+128*segimg[:, :, ::-1])\n            plt.show()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2 gradienter detection","metadata":{}},{"cell_type":"markdown","source":"# 2.1 check data","metadata":{}},{"cell_type":"code","source":"!ls /kaggle/input/gradienterbalance/gradienter","metadata":{"execution":{"iopub.status.busy":"2023-05-17T02:07:28.442482Z","iopub.execute_input":"2023-05-17T02:07:28.442879Z","iopub.status.idle":"2023-05-17T02:07:29.412661Z","shell.execute_reply.started":"2023-05-17T02:07:28.442851Z","shell.execute_reply":"2023-05-17T02:07:29.411471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2.2 model weight trainning","metadata":{}},{"cell_type":"markdown","source":"# 2.2.1 install amd import toolboxs","metadata":{}},{"cell_type":"code","source":"!pip install albumentations==0.4.6\n!pip install segmentation_models_pytorch\n!pip install scipy scikit-image==0.19.3","metadata":{"execution":{"iopub.status.busy":"2023-05-17T02:16:29.951606Z","iopub.execute_input":"2023-05-17T02:16:29.952659Z","iopub.status.idle":"2023-05-17T02:17:05.27471Z","shell.execute_reply.started":"2023-05-17T02:16:29.952612Z","shell.execute_reply":"2023-05-17T02:17:05.273256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport time\nimport numpy as np\nfrom torch.optim.lr_scheduler import ReduceLROnPlateau,CosineAnnealingLR\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.backends.cudnn as cudnn\nfrom torch.utils.data import DataLoader, Dataset\nfrom matplotlib import pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfrom PIL import Image\nfrom glob import glob\nimport sys\nfrom torch.utils.data import DataLoader, Dataset\nfrom albumentations import (Resize, RandomCrop,VerticalFlip, HorizontalFlip, Normalize, Compose, Crop, PadIfNeeded, RandomBrightness, Rotate)\nfrom albumentations.pytorch import ToTensorV2\nimport cv2\nfrom torch.nn import functional as F\nfrom tqdm import tqdm\nimport segmentation_models_pytorch as smp","metadata":{"execution":{"iopub.status.busy":"2023-05-17T14:49:47.498624Z","iopub.execute_input":"2023-05-17T14:49:47.499051Z","iopub.status.idle":"2023-05-17T14:49:53.40637Z","shell.execute_reply.started":"2023-05-17T14:49:47.499021Z","shell.execute_reply":"2023-05-17T14:49:53.404901Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !pip list","metadata":{"execution":{"iopub.status.busy":"2023-05-17T14:49:44.561121Z","iopub.execute_input":"2023-05-17T14:49:44.562041Z","iopub.status.idle":"2023-05-17T14:49:44.56668Z","shell.execute_reply.started":"2023-05-17T14:49:44.562Z","shell.execute_reply":"2023-05-17T14:49:44.56566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2.2.2 load image toolbox","metadata":{}},{"cell_type":"code","source":"def provider(\n    image_path,\n    phase,\n    mean=None,\n    std=None,\n    batch_size=8,\n    num_workers=0,\n):\n\n    image_list = glob(os.path.join(image_path, \"*\"))\n    train_idx, val_idx = train_test_split(\n        range(len(image_list)), random_state=4396, test_size=0.1\n    )\n\n    index = train_idx if phase == \"train\" else val_idx\n    dataset = GradienterDataset(index, image_list, phase=phase)\n\n    dataloader = DataLoader(\n        dataset,\n        batch_size=batch_size,\n        num_workers=num_workers,\n        pin_memory=False,\n        shuffle=True,\n    )\n\n    return dataloader","metadata":{"execution":{"iopub.status.busy":"2023-05-17T03:24:18.392867Z","iopub.execute_input":"2023-05-17T03:24:18.393239Z","iopub.status.idle":"2023-05-17T03:24:18.399812Z","shell.execute_reply.started":"2023-05-17T03:24:18.39321Z","shell.execute_reply":"2023-05-17T03:24:18.398831Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2.2.3 transform and extend image dataset","metadata":{}},{"cell_type":"code","source":"def get_transforms(phase, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)):\n    list_transforms = []\n    if phase == \"train\":\n        list_transforms.extend(\n            [\n                HorizontalFlip(),\n                VerticalFlip()\n            ]\n        )\n    list_transforms.extend(\n        [\n            Resize(256, 256, interpolation=Image.BILINEAR),\n            Normalize(mean=mean, std=std, p=1),\n            ToTensorV2(),\n        ]\n    )\n    list_trfms = Compose(list_transforms)\n    return list_trfms\n\nclass GradienterDataset(Dataset):\n    def __init__(self, idx, image_list, phase=\"train\"):\n        assert phase in (\"train\", \"val\", \"test\")\n        self.idx = idx\n        self.image_list = image_list\n        self.phase = phase\n\n        self.transform = get_transforms(phase)\n\n    def __getitem__(self, index):\n        real_idx = self.idx[index]\n        image_path = os.path.join(self.image_list[real_idx], \"img.png\")\n        mask_path = os.path.join(self.image_list[real_idx], \"label.png\")\n\n        image = cv2.imread(image_path)\n        mask = cv2.imread(mask_path)\n\n        augmented = self.transform(image=image, mask=mask/128)\n\n        return augmented[\"image\"], augmented[\"mask\"][:, :, 2], image_path\n\n    def __len__(self):\n        return len(self.idx)","metadata":{"execution":{"iopub.status.busy":"2023-05-17T03:24:21.750657Z","iopub.execute_input":"2023-05-17T03:24:21.751042Z","iopub.status.idle":"2023-05-17T03:24:21.761289Z","shell.execute_reply.started":"2023-05-17T03:24:21.751007Z","shell.execute_reply":"2023-05-17T03:24:21.760383Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2.2.4 evaluation function","metadata":{}},{"cell_type":"code","source":"def predict(X, threshold):\n    '''X is sigmoid output of the model'''\n    X_p = np.copy(X)\n    preds = (X_p > threshold).astype('uint8')\n    return preds\n\ndef metric(probability, truth, threshold=0.5, reduction='none'):\n    '''Calculates dice of positive and negative images seperately'''\n    '''probability and truth must be torch tensors'''\n    batch_size = len(truth)\n    with torch.no_grad():\n        probability = probability.contiguous().view(batch_size, -1)\n        truth = truth.contiguous().view(batch_size, -1)\n        assert(probability.shape == truth.shape)\n\n        p = (probability > threshold).float()\n        t = (truth > 0.5).float()\n\n        t_sum = t.sum(-1)\n        p_sum = p.sum(-1)\n        neg_index = torch.nonzero(t_sum == 0)\n        pos_index = torch.nonzero(t_sum >= 1)\n\n        dice_neg = (p_sum == 0).float()\n        dice_pos = 2 * (p*t).sum(-1)/((p+t).sum(-1))\n\n        dice_neg = dice_neg[neg_index]\n        dice_pos = dice_pos[pos_index]\n        dice = torch.cat([dice_pos, dice_neg])\n\n        dice_neg = np.nan_to_num(dice_neg.mean().item(), 0)\n        dice_pos = np.nan_to_num(dice_pos.mean().item(), 0)\n        dice = dice.mean().item()\n\n        num_neg = len(neg_index)\n        num_pos = len(pos_index)\n\n    return dice, dice_neg, dice_pos, num_neg, num_pos\n\nclass Meter:\n    '''A meter to keep track of iou and dice scores throughout an epoch'''\n    def __init__(self, phase, epoch):\n        self.base_threshold = 0.5 # <<<<<<<<<<< here's the threshold\n        self.base_dice_scores = []\n        self.dice_neg_scores = []\n        self.dice_pos_scores = []\n        self.iou_scores = []\n\n    def update(self, targets, outputs):\n        probs = torch.sigmoid(outputs)\n        dice, dice_neg, dice_pos, _, _ = metric(probs, targets, self.base_threshold)\n        self.base_dice_scores.append(dice)\n        self.dice_pos_scores.append(dice_pos)\n        self.dice_neg_scores.append(dice_neg)\n        preds = predict(probs, self.base_threshold)\n        iou = compute_iou_batch(preds, targets, classes=[1])\n        self.iou_scores.append(iou)\n\n    def get_metrics(self):\n        dice = np.mean(self.base_dice_scores)\n        dice_neg = np.mean(self.dice_neg_scores)\n        dice_pos = np.mean(self.dice_pos_scores)\n        dices = [dice, dice_neg, dice_pos]\n        iou = np.nanmean(self.iou_scores)\n        return dices, iou\n\ndef epoch_log(phase, epoch, epoch_loss, meter, start):\n    '''logging the metrics at the end of an epoch'''\n    dices, iou = meter.get_metrics()\n    dice, dice_neg, dice_pos = dices\n    print(\"Loss: %0.6f | IoU: %0.4f | dice: %0.4f | dice_neg: %0.4f | dice_pos: %0.4f\" % (epoch_loss, iou, dice, dice_neg, dice_pos))\n    return dice, iou\n\ndef compute_ious(pred, label, classes, ignore_index=255, only_present=True):\n    '''computes iou for one ground truth mask and predicted mask'''\n    pred[label == ignore_index] = 0\n    ious = []\n    for c in classes:\n        label_c = label == c\n        if only_present and np.sum(label_c) == 0:\n            ious.append(np.nan)\n            continue\n        pred_c = pred == c\n        intersection = np.logical_and(pred_c, label_c).sum()\n        union = np.logical_or(pred_c, label_c).sum()\n        if union != 0:\n            ious.append(intersection / union)\n    return ious if ious else [1]\n\ndef compute_iou_batch(outputs, labels, classes=None):\n    '''computes mean iou for a batch of ground truth masks and predicted masks'''\n    ious = []\n    preds = np.copy(outputs) # copy is imp\n    labels = np.array(labels) # tensor to np\n\n    for pred, label in zip(preds, labels):\n        ious.append(np.nanmean(compute_ious(pred, label, classes)))\n    iou = np.nanmean(ious)\n    return iou","metadata":{"execution":{"iopub.status.busy":"2023-05-17T03:24:24.100477Z","iopub.execute_input":"2023-05-17T03:24:24.101409Z","iopub.status.idle":"2023-05-17T03:24:24.123159Z","shell.execute_reply.started":"2023-05-17T03:24:24.101366Z","shell.execute_reply":"2023-05-17T03:24:24.121619Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2.2.5 trainning model definition","metadata":{}},{"cell_type":"code","source":"class Trainer(object):\n    '''This class takes care of training and validation of our model'''\n    def __init__(self, model):\n        self.num_workers = 2\n        self.batch_size = {\"train\": 32, \"val\":8}\n        self.accumulation_steps = 32 // self.batch_size['train']\n        self.lr = 1e-3\n        self.num_epochs = 100\n        self.best_loss = float(\"inf\")\n        self.best_dice = float(0)\n        self.phases = [\"train\", \"val\"]\n        self.device = torch.device(\"cuda\")\n        self.net = model\n        self.criterion = nn.BCEWithLogitsLoss()\n        self.optimizer = optim.Adam(self.net.parameters(), lr=self.lr)\n        self.scheduler = ReduceLROnPlateau(self.optimizer, mode=\"min\", patience=4, verbose=True)\n        self.net = self.net.to(self.device)\n        cudnn.benchmark = True\n        self.dataloaders = {\n            phase: provider(\n                image_path=image_path,\n                phase=phase,\n                mean=(0.485, 0.456, 0.406),\n                std=(0.229, 0.224, 0.225),\n                batch_size=self.batch_size[phase],\n                num_workers=self.num_workers,\n            )\n            for phase in self.phases\n        }\n        self.losses = {phase: [] for phase in self.phases}\n        self.iou_scores = {phase: [] for phase in self.phases}\n        self.dice_scores = {phase: [] for phase in self.phases}\n\n    def forward(self, images, targets):\n        images = images.to(self.device)\n        masks = targets.to(self.device).unsqueeze(dim=1)\n        outputs = self.net(images)\n\n        loss = self.criterion(outputs, masks)\n        return loss, outputs\n\n    def iterate(self, epoch, phase):\n        if not epoch % 20:\n            sys.stdout.flush()\n        meter = Meter(phase, epoch)\n        start = time.strftime(\"%H:%M:%S\")\n        print(f\"Starting epoch: {epoch} | phase: {phase} | ⏰: {start}\")\n        batch_size = self.batch_size[phase]\n        self.net.train(phase == \"train\")\n        dataloader = self.dataloaders[phase]\n        running_loss = 0.0\n        total_batches = len(dataloader)\n        self.optimizer.zero_grad()\n        for itr, batch in enumerate(dataloader):\n            images, targets, image_path = batch\n\n            loss, outputs = self.forward(images, targets)\n            loss = loss / self.accumulation_steps\n\n            if phase == \"train\":\n                loss.backward()\n                if (itr + 1 ) % self.accumulation_steps == 0:\n                    self.optimizer.step()\n                    self.optimizer.zero_grad()\n            running_loss += loss.item()\n            outputs = outputs.detach().squeeze(dim=1).cpu()\n            meter.update(targets, outputs)\n\n        # vis.close()\n        epoch_loss = (running_loss * self.accumulation_steps) / total_batches\n        dice, iou = epoch_log(phase, epoch, epoch_loss, meter, start)\n        self.losses[phase].append(epoch_loss)\n        self.dice_scores[phase].append(dice)\n        self.iou_scores[phase].append(iou)\n        torch.cuda.empty_cache()\n\n        return epoch_loss, dice\n\n    def start(self, modelpath, encoder_name):\n        for epoch in range(self.num_epochs):\n            self.iterate(epoch, \"train\")\n            state = {\n                \"epoch\": epoch,\n                \"best_loss\": self.best_loss,\n                \"state_dict\": self.net.state_dict(),\n                \"optimizer\": self.optimizer.state_dict(),\n            }\n            val_loss, dice = self.iterate(epoch, \"val\")\n\n            self.scheduler.step(val_loss)\n\n            if val_loss < self.best_loss:\n                print(\"******** New optimal found, saving state ********\")\n                state[\"best_loss\"] = self.best_loss = val_loss\n                self.best_dice = dice\n                torch.save(state, os.path.join(modelpath, encoder_name+\".pth\"))\n\n            print()","metadata":{"execution":{"iopub.status.busy":"2023-05-17T03:24:27.136587Z","iopub.execute_input":"2023-05-17T03:24:27.136954Z","iopub.status.idle":"2023-05-17T03:24:27.158897Z","shell.execute_reply.started":"2023-05-17T03:24:27.136924Z","shell.execute_reply":"2023-05-17T03:24:27.157966Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2.2.6 weight trainning procedure","metadata":{}},{"cell_type":"code","source":"!ls ","metadata":{"execution":{"iopub.status.busy":"2023-05-17T03:24:28.674151Z","iopub.execute_input":"2023-05-17T03:24:28.674555Z","iopub.status.idle":"2023-05-17T03:24:29.668944Z","shell.execute_reply.started":"2023-05-17T03:24:28.674514Z","shell.execute_reply":"2023-05-17T03:24:29.667648Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_path = \"/kaggle/input/gradienterbalance/gradienter/\"\nos.system(\"mkdir /kaggle/working/gradienter_model_zoo/\")\nencoders = ['vgg16'] #,'vgg19', 'mobilenet_v2'\nfor encoder in encoders:\n    print(encoder)\n    modelunet = smp.Unet(encoder_name=encoder, encoder_weights='imagenet', classes=1, activation=None)\n    model_trainer = Trainer(modelunet)\n    model_trainer.start(\"/kaggle/working/gradienter_model_zoo\", encoder)\n    del modelunet\n    torch.cuda.empty_cache()","metadata":{"execution":{"iopub.status.busy":"2023-05-17T03:24:30.645707Z","iopub.execute_input":"2023-05-17T03:24:30.646954Z","iopub.status.idle":"2023-05-17T04:23:47.658861Z","shell.execute_reply.started":"2023-05-17T03:24:30.646903Z","shell.execute_reply":"2023-05-17T04:23:47.657556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2.3 image test","metadata":{}},{"cell_type":"markdown","source":"# 2.3.1 import toolboxs","metadata":{}},{"cell_type":"code","source":"import os\nimport time\nimport numpy as np\nfrom torch.optim.lr_scheduler import ReduceLROnPlateau,CosineAnnealingLR\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.backends.cudnn as cudnn\nfrom torch.utils.data import DataLoader, Dataset\nfrom matplotlib import pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfrom PIL import Image\nfrom glob import glob\nimport sys\nfrom torch.utils.data import DataLoader, Dataset\nfrom albumentations import (Resize, RandomCrop,VerticalFlip, HorizontalFlip, Normalize, Compose, Crop, PadIfNeeded, RandomBrightness, Rotate)\nfrom albumentations.pytorch import ToTensorV2\nimport cv2\nfrom torch.nn import functional as F\nfrom tqdm import tqdm\nimport segmentation_models_pytorch as smp","metadata":{"execution":{"iopub.status.busy":"2023-05-17T04:34:18.941638Z","iopub.execute_input":"2023-05-17T04:34:18.942055Z","iopub.status.idle":"2023-05-17T04:34:18.953092Z","shell.execute_reply.started":"2023-05-17T04:34:18.942023Z","shell.execute_reply":"2023-05-17T04:34:18.951676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2.3.2 image load toolbox","metadata":{}},{"cell_type":"code","source":"def provider(\n    image_path,\n    phase,\n    mean=None,\n    std=None,\n    batch_size=8,\n    num_workers=0,\n):\n    assert phase in (\"train\", \"val\", \"test\")\n\n    image_list = glob(os.path.join(image_path, \"*\"))\n    print(\"total images: {}\".format(len(image_list)))\n\n    index = range(len(image_list))\n\n    dataset = GradienterDataset(index, image_list, phase=phase)\n\n    dataloader = DataLoader(\n        dataset,\n        batch_size=batch_size,\n        num_workers=num_workers,\n        pin_memory=False,\n        shuffle=False,\n    )\n    return dataloader","metadata":{"execution":{"iopub.status.busy":"2023-05-17T04:34:20.256641Z","iopub.execute_input":"2023-05-17T04:34:20.257023Z","iopub.status.idle":"2023-05-17T04:34:20.263982Z","shell.execute_reply.started":"2023-05-17T04:34:20.256994Z","shell.execute_reply":"2023-05-17T04:34:20.263092Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2.3.3 transform and enhance image data","metadata":{}},{"cell_type":"code","source":"def get_transforms(phase, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)):\n    list_transforms = []\n    list_transforms.extend(\n        [\n            Resize(256, 256),\n            Normalize(mean=mean, std=std, p=1),\n            ToTensorV2(),\n        ]\n    )\n    list_trfms = Compose(list_transforms)\n    return list_trfms\n\nclass GradienterDataset(Dataset):\n    def __init__(self, idx, image_list, phase=\"train\"):\n        assert phase in ( \"test\")\n        self.idx = idx\n        self.image_list = image_list\n        self.phase = phase\n\n        self.transform = get_transforms(phase)\n\n    def __getitem__(self, index):\n        real_idx = self.idx[index]\n        image_path = self.image_list[real_idx]\n\n        image = cv2.imread(image_path)\n        augmented = self.transform(image=image)\n\n        return augmented[\"image\"], image_path\n\n    def __len__(self):\n        return len(self.idx)","metadata":{"execution":{"iopub.status.busy":"2023-05-17T04:34:21.64831Z","iopub.execute_input":"2023-05-17T04:34:21.649276Z","iopub.status.idle":"2023-05-17T04:34:21.660577Z","shell.execute_reply.started":"2023-05-17T04:34:21.649208Z","shell.execute_reply":"2023-05-17T04:34:21.659359Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2.3.4 test model definition","metadata":{}},{"cell_type":"code","source":"class Tester(object):\n    '''This class takes care of training and validation of our model'''\n    def __init__(self, model):\n        self.num_workers = 2\n        self.batch_size = {\"test\":32}\n        #self.accumulation_steps = 32 // self.batch_size['test']\n        self.phases = [\"test\"]\n        self.device = torch.device(\"cuda\")\n        self.net = model\n\n        self.net = self.net.to(self.device)\n        cudnn.benchmark = True\n        self.dataloaders = {\n            phase: provider(\n                image_path=image_path,\n                phase=phase,\n                mean=(0.485, 0.456, 0.406),\n                std=(0.229, 0.224, 0.225),\n                batch_size=self.batch_size[phase],\n                num_workers=self.num_workers,\n            )\n            for phase in self.phases\n        }\n        self.losses = {phase: [] for phase in self.phases}\n\n    def forward(self, images):\n        images = images.to(self.device)\n        outputs = self.net(images)\n\n        return  outputs\n\n\n    def iterate(self, phase, outputpath):\n        start = time.strftime(\"%H:%M:%S\")\n        print(f\"Starting epoch: 0 | phase: {phase} | ⏰: {start}\")\n        self.net.train(phase == \"train\")\n        dataloader = self.dataloaders[phase]\n        print(tqdm(dataloader))\n        for batch in tqdm(dataloader):\n            images, pathes = batch\n\n            with torch.no_grad():\n                outputs = self.forward(images)            \n            batch_preds = torch.sigmoid(outputs)  \n            for ii in range(batch_preds.shape[0]):\n                numpy_output = batch_preds[ii].squeeze(0).detach().cpu().numpy()\n                segimg = cv2.resize(np.where(numpy_output > 0.5, 255, 0).astype(\"uint8\"), (3840, 2160))                \n                segname = os.path.basename(pathes[ii])[:-4]\n                cv2.imwrite(outputpath+\"/\"+segname+\".png\", segimg)\n\n    def start(self, outputpath):\n        self.iterate(\"test\", outputpath)","metadata":{"execution":{"iopub.status.busy":"2023-05-17T05:18:13.0102Z","iopub.execute_input":"2023-05-17T05:18:13.010618Z","iopub.status.idle":"2023-05-17T05:18:13.024027Z","shell.execute_reply.started":"2023-05-17T05:18:13.010581Z","shell.execute_reply":"2023-05-17T05:18:13.023115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2.3.5 test image by different trained models","metadata":{}},{"cell_type":"code","source":"from tqdm import tqdm\nimage_path = \"/kaggle/input/p24testimage/\"\nmodel_path = \"/kaggle/working/gradienter_model_zoo/\"\nsmpsegpath = \"/kaggle/working/gradienterseg/\"\nos.system(\"mkdir \"+smpsegpath)\nencoders = ['vgg16']#,'vgg19','mobilenet_v2'\nfor encoder in encoders:\n    modeltest = smp.Unet(encoder_name=encoder, encoder_weights='imagenet', classes=1, activation=None)\n    state = torch.load(model_path+encoder+'.pth', map_location=lambda storage, loc: storage)\n    modeltest.load_state_dict(state[\"state_dict\"])\n    os.system(f\"mkdir {os.path.join(smpsegpath, encoder)}\")\n    model_test = Tester(modeltest)\n    model_test.start(os.path.join(smpsegpath, encoder))","metadata":{"execution":{"iopub.status.busy":"2023-05-17T05:18:17.889974Z","iopub.execute_input":"2023-05-17T05:18:17.890558Z","iopub.status.idle":"2023-05-17T05:19:03.817615Z","shell.execute_reply.started":"2023-05-17T05:18:17.890516Z","shell.execute_reply":"2023-05-17T05:19:03.815835Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"segimgpath = \"/kaggle/working/gradienterseg/\"\nimfiles = os.listdir(srcimgpath)\nimfiles.sort()\nfor encoder in encoders:\n    segimgpath = os.path.join(smpsegpath, encoder)    \n    for idx, imfile in enumerate(imfiles):\n        if not (idx % 50):\n            srcimg = cv2.imread(srcimgpath+imfile)\n            print(segimgpath+encoder+\"/\"+imfile)\n            segimg = cv2.imread(segimgpath+\"/\"+imfile)\n            plt.figure(figsize=(40, 40))\n            plt.subplot(1, 3, 1), plt.imshow(srcimg[:, :, ::-1])\n            plt.subplot(1, 3, 2), plt.imshow(segimg)\n            plt.subplot(1, 3, 3), plt.imshow(srcimg[:, :, ::-1]+128*segimg[:, :, ::-1])\n            plt.show()# # 2.4 show segmentation result","metadata":{}},{"cell_type":"code","source":"srcimgpath = \"/kaggle/input/p24testimage/\"\nsegimgpath = \"/kaggle/working/gradienterseg/\"\nimfiles = os.listdir(srcimgpath)\nimfiles.sort()\nfor encoder in encoders:\n    segimgpath = os.path.join(smpsegpath, encoder)    \n    for idx, imfile in enumerate(imfiles):\n        if not (idx % 50):\n            srcimg = cv2.imread(srcimgpath+imfile)\n            print(segimgpath+encoder+\"/\"+imfile)\n            segimg = cv2.imread(segimgpath+\"/\"+imfile)\n            plt.figure(figsize=(40, 40))\n            plt.subplot(1, 3, 1), plt.imshow(srcimg[:, :, ::-1])\n            plt.subplot(1, 3, 2), plt.imshow(segimg)\n            plt.subplot(1, 3, 3), plt.imshow(srcimg[:, :, ::-1]+128*segimg[:, :, ::-1])\n            plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-05-17T05:23:26.052519Z","iopub.execute_input":"2023-05-17T05:23:26.052895Z","iopub.status.idle":"2023-05-17T05:23:49.479224Z","shell.execute_reply.started":"2023-05-17T05:23:26.052863Z","shell.execute_reply":"2023-05-17T05:23:49.478365Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}