{"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","_kg_hide-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-12-01T11:42:03.631959Z","iopub.execute_input":"2021-12-01T11:42:03.632324Z","iopub.status.idle":"2021-12-01T11:42:09.057450Z","shell.execute_reply.started":"2021-12-01T11:42:03.632255Z","shell.execute_reply":"2021-12-01T11:42:09.056579Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Importing the required libraries**","metadata":{}},{"cell_type":"code","source":"import 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\n\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","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:09.059417Z","iopub.execute_input":"2021-12-01T11:42:09.059677Z","iopub.status.idle":"2021-12-01T11:42:13.069732Z","shell.execute_reply.started":"2021-12-01T11:42:09.059639Z","shell.execute_reply":"2021-12-01T11:42:13.068908Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_train = pd.read_csv('../input/sartorius-cell-instance-segmentation/train.csv')","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:13.070978Z","iopub.execute_input":"2021-12-01T11:42:13.072984Z","iopub.status.idle":"2021-12-01T11:42:13.577297Z","shell.execute_reply.started":"2021-12-01T11:42:13.072951Z","shell.execute_reply":"2021-12-01T11:42:13.576420Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_train.head(10)","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:13.579472Z","iopub.execute_input":"2021-12-01T11:42:13.579935Z","iopub.status.idle":"2021-12-01T11:42:13.603769Z","shell.execute_reply.started":"2021-12-01T11:42:13.579896Z","shell.execute_reply":"2021-12-01T11:42:13.603100Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Visualization of the images**","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,0]}.png')\n        plt.imshow(img, cmap='cividis')\n\nimshow()","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:13.605014Z","iopub.execute_input":"2021-12-01T11:42:13.605408Z","iopub.status.idle":"2021-12-01T11:42:14.739123Z","shell.execute_reply.started":"2021-12-01T11:42:13.605368Z","shell.execute_reply":"2021-12-01T11:42:14.738468Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(20,20))\ncurrent_axis = plt.gca()\nplt.grid(False)\nplt.xticks([])\nplt.yticks([])\nimg=mpimg.imread(f'../input/sartorius-cell-instance-segmentation/train/{data_train.iloc[0,0]}.png')\nplt.imshow(img,cmap='bone')\n","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:14.740158Z","iopub.execute_input":"2021-12-01T11:42:14.740508Z","iopub.status.idle":"2021-12-01T11:42:15.518973Z","shell.execute_reply.started":"2021-12-01T11:42:14.740475Z","shell.execute_reply":"2021-12-01T11:42:15.518335Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def decode_rle_mask(rle_mask, shape):\n\n    rle_mask = rle_mask.split()\n    starts, lengths = [np.asarray(x, dtype=int) for x in (rle_mask[0:][::2], rle_mask[1:][::2])]\n    starts -= 1\n    ends = starts + lengths\n\n    mask = np.zeros((shape[0] * shape[1]), dtype=np.uint8)\n    for start, end in zip(starts, ends):\n        mask[start:end] = 1\n\n    mask = mask.reshape(shape[0], shape[1])\n    return mask","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:15.520142Z","iopub.execute_input":"2021-12-01T11:42:15.520654Z","iopub.status.idle":"2021-12-01T11:42:15.528594Z","shell.execute_reply.started":"2021-12-01T11:42:15.520617Z","shell.execute_reply":"2021-12-01T11:42:15.527742Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def visualize_image(df, image_id):   \n    image_path = df.loc[df['id'] == image_id, 'id'].values[0]\n    cell_type = df.loc[df['id'] == image_id, 'cell_type'].values[0]\n    plate_time = df.loc[df['id'] == image_id, 'plate_time'].values[0]\n    sample_date = df.loc[df['id'] == image_id, 'sample_date'].values[0]\n    sample_id = df.loc[df['id'] == image_id, 'sample_id'].values[0]\n\n    image = cv2.imread(f'../input/sartorius-cell-instance-segmentation/train/{image_path}.png')\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n\n    fig, axes = plt.subplots(figsize=(20, 20), ncols=2)\n    fig.tight_layout(pad=5.0)\n    \n    axes[0].imshow(image, cmap='gray')\n    masks = []\n    for mask in df.loc[df['id'] == image_id, 'annotation'].values:\n        decoded_mask = decode_rle_mask(rle_mask=mask, shape=image.shape)\n        masks.append(decoded_mask)\n    mask = np.stack(masks)\n    mask = np.any(mask == 1, axis=0)\n    axes[1].imshow(image, cmap='gray')\n    axes[1].imshow(mask, alpha=0.4)\n\n    for i in range(2):\n        axes[i].set_xlabel('')\n        axes[i].set_ylabel('')\n        axes[i].tick_params(axis='x', labelsize=10, pad=10)\n        axes[i].tick_params(axis='y', labelsize=10, pad=10)\n        \n    axes[0].set_title(f'{cell_type}', fontsize=10, pad=12)\n    axes[1].set_title('Segmentation Mask', fontsize=10, pad=12)\n    plt.show()\n    plt.close(fig)\n","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:15.529960Z","iopub.execute_input":"2021-12-01T11:42:15.530223Z","iopub.status.idle":"2021-12-01T11:42:15.546079Z","shell.execute_reply.started":"2021-12-01T11:42:15.530191Z","shell.execute_reply":"2021-12-01T11:42:15.545242Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"select_image_ids = []\nselect_image_ids.append(data_train.loc[data_train['cell_type'] == 'shsy5y', 'id'].sample(1).to_list()[0])\nselect_image_ids.append(data_train.loc[data_train['cell_type'] == 'shsy5y', 'id'].sample(2).to_list()[0])\nselect_image_ids.append(data_train.loc[data_train['cell_type'] == 'shsy5y', 'id'].sample(3).to_list()[0])\nselect_image_ids.append(data_train.loc[data_train['cell_type'] == 'cort', 'id'].sample(1).to_list()[0])\nselect_image_ids.append(data_train.loc[data_train['cell_type'] == 'cort', 'id'].sample(2).to_list()[0])\nselect_image_ids.append(data_train.loc[data_train['cell_type'] == 'cort', 'id'].sample(3).to_list()[0])\nselect_image_ids.append(data_train.loc[data_train['cell_type'] == 'astro', 'id'].sample(1).to_list()[0])\nselect_image_ids.append(data_train.loc[data_train['cell_type'] == 'astro', 'id'].sample(2).to_list()[0])\nselect_image_ids.append(data_train.loc[data_train['cell_type'] == 'astro', 'id'].sample(3).to_list()[0])\n\nfor image_id in select_image_ids:\n     visualize_image(df=data_train, image_id=image_id)","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:15.547770Z","iopub.execute_input":"2021-12-01T11:42:15.548281Z","iopub.status.idle":"2021-12-01T11:42:23.921337Z","shell.execute_reply.started":"2021-12-01T11:42:15.548249Z","shell.execute_reply":"2021-12-01T11:42:23.919679Z"},"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-01T11:42:23.925026Z","iopub.execute_input":"2021-12-01T11:42:23.925342Z","iopub.status.idle":"2021-12-01T11:42:24.236772Z","shell.execute_reply.started":"2021-12-01T11:42:23.925306Z","shell.execute_reply":"2021-12-01T11:42:24.235584Z"},"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)\n\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)","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:24.238439Z","iopub.execute_input":"2021-12-01T11:42:24.238769Z","iopub.status.idle":"2021-12-01T11:42:24.249337Z","shell.execute_reply.started":"2021-12-01T11:42:24.238721Z","shell.execute_reply":"2021-12-01T11:42:24.248271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Dataset class**","metadata":{}},{"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[iperm[:num_train_samples]]\n        else:\n             self.image_ids = all_image_ids[iperm[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":{"execution":{"iopub.status.busy":"2021-12-01T11:42:24.251209Z","iopub.execute_input":"2021-12-01T11:42:24.251677Z","iopub.status.idle":"2021-12-01T11:42:24.268917Z","shell.execute_reply.started":"2021-12-01T11:42:24.251594Z","shell.execute_reply":"2021-12-01T11:42:24.267883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Data Loaders**","metadata":{}},{"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":{"execution":{"iopub.status.busy":"2021-12-01T11:42:24.270591Z","iopub.execute_input":"2021-12-01T11:42:24.271326Z","iopub.status.idle":"2021-12-01T11:42:24.286572Z","shell.execute_reply.started":"2021-12-01T11:42:24.271287Z","shell.execute_reply":"2021-12-01T11:42:24.285784Z"},"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":{"execution":{"iopub.status.busy":"2021-12-01T11:42:24.288227Z","iopub.execute_input":"2021-12-01T11:42:24.288579Z","iopub.status.idle":"2021-12-01T11:42:24.302427Z","shell.execute_reply.started":"2021-12-01T11:42:24.288534Z","shell.execute_reply":"2021-12-01T11:42:24.301419Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Visualization of the images and masks**","metadata":{}},{"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)}\")\n\nplt.figure(figsize=(20, 20))\n        \nplt.subplot(1, 3, 1)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(images[1][1])\nplt.title('Original image')\n\nplt.subplot( 1, 3, 2)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(masks[1][0])\nplt.title('Mask')\n\nplt.subplot( 1, 3, 3)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(images[1][1])\nplt.imshow(masks[1][0],alpha=0.2)\nplt.title('Both')\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:24.304117Z","iopub.execute_input":"2021-12-01T11:42:24.304808Z","iopub.status.idle":"2021-12-01T11:42:32.661396Z","shell.execute_reply.started":"2021-12-01T11:42:24.304763Z","shell.execute_reply":"2021-12-01T11:42:32.660697Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Train the model**","metadata":{}},{"cell_type":"code","source":"class DoubleConv(nn.Module):\n    def __init__(self, in_ch, out_ch):\n        super(DoubleConv, self).__init__()\n        self.conv = nn.Sequential( \n            nn.Conv2d(in_ch, out_ch, kernel_size=3, stride=1, padding=1),\n            nn.BatchNorm2d(out_ch),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(out_ch, out_ch, kernel_size=3, stride=1, padding=1),\n            nn.BatchNorm2d(out_ch),\n            nn.ReLU(inplace=True)\n         )\n    def forward(self, x):\n        x = self.conv(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:32.663143Z","iopub.execute_input":"2021-12-01T11:42:32.663580Z","iopub.status.idle":"2021-12-01T11:42:32.671542Z","shell.execute_reply.started":"2021-12-01T11:42:32.663543Z","shell.execute_reply":"2021-12-01T11:42:32.670666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class InConv(nn.Module):\n    def __init__(self, in_ch, out_ch):\n        super(InConv, self).__init__()\n        self.conv = DoubleConv(in_ch, out_ch)\n    def forward(self, x):\n        x = self.conv(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:32.672888Z","iopub.execute_input":"2021-12-01T11:42:32.673310Z","iopub.status.idle":"2021-12-01T11:42:32.683303Z","shell.execute_reply.started":"2021-12-01T11:42:32.673274Z","shell.execute_reply":"2021-12-01T11:42:32.682427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Down(nn.Module):\n    def __init__(self, in_ch, out_ch):\n        super(Down, self).__init__()\n        self.mpconv = nn.Sequential( \n            nn.MaxPool2d(2,2),\n            DoubleConv(in_ch, out_ch)\n         )\n    def forward(self, x):\n        x = self.mpconv(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:32.684914Z","iopub.execute_input":"2021-12-01T11:42:32.685427Z","iopub.status.idle":"2021-12-01T11:42:32.693135Z","shell.execute_reply.started":"2021-12-01T11:42:32.685390Z","shell.execute_reply":"2021-12-01T11:42:32.692394Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Up(nn.Module):\n    def __init__(self, in_ch, out_ch):\n        super(Up, self).__init__()\n        self.up = nn.ConvTranspose2d(in_ch // 2, in_ch // 2, kernel_size=2, stride=2)\n        self.conv = DoubleConv(in_ch, out_ch)\n    def forward(self, x1, x2):\n        x1 = self.up(x1)\n        x = torch.cat([x2, x1], dim=1)\n        x = self.conv(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:32.694464Z","iopub.execute_input":"2021-12-01T11:42:32.694961Z","iopub.status.idle":"2021-12-01T11:42:32.703372Z","shell.execute_reply.started":"2021-12-01T11:42:32.694915Z","shell.execute_reply":"2021-12-01T11:42:32.702426Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class OutConv(nn.Module):\n    def __init__(self, in_ch, out_ch):\n        super(OutConv, self).__init__()\n        self.conv = nn.Conv2d(in_ch, out_ch, 1)\n        self.sigmoid = nn.Sigmoid()\n    def forward(self, x):\n        x = self.conv(x)\n        x = self.sigmoid(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:32.704805Z","iopub.execute_input":"2021-12-01T11:42:32.705376Z","iopub.status.idle":"2021-12-01T11:42:32.716140Z","shell.execute_reply.started":"2021-12-01T11:42:32.705340Z","shell.execute_reply":"2021-12-01T11:42:32.715372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class UNet(nn.Module):\n    def __init__(self, in_channels, num_classes):\n        super(UNet, self).__init__()\n        self.inc = InConv(in_channels, 64)\n        self.down1 = Down(64, 128)\n        self.down2 = Down(128, 256)\n        self.down3 = Down(256, 512)\n        self.down4 = Down(512, 512)\n        self.up1 = Up(1024, 256)\n        self.up2 = Up(512, 128)\n        self.up3 = Up(256, 64)\n        self.up4 = Up(128, 64)\n        self.outc = OutConv(64, num_classes)\n    def forward(self, x):\n        x1 = self.inc(x)\n        x2 = self.down1(x1)\n        x3 = self.down2(x2)\n        x4 = self.down3(x3)\n        x5 = self.down4(x4)\n        x = self.up1(x5, x4)\n        x = self.up2(x, x3)\n        x = self.up3(x, x2)\n        x = self.up4(x, x1)\n        x = self.outc(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:32.718045Z","iopub.execute_input":"2021-12-01T11:42:32.718221Z","iopub.status.idle":"2021-12-01T11:42:32.729423Z","shell.execute_reply.started":"2021-12-01T11:42:32.718199Z","shell.execute_reply":"2021-12-01T11:42:32.728640Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:32.731037Z","iopub.execute_input":"2021-12-01T11:42:32.731588Z","iopub.status.idle":"2021-12-01T11:42:32.739595Z","shell.execute_reply.started":"2021-12-01T11:42:32.731545Z","shell.execute_reply":"2021-12-01T11:42:32.738690Z"},"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":{"execution":{"iopub.status.busy":"2021-12-01T11:42:32.741218Z","iopub.execute_input":"2021-12-01T11:42:32.741799Z","iopub.status.idle":"2021-12-01T11:42:32.750601Z","shell.execute_reply.started":"2021-12-01T11:42:32.741734Z","shell.execute_reply":"2021-12-01T11:42:32.749727Z"},"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 = [], []\n        pbar = tqdm(eval_loader, desc='Iterating over evaluation 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]\n            # calculate predictions using output\n            predicted = (out > 0.5).float()\n            predicted = predicted.view(-1).cpu().numpy()\n            labels = masks.view(-1).cpu().numpy()\n            accuracy.append(accuracy_score(labels, predicted))\n            f1_scores.append(f1_score(labels, predicted))\n    acc = sum(accuracy)/len(accuracy)\n    f1 = sum(f1_scores)/len(f1_scores)\n    running_loss /= len(eval_loader.sampler)\n    return {\n        'accuracy':acc,\n        'f1_macro':f1, \n        'loss':running_loss}","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:32.752231Z","iopub.execute_input":"2021-12-01T11:42:32.752773Z","iopub.status.idle":"2021-12-01T11:42:32.764367Z","shell.execute_reply.started":"2021-12-01T11:42:32.752723Z","shell.execute_reply":"2021-12-01T11:42:32.763591Z"},"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=30, \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(print_string)\n\n\n        # save the model \n        if metrics[\"loss\"] <= valid_loss_min:\n            torch.save(model.state_dict(), 'UNet.pt')\n            valid_loss_min = metrics[\"loss\"]","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:32.765903Z","iopub.execute_input":"2021-12-01T11:42:32.766452Z","iopub.status.idle":"2021-12-01T11:42:32.775651Z","shell.execute_reply.started":"2021-12-01T11:42:32.766409Z","shell.execute_reply":"2021-12-01T11:42:32.774921Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# set_seed(21)\nmodel = UNet(3, 1).to(device)\noptimizer = optim.Adam(model.parameters(), lr=0.01)\ncriterion = nn.BCELoss()","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:32.777082Z","iopub.execute_input":"2021-12-01T11:42:32.777586Z","iopub.status.idle":"2021-12-01T11:42:33.023349Z","shell.execute_reply.started":"2021-12-01T11:42:32.777550Z","shell.execute_reply":"2021-12-01T11:42:33.022466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train(model, optimizer, criterion, dl_train, dl_test)","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:33.024800Z","iopub.execute_input":"2021-12-01T11:42:33.025195Z","iopub.status.idle":"2021-12-01T11:42:33.033624Z","shell.execute_reply.started":"2021-12-01T11:42:33.025159Z","shell.execute_reply":"2021-12-01T11:42:33.032665Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load the latest model\nmodel.load_state_dict(torch.load('../input/cell-segment-weights/UNet.pt'))\nmetrics = eval_loop(model, criterion, dl_test)\nprint('accuracy:', metrics['accuracy'])\nprint('f1 macro:', metrics['f1_macro'])\nprint('test loss:', metrics['loss'])","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:33.039850Z","iopub.execute_input":"2021-12-01T11:42:33.040317Z","iopub.status.idle":"2021-12-01T11:42:44.909940Z","shell.execute_reply.started":"2021-12-01T11:42:33.040268Z","shell.execute_reply":"2021-12-01T11:42:44.908854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Visualisation of predicted masks**","metadata":{}},{"cell_type":"code","source":"with torch.no_grad():\n    outputs = []\n    ground_trues = []\n    imgs_test = []\n    pbar = tqdm(dl_test, desc='Iterating over evaluation 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        predicted = (out > 0.5).float()\n#         print(predicted.shape)\n        outputs.extend(predicted)\n        ground_trues.extend(masks)\n        imgs_test.extend(imgs)      ","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:44.912511Z","iopub.execute_input":"2021-12-01T11:42:44.913051Z","iopub.status.idle":"2021-12-01T11:42:49.309778Z","shell.execute_reply.started":"2021-12-01T11:42:44.913004Z","shell.execute_reply":"2021-12-01T11:42:49.308819Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"imgs_test[0].shape","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:49.311894Z","iopub.execute_input":"2021-12-01T11:42:49.312623Z","iopub.status.idle":"2021-12-01T11:42:49.320671Z","shell.execute_reply.started":"2021-12-01T11:42:49.312575Z","shell.execute_reply":"2021-12-01T11:42:49.319970Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ground_trues[0].shape","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:49.321757Z","iopub.execute_input":"2021-12-01T11:42:49.322468Z","iopub.status.idle":"2021-12-01T11:42:49.332440Z","shell.execute_reply.started":"2021-12-01T11:42:49.322430Z","shell.execute_reply":"2021-12-01T11:42:49.331741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"outputs[0].shape","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:49.334461Z","iopub.execute_input":"2021-12-01T11:42:49.335024Z","iopub.status.idle":"2021-12-01T11:42:49.342163Z","shell.execute_reply.started":"2021-12-01T11:42:49.334987Z","shell.execute_reply":"2021-12-01T11:42:49.341353Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(len(imgs_test)):\n    plt.figure(figsize=(40, 20))\n        \n    plt.subplot(1, 3, 1)\n    plt.xticks([])\n    plt.yticks([])\n    plt.imshow(imgs_test[i][0].cpu().numpy())\n    plt.title('Original image')\n\n    plt.subplot( 1, 3, 2)\n    plt.xticks([])\n    plt.yticks([])\n    plt.imshow(ground_trues[i][0].cpu().numpy())\n    plt.title('Mask')\n\n\n    plt.subplot(1, 3, 3)\n    plt.xticks([])\n    plt.yticks([])\n    plt.imshow(outputs[i][0].cpu().numpy())\n    plt.title('Predicted')\n    plt.tight_layout()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:42:49.343315Z","iopub.execute_input":"2021-12-01T11:42:49.343712Z","iopub.status.idle":"2021-12-01T11:43:32.046572Z","shell.execute_reply.started":"2021-12-01T11:42:49.343675Z","shell.execute_reply":"2021-12-01T11:43:32.045773Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Make submission**","metadata":{}},{"cell_type":"code","source":"def rle_encoding(x):\n    dots = np.where(x.flatten() == 1)[0]\n    run_lengths = []\n    prev = -2\n    for b in dots:\n        if (b>prev+1): run_lengths.extend((b + 1, 0))\n        run_lengths[-1] += 1\n        prev = b\n    return ' '.join(map(str, run_lengths))\n\n\ndef remove_overlapping_pixels(mask, other_masks):\n    for other_mask in other_masks:\n        if np.sum(np.logical_and(mask, other_mask)) > 0:\n            mask[np.logical_and(mask, other_mask)] = 0\n    return mask","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:43:32.047947Z","iopub.execute_input":"2021-12-01T11:43:32.048707Z","iopub.status.idle":"2021-12-01T11:43:32.056366Z","shell.execute_reply.started":"2021-12-01T11:43:32.048666Z","shell.execute_reply":"2021-12-01T11:43:32.055638Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"id_1 = '7ae19de7bc2a'\nid_2 = 'd48ec7815252'\nid_3 = 'd8bfd1dafdc4'\nimage_ids = []\nimage_ids.append(id_1)\nimage_ids.append(id_2)\nimage_ids.append(id_3)","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:43:32.057884Z","iopub.execute_input":"2021-12-01T11:43:32.058413Z","iopub.status.idle":"2021-12-01T11:43:32.067043Z","shell.execute_reply.started":"2021-12-01T11:43:32.058374Z","shell.execute_reply":"2021-12-01T11:43:32.066372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CellDatasetTest(Dataset):\n    def __init__(self):\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.base_path = '../input/sartorius-cell-instance-segmentation/test'\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                                   ])\n        \n        # Split train and val set\n        self.image_ids = np.array(image_ids)\n        \n\n    def __getitem__(self, idx: int):\n\n        image_id = self.image_ids[idx]\n\n\n        # Read image\n        image_path = os.path.join(self.base_path, image_id + \".png\")\n        image = cv2.imread(image_path)\n\n\n        augmented = self.transforms(image=image, target=None)\n        image = augmented['image']\n        return np.moveaxis(np.array(image),2,0)\n\n\n    def __len__(self):\n        return len(self.image_ids)","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:43:32.068096Z","iopub.execute_input":"2021-12-01T11:43:32.068309Z","iopub.status.idle":"2021-12-01T11:43:32.093674Z","shell.execute_reply.started":"2021-12-01T11:43:32.068276Z","shell.execute_reply":"2021-12-01T11:43:32.092602Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_val = CellDatasetTest()","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:43:32.098113Z","iopub.execute_input":"2021-12-01T11:43:32.098448Z","iopub.status.idle":"2021-12-01T11:43:32.107401Z","shell.execute_reply.started":"2021-12-01T11:43:32.098411Z","shell.execute_reply":"2021-12-01T11:43:32.106616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ds_val.__getitem__(0)","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:43:32.112159Z","iopub.execute_input":"2021-12-01T11:43:32.113952Z","iopub.status.idle":"2021-12-01T11:43:32.121279Z","shell.execute_reply.started":"2021-12-01T11:43:32.113914Z","shell.execute_reply":"2021-12-01T11:43:32.120233Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nfrom torchvision.transforms import functional as F","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:43:32.123458Z","iopub.execute_input":"2021-12-01T11:43:32.124363Z","iopub.status.idle":"2021-12-01T11:43:32.139259Z","shell.execute_reply.started":"2021-12-01T11:43:32.124299Z","shell.execute_reply":"2021-12-01T11:43:32.137516Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.eval();\n\nsubmission = []\npbar = tqdm(ds_val, desc='Iterating over evaluation data')\nfor im in range(len(image_ids)):\n    image_id = image_ids[im]\n    for sample in pbar:\n# for  in ds_val:\n\n    \n#     print(image_ids[im])\n        img =  sample\n    \n#     print(image_id)\n        with torch.no_grad():\n            result = model(imgs.to(device))\n    \n        previous_masks = []\n        for i, mask in enumerate(result):\n        \n \n            mask = mask.cpu().numpy()\n        # Keep only highly likely pixels\n            binary_mask = mask > 0.5\n            binary_mask = remove_overlapping_pixels(binary_mask, previous_masks)\n            previous_masks.append(binary_mask)\n            rle = rle_encoding(binary_mask)\n            submission.append((image_id, rle))\n        \n#             im+=1\n    \n    # Add empty prediction if no RLE was generated for this image\n        all_images_ids = [image_id for image_id, rle in submission]\n        if image_id not in all_images_ids:\n            submission.append((image_id, \"\"))","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:52:51.530135Z","iopub.execute_input":"2021-12-01T11:52:51.530965Z","iopub.status.idle":"2021-12-01T11:52:51.749569Z","shell.execute_reply.started":"2021-12-01T11:52:51.530919Z","shell.execute_reply":"2021-12-01T11:52:51.748880Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# submission","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:51:12.130742Z","iopub.execute_input":"2021-12-01T11:51:12.131416Z","iopub.status.idle":"2021-12-01T11:51:12.137116Z","shell.execute_reply.started":"2021-12-01T11:51:12.131379Z","shell.execute_reply":"2021-12-01T11:51:12.136383Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_sub = pd.DataFrame(submission, columns=['id', 'predicted'])\ndf_sub.to_csv(\"submission.csv\", index=False)\ndf_sub","metadata":{"execution":{"iopub.status.busy":"2021-12-01T11:52:57.738803Z","iopub.execute_input":"2021-12-01T11:52:57.739396Z","iopub.status.idle":"2021-12-01T11:52:57.752315Z","shell.execute_reply.started":"2021-12-01T11:52:57.739359Z","shell.execute_reply":"2021-12-01T11:52:57.751529Z"},"trusted":true},"execution_count":null,"outputs":[]}]}