{
  "id": 238404,
  "title": "39th solution",
  "url": "/competitions/hubmap-kidney-segmentation/writeups/snowballball-39th-solution",
  "author_name": "",
  "post_date": "2021-05-12T06:17:01.682093100Z",
  "votes": 6,
  "comment_count": 2,
  "views": 0,
  "content": "<p>Thank you kaggle and the host team for such a interesting competition and thanks for everyone to share their brilliant mind! So happy to win my first medal in my first medical segmentation competition, and i have learned a lot from this.<br>\nMy notebook is based on <a href=\"https://www.kaggle.com/wrrosa/hubmap-tf-with-tpu-efficientunet-512x512-train\" target=\"_blank\">hubmap-tf-with-tpu-efficientunet-512x512-train</a>, <a href=\"https://www.kaggle.com/wrrosa/hubmap-tf-with-tpu-efficientunet-512x512-subm\" target=\"_blank\">hubmap-tf-with-tpu-efficientunet-512x512-subm</a> and <a href=\"https://www.kaggle.com/wrrosa/hubmap-tf-with-tpu-efficientunet-512x512-tfrecs\" target=\"_blank\">hubmap-tf-with-tpu-efficientunet-512x512-tfrecs</a>, and besides I've made several improvements and explorations by myself. (thank you for sharing these excellent notebooks <a href=\"https://www.kaggle.com/wrrosa\" target=\"_blank\">@wrrosa</a>)<br>\n Here is a brief description about my solution:</p>\n<h1>Dataset</h1>\n<p>Split origin tiff images with window size of 1024x1024 and overlap size of 512, then resize to 320x320 images.<br>\nSplit dataset to 5-fold and make every fold have nearly the same sum of training examples.<br>\nUse <a href=\"https://www.kaggle.com/carnozhao/d48-hand-labelled\" target=\"_blank\">d48-hand-labelled</a> as external data (thanks <a href=\"https://www.kaggle.com/carnozhao\" target=\"_blank\">@carnozhao</a>!)</p>\n<p><strong>Note:</strong><br>\nI've also tried other combinations of window size and overlap size, such as 1024-256, 1536-512 and 1560-320, but haven't get better CV and LB.<br>\nI haven't tried 1024-512, because training time is so long for me.<br>\nEqual k-fold split give slightly better CV and public LB than random split.<br>\nUsing <a href=\"https://www.kaggle.com/carnozhao/d48-hand-labelled\" target=\"_blank\">d48-hand-labelled</a> helps get better public LB on both d488c759a and other public test images (about 0.001).<br>\nI've also tried to add <a href=\"https://www.kaggle.com/baesiann\" target=\"_blank\">@baesiann</a>'s <a href=\"https://www.kaggle.com/baesiann/glomeruli-hubmap-external-1024x1024\" target=\"_blank\">external dataset</a>, but achieved low public LB.</p>\n<h1>Model</h1>\n<p>U-Net with EfficientB3 encoder. <br>\n<strong>Note:</strong><br>\nI've also tried LinkNet as segmentation framework and other encoders (such as EfficientB0~B2, Resnet50 and Swin-Transformer),  but didn't get better CV and public LB.</p>\n<h1>Loss</h1>\n<p>cross entropy and finetune with lovasz softmax.<br>\nFor evaluation, compute global dice score rather than mean dice score for every tile.<br>\n<strong>Note:</strong><br>\nFinetune with lovasz softmax gives 0.003+ inprovement in public LB.<br>\nI've also tried other loss functions, such as tversky loss, focal tversky loss and bce jaccard loss, but didn't get better CV and public LB.<br>\nWith global dice score, better CV often implies better public LB.</p>\n<h1>optimizer</h1>\n<p>Adam+SAM (Sharpness-Aware Minimization)<br>\n<strong>Note:</strong><br>\nFor me, SAM give more stable CV and public LB.<br>\nI've also tried Ranger as optimizer, but get better CV and worse public LB.</p>\n<h1>Shuffle Training</h1>\n<p>Shuffle train files in every fold between every epoch.<br>\n<strong>Note:</strong><br>\nTFRecordDataset have a fixed order of input files, I believe that a more adequate shuffle in training process will benefits.</p>\n<h1>Center Crop Inference</h1>\n<p>Just split test images as train dataset does. Center crop 1/2 of every test tile's predict mask and tie every tile mask together as the final mask.<br>\n<strong>Note:</strong><br>\nCenter crop Inference is the key idea to achieve high LB score. It gives about 0.005+ improvement.<br>\nI have tried to crop 1/4 of  predict mask, but got almost the same public LB, although has higher private LB (0.948)</p>\n<h1>Ensemble</h1>\n<p>Because model ensemble doesn't give better CV and LB score, I mostly use single model to submit.</p>\n<h1>Code</h1>\n<p>1) <a href=\"https://www.kaggle.com/snowballball/hubmap-submit1\" target=\"_blank\">inference notebook</a><br>\n2) I have modified <a href=\"https://github.com/qubvel/segmentation_models.pytorch\" target=\"_blank\">segmentation_models.pytorch</a> and <a href=\"https://github.com/microsoft/Swin-Transformer\" target=\"_blank\">Swin-Transformer</a>to support Swin-Transformer encoder, and here is the modification code:  (hope it helps in other competitions)<br>\n<a href=\"https://github.com/cersar/segmentation_models.pytorch\" target=\"_blank\">https://github.com/cersar/segmentation_models.pytorch</a><br>\n<a href=\"https://github.com/cersar/Swin-Transformer\" target=\"_blank\">https://github.com/cersar/Swin-Transformer</a></p>",
  "messages": [
    {
      "id": "1303562",
      "postDate": "05/12/2021 06:17:01",
      "content": "<p>Thank you kaggle and the host team for such a interesting competition and thanks for everyone to share their brilliant mind! So happy to win my first medal in my first medical segmentation competition, and i have learned a lot from this.<br>\nMy notebook is based on <a href=\"https://www.kaggle.com/wrrosa/hubmap-tf-with-tpu-efficientunet-512x512-train\" target=\"_blank\">hubmap-tf-with-tpu-efficientunet-512x512-train</a>, <a href=\"https://www.kaggle.com/wrrosa/hubmap-tf-with-tpu-efficientunet-512x512-subm\" target=\"_blank\">hubmap-tf-with-tpu-efficientunet-512x512-subm</a> and <a href=\"https://www.kaggle.com/wrrosa/hubmap-tf-with-tpu-efficientunet-512x512-tfrecs\" target=\"_blank\">hubmap-tf-with-tpu-efficientunet-512x512-tfrecs</a>, and besides I've made several improvements and explorations by myself. (thank you for sharing these excellent notebooks <a href=\"https://www.kaggle.com/wrrosa\" target=\"_blank\">@wrrosa</a>)<br>\n Here is a brief description about my solution:</p>\n<h1>Dataset</h1>\n<p>Split origin tiff images with window size of 1024x1024 and overlap size of 512, then resize to 320x320 images.<br>\nSplit dataset to 5-fold and make every fold have nearly the same sum of training examples.<br>\nUse <a href=\"https://www.kaggle.com/carnozhao/d48-hand-labelled\" target=\"_blank\">d48-hand-labelled</a> as external data (thanks <a href=\"https://www.kaggle.com/carnozhao\" target=\"_blank\">@carnozhao</a>!)</p>\n<p><strong>Note:</strong><br>\nI've also tried other combinations of window size and overlap size, such as 1024-256, 1536-512 and 1560-320, but haven't get better CV and LB.<br>\nI haven't tried 1024-512, because training time is so long for me.<br>\nEqual k-fold split give slightly better CV and public LB than random split.<br>\nUsing <a href=\"https://www.kaggle.com/carnozhao/d48-hand-labelled\" target=\"_blank\">d48-hand-labelled</a> helps get better public LB on both d488c759a and other public test images (about 0.001).<br>\nI've also tried to add <a href=\"https://www.kaggle.com/baesiann\" target=\"_blank\">@baesiann</a>'s <a href=\"https://www.kaggle.com/baesiann/glomeruli-hubmap-external-1024x1024\" target=\"_blank\">external dataset</a>, but achieved low public LB.</p>\n<h1>Model</h1>\n<p>U-Net with EfficientB3 encoder. <br>\n<strong>Note:</strong><br>\nI've also tried LinkNet as segmentation framework and other encoders (such as EfficientB0~B2, Resnet50 and Swin-Transformer),  but didn't get better CV and public LB.</p>\n<h1>Loss</h1>\n<p>cross entropy and finetune with lovasz softmax.<br>\nFor evaluation, compute global dice score rather than mean dice score for every tile.<br>\n<strong>Note:</strong><br>\nFinetune with lovasz softmax gives 0.003+ inprovement in public LB.<br>\nI've also tried other loss functions, such as tversky loss, focal tversky loss and bce jaccard loss, but didn't get better CV and public LB.<br>\nWith global dice score, better CV often implies better public LB.</p>\n<h1>optimizer</h1>\n<p>Adam+SAM (Sharpness-Aware Minimization)<br>\n<strong>Note:</strong><br>\nFor me, SAM give more stable CV and public LB.<br>\nI've also tried Ranger as optimizer, but get better CV and worse public LB.</p>\n<h1>Shuffle Training</h1>\n<p>Shuffle train files in every fold between every epoch.<br>\n<strong>Note:</strong><br>\nTFRecordDataset have a fixed order of input files, I believe that a more adequate shuffle in training process will benefits.</p>\n<h1>Center Crop Inference</h1>\n<p>Just split test images as train dataset does. Center crop 1/2 of every test tile's predict mask and tie every tile mask together as the final mask.<br>\n<strong>Note:</strong><br>\nCenter crop Inference is the key idea to achieve high LB score. It gives about 0.005+ improvement.<br>\nI have tried to crop 1/4 of  predict mask, but got almost the same public LB, although has higher private LB (0.948)</p>\n<h1>Ensemble</h1>\n<p>Because model ensemble doesn't give better CV and LB score, I mostly use single model to submit.</p>\n<h1>Code</h1>\n<p>1) <a href=\"https://www.kaggle.com/snowballball/hubmap-submit1\" target=\"_blank\">inference notebook</a><br>\n2) I have modified <a href=\"https://github.com/qubvel/segmentation_models.pytorch\" target=\"_blank\">segmentation_models.pytorch</a> and <a href=\"https://github.com/microsoft/Swin-Transformer\" target=\"_blank\">Swin-Transformer</a>to support Swin-Transformer encoder, and here is the modification code:  (hope it helps in other competitions)<br>\n<a href=\"https://github.com/cersar/segmentation_models.pytorch\" target=\"_blank\">https://github.com/cersar/segmentation_models.pytorch</a><br>\n<a href=\"https://github.com/cersar/Swin-Transformer\" target=\"_blank\">https://github.com/cersar/Swin-Transformer</a></p>",
      "rawMarkdown": "Thank you kaggle and the host team for such a interesting competition and thanks for everyone to share their brilliant mind! So happy to win my first medal in my first medical segmentation competition, and i have learned a lot from this.\nMy notebook is based on [hubmap-tf-with-tpu-efficientunet-512x512-train](https://www.kaggle.com/wrrosa/hubmap-tf-with-tpu-efficientunet-512x512-train), [hubmap-tf-with-tpu-efficientunet-512x512-subm](https://www.kaggle.com/wrrosa/hubmap-tf-with-tpu-efficientunet-512x512-subm) and [hubmap-tf-with-tpu-efficientunet-512x512-tfrecs](https://www.kaggle.com/wrrosa/hubmap-tf-with-tpu-efficientunet-512x512-tfrecs), and besides I've made several improvements and explorations by myself. (thank you for sharing these excellent notebooks @wrrosa)\n Here is a brief description about my solution:\n# Dataset\nSplit origin tiff images with window size of 1024x1024 and overlap size of 512, then resize to 320x320 images.\nSplit dataset to 5-fold and make every fold have nearly the same sum of training examples.\nUse [d48-hand-labelled](https://www.kaggle.com/carnozhao/d48-hand-labelled) as external data (thanks [@carnozhao](https://www.kaggle.com/carnozhao)!)\n\n**Note:**\nI've also tried other combinations of window size and overlap size, such as 1024-256, 1536-512 and 1560-320, but haven't get better CV and LB.\nI haven't tried 1024-512, because training time is so long for me.\nEqual k-fold split give slightly better CV and public LB than random split.\nUsing [d48-hand-labelled](https://www.kaggle.com/carnozhao/d48-hand-labelled) helps get better public LB on both d488c759a and other public test images (about 0.001).\nI've also tried to add @baesiann's [external dataset](https://www.kaggle.com/baesiann/glomeruli-hubmap-external-1024x1024), but achieved low public LB.\n# Model\nU-Net with EfficientB3 encoder. \n**Note:**\nI've also tried LinkNet as segmentation framework and other encoders (such as EfficientB0~B2, Resnet50 and Swin-Transformer),  but didn't get better CV and public LB.\n# Loss\ncross entropy and finetune with lovasz softmax.\nFor evaluation, compute global dice score rather than mean dice score for every tile.\n**Note:**\nFinetune with lovasz softmax gives 0.003+ inprovement in public LB.\nI've also tried other loss functions, such as tversky loss, focal tversky loss and bce jaccard loss, but didn't get better CV and public LB.\nWith global dice score, better CV often implies better public LB.\n# optimizer\nAdam+SAM (Sharpness-Aware Minimization)\n**Note:**\nFor me, SAM give more stable CV and public LB.\nI've also tried Ranger as optimizer, but get better CV and worse public LB.\n# Shuffle Training\nShuffle train files in every fold between every epoch.\n**Note:**\nTFRecordDataset have a fixed order of input files, I believe that a more adequate shuffle in training process will benefits.\n# Center Crop Inference\nJust split test images as train dataset does. Center crop 1/2 of every test tile's predict mask and tie every tile mask together as the final mask.\n**Note:**\nCenter crop Inference is the key idea to achieve high LB score. It gives about 0.005+ improvement.\nI have tried to crop 1/4 of  predict mask, but got almost the same public LB, although has higher private LB (0.948)\n# Ensemble\nBecause model ensemble doesn't give better CV and LB score, I mostly use single model to submit.\n# Code\n1) [inference notebook](https://www.kaggle.com/snowballball/hubmap-submit1)\n2) I have modified [segmentation_models.pytorch](https://github.com/qubvel/segmentation_models.pytorch) and [Swin-Transformer](https://github.com/microsoft/Swin-Transformer)to support Swin-Transformer encoder, and here is the modification code:  (hope it helps in other competitions)\nhttps://github.com/cersar/segmentation_models.pytorch\nhttps://github.com/cersar/Swin-Transformer",
      "votes": null
    },
    {
      "id": "1304576",
      "postDate": "05/12/2021 17:49:49",
      "content": "<p>Good job, and congratulation!</p>",
      "rawMarkdown": "Good job, and congratulation!",
      "votes": null
    },
    {
      "id": "1305829",
      "postDate": "05/13/2021 13:50:44",
      "content": "<p><a href=\"https://www.kaggle.com/snowballball\" target=\"_blank\">@snowballball</a> Congratulations and Thanks for sharing the approach</p>",
      "rawMarkdown": "snowballball Congratulations and Thanks for sharing the approach",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 1304576,
      "author_name": "bessenyeiszilrd",
      "author_url": "",
      "post_date": "05/12/2021 17:49:49",
      "content": "<p>Good job, and congratulation!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1305829,
      "author_name": "usharengaraju",
      "author_url": "",
      "post_date": "05/13/2021 13:50:44",
      "content": "<p><a href=\"https://www.kaggle.com/snowballball\" target=\"_blank\">@snowballball</a> Congratulations and Thanks for sharing the approach</p>",
      "votes": null,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "1303562": "Thank you kaggle and the host team for such a interesting competition and thanks for everyone to share their brilliant mind! So happy to win my first medal in my first medical segmentation competition, and i have learned a lot from this.\nMy notebook is based on [hubmap-tf-with-tpu-efficientunet-512x512-train](https://www.kaggle.com/wrrosa/hubmap-tf-with-tpu-efficientunet-512x512-train), [hubmap-tf-with-tpu-efficientunet-512x512-subm](https://www.kaggle.com/wrrosa/hubmap-tf-with-tpu-efficientunet-512x512-subm) and [hubmap-tf-with-tpu-efficientunet-512x512-tfrecs](https://www.kaggle.com/wrrosa/hubmap-tf-with-tpu-efficientunet-512x512-tfrecs), and besides I've made several improvements and explorations by myself. (thank you for sharing these excellent notebooks @wrrosa)\n Here is a brief description about my solution:\n# Dataset\nSplit origin tiff images with window size of 1024x1024 and overlap size of 512, then resize to 320x320 images.\nSplit dataset to 5-fold and make every fold have nearly the same sum of training examples.\nUse [d48-hand-labelled](https://www.kaggle.com/carnozhao/d48-hand-labelled) as external data (thanks [@carnozhao](https://www.kaggle.com/carnozhao)!)\n\n**Note:**\nI've also tried other combinations of window size and overlap size, such as 1024-256, 1536-512 and 1560-320, but haven't get better CV and LB.\nI haven't tried 1024-512, because training time is so long for me.\nEqual k-fold split give slightly better CV and public LB than random split.\nUsing [d48-hand-labelled](https://www.kaggle.com/carnozhao/d48-hand-labelled) helps get better public LB on both d488c759a and other public test images (about 0.001).\nI've also tried to add @baesiann's [external dataset](https://www.kaggle.com/baesiann/glomeruli-hubmap-external-1024x1024), but achieved low public LB.\n# Model\nU-Net with EfficientB3 encoder. \n**Note:**\nI've also tried LinkNet as segmentation framework and other encoders (such as EfficientB0~B2, Resnet50 and Swin-Transformer),  but didn't get better CV and public LB.\n# Loss\ncross entropy and finetune with lovasz softmax.\nFor evaluation, compute global dice score rather than mean dice score for every tile.\n**Note:**\nFinetune with lovasz softmax gives 0.003+ inprovement in public LB.\nI've also tried other loss functions, such as tversky loss, focal tversky loss and bce jaccard loss, but didn't get better CV and public LB.\nWith global dice score, better CV often implies better public LB.\n# optimizer\nAdam+SAM (Sharpness-Aware Minimization)\n**Note:**\nFor me, SAM give more stable CV and public LB.\nI've also tried Ranger as optimizer, but get better CV and worse public LB.\n# Shuffle Training\nShuffle train files in every fold between every epoch.\n**Note:**\nTFRecordDataset have a fixed order of input files, I believe that a more adequate shuffle in training process will benefits.\n# Center Crop Inference\nJust split test images as train dataset does. Center crop 1/2 of every test tile's predict mask and tie every tile mask together as the final mask.\n**Note:**\nCenter crop Inference is the key idea to achieve high LB score. It gives about 0.005+ improvement.\nI have tried to crop 1/4 of  predict mask, but got almost the same public LB, although has higher private LB (0.948)\n# Ensemble\nBecause model ensemble doesn't give better CV and LB score, I mostly use single model to submit.\n# Code\n1) [inference notebook](https://www.kaggle.com/snowballball/hubmap-submit1)\n2) I have modified [segmentation_models.pytorch](https://github.com/qubvel/segmentation_models.pytorch) and [Swin-Transformer](https://github.com/microsoft/Swin-Transformer)to support Swin-Transformer encoder, and here is the modification code:  (hope it helps in other competitions)\nhttps://github.com/cersar/segmentation_models.pytorch\nhttps://github.com/cersar/Swin-Transformer",
    "1304576": "Good job, and congratulation!",
    "1305829": "snowballball Congratulations and Thanks for sharing the approach"
  },
  "source": "meta"
}