{"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":"# **Importing the required libraries**","metadata":{}},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd\nimport os\nimport torch\nfrom torch import nn\nfrom torch import optim\nfrom torch.utils.tensorboard import SummaryWriter\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\n# import torchvision.transforms.functional as TF\n\nimport random\nimport os, shutil\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\nfrom tqdm.auto import tqdm\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nimport os\nfrom os.path import join\nimport matplotlib.pyplot as plt\nplt.rcParams.update({'font.size': 18})\nimport cv2\n\nimport torch.nn.functional as F\nfrom torch.utils.data import DataLoader, Dataset, sampler\nfrom albumentations import (HorizontalFlip, VerticalFlip, ShiftScaleRotate, Normalize, Resize, Compose, GaussNoise)\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score, f1_score,roc_auc_score,recall_score,precision_score\n","metadata":{"execution":{"iopub.status.busy":"2021-12-13T18:25:19.644344Z","iopub.execute_input":"2021-12-13T18:25:19.647345Z","iopub.status.idle":"2021-12-13T18:25:19.662023Z","shell.execute_reply.started":"2021-12-13T18:25:19.647288Z","shell.execute_reply":"2021-12-13T18:25:19.661224Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Data Loading and Decoding**","metadata":{}},{"cell_type":"code","source":"data_train = pd.read_csv('../input/sartorius-cell-instance-segmentation/train.csv')","metadata":{"execution":{"iopub.status.busy":"2021-12-13T17:39:38.27079Z","iopub.execute_input":"2021-12-13T17:39:38.271565Z","iopub.status.idle":"2021-12-13T17:39:38.620134Z","shell.execute_reply.started":"2021-12-13T17:39:38.271516Z","shell.execute_reply":"2021-12-13T17:39:38.619122Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_train.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DATA_PATH = '../input/sartorius-cell-instance-segmentation'\nSAMPLE_SUBMISSION = join(DATA_PATH,'train')\nTRAIN_CSV = join(DATA_PATH,'train.csv')\nTRAIN_PATH = join(DATA_PATH,'train')\nTEST_PATH = join(DATA_PATH,'test')\n\ndf_train = pd.read_csv(TRAIN_CSV)\nprint(f'Training Set Shape: {df_train.shape} - {df_train[\"id\"].nunique()} \\\nImages - Memory Usage: {df_train.memory_usage().sum() / 1024 ** 2:.2f} MB')","metadata":{"execution":{"iopub.status.busy":"2021-12-13T17:39:55.20617Z","iopub.execute_input":"2021-12-13T17:39:55.206682Z","iopub.status.idle":"2021-12-13T17:39:55.492124Z","shell.execute_reply.started":"2021-12-13T17:39:55.206642Z","shell.execute_reply":"2021-12-13T17:39:55.491242Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rle_decode(mask_rle, shape, color=1):\n    '''\n    mask_rle: run-length as string formated (start length)\n    shape: (height,width) of array to return \n    Returns numpy array, 1 - mask, 0 - background\n\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.float32)\n    for lo, hi in zip(starts, ends):\n        img[lo : hi] = color\n    return img.reshape(shape)\ndef build_masks(df_train, image_id, input_shape):\n    height, width = input_shape\n    labels = df_train[df_train[\"id\"] == image_id][\"annotation\"].tolist()\n    mask = np.zeros((height, width))\n    for label in labels:\n        mask += rle_decode(label, shape=(height, width))\n    mask = mask.clip(0, 1)\n    return np.array(mask)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CellDataset(Dataset):\n    def __init__(self, df: pd.core.frame.DataFrame, train:bool):\n        self.IMAGE_RESIZE = (224, 224)\n        self.RESNET_MEAN = (0.485, 0.456, 0.406)\n        self.RESNET_STD = (0.229, 0.224, 0.225)\n        self.df = df\n        self.base_path = TRAIN_PATH\n        self.gb = self.df.groupby('id')\n        self.transforms = Compose([Resize(self.IMAGE_RESIZE[0],  self.IMAGE_RESIZE[1]),\n                                   Normalize(mean=self.RESNET_MEAN, std= self.RESNET_STD, p=1),\n                                   HorizontalFlip(p=0.5),\n                                   VerticalFlip(p=0.5)])\n        \n        # Split train and val set\n        all_image_ids = np.array(df_train.id.unique())\n        np.random.seed(42)\n#         iperm = np.random.permutation(len(all_image_ids))\n        num_train_samples = int(len(all_image_ids) * 0.9)\n\n        if train:\n            self.image_ids = all_image_ids[:num_train_samples]\n        else:\n             self.image_ids = all_image_ids[num_train_samples:]\n\n    def __getitem__(self, idx: int) -> dict:\n\n        image_id = self.image_ids[idx]\n        df = self.gb.get_group(image_id)\n\n        # Read image\n        image_path = os.path.join(self.base_path, image_id + \".png\")\n        image = cv2.imread(image_path)\n\n        # Create the mask\n        mask = build_masks(df_train, image_id, input_shape=(520, 704))\n        mask = (mask >= 1).astype('float32')\n        augmented = self.transforms(image=image, mask=mask)\n        image = augmented['image']\n        mask = augmented['mask']\n        # print(np.moveaxis(image,0,2).shape)\n        return np.moveaxis(np.array(image),2,0), mask.reshape((1, self.IMAGE_RESIZE[0], self.IMAGE_RESIZE[1]))\n\n\n    def __len__(self):\n        return len(self.image_ids)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_train = CellDataset(df_train, train=True)\ndl_train = DataLoader(ds_train, batch_size=16, num_workers=2, pin_memory=True, shuffle=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_test = CellDataset(df_train, train=False)\ndl_test = DataLoader(ds_test, batch_size=4, num_workers=2, pin_memory=True, shuffle=False)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Visualization of the images and masks**","metadata":{}},{"cell_type":"code","source":"def imshow(num_to_show=9):\n    \n    plt.figure(figsize=(20,20))\n    \n    for i in range(num_to_show):\n        plt.subplot(3, 3, i+1)\n        plt.grid(False)\n        plt.xticks([])\n        plt.yticks([])\n        \n        img = mpimg.imread(f'../input/sartorius-cell-instance-segmentation/train/{data_train.iloc[i*500,0]}.png')\n        plt.imshow(img, cmap='plasma')\n\nimshow()","metadata":{"execution":{"iopub.status.busy":"2021-12-13T18:40:37.925161Z","iopub.execute_input":"2021-12-13T18:40:37.92541Z","iopub.status.idle":"2021-12-13T18:40:39.289466Z","shell.execute_reply.started":"2021-12-13T18:40:37.925382Z","shell.execute_reply":"2021-12-13T18:40:39.288796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# plot simages and mask from dataloader\nbatch = next(iter(dl_train))\nimages, masks = batch\nprint(f\"image shape: {images.shape},\\nmask shape:{masks.shape},\\nbatch len: {len(batch)}\")\nk=11\nplt.figure(figsize=(20, 20))\n        \nplt.subplot(1, 3, 1)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(images[k][0])\nplt.title('Original image')\n\nplt.subplot( 1, 3, 2)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(masks[k][0])\nplt.title('Mask')\n\nplt.subplot( 1, 3, 3)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(images[k][0])\nplt.imshow(masks[k][0],alpha=0.2)\nplt.title('Both')\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-13T18:40:29.683958Z","iopub.execute_input":"2021-12-13T18:40:29.684404Z","iopub.status.idle":"2021-12-13T18:40:29.707304Z","shell.execute_reply.started":"2021-12-13T18:40:29.684367Z","shell.execute_reply":"2021-12-13T18:40:29.705958Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# K-means","metadata":{}},{"cell_type":"markdown","source":"Helper class to load data, transfer mask to RLE, and binarization images.","metadata":{}},{"cell_type":"code","source":"class RLE:\n    def __init__(self):\n        return\n    def mask2rle(self, img):\n        '''\n        Efficient implementation of mask2rle, from @paulorzp\n        --\n        img: numpy array, 1 - mask, 0 - background\n        Returns run length as string formated\n        Source: https://www.kaggle.com/xhlulu/efficient-mask2rle\n        '''\n        pixels = img.T.flatten()\n        pixels = np.pad(pixels, ((1, 1),))\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\n\n    def rle_decode(self, mask_rle, shape, color=1):\n        '''\n        mask_rle: run-length as string formated (start length)\n        shape: (height, width, channels) of array to return\n        color: color for the mask\n        Returns numpy array (mask)\n\n        '''\n        s = mask_rle.split()\n        starts = list(map(lambda x: int(x) - 1, s[0::2]))\n        lengths = list(map(int, s[1::2]))\n        ends = [x + y for x, y in zip(starts, lengths)]\n\n        img = np.zeros((shape[0] * shape[1], shape[2]), dtype=np.float32)\n\n        for start, end in zip(starts, ends):\n            img[start: end] = color\n\n        return img.reshape(shape)\n    \n    def loadData(self):\n#         df = pd.read_csv(f'../input/sartorius-cell-instance-segmentation/train.csv')\n        df = df_train\n        df['image_path'] = TRAIN_PATH + '/' + df['id'] + '.png'\n        # data = df.head(2)\n        # labels = ['id', 'annotation', 'width', 'height', 'cell_type',\n        #           'plate_time', 'sample_date', 'sample_id', 'elapsed_timedelta']\n        # annotation = df['annotation']\n        tmp_df = df.drop_duplicates(subset=[\"id\", \"image_path\"]).reset_index(drop=True)\n        tmp_df[\"annotation\"] = df.groupby(\"id\")[\"annotation\"].agg(list).reset_index(drop=True)\n        df = tmp_df.copy()\n#         print(df['image_path'][20])\n        return df\n    \n    def show(self, winname, src):\n        cv2.namedWindow(winname, cv2.WINDOW_GUI_NORMAL)\n        cv2.imshow(winname, src)\n    #     cv2.waitKey()\n    \n    def thre_method(self, img_src):\n        ret, thresh = cv2.threshold(img_src, 127, 255, cv2.THRESH_BINARY)\n        thresh_gray = cv2.cvtColor(thresh, cv2.COLOR_BGR2GRAY)\n        return thresh_gray","metadata":{"execution":{"iopub.status.busy":"2021-12-13T18:25:42.480308Z","iopub.execute_input":"2021-12-13T18:25:42.480568Z","iopub.status.idle":"2021-12-13T18:25:42.759864Z","shell.execute_reply.started":"2021-12-13T18:25:42.480538Z","shell.execute_reply":"2021-12-13T18:25:42.759131Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> Implement K-means clustering, and caculate accuracy and F1 score of results.","metadata":{}},{"cell_type":"code","source":"rle = RLE()\n    \ndef Kmeans(data, imageIndex):\n    print(data['image_path'][1])\n    fileName = data['image_path'][imageIndex]\n    img = cv2.imread(fileName)\n\n    plt.subplot(1, 3, 1)\n    plt.xticks([])\n    plt.yticks([])\n    plt.imshow(img)\n    plt.title('Original image')\n    \n    img = cv2.fastNlMeansDenoising(img, 10, 10, 7, 21)\n\n\n    data = img.reshape((-1, 3)\n    data = np.float32(data)\n    \n    # set parameters of K-means\n    critera = (cv2.TermCriteria_EPS+cv2.TermCriteria_MAX_ITER, 10, 0.1)\n    flags = cv2.KMEANS_RANDOM_CENTERS\n    \n    # Implement K-means\n    r, best, center = cv2.kmeans(data, 4, None, criteria=critera, attempts=10, flags=flags)\n\n    center = np.uint8(center)\n\n    # set different color to the image\n    data[best.ravel() == 0] = (0, 0, 0)\n    data[best.ravel() == 1] = (0, 0, 255)\n    data[best.ravel() == 2] = (255, 0, 0)\n    data[best.ravel() == 3] = (255, 255, 255)\n\n    data = np.uint8(data)\n    oi = data.reshape((img.shape))\n\n    # show image\n    plt.subplot(1, 3, 2)\n    plt.xticks([])\n    plt.yticks([])\n    plt.imshow(oi)\n    plt.title('K-means')\n\n    thre = rle.thre_method(oi)\n\n    contours, _ = cv2.findContours(thre, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n    # make a mask\n    img_mask = np.zeros(thre.shape, np.uint8)\n    \n    cv2.drawContours(img_mask, contours, -1, (255, 255, 255), -1)\n\n    # kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))\n    # img_mask = cv.morphologyEx(img_mask, cv.MORPH_OPEN, kernel)\n\n    plt.subplot(1, 3, 3)\n    plt.xticks([])\n    plt.yticks([])\n    plt.imshow(img_mask)\n    plt.title('Mask img')\n    plt.show()\n    flat_image = img_mask.flatten()\n    r = list(rle.mask2rle(img_mask))\n\n    return r, flat_image\n\n\ndef accuracy(index):\n    data = rle.loadData()\n    _, labels = testKmeans(index)\n    _, predicted = Kmeans(data, index)\n    acc = accuracy_score(labels, predicted)\n    print('acc:', acc)\n    black_img = np.zeros([520, 704], dtype=np.uint8)\n    black_img = black_img.flatten()\n    acc_blk = accuracy_score(labels, black_img)\n#     print('blk acc:', acc_blk)\n    f1_blk = f1_score(labels, black_img, average='macro')\n    f1 = f1_score(labels, predicted, average='macro')\n    print('f1:', f1)\n#     print('f1_black:', f1_blk)\n    \n\n    \n","metadata":{"execution":{"iopub.status.busy":"2021-12-13T19:13:06.011052Z","iopub.execute_input":"2021-12-13T19:13:06.01144Z","iopub.status.idle":"2021-12-13T19:13:06.029907Z","shell.execute_reply.started":"2021-12-13T19:13:06.011401Z","shell.execute_reply":"2021-12-13T19:13:06.029078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def testKmeans(imageIndex):\n\n    shape = (520, 704, 3)\n    data = rle.loadData()\n    lens = 0\n    for i in range(len(data['annotation'][imageIndex])):\n        if i == 0:\n            mask = rle.rle_decode(data['annotation'][imageIndex][i], shape)\n            lens = len(data['annotation'][imageIndex][i])\n        else:\n            mask = cv2.add(mask, rle.rle_decode(data['annotation'][imageIndex][i], shape))\n            lens += len(data['annotation'][imageIndex][i])\n        fileName = data['image_path'][imageIndex]\n        \n    img = cv2.imread(fileName)\n    mask *= 255.0\n    mask = mask.astype(np.uint8)\n\n    mask_img = cv2.addWeighted(img, 1, mask, 0.2, 0)\n\n#     cv2.imshow('origin', img)\n#     cv2.imshow('mask', mask)\n#     cv2.imshow('mask img', mask_img)\n\n    plt.subplot(1, 3, 1)\n    plt.xticks([])\n    plt.yticks([])\n    plt.imshow(img)\n    plt.title('Original image')\n    \n    plt.subplot(1, 3, 2)\n    plt.xticks([])\n    plt.yticks([])\n    plt.imshow(mask)\n    plt.title('Annotation Mask')\n    \n    plt.subplot(1, 3, 3)\n    plt.xticks([])\n    plt.yticks([])\n    plt.imshow(mask_img)\n    plt.title('Mask image')\n\n    mask = cv2.cvtColor(mask, cv2.COLOR_RGB2GRAY)\n    flat_mask = mask.flatten()\n\n    return mask, flat_mask","metadata":{"execution":{"iopub.status.busy":"2021-12-13T19:12:11.400585Z","iopub.execute_input":"2021-12-13T19:12:11.40086Z","iopub.status.idle":"2021-12-13T19:12:11.41176Z","shell.execute_reply.started":"2021-12-13T19:12:11.400813Z","shell.execute_reply":"2021-12-13T19:12:11.411039Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rle = RLE()\nimageIndex = 15\n# mask, flat_mask = testKmeans(imageIndex)\naccuracy(imageIndex)","metadata":{"execution":{"iopub.status.busy":"2021-12-13T20:45:02.59114Z","iopub.execute_input":"2021-12-13T20:45:02.591849Z","iopub.status.idle":"2021-12-13T20:45:02.607616Z","shell.execute_reply.started":"2021-12-13T20:45:02.591814Z","shell.execute_reply":"2021-12-13T20:45:02.606555Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **CNN**","metadata":{}},{"cell_type":"code","source":"class CNN(nn.Module):\n    def __init__(self, in_channels, num_classes):\n        super(CNN, self).__init__()\n        self.cov1=nn.Conv2d(in_channels, 20, kernel_size=5, padding=\"same\")\n        self.btn=nn.BatchNorm2d(20)\n        self.relu=nn.ReLU()\n        self.cov2=nn.Conv2d(20, 10, kernel_size=1)\n        self.cov3=nn.Conv2d(10, 10, kernel_size=5, padding=\"same\")\n        self.btn2=nn.BatchNorm2d(10)\n        self.cov4=nn.Conv2d(10, num_classes, kernel_size=1)\n        self.sigmod=nn.Sigmoid()\n        \n    def forward(self, x):\n        # print(x.shape)\n        x1 = self.cov1(x)\n        # print(x1.shape)\n        x2 = self.btn(x1)\n        # print(x2.shape)\n        x3 = self.relu(x2)\n        # print(x3.shape)\n        x4 = self.cov2(x3)\n        # print(x4.shape)\n        x5 = self.cov3(x4)\n        # print(x5.shape)\n        # print('up')\n        x = self.btn2(x4)\n        # print(x.shape)\n        x = self.relu(x)\n        # print(x.shape)\n        x = self.cov4(x)\n        # print(x.shape)\n        x = self.sigmod(x)\n        # print(x.shape)\n        return x","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')\n# device=torch.device('cpu')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_loop(model, optimizer, criterion, train_loader, device=device):\n    running_loss = 0\n    model.train()\n    pbar = tqdm(train_loader, desc='Iterating over train data')\n    for imgs, masks in pbar:\n        # pass to device\n        imgs = imgs.to(device)\n        masks = masks.to(device)\n        # forward\n        out = model(imgs)\n        loss = criterion(out, masks)\n        running_loss += loss.item()*imgs.shape[0]  # += loss * current batch size\n        # optimize\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n    running_loss /= len(train_loader.sampler)\n    return running_loss","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def eval_loop(model, criterion, eval_loader, device=device):\n    running_loss = 0\n    model.eval()\n    with torch.no_grad():\n        accuracy, f1_scores,roc_auc_score, recall_score, precision_score = [],[],[],[],[]\n        pbar = tqdm(eval_loader, desc='Iterating over evaluation data')\n        \n        for imgs, masks in pbar:\n#             print(imgs.shape)\n#             print(masks.shape)\n            # pass to device\n            li=imgs\n            lm=masks\n            imgs = imgs.to(device)\n            masks = masks.to(device)\n            # forward\n            out = model(imgs)\n#             print(out.shape)\n            loss = criterion(out, masks)\n            running_loss += loss.item()*imgs.shape[0]\n            # calculate predictions using output\n            predicted = (out > 0.5).float()\n#             print(predicted.shape)\n            predicted = predicted.view(-1).cpu().numpy()\n            labels = masks.view(-1).cpu().numpy()\n#             print(predicted.shape)\n#             print(labels.shape)\n            accuracy.append(accuracy_score(labels, predicted))\n            f1_scores.append(f1_score(labels, predicted))\n            roc_auc_score.append(roc_auc_score(labels, predicted))\n            recall_score.append(recall_score(labels, predicted))\n            precision_score.append(precision_score(labels, predicted))\n            \n    acc = sum(accuracy)/len(accuracy)\n    f1 = sum(f1_scores)/len(f1_scores)\n    f2= sum(roc_auc_score)/len(roc_auc_score)\n    f3= sum(recall_score)/len(recall_score)\n    f4= sum(precision_score)/len(precision_score)\n    running_loss /= len(eval_loader.sampler)\n    return {\n        'accuracy':acc,\n        'f1_macro':f1, \n        'f2_macro':f2,\n        'f3_macro':f3,\n        'f4_macro':f4,\n        'loss':running_loss,\n        'img': li,\n        'masks': lm,\n        'out':out\n    }","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train(model, optimizer, criterion, train_loader, valid_loader,\n          device=device, \n          num_epochs=1, \n          valid_loss_min=np.inf,\n          logdir='logdir'):\n    \n    tb_writer = SummaryWriter(log_dir=logdir)\n    for e in range(num_epochs):\n        # train for epoch\n        train_loss = train_loop(\n            model, optimizer, criterion, train_loader, device=device)\n        # evaluate on validation set\n        metrics = eval_loop(\n            model, criterion, valid_loader, device=device\n        )\n        # show progress\n        print_string = f'Epoch: {e+1} '\n        print_string+= f'TrainLoss: {train_loss:.5f} '\n        print_string+= f'ValidLoss: {metrics[\"loss\"]:.5f} '\n        print_string+= f'ACC: {metrics[\"accuracy\"]:.5f} '\n        print_string+= f'F1: {metrics[\"f1_macro\"]:.3f}'\n        print_string+= f'roc_auc_score: {metrics[\"f2_macro\"]:.3f}'\n        print_string+= f'recall_score: {metrics[\"f3_macro\"]:.3f}'\n        print_string+= f'precision_score: {metrics[\"f4_macro\"]:.3f}'\n        print(print_string)\n\n        # Tensorboards Logging\n        tb_writer.add_scalar('UNet/Train Loss', train_loss, e)\n        tb_writer.add_scalar('UNet/Valid Loss', metrics[\"loss\"], e)\n        tb_writer.add_scalar('UNet/Accuracy', metrics[\"accuracy\"], e)\n        tb_writer.add_scalar('UNet/F1 Macro', metrics[\"f1_macro\"], e)\n\n        # save the model \n        if metrics[\"loss\"] <= valid_loss_min:\n            torch.save(model.state_dict(), 'model.pt')\n            valid_loss_min = metrics[\"loss\"]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# set_seed(21)\nmodel1 = CNN(3, 1).to(device)\noptimizer = optim.Adam(model1.parameters(), lr=0.01)\ncriterion = nn.BCELoss()\ntrain(model1, optimizer, criterion, dl_train, dl_test)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load the latest model\nmodel1.load_state_dict(torch.load('model.pt'))\nmetrics = eval_loop(model1, criterion, dl_test)\n\nprint('accuracy:', metrics['accuracy'])\nprint('f1 macro:', metrics['f1_macro'])\nprint('test loss:', metrics['loss'])\nprint('roc_auc_score:', metrics['f2_macro'])\nprint('recall_score:', metrics['f3_macro'])\nprint('precision_score:', metrics['f4_macro'])\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Unet","metadata":{}},{"cell_type":"code","source":"class conv_block(nn.Module):\n    \"\"\"\n    Convolution Block \n    \"\"\"\n    def __init__(self, in_ch, out_ch):\n        super(conv_block, self).__init__()\n        \n        self.conv = nn.Sequential(\n            nn.Conv2d(in_ch, out_ch, kernel_size=3, stride=1, padding=1, bias=True),\n            nn.BatchNorm2d(out_ch),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(out_ch, out_ch, kernel_size=3, stride=1, padding=1, bias=True),\n            nn.BatchNorm2d(out_ch),\n            nn.ReLU(inplace=True))\n\n    def forward(self, x):\n\n        x = self.conv(x)\n        return x\n\n\nclass up_conv(nn.Module):\n    \"\"\"\n    Up Convolution Block\n    \"\"\"\n    def __init__(self, in_ch, out_ch):\n        super(up_conv, self).__init__()\n        self.up = nn.Sequential(\n            nn.Upsample(scale_factor=2),\n            nn.Conv2d(in_ch, out_ch, kernel_size=3, stride=1, padding=1, bias=True),\n            nn.BatchNorm2d(out_ch),\n            nn.ReLU(inplace=True)\n        )\n\n    def forward(self, x):\n        x = self.up(x)\n        return x","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class U_Net(nn.Module):\n    \"\"\"\n    UNet - Basic Implementation\n    Paper : https://arxiv.org/abs/1505.04597\n    \"\"\"\n    def __init__(self, in_ch=3, out_ch=1):\n        super(U_Net, self).__init__()\n\n        n1 = 64\n        filters = [n1, n1 * 2, n1 * 4, n1 * 8, n1 * 16]\n        \n        self.Maxpool1 = nn.MaxPool2d(kernel_size=2, stride=2)\n        self.Maxpool2 = nn.MaxPool2d(kernel_size=2, stride=2)\n        self.Maxpool3 = nn.MaxPool2d(kernel_size=2, stride=2)\n        self.Maxpool4 = nn.MaxPool2d(kernel_size=2, stride=2)\n\n        self.Conv1 = conv_block(in_ch, filters[0])\n        self.Conv2 = conv_block(filters[0], filters[1])\n        self.Conv3 = conv_block(filters[1], filters[2])\n        self.Conv4 = conv_block(filters[2], filters[3])\n        self.Conv5 = conv_block(filters[3], filters[4])\n\n        self.Up5 = up_conv(filters[4], filters[3])\n        self.Up_conv5 = conv_block(filters[4], filters[3])\n\n        self.Up4 = up_conv(filters[3], filters[2])\n        self.Up_conv4 = conv_block(filters[3], filters[2])\n\n        self.Up3 = up_conv(filters[2], filters[1])\n        self.Up_conv3 = conv_block(filters[2], filters[1])\n\n        self.Up2 = up_conv(filters[1], filters[0])\n        self.Up_conv2 = conv_block(filters[1], filters[0])\n\n        self.Conv = nn.Conv2d(filters[0], out_ch, kernel_size=1, stride=1, padding=0)\n\n        self.active = torch.nn.Sigmoid()\n\n    def forward(self, x):\n\n        e1 = self.Conv1(x)\n\n        e2 = self.Maxpool1(e1)\n        e2 = self.Conv2(e2)\n\n        e3 = self.Maxpool2(e2)\n        e3 = self.Conv3(e3)\n\n        e4 = self.Maxpool3(e3)\n        e4 = self.Conv4(e4)\n\n        e5 = self.Maxpool4(e4)\n        e5 = self.Conv5(e5)\n\n        d5 = self.Up5(e5)\n        d5 = torch.cat((e4, d5), dim=1)\n\n        d5 = self.Up_conv5(d5)\n\n        d4 = self.Up4(d5)\n        d4 = torch.cat((e3, d4), dim=1)\n        d4 = self.Up_conv4(d4)\n\n        d3 = self.Up3(d4)\n        d3 = torch.cat((e2, d3), dim=1)\n        d3 = self.Up_conv3(d3)\n\n        d2 = self.Up2(d3)\n        d2 = torch.cat((e1, d2), dim=1)\n        d2 = self.Up_conv2(d2)\n\n        out = self.Conv(d2)\n        out = self.active(out)\n\n        return out","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# set_seed(21)\nmodel2 = U_Net(3, 1).to(device)\noptimizer = optim.Adam(model2.parameters(), lr=0.01)\ncriterion = nn.BCELoss()\ntrain(model2, optimizer, criterion, dl_train, dl_test)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load the latest model\nmodel2.load_state_dict(torch.load('model.pt'))\nmetrics = eval_loop(model2, criterion, dl_test)\n\nprint('accuracy:', metrics['accuracy'])\nprint('f1 macro:', metrics['f1_macro'])\nprint('test loss:', metrics['loss'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Attention Unet","metadata":{}},{"cell_type":"code","source":"class Attention_block(nn.Module):\n    \"\"\"\n    Attention Block\n    \"\"\"\n\n    def __init__(self, F_g, F_l, F_int):\n        super(Attention_block, self).__init__()\n\n        self.W_g = nn.Sequential(\n            nn.Conv2d(F_l, F_int, kernel_size=1, stride=1, padding=0, bias=True),\n            nn.BatchNorm2d(F_int)\n        )\n\n        self.W_x = nn.Sequential(\n            nn.Conv2d(F_g, F_int, kernel_size=1, stride=1, padding=0, bias=True),\n            nn.BatchNorm2d(F_int)\n        )\n\n        self.psi = nn.Sequential(\n            nn.Conv2d(F_int, 1, kernel_size=1, stride=1, padding=0, bias=True),\n            nn.BatchNorm2d(1),\n            nn.Sigmoid()\n        )\n\n        self.relu = nn.ReLU(inplace=True)\n\n    def forward(self, g, x):\n        g1 = self.W_g(g)\n        x1 = self.W_x(x)\n        psi = self.relu(g1 + x1)\n        psi = self.psi(psi)\n        out = x * psi\n        return out\n\n\nclass AttU_Net(nn.Module):\n    \"\"\"\n    Attention Unet implementation\n    Paper: https://arxiv.org/abs/1804.03999\n    \"\"\"\n    def __init__(self, img_ch=3, output_ch=1):\n        super(AttU_Net, self).__init__()\n\n        n1 = 64\n        filters = [n1, n1 * 2, n1 * 4, n1 * 8, n1 * 16]\n\n        self.Maxpool1 = nn.MaxPool2d(kernel_size=2, stride=2)\n        self.Maxpool2 = nn.MaxPool2d(kernel_size=2, stride=2)\n        self.Maxpool3 = nn.MaxPool2d(kernel_size=2, stride=2)\n        self.Maxpool4 = nn.MaxPool2d(kernel_size=2, stride=2)\n\n        self.Conv1 = conv_block(img_ch, filters[0])\n        self.Conv2 = conv_block(filters[0], filters[1])\n        self.Conv3 = conv_block(filters[1], filters[2])\n        self.Conv4 = conv_block(filters[2], filters[3])\n        self.Conv5 = conv_block(filters[3], filters[4])\n\n        self.Up5 = up_conv(filters[4], filters[3])\n        self.Att5 = Attention_block(F_g=filters[3], F_l=filters[3], F_int=filters[2])\n        self.Up_conv5 = conv_block(filters[4], filters[3])\n\n        self.Up4 = up_conv(filters[3], filters[2])\n        self.Att4 = Attention_block(F_g=filters[2], F_l=filters[2], F_int=filters[1])\n        self.Up_conv4 = conv_block(filters[3], filters[2])\n\n        self.Up3 = up_conv(filters[2], filters[1])\n        self.Att3 = Attention_block(F_g=filters[1], F_l=filters[1], F_int=filters[0])\n        self.Up_conv3 = conv_block(filters[2], filters[1])\n\n        self.Up2 = up_conv(filters[1], filters[0])\n        self.Att2 = Attention_block(F_g=filters[0], F_l=filters[0], F_int=32)\n        self.Up_conv2 = conv_block(filters[1], filters[0])\n\n        self.Conv = nn.Conv2d(filters[0], output_ch, kernel_size=1, stride=1, padding=0)\n\n        self.active = torch.nn.Sigmoid()\n\n\n    def forward(self, x):\n\n        e1 = self.Conv1(x)\n\n        e2 = self.Maxpool1(e1)\n        e2 = self.Conv2(e2)\n\n        e3 = self.Maxpool2(e2)\n        e3 = self.Conv3(e3)\n\n        e4 = self.Maxpool3(e3)\n        e4 = self.Conv4(e4)\n\n        e5 = self.Maxpool4(e4)\n        e5 = self.Conv5(e5)\n\n        #print(x5.shape)\n        d5 = self.Up5(e5)\n        #print(d5.shape)\n        x4 = self.Att5(g=d5, x=e4)\n        d5 = torch.cat((x4, d5), dim=1)\n        d5 = self.Up_conv5(d5)\n\n        d4 = self.Up4(d5)\n        x3 = self.Att4(g=d4, x=e3)\n        d4 = torch.cat((x3, d4), dim=1)\n        d4 = self.Up_conv4(d4)\n\n        d3 = self.Up3(d4)\n        x2 = self.Att3(g=d3, x=e2)\n        d3 = torch.cat((x2, d3), dim=1)\n        d3 = self.Up_conv3(d3)\n\n        d2 = self.Up2(d3)\n        x1 = self.Att2(g=d2, x=e1)\n        d2 = torch.cat((x1, d2), dim=1)\n        d2 = self.Up_conv2(d2)\n\n        out = self.Conv(d2)\n#         print(out.shape)\n\n        out = self.active(out)\n\n        return out","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# set_seed(21)\nmodel3 = AttU_Net(3, 1).to(device)\noptimizer = optim.Adam(model3.parameters(), lr=0.01)\ncriterion = nn.BCELoss()\ntrain(model3, optimizer, criterion, dl_train, dl_test)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load the latest model\nmodel3.load_state_dict(torch.load('model.pt'))\nmetrics = eval_loop(model3, criterion, dl_test)\n\nprint('accuracy:', metrics['accuracy'])\nprint('f1 macro:', metrics['f1_macro'])\nprint('test loss:', metrics['loss'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **comparison of 3 supervised learning methods**","metadata":{}},{"cell_type":"code","source":"batchs = next(iter(dl_train))\nimages, masks = batchs\nim=images\nk=11\nimages = images.to(device)\nplt.figure(figsize=(20, 20))\nout1=model1(images)\nout1=out1.cpu().detach()\nout2=model2(images)\nout2=out2.cpu().detach()\nout3=model3(images)\nout3=out3.cpu().detach()\n\nplt.subplot(1, 3, 1)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(im[k][1])\nplt.title('Original image')\n\nplt.subplot( 1, 3, 2)\nplt.xticks([])\nplt.yticks([])\n\nplt.imshow(masks[k][0])\nplt.title('Mask (Ground Truth)')\n\nplt.subplot( 1, 3, 3)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(im[k][1])\nplt.imshow(masks[k][0],alpha=0.2)\nplt.title('Both')\nplt.tight_layout()\nplt.show()\n\nplt.figure(figsize=(20, 20))\nplt.subplot( 1, 3, 1)\nplt.xticks([])\nplt.yticks([])\n# plt.imshow(im[k][1])\nplt.imshow(out1[k][0])\nplt.title('Mask predicted by CNN')\n\nplt.subplot( 1, 3, 2)\nplt.xticks([])\nplt.yticks([])\n# plt.imshow(im[k][1])\nplt.imshow(out2[k][0])\nplt.title('Mask predicted by UNet')\n\nplt.subplot( 1, 3, 3)\nplt.xticks([])\nplt.yticks([])\n# plt.imshow(im[k][1])\nplt.imshow(out3[k][0])\nplt.title('Mask predicted by AttUNet')\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}