{"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":"<h2 class=\"list-group-item list-group-item-action active\" style='color:#124A94 ; background:white'>1.Loading libraries and setting constants </h2>\n<a id=3></a>","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:02:56.069798Z","iopub.execute_input":"2022-08-20T11:02:56.070185Z","iopub.status.idle":"2022-08-20T11:02:56.076509Z","shell.execute_reply.started":"2022-08-20T11:02:56.070150Z","shell.execute_reply":"2022-08-20T11:02:56.075149Z"}}},{"cell_type":"code","source":"import os\nimport gc\nfrom tqdm.notebook import tqdm\n\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport cv2 as cv\nimport tifffile as tiff \n\nimport albumentations as A\n\nfrom sklearn.model_selection import StratifiedKFold\n\nimport torch\nimport torchvision.transforms as transforms\nimport torch.optim as optim\nimport torch.nn.functional as F\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader\n\nfrom albumentations.pytorch.transforms import ToTensorV2\n\nimport warnings\nimport random\nwarnings.filterwarnings(\"ignore\")\n\nplt.style.use(\"dark_background\")","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:04.386995Z","iopub.execute_input":"2022-08-20T11:59:04.388054Z","iopub.status.idle":"2022-08-20T11:59:08.542200Z","shell.execute_reply.started":"2022-08-20T11:59:04.387945Z","shell.execute_reply":"2022-08-20T11:59:08.541221Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"seed = 113\nk_fold = 5\nbatch_size = 22","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:08.544467Z","iopub.execute_input":"2022-08-20T11:59:08.545188Z","iopub.status.idle":"2022-08-20T11:59:08.551625Z","shell.execute_reply.started":"2022-08-20T11:59:08.545148Z","shell.execute_reply":"2022-08-20T11:59:08.549719Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"random.seed(seed)\nos.environ[\"PYTHONHASHSEED\"] = str(seed)\nnp.random.seed(seed)\ntorch.cuda.manual_seed_all(seed)\ntorch.cuda.manual_seed(seed)\ntorch.backends.cudnn.deterministic = True","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:08.553507Z","iopub.execute_input":"2022-08-20T11:59:08.554379Z","iopub.status.idle":"2022-08-20T11:59:08.564364Z","shell.execute_reply.started":"2022-08-20T11:59:08.554311Z","shell.execute_reply":"2022-08-20T11:59:08.563245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h2 class=\"list-group-item list-group-item-action active\" style='color:#124A94 ; background:white'>2.Сheck cpu / gpu </h2>\n<a id=3></a>","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:04:08.243216Z","iopub.execute_input":"2022-08-20T11:04:08.243891Z","iopub.status.idle":"2022-08-20T11:04:08.249800Z","shell.execute_reply.started":"2022-08-20T11:04:08.243855Z","shell.execute_reply":"2022-08-20T11:04:08.248576Z"}}},{"cell_type":"code","source":"if torch.cuda.is_available():\n    device = torch.device('cuda')\n    print('Thera are  %d GPU(s) available.' % torch.cuda.device_count())\n    print(torch.cuda.get_device_name(device=None))\nelse:\n    print('No GPU available, using the CPU instead.')\n    device = torch.device(\"cpu\")","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:08.568655Z","iopub.execute_input":"2022-08-20T11:59:08.569424Z","iopub.status.idle":"2022-08-20T11:59:08.649187Z","shell.execute_reply.started":"2022-08-20T11:59:08.569384Z","shell.execute_reply":"2022-08-20T11:59:08.647865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h2 class=\"list-group-item list-group-item-action active\" style='color:#124A94 ; background:white'>3.Show data </h2>\n<a id=3></a>","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:06:29.573676Z","iopub.execute_input":"2022-08-20T11:06:29.574099Z","iopub.status.idle":"2022-08-20T11:06:29.581302Z","shell.execute_reply.started":"2022-08-20T11:06:29.574064Z","shell.execute_reply":"2022-08-20T11:06:29.579806Z"}}},{"cell_type":"code","source":"train_path = '../input/hubmap-organ-segmentation/train.csv'\ndf = pd.read_csv(train_path)\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:08.650808Z","iopub.execute_input":"2022-08-20T11:59:08.652317Z","iopub.status.idle":"2022-08-20T11:59:09.000653Z","shell.execute_reply.started":"2022-08-20T11:59:08.652277Z","shell.execute_reply":"2022-08-20T11:59:08.999476Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def mask2rle(img):\n    '''\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    '''\n    pixels= img.T.flatten()\n    pixels = np.concatenate([[0], pixels, [0]])\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1\n    runs[1::2] -= runs[::2]\n    return ' '.join(str(x) for x in runs)\n\ndef rle2mask(mask_rle, shape=(3000,3000)):\n    '''\n    mask_rle: run-length as string formated (start length)\n    shape: (width,height) of array to return \n    Returns numpy array, 1 - mask, 0 - background\n    '''\n    s = mask_rle.split()\n    starts, lengths = [np.asarray(x, dtype=int) for x in (s[0::2], s[1::2])]\n    starts -= 1\n    ends = starts + lengths\n    img = np.zeros(shape[0]*shape[1], dtype=np.uint8)\n    for lo, hi in zip(starts, ends):\n        img[lo:hi] = 1\n    return img.reshape(shape).T","metadata":{"_kg_hide-input":false,"execution":{"iopub.status.busy":"2022-08-20T11:59:09.002999Z","iopub.execute_input":"2022-08-20T11:59:09.004189Z","iopub.status.idle":"2022-08-20T11:59:09.015020Z","shell.execute_reply.started":"2022-08-20T11:59:09.004140Z","shell.execute_reply":"2022-08-20T11:59:09.013581Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path_image = '../input/hubmap-organ-segmentation/train_images/'\ndf['path_image'] = df.apply(lambda row: path_image + str(row['id']) + \".tiff\", axis=1) ","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:09.016857Z","iopub.execute_input":"2022-08-20T11:59:09.017280Z","iopub.status.idle":"2022-08-20T11:59:09.036139Z","shell.execute_reply.started":"2022-08-20T11:59:09.017240Z","shell.execute_reply":"2022-08-20T11:59:09.035152Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"masks = []\nfor i, rle in enumerate(df.rle):\n    h, w = df[\"img_height\"][i], df[\"img_width\"][i]\n    mask = rle2mask(rle, [w, h])\n    masks.append(mask)\ndf['mask'] = pd.Series(masks)\n\ndf = df.drop(['data_source', 'pixel_size', 'tissue_thickness',\n              'age', 'sex', 'img_height', 'img_width', 'rle'], axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:09.037872Z","iopub.execute_input":"2022-08-20T11:59:09.038530Z","iopub.status.idle":"2022-08-20T11:59:11.094419Z","shell.execute_reply.started":"2022-08-20T11:59:09.038494Z","shell.execute_reply":"2022-08-20T11:59:11.093386Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def random_image():\n    path_image = '../input/hubmap-organ-segmentation/train_images/'\n    i = np.random.randint(df.shape[0])\n    img_numpy = tiff.imread(df['path_image'][i])\n    mask_numpy = df['mask'][i]\n    plt.imshow(img_numpy);\n    plt.imshow(mask_numpy, cmap=\"binary\", alpha=0.6);\n    plt.axis(\"off\");\n    \n","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:11.097071Z","iopub.execute_input":"2022-08-20T11:59:11.097835Z","iopub.status.idle":"2022-08-20T11:59:11.104583Z","shell.execute_reply.started":"2022-08-20T11:59:11.097794Z","shell.execute_reply":"2022-08-20T11:59:11.103353Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:11.109294Z","iopub.execute_input":"2022-08-20T11:59:11.110672Z","iopub.status.idle":"2022-08-20T11:59:11.581852Z","shell.execute_reply.started":"2022-08-20T11:59:11.110633Z","shell.execute_reply":"2022-08-20T11:59:11.580809Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h2 class=\"list-group-item list-group-item-action active\" style='color:#124A94 ; background:white'>4. StratifiedKFold </h2>\n<a id=3></a>","metadata":{}},{"cell_type":"code","source":"\nStratified_KF = StratifiedKFold(n_splits=k_fold, shuffle=True, random_state = seed)\ndf['fold'] = None\nfor fold, (train_id, fold_id), in enumerate(Stratified_KF.split(X = df['id'], y = df['organ'] )):\n    df.loc[fold_id,'fold'] = fold\n","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:11.583442Z","iopub.execute_input":"2022-08-20T11:59:11.583811Z","iopub.status.idle":"2022-08-20T11:59:11.601039Z","shell.execute_reply.started":"2022-08-20T11:59:11.583773Z","shell.execute_reply":"2022-08-20T11:59:11.600053Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h2 class=\"list-group-item list-group-item-action active\" style='color:#124A94 ; background:white'>5. Create augmentation </h2>\n<a id=3></a>","metadata":{}},{"cell_type":"code","source":"\ndef transforms_method(image=None, mask=None, image_size=512):\n    transforms = A.Compose([\n#             A.RandomCrop(height=image_size, width=image_size, always_apply=True),\n            A.Resize(height=image_size, width=image_size, always_apply=True),\n            A.Rotate([-90,90], p=1),\n            A.CoarseDropout(max_height=int(image_size * 0.17), max_width=int(image_size * 0.17),\n                             min_holes=4, max_holes=9, p=0.7),\n            A.RandomGridShuffle(grid=(2, 2), p=0.3),\n            A.GaussianBlur(blur_limit=(3, 7), p=0.15),\n            A.RandomSnow(p=0.15),\n            A.RandomRain(p=0.15),\n            A.Normalize(mean = [0.7720342, 0.74582646, 0.76392896],\n                    std = [0.24745085, 0.26182273, 0.25782376]),\n            ToTensorV2(),\n        ])\n    return transforms\n\ndef transforms_method_test(image=None, mask=None, image_size=512):\n    transforms = A.Compose([\n    A.Resize(height=image_size, width=image_size, always_apply=True),\n    A.Normalize(mean = [0.7720342, 0.74582646, 0.76392896],\n                std = [0.24745085, 0.26182273, 0.25782376]),\n    ToTensorV2(),\n    ])\n    return transforms\n","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:11.603029Z","iopub.execute_input":"2022-08-20T11:59:11.603665Z","iopub.status.idle":"2022-08-20T11:59:11.615139Z","shell.execute_reply.started":"2022-08-20T11:59:11.603627Z","shell.execute_reply":"2022-08-20T11:59:11.613503Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"row, col = 3, 5\nnumber = 1\nplt.figure(figsize=(12, 8))\nfor r in range(row):\n    # choose a random picture \n    i = np.random.randint(df.shape[0])\n    image = cv.imread(df['path_image'][i])\n    image = cv.cvtColor(image, cv.COLOR_BGR2RGB)\n    mask_numpy = df['mask'][i]\n    for c in range(col):\n        # create transform\n        if number % col == 1:\n            plt.subplot(row, col, number)\n            image_r = cv.resize(image, (256, 256))\n            plt.imshow(image)\n            plt.imshow(mask_numpy, cmap=\"binary\", alpha=0.6)\n            plt.title('original')\n        else:\n            mask = df['mask'][i]\n            data = {'image': image, 'mask': mask}\n            transformed = transforms_method(**data)\n            transformed = transformed(**data)\n            crop_img, crop_mask = transformed[\"image\"], transformed[\"mask\"]\n            plt.subplot(row, col, number)\n            plt.imshow(crop_mask, cmap=\"binary\", alpha=0.6)\n        plt.xticks([]);\n        plt.yticks([]);\n        number += 1\n                \nplt.show()    ","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:11.617097Z","iopub.execute_input":"2022-08-20T11:59:11.617508Z","iopub.status.idle":"2022-08-20T11:59:18.589011Z","shell.execute_reply.started":"2022-08-20T11:59:11.617467Z","shell.execute_reply":"2022-08-20T11:59:18.587994Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h2 class=\"list-group-item list-group-item-action active\" style='color:#124A94 ; background:white'>6.Create dataset</h2>\n<a id=3></a>","metadata":{}},{"cell_type":"code","source":"\nclass OrganDataset(Dataset):\n    def __init__(self, images_filepaths, masks, transform=None):\n        self.images_filepaths = images_filepaths\n        self.masks = masks\n        self.transform = transform\n        self.w = masks[0].shape[0]\n        self.h = masks[0].shape[1]\n\n    def __len__(self):\n        return len(self.images_filepaths)\n\n    def __getitem__(self, idx):\n        image_filepath = self.images_filepaths[idx]\n        image = cv.imread(image_filepath)\n        image = cv.cvtColor(image, cv.COLOR_BGR2RGB)\n        mask = np.array(self.masks[idx])\n        if self.transform is not None:\n            result = self.transform(image=image, mask=mask)\n            image = result['image']\n            mask = result['mask']\n        \n        return image, mask","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:18.590012Z","iopub.execute_input":"2022-08-20T11:59:18.590428Z","iopub.status.idle":"2022-08-20T11:59:18.599897Z","shell.execute_reply.started":"2022-08-20T11:59:18.590387Z","shell.execute_reply":"2022-08-20T11:59:18.598796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h2 class=\"list-group-item list-group-item-action active\" style='color:#124A94 ; background:white'>7. Install model </h2>\n<a id=3></a>","metadata":{}},{"cell_type":"code","source":"pip install segmentation_models_pytorch ","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:18.601582Z","iopub.execute_input":"2022-08-20T11:59:18.602613Z","iopub.status.idle":"2022-08-20T11:59:33.957545Z","shell.execute_reply.started":"2022-08-20T11:59:18.602457Z","shell.execute_reply":"2022-08-20T11:59:33.956270Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import segmentation_models_pytorch as smp\nmodel = smp.Unet(\"resnet34\", encoder_weights=\"imagenet\", activation=None).to(device)","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:33.959316Z","iopub.execute_input":"2022-08-20T11:59:33.959975Z","iopub.status.idle":"2022-08-20T11:59:47.376563Z","shell.execute_reply.started":"2022-08-20T11:59:33.959929Z","shell.execute_reply":"2022-08-20T11:59:47.375493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimizer = torch.optim.Adam(model.parameters(),  lr = 10 **(-3))\ncriterion = nn.BCEWithLogitsLoss()\nfrom torch.optim.lr_scheduler import ReduceLROnPlateau\nscheduler = ReduceLROnPlateau(optimizer, mode=\"min\", patience=8, verbose=True)","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:47.378662Z","iopub.execute_input":"2022-08-20T11:59:47.379030Z","iopub.status.idle":"2022-08-20T11:59:47.387668Z","shell.execute_reply.started":"2022-08-20T11:59:47.378991Z","shell.execute_reply":"2022-08-20T11:59:47.386138Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h2 class=\"list-group-item list-group-item-action active\" style='color:#124A94 ; background:white'>8. Create metric</h2>\n<a id=3></a>","metadata":{}},{"cell_type":"code","source":"\ndef predict(X, threshold=0.5):\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.view(batch_size, -1)\n        truth = truth.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\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    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\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]","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:47.390076Z","iopub.execute_input":"2022-08-20T11:59:47.390873Z","iopub.status.idle":"2022-08-20T11:59:47.405748Z","shell.execute_reply.started":"2022-08-20T11:59:47.390823Z","shell.execute_reply":"2022-08-20T11:59:47.404829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n<h2 class=\"list-group-item list-group-item-action active\" style='color:#124A94 ; background:white'>9. Training model</h2>\n<a id=3></a>","metadata":{}},{"cell_type":"code","source":"%%time\nepochs = 20\nlist_of_loss_train = []\nlist_of_loss_val = []\nlist_of_dice = []\nlist_of_iou= []\n# epochs\nfor epoch_i in range(1, epochs + 1):\n    \n    # k_fold\n    print(f'---------------------epoch:{epoch_i}/{epochs}---------------------')\n    for valid_fold in tqdm(range(k_fold)):\n        \n        #train, test    \n        train = df[df['fold'] != valid_fold]\n        valid = df[df['fold'] == valid_fold]\n\n        X_train = train['path_image']\n        y_train = train['mask']\n        X_valid = valid['path_image']\n        y_valid = valid['mask']\n\n        train_dataset = OrganDataset(\n            images_filepaths=X_train.values,\n            masks=y_train.values,\n            transform=transforms_method()\n        )\n\n        valid_dataset = OrganDataset(\n            images_filepaths=X_valid.values,\n            masks=y_valid.values,\n            transform=transforms_method_test()\n        )\n        \n        train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\n        valid_loader = DataLoader(valid_dataset, batch_size=batch_size)\n        \n        # loss, criteriy\n        mean_dice = 0\n        avg_train_loss = 0\n        avg_val_loss = 0\n        base_dice_scores = []\n        iou_scores = []\n        dice_pos_scores = []\n        dice_neg_scores = []\n        #train \n        model.train()\n        for batch in tqdm(train_loader):\n            #forward\n            X_batch = batch[0].to(device)\n            y_batch = batch[1].to(device)\n            optimizer.zero_grad()\n            res = model.forward(X_batch)\n            loss = criterion(res.float(), y_batch.unsqueeze(1).float())\n            loss.backward()\n            optimizer.step()\n\n            avg_train_loss += loss / len(train_loader)\n            del batch, res\n            gc.collect()\n        model.eval()\n            \n        for batch in (valid_loader):\n            X_batch = batch[0].to(device)\n            y_batch = batch[1].to(device)\n\n            with torch.no_grad(): \n                #forward_valid\n                res = model.forward(X_batch)\n                loss = criterion(res.float(), y_batch.unsqueeze(1).float())\n                avg_val_loss += loss / len(valid_loader) \n\n                #metrics\n                res = res.detach().cpu()\n                y_batch = y_batch.unsqueeze(1).detach().cpu()\n                \n                probs = torch.sigmoid(res)\n                dice, _, _, _, _ = metric(probs, y_batch)\n                base_dice_scores.extend(dice.tolist())\n\n                preds = predict(probs)\n                iou = compute_iou_batch(preds, y_batch, classes=[1])\n                iou_scores.append(iou)\n                \n            last_predic_mask = res.clone() \n            del batch, res\n            gc.collect\n\n        scheduler.step(avg_val_loss)\n        dice = np.nanmean(base_dice_scores)\n\n        iou = np.nanmean(iou_scores)\n        \n        list_of_loss_train.append(avg_train_loss.detach().cpu().numpy())\n        list_of_loss_val.append(avg_val_loss.detach().cpu().numpy())\n        list_of_dice.append(dice)\n        list_of_iou.append(iou)\n        print(f'epoch: {epoch_i}, path: {valid_fold+1}/{k_fold}')    \n        print(\"loss_train: %0.4f| loss_valid: %0.4f| IoU: %0.4f | dice: %0.4f\" % (avg_train_loss, avg_val_loss, iou, dice,))","metadata":{"execution":{"iopub.status.busy":"2022-08-20T11:59:47.407539Z","iopub.execute_input":"2022-08-20T11:59:47.408311Z","iopub.status.idle":"2022-08-20T13:24:07.527786Z","shell.execute_reply.started":"2022-08-20T11:59:47.408257Z","shell.execute_reply":"2022-08-20T13:24:07.525009Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.save(model, 'model.pt')","metadata":{"execution":{"iopub.status.busy":"2022-08-20T13:24:07.532582Z","iopub.execute_input":"2022-08-20T13:24:07.533277Z","iopub.status.idle":"2022-08-20T13:24:07.774000Z","shell.execute_reply.started":"2022-08-20T13:24:07.533226Z","shell.execute_reply":"2022-08-20T13:24:07.772963Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n<h2 class=\"list-group-item list-group-item-action active\" style='color:#124A94 ; background:white'>10. Check metric</h2>\n<a id=3></a>","metadata":{}},{"cell_type":"code","source":"# PLOT TRAINING\nplt.rcParams[\"font.family\"] = 'serif'\ndef plot(name, list_value, list_train=None):\n    plt.figure(figsize=(10,5))\n    plt.plot(range(len(list_value)), list_value, label=f'val {name}', linewidth=5.0)\n    if list_train:\n        plt.plot(range(len(list_train)), list_train, label=f'train {name}',  linewidth=5.0)\n    plt.title(f'{name} plot',  fontsize=22); plt.xlabel('iter',  fontsize=14); plt.ylabel(f'{name}', fontsize=14);\n    plt.legend(fontsize=16); \n    plt.xticks([]);\n    plt.show()\n\nplot(\"BCE loss\", list_of_loss_val, list_of_loss_train)\nplot(\"Dice score\", list_of_dice)\nplot(\"IoU score\", list_of_iou)","metadata":{"execution":{"iopub.status.busy":"2022-08-20T13:24:07.775517Z","iopub.execute_input":"2022-08-20T13:24:07.776391Z","iopub.status.idle":"2022-08-20T13:24:08.397102Z","shell.execute_reply.started":"2022-08-20T13:24:07.776352Z","shell.execute_reply":"2022-08-20T13:24:08.396044Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n<h2 class=\"list-group-item list-group-item-action active\" style='color:#124A94 ; background:white'>11. Check result original / predict masks</h2>\n<a id=3></a>","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(8, 16))\nplt.suptitle(\"Random original / predict image\", fontsize=16)\nk = 1 \nfor i in range(4):\n    pred = np.squeeze(last_predic_mask[i], axis=0)       \n    probs = torch.sigmoid(pred)\n    probs = predict(probs)\n    mask = np.squeeze(y_batch[i].detach().cpu(), axis=0) \n    \n    plt.subplot(4, 2, k)\n    plt.title('original')\n    plt.imshow(mask)\n    plt.xticks([]);\n    plt.yticks([]);\n    \n    plt.subplot(4, 2, k + 1)\n    plt.title('predict')\n    plt.imshow(probs)\n    plt.xticks([]);\n    plt.yticks([]);\n    \n    k += 2\nplt.show();","metadata":{"execution":{"iopub.status.busy":"2022-08-20T13:24:08.398697Z","iopub.execute_input":"2022-08-20T13:24:08.399044Z","iopub.status.idle":"2022-08-20T13:24:09.062174Z","shell.execute_reply.started":"2022-08-20T13:24:08.399008Z","shell.execute_reply":"2022-08-20T13:24:09.061073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n<h2 class=\"list-group-item list-group-item-action active\" style='color:#124A94 ; background:white'>12. Test prediction</h2>\n<a id=3></a>","metadata":{}},{"cell_type":"code","source":"test_path = '../input/hubmap-organ-segmentation/test.csv'\ndf_test  = pd.read_csv(test_path)\ndf_test.head()","metadata":{"execution":{"iopub.status.busy":"2022-08-20T13:24:09.063923Z","iopub.execute_input":"2022-08-20T13:24:09.064389Z","iopub.status.idle":"2022-08-20T13:24:09.110316Z","shell.execute_reply.started":"2022-08-20T13:24:09.064344Z","shell.execute_reply":"2022-08-20T13:24:09.109139Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.eval()\nt_method = transforms_method_test()\n\nrle_list = []\nid_list = []\nwith torch.no_grad(): \n\n    for id in df_test['id']:\n        \n        #load image \n        image_filepath = '../input/hubmap-organ-segmentation/test_images/' + str(id) +'.tiff'\n        image = cv.imread(image_filepath)\n        image = cv.cvtColor(image, cv.COLOR_BGR2RGB)\n        \n        #load width, height\n        w = df_test[df_test['id'] == id]['img_height'][0]\n        h = df_test[df_test['id'] == id]['img_width'][0]\n\n        #transform for test_transform_method\n        result = t_method(image=image)['image']\n        #prediction mask\n        mask_pred_512 = model.forward(result.unsqueeze(0).to(device))\n        pred = np.squeeze(mask_pred_512[0].to('cpu'), axis=0)       \n        probs = torch.sigmoid(pred)\n        probs = predict(probs)\n        resize_image = A.Resize(h, w, always_apply=True)(image=probs)['image']\n        rle = mask2rle(resize_image)\n        \n        id_list.append(id)\n        rle_list.append(rle)","metadata":{"execution":{"iopub.status.busy":"2022-08-20T13:24:09.112151Z","iopub.execute_input":"2022-08-20T13:24:09.112751Z","iopub.status.idle":"2022-08-20T13:24:09.426574Z","shell.execute_reply.started":"2022-08-20T13:24:09.112710Z","shell.execute_reply":"2022-08-20T13:24:09.425614Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n<h2 class=\"list-group-item list-group-item-action active\" style='color:#124A94 ; background:white'>13. Check right convertation: mask -> rle -> mask</h2>\n<a id=3></a>","metadata":{}},{"cell_type":"code","source":"# start\nplt.figure(figsize=(16, 16))\n\nplt.subplot(1, 3, 1)\nplt.title('predict',fontsize=20)\nplt.xticks([]);\nplt.yticks([]);\nplt.imshow(resize_image)\n\nplt.subplot(1, 3, 2)\nrle = mask2rle(resize_image)\nmask = rle2mask(rle, shape=(2023, 2023))\nplt.title('predict->rle->mask',fontsize=20)\nplt.xticks([]);\nplt.yticks([]);\nplt.imshow(mask)\n\n# plt.subplot(1, 3, 3)","metadata":{"execution":{"iopub.status.busy":"2022-08-20T13:24:09.428117Z","iopub.execute_input":"2022-08-20T13:24:09.428459Z","iopub.status.idle":"2022-08-20T13:24:10.365758Z","shell.execute_reply.started":"2022-08-20T13:24:09.428423Z","shell.execute_reply":"2022-08-20T13:24:10.364740Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n<h2 class=\"list-group-item list-group-item-action active\" style='color:#124A94 ; background:white'>14. Save prediction</h2>\n<a id=3></a>","metadata":{}},{"cell_type":"code","source":"submission = pd.DataFrame({\n    'id': id_list,\n    'rle': rle_list,\n})\nsubmission.to_csv(\"submission.csv\", index=False, header=True)","metadata":{"execution":{"iopub.status.busy":"2022-08-20T13:24:10.367347Z","iopub.execute_input":"2022-08-20T13:24:10.367950Z","iopub.status.idle":"2022-08-20T13:24:10.383467Z","shell.execute_reply.started":"2022-08-20T13:24:10.367911Z","shell.execute_reply":"2022-08-20T13:24:10.382532Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.head()","metadata":{"execution":{"iopub.status.busy":"2022-08-20T13:24:10.385006Z","iopub.execute_input":"2022-08-20T13:24:10.385611Z","iopub.status.idle":"2022-08-20T13:24:10.397315Z","shell.execute_reply.started":"2022-08-20T13:24:10.385567Z","shell.execute_reply":"2022-08-20T13:24:10.396193Z"},"trusted":true},"execution_count":null,"outputs":[]}]}