{"cells":[{"metadata":{},"cell_type":"markdown","source":"<img src=\"https://cellero.com/wp-content/uploads/2019/12/human-protein-atlas-logo-1.png\" width=\"600\" height=\"400\">\n\n\n## <center>Human Protein Atlas - Single Cell Classification</center>\n### <center>🔬Find individual human cell differences in microscope images🔬</center>"},{"metadata":{},"cell_type":"markdown","source":"# Table of contents <a id='0.1'></a>\n\n1. [Version Notes](#0)\n1. [Introduction](#1)\n    * [Evaluation Metric: Mean Average Precision (mAP)](#1.1)\n2. [Import Packages](#2)\n3. [Utility](#3)\n5. [Data Overview](#4)\n5. [Exploratory Data Analysis](#5)\n    * 5.1 [Label Preprocessing](#5.1)\n    * 5.2 [Exploring Image Data](#5.2)\n    * 5.3 [Label Wise Cell Segmentation](#5.3)\n    * 5.4 [Label Wise Single Cell Segmentation](#5.4)\n6. [Useful Resources](#6)\n6. [Refrence](#7)"},{"metadata":{},"cell_type":"markdown","source":"# 1. <a id='0'>Version Notes📃</a>\n[Table of contents](#0.1)\n\n* Version 12: Updated EDA for bar graph explanation.\n* version 19: Added visualization for single cell mask.\n* Version 20: Visualize images for single label/organelle.\n* Version 21: Updated submission.csv table representation.\n* Version 23: Added Mean Average Precision (mAP) explanation video in Inroduction section.\n* Version 25: Added **Useful Resources** section.\n\n# 2. <a id='1'>Introduction📒</a>\n[Table of contents](#0.1)\n\nWelcome to **Human Protein Atlas - Single Cell Classification** competiton hosted by [Human Protein Atlas](https://www.proteinatlas.org/). This competition aims to solve the single-cell image classification challenge that will help us to characterize single-cell heterogeneity in the large collection of images by generating more accurate annotations of the subcellular localizations for thousands of human proteins in individual cells. Please go through this section thouroghly to develop understanding for the competiton goal and data.\n\n## What is Human Protein Atlas?\n\nThe Human Protein Atlas is an initiative based in Sweden that is aimed at mapping proteins in all human cells, tissues, and organs. The data in the Human Protein Atlas [database](https://www.proteinatlas.org/) is freely accessible to scientists all around the world that allows them to explore the cellular makeup of the human body."},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"from IPython.display import HTML\n\nHTML('<center><iframe width=\"950\" height=\"450\" src=\"https://www.youtube.com/embed/P4gz6DrZOOI\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe></center>')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Competition Goal (Brief Introduction)\n[Table of contents](#0.1)\n* This is segmentation and classification problem. We are provided with images of microscopic cells and corresponding labels of protein location assigned together for each cells in the image. This means for every train image we are given multiple labels. There are total **19 labels/classes**.\n\n* The training image-level labels are provided for each sample in train.csv.\n\n* For each sample we have 4 image files. Each file represents a different filter on the subcellular protein patterns represented by the sample. Colors are red for microtubule channels, blue for nuclei channels, yellow for Endoplasmic Reticulum (ER) channels, and green for protein of interest.\n\n* We have to develop models capable of segmenting and classifying each individual cell with precise labels. This means we are predicting protein organelle localization labels for each cell in the image. First we need to segment each cell in the image and then assign it appropriate label. So this is segmentation - classification problem. It may be possible that not all cells in the image contain protein and so we need to only assign labels to those cells for which the protein in present. The labels only apply to the cells where green is present  **This is a weakly supervised multi-label classification problem**. Please visit [this](https://www.kaggle.com/c/hpa-single-cell-image-classification/discussion/215736) awesome discussion to know more. \n\n## What is weak image-level labels?\n\nThe labels you will get for training are image level labels while the task is to predict cell level labels. That is to say, each training image contains a number of cells that have collectively been labeled. The prediction task is to look at images of the same type and predict the labels of each individual cell within those images.\n\nAs the training labels are a collective label for all the cells in an image, it means that each labeled pattern can be seen in the image but not necessarily that each cell within the image expresses the pattern. This imprecise labeling is what we refer to as weak.\n\nDuring the challenge you will both need to segment the cells in the images and predict the labels of those segmented cells.\n\n## About Competition Data\nWe are provided with following files - \n\n   * train.csv - filenames and image level labels for the training set. For each filename there are 4 files (images) in  train directory.\n   \n   * sample_submission.csv - the test set filenames and a guide for constructing a working submission.\n   \n   * train - train set image directory which consists of sample images for training. Each train images (sample) has four files. Each file represents a different filter on the subcellular protein patterns represented by the sample.    The format should be **\"filename_filtercolor.png\"** for the PNG files. Colors are red for microtubule channels, blue for nuclei channels, yellow for Endoplasmic Reticulum (ER) channels, and green for protein of interest. \"**The green filter should hence be used to predict the label, and the other filters are used as references**\". Check below example.\n   \n   <div class=\"alert alert-block alert-info\">\n       Example - \n\n       * 000a6c98-bb9b-11e8-b2b9-ac1f6b6435d0_blue.png\n       * 000a6c98-bb9b-11e8-b2b9-ac1f6b6435d0_green.png\n       * 000a6c98-bb9b-11e8-b2b9-ac1f6b6435d0_red.png\n       * 000a6c98-bb9b-11e8-b2b9-ac1f6b6435d0_yellow.png     \n    \n   * test - test image directory. \"**Our task is to segment and label the images in this folder**\". \n    \n   * The labels are represented as integers that map to the following:    \n    0. Nucleoplasm\n    1. Nuclear membrane\n    2. Nucleoli\n    3. Nucleoli fibrillar center\n    4. Nuclear speckles\n    5. Nuclear bodies\n    6. Endoplasmic reticulum\n    7. Golgi apparatus\n    8. Intermediate filaments\n    9. Actin filaments \n    10. Microtubules\n    11. Mitotic spindle\n    12. Centrosome\n    13. Plasma membrane\n    14. Mitochondria\n    15. Aggresome\n    16. Cytosol\n    17. Vesicles and punctate cytosolic patterns\n    18. Negative\n\n## Label Discription\n[Table of contents](#0.1)   \n   * Nucleoplasm - Nucleoplasm is a type of protoplasm that is composed of thick fluid and constitutes chromatin fibres made up of DNA and usually found in the nucleus of the cells. This fluid contains primarily water, dissolved ions, and a complex mixture of molecules.\n   \n   * Nuclear membrane - The nuclear membrane appears as a thin circle around the nucleus. It is not perfectly smooth and sometimes it is also possible to see the folds of the membrane as small circles or dots inside the nucleus.\n   \n   * Nucleoli - The nucleoli are non-membrane enclosed, highly conserved, sub-organelles within the nucleus.\n   \n   * Nucleoli fibrillar center - Nucleoli fibrillary center can appear as a spotty cluster or as a single bigger spot in the nucleolus, depending on the cell type.\n   \n   * Nuclear speckles - Nuclear speckles are self-organizing non-membrane bound sub-compartments found in the interchromatin regions of the nucleoplasm.\n   \n   * Nuclear bodies - Nuclear bodies is a collective term for a number of non-membrane bound nuclear sub-compartments. They vary in shape, size and numbers depending on the type of bodies as well as cell type, but are usually more rounded compared to nuclear speckles.\n   \n   * Endoplasmic reticulum - The endoplasmic reticulum (ER) is a delicate membranous network composed of sheets and tubules that spread throughout the cytoplasm and are contiguous with the nuclear membrane.\n   \n   * Golgi apparatus - The Golgi apparatus is a central hub in the endomembrane system of human cells, placed at the intersection of the endosomal-, secretory- and lysosomal pathways. It consists of several stacks of flattened cisternae and tubular connections, forming a ribbon-like structure that is highly dynamic. \n   \n   * Intermediate filaments - Intermediate filaments often exhibit a slightly tangled structure with strands crossing every so often. They can appear similar to microtubules, but do not match well with the staining in the red microtubule channel. Intermediate filaments may extend through the whole cytosol, or be concentrated in an area close to the nucleus.\n   \n   * Actin filaments - Actin filaments can be seen as long and rather straight bundles of filaments or as branched networks of thinner filaments. They are usually located close to the edges of the cells.\n   \n   * Microtubules - Microtubules are one of three principal components of the cytoskeleton. Microtubules are seen as thin strands that stretch throughout the whole cell. It is almost always possible to detect the center from which they all originate (the centrosome). And yes, as you might have guessed, this overlaps the staining in the red channel.\n   \n   * Mitotic spindle - The mitotic spindle can be seen as an intricate structure of microtubules radiating from each of the centrosomes at opposite ends of a dividing cell (mitosis). At this stage, the chromatin of the cell is condensed, as visible by intense DAPI staining. The size and exact shape of the mitotic spindle changes during mitotic progression, clearly reflecting the different stages of mitosis.\n   \n   * Centrosome - This class includes centrosomes and centriolar satellites. They can be seen as a more or less distinct staining of a small area at the origin of the microtubules, close to the nucleus. When a cell is dividing, the two centrosomes move to opposite ends of the cell and form the poles of the mitotic spindle.\n   \n   * Plasma membrane - The plasma membrane, or cell membrane, consists of a lipid bilayer which separates the interior of the cell from the exterior. The membrane is composed of phospholipids, cholesterol, glycolipids, and a large fraction of membrane proteins, organized together in different domains. \n   \n   * Mitochondria - Mitochondria generate the energy that is needed to power the functions of the cell, but also participate directly in several other cellular processes, including apoptosis, cell cycle control and calcium homeostasis.. Mitochondria are small organelles distríbuted in varying numbers and patterns in the cytosol of most human cells. Mitochondria are enclosed by a double membrane, with the inner membrane folded into characteristic cristae. \n   \n   * Aggresome - Aggresomes are structures that form in response to accumulation of misfolded proteins in the cytosol. Aggresome formation is a regulated process that occurs in response to overload of the protein folding- and degradation systems, due to cellular stress or disease. \n   \n   * Cytosol - The cytosol is a semi-fluid matrix that fills the space between the plasma membrane and the nuclear membrane, and embedding various organelles and cellular substructures.\n   \n   * Vesicles and punctate cytosolic patterns - Vesicles is a collective term for cytoplasmic organelles that are often too small to have distinct features when imaged by light microscopy. The majority of the vesicles are membrane-bound organelles, however, also large protein complexes and cytosolic bodies can fall under this category, as they are difficult to distinguish. Examples of organelles with a vesicle annotation are the members of the endolysosomal pathway, transport vesicles, peroxisomes, and lipid droplets. Following Substructures fall in this class such as, \n       * Vesicles\n       * Peroxisomes\n       * Endosomes\n       * Lysosomes\n       * Lipid droplets\n     \n   * Negative - This class include negative stainings and unspecific patterns. This means that the cells have no green staining (negative), or have staining but no pattern can be deciphered from the staining (unspecific).\n    \n## What we are prediciting?\n[Table of contents](#0.1)\n    \nLet us first understand what is **protein targeting?** \"So, Protein targeting or protein sorting is the biological mechanism by which proteins are transported to their appropriate destinations within or outside the cell.\"\n    \nWe are the prediciting location (organelle) where the protein is targeted in a single cell. There are **19 labels/organelle present in the dataset (18 labels for specific locations, and 1 label for negative and unspecific signal)**.    \n    \nFor each image we need to segment every cell present in it and identify the label/organelle of each cell (out of 19) and submit a string such that it contains a list of instance segmentation masks and their associated detection score (Confidence) and segmentation mask for each cell. The sample submission will look something like, "},{"metadata":{},"cell_type":"markdown","source":"<table style=\"width:70% height:200px\">\n  <tr>\n    <th style=\"text-align:left\">ImageID</th>\n    <th style=\"text-align:left\">ImageWidth</th>\n    <th style=\"text-align:left\">ImageHeight</th>\n    <th style=\"text-align:left\">PredictionString</th>\n  </tr>\n  <tr>\n    <td style=\"text-align:left\">ImageAID</td>\n    <td style=\"text-align:left\">ImageAWidth</td>\n    <td style=\"text-align:left\">ImageAHeight</td>\n    <td style=\"text-align:left\">LabelA1 ConfidenceA1 EncodedMaskA1 LabelA2 ConfidenceA2 EncodedMaskA2 ...</td>\n  </tr>\n  <tr>\n    <td style=\"text-align:left\">ImageBID</td>\n    <td style=\"text-align:left\">ImageBWidth</td>\n    <td style=\"text-align:left\">ImageAHeight</td>\n    <td style=\"text-align:left\">LabelB1 ConfidenceB1 EncodedMaskB1 LabelB2 ConfidenceB2 EncodedMaskB2 …</td>\n  </tr>\n</table>"},{"metadata":{},"cell_type":"markdown","source":"### What exactly is **PredictionString** column in submission.csv? \n\nThe PredicitionString column contains a string of label, confidence score for that classified label/organelle and mask information ecoded in RLE encoding and we are doing this for every cell present in the image. It may be possible that some of the cells in the image may not have the protein of interest. \n\nFor more information regarding evaluation metric check [here](https://www.kaggle.com/c/open-images-2019-instance-segmentation/overview/evaluation)."},{"metadata":{},"cell_type":"markdown","source":"## Evaluation Metric: Mean Average Precision (mAP) <a id='1.1'></a>\n[Table of contents](#0.1)\n\nPlease check this discussion [here](https://www.kaggle.com/c/hpa-single-cell-image-classification/discussion/219885) for more information. "},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"HTML('<center><iframe width=\"950\" height=\"450\" src=\"https://www.youtube.com/embed/FppOzcDvaDI\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe></center>')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 3. <a id='2'>Import Packages📚</a>\n[Table of contents](#0.1)"},{"metadata":{"_kg_hide-output":true,"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"!pip install https://github.com/CellProfiling/HPA-Cell-Segmentation/archive/master.zip","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# basic \nimport warnings\nimport os, gc, cv2\nimport numpy as np\nimport pandas as pd\nfrom glob import glob\nfrom tqdm.notebook import tqdm\n\n# visualize\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n\n# segmentation tool\nimport hpacellseg.cellsegmentator as cellsegmentator\nfrom hpacellseg.utils import label_cell, label_nuclei\n\n%matplotlib inline\nwarnings.filterwarnings('ignore')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let us have a look at competiton data directory."},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"# directory\nprint('Competition Data/Files')\nROOT = '../input/hpa-single-cell-image-classification/'\nos.listdir(ROOT)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 4. <a id='3'>Utility🔨</a>\n[Table of contents](#0.1)"},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"# read and visualize sample image\ndef read_sample_image(filename):\n    \n    '''\n    read individual images\n    of different filters (R, G, B, Y)\n    and stack them.\n    ---------------------------------\n    Arguments:\n    filename -- sample image path\n    \n    Returns:\n    stacked_images -- stacked (RGBY) image\n    '''\n    \n    red = cv2.imread(os.path.join(ROOT, 'train/') + filename + \"_red.png\", cv2.IMREAD_UNCHANGED)\n    green = cv2.imread(os.path.join(ROOT, 'train/') + filename + \"_green.png\", cv2.IMREAD_UNCHANGED)\n    blue = cv2.imread(os.path.join(ROOT, 'train/') + filename + \"_blue.png\", cv2.IMREAD_UNCHANGED)\n    yellow = cv2.imread(os.path.join(ROOT, 'train/') + filename + \"_yellow.png\", cv2.IMREAD_UNCHANGED)\n\n    stacked_images = np.transpose(np.array([red, green, blue, yellow]), (1,2,0))\n    return stacked_images\n\ndef plot_all(im, label):\n    \n    '''\n    plot all RGBY image,\n    Red, Green, Blue, Yellow, \n    filters images.\n    --------------------------\n    Argument:\n    im - image\n    '''\n    \n    plt.figure(figsize=(15, 15))\n    plt.subplot(1, 5, 1)\n    plt.imshow(im[:,:,:3])\n    plt.title('RGBY Image')\n    plt.axis('off')\n    plt.subplot(1, 5, 2)\n    plt.imshow(im[:,:,0], cmap='Reds')\n    plt.title('Microtubule channels')\n    plt.axis('off')\n    plt.subplot(1, 5, 3)\n    plt.imshow(im[:,:,1], cmap='Greens')\n    plt.title('Protein of Interest')\n    plt.axis('off')\n    plt.subplot(1, 5, 4)\n    plt.imshow(im[:,:,2], cmap='Blues')\n    plt.title('Nucleus')\n    plt.axis('off')\n    plt.subplot(1, 5, 5)\n    plt.imshow(im[:,:,3], cmap='Oranges')\n    plt.title('Endoplasmic Reticulum')\n    plt.axis('off')\n    plt.show()\n\n# read and visualize sample image\ndef read_sample_image_seg(filename):\n    \n    '''\n    read individual images\n    of different filters (R, B, Y)\n    and stack them for segmentation.\n    ---------------------------------\n    Arguments:\n    filename -- sample image file path\n    \n    Returns:\n    stacked_images -- stacked (RBY) image path in lists.\n    '''\n    \n    red = os.path.join(ROOT, 'train/') + filename + \"_red.png\"\n    blue = os.path.join(ROOT, 'train/') + filename + \"_blue.png\"\n    yellow = os.path.join(ROOT, 'train/') + filename + \"_yellow.png\"\n\n    stacked_images = [[red], [yellow], [blue]]\n    return stacked_images, red, blue, yellow\n\n# segment cell \ndef segmentCell(image, segmentator):\n    \n    '''\n    segment cell and nuclei from\n    microtubules, endoplasmic reticulum,\n    and nuclei (R, B, Y) filters.\n    ------------------------------------\n    Argument:\n    image -- (R, B, Y) list of image arrays\n    segmentator -- CellSegmentator class object\n    \n    Returns:\n    cell_mask -- segmented cell mask\n    '''\n    \n    nuc_segmentations = segmentator.pred_nuclei(image[2])\n    cell_segmentations = segmentator.pred_cells(image)\n    nuclei_mask, cell_mask = label_cell(nuc_segmentations[0], cell_segmentations[0])\n    \n    gc.collect(); del nuc_segmentations; del cell_segmentations; del nuclei_mask\n    \n    return cell_mask\n\n# plot segmented cells mask, image\ndef plot_cell_segments(mask, red, blue, yellow):\n    \n    '''\n    plot segmented cells\n    and images\n    ---------------------\n    Arguments:\n    mask -- cell mask\n    red -- red filter image path\n    blue -- blue filter image path\n    yellow -- yellow filter image path\n    '''\n    microtubule = plt.imread(r)    \n    endoplasmicrec = plt.imread(b)    \n    nuclei = plt.imread(y)\n    img = np.dstack((microtubule, endoplasmicrec, nuclei))\n    \n    plt.figure(figsize=(15, 15))\n    plt.subplot(1, 3, 1)\n    plt.imshow(img)\n    plt.title('Image')\n    plt.axis('off')\n    \n    plt.subplot(1, 3, 2)\n    plt.imshow(mask)\n    plt.title('Mask')\n    plt.axis('off')\n    \n    plt.subplot(1, 3, 3)\n    plt.imshow(img)\n    plt.imshow(mask, alpha=0.6)\n    plt.title('Image + Mask')\n    plt.axis('off')\n    plt.show()\n\n# plot single segmented cells mask, image\ndef plot_single_cell(mask, red, blue, yellow):\n    \n    '''\n    plot single cell mask\n    and image\n    ---------------------\n    Arguments:\n    mask -- cell mask\n    red -- red filter image path\n    blue -- blue filter image path\n    yellow -- yellow filter image path\n    '''\n    microtubule = plt.imread(r)    \n    endoplasmicrec = plt.imread(b)    \n    nuclei = plt.imread(y)\n    img = np.dstack((microtubule, endoplasmicrec, nuclei))\n    \n    contours= cv2.findContours(mask.astype('uint8'),\n                               cv2.RETR_TREE, \n                               cv2.CHAIN_APPROX_SIMPLE)\n\n    areas = [cv2.contourArea(c) for c in contours[0]]\n    x = np.argsort(areas)\n    cnt = contours[0][x[-1]]\n    x,yc,w,h = cv2.boundingRect(cnt)\n    \n    plt.figure(figsize=(15, 15))\n    plt.subplot(1, 3, 1)\n    plt.imshow(img[yc:yc+h, x:x+w])\n    plt.title('Cell Image')\n    plt.axis('off')\n    \n    plt.subplot(1, 3, 2)\n    plt.imshow(mask[yc:yc+h, x:x+w])\n    plt.title('Cell Mask')\n    plt.axis('off')\n    \n    plt.subplot(1, 3, 3)\n    plt.imshow(img[yc:yc+h, x:x+w])\n    plt.imshow(mask[yc:yc+h, x:x+w], alpha=0.6)\n    plt.title('Cell Image + Mask')\n    plt.axis('off')\n    plt.show()\n    \ndef binary_mask(rgby_images):\n    \n    '''\n    generate masks from \n    rgby images.\n    --------------------\n    Arguments:\n    rgby_images -- RGBY cell images\n    \n    Return:\n    mask -- binary mask.\n    '''\n    pass","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 5. <a id='4'>Data Overview🧫</a>\n## 5.1 <a id='4.1'>Train Data</a>\n[Table of contents](#0.1)\n\nIn this section we will develop intuition for data we are working with."},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv(os.path.join(ROOT, 'train.csv'))\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**📌 Observations**\n\nWe have following features in train.csv-\n\n   * ID - The base filename of the sample. All samples consist of four files - blue, green, red, and yellow.\n   * Label - This represents the labels assigned to each sample.\n   \nAs mentioned in the [data](https://www.kaggle.com/c/hpa-single-cell-image-classification/data) section of the competition in [Introduction](#1) section above we can see every sample has multiple label. "},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"print(f'We have {train_df.shape[0]} rows and {train_df.shape[1]} columns in our train_df.csv.')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Missing Values"},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"print(f'Missing values in train_df.csv in each columns:\\n{train_df.isnull().sum()}')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Unique Values"},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"print('Unique Values in each column of train_df.csv')\nprint('##########################################')\nfor col in train_df:\n    print(f'{col}: {train_df[col].nunique()}')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 5.2 <a id='4.2'>Test/Submission Data</a>\n[Table of contents](#0.1)"},{"metadata":{"_kg_hide-input":false,"trusted":true},"cell_type":"code","source":"sample_sub = pd.read_csv(os.path.join(ROOT, 'sample_submission.csv'))\nsample_sub.head()","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"print(f'We have {sample_sub.shape[0]} rows and {sample_sub.shape[1]} columns in our sample_sub.csv.')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 6 <a id='5'>Exploratory Data Analysis🧬</a>\n## 6.1 <a id=5.1>Preprocessing Labels</a>\n[Table of contents](#0.1)\n\nSince we are given multiple label in our **\"Label\"** column we need to binarize them so that each label/class will become a column.  "},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"# spliting label column\ntrain_df[\"Label\"] = train_df[\"Label\"].str.split(\"|\")\n\n# class labels\nclass_labels = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18']\n\n# binarizing each label/class\nfor label in tqdm(class_labels):\n    train_df[label] = train_df['Label'].map(lambda result: 1 if label in result else 0)\n\n# rename column\ntrain_df.columns = ['ID', 'Label', 'Nucleoplasm', 'Nuclear membrane', 'Nucleoli', 'Nucleoli fibrillar center',\n                    'Nuclear speckles', 'Nuclear bodies', 'Endoplasmic reticulum', 'Golgi apparatus', 'Intermediate filaments',\n                    'Actin filaments', 'Microtubules', 'Mitotic spindle', 'Centrosome', 'Plasma membrane', 'Mitochondria',\n                    'Aggresome', 'Cytosol', 'Vesicles and punctate cytosolic patterns', 'Negative']\n\ntrain_df","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"class_counts = train_df.sum().drop(['ID', 'Label']).sort_values(ascending=False)\n\nprint('Per class count in train dataset')\nprint('-------------------------------------------------')\nfor column in class_counts.keys():\n    print(f\"The class {column} has {train_df[column].sum()} samples\")","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(14,12))\nwith sns.axes_style(\"whitegrid\"):\n    aa = sns.barplot(y=class_counts.index.values, x=class_counts.values, palette='gist_earth')\n    plt.title(\"Label Distribution\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**📌 Observations**\n\n   * We see **Nucleoplasm** has most occurence around **8797**.\n   * Plasma is the 3 most label with 3111 occurences followed by Cytosol with 5685.  \n   * **Negative** are least only 34 samples with unspecified location.\n   * Most labels seems to have occurence less than 2000. "},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"label_per_image = train_df.drop(['ID', 'Label'], axis=1).sum(axis=1)\n\nplt.figure(figsize=(16,10))\nwith sns.axes_style(\"whitegrid\"):\n    ax = sns.countplot(label_per_image, palette='Pastel1')\n    for p in ax.patches:\n        height = p.get_height()\n        ax.text(p.get_x()+p.get_width()/2.,\n                height + 3,\n                '{:1.2f}%'.format(height/len(label_per_image)*100),\n                ha=\"center\", fontsize=12)\n    plt.title(\"Label Per Sample/Image\", fontsize=16)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**📌 Observations**\n\n   * 48% samples have only 1 label, 40% have 2 labels per image.\n   * 10% samples have 3 labels.\n   * Very small number of samples seems to have more than 3 labels."},{"metadata":{},"cell_type":"markdown","source":"## 6.2 <a id=5.2>Exploring Image Data</a>\n[Table of contents](#0.1)\n\nEach sample consists of four image files. Each file represents a different filter on the subcellular protein patterns represented by the sample (ID).\n\n* Red for Microtubule channels.\n* Blue for Nuclei channels.\n* Yellow for Endoplasmic Reticulum (ER) channels.\n* Green for Protein of interest.\n\nThe \"**Protein of interest**\" (Green channel) is what we are prediciting for each sample with labels (multiple labels). This labels are the organelles. It is the pattern(s) in the green channel that we should classify. \n\nWe want to visualize those images which have single label to get proper understanding of the orgenelles. Thanks to [Kishan Joshi](https://www.kaggle.com/joshi98kishan) my teammate for suggesting this and helping me with this work. "},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"train = train_df.loc[train_df['Label'].apply(lambda x: len(x)==1)==True]","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"for label in train_df.drop(['ID', 'Label'], axis=1):\n    print(label)\n    im = read_sample_image(train[train[label]==1].sample(1).ID.to_string().split(' ')[4])\n    plot_all(im, label)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 6.3 <a id=5.3>Label Wise Cell Segmentation</a>\n[Table of contents](#0.1)\n\nFor segmenting cells we will use the [HPA Cell Segmentation](https://github.com/CellProfiling/HPA-Cell-Segmentation) tool provided by the competition host. For more details check [here](https://www.kaggle.com/lnhtrang/hpa-public-data-download-and-hpacellseg/notebook). We will use the HPACellSegmentation model to segment the cells in images. \n\nThe `CellSegmentator` class takes in following arguments - \n\n* nuclei_model - This should be a string containing the path to the nuclei-model weights. If the weights do not exist at the path, they will be downloaded to it. Defaults to ./nuclei_model.pth.\n\n* cell_model - This should be a string containing the path to the cell-model weights. If the weights do not exist at the path, they will be downloaded to it. Defaults to ./cell_model.pth.\n\n* scale_factor - This value determines how much the images should be scaled before being fed to the models. For HPA Cell images, a value of 0.25 is good. Defaults to 0.25.\n\n* device - Inform Torch which device to put the model on. Valid values are ‘cpu’ or ‘cuda’ or pointed cuda device like ‘cuda:0’. Defaults to cuda.\n\n* padding - If True, add some padding before feeding the images to the neural networks. This is not required but can make segmentations, especially cell segmentations, more accurate. Defaults to False.\n\n* multi_channel_model - If True, use the pretrained three-channel version of the model. Having this set to True gives you better cell segmentations but requires you to give the model endoplasmic reticulum images as part of the cell segmentation. Otherwise, the version trained with only two channels, microtubules and nuclei, will be used. Defaults to True.\n\nWe will post process the generated cell masks using the `label_cell` method followed by the `pred_cells` method to generate cell segmentations. "},{"metadata":{"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"NUC_MODEL = \"./nuclei-model.pth\"\nCELL_MODEL = \"./cell-model.pth\"\nsegmentator = cellsegmentator.CellSegmentator(\n    NUC_MODEL,\n    CELL_MODEL,\n    scale_factor=0.25,\n    device=\"cpu\",\n    padding=False,\n    multi_channel_model=True,\n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"I am going to plot the images and mask for each label present in the dataset. "},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"for label in train_df.drop(['ID', 'Label'], axis=1):\n    print(label)\n    im, r, b, y = read_sample_image_seg(train[train[label]==1].sample(1).ID.to_string().split(' ')[4])\n    mask = segmentCell(im, segmentator)\n    plot_cell_segments(mask, r, b, y)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 6.4 <a id=5.4>Label Wise Single Cell Segmentation</a>\n[Table of contents](#0.1)\n\nIn this section we will look at each cell closely on the basis of labels."},{"metadata":{"trusted":true},"cell_type":"code","source":"for label in train_df.drop(['ID', 'Label'], axis=1):\n    print(label)\n    im, r, b, y = read_sample_image_seg(train[train[label]==1].sample(1).ID.to_string().split(' ')[4])\n    mask = segmentCell(im, segmentator)\n    plot_single_cell(mask, r, b, y)","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"gc.collect()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 7. <a id='6'>Useful Resources</a>\n[Table of cotents](#0.1)\n\n1. **Leveraging Instance-, Image- and Dataset-Level Information for Weakly Supervised Instance Segmentation.** [[Paper]](http://mftp.mmcheng.net/Papers/21PAMI_InsImgDatasetWSIS.pdf) [[Code]](https://github.com/yun-liu/LIID)\n\n1. **Matrix Completion for Weakly-supervised Multi-label Image Classification.** [[Paper]](http://ca.cs.cmu.edu/sites/default/files/complete_14.pdf)\n\n1. **Weakly Supervised Multi-Label Learning via Label Enhancement.** [[Paper]](https://www.ijcai.org/Proceedings/2019/0430.pdf)\n\n1. **Puzzle-CAM: Improved localization via matching partial and full features** [[Code]](https://github.com/OFRIN/PuzzleCAM) [[Paper]](https://arxiv.org/abs/2101.11253) [[Discussion]](https://www.kaggle.com/c/hpa-single-cell-image-classification/discussion/222094) [[Approach]](https://www.kaggle.com/c/hpa-single-cell-image-classification/discussion/217395)\n\n1. **Protein localization patterns Explained** [[notebook]](https://www.kaggle.com/lnhtrang/single-cell-patterns)\n\n1. **The Previous Human Protein Atlas Competition** [[Discussion]](https://www.kaggle.com/c/hpa-single-cell-image-classification/discussion/214518)"},{"metadata":{},"cell_type":"markdown","source":"# 8. <a id='7'>Reference👀</a>\n[Table of cotents](#0.1)\n\n* https://www.kaggle.com/allunia/protein-atlas-exploration-and-baseline\n* https://www.kaggle.com/lnhtrang/hpa-public-data-download-and-hpacellseg/notebook\n* https://www.kaggle.com/thedrcat/hpa-single-cell-classification-eda\n* [mAP](https://www.kaggle.com/c/hpa-single-cell-image-classification/discussion/219885)"}],"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":4,"nbformat_minor":4}