{
  "id": 216926,
  "title": "Single-Stage Submission Approaches Overview [0.354 LB]",
  "url": "/competitions/hpa-single-cell-image-classification/discussion/216926",
  "author_name": "Darien Schettler",
  "post_date": "2021-02-04T14:51:26.960000",
  "votes": 46,
  "comment_count": 27,
  "views": 0,
  "content": "<hr>\n<h3>EDIT ––&nbsp;RECENT SUBMISSION DETAILS BELOW</h3>\n<p><em>As of March 2nd, 2021</em></p>\n<hr>\n<p><strong>ORIGINAL SUBMISSION</strong></p>\n<ul>\n<li><strong>Scores 0.025</strong></li>\n<li>Multi-Class Classification</li>\n<li>Clipped Class Weighting</li>\n<li>CellSegmentator at 0.5 Scale (no padding)</li>\n<li>Confidence Threshold of 0.25 for Model Inference (EfficientNet B0)</li>\n<li>Tile size of 256x256</li>\n</ul>\n<p></p>\n<p><br></p>\n<p><strong>V2 SUBMISSION</strong></p>\n<ul>\n<li><strong>Scores 0.121</strong></li>\n<li>Multi-Label Classification</li>\n<li>Clipped Class Weighting</li>\n<li>CellSegmentator at 0.5 Scale (no padding)</li>\n<li>Confidence Threshold of 0.25 for Model Inference (EfficientNet B0)</li>\n<li>Tile size of 128x128</li>\n</ul>\n<p><br></p>\n<p><strong>V3 SUBMISSION</strong></p>\n<ul>\n<li><strong>Scores 0.201</strong></li>\n<li>Multi-Label Classification</li>\n<li>Clipped Class Weighting</li>\n<li>CellSegmentator at 0.25 Scale (w/ padding)</li>\n<li>Confidence Threshold of 0.25 for Model Inference (EfficientNet B0)</li>\n<li>Tile size of 128x128</li>\n<li>Massive refactoring of code reduced inference time from <em>9 hours</em> to <em>6 hours</em> (hidden test set)<ul>\n<li>This should not have impacted the score… but I can't be certain either way.</li></ul></li>\n</ul>\n<p><br></p>\n<p><strong>V4 SUBMISSION</strong></p>\n<ul>\n<li><strong>Scores 0.255</strong></li>\n<li>Multi-Label Classification</li>\n<li>No Class Weighting</li>\n<li>CellSegmentator at 0.25 Scale (w/ padding)</li>\n<li>Confidence Threshold of 0.25 for Model Inference (EfficientNet B1 – Dropout at 0.25)</li>\n<li>Tile size of 224x224</li>\n<li>TTA (Test Time Augmentation)<ul>\n<li>3 Repeats + The Original Image</li>\n<li>Flipping, Rotation, Brightness, Contrast, Saturation (same as training)</li></ul></li>\n</ul>\n<p><br></p>\n<p><strong>V5 SUBMISSION</strong></p>\n<ul>\n<li><strong>Scores 0.232</strong></li>\n<li>Multi-Label Classification</li>\n<li>No Class Weighting</li>\n<li>CellSegmentator at 0.25 Scale (w/ padding)</li>\n<li>Confidence Threshold of 0.25 for Model Inference (EfficientNet B1 – Dropout at <strong>0.05</strong>)</li>\n<li>Tile size of 224x224</li>\n<li>TTA (Test Time Augmentation)<ul>\n<li>3 Repeats + The Original Image</li>\n<li>Flipping, Rotation, Brightness, Contrast, Saturation (same as training)</li></ul></li>\n</ul>\n<p><br></p>\n<p><strong>V6 SUBMISSION</strong></p>\n<ul>\n<li><strong>Scores 0.320</strong></li>\n<li>Multi-Label Classification</li>\n<li>No Class Weighting</li>\n<li>CellSegmentator at 0.25 Scale (w/ padding)(<strong>updated version</strong>)</li>\n<li>Confidence Threshold of essentially 0 for Model Inference (EfficientNet B1 – Dropout at <strong>0.25</strong>)</li>\n<li>Tile size of 224x224</li>\n<li>TTA (Test Time Augmentation)<ul>\n<li>10 Repeats + The Original Image</li>\n<li>Flipping, Rotation, Brightness, Contrast, Saturation (same as training)</li></ul></li>\n</ul>\n<p><br></p>\n<p><strong>V7 SUBMISSION</strong></p>\n<ul>\n<li><strong>Scores 0.337</strong></li>\n<li>Multi-Label Classification</li>\n<li>No Class Weighting</li>\n<li>CellSegmentator at 0.25 Scale (w/ padding)(<strong>updated version</strong>)</li>\n<li>Confidence Threshold of 0 for Model Inference (see <a href=\"https://www.kaggle.com/c/hpa-single-cell-image-classification/discussion/217158\" target=\"_blank\">Tito's post</a>)<ul>\n<li>EfficientNet B2</li>\n<li>Dropout at <strong>0.5</strong> </li>\n<li>Added batch normalization</li>\n<li>Additional dense layer followed by dropout of <strong>0.25</strong></li></ul></li>\n<li>Tile size of 224x224</li>\n<li>TTA (Test Time Augmentation)<ul>\n<li>8 Repeats + The Original Image</li>\n<li>Flipping, Rotation, Brightness, Contrast, Saturation (same as training)</li></ul></li>\n</ul>\n<p><br><br>\n<br></p>\n<p><strong>V8 SUBMISSION ––&nbsp;FINAL PUBLIC SINGLE STAGE SUBMISSION</strong></p>\n<ul>\n<li><strong>Scores 0.352</strong></li>\n<li>Multi-Label Classification</li>\n<li>No Class Weighting</li>\n<li>CellSegmentator at 0.25 Scale (w/ padding)(<strong>updated version</strong>)</li>\n<li>Confidence Threshold of 0 for Model Inference (see <a href=\"https://www.kaggle.com/c/hpa-single-cell-image-classification/discussion/217158\" target=\"_blank\">Tito's post</a>)<ul>\n<li>EfficientNet B2</li>\n<li>Dropout at <strong>0.5</strong> </li>\n<li>Added batch normalization</li>\n<li>Additional dense layer followed by dropout of <strong>0.25</strong></li></ul></li>\n<li>Tile size of 224x224</li>\n<li>TTA (Test Time Augmentation)<ul>\n<li>8 Repeats + The Original Image</li>\n<li>Flipping, Rotation, Brightness, Contrast, Saturation (same as training)</li></ul></li>\n<li><strong><em>Additional 7 epochs of fine-tuning from V7 checkpoint</em></strong></li>\n</ul>\n<hr>\n<p><br></p>\n<h3>APPROACH OVERVIEW</h3>\n<hr>\n<p><strong>TRAINING</strong></p>\n<ol>\n<li>Identify slide-level images containing only one label</li>\n<li>Segment slide-level images (get RLEs for all cells in all applicable slide-level images)</li>\n<li>Crop RGBY image around each cell</li>\n<li>Pad each RGBY tile to be square</li>\n<li>Resize each RGBY tile to be (256px by 256px) (<em>drop yellow channel</em>)</li>\n<li>Separate the channels and store them as separate datasets<br>\n (I didn't do this… as a result, my validation loss is all over the place. Not ideal!)</li>\n<li>Augment the dataset (rotation, flipping (horizontal and vertical), brightness, contrast, saturation)</li>\n<li>Train a model (EfficientNet B0, B1 or B2) to perform multi-label classification on these tile-level images</li>\n</ol>\n<p><em>OTHER TBD ---&gt; Leverage TFRecords Instead of Images to use both TPU and GPU quota</em></p>\n<p>--</p>\n<p><strong>INFERENCE</strong></p>\n<ol>\n<li>Use CellSegmentator to do instance segmentation on images in test-dataset (or leverage precomputed cell masks for public dataset probing … this won't work for final submissions)</li>\n<li>Record this mask in the appropriate format for later submission (or access directly from premade CSV)</li>\n<li>Identify the bounding box for each mask to be able to crop each cell (padded) (or access directly from the premade CSV)</li>\n<li>Crop RGBY image around each cell</li>\n<li>Pad each RGBY tile to be square (<em>drop yellow channel</em>)</li>\n<li>Resize each RGBY tile to be (224px by 224px … or similar)</li>\n<li>Infer on all tiles on each slide (all tiles will be passed as a batch for better latency)</li>\n<li>Do TTA and average results</li>\n<li>Combine cell-level classification with segmentation as RLE when submitting</li>\n<li>Make <strong><code>submission.csv</code></strong> file</li>\n</ol>\n<p><br></p>\n<h3>NOTEBOOK LINKS</h3>\n<hr>\n<p>I created and made public my notebooks showing my approach for <a href=\"https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-inference\" target=\"_blank\">inference</a> and <a href=\"https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-training\" target=\"_blank\">training</a>.</p>\n<ul>\n<li><a href=\"https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-training\" target=\"_blank\">TRAINING</a> --&gt; <a href=\"https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-training\" target=\"_blank\">https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-training</a></li>\n<li><a href=\"https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-inference\" target=\"_blank\">INFERENCE</a> --&gt; <a href=\"https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-inference\" target=\"_blank\">https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-inference</a></li>\n</ul>\n<p><br><br>\n<br></p>\n<p><em>Thanks for taking the time to read. I'm still learning and wanted to share with you all. Please give me as much feedback as possible (or ask questions) and I'll do my best to improve/share.</em></p>",
  "messages": [
    {
      "id": 1186033,
      "postDate": "2021-02-04T14:51:26.960Z",
      "content": "<hr>\n<h3>EDIT ––&nbsp;RECENT SUBMISSION DETAILS BELOW</h3>\n<p><em>As of March 2nd, 2021</em></p>\n<hr>\n<p><strong>ORIGINAL SUBMISSION</strong></p>\n<ul>\n<li><strong>Scores 0.025</strong></li>\n<li>Multi-Class Classification</li>\n<li>Clipped Class Weighting</li>\n<li>CellSegmentator at 0.5 Scale (no padding)</li>\n<li>Confidence Threshold of 0.25 for Model Inference (EfficientNet B0)</li>\n<li>Tile size of 256x256</li>\n</ul>\n<p></p>\n<p><br></p>\n<p><strong>V2 SUBMISSION</strong></p>\n<ul>\n<li><strong>Scores 0.121</strong></li>\n<li>Multi-Label Classification</li>\n<li>Clipped Class Weighting</li>\n<li>CellSegmentator at 0.5 Scale (no padding)</li>\n<li>Confidence Threshold of 0.25 for Model Inference (EfficientNet B0)</li>\n<li>Tile size of 128x128</li>\n</ul>\n<p><br></p>\n<p><strong>V3 SUBMISSION</strong></p>\n<ul>\n<li><strong>Scores 0.201</strong></li>\n<li>Multi-Label Classification</li>\n<li>Clipped Class Weighting</li>\n<li>CellSegmentator at 0.25 Scale (w/ padding)</li>\n<li>Confidence Threshold of 0.25 for Model Inference (EfficientNet B0)</li>\n<li>Tile size of 128x128</li>\n<li>Massive refactoring of code reduced inference time from <em>9 hours</em> to <em>6 hours</em> (hidden test set)<ul>\n<li>This should not have impacted the score… but I can't be certain either way.</li></ul></li>\n</ul>\n<p><br></p>\n<p><strong>V4 SUBMISSION</strong></p>\n<ul>\n<li><strong>Scores 0.255</strong></li>\n<li>Multi-Label Classification</li>\n<li>No Class Weighting</li>\n<li>CellSegmentator at 0.25 Scale (w/ padding)</li>\n<li>Confidence Threshold of 0.25 for Model Inference (EfficientNet B1 – Dropout at 0.25)</li>\n<li>Tile size of 224x224</li>\n<li>TTA (Test Time Augmentation)<ul>\n<li>3 Repeats + The Original Image</li>\n<li>Flipping, Rotation, Brightness, Contrast, Saturation (same as training)</li></ul></li>\n</ul>\n<p><br></p>\n<p><strong>V5 SUBMISSION</strong></p>\n<ul>\n<li><strong>Scores 0.232</strong></li>\n<li>Multi-Label Classification</li>\n<li>No Class Weighting</li>\n<li>CellSegmentator at 0.25 Scale (w/ padding)</li>\n<li>Confidence Threshold of 0.25 for Model Inference (EfficientNet B1 – Dropout at <strong>0.05</strong>)</li>\n<li>Tile size of 224x224</li>\n<li>TTA (Test Time Augmentation)<ul>\n<li>3 Repeats + The Original Image</li>\n<li>Flipping, Rotation, Brightness, Contrast, Saturation (same as training)</li></ul></li>\n</ul>\n<p><br></p>\n<p><strong>V6 SUBMISSION</strong></p>\n<ul>\n<li><strong>Scores 0.320</strong></li>\n<li>Multi-Label Classification</li>\n<li>No Class Weighting</li>\n<li>CellSegmentator at 0.25 Scale (w/ padding)(<strong>updated version</strong>)</li>\n<li>Confidence Threshold of essentially 0 for Model Inference (EfficientNet B1 – Dropout at <strong>0.25</strong>)</li>\n<li>Tile size of 224x224</li>\n<li>TTA (Test Time Augmentation)<ul>\n<li>10 Repeats + The Original Image</li>\n<li>Flipping, Rotation, Brightness, Contrast, Saturation (same as training)</li></ul></li>\n</ul>\n<p><br></p>\n<p><strong>V7 SUBMISSION</strong></p>\n<ul>\n<li><strong>Scores 0.337</strong></li>\n<li>Multi-Label Classification</li>\n<li>No Class Weighting</li>\n<li>CellSegmentator at 0.25 Scale (w/ padding)(<strong>updated version</strong>)</li>\n<li>Confidence Threshold of 0 for Model Inference (see <a href=\"https://www.kaggle.com/c/hpa-single-cell-image-classification/discussion/217158\" target=\"_blank\">Tito's post</a>)<ul>\n<li>EfficientNet B2</li>\n<li>Dropout at <strong>0.5</strong> </li>\n<li>Added batch normalization</li>\n<li>Additional dense layer followed by dropout of <strong>0.25</strong></li></ul></li>\n<li>Tile size of 224x224</li>\n<li>TTA (Test Time Augmentation)<ul>\n<li>8 Repeats + The Original Image</li>\n<li>Flipping, Rotation, Brightness, Contrast, Saturation (same as training)</li></ul></li>\n</ul>\n<p><br><br>\n<br></p>\n<p><strong>V8 SUBMISSION ––&nbsp;FINAL PUBLIC SINGLE STAGE SUBMISSION</strong></p>\n<ul>\n<li><strong>Scores 0.352</strong></li>\n<li>Multi-Label Classification</li>\n<li>No Class Weighting</li>\n<li>CellSegmentator at 0.25 Scale (w/ padding)(<strong>updated version</strong>)</li>\n<li>Confidence Threshold of 0 for Model Inference (see <a href=\"https://www.kaggle.com/c/hpa-single-cell-image-classification/discussion/217158\" target=\"_blank\">Tito's post</a>)<ul>\n<li>EfficientNet B2</li>\n<li>Dropout at <strong>0.5</strong> </li>\n<li>Added batch normalization</li>\n<li>Additional dense layer followed by dropout of <strong>0.25</strong></li></ul></li>\n<li>Tile size of 224x224</li>\n<li>TTA (Test Time Augmentation)<ul>\n<li>8 Repeats + The Original Image</li>\n<li>Flipping, Rotation, Brightness, Contrast, Saturation (same as training)</li></ul></li>\n<li><strong><em>Additional 7 epochs of fine-tuning from V7 checkpoint</em></strong></li>\n</ul>\n<hr>\n<p><br></p>\n<h3>APPROACH OVERVIEW</h3>\n<hr>\n<p><strong>TRAINING</strong></p>\n<ol>\n<li>Identify slide-level images containing only one label</li>\n<li>Segment slide-level images (get RLEs for all cells in all applicable slide-level images)</li>\n<li>Crop RGBY image around each cell</li>\n<li>Pad each RGBY tile to be square</li>\n<li>Resize each RGBY tile to be (256px by 256px) (<em>drop yellow channel</em>)</li>\n<li>Separate the channels and store them as separate datasets<br>\n (I didn't do this… as a result, my validation loss is all over the place. Not ideal!)</li>\n<li>Augment the dataset (rotation, flipping (horizontal and vertical), brightness, contrast, saturation)</li>\n<li>Train a model (EfficientNet B0, B1 or B2) to perform multi-label classification on these tile-level images</li>\n</ol>\n<p><em>OTHER TBD ---&gt; Leverage TFRecords Instead of Images to use both TPU and GPU quota</em></p>\n<p>--</p>\n<p><strong>INFERENCE</strong></p>\n<ol>\n<li>Use CellSegmentator to do instance segmentation on images in test-dataset (or leverage precomputed cell masks for public dataset probing … this won't work for final submissions)</li>\n<li>Record this mask in the appropriate format for later submission (or access directly from premade CSV)</li>\n<li>Identify the bounding box for each mask to be able to crop each cell (padded) (or access directly from the premade CSV)</li>\n<li>Crop RGBY image around each cell</li>\n<li>Pad each RGBY tile to be square (<em>drop yellow channel</em>)</li>\n<li>Resize each RGBY tile to be (224px by 224px … or similar)</li>\n<li>Infer on all tiles on each slide (all tiles will be passed as a batch for better latency)</li>\n<li>Do TTA and average results</li>\n<li>Combine cell-level classification with segmentation as RLE when submitting</li>\n<li>Make <strong><code>submission.csv</code></strong> file</li>\n</ol>\n<p><br></p>\n<h3>NOTEBOOK LINKS</h3>\n<hr>\n<p>I created and made public my notebooks showing my approach for <a href=\"https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-inference\" target=\"_blank\">inference</a> and <a href=\"https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-training\" target=\"_blank\">training</a>.</p>\n<ul>\n<li><a href=\"https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-training\" target=\"_blank\">TRAINING</a> --&gt; <a href=\"https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-training\" target=\"_blank\">https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-training</a></li>\n<li><a href=\"https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-inference\" target=\"_blank\">INFERENCE</a> --&gt; <a href=\"https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-inference\" target=\"_blank\">https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-inference</a></li>\n</ul>\n<p><br><br>\n<br></p>\n<p><em>Thanks for taking the time to read. I'm still learning and wanted to share with you all. Please give me as much feedback as possible (or ask questions) and I'll do my best to improve/share.</em></p>",
      "rawMarkdown": "---\n\n<h3>EDIT –– RECENT SUBMISSION DETAILS BELOW</h3>\n*As of March 2nd, 2021*\n\n---\n\n**ORIGINAL SUBMISSION**\n\n* **Scores 0.025**\n* Multi-Class Classification\n* Clipped Class Weighting\n* CellSegmentator at 0.5 Scale (no padding)\n* Confidence Threshold of 0.25 for Model Inference (EfficientNet B0)\n* Tile size of 256x256\n\n</div>\n\n\n\n\n<br>\n\n**V2 SUBMISSION**\n* **Scores 0.121**\n* Multi-Label Classification\n* Clipped Class Weighting\n* CellSegmentator at 0.5 Scale (no padding)\n* Confidence Threshold of 0.25 for Model Inference (EfficientNet B0)\n* Tile size of 128x128\n\n<br>\n\n**V3 SUBMISSION**\n* **Scores 0.201**\n* Multi-Label Classification\n* Clipped Class Weighting\n* CellSegmentator at 0.25 Scale (w/ padding)\n* Confidence Threshold of 0.25 for Model Inference (EfficientNet B0)\n* Tile size of 128x128\n* Massive refactoring of code reduced inference time from *9 hours* to *6 hours* (hidden test set)\n  * This should not have impacted the score... but I can't be certain either way.\n\n<br>\n\n**V4 SUBMISSION**\n* **Scores 0.255**\n* Multi-Label Classification\n* No Class Weighting\n* CellSegmentator at 0.25 Scale (w/ padding)\n* Confidence Threshold of 0.25 for Model Inference (EfficientNet B1 – Dropout at 0.25)\n* Tile size of 224x224\n* TTA (Test Time Augmentation)\n  * 3 Repeats + The Original Image\n  * Flipping, Rotation, Brightness, Contrast, Saturation (same as training)\n\n<br>\n\n**V5 SUBMISSION**\n* **Scores 0.232**\n* Multi-Label Classification\n* No Class Weighting\n* CellSegmentator at 0.25 Scale (w/ padding)\n* Confidence Threshold of 0.25 for Model Inference (EfficientNet B1 – Dropout at **0.05**)\n* Tile size of 224x224\n* TTA (Test Time Augmentation)\n  * 3 Repeats + The Original Image\n  * Flipping, Rotation, Brightness, Contrast, Saturation (same as training)\n\n<br>\n\n**V6 SUBMISSION**\n* **Scores 0.320**\n* Multi-Label Classification\n* No Class Weighting\n* CellSegmentator at 0.25 Scale (w/ padding)(**updated version**)\n* Confidence Threshold of essentially 0 for Model Inference (EfficientNet B1 – Dropout at **0.25**)\n* Tile size of 224x224\n* TTA (Test Time Augmentation)\n  * 10 Repeats + The Original Image\n  * Flipping, Rotation, Brightness, Contrast, Saturation (same as training)\n\n<br>\n\n**V7 SUBMISSION**\n* **Scores 0.337**\n* Multi-Label Classification\n* No Class Weighting\n* CellSegmentator at 0.25 Scale (w/ padding)(**updated version**)\n* Confidence Threshold of 0 for Model Inference (see [Tito's post](https://www.kaggle.com/c/hpa-single-cell-image-classification/discussion/217158))\n  * EfficientNet B2\n  * Dropout at **0.5** \n  * Added batch normalization\n  * Additional dense layer followed by dropout of **0.25**\n* Tile size of 224x224\n* TTA (Test Time Augmentation)\n  * 8 Repeats + The Original Image\n  * Flipping, Rotation, Brightness, Contrast, Saturation (same as training)\n\n<br>\n<br>\n\n**V8 SUBMISSION –– FINAL PUBLIC SINGLE STAGE SUBMISSION**\n* **Scores 0.352**\n* Multi-Label Classification\n* No Class Weighting\n* CellSegmentator at 0.25 Scale (w/ padding)(**updated version**)\n* Confidence Threshold of 0 for Model Inference (see [Tito's post](https://www.kaggle.com/c/hpa-single-cell-image-classification/discussion/217158))\n  * EfficientNet B2\n  * Dropout at **0.5** \n  * Added batch normalization\n  * Additional dense layer followed by dropout of **0.25**\n* Tile size of 224x224\n* TTA (Test Time Augmentation)\n  * 8 Repeats + The Original Image\n  * Flipping, Rotation, Brightness, Contrast, Saturation (same as training)\n* ***Additional 7 epochs of fine-tuning from V7 checkpoint***\n\n---\n\n<br>\n\n<h3 style=\"text-align: font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: navy; background-color: #ffffff;\">APPROACH OVERVIEW</h3>\n\n---\n\n**TRAINING**\n\n1. Identify slide-level images containing only one label\n2. Segment slide-level images (get RLEs for all cells in all applicable slide-level images)\n3. Crop RGBY image around each cell\n4. Pad each RGBY tile to be square\n5. Resize each RGBY tile to be (256px by 256px) (*drop yellow channel*)\n6. Separate the channels and store them as separate datasets\n~~7. Ensure stratification in the validation dataset even if it doesn't follow a similar distribution to the training dataset~~ (I didn't do this... as a result, my validation loss is all over the place. Not ideal!)\n8. Augment the dataset (rotation, flipping (horizontal and vertical), brightness, contrast, saturation)\n9. Train a model (EfficientNet B0, B1 or B2) to perform multi-label classification on these tile-level images\n\n*OTHER TBD ---> Leverage TFRecords Instead of Images to use both TPU and GPU quota*\n\n--\n\n**INFERENCE**\n\n1. Use CellSegmentator to do instance segmentation on images in test-dataset (or leverage precomputed cell masks for public dataset probing ... this won't work for final submissions)\n2. Record this mask in the appropriate format for later submission (or access directly from premade CSV)\n3. Identify the bounding box for each mask to be able to crop each cell (padded) (or access directly from the premade CSV)\n4. Crop RGBY image around each cell\n5. Pad each RGBY tile to be square (*drop yellow channel*)\n6. Resize each RGBY tile to be (224px by 224px ... or similar)\n7. Infer on all tiles on each slide (all tiles will be passed as a batch for better latency)\n8. Do TTA and average results\n9. Combine cell-level classification with segmentation as RLE when submitting\n10. Make **`submission.csv`** file\n\n<br>\n\n<h3 style=\"text-align: font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: navy; background-color: #ffffff;\">NOTEBOOK LINKS</h3>\n\n---\nI created and made public my notebooks showing my approach for [inference](https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-inference) and [training](https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-training).\n- [TRAINING](https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-training) --> https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-training\n- [INFERENCE](https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-inference) --> https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-inference\n\n<br>\n<br>\n\n*Thanks for taking the time to read. I'm still learning and wanted to share with you all. Please give me as much feedback as possible (or ask questions) and I'll do my best to improve/share.*",
      "votes": 44
    },
    {
      "id": 1187085,
      "postDate": "2021-02-05T07:58:07.463Z",
      "content": "<p>Hi Darien,</p>\n<p>thank you for sharing these experiments!<br>\n<a href=\"https://www.kaggle.com/c/hpa-single-cell-image-classification/overview\" target=\"_blank\">The main page</a> states that \"This is a weakly supervised <strong>multi-label classification</strong> problem\". </p>\n<p>Therefore, I'd suggest to try replacing softmax activation in your training notebook with sigmoid activation. </p>\n<p><code>def add_head_to_bb(bb, n_classes=19, dropout=0.25):\n    x = tf.keras.layers.Dropout(dropout)(bb.output)\n    output = tf.keras.layers.Dense(n_classes, activation=\"</code><strong></strong><code>\")(x)\n    return tf.keras.Model(inputs=bb.inputs, outputs=output)</code></p>\n<p>Currently, if your model outputs large logits for two classes, e.g. for both Nucleoplasm and Cytosol, then your final predictions would be around 0.5 for both classes. With sigmoid activation function, you'll allow your net to simultaneously predict 90% probability of protein being located in the Nucleoplasm and 90% prob. of protein in the Cytosol.</p>\n<p>And then I'd modify the inference notebook accordingly, to predict multiple labels instead of </p>\n<p><code>#     ######### MODEL PREDICT #########\n    preds = inference_model.predict(np.array(cell_tiles, dtype=np.uint8))\n    confs = preds.max(axis=1)\n    preds = preds.argmax(axis=1)</code></p>\n<p>Fingers crossed!</p>",
      "rawMarkdown": "Hi Darien,\n\nthank you for sharing these experiments!\n[The main page](https://www.kaggle.com/c/hpa-single-cell-image-classification/overview) states that \"This is a weakly supervised **multi-label classification** problem\". \n\nTherefore, I'd suggest to try replacing softmax activation in your training notebook with sigmoid activation. \n\n`def add_head_to_bb(bb, n_classes=19, dropout=0.25):\n    x = tf.keras.layers.Dropout(dropout)(bb.output)\n    output = tf.keras.layers.Dense(n_classes, activation=\"`**~~`softmax`~~**`\")(x)\n    return tf.keras.Model(inputs=bb.inputs, outputs=output)`\n\nCurrently, if your model outputs large logits for two classes, e.g. for both Nucleoplasm and Cytosol, then your final predictions would be around 0.5 for both classes. With sigmoid activation function, you'll allow your net to simultaneously predict 90% probability of protein being located in the Nucleoplasm and 90% prob. of protein in the Cytosol.\n\nAnd then I'd modify the inference notebook accordingly, to predict multiple labels instead of \n\n```#     ######### MODEL PREDICT #########\n    preds = inference_model.predict(np.array(cell_tiles, dtype=np.uint8))\n    confs = preds.max(axis=1)\n    preds = preds.argmax(axis=1)```\n\nFingers crossed!",
      "votes": 4,
      "replies": [
        {
          "id": 1187294,
          "postDate": "2021-02-05T10:53:31.280Z",
          "content": "<p>I will give this a try! Thank you for the detailed feedback. </p>\n<p>I will give you credit/reference when I update on this approach.</p>\n<p>Thanks Raman!</p>",
          "rawMarkdown": "I will give this a try! Thank you for the detailed feedback. \n\nI will give you credit/reference when I update on this approach.\n\nThanks Raman!",
          "votes": 1
        },
        {
          "id": 1187372,
          "postDate": "2021-02-05T11:41:23.253Z",
          "content": "<p>Darien, no problem at all😊</p>\n<p>I'd like to try out submission using RBGY-based classifier (sigmoid activation) and cell-level masked images as well, just in case you might be interested, here's <a href=\"https://www.kaggle.com/samusram/hpa-pretrained-keras-rgb-model-rgby\" target=\"_blank\">a corresponding notebook</a>.</p>",
          "rawMarkdown": "Darien, no problem at all😊\n\nI'd like to try out submission using RBGY-based classifier (sigmoid activation) and cell-level masked images as well, just in case you might be interested, here's [a corresponding notebook](https://www.kaggle.com/samusram/hpa-pretrained-keras-rgb-model-rgby).",
          "votes": 1
        },
        {
          "id": 1191510,
          "postDate": "2021-02-08T13:59:39.343Z",
          "content": "<p>This is awesome to see. It makes me hopeful that I should be able to rerun with much greater success in the future! Great job on your notebook as well!</p>",
          "rawMarkdown": "This is awesome to see. It makes me hopeful that I should be able to rerun with much greater success in the future! Great job on your notebook as well!",
          "votes": 1
        }
      ]
    },
    {
      "id": 1227430,
      "postDate": "2021-03-05T14:18:34.127Z",
      "content": "<p>Hi again, could you tell the essential difference between your V5 and V6 submissions? The only difference I see is increased number of TTAs, but I doubt this difference resulted in huge 0.1 boost. Thanks!</p>",
      "rawMarkdown": "Hi again, could you tell the essential difference between your V5 and V6 submissions? The only difference I see is increased number of TTAs, but I doubt this difference resulted in huge 0.1 boost. Thanks!\n",
      "votes": 1,
      "replies": [
        {
          "id": 1227527,
          "postDate": "2021-03-05T16:10:26.987Z",
          "content": "<p>There are two differences in addition to the TTA:</p>\n<hr>\n<ol>\n<li><p>Change confidence threshold from 0.25 to essentially 0 (it should be 0… read <a href=\"https://www.kaggle.com/c/hpa-single-cell-image-classification/discussion/217158\" target=\"_blank\">Tito's post</a> for clarification on why). <strong>This is probably responsible for the lions-share of the gain.</strong></p></li>\n<li><p>Use the updated version of the CellSegmentator tool. (See the <a href=\"https://www.kaggle.com/linshokaku/faster-hpa-cell-segmentation\" target=\"_blank\">Faster Segmentation</a> and <a href=\"https://www.kaggle.com/samusram/even-faster-hpa-cell-segmentation\" target=\"_blank\">Even Faster Segmentation</a> Notebooks… I used the implementation in the <a href=\"https://www.kaggle.com/samusram/even-faster-hpa-cell-segmentation\" target=\"_blank\">Even Faster Segmentation notebook</a>.) <strong>This is probably responsible for only a small part of the gain</strong> as the mask output difference between this and the original tool is minimal (while the latency improvement is massive).</p></li>\n</ol>\n<hr>\n<p>I hope this clarifies/helps!</p>",
          "rawMarkdown": "There are two differences in addition to the TTA:\n\n---\n\n1. Change confidence threshold from 0.25 to essentially 0 (it should be 0... read [Tito's post](https://www.kaggle.com/c/hpa-single-cell-image-classification/discussion/217158) for clarification on why). **This is probably responsible for the lions-share of the gain.**\n\n2. Use the updated version of the CellSegmentator tool. (See the [Faster Segmentation](https://www.kaggle.com/linshokaku/faster-hpa-cell-segmentation) and [Even Faster Segmentation](https://www.kaggle.com/samusram/even-faster-hpa-cell-segmentation) Notebooks... I used the implementation in the [Even Faster Segmentation notebook](https://www.kaggle.com/samusram/even-faster-hpa-cell-segmentation).) **This is probably responsible for only a small part of the gain** as the mask output difference between this and the original tool is minimal (while the latency improvement is massive).\n\n---\n\nI hope this clarifies/helps!",
          "votes": 2
        },
        {
          "id": 1227529,
          "postDate": "2021-03-05T16:12:25.860Z",
          "content": "<p>Ah yeah, conf thresh is the reason for sure. Thanks a lot)</p>",
          "rawMarkdown": "Ah yeah, conf thresh is the reason for sure. Thanks a lot)"
        }
      ]
    },
    {
      "id": 1198931,
      "postDate": "2021-02-13T12:24:52.820Z",
      "content": "<p>Thanks for sharing ur experiment results, hope u could keep receiving incremental improvements over time and look forward to more of ur news on what works and what doesn’t. </p>\n<p>There is one thing I would like to ask though: <br>\nWhat do u mean by “Clipped Class Weighting”? </p>",
      "rawMarkdown": "Thanks for sharing ur experiment results, hope u could keep receiving incremental improvements over time and look forward to more of ur news on what works and what doesn’t. \n\nThere is one thing I would like to ask though: \nWhat do u mean by “Clipped Class Weighting”? ",
      "votes": 1,
      "replies": [
        {
          "id": 1200419,
          "postDate": "2021-02-14T16:37:08.950Z",
          "content": "<p>Hey! Thanks for commenting, I hope I keep improving and can share it with everyone too.</p>\n<p><br></p>\n<p><strong><em>Clipped Class Weighting</em></strong> is my term for clipping class counts before calculating the class weighting to reduce the impact of extreme class imbalance. I will demonstrate below with a toy example…</p>\n<hr>\n<p><b></b></p>\n<pre><code>class_counts = {\n    \"c_1\":1,\n    \"c_2\":10,\n    \"c_3\":100,\n    \"c_4\":1000,\n    \"c_5\":10000,\n    \"c_6\":100000,\n}\n\n# Calculate dynamically or whatever...\nMIN_COUNT = 1\nCLIP_MAX_COUNT = 100\n\n# Get clipped class counts\nclipped_class_counts = {k:min(v, MAX_COUNT) for k,v in class_counts.items()}\n# &gt;&gt;&gt; {\"c_1\":1, \"c_2\":10, \"c_3\":100, \"c_4\":100, \"c_5\":100, \"c_6\":100}\n\n# Calculate Regular Class Weighting\nclass_wts = {k:MIN_COUNT/v for k,v in class_counts.items()}\n# &gt;&gt;&gt; {\"c_1\":1, \"c_2\":0.1, \"c_3\":0.01, \"c_4\":0.001, \"c_5\":0.0001, \"c_6\":0.00001}\n\n# Calculate Clipped Class Weighting\nclipped_class_wts = {k:MIN_COUNT/v for k,v in clipped_class_counts.items()}\n# &gt;&gt;&gt; {\"c_1\":1, \"c_2\":0.1, \"c_3\":0.01, \"c_4\":0.01, \"c_5\":0.01, \"c_6\":0.01}\n</code></pre>\n<p></p>\n<hr>\n<p>Now when we pass the class weights to the <strong><code>model.fit()</code></strong> function, the weighting won't be AS extreme. Since we have SO FEW examples in the <strong>mitotic spindle</strong> class, the class weighting is very extreme if you do not clip them.</p>\n<p><strong>Hope this helps!</strong></p>",
          "rawMarkdown": "Hey! Thanks for commenting, I hope I keep improving and can share it with everyone too.\n\n<br>\n\n***Clipped Class Weighting*** is my term for clipping class counts before calculating the class weighting to reduce the impact of extreme class imbalance. I will demonstrate below with a toy example...\n\n---\n\n<b>\n\n```python\n\nclass_counts = {\n    \"c_1\":1,\n    \"c_2\":10,\n    \"c_3\":100,\n    \"c_4\":1000,\n    \"c_5\":10000,\n    \"c_6\":100000,\n}\n\n# Calculate dynamically or whatever...\nMIN_COUNT = 1\nCLIP_MAX_COUNT = 100\n\n# Get clipped class counts\nclipped_class_counts = {k:min(v, MAX_COUNT) for k,v in class_counts.items()}\n# >>> {\"c_1\":1, \"c_2\":10, \"c_3\":100, \"c_4\":100, \"c_5\":100, \"c_6\":100}\n\n# Calculate Regular Class Weighting\nclass_wts = {k:MIN_COUNT/v for k,v in class_counts.items()}\n# >>> {\"c_1\":1, \"c_2\":0.1, \"c_3\":0.01, \"c_4\":0.001, \"c_5\":0.0001, \"c_6\":0.00001}\n\n# Calculate Clipped Class Weighting\nclipped_class_wts = {k:MIN_COUNT/v for k,v in clipped_class_counts.items()}\n# >>> {\"c_1\":1, \"c_2\":0.1, \"c_3\":0.01, \"c_4\":0.01, \"c_5\":0.01, \"c_6\":0.01}\n```\n\n</b>\n\n---\n\nNow when we pass the class weights to the **`model.fit()`** function, the weighting won't be AS extreme. Since we have SO FEW examples in the **mitotic spindle** class, the class weighting is very extreme if you do not clip them.\n\n**Hope this helps!**",
          "votes": 2
        }
      ]
    },
    {
      "id": 1186518,
      "postDate": "2021-02-04T21:41:14.263Z",
      "content": "<p>I've submitted the similar approach, and the score is close to yours. I've no idea why this approach works that bad. Only assumption is that almost all cells in the images of the hidden test set have multiple labels. Any thoughts why the method doesn't work almost at all?</p>",
      "rawMarkdown": "I've submitted the similar approach, and the score is close to yours. I've no idea why this approach works that bad. Only assumption is that almost all cells in the images of the hidden test set have multiple labels. Any thoughts why the method doesn't work almost at all?",
      "votes": 1,
      "replies": [
        {
          "id": 1186536,
          "postDate": "2021-02-04T21:59:50.187Z",
          "content": "<p>My guess is that what you described is true (many multi-label images). This may have been specifically called out by the competition hosts in a different thread. I think the basic idea was that the testing dataset has higher <a href=\"https://en.wikipedia.org/wiki/Single-cell_variability\" target=\"_blank\"><strong>SCV (Single Cell Variability)</strong></a> than the training dataset. This means that having a system that only predicts a single label may be a weak solution.</p>\n<p><strong>EDIT</strong>: Providing the direct quote from <a href=\"https://www.kaggle.com/lnhtrang/single-cell-patterns\" target=\"_blank\"><strong>this notebook about single-cell patterns</strong></a>.</p>\n<blockquote>\n  <p>\"In the hidden test set of this challenge, we purposely chose images with high single cell variation (SCV). Therefore I believe you won’t gain significant advantages with a metric learning approach (like the winning solution last challenge). Good luck and enjoy!\"</p>\n</blockquote>\n<hr>\n<p><br></p>\n<p><strong>Additionally</strong>, I think labelling all cells in a slide with the image-level label is a nieve approach. When I investigated I found that many of the cells in a given image were actually negative. I plan to implement a heuristic to remap certain cells to be negative.</p>\n<p>Take this image from the <strong>Aggresome</strong> class…</p>\n<hr>\n<p><img src=\"https://i.ibb.co/Q62H6q1/Screen-Shot-2021-02-04-at-4-53-17-PM.png\"></p>\n<hr>\n<p>We can easily see that there may be 25+ cells in this image, however, there are only half that many bright green dots (what I take to be indicative of protein localized in the Aggresome organelle structure). In this case, with nieve labelling, we are probably adding 25-50% to our classifier tile-level dataset that are incorrectly labelled as <strong>Aggresome</strong> when they should be labelled as <strong>Negative</strong></p>\n<hr>\n<p><br></p>\n<p>This was just my take, I may be wrong though. Hope this helps! Thanks for commenting!</p>",
          "rawMarkdown": "My guess is that what you described is true (many multi-label images). This may have been specifically called out by the competition hosts in a different thread. I think the basic idea was that the testing dataset has higher [**SCV (Single Cell Variability)**](https://en.wikipedia.org/wiki/Single-cell_variability) than the training dataset. This means that having a system that only predicts a single label may be a weak solution.\n\n**EDIT**: Providing the direct quote from [**this notebook about single-cell patterns**](https://www.kaggle.com/lnhtrang/single-cell-patterns).\n\n> \"In the hidden test set of this challenge, we purposely chose images with high single cell variation (SCV). Therefore I believe you won’t gain significant advantages with a metric learning approach (like the winning solution last challenge). Good luck and enjoy!\"\n\n---\n\n<br>\n\n**Additionally**, I think labelling all cells in a slide with the image-level label is a nieve approach. When I investigated I found that many of the cells in a given image were actually negative. I plan to implement a heuristic to remap certain cells to be negative.\n\nTake this image from the **Aggresome** class...\n\n---\n\n<img src=\"https://i.ibb.co/Q62H6q1/Screen-Shot-2021-02-04-at-4-53-17-PM.png\">\n\n---\n\nWe can easily see that there may be 25+ cells in this image, however, there are only half that many bright green dots (what I take to be indicative of protein localized in the Aggresome organelle structure). In this case, with nieve labelling, we are probably adding 25-50% to our classifier tile-level dataset that are incorrectly labelled as **Aggresome** when they should be labelled as **Negative**\n\n\n---\n\n<br>\n\nThis was just my take, I may be wrong though. Hope this helps! Thanks for commenting!",
          "votes": 3
        },
        {
          "id": 1186547,
          "postDate": "2021-02-04T22:12:53.860Z",
          "content": "<p>Also, I'm currently retraining the model (smaller model) for a bit longer with a better LR decay. So we shall see how that goes…</p>",
          "rawMarkdown": "Also, I'm currently retraining the model (smaller model) for a bit longer with a better LR decay. So we shall see how that goes..."
        },
        {
          "id": 1186548,
          "postDate": "2021-02-04T22:13:00.117Z",
          "content": "<p>I see, thanks for the quick response!</p>",
          "rawMarkdown": "I see, thanks for the quick response!"
        }
      ]
    },
    {
      "id": 1212957,
      "postDate": "2021-02-21T18:34:14.923Z",
      "content": "<p>Hi,</p>\n<p>I really appreciate for taking your time and putting this notebook. It is useful for beginners like me. I have a question. I read the segmentation are of two types called instance based and semantic based segmentation. So, based on your notebook I came to know the HPA tool does instance based segmentation. Correct me if I am wrong the HPA tool, while segmenting treats each cell as separate entity and does the segmentation?</p>",
      "rawMarkdown": "Hi,\n\nI really appreciate for taking your time and putting this notebook. It is useful for beginners like me. I have a question. I read the segmentation are of two types called instance based and semantic based segmentation. So, based on your notebook I came to know the HPA tool does instance based segmentation. Correct me if I am wrong the HPA tool, while segmenting treats each cell as separate entity and does the segmentation?",
      "votes": 2,
      "replies": [
        {
          "id": 1213003,
          "postDate": "2021-02-21T18:57:51.013Z",
          "content": "<p>Hi <a href=\"https://www.kaggle.com/strivathsav\" target=\"_blank\">@strivathsav</a>. You're quite welcome. I should have more updates later today. </p>\n<p>To your point, your understanding is 100% correct. </p>",
          "rawMarkdown": "Hi @strivathsav. You're quite welcome. I should have more updates later today. \n\nTo your point, your understanding is 100% correct. "
        }
      ]
    },
    {
      "id": 1249088,
      "postDate": "2021-03-23T05:13:17.803Z",
      "content": "<p>Hello,how to produce this dataset</p>",
      "rawMarkdown": "Hello,how to produce this dataset",
      "replies": [
        {
          "id": 1250096,
          "postDate": "2021-03-23T19:26:25.597Z",
          "content": "<p>Hi there <a href=\"https://www.kaggle.com/zekunn\" target=\"_blank\">@zekunn</a> … which dataset are you referring to? If you are referring to the one I trained on, the dataset can be found here…</p>\n<p><em>I created this dataset by using the CellSegmentator and cutting out the instances of each cell and padding to square before resizing to 256x256 pixels.</em></p>\n<hr>\n<p><strong>Dataset Links</strong></p>\n<p><a href=\"https://www.kaggle.com/dschettler8845/human-protein-atlas-red-cell-tile-dataset\" target=\"_blank\"><strong>Red Tiles</strong></a><br>\n<a href=\"https://www.kaggle.com/dschettler8845/human-protein-atlas-green-cell-tile-dataset\" target=\"_blank\"><strong>Green Tiles</strong></a><br>\n<a href=\"https://www.kaggle.com/dschettler8845/human-protein-atlas-blue-cell-tile-dataset\" target=\"_blank\"><strong>Blue Tiles</strong></a><br>\n<a href=\"https://www.kaggle.com/dschettler8845/human-protein-atlas-yellow-cell-tile-dataset\" target=\"_blank\"><strong>Yellow Tiles</strong></a></p>\n<hr>",
          "rawMarkdown": "Hi there @zekunn ... which dataset are you referring to? If you are referring to the one I trained on, the dataset can be found here...\n\n*I created this dataset by using the CellSegmentator and cutting out the instances of each cell and padding to square before resizing to 256x256 pixels.*\n\n---\n\n**Dataset Links**\n\n[**Red Tiles**](https://www.kaggle.com/dschettler8845/human-protein-atlas-red-cell-tile-dataset)\n[**Green Tiles**](https://www.kaggle.com/dschettler8845/human-protein-atlas-green-cell-tile-dataset)\n[**Blue Tiles**](https://www.kaggle.com/dschettler8845/human-protein-atlas-blue-cell-tile-dataset)\n[**Yellow Tiles**](https://www.kaggle.com/dschettler8845/human-protein-atlas-yellow-cell-tile-dataset)\n\n---"
        },
        {
          "id": 1250758,
          "postDate": "2021-03-24T08:57:05.447Z",
          "content": "<p>Thanks.I have some questions. :)</p>\n<ol>\n<li>Is CellSegmentator  only predict one class?<br>\n2.If not 1,how to train CellSegmentator  on HPA dataset?How to deal with the Label  such as '8|3'?</li>\n</ol>",
          "rawMarkdown": "Thanks.I have some questions. :)\n1. Is CellSegmentator  only predict one class?\n2.If not 1,how to train CellSegmentator  on HPA dataset?How to deal with the Label  such as '8|3'?\n"
        },
        {
          "id": 1251073,
          "postDate": "2021-03-24T13:28:13.120Z",
          "content": "<p>Hi there!</p>\n<hr>\n<p><strong>1.</strong> CellSegmentator generates instance masks for cells. I drew a small representation of what the output mask might look like. Obviously, the size and shape of the regions are not accurate. In the below depiction each group of numbers greater than 0 is a 'cell'. The zeros are the background. In the image below there are three 'cells'. To find the individual cell masks you would use something like… <strong><code>np.where(all_masks==1, 1, 0)</code></strong>. This would give you the mask for only the cell labelled below with the number <strong><code>1</code></strong>.</p>\n<pre><code>0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n0 0 0 0 2 2 2 2 2 0 3 3 3 0 0 0 0 0 0\n0 0 0 0 2 2 2 2 2 0 3 3 3 3 0 0 0 0 0\n0 0 0 0 2 2 2 2 2 0 3 3 3 3 3 3 3 3 0\n0 0 0 0 0 0 0 0 0 0 3 3 3 3 3 3 3 3 0\n</code></pre>\n<p><strong>2.</strong> The labels are <strong><code>|</code></strong> delimited. This means that the label you mentioned (<strong><code>8|3</code></strong>) is indicating that two labels are present in the slide (8 and 3). These labels are not related in any way to the output given by CellSegmentator which only deals with segmenting the individual cells (not classifying them). The point of this competition is to translate that slide-level label to the individual cells (which you could mask/locate by using a tool like CellSegmentator). A simple, albeit nieve, way to handle this would be to develop a simple slide-level classifier and let all of the cells in the image inherit that class. If we assume that the diagram I drew above is the <strong>slide-level</strong> image mask for the label <strong><code>8|3</code></strong>, we could naively assume that the individual cells are also labelled as <strong><code>8|3</code></strong>.</p>\n<ul>\n<li>Cell 1 - Label=\"8|3\"</li>\n<li>Cell 2 - Label=\"8|3\"</li>\n<li>Cell 3 - Label=\"8|3\"</li>\n</ul>\n<p>Reference the numerous helpful notebooks and discussion posts and competition organizer posts on how to submit your predictions to see how you would format this appropriately.</p>\n<hr>\n<p>I hope this helps!</p>",
          "rawMarkdown": "Hi there!\n\n---\n\n**1.** CellSegmentator generates instance masks for cells. I drew a small representation of what the output mask might look like. Obviously, the size and shape of the regions are not accurate. In the below depiction each group of numbers greater than 0 is a 'cell'. The zeros are the background. In the image below there are three 'cells'. To find the individual cell masks you would use something like... **`np.where(all_masks==1, 1, 0)`**. This would give you the mask for only the cell labelled below with the number **`1`**.\n\n```\n0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n0 0 0 0 2 2 2 2 2 0 3 3 3 0 0 0 0 0 0\n0 0 0 0 2 2 2 2 2 0 3 3 3 3 0 0 0 0 0\n0 0 0 0 2 2 2 2 2 0 3 3 3 3 3 3 3 3 0\n0 0 0 0 0 0 0 0 0 0 3 3 3 3 3 3 3 3 0\n```\n\n**2.** The labels are **`|`** delimited. This means that the label you mentioned (**`8|3`**) is indicating that two labels are present in the slide (8 and 3). These labels are not related in any way to the output given by CellSegmentator which only deals with segmenting the individual cells (not classifying them). The point of this competition is to translate that slide-level label to the individual cells (which you could mask/locate by using a tool like CellSegmentator). A simple, albeit nieve, way to handle this would be to develop a simple slide-level classifier and let all of the cells in the image inherit that class. If we assume that the diagram I drew above is the **slide-level** image mask for the label **`8|3`**, we could naively assume that the individual cells are also labelled as **`8|3`**.\n\n* Cell 1 - Label=\"8|3\"\n* Cell 2 - Label=\"8|3\"\n* Cell 3 - Label=\"8|3\"\n\nReference the numerous helpful notebooks and discussion posts and competition organizer posts on how to submit your predictions to see how you would format this appropriately.\n\n---\n\nI hope this helps!"
        },
        {
          "id": 1251118,
          "postDate": "2021-03-24T13:55:22.573Z",
          "content": "<p>Thanks for your explaination!<br>\nI though I was wrong…. Label '8|3' means all cells in this image is class 8 and class 3 , not class 8 or class 3……is it right?</p>",
          "rawMarkdown": "Thanks for your explaination!\nI though I was wrong.... Label '8|3' means all cells in this image is class 8 and class 3 , not class 8 or class 3......is it right?"
        },
        {
          "id": 1251121,
          "postDate": "2021-03-24T13:56:41.230Z",
          "content": "<p>I firstly think that each cell can be '8' or '3' or '8' and '3'..:)</p>",
          "rawMarkdown": "I firstly think that each cell can be '8' or '3' or '8' and '3'..:)"
        },
        {
          "id": 1251134,
          "postDate": "2021-03-24T14:08:34.790Z",
          "content": "<p>That label means what you said.</p>\n<p>Any cell could be 8 … or 3 … or both… or neither.</p>\n<p>My approach, shown in the comment above to clarify how the CellSegmentator works, is naive BECAUSE it assumes that the slide level label would be identical to the cel level labels.</p>",
          "rawMarkdown": "That label means what you said.\n\nAny cell could be 8 ... or 3 ... or both... or neither.\n\nMy approach, shown in the comment above to clarify how the CellSegmentator works, is naive BECAUSE it assumes that the slide level label would be identical to the cel level labels."
        },
        {
          "id": 1251149,
          "postDate": "2021-03-24T14:21:10.703Z",
          "content": "<p>Your approach seems to deal them all with 8and3.<br>\nthanks </p>",
          "rawMarkdown": "Your approach seems to deal them all with 8and3.\nthanks "
        },
        {
          "id": 1251157,
          "postDate": "2021-03-24T14:28:56.590Z",
          "content": "<p>The approach I showed above in my comment that does that was to illustrate a Naive approach to help clarify the usage and function surrounding the CellSegmentator tool.</p>",
          "rawMarkdown": "The approach I showed above in my comment that does that was to illustrate a Naive approach to help clarify the usage and function surrounding the CellSegmentator tool."
        },
        {
          "id": 1251171,
          "postDate": "2021-03-24T14:38:55.123Z",
          "content": "<p>Thanks for your idea!</p>",
          "rawMarkdown": "Thanks for your idea!"
        }
      ]
    },
    {
      "id": 1194693,
      "postDate": "2021-02-10T10:02:51.823Z",
      "content": "<p><a href=\"https://www.kaggle.com/dschettler8845\" target=\"_blank\">@dschettler8845</a> This statement is pretty new to me -&gt; \"Separate the channels and store them as separate datasets\". Can you please tell me what is the importance of this step apart from the obvious increase of training data?</p>",
      "rawMarkdown": "@dschettler8845 This statement is pretty new to me -> \"Separate the channels and store them as separate datasets\". Can you please tell me what is the importance of this step apart from the obvious increase of training data?",
      "replies": [
        {
          "id": 1194847,
          "postDate": "2021-02-10T12:02:39.833Z",
          "content": "<p>I only did this because the combined files would have been larger than 20gb. 20gb is the limit on size for public datasets I believe. </p>\n<p>So I went ahead and created a dataset for each channel instead.</p>\n<p>Hope this answers your question.</p>",
          "rawMarkdown": "I only did this because the combined files would have been larger than 20gb. 20gb is the limit on size for public datasets I believe. \n\nSo I went ahead and created a dataset for each channel instead.\n\nHope this answers your question."
        }
      ]
    }
  ],
  "comments": [
    {
      "id": 1187085,
      "author_name": "Raman",
      "author_url": "",
      "post_date": "2021-02-05T07:58:07.463000",
      "content": "<p>Hi Darien,</p>\n<p>thank you for sharing these experiments!<br>\n<a href=\"https://www.kaggle.com/c/hpa-single-cell-image-classification/overview\" target=\"_blank\">The main page</a> states that \"This is a weakly supervised <strong>multi-label classification</strong> problem\". </p>\n<p>Therefore, I'd suggest to try replacing softmax activation in your training notebook with sigmoid activation. </p>\n<p><code>def add_head_to_bb(bb, n_classes=19, dropout=0.25):\n    x = tf.keras.layers.Dropout(dropout)(bb.output)\n    output = tf.keras.layers.Dense(n_classes, activation=\"</code><strong></strong><code>\")(x)\n    return tf.keras.Model(inputs=bb.inputs, outputs=output)</code></p>\n<p>Currently, if your model outputs large logits for two classes, e.g. for both Nucleoplasm and Cytosol, then your final predictions would be around 0.5 for both classes. With sigmoid activation function, you'll allow your net to simultaneously predict 90% probability of protein being located in the Nucleoplasm and 90% prob. of protein in the Cytosol.</p>\n<p>And then I'd modify the inference notebook accordingly, to predict multiple labels instead of </p>\n<p><code>#     ######### MODEL PREDICT #########\n    preds = inference_model.predict(np.array(cell_tiles, dtype=np.uint8))\n    confs = preds.max(axis=1)\n    preds = preds.argmax(axis=1)</code></p>\n<p>Fingers crossed!</p>",
      "votes": 4,
      "replies": [
        {
          "id": 1187294,
          "author_name": "Darien Schettler",
          "author_url": "",
          "post_date": "2021-02-05T10:53:31.280000",
          "content": "<p>I will give this a try! Thank you for the detailed feedback. </p>\n<p>I will give you credit/reference when I update on this approach.</p>\n<p>Thanks Raman!</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 1187372,
          "author_name": "Raman",
          "author_url": "",
          "post_date": "2021-02-05T11:41:23.253000",
          "content": "<p>Darien, no problem at all😊</p>\n<p>I'd like to try out submission using RBGY-based classifier (sigmoid activation) and cell-level masked images as well, just in case you might be interested, here's <a href=\"https://www.kaggle.com/samusram/hpa-pretrained-keras-rgb-model-rgby\" target=\"_blank\">a corresponding notebook</a>.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 1191510,
          "author_name": "Darien Schettler",
          "author_url": "",
          "post_date": "2021-02-08T13:59:39.343000",
          "content": "<p>This is awesome to see. It makes me hopeful that I should be able to rerun with much greater success in the future! Great job on your notebook as well!</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 1227430,
      "author_name": "Vladislav Ostankovich",
      "author_url": "",
      "post_date": "2021-03-05T14:18:34.127000",
      "content": "<p>Hi again, could you tell the essential difference between your V5 and V6 submissions? The only difference I see is increased number of TTAs, but I doubt this difference resulted in huge 0.1 boost. Thanks!</p>",
      "votes": 1,
      "replies": [
        {
          "id": 1227527,
          "author_name": "Darien Schettler",
          "author_url": "",
          "post_date": "2021-03-05T16:10:26.987000",
          "content": "<p>There are two differences in addition to the TTA:</p>\n<hr>\n<ol>\n<li><p>Change confidence threshold from 0.25 to essentially 0 (it should be 0… read <a href=\"https://www.kaggle.com/c/hpa-single-cell-image-classification/discussion/217158\" target=\"_blank\">Tito's post</a> for clarification on why). <strong>This is probably responsible for the lions-share of the gain.</strong></p></li>\n<li><p>Use the updated version of the CellSegmentator tool. (See the <a href=\"https://www.kaggle.com/linshokaku/faster-hpa-cell-segmentation\" target=\"_blank\">Faster Segmentation</a> and <a href=\"https://www.kaggle.com/samusram/even-faster-hpa-cell-segmentation\" target=\"_blank\">Even Faster Segmentation</a> Notebooks… I used the implementation in the <a href=\"https://www.kaggle.com/samusram/even-faster-hpa-cell-segmentation\" target=\"_blank\">Even Faster Segmentation notebook</a>.) <strong>This is probably responsible for only a small part of the gain</strong> as the mask output difference between this and the original tool is minimal (while the latency improvement is massive).</p></li>\n</ol>\n<hr>\n<p>I hope this clarifies/helps!</p>",
          "votes": 2,
          "replies": []
        },
        {
          "id": 1227529,
          "author_name": "Vladislav Ostankovich",
          "author_url": "",
          "post_date": "2021-03-05T16:12:25.860000",
          "content": "<p>Ah yeah, conf thresh is the reason for sure. Thanks a lot)</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1198931,
      "author_name": "Alex Lau",
      "author_url": "",
      "post_date": "2021-02-13T12:24:52.820000",
      "content": "<p>Thanks for sharing ur experiment results, hope u could keep receiving incremental improvements over time and look forward to more of ur news on what works and what doesn’t. </p>\n<p>There is one thing I would like to ask though: <br>\nWhat do u mean by “Clipped Class Weighting”? </p>",
      "votes": 1,
      "replies": [
        {
          "id": 1200419,
          "author_name": "Darien Schettler",
          "author_url": "",
          "post_date": "2021-02-14T16:37:08.950000",
          "content": "<p>Hey! Thanks for commenting, I hope I keep improving and can share it with everyone too.</p>\n<p><br></p>\n<p><strong><em>Clipped Class Weighting</em></strong> is my term for clipping class counts before calculating the class weighting to reduce the impact of extreme class imbalance. I will demonstrate below with a toy example…</p>\n<hr>\n<p><b></b></p>\n<pre><code>class_counts = {\n    \"c_1\":1,\n    \"c_2\":10,\n    \"c_3\":100,\n    \"c_4\":1000,\n    \"c_5\":10000,\n    \"c_6\":100000,\n}\n\n# Calculate dynamically or whatever...\nMIN_COUNT = 1\nCLIP_MAX_COUNT = 100\n\n# Get clipped class counts\nclipped_class_counts = {k:min(v, MAX_COUNT) for k,v in class_counts.items()}\n# &gt;&gt;&gt; {\"c_1\":1, \"c_2\":10, \"c_3\":100, \"c_4\":100, \"c_5\":100, \"c_6\":100}\n\n# Calculate Regular Class Weighting\nclass_wts = {k:MIN_COUNT/v for k,v in class_counts.items()}\n# &gt;&gt;&gt; {\"c_1\":1, \"c_2\":0.1, \"c_3\":0.01, \"c_4\":0.001, \"c_5\":0.0001, \"c_6\":0.00001}\n\n# Calculate Clipped Class Weighting\nclipped_class_wts = {k:MIN_COUNT/v for k,v in clipped_class_counts.items()}\n# &gt;&gt;&gt; {\"c_1\":1, \"c_2\":0.1, \"c_3\":0.01, \"c_4\":0.01, \"c_5\":0.01, \"c_6\":0.01}\n</code></pre>\n<p></p>\n<hr>\n<p>Now when we pass the class weights to the <strong><code>model.fit()</code></strong> function, the weighting won't be AS extreme. Since we have SO FEW examples in the <strong>mitotic spindle</strong> class, the class weighting is very extreme if you do not clip them.</p>\n<p><strong>Hope this helps!</strong></p>",
          "votes": 2,
          "replies": []
        }
      ]
    },
    {
      "id": 1186518,
      "author_name": "Vladislav Ostankovich",
      "author_url": "",
      "post_date": "2021-02-04T21:41:14.263000",
      "content": "<p>I've submitted the similar approach, and the score is close to yours. I've no idea why this approach works that bad. Only assumption is that almost all cells in the images of the hidden test set have multiple labels. Any thoughts why the method doesn't work almost at all?</p>",
      "votes": 1,
      "replies": [
        {
          "id": 1186536,
          "author_name": "Darien Schettler",
          "author_url": "",
          "post_date": "2021-02-04T21:59:50.187000",
          "content": "<p>My guess is that what you described is true (many multi-label images). This may have been specifically called out by the competition hosts in a different thread. I think the basic idea was that the testing dataset has higher <a href=\"https://en.wikipedia.org/wiki/Single-cell_variability\" target=\"_blank\"><strong>SCV (Single Cell Variability)</strong></a> than the training dataset. This means that having a system that only predicts a single label may be a weak solution.</p>\n<p><strong>EDIT</strong>: Providing the direct quote from <a href=\"https://www.kaggle.com/lnhtrang/single-cell-patterns\" target=\"_blank\"><strong>this notebook about single-cell patterns</strong></a>.</p>\n<blockquote>\n  <p>\"In the hidden test set of this challenge, we purposely chose images with high single cell variation (SCV). Therefore I believe you won’t gain significant advantages with a metric learning approach (like the winning solution last challenge). Good luck and enjoy!\"</p>\n</blockquote>\n<hr>\n<p><br></p>\n<p><strong>Additionally</strong>, I think labelling all cells in a slide with the image-level label is a nieve approach. When I investigated I found that many of the cells in a given image were actually negative. I plan to implement a heuristic to remap certain cells to be negative.</p>\n<p>Take this image from the <strong>Aggresome</strong> class…</p>\n<hr>\n<p><img src=\"https://i.ibb.co/Q62H6q1/Screen-Shot-2021-02-04-at-4-53-17-PM.png\"></p>\n<hr>\n<p>We can easily see that there may be 25+ cells in this image, however, there are only half that many bright green dots (what I take to be indicative of protein localized in the Aggresome organelle structure). In this case, with nieve labelling, we are probably adding 25-50% to our classifier tile-level dataset that are incorrectly labelled as <strong>Aggresome</strong> when they should be labelled as <strong>Negative</strong></p>\n<hr>\n<p><br></p>\n<p>This was just my take, I may be wrong though. Hope this helps! Thanks for commenting!</p>",
          "votes": 3,
          "replies": []
        },
        {
          "id": 1186547,
          "author_name": "Darien Schettler",
          "author_url": "",
          "post_date": "2021-02-04T22:12:53.860000",
          "content": "<p>Also, I'm currently retraining the model (smaller model) for a bit longer with a better LR decay. So we shall see how that goes…</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 1186548,
          "author_name": "Vladislav Ostankovich",
          "author_url": "",
          "post_date": "2021-02-04T22:13:00.117000",
          "content": "<p>I see, thanks for the quick response!</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1212957,
      "author_name": "RSASHWIN",
      "author_url": "",
      "post_date": "2021-02-21T18:34:14.923000",
      "content": "<p>Hi,</p>\n<p>I really appreciate for taking your time and putting this notebook. It is useful for beginners like me. I have a question. I read the segmentation are of two types called instance based and semantic based segmentation. So, based on your notebook I came to know the HPA tool does instance based segmentation. Correct me if I am wrong the HPA tool, while segmenting treats each cell as separate entity and does the segmentation?</p>",
      "votes": 2,
      "replies": [
        {
          "id": 1213003,
          "author_name": "Darien Schettler",
          "author_url": "",
          "post_date": "2021-02-21T18:57:51.013000",
          "content": "<p>Hi <a href=\"https://www.kaggle.com/strivathsav\" target=\"_blank\">@strivathsav</a>. You're quite welcome. I should have more updates later today. </p>\n<p>To your point, your understanding is 100% correct. </p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1249088,
      "author_name": "Zekun",
      "author_url": "",
      "post_date": "2021-03-23T05:13:17.803000",
      "content": "<p>Hello,how to produce this dataset</p>",
      "votes": 0,
      "replies": [
        {
          "id": 1250096,
          "author_name": "Darien Schettler",
          "author_url": "",
          "post_date": "2021-03-23T19:26:25.597000",
          "content": "<p>Hi there <a href=\"https://www.kaggle.com/zekunn\" target=\"_blank\">@zekunn</a> … which dataset are you referring to? If you are referring to the one I trained on, the dataset can be found here…</p>\n<p><em>I created this dataset by using the CellSegmentator and cutting out the instances of each cell and padding to square before resizing to 256x256 pixels.</em></p>\n<hr>\n<p><strong>Dataset Links</strong></p>\n<p><a href=\"https://www.kaggle.com/dschettler8845/human-protein-atlas-red-cell-tile-dataset\" target=\"_blank\"><strong>Red Tiles</strong></a><br>\n<a href=\"https://www.kaggle.com/dschettler8845/human-protein-atlas-green-cell-tile-dataset\" target=\"_blank\"><strong>Green Tiles</strong></a><br>\n<a href=\"https://www.kaggle.com/dschettler8845/human-protein-atlas-blue-cell-tile-dataset\" target=\"_blank\"><strong>Blue Tiles</strong></a><br>\n<a href=\"https://www.kaggle.com/dschettler8845/human-protein-atlas-yellow-cell-tile-dataset\" target=\"_blank\"><strong>Yellow Tiles</strong></a></p>\n<hr>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 1250758,
          "author_name": "Zekun",
          "author_url": "",
          "post_date": "2021-03-24T08:57:05.447000",
          "content": "<p>Thanks.I have some questions. :)</p>\n<ol>\n<li>Is CellSegmentator  only predict one class?<br>\n2.If not 1,how to train CellSegmentator  on HPA dataset?How to deal with the Label  such as '8|3'?</li>\n</ol>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 1251073,
          "author_name": "Darien Schettler",
          "author_url": "",
          "post_date": "2021-03-24T13:28:13.120000",
          "content": "<p>Hi there!</p>\n<hr>\n<p><strong>1.</strong> CellSegmentator generates instance masks for cells. I drew a small representation of what the output mask might look like. Obviously, the size and shape of the regions are not accurate. In the below depiction each group of numbers greater than 0 is a 'cell'. The zeros are the background. In the image below there are three 'cells'. To find the individual cell masks you would use something like… <strong><code>np.where(all_masks==1, 1, 0)</code></strong>. This would give you the mask for only the cell labelled below with the number <strong><code>1</code></strong>.</p>\n<pre><code>0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n0 0 0 0 2 2 2 2 2 0 3 3 3 0 0 0 0 0 0\n0 0 0 0 2 2 2 2 2 0 3 3 3 3 0 0 0 0 0\n0 0 0 0 2 2 2 2 2 0 3 3 3 3 3 3 3 3 0\n0 0 0 0 0 0 0 0 0 0 3 3 3 3 3 3 3 3 0\n</code></pre>\n<p><strong>2.</strong> The labels are <strong><code>|</code></strong> delimited. This means that the label you mentioned (<strong><code>8|3</code></strong>) is indicating that two labels are present in the slide (8 and 3). These labels are not related in any way to the output given by CellSegmentator which only deals with segmenting the individual cells (not classifying them). The point of this competition is to translate that slide-level label to the individual cells (which you could mask/locate by using a tool like CellSegmentator). A simple, albeit nieve, way to handle this would be to develop a simple slide-level classifier and let all of the cells in the image inherit that class. If we assume that the diagram I drew above is the <strong>slide-level</strong> image mask for the label <strong><code>8|3</code></strong>, we could naively assume that the individual cells are also labelled as <strong><code>8|3</code></strong>.</p>\n<ul>\n<li>Cell 1 - Label=\"8|3\"</li>\n<li>Cell 2 - Label=\"8|3\"</li>\n<li>Cell 3 - Label=\"8|3\"</li>\n</ul>\n<p>Reference the numerous helpful notebooks and discussion posts and competition organizer posts on how to submit your predictions to see how you would format this appropriately.</p>\n<hr>\n<p>I hope this helps!</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 1251118,
          "author_name": "Zekun",
          "author_url": "",
          "post_date": "2021-03-24T13:55:22.573000",
          "content": "<p>Thanks for your explaination!<br>\nI though I was wrong…. Label '8|3' means all cells in this image is class 8 and class 3 , not class 8 or class 3……is it right?</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 1251121,
          "author_name": "Zekun",
          "author_url": "",
          "post_date": "2021-03-24T13:56:41.230000",
          "content": "<p>I firstly think that each cell can be '8' or '3' or '8' and '3'..:)</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 1251134,
          "author_name": "Darien Schettler",
          "author_url": "",
          "post_date": "2021-03-24T14:08:34.790000",
          "content": "<p>That label means what you said.</p>\n<p>Any cell could be 8 … or 3 … or both… or neither.</p>\n<p>My approach, shown in the comment above to clarify how the CellSegmentator works, is naive BECAUSE it assumes that the slide level label would be identical to the cel level labels.</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 1251149,
          "author_name": "Zekun",
          "author_url": "",
          "post_date": "2021-03-24T14:21:10.703000",
          "content": "<p>Your approach seems to deal them all with 8and3.<br>\nthanks </p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 1251157,
          "author_name": "Darien Schettler",
          "author_url": "",
          "post_date": "2021-03-24T14:28:56.590000",
          "content": "<p>The approach I showed above in my comment that does that was to illustrate a Naive approach to help clarify the usage and function surrounding the CellSegmentator tool.</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 1251171,
          "author_name": "Zekun",
          "author_url": "",
          "post_date": "2021-03-24T14:38:55.123000",
          "content": "<p>Thanks for your idea!</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1194693,
      "author_name": "Izzy Adesanya",
      "author_url": "",
      "post_date": "2021-02-10T10:02:51.823000",
      "content": "<p><a href=\"https://www.kaggle.com/dschettler8845\" target=\"_blank\">@dschettler8845</a> This statement is pretty new to me -&gt; \"Separate the channels and store them as separate datasets\". Can you please tell me what is the importance of this step apart from the obvious increase of training data?</p>",
      "votes": 0,
      "replies": [
        {
          "id": 1194847,
          "author_name": "Darien Schettler",
          "author_url": "",
          "post_date": "2021-02-10T12:02:39.833000",
          "content": "<p>I only did this because the combined files would have been larger than 20gb. 20gb is the limit on size for public datasets I believe. </p>\n<p>So I went ahead and created a dataset for each channel instead.</p>\n<p>Hope this answers your question.</p>",
          "votes": 0,
          "replies": []
        }
      ]
    }
  ],
  "raw_markdown_by_id": {
    "1186033": "---\n\n<h3>EDIT –– RECENT SUBMISSION DETAILS BELOW</h3>\n*As of March 2nd, 2021*\n\n---\n\n**ORIGINAL SUBMISSION**\n\n* **Scores 0.025**\n* Multi-Class Classification\n* Clipped Class Weighting\n* CellSegmentator at 0.5 Scale (no padding)\n* Confidence Threshold of 0.25 for Model Inference (EfficientNet B0)\n* Tile size of 256x256\n\n</div>\n\n\n\n\n<br>\n\n**V2 SUBMISSION**\n* **Scores 0.121**\n* Multi-Label Classification\n* Clipped Class Weighting\n* CellSegmentator at 0.5 Scale (no padding)\n* Confidence Threshold of 0.25 for Model Inference (EfficientNet B0)\n* Tile size of 128x128\n\n<br>\n\n**V3 SUBMISSION**\n* **Scores 0.201**\n* Multi-Label Classification\n* Clipped Class Weighting\n* CellSegmentator at 0.25 Scale (w/ padding)\n* Confidence Threshold of 0.25 for Model Inference (EfficientNet B0)\n* Tile size of 128x128\n* Massive refactoring of code reduced inference time from *9 hours* to *6 hours* (hidden test set)\n  * This should not have impacted the score... but I can't be certain either way.\n\n<br>\n\n**V4 SUBMISSION**\n* **Scores 0.255**\n* Multi-Label Classification\n* No Class Weighting\n* CellSegmentator at 0.25 Scale (w/ padding)\n* Confidence Threshold of 0.25 for Model Inference (EfficientNet B1 – Dropout at 0.25)\n* Tile size of 224x224\n* TTA (Test Time Augmentation)\n  * 3 Repeats + The Original Image\n  * Flipping, Rotation, Brightness, Contrast, Saturation (same as training)\n\n<br>\n\n**V5 SUBMISSION**\n* **Scores 0.232**\n* Multi-Label Classification\n* No Class Weighting\n* CellSegmentator at 0.25 Scale (w/ padding)\n* Confidence Threshold of 0.25 for Model Inference (EfficientNet B1 – Dropout at **0.05**)\n* Tile size of 224x224\n* TTA (Test Time Augmentation)\n  * 3 Repeats + The Original Image\n  * Flipping, Rotation, Brightness, Contrast, Saturation (same as training)\n\n<br>\n\n**V6 SUBMISSION**\n* **Scores 0.320**\n* Multi-Label Classification\n* No Class Weighting\n* CellSegmentator at 0.25 Scale (w/ padding)(**updated version**)\n* Confidence Threshold of essentially 0 for Model Inference (EfficientNet B1 – Dropout at **0.25**)\n* Tile size of 224x224\n* TTA (Test Time Augmentation)\n  * 10 Repeats + The Original Image\n  * Flipping, Rotation, Brightness, Contrast, Saturation (same as training)\n\n<br>\n\n**V7 SUBMISSION**\n* **Scores 0.337**\n* Multi-Label Classification\n* No Class Weighting\n* CellSegmentator at 0.25 Scale (w/ padding)(**updated version**)\n* Confidence Threshold of 0 for Model Inference (see [Tito's post](https://www.kaggle.com/c/hpa-single-cell-image-classification/discussion/217158))\n  * EfficientNet B2\n  * Dropout at **0.5** \n  * Added batch normalization\n  * Additional dense layer followed by dropout of **0.25**\n* Tile size of 224x224\n* TTA (Test Time Augmentation)\n  * 8 Repeats + The Original Image\n  * Flipping, Rotation, Brightness, Contrast, Saturation (same as training)\n\n<br>\n<br>\n\n**V8 SUBMISSION –– FINAL PUBLIC SINGLE STAGE SUBMISSION**\n* **Scores 0.352**\n* Multi-Label Classification\n* No Class Weighting\n* CellSegmentator at 0.25 Scale (w/ padding)(**updated version**)\n* Confidence Threshold of 0 for Model Inference (see [Tito's post](https://www.kaggle.com/c/hpa-single-cell-image-classification/discussion/217158))\n  * EfficientNet B2\n  * Dropout at **0.5** \n  * Added batch normalization\n  * Additional dense layer followed by dropout of **0.25**\n* Tile size of 224x224\n* TTA (Test Time Augmentation)\n  * 8 Repeats + The Original Image\n  * Flipping, Rotation, Brightness, Contrast, Saturation (same as training)\n* ***Additional 7 epochs of fine-tuning from V7 checkpoint***\n\n---\n\n<br>\n\n<h3 style=\"text-align: font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: navy; background-color: #ffffff;\">APPROACH OVERVIEW</h3>\n\n---\n\n**TRAINING**\n\n1. Identify slide-level images containing only one label\n2. Segment slide-level images (get RLEs for all cells in all applicable slide-level images)\n3. Crop RGBY image around each cell\n4. Pad each RGBY tile to be square\n5. Resize each RGBY tile to be (256px by 256px) (*drop yellow channel*)\n6. Separate the channels and store them as separate datasets\n~~7. Ensure stratification in the validation dataset even if it doesn't follow a similar distribution to the training dataset~~ (I didn't do this... as a result, my validation loss is all over the place. Not ideal!)\n8. Augment the dataset (rotation, flipping (horizontal and vertical), brightness, contrast, saturation)\n9. Train a model (EfficientNet B0, B1 or B2) to perform multi-label classification on these tile-level images\n\n*OTHER TBD ---> Leverage TFRecords Instead of Images to use both TPU and GPU quota*\n\n--\n\n**INFERENCE**\n\n1. Use CellSegmentator to do instance segmentation on images in test-dataset (or leverage precomputed cell masks for public dataset probing ... this won't work for final submissions)\n2. Record this mask in the appropriate format for later submission (or access directly from premade CSV)\n3. Identify the bounding box for each mask to be able to crop each cell (padded) (or access directly from the premade CSV)\n4. Crop RGBY image around each cell\n5. Pad each RGBY tile to be square (*drop yellow channel*)\n6. Resize each RGBY tile to be (224px by 224px ... or similar)\n7. Infer on all tiles on each slide (all tiles will be passed as a batch for better latency)\n8. Do TTA and average results\n9. Combine cell-level classification with segmentation as RLE when submitting\n10. Make **`submission.csv`** file\n\n<br>\n\n<h3 style=\"text-align: font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: navy; background-color: #ffffff;\">NOTEBOOK LINKS</h3>\n\n---\nI created and made public my notebooks showing my approach for [inference](https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-inference) and [training](https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-training).\n- [TRAINING](https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-training) --> https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-training\n- [INFERENCE](https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-inference) --> https://www.kaggle.com/dschettler8845/hpa-cellwise-classification-inference\n\n<br>\n<br>\n\n*Thanks for taking the time to read. I'm still learning and wanted to share with you all. Please give me as much feedback as possible (or ask questions) and I'll do my best to improve/share.*",
    "1187085": "Hi Darien,\n\nthank you for sharing these experiments!\n[The main page](https://www.kaggle.com/c/hpa-single-cell-image-classification/overview) states that \"This is a weakly supervised **multi-label classification** problem\". \n\nTherefore, I'd suggest to try replacing softmax activation in your training notebook with sigmoid activation. \n\n`def add_head_to_bb(bb, n_classes=19, dropout=0.25):\n    x = tf.keras.layers.Dropout(dropout)(bb.output)\n    output = tf.keras.layers.Dense(n_classes, activation=\"`**~~`softmax`~~**`\")(x)\n    return tf.keras.Model(inputs=bb.inputs, outputs=output)`\n\nCurrently, if your model outputs large logits for two classes, e.g. for both Nucleoplasm and Cytosol, then your final predictions would be around 0.5 for both classes. With sigmoid activation function, you'll allow your net to simultaneously predict 90% probability of protein being located in the Nucleoplasm and 90% prob. of protein in the Cytosol.\n\nAnd then I'd modify the inference notebook accordingly, to predict multiple labels instead of \n\n```#     ######### MODEL PREDICT #########\n    preds = inference_model.predict(np.array(cell_tiles, dtype=np.uint8))\n    confs = preds.max(axis=1)\n    preds = preds.argmax(axis=1)```\n\nFingers crossed!",
    "1227430": "Hi again, could you tell the essential difference between your V5 and V6 submissions? The only difference I see is increased number of TTAs, but I doubt this difference resulted in huge 0.1 boost. Thanks!\n",
    "1198931": "Thanks for sharing ur experiment results, hope u could keep receiving incremental improvements over time and look forward to more of ur news on what works and what doesn’t. \n\nThere is one thing I would like to ask though: \nWhat do u mean by “Clipped Class Weighting”? ",
    "1186518": "I've submitted the similar approach, and the score is close to yours. I've no idea why this approach works that bad. Only assumption is that almost all cells in the images of the hidden test set have multiple labels. Any thoughts why the method doesn't work almost at all?",
    "1212957": "Hi,\n\nI really appreciate for taking your time and putting this notebook. It is useful for beginners like me. I have a question. I read the segmentation are of two types called instance based and semantic based segmentation. So, based on your notebook I came to know the HPA tool does instance based segmentation. Correct me if I am wrong the HPA tool, while segmenting treats each cell as separate entity and does the segmentation?",
    "1249088": "Hello,how to produce this dataset",
    "1194693": "@dschettler8845 This statement is pretty new to me -> \"Separate the channels and store them as separate datasets\". Can you please tell me what is the importance of this step apart from the obvious increase of training data?"
  }
}