{
  "id": 354859,
  "title": "7th place solution",
  "url": "/competitions/hubmap-organ-segmentation/discussion/354859",
  "author_name": "Q_takka",
  "post_date": "2022-09-24T09:39:27.454000",
  "votes": 37,
  "comment_count": 13,
  "views": 0,
  "content": "<p>Thanks to the competition host, Kaggle, and all participants. <br>\nAnd congrats to all the winners!</p>\n<h1>Overview</h1>\n<p>The key points of my solution are:</p>\n<ul>\n<li>Strong data augmentation</li>\n<li>Using whole and tile images simultaneously</li>\n</ul>\n<h1>Model &amp; Training</h1>\n<p>I used 9 CNN models.</p>\n<ul>\n<li>efficientnet b5 x 7</li>\n<li>convnext base x 2<ul>\n<li>1-class segmentation : 7 models</li>\n<li>Multi class segmentation : 2 models</li></ul></li>\n</ul>\n<h5>Best single model training settings</h5>\n<ul>\n<li>Encoder <ul>\n<li>efficientnet b5 advprop pre-trained</li></ul></li>\n<li>Decoder<ul>\n<li>UNet-based model that I modified</li></ul></li>\n<li>Data augmentation<ul>\n<li>Resize<ul>\n<li>e.g.) prostate : <code>cv2.resize(img, dsize=None, fx= 0.4/6.263, fy= 0.4/6.263, interpolation=cv2.INTER_LINEAR)</code></li></ul></li>\n<li>RandomCrop (p=0.5) <ul>\n<li>If cropped : tile image</li>\n<li>Else : whole image</li></ul></li>\n<li>ShiftScaleRotate</li>\n<li>GaussNoise</li>\n<li>GaussianBlur or MotionBlur</li>\n<li>HorizontalFlip </li>\n<li>ColorJitter</li>\n<li>RGBShift</li></ul></li>\n<li>Other detailed training settings<ul>\n<li>Input image size : 800 x 800</li>\n<li>65 epochs</li>\n<li>Loss: BCE loss + Tversky loss</li>\n<li>Optimizer: RAdam</li>\n<li>Using external data from GTEx Portal and HuBMAP - Hacking the Kidney<ul>\n<li>GTEx Portal : spleen, prostate, largeintestine<ul>\n<li>I only used 1 slide per organ because I couldn't find out that they helped my scores increased.</li></ul></li></ul></li>\n<li>All images were used for training </li>\n<li>1-class segmentation</li></ul></li>\n</ul>\n<h5>Best single model scores</h5>\n<ul>\n<li>Public HuBMAP : 0.596</li>\n<li>Private : 0.810</li>\n</ul>\n<h1>Inference</h1>\n<h5>TTA</h5>\n<ul>\n<li>Whole image<ul>\n<li>Rotate (0, 90, 180, 270) </li>\n<li>HorizontalFlip + rotate (0, 90, 180, 270) </li></ul></li>\n<li>Tile Image<ul>\n<li>Crop size : 1900 x 1900<ul>\n<li>If image size &lt; 1900 : no crop</li>\n<li>If 1900 &lt;= image size &lt; 3000 : 4 crops (2 x 2 tiles)</li>\n<li>If 3000 &lt;= image size : 9 crops (3 x 3 tiles)</li></ul></li></ul></li>\n</ul>\n<h5>Ensemble</h5>\n<ul>\n<li>Each model prediction : ((mean whole images) &gt; threshold_1) + ((mean tile images) &gt; threshold_1)</li>\n<li>Final prediction : Sum of each model prediction &gt; threshold_2<ul>\n<li>lung threshold_2 : 0</li>\n<li>kidney threshold_2 : 4</li>\n<li>the others : 2</li></ul></li>\n</ul>\n<h3>Tips</h3>\n<p>My scores increased a little using this trick.</p>\n<pre><code>img = tifffile.imread(\"test_image.tiff\").astype(np.float32)\nimg = np.clip(img+15, 0, 255).astype(np.uint8)\n</code></pre>\n<hr>\n<p>P.S.<br>\nI only used kaggle kernel for training :) </p>",
  "messages": [
    {
      "id": 1953186,
      "postDate": "2022-09-24T09:39:27.453Z",
      "content": "<p>Thanks to the competition host, Kaggle, and all participants. <br>\nAnd congrats to all the winners!</p>\n<h1>Overview</h1>\n<p>The key points of my solution are:</p>\n<ul>\n<li>Strong data augmentation</li>\n<li>Using whole and tile images simultaneously</li>\n</ul>\n<h1>Model &amp; Training</h1>\n<p>I used 9 CNN models.</p>\n<ul>\n<li>efficientnet b5 x 7</li>\n<li>convnext base x 2<ul>\n<li>1-class segmentation : 7 models</li>\n<li>Multi class segmentation : 2 models</li></ul></li>\n</ul>\n<h5>Best single model training settings</h5>\n<ul>\n<li>Encoder <ul>\n<li>efficientnet b5 advprop pre-trained</li></ul></li>\n<li>Decoder<ul>\n<li>UNet-based model that I modified</li></ul></li>\n<li>Data augmentation<ul>\n<li>Resize<ul>\n<li>e.g.) prostate : <code>cv2.resize(img, dsize=None, fx= 0.4/6.263, fy= 0.4/6.263, interpolation=cv2.INTER_LINEAR)</code></li></ul></li>\n<li>RandomCrop (p=0.5) <ul>\n<li>If cropped : tile image</li>\n<li>Else : whole image</li></ul></li>\n<li>ShiftScaleRotate</li>\n<li>GaussNoise</li>\n<li>GaussianBlur or MotionBlur</li>\n<li>HorizontalFlip </li>\n<li>ColorJitter</li>\n<li>RGBShift</li></ul></li>\n<li>Other detailed training settings<ul>\n<li>Input image size : 800 x 800</li>\n<li>65 epochs</li>\n<li>Loss: BCE loss + Tversky loss</li>\n<li>Optimizer: RAdam</li>\n<li>Using external data from GTEx Portal and HuBMAP - Hacking the Kidney<ul>\n<li>GTEx Portal : spleen, prostate, largeintestine<ul>\n<li>I only used 1 slide per organ because I couldn't find out that they helped my scores increased.</li></ul></li></ul></li>\n<li>All images were used for training </li>\n<li>1-class segmentation</li></ul></li>\n</ul>\n<h5>Best single model scores</h5>\n<ul>\n<li>Public HuBMAP : 0.596</li>\n<li>Private : 0.810</li>\n</ul>\n<h1>Inference</h1>\n<h5>TTA</h5>\n<ul>\n<li>Whole image<ul>\n<li>Rotate (0, 90, 180, 270) </li>\n<li>HorizontalFlip + rotate (0, 90, 180, 270) </li></ul></li>\n<li>Tile Image<ul>\n<li>Crop size : 1900 x 1900<ul>\n<li>If image size &lt; 1900 : no crop</li>\n<li>If 1900 &lt;= image size &lt; 3000 : 4 crops (2 x 2 tiles)</li>\n<li>If 3000 &lt;= image size : 9 crops (3 x 3 tiles)</li></ul></li></ul></li>\n</ul>\n<h5>Ensemble</h5>\n<ul>\n<li>Each model prediction : ((mean whole images) &gt; threshold_1) + ((mean tile images) &gt; threshold_1)</li>\n<li>Final prediction : Sum of each model prediction &gt; threshold_2<ul>\n<li>lung threshold_2 : 0</li>\n<li>kidney threshold_2 : 4</li>\n<li>the others : 2</li></ul></li>\n</ul>\n<h3>Tips</h3>\n<p>My scores increased a little using this trick.</p>\n<pre><code>img = tifffile.imread(\"test_image.tiff\").astype(np.float32)\nimg = np.clip(img+15, 0, 255).astype(np.uint8)\n</code></pre>\n<hr>\n<p>P.S.<br>\nI only used kaggle kernel for training :) </p>",
      "rawMarkdown": "Thanks to the competition host, Kaggle, and all participants. \nAnd congrats to all the winners!\n\n# Overview\nThe key points of my solution are:\n- Strong data augmentation\n- Using whole and tile images simultaneously\n\n# Model & Training\nI used 9 CNN models.\n- efficientnet b5 x 7\n- convnext base x 2\n    - 1-class segmentation : 7 models\n    - Multi class segmentation : 2 models\n\n##### Best single model training settings\n- Encoder \n - efficientnet b5 advprop pre-trained\n- Decoder\n - UNet-based model that I modified\n- Data augmentation\n - Resize\n     - e.g.) prostate : `cv2.resize(img, dsize=None, fx= 0.4/6.263, fy= 0.4/6.263, interpolation=cv2.INTER_LINEAR)`\n - RandomCrop (p=0.5) \n     - If cropped : tile image\n     - Else : whole image\n - ShiftScaleRotate\n - GaussNoise\n - GaussianBlur or MotionBlur\n - HorizontalFlip \n - ColorJitter\n - RGBShift\n- Other detailed training settings\n - Input image size : 800 x 800\n - 65 epochs\n - Loss: BCE loss + Tversky loss\n - Optimizer: RAdam\n - Using external data from GTEx Portal and HuBMAP - Hacking the Kidney\n     - GTEx Portal : spleen, prostate, largeintestine\n          - I only used 1 slide per organ because I couldn't find out that they helped my scores increased.\n - All images were used for training \n - 1-class segmentation\n\n##### Best single model scores\n- Public HuBMAP : 0.596\n- Private : 0.810\n\n\n# Inference\n##### TTA\n- Whole image\n    - Rotate (0, 90, 180, 270) \n    - HorizontalFlip + rotate (0, 90, 180, 270) \n- Tile Image\n    - Crop size : 1900 x 1900\n        - If image size < 1900 : no crop\n        - If 1900 <= image size < 3000 : 4 crops (2 x 2 tiles)\n        - If 3000 <= image size : 9 crops (3 x 3 tiles)\n\n##### Ensemble\n- Each model prediction : ((mean whole images) > threshold_1) + ((mean tile images) > threshold_1)\n- Final prediction : Sum of each model prediction > threshold_2\n    - lung threshold_2 : 0\n    - kidney threshold_2 : 4\n    - the others : 2\n\n### Tips\nMy scores increased a little using this trick.\n```\nimg = tifffile.imread(\"test_image.tiff\").astype(np.float32)\nimg = np.clip(img+15, 0, 255).astype(np.uint8)\n```\n\n--------------------------------------------------------------------------\n\nP.S.\nI only used kaggle kernel for training :) ",
      "votes": 37
    },
    {
      "id": 2106712,
      "postDate": "2023-01-19T10:15:06.423Z",
      "content": "<p>Impressive, all on Kaggle kernels, 😎</p>",
      "rawMarkdown": "Impressive, all on Kaggle kernels, 😎",
      "votes": 2
    },
    {
      "id": 1956528,
      "postDate": "2022-09-26T13:49:18.807Z",
      "content": "<p>Hello, could I ask how did you tune the hyperparameters? I see that you train for 65 epochs, and that seems quite a long time if we have to tune hyperparameters as well.</p>",
      "rawMarkdown": "Hello, could I ask how did you tune the hyperparameters? I see that you train for 65 epochs, and that seems quite a long time if we have to tune hyperparameters as well.",
      "votes": 1,
      "replies": [
        {
          "id": 1958091,
          "postDate": "2022-09-27T09:19:28.940Z",
          "content": "<p>heuristic and trial and error.<br>\nThe keys of this competition were color shift and pixel size, so I focused on tuning the hyper-parameters related to them.</p>",
          "rawMarkdown": "heuristic and trial and error.\nThe keys of this competition were color shift and pixel size, so I focused on tuning the hyper-parameters related to them.",
          "votes": 1
        }
      ]
    },
    {
      "id": 1954354,
      "postDate": "2022-09-25T06:57:25.703Z",
      "content": "<p>This is a very impressive work! I have a question about  \"efficientnet b5 x 7\". Does \"efficientnet b5 x 7\" mean these 7 models are trained with 7 folds data?</p>",
      "rawMarkdown": "This is a very impressive work! I have a question about  \"efficientnet b5 x 7\". Does \"efficientnet b5 x 7\" mean these 7 models are trained with 7 folds data?",
      "votes": 1,
      "replies": [
        {
          "id": 1954541,
          "postDate": "2022-09-25T10:23:15.730Z",
          "content": "<p>Thank you!<br>\nThese models are slightly different seed, hyper parameter, and the way of pre-training.</p>",
          "rawMarkdown": "Thank you!\nThese models are slightly different seed, hyper parameter, and the way of pre-training.",
          "votes": 1
        },
        {
          "id": 1954631,
          "postDate": "2022-09-25T11:12:40.657Z",
          "content": "<p>Thanks for your reply!</p>",
          "rawMarkdown": "Thanks for your reply!"
        }
      ]
    },
    {
      "id": 1954250,
      "postDate": "2022-09-25T06:01:54.247Z",
      "content": "<p><code>I only used kaggle kernel for training</code> Really amazing!</p>",
      "rawMarkdown": "`I only used kaggle kernel for training` Really amazing!",
      "votes": 1
    },
    {
      "id": 1953423,
      "postDate": "2022-09-24T13:19:43.393Z",
      "content": "<p>Great! It's really informative for me, especially the tile image part in Inference!</p>",
      "rawMarkdown": "Great! It's really informative for me, especially the tile image part in Inference!",
      "votes": 1
    },
    {
      "id": 1953223,
      "postDate": "2022-09-24T10:09:07.807Z",
      "content": "<p>Well done! Quite impressed with the usage of Kaggle alone. 👌</p>",
      "rawMarkdown": "Well done! Quite impressed with the usage of Kaggle alone. 👌",
      "votes": 1
    },
    {
      "id": 1953335,
      "postDate": "2022-09-24T12:01:13.757Z",
      "content": "<p>Great to see that it's still possible to score in the top 10 with a good solution despite a constraint on compute.  </p>\n<p>I wish competitions had a special class or bracket for competitors using only kaggle compute.  Formula one cars have regulations to compete.  We might learn some new stuff if we compare the solution strategies between this class, and an open class where any compute is allowed.  </p>\n<p>This would also make contests more accessible and reduce energy consumption of the overall contest.</p>",
      "rawMarkdown": "Great to see that it's still possible to score in the top 10 with a good solution despite a constraint on compute.  \n\nI wish competitions had a special class or bracket for competitors using only kaggle compute.  Formula one cars have regulations to compete.  We might learn some new stuff if we compare the solution strategies between this class, and an open class where any compute is allowed.  \n\nThis would also make contests more accessible and reduce energy consumption of the overall contest.",
      "votes": 2,
      "replies": [
        {
          "id": 1954127,
          "postDate": "2022-09-25T03:51:29.587Z",
          "content": "<p>Thank you!<br>\nAnd I completely agree with you.</p>",
          "rawMarkdown": "Thank you!\nAnd I completely agree with you."
        }
      ]
    },
    {
      "id": 1959652,
      "postDate": "2022-09-28T08:29:59.933Z",
      "content": "<p>nice share <a href=\"https://www.kaggle.com/qtakka\" target=\"_blank\">@qtakka</a> </p>",
      "rawMarkdown": "nice share @qtakka "
    },
    {
      "id": 2259653,
      "postDate": "2023-05-15T06:41:50.137Z",
      "rawMarkdown": "",
      "isDeleted": true
    }
  ],
  "comments": [
    {
      "id": 2106712,
      "author_name": "Darragh",
      "author_url": "",
      "post_date": "2023-01-19T10:15:06.423000",
      "content": "<p>Impressive, all on Kaggle kernels, 😎</p>",
      "votes": 2,
      "replies": []
    },
    {
      "id": 1956528,
      "author_name": "kagglerz",
      "author_url": "",
      "post_date": "2022-09-26T13:49:18.807000",
      "content": "<p>Hello, could I ask how did you tune the hyperparameters? I see that you train for 65 epochs, and that seems quite a long time if we have to tune hyperparameters as well.</p>",
      "votes": 1,
      "replies": [
        {
          "id": 1958091,
          "author_name": "Q_takka",
          "author_url": "",
          "post_date": "2022-09-27T09:19:28.940000",
          "content": "<p>heuristic and trial and error.<br>\nThe keys of this competition were color shift and pixel size, so I focused on tuning the hyper-parameters related to them.</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 1954354,
      "author_name": "gray98",
      "author_url": "",
      "post_date": "2022-09-25T06:57:25.703000",
      "content": "<p>This is a very impressive work! I have a question about  \"efficientnet b5 x 7\". Does \"efficientnet b5 x 7\" mean these 7 models are trained with 7 folds data?</p>",
      "votes": 1,
      "replies": [
        {
          "id": 1954541,
          "author_name": "Q_takka",
          "author_url": "",
          "post_date": "2022-09-25T10:23:15.730000",
          "content": "<p>Thank you!<br>\nThese models are slightly different seed, hyper parameter, and the way of pre-training.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 1954631,
          "author_name": "gray98",
          "author_url": "",
          "post_date": "2022-09-25T11:12:40.657000",
          "content": "<p>Thanks for your reply!</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1954250,
      "author_name": "ForcewithMe",
      "author_url": "",
      "post_date": "2022-09-25T06:01:54.247000",
      "content": "<p><code>I only used kaggle kernel for training</code> Really amazing!</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1953423,
      "author_name": "wiz",
      "author_url": "",
      "post_date": "2022-09-24T13:19:43.393000",
      "content": "<p>Great! It's really informative for me, especially the tile image part in Inference!</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1953223,
      "author_name": "Yassine Alouini",
      "author_url": "",
      "post_date": "2022-09-24T10:09:07.807000",
      "content": "<p>Well done! Quite impressed with the usage of Kaggle alone. 👌</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1953335,
      "author_name": "Filip Mulier",
      "author_url": "",
      "post_date": "2022-09-24T12:01:13.757000",
      "content": "<p>Great to see that it's still possible to score in the top 10 with a good solution despite a constraint on compute.  </p>\n<p>I wish competitions had a special class or bracket for competitors using only kaggle compute.  Formula one cars have regulations to compete.  We might learn some new stuff if we compare the solution strategies between this class, and an open class where any compute is allowed.  </p>\n<p>This would also make contests more accessible and reduce energy consumption of the overall contest.</p>",
      "votes": 2,
      "replies": [
        {
          "id": 1954127,
          "author_name": "Q_takka",
          "author_url": "",
          "post_date": "2022-09-25T03:51:29.587000",
          "content": "<p>Thank you!<br>\nAnd I completely agree with you.</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1959652,
      "author_name": "RuiYang Ju",
      "author_url": "",
      "post_date": "2022-09-28T08:29:59.933000",
      "content": "<p>nice share <a href=\"https://www.kaggle.com/qtakka\" target=\"_blank\">@qtakka</a> </p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 2259653,
      "author_name": "",
      "author_url": "",
      "post_date": "2023-05-15T06:41:50.137000",
      "content": "",
      "votes": 0,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "1953186": "Thanks to the competition host, Kaggle, and all participants. \nAnd congrats to all the winners!\n\n# Overview\nThe key points of my solution are:\n- Strong data augmentation\n- Using whole and tile images simultaneously\n\n# Model & Training\nI used 9 CNN models.\n- efficientnet b5 x 7\n- convnext base x 2\n    - 1-class segmentation : 7 models\n    - Multi class segmentation : 2 models\n\n##### Best single model training settings\n- Encoder \n - efficientnet b5 advprop pre-trained\n- Decoder\n - UNet-based model that I modified\n- Data augmentation\n - Resize\n     - e.g.) prostate : `cv2.resize(img, dsize=None, fx= 0.4/6.263, fy= 0.4/6.263, interpolation=cv2.INTER_LINEAR)`\n - RandomCrop (p=0.5) \n     - If cropped : tile image\n     - Else : whole image\n - ShiftScaleRotate\n - GaussNoise\n - GaussianBlur or MotionBlur\n - HorizontalFlip \n - ColorJitter\n - RGBShift\n- Other detailed training settings\n - Input image size : 800 x 800\n - 65 epochs\n - Loss: BCE loss + Tversky loss\n - Optimizer: RAdam\n - Using external data from GTEx Portal and HuBMAP - Hacking the Kidney\n     - GTEx Portal : spleen, prostate, largeintestine\n          - I only used 1 slide per organ because I couldn't find out that they helped my scores increased.\n - All images were used for training \n - 1-class segmentation\n\n##### Best single model scores\n- Public HuBMAP : 0.596\n- Private : 0.810\n\n\n# Inference\n##### TTA\n- Whole image\n    - Rotate (0, 90, 180, 270) \n    - HorizontalFlip + rotate (0, 90, 180, 270) \n- Tile Image\n    - Crop size : 1900 x 1900\n        - If image size < 1900 : no crop\n        - If 1900 <= image size < 3000 : 4 crops (2 x 2 tiles)\n        - If 3000 <= image size : 9 crops (3 x 3 tiles)\n\n##### Ensemble\n- Each model prediction : ((mean whole images) > threshold_1) + ((mean tile images) > threshold_1)\n- Final prediction : Sum of each model prediction > threshold_2\n    - lung threshold_2 : 0\n    - kidney threshold_2 : 4\n    - the others : 2\n\n### Tips\nMy scores increased a little using this trick.\n```\nimg = tifffile.imread(\"test_image.tiff\").astype(np.float32)\nimg = np.clip(img+15, 0, 255).astype(np.uint8)\n```\n\n--------------------------------------------------------------------------\n\nP.S.\nI only used kaggle kernel for training :) ",
    "2106712": "Impressive, all on Kaggle kernels, 😎",
    "1956528": "Hello, could I ask how did you tune the hyperparameters? I see that you train for 65 epochs, and that seems quite a long time if we have to tune hyperparameters as well.",
    "1954354": "This is a very impressive work! I have a question about  \"efficientnet b5 x 7\". Does \"efficientnet b5 x 7\" mean these 7 models are trained with 7 folds data?",
    "1954250": "`I only used kaggle kernel for training` Really amazing!",
    "1953423": "Great! It's really informative for me, especially the tile image part in Inference!",
    "1953223": "Well done! Quite impressed with the usage of Kaggle alone. 👌",
    "1953335": "Great to see that it's still possible to score in the top 10 with a good solution despite a constraint on compute.  \n\nI wish competitions had a special class or bracket for competitors using only kaggle compute.  Formula one cars have regulations to compete.  We might learn some new stuff if we compare the solution strategies between this class, and an open class where any compute is allowed.  \n\nThis would also make contests more accessible and reduce energy consumption of the overall contest.",
    "1959652": "nice share @qtakka ",
    "2259653": ""
  }
}