{"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":"<h1><center>Sartorius: Complete UNet Understanding</center></h1>\n                                                      \n<center><img src = \"https://www.innovationnewsnetwork.com/wp-content/uploads/2021/02/%C2%A9-iStock-peterschreiber.media_-696x392.jpg\" width = \"750\" height = \"500\"/></center>                                                                            ","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"markdown","source":"<h2 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style='background:orange; border:0; color:white' role=\"tab\" aria-controls=\"home\"><center>Contents</center></h2>","metadata":{}},{"cell_type":"markdown","source":"1. [Competition Overview](#competition-overview)    \n2. [Libraries](#libraries)  \n3. [Weights and Biases](#weights-and-biases)  \n4. [Global Config](#global-config)  \n5. [Load Datasets](#load-datasets)\n6. [U-Net Model](#unet-model)\n7. [References](#references)  ","metadata":{}},{"cell_type":"markdown","source":"<div class=\"list-group\" id=\"list-tab\" role=\"tablist\">\n<h3 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style='background:maroon; border:0; color:white' role=\"tab\" aria-controls=\"home\"><center>If you find this notebook useful, do give me an upvote, it helps to keep up my motivation. This notebook will be updated frequently so keep checking for furthur developments.</center></h3>","metadata":{}},{"cell_type":"markdown","source":"<a id=\"competition-overview\"></a>\n<div class=\"list-group\" id=\"list-tab\" role=\"tablist\">\n<h2 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style='background:orange; border:0; color:white' role=\"tab\" aria-controls=\"home\"><center>Competition Overview</center></h2>","metadata":{}},{"cell_type":"markdown","source":"## **<span style=\"color:orange;\">Description</span>**\n\n\nIn this competition, you’ll detect and delineate distinct objects of interest in biological images depicting neuronal cell types commonly used in the study of neurological disorders. More specifically, you'll use phase contrast microscopy images to train and test your model for instance segmentation of neuronal cells. Successful models will do this with a high level of accuracy.\n\nIf successful, you'll help further research in neurobiology thanks to the collection of robust quantitative data. Researchers may be able to use this to more easily measure the effects of disease and treatment conditions on neuronal cells. As a result, new drugs could be discovered to treat the millions of people with these leading causes of death and disability.\n\n---","metadata":{}},{"cell_type":"markdown","source":"## **<span style=\"color:orange;\">Evaluation Metric</span>**\n\nThis competition is evaluated on the **mean average precision** at different intersection over union  thresholds. The IoU of a proposed set of object pixels and a set of true object pixels is calculated as:\n\n`IoU(A,B)= (A∩B)/(A∪B)`\n\n---","metadata":{}},{"cell_type":"markdown","source":"> The competition uses a couple of medical terms which many people will be unfamiliar with. To easen out the process I am providing the foundations of the mentioned diseases and proposed treatments to give a stronger domain understanding.","metadata":{}},{"cell_type":"markdown","source":"<a id=\"libraries\"></a>\n<div class=\"list-group\" id=\"list-tab\" role=\"tablist\">\n<h2 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style='background:orange; border:0; color:white' role=\"tab\" aria-controls=\"home\"><center>Libraries</center></h2>","metadata":{}},{"cell_type":"code","source":"%%capture\n!pip install ../input/segmentation-models-wheels/efficientnet_pytorch-0.6.3-py3-none-any.whl\n!pip install ../input/segmentation-models-wheels/pretrainedmodels-0.7.4-py3-none-any.whl\n!pip install ../input/segmentation-models-wheels/timm-0.3.2-py3-none-any.whl\n!pip install ../input/segmentation-models-wheels/segmentation_models_pytorch-0.1.3-py3-none-any.whl","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:32:02.233791Z","iopub.execute_input":"2021-11-04T08:32:02.234099Z","iopub.status.idle":"2021-11-04T08:32:33.189808Z","shell.execute_reply.started":"2021-11-04T08:32:02.234019Z","shell.execute_reply":"2021-11-04T08:32:33.188873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!mkdir -p /root/.cache/torch/hub/checkpoints/\n!cp ../input/pytorch-pretrained-image-models/resnet34.pth /root/.cache/torch/hub/checkpoints/resnet34-333f7ec4.pth","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:32:33.191795Z","iopub.execute_input":"2021-11-04T08:32:33.192055Z","iopub.status.idle":"2021-11-04T08:32:35.907631Z","shell.execute_reply.started":"2021-11-04T08:32:33.192019Z","shell.execute_reply":"2021-11-04T08:32:35.906690Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%sh\npip install -q --upgrade wandb\npip install -q timm","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-11-04T08:32:35.909461Z","iopub.execute_input":"2021-11-04T08:32:35.909739Z","iopub.status.idle":"2021-11-04T08:32:52.653363Z","shell.execute_reply.started":"2021-11-04T08:32:35.909700Z","shell.execute_reply":"2021-11-04T08:32:52.652487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import gc\nimport os\nimport pdb\nimport time\nimport glob\nimport sys\nimport cv2\nimport imageio\nimport joblib\nimport math\nimport random\nimport wandb\nimport math\n\nimport numpy as np\nimport pandas as pd\n\nimport plotly.express as px\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as patches\n\nplt.rcParams.update({'font.size': 18})\nplt.style.use('fivethirtyeight')\n\nimport seaborn as sns\nimport matplotlib\nfrom dask import bag, diagnostics \nfrom mpl_toolkits.mplot3d import Axes3D\n\nfrom termcolor import colored\n\nfrom tqdm.notebook import tqdm\n\n# import timm\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.nn import functional as F\nimport torch.backends.cudnn as cudnn\nfrom torch.optim.lr_scheduler import ReduceLROnPlateau\nfrom torch.utils.data import DataLoader, Dataset, sampler\n\nimport collections.abc as container_abcs\ntorch._six.container_abcs = container_abcs\nimport segmentation_models_pytorch as smp\n\nfrom sklearn.model_selection import KFold\n\nfrom albumentations import (HorizontalFlip, VerticalFlip, \n                            ShiftScaleRotate, Normalize, Resize, \n                            Compose, GaussNoise)\nfrom albumentations.pytorch import ToTensorV2\n\nimport warnings\nwarnings.simplefilter('ignore')\n\n# Activate pandas progress apply bar\ntqdm.pandas()","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:32:52.655235Z","iopub.execute_input":"2021-11-04T08:32:52.655538Z","iopub.status.idle":"2021-11-04T08:32:59.895592Z","shell.execute_reply.started":"2021-11-04T08:32:52.655500Z","shell.execute_reply":"2021-11-04T08:32:59.894816Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Wandb Login\nimport wandb\nwandb.login()","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:41:47.865857Z","iopub.execute_input":"2021-11-04T08:41:47.866684Z","iopub.status.idle":"2021-11-04T08:42:00.079026Z","shell.execute_reply.started":"2021-11-04T08:41:47.866642Z","shell.execute_reply":"2021-11-04T08:42:00.078309Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"weights-and-biases\"></a>\n<div class=\"list-group\" id=\"list-tab\" role=\"tablist\">\n<h2 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style='background:orange; border:0; color:white' role=\"tab\" aria-controls=\"home\"><center>Weights and Biases (W&B)</center></h2>","metadata":{}},{"cell_type":"markdown","source":"<center><img src = \"https://i.imgur.com/1sm6x8P.png\" width = \"750\" height = \"500\"/></center>  ","metadata":{}},{"cell_type":"markdown","source":"\n  \n \n  \n**Weights & Biases** is the machine learning platform for developers to build better models faster. \n\nYou can use W&B's lightweight, interoperable tools to \n- quickly track experiments, \n- version and iterate on datasets, \n- evaluate model performance, \n- reproduce models, \n- visualize results and spot regressions, \n- and share findings with colleagues. \n\nSet up W&B in 5 minutes, then quickly iterate on your machine learning pipeline with the confidence that your datasets and models are tracked and versioned in a reliable system of record.\n\nIn this notebook I will use Weights and Biases's amazing features to perform wonderful visualizations and logging seamlessly. ","metadata":{}},{"cell_type":"markdown","source":"<a id=\"global-config\"></a>\n<div class=\"list-group\" id=\"list-tab\" role=\"tablist\">\n<h2 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style='background:orange; border:0; color:white' role=\"tab\" aria-controls=\"home\"><center>Global Config</center></h2>","metadata":{}},{"cell_type":"code","source":"class config:\n    DIRECTORY_PATH = \"../input/sartorius-cell-instance-segmentation\"\n    TRAIN_CSV = DIRECTORY_PATH + \"/train.csv\"\n    TRAIN_PATH = DIRECTORY_PATH + \"/train\"\n    TEST_PATH = DIRECTORY_PATH + \"/test\"\n    TRAIN_SEMI_SUPERVISED_PATH = DIRECTORY_PATH + \"/train_semi_supervised\"\n    \n    SEED = 42\n    \n    RESNET_MEAN = (0.485, 0.456, 0.406)\n    RESNET_STD = (0.229, 0.224, 0.225)\n\n    # (336, 336)\n    IMAGE_RESIZE = (224, 224)\n\n    LEARNING_RATE = 5e-4\n    EPOCHS = 10","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:34:08.775138Z","iopub.execute_input":"2021-11-04T08:34:08.775437Z","iopub.status.idle":"2021-11-04T08:34:08.781974Z","shell.execute_reply.started":"2021-11-04T08:34:08.775386Z","shell.execute_reply":"2021-11-04T08:34:08.781268Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# wandb config\nWANDB_CONFIG = {\n     'competition': 'Sartorius', \n              '_wandb_kernel': 'neuracort'\n    }","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:32:59.922653Z","iopub.execute_input":"2021-11-04T08:32:59.923218Z","iopub.status.idle":"2021-11-04T08:32:59.933043Z","shell.execute_reply.started":"2021-11-04T08:32:59.923181Z","shell.execute_reply":"2021-11-04T08:32:59.932355Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def set_seed(seed=config.SEED):\n    random.seed(seed)\n    os.environ[\"PYTHONHASHSEED\"] = str(seed)\n    np.random.seed(seed)\n    \n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n    \nset_seed()","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:32:59.935612Z","iopub.execute_input":"2021-11-04T08:32:59.935884Z","iopub.status.idle":"2021-11-04T08:32:59.945823Z","shell.execute_reply.started":"2021-11-04T08:32:59.935850Z","shell.execute_reply":"2021-11-04T08:32:59.945156Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"load-datasets\"></a>\n<div class=\"list-group\" id=\"list-tab\" role=\"tablist\">\n<h2 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style='background:orange; border:0; color:white' role=\"tab\" aria-controls=\"home\"><center>Load Datasets</center></h2>","metadata":{}},{"cell_type":"markdown","source":"## **<span style=\"color:orange;\">Understanding the Structure of the Dataset</span>**\n\n> ### **<span style=\"color:orange;\">Goal of Competition</span>**\n> \n> In this competition we are segmenting neuronal cells in images. The training annotations are provided as run length encoded masks, and the images are in PNG format. The number of images is small, but the number of annotated objects is quite high. The hidden test set is roughly 240 images.\n> \n> ### **<span style=\"color:orange;\">Files</span>**\n> \n> **train.csv** - IDs and masks for all training objects. None of this metadata is provided for the test set.\n> \n> - `id` - unique identifier for object\n> \n> - `annotation` - run length encoded pixels for the identified neuronal cell\n> \n> - `width` - source image width\n> \n> - `height` - source image height\n> \n> - `cell_type` - the cell line\n> \n> - `plate_time` - time plate was created\n> \n> - `sample_date` - date sample was created\n> \n> - `sample_id` - sample identifier\n> \n> - `elapsed_timedelta` - time since first image taken of sample\n> \n> **sample_submission.csv** - a sample submission file in the correct format\n> \n> **train** - train images in PNG format\n> \n> **test** - test images in PNG format. Only a few test set images are available for download; the remainder can only be accessed by your notebooks when you submit.\n> \n> **train_semi_supervised** - unlabeled images offered in case you want to use additional data for a semi-supervised approach.\n> \n> **LIVECell_dataset_2021** - A mirror of the data from the LIVECell dataset. LIVECell is the predecessor dataset to this competition. You will find extra data for the SH-SHY5Y cell line, plus several other cell lines not covered in the competition dataset that may be of interest for transfer learning.\n>\n>---","metadata":{}},{"cell_type":"code","source":"df_train = pd.read_csv(config.TRAIN_CSV)","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:32:59.947021Z","iopub.execute_input":"2021-11-04T08:32:59.947816Z","iopub.status.idle":"2021-11-04T08:33:00.466851Z","shell.execute_reply.started":"2021-11-04T08:32:59.947789Z","shell.execute_reply":"2021-11-04T08:33:00.466179Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def getImagePaths(path):\n    \"\"\"\n    Function to Combine Directory Path with individual Image Paths\n    \n    parameters: path(string) - Path of directory\n    returns: image_names(string) - Full Image Path\n    \"\"\"\n    image_names = []\n    for dirname, _, filenames in os.walk(path):\n        for filename in tqdm(filenames):\n            fullpath = os.path.join(dirname, filename)\n            image_names.append(fullpath)\n    return image_names","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:33:00.468083Z","iopub.execute_input":"2021-11-04T08:33:00.468325Z","iopub.status.idle":"2021-11-04T08:33:00.475972Z","shell.execute_reply.started":"2021-11-04T08:33:00.468290Z","shell.execute_reply":"2021-11-04T08:33:00.475256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Get complete image paths for train and test datasets\ntrain_images_path = getImagePaths(config.TRAIN_PATH)\ntest_images_path = getImagePaths(config.TEST_PATH)\ntrain_semi_supervised_path = getImagePaths(config.TRAIN_SEMI_SUPERVISED_PATH)","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:33:00.477369Z","iopub.execute_input":"2021-11-04T08:33:00.477658Z","iopub.status.idle":"2021-11-04T08:33:02.304349Z","shell.execute_reply.started":"2021-11-04T08:33:00.477622Z","shell.execute_reply":"2021-11-04T08:33:02.303637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"unet-model\"></a>\n<div class=\"list-group\" id=\"list-tab\" role=\"tablist\">\n<h2 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style='background:orange; border:0; color:white' role=\"tab\" aria-controls=\"home\"><center>U-Net Model</center></h2>","metadata":{}},{"cell_type":"markdown","source":"There is large consent that successful training of **deep networks** requires many thousand annotated training samples. In the UNet paper, researchers presented a network and training strategy that relies on the strong use of **data augmentation** to use the available annotated samples more efficiently. \n  \nThe architecture consists of a **contracting path** to capture context and a **symmetric expanding path** that enables precise localization. They showed that such a network can be trained end-to-end from very few images and outperforms the prior best method (*a sliding-window convolutional network*) on the ISBI challenge for segmentation of neuronal structures in electron microscopic stacks. \n  \nMoreover, the network is fast. Segmentation of a 512x512 image takes less than a second on a recent GPU. \n  \n> The full\n> implementation (based on Caffe) and the trained networks are available\n> at http://lmb.informatik.uni-freiburg.de/people/ronneber/u-net","metadata":{}},{"cell_type":"markdown","source":"---","metadata":{}},{"cell_type":"markdown","source":"## **<span style=\"color:orange;\">Introduction to UNet</span>**\n\nIn the **UNet architecture** the upsampling part has a large number of feature channels, which allow the network to propagate context information to higher resolution layers. As a consequence, the **expansive path** is more or less symmetric to the **contracting path**, and yields a u-shaped architecture. \n  \n>The network does not have any fully connected layers and only uses the valid part of each convolution, i.e., the segmentation map only contains the pixels, for which the full context is available in the input image.\n\n![](https://www.researchgate.net/publication/350484428/figure/fig2/AS:1006897591238656@1617074501235/U-Net-Overlap-tile-strategy-for-seamless-segmentation-of-arbitrary-large-images-here.ppm)\n\nThis strategy allows the seamless segmentation of arbitrarily large images by an\n**overlap-tile strategy** (above image). \n  \nTo predict the pixels in the border region of the image, the missing context is extrapolated by mirroring the input image. \n  \n>This tiling strategy is important to apply the network to large images, since otherwise the resolution would be limited by the GPU memory.\n  \nAs for the tasks there is very little training data available, researchers used excessive\n**data augmentation** by applying **elastic deformations** to the available training images. This allows the network to learn invariance to such deformations, without the need to see these transformations in the annotated image corpus. \n  \nThis is particularly important in *biomedical segmentation*, since deformation used to\nbe the most common variation in tissue and realistic deformations can be simulated efficiently. \n\n![](https://yann-leguilly.gitlab.io/img/unet_1/figure_3.png)\n\nAnother challenge in many cell segmentation tasks is the separation of touching objects of the same class (above image). To this end, researchers proposed the use of a **weighted loss**, where the separating background labels between touching cells obtain a large weight in the loss function.\n  \nThe resulting network is applicable to various biomedical segmentation problems.","metadata":{}},{"cell_type":"markdown","source":"## **<span style=\"color:orange;\">UNet Architecture</span>**","metadata":{}},{"cell_type":"markdown","source":"![](https://production-media.paperswithcode.com/methods/Screen_Shot_2020-07-07_at_9.08.00_PM_rpNArED.png)","metadata":{}},{"cell_type":"markdown","source":"The network architecture is illustrated above. \n  \nIt consists of a **Contracting Path** (left side) and an **Expansive Path** (right side). \n  \n1.**Contracting Path:**\n  \n>The contracting path follows the typical architecture of a convolutional network. It consists of the repeated application of two 3x3 convolutions (*unpadded convolutions*), each followed by\na rectified linear unit (ReLU) and a 2x2 max pooling operation with *stride 2\nfor downsampling*. \n  \n>At each downsampling step we double the number of feature channels. \n\n2.**Expansive Path:**\n\n>Every step in the expansive path consists of an upsampling of the feature map followed by a 2x2 convolution (*up-convolution*) that halves the number of feature channels, a concatenation with the correspondingly cropped feature map from the contracting path, and two 3x3 convolutions, each followed by a ReLU. \n  \nThe cropping is necessary due to the loss of border pixels in every convolution. At the final layer a 1x1 convolution is used to map each 64-component feature vector to the desired number of classes. \n  \n*In total the network has 23 convolutional layers.*\n  \nTo allow a seamless tiling of the output segmentation map, it is important to select the input tile size such that all 2x2 max-pooling operations are applied to a layer with an even x- and y-size.","metadata":{}},{"cell_type":"markdown","source":"---","metadata":{}},{"cell_type":"markdown","source":"## **<span style=\"color:orange;\">Data Augmentation</span>**\n\n- Data augmentation is essential to teach the network the desired **invariance** and **robustness** properties, when only few training samples are available. \n  \n- In case of microscopical images we primarily need shift and rotation invariance as well as\nrobustness to deformations and gray value variations. \n  \n- Especially **random elastic deformations** of the training samples seem to be the key concept to train a segmentation network with very few annotated images. \n  \n- We generate smooth deformations using random **displacement vectors** on a coarse 3 by 3 grid. \n  \n- The displacements are sampled from a **Gaussian distribution** with 10 pixels standard deviation. \n  \n- Per-pixel displacements are then computed using **bicubic interpolation**. \n  \n- Drop-out layers at the end of the contracting path perform further implicit data augmentation.\n","metadata":{}},{"cell_type":"markdown","source":"---","metadata":{}},{"cell_type":"markdown","source":"## **<span style=\"color:orange;\">Utilities</span>**","metadata":{}},{"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\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 mask","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:33:02.308126Z","iopub.execute_input":"2021-11-04T08:33:02.309698Z","iopub.status.idle":"2021-11-04T08:33:02.320820Z","shell.execute_reply.started":"2021-11-04T08:33:02.309658Z","shell.execute_reply":"2021-11-04T08:33:02.319936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **<span style=\"color:orange;\">Dataset Class</span>**","metadata":{}},{"cell_type":"code","source":"class CellDataset(Dataset):\n    def __init__(self, df):\n        self.df = df\n        self.base_path = config.TRAIN_PATH\n        self.transforms = Compose([Resize(config.IMAGE_RESIZE[0], config.IMAGE_RESIZE[1]), \n                                   Normalize(mean=config.RESNET_MEAN, std=config.RESNET_STD, p=1), \n                                   HorizontalFlip(p=0.5),\n                                   VerticalFlip(p=0.5),\n                                   ToTensorV2()])\n        self.gb = self.df.groupby('id')\n        self.image_ids = df.id.unique().tolist()\n\n    def __getitem__(self, idx):\n        image_id = self.image_ids[idx]\n        df = self.gb.get_group(image_id)\n        annotations = df['annotation'].tolist()\n        image_path = os.path.join(self.base_path, image_id + \".png\")\n        image = cv2.imread(image_path)\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        return image, mask.reshape((1, config.IMAGE_RESIZE[0], config.IMAGE_RESIZE[1]))\n\n    def __len__(self):\n        return len(self.image_ids)  ","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:33:02.322142Z","iopub.execute_input":"2021-11-04T08:33:02.322583Z","iopub.status.idle":"2021-11-04T08:33:02.337481Z","shell.execute_reply.started":"2021-11-04T08:33:02.322543Z","shell.execute_reply":"2021-11-04T08:33:02.336634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prepare Dataset\n\nds_train = CellDataset(df_train)\nimage, mask = ds_train[1]\nimage.shape, mask.shape","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:33:02.341103Z","iopub.execute_input":"2021-11-04T08:33:02.341558Z","iopub.status.idle":"2021-11-04T08:33:02.550926Z","shell.execute_reply.started":"2021-11-04T08:33:02.341518Z","shell.execute_reply":"2021-11-04T08:33:02.548476Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(image[0], cmap='bone')\nplt.show()\nplt.imshow(mask[0], alpha=0.3)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:33:02.555534Z","iopub.execute_input":"2021-11-04T08:33:02.558073Z","iopub.status.idle":"2021-11-04T08:33:03.107007Z","shell.execute_reply.started":"2021-11-04T08:33:02.558033Z","shell.execute_reply":"2021-11-04T08:33:03.105808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **<span style=\"color:orange;\">Dataset Loader</span>**","metadata":{}},{"cell_type":"code","source":"# Prepare Dataloader\n\ndl_train = DataLoader(\n    ds_train, \n    batch_size=64, \n    num_workers=4, \n    pin_memory=True, \n    shuffle=False\n)","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:33:03.108620Z","iopub.execute_input":"2021-11-04T08:33:03.109092Z","iopub.status.idle":"2021-11-04T08:33:03.114787Z","shell.execute_reply.started":"2021-11-04T08:33:03.109047Z","shell.execute_reply":"2021-11-04T08:33:03.113429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **<span style=\"color:orange;\">Losses</span>**","metadata":{}},{"cell_type":"code","source":"def dice_loss(input, target):\n    input = torch.sigmoid(input)\n    smooth = 1.0\n    iflat = input.view(-1)\n    tflat = target.view(-1)\n    intersection = (iflat * tflat).sum()\n    return ((2.0 * intersection + smooth) / (iflat.sum() + tflat.sum() + smooth))","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:33:03.116920Z","iopub.execute_input":"2021-11-04T08:33:03.117230Z","iopub.status.idle":"2021-11-04T08:33:03.125843Z","shell.execute_reply.started":"2021-11-04T08:33:03.117191Z","shell.execute_reply":"2021-11-04T08:33:03.124676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **<span style=\"color:orange;\">1. Focal Loss</span>**\n\nFocal loss was introduced by Lin et al. in [Focal Loss for Dense Object Detection](https://paperswithcode.com/paper/focal-loss-for-dense-object-detection)\n\n- A **Focal Loss** function addresses class imbalance during training in tasks like object detection. \n  \n- Focal loss applies a modulating term to the cross entropy loss in order to focus learning on hard negative examples. \n  \n- It is a dynamically scaled cross entropy loss, where the scaling factor decays to zero as confidence in the correct class increases. \n  \n- Intuitively, this scaling factor can automatically down-weight the contribution of easy examples during training and rapidly focus the model on hard examples.\n\n![](https://production-media.paperswithcode.com/methods/Screen_Shot_2020-06-07_at_4.45.06_PM_leJm2yh.png)","metadata":{}},{"cell_type":"code","source":"class FocalLoss(nn.Module):\n    def __init__(self, gamma):\n        super().__init__()\n        self.gamma = gamma\n\n    def forward(self, input, target):\n        if not (target.size() == input.size()):\n            raise ValueError(\"Target size ({}) must be the same as input size ({})\"\n                             .format(target.size(), input.size()))\n        max_val = (-input).clamp(min=0)\n        loss = input - input * target + max_val + \\\n            ((-max_val).exp() + (-input - max_val).exp()).log()\n        invprobs = F.logsigmoid(-input * (target * 2.0 - 1.0))\n        loss = (invprobs * self.gamma).exp() * loss\n        return loss.mean()","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:33:03.128004Z","iopub.execute_input":"2021-11-04T08:33:03.128652Z","iopub.status.idle":"2021-11-04T08:33:03.139237Z","shell.execute_reply.started":"2021-11-04T08:33:03.128605Z","shell.execute_reply":"2021-11-04T08:33:03.138305Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **<span style=\"color:orange;\">2. Focal Loss</span>**","metadata":{}},{"cell_type":"code","source":"class MixedLoss(nn.Module):\n    def __init__(self, alpha, gamma):\n        super().__init__()\n        self.alpha = alpha\n        self.focal = FocalLoss(gamma)\n\n    def forward(self, input, target):\n        loss = self.alpha*self.focal(input, target) - torch.log(dice_loss(input, target))\n        return loss.mean()","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:33:03.141876Z","iopub.execute_input":"2021-11-04T08:33:03.142111Z","iopub.status.idle":"2021-11-04T08:33:03.151352Z","shell.execute_reply.started":"2021-11-04T08:33:03.142079Z","shell.execute_reply":"2021-11-04T08:33:03.150466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **<span style=\"color:orange;\">Model</span>**","metadata":{}},{"cell_type":"code","source":"model = smp.Unet(\"resnet34\", encoder_weights=\"imagenet\", activation=None)","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:33:03.153191Z","iopub.execute_input":"2021-11-04T08:33:03.153493Z","iopub.status.idle":"2021-11-04T08:33:03.645985Z","shell.execute_reply.started":"2021-11-04T08:33:03.153457Z","shell.execute_reply":"2021-11-04T08:33:03.645255Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **<span style=\"color:orange;\">Training</span>**","metadata":{}},{"cell_type":"code","source":"torch.set_default_tensor_type(\"torch.cuda.FloatTensor\")\nn_batches = len(dl_train)\n\nmodel.cuda()\nmodel.train()\n\ncriterion = MixedLoss(10.0, 2.0)\noptimizer = optim.Adam(model.parameters(), lr=config.LEARNING_RATE)\n\n# Initialize W&B\nrun = wandb.init(project='sartorius-unet', config=WANDB_CONFIG)\n\nfor epoch in range(1, config.EPOCHS + 1):\n    print(f\"Starting epoch: {epoch} / {config.EPOCHS}\")\n    running_loss = 0.0\n    optimizer.zero_grad()\n    \n    for batch_idx, batch in enumerate(dl_train):\n        \n        # Predict\n        images, masks = batch\n        images, masks = images.cuda(),  masks.cuda()\n        outputs = model(images)\n        loss = criterion(outputs, masks)\n        wandb.log({\"loss\": loss})\n        \n        # Back prop\n        loss.backward()\n        optimizer.step()\n        optimizer.zero_grad()\n        running_loss += loss.item()\n\n    epoch_loss = running_loss / n_batches\n    print(f\"Epoch: {epoch} - Train Loss {epoch_loss:.4f}\")\n    \nwandb.finish()","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:42:40.499967Z","iopub.execute_input":"2021-11-04T08:42:40.500229Z","iopub.status.idle":"2021-11-04T08:49:31.066312Z","shell.execute_reply.started":"2021-11-04T08:42:40.500200Z","shell.execute_reply":"2021-11-04T08:49:31.065567Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## [Check out the run page here $\\rightarrow$](https://wandb.ai/ishandutta/sartorius-unet?workspace=)  ","metadata":{}},{"cell_type":"markdown","source":"<a id=\"references\"></a>\n<div class=\"list-group\" id=\"list-tab\" role=\"tablist\">\n<h2 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style='background:orange; border:0; color:white' role=\"tab\" aria-controls=\"home\"><center>References</center></h2>","metadata":{}},{"cell_type":"markdown","source":">- [🦠 Sartorius - Starter Baseline Torch U-net](https://www.kaggle.com/julian3833/sartorius-starter-baseline-torch-u-net)\n>- [U-Net: Convolutional Networks for Biomedical Image Segmentation](https://paperswithcode.com/paper/u-net-convolutional-networks-for-biomedical)\n>\n>---","metadata":{}},{"cell_type":"markdown","source":"<h1><center>More Plots and Models coming soon!</center></h1>\n\n<center><img src = \"https://static.wixstatic.com/media/5f8fae_7581e21a24a1483085024f88b0949a9d~mv2.jpg/v1/fill/w_934,h_379,al_c,q_90/5f8fae_7581e21a24a1483085024f88b0949a9d~mv2.jpg\" width = \"750\" height = \"500\"/></center> ","metadata":{}},{"cell_type":"markdown","source":"--- \n\n## **<span style=\"color:orange;\">Let's have a Talk!</span>**\n> ### Reach out to me on [LinkedIn](https://www.linkedin.com/in/ishandutta0098)\n\n---","metadata":{}}]}