{
  "id": 429060,
  "title": "1st place solution",
  "url": "/competitions/hubmap-hacking-the-human-vasculature/discussion/429060",
  "author_name": "tascj",
  "post_date": "2023-08-04T01:35:06.368000",
  "votes": 82,
  "comment_count": 24,
  "views": 0,
  "content": "<p>Thank you to the organizers for hosting this competition.</p>\n<p>Thanks to <a href=\"https://www.kaggle.com/nghiahoangtrung\" target=\"_blank\">@nghiahoangtrung</a> for sharing the <a href=\"https://www.kaggle.com/code/nghiahoangtrung/hubmap-mmdet3-1-single-fold-inference/notebook\" target=\"_blank\">notebook and dataset</a>, which helped me make submissions within a short time.</p>\n<p>Training code of my best single model is shared on <a href=\"https://github.com/tascj/kaggle-hubmap-hacking-the-human-vasculature\" target=\"_blank\">GitHub</a>. (Update 2023/08/12)</p>\n<p>Inference notebook is public <a href=\"https://www.kaggle.com/tascj0/hubmap-2023-release\" target=\"_blank\">here</a>.</p>\n<h2>Overal strategy</h2>\n<p>For most instance segmentation models, the AP mainly relies on bounding box (bbox) prediction, while the precision of mask prediction has a minor impact. Additionally, mask prediction can be handled by other models (like the mask head of Mask R-CNN or any semantic segmentation model). Therefore, when dealing with instance segmentation tasks, I usually focus my efforts on optimizing bbox accuracy.</p>\n<p>After trying out several models, I found RTMDet to perform exceptionally well and train fast. Hence, I chose RTMDet as the primary model for my experiments.</p>\n<h2>EMA</h2>\n<p>I highlighted this because it's the most crucial technique I found in my experiments. The Exponential Moving Average (EMA) models not only demonstrates higher accuracy on the validation set but also achieves higher accuracy on the training set. In most of my experiments, I utilized EMA along with a fixed learning rate. This approach provided me with a stable foundation for conducting various experiments.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F381412%2Fc7fe742970beb68fdeca794c40919644%2Fema.png?generation=1691111824367027&amp;alt=media\" alt=\"ema\"></p>\n<h2>Dataset</h2>\n<p>I trained the final submitted models using both dataset1 and dataset2. dataset1 was split into train and val sets based on 'i' location.<br>\nSplitting based on 'i' is more difficult than random splitting. The validation score is approximately (0.47 bbox_mAP, 0.72 segm_mAP60) for random splitting and around (0.43 bbox_mAP, 0.68 segm_mAP60) for 'i' splitting.</p>\n<h2>Modeling</h2>\n<p>RTMDet-x is my baseline. I trained models with all 3 classes. Input size is 768.</p>\n<h3>add mask supervision</h3>\n<p>In the early experiments, I compared Faster R-CNN and Mask R-CNN, using the same Faster R-CNN pre-trained weights. The latter exhibited higher bbox mAP, indicating the helpfulness of mask annotation.</p>\n<p>Without using mask supervision, RTMDet-x already achieves a higher bbox mAP compared to models like Mask R-CNN. The addition of mask supervision further improves performance.</p>\n<p>There are two ways to utilize mask annotation:</p>\n<ol>\n<li>Indirectly use mask information through random rotation. Recalculate bboxes after rotation.</li>\n<li>Add a mask head to the model.</li>\n</ol>\n<p>Both worked well.</p>\n<table>\n<thead>\n<tr>\n<th>random rotate</th>\n<th>mask head</th>\n<th>bbox_mAP</th>\n<th>segm_mAP60</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>N</td>\n<td>N</td>\n<td>0.424</td>\n<td></td>\n</tr>\n<tr>\n<td>Y</td>\n<td>N</td>\n<td>0.434</td>\n<td></td>\n</tr>\n<tr>\n<td>N</td>\n<td>Y</td>\n<td>0.43</td>\n<td>0.68</td>\n</tr>\n<tr>\n<td>Y</td>\n<td>Y</td>\n<td>0.432</td>\n<td>0.688</td>\n</tr>\n</tbody>\n</table>\n<p>Due to minimal instance overlap, mask prediction is much simpler compared to typical instance segmentation scenarios.<br>\nI added a naive mask head in training to enhance bbox prediction. Surprisingly, the predictions from the mask head turned out not bad. Using the same bboxes, segm_mAP60 is slightly high than Mask R-CNN, while segm_mAP75 is slightly lower than Mask R-CNN. A single fold model without tta scored 0.565+ on the private LB, which is sufficient for a gold medal.</p>\n<h3>augmentations</h3>\n<p>I used strong geometric augmentations.</p>\n<pre><code>    dict(=,\n         img_scale=(768, 768),\n         angle_range=(-180, 180),\n         scale_range=(0.1, 2.0),\n         border_value=(114, 114, 114),\n         =0.5,\n         =1.0,\n         =0.5,\n         =1.0,\n    ),\n</code></pre>\n<h3>training</h3>\n<p>I trained with a batch size of 8, comprising 3 images from dataset1 and 5 images from dataset2. This approach led to a slight improvement.</p>\n<h3>ensemble</h3>\n<p>My final model is an ensemble, where bbox prediction is a WBF of 3 RTMDet models, a YOLOX-x (with mask supervision), and a Mask R-CNN. All models has two different weights (2 of 5 folds). Mask prediction is generated by mask head of Mask R-CNN using input size 1440. TTA was not used.</p>\n<p>The ensemble scored 0.589 private and 0.317 public.</p>\n<h2>dilation</h2>\n<p>In fact, I forgot about dilation until I saw my public score on the final day of the competition.</p>\n<p>In my local validation, adding wsi3dataset2 to the training set improved the mAP of wsi1dataset1 (all wsi1 holdout) and wsi2dataset2 (all wsi2 holdout). So I choose to trust wsi1dataset1 and wsi2dataset2.</p>\n<p>This was mostly a stroke of luck. If I had made the submission earlier, I might have made different choices in experiments. Anyway, I would definitely keep one final submission without dilation in the end.</p>\n<h2>A few tips</h2>\n<ol>\n<li>keep multiple EMA models in a single training run.</li>\n<li>use <code>torch._foreach_lerp_</code> to calculate EMA. It could save some time.</li>\n<li>use a fast COCOeval implementation. Since evaluation needs to be conducted on multiple EMA models with different momentums, faster evaluation can also save some time.</li>\n</ol>",
  "messages": [
    {
      "id": 2372816,
      "postDate": "2023-08-04T01:35:06.367Z",
      "content": "<p>Thank you to the organizers for hosting this competition.</p>\n<p>Thanks to <a href=\"https://www.kaggle.com/nghiahoangtrung\" target=\"_blank\">@nghiahoangtrung</a> for sharing the <a href=\"https://www.kaggle.com/code/nghiahoangtrung/hubmap-mmdet3-1-single-fold-inference/notebook\" target=\"_blank\">notebook and dataset</a>, which helped me make submissions within a short time.</p>\n<p>Training code of my best single model is shared on <a href=\"https://github.com/tascj/kaggle-hubmap-hacking-the-human-vasculature\" target=\"_blank\">GitHub</a>. (Update 2023/08/12)</p>\n<p>Inference notebook is public <a href=\"https://www.kaggle.com/tascj0/hubmap-2023-release\" target=\"_blank\">here</a>.</p>\n<h2>Overal strategy</h2>\n<p>For most instance segmentation models, the AP mainly relies on bounding box (bbox) prediction, while the precision of mask prediction has a minor impact. Additionally, mask prediction can be handled by other models (like the mask head of Mask R-CNN or any semantic segmentation model). Therefore, when dealing with instance segmentation tasks, I usually focus my efforts on optimizing bbox accuracy.</p>\n<p>After trying out several models, I found RTMDet to perform exceptionally well and train fast. Hence, I chose RTMDet as the primary model for my experiments.</p>\n<h2>EMA</h2>\n<p>I highlighted this because it's the most crucial technique I found in my experiments. The Exponential Moving Average (EMA) models not only demonstrates higher accuracy on the validation set but also achieves higher accuracy on the training set. In most of my experiments, I utilized EMA along with a fixed learning rate. This approach provided me with a stable foundation for conducting various experiments.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F381412%2Fc7fe742970beb68fdeca794c40919644%2Fema.png?generation=1691111824367027&amp;alt=media\" alt=\"ema\"></p>\n<h2>Dataset</h2>\n<p>I trained the final submitted models using both dataset1 and dataset2. dataset1 was split into train and val sets based on 'i' location.<br>\nSplitting based on 'i' is more difficult than random splitting. The validation score is approximately (0.47 bbox_mAP, 0.72 segm_mAP60) for random splitting and around (0.43 bbox_mAP, 0.68 segm_mAP60) for 'i' splitting.</p>\n<h2>Modeling</h2>\n<p>RTMDet-x is my baseline. I trained models with all 3 classes. Input size is 768.</p>\n<h3>add mask supervision</h3>\n<p>In the early experiments, I compared Faster R-CNN and Mask R-CNN, using the same Faster R-CNN pre-trained weights. The latter exhibited higher bbox mAP, indicating the helpfulness of mask annotation.</p>\n<p>Without using mask supervision, RTMDet-x already achieves a higher bbox mAP compared to models like Mask R-CNN. The addition of mask supervision further improves performance.</p>\n<p>There are two ways to utilize mask annotation:</p>\n<ol>\n<li>Indirectly use mask information through random rotation. Recalculate bboxes after rotation.</li>\n<li>Add a mask head to the model.</li>\n</ol>\n<p>Both worked well.</p>\n<table>\n<thead>\n<tr>\n<th>random rotate</th>\n<th>mask head</th>\n<th>bbox_mAP</th>\n<th>segm_mAP60</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>N</td>\n<td>N</td>\n<td>0.424</td>\n<td></td>\n</tr>\n<tr>\n<td>Y</td>\n<td>N</td>\n<td>0.434</td>\n<td></td>\n</tr>\n<tr>\n<td>N</td>\n<td>Y</td>\n<td>0.43</td>\n<td>0.68</td>\n</tr>\n<tr>\n<td>Y</td>\n<td>Y</td>\n<td>0.432</td>\n<td>0.688</td>\n</tr>\n</tbody>\n</table>\n<p>Due to minimal instance overlap, mask prediction is much simpler compared to typical instance segmentation scenarios.<br>\nI added a naive mask head in training to enhance bbox prediction. Surprisingly, the predictions from the mask head turned out not bad. Using the same bboxes, segm_mAP60 is slightly high than Mask R-CNN, while segm_mAP75 is slightly lower than Mask R-CNN. A single fold model without tta scored 0.565+ on the private LB, which is sufficient for a gold medal.</p>\n<h3>augmentations</h3>\n<p>I used strong geometric augmentations.</p>\n<pre><code>    dict(=,\n         img_scale=(768, 768),\n         angle_range=(-180, 180),\n         scale_range=(0.1, 2.0),\n         border_value=(114, 114, 114),\n         =0.5,\n         =1.0,\n         =0.5,\n         =1.0,\n    ),\n</code></pre>\n<h3>training</h3>\n<p>I trained with a batch size of 8, comprising 3 images from dataset1 and 5 images from dataset2. This approach led to a slight improvement.</p>\n<h3>ensemble</h3>\n<p>My final model is an ensemble, where bbox prediction is a WBF of 3 RTMDet models, a YOLOX-x (with mask supervision), and a Mask R-CNN. All models has two different weights (2 of 5 folds). Mask prediction is generated by mask head of Mask R-CNN using input size 1440. TTA was not used.</p>\n<p>The ensemble scored 0.589 private and 0.317 public.</p>\n<h2>dilation</h2>\n<p>In fact, I forgot about dilation until I saw my public score on the final day of the competition.</p>\n<p>In my local validation, adding wsi3dataset2 to the training set improved the mAP of wsi1dataset1 (all wsi1 holdout) and wsi2dataset2 (all wsi2 holdout). So I choose to trust wsi1dataset1 and wsi2dataset2.</p>\n<p>This was mostly a stroke of luck. If I had made the submission earlier, I might have made different choices in experiments. Anyway, I would definitely keep one final submission without dilation in the end.</p>\n<h2>A few tips</h2>\n<ol>\n<li>keep multiple EMA models in a single training run.</li>\n<li>use <code>torch._foreach_lerp_</code> to calculate EMA. It could save some time.</li>\n<li>use a fast COCOeval implementation. Since evaluation needs to be conducted on multiple EMA models with different momentums, faster evaluation can also save some time.</li>\n</ol>",
      "rawMarkdown": "Thank you to the organizers for hosting this competition.\n\nThanks to @nghiahoangtrung for sharing the [notebook and dataset](https://www.kaggle.com/code/nghiahoangtrung/hubmap-mmdet3-1-single-fold-inference/notebook), which helped me make submissions within a short time.\n\nTraining code of my best single model is shared on [GitHub](https://github.com/tascj/kaggle-hubmap-hacking-the-human-vasculature). (Update 2023/08/12)\n\nInference notebook is public [here](https://www.kaggle.com/tascj0/hubmap-2023-release).\n\n## Overal strategy\n\nFor most instance segmentation models, the AP mainly relies on bounding box (bbox) prediction, while the precision of mask prediction has a minor impact. Additionally, mask prediction can be handled by other models (like the mask head of Mask R-CNN or any semantic segmentation model). Therefore, when dealing with instance segmentation tasks, I usually focus my efforts on optimizing bbox accuracy.\n\nAfter trying out several models, I found RTMDet to perform exceptionally well and train fast. Hence, I chose RTMDet as the primary model for my experiments.\n\n## EMA\n\nI highlighted this because it's the most crucial technique I found in my experiments. The Exponential Moving Average (EMA) models not only demonstrates higher accuracy on the validation set but also achieves higher accuracy on the training set. In most of my experiments, I utilized EMA along with a fixed learning rate. This approach provided me with a stable foundation for conducting various experiments.\n\n![ema](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F381412%2Fc7fe742970beb68fdeca794c40919644%2Fema.png?generation=1691111824367027&alt=media)\n\n## Dataset\n\nI trained the final submitted models using both dataset1 and dataset2. dataset1 was split into train and val sets based on 'i' location.\nSplitting based on 'i' is more difficult than random splitting. The validation score is approximately (0.47 bbox_mAP, 0.72 segm_mAP60) for random splitting and around (0.43 bbox_mAP, 0.68 segm_mAP60) for 'i' splitting.\n\n## Modeling\n\nRTMDet-x is my baseline. I trained models with all 3 classes. Input size is 768.\n\n### add mask supervision\n\nIn the early experiments, I compared Faster R-CNN and Mask R-CNN, using the same Faster R-CNN pre-trained weights. The latter exhibited higher bbox mAP, indicating the helpfulness of mask annotation.\n\nWithout using mask supervision, RTMDet-x already achieves a higher bbox mAP compared to models like Mask R-CNN. The addition of mask supervision further improves performance.\n\nThere are two ways to utilize mask annotation:\n\n1. Indirectly use mask information through random rotation. Recalculate bboxes after rotation.\n2. Add a mask head to the model.\n\nBoth worked well.\n\n| random rotate | mask head | bbox_mAP | segm_mAP60 |\n|---------------|-----------|----------|------------|\n| N             | N         | 0.424    |            |\n| Y             | N         | 0.434    |            |\n| N             | Y         | 0.43     | 0.68       |\n| Y             | Y         | 0.432    | 0.688      |\n\nDue to minimal instance overlap, mask prediction is much simpler compared to typical instance segmentation scenarios.\nI added a naive mask head in training to enhance bbox prediction. Surprisingly, the predictions from the mask head turned out not bad. Using the same bboxes, segm_mAP60 is slightly high than Mask R-CNN, while segm_mAP75 is slightly lower than Mask R-CNN. A single fold model without tta scored 0.565+ on the private LB, which is sufficient for a gold medal.\n\n### augmentations\n\nI used strong geometric augmentations.\n\n```\n    dict(type='RandomRotateScaleCrop',\n         img_scale=(768, 768),\n         angle_range=(-180, 180),\n         scale_range=(0.1, 2.0),\n         border_value=(114, 114, 114),\n         rotate_prob=0.5,\n         scale_prob=1.0,\n         hflip_prob=0.5,\n         rot90_prob=1.0,\n    ),\n```\n\n### training\n\nI trained with a batch size of 8, comprising 3 images from dataset1 and 5 images from dataset2. This approach led to a slight improvement.\n\n### ensemble\n\nMy final model is an ensemble, where bbox prediction is a WBF of 3 RTMDet models, a YOLOX-x (with mask supervision), and a Mask R-CNN. All models has two different weights (2 of 5 folds). Mask prediction is generated by mask head of Mask R-CNN using input size 1440. TTA was not used.\n\nThe ensemble scored 0.589 private and 0.317 public.\n\n## dilation\n\nIn fact, I forgot about dilation until I saw my public score on the final day of the competition.\n\nIn my local validation, adding wsi3dataset2 to the training set improved the mAP of wsi1dataset1 (all wsi1 holdout) and wsi2dataset2 (all wsi2 holdout). So I choose to trust wsi1dataset1 and wsi2dataset2.\n\nThis was mostly a stroke of luck. If I had made the submission earlier, I might have made different choices in experiments. Anyway, I would definitely keep one final submission without dilation in the end.\n\n## A few tips\n\n1. keep multiple EMA models in a single training run.\n2. use `torch._foreach_lerp_` to calculate EMA. It could save some time.\n3. use a fast COCOeval implementation. Since evaluation needs to be conducted on multiple EMA models with different momentums, faster evaluation can also save some time.\n",
      "votes": 82
    },
    {
      "id": 2374519,
      "postDate": "2023-08-05T04:04:37.390Z",
      "content": "<p>Congratulations man! Great achievement.</p>\n<p>Thanks for sharing the solution.</p>",
      "rawMarkdown": "Congratulations man! Great achievement.\n\nThanks for sharing the solution.",
      "votes": 1
    },
    {
      "id": 2374405,
      "postDate": "2023-08-05T00:19:37.600Z",
      "content": "<p>Congratulations and thanks for sharing your thoughts and code to learn from your success!</p>",
      "rawMarkdown": "Congratulations and thanks for sharing your thoughts and code to learn from your success!",
      "votes": 1
    },
    {
      "id": 2373350,
      "postDate": "2023-08-04T08:22:30.830Z",
      "content": "<p>Magnificent !</p>",
      "rawMarkdown": "Magnificent !",
      "votes": 1
    },
    {
      "id": 2373306,
      "postDate": "2023-08-04T07:54:18.580Z",
      "content": "<p>Congratulations !</p>",
      "rawMarkdown": "Congratulations !",
      "votes": 1
    },
    {
      "id": 2372958,
      "postDate": "2023-08-04T04:52:51.230Z",
      "content": "<p>Kudos, <a href=\"https://www.kaggle.com/tascj0\" target=\"_blank\">@tascj0</a> . It shows your dedication and efforts!! You deserve it…</p>",
      "rawMarkdown": "Kudos, @tascj0 . It shows your dedication and efforts!! You deserve it...",
      "votes": 1
    },
    {
      "id": 2372848,
      "postDate": "2023-08-04T02:23:45.603Z",
      "content": "<p>Congratulations!🥳</p>",
      "rawMarkdown": "Congratulations!🥳",
      "votes": 1
    },
    {
      "id": 2372818,
      "postDate": "2023-08-04T01:45:42.510Z",
      "content": "<p>Kudos on winning the competition <a href=\"https://www.kaggle.com/tascj0\" target=\"_blank\">@tascj0</a>  🎉<br>\nThanks for sharing. Hope to learn a lot from your notebook. </p>",
      "rawMarkdown": "Kudos on winning the competition @tascj0  🎉\nThanks for sharing. Hope to learn a lot from your notebook. ",
      "votes": 1
    },
    {
      "id": 2379142,
      "postDate": "2023-08-08T02:54:32.130Z",
      "content": "<p>Thanks for sharing. Hope to learn a lot from your notebook.</p>",
      "rawMarkdown": "Thanks for sharing. Hope to learn a lot from your notebook.",
      "votes": 2
    },
    {
      "id": 2375399,
      "postDate": "2023-08-05T15:47:34.830Z",
      "content": "<p>Congratulations and thanks for sharing your solution!</p>",
      "rawMarkdown": "Congratulations and thanks for sharing your solution!",
      "votes": 2
    },
    {
      "id": 2375365,
      "postDate": "2023-08-05T15:19:24.450Z",
      "content": "<p>Thanks for sharing your solution and insights. 🥳<br>\nFocusing on bounding box prediction for instance segmentation makes sense indeed since it is mAP that is measured and not mIoU. 👍</p>",
      "rawMarkdown": "Thanks for sharing your solution and insights. 🥳\nFocusing on bounding box prediction for instance segmentation makes sense indeed since it is mAP that is measured and not mIoU. 👍",
      "votes": 2
    },
    {
      "id": 2943225,
      "postDate": "2024-08-01T12:43:36.733Z",
      "content": "<p>Congratulations and thank you for sharing! Great job!</p>",
      "rawMarkdown": "Congratulations and thank you for sharing! Great job!"
    },
    {
      "id": 2717618,
      "postDate": "2024-03-26T17:07:04.030Z",
      "content": "<p>Congratulations and thanks for your sharing!</p>",
      "rawMarkdown": "Congratulations and thanks for your sharing!"
    },
    {
      "id": 2590548,
      "postDate": "2024-01-07T09:23:13.027Z",
      "content": "<p>Congratulations and thanks for sharing your ideas</p>",
      "rawMarkdown": "Congratulations and thanks for sharing your ideas"
    },
    {
      "id": 2486912,
      "postDate": "2023-10-18T08:33:36.743Z",
      "content": "<p>Really good !</p>",
      "rawMarkdown": "Really good !"
    },
    {
      "id": 2387195,
      "postDate": "2023-08-12T13:32:49.890Z",
      "content": "<p>ths，bro ！very nice notebook！</p>",
      "rawMarkdown": "ths，bro ！very nice notebook！"
    },
    {
      "id": 2379458,
      "postDate": "2023-08-08T06:58:16.233Z",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/tascj0\" target=\"_blank\">@tascj0</a> for attaining the position. Thanks for sharing motivational stuff. 👏</p>",
      "rawMarkdown": "Congratulations @tascj0 for attaining the position. Thanks for sharing motivational stuff. 👏"
    },
    {
      "id": 2378954,
      "postDate": "2023-08-07T22:02:40.043Z",
      "content": "<p>Thanks for sharing your solution and congrats! Excited to learn from your notebook 🙏</p>",
      "rawMarkdown": "Thanks for sharing your solution and congrats! Excited to learn from your notebook 🙏"
    },
    {
      "id": 2377469,
      "postDate": "2023-08-07T06:59:38.530Z",
      "content": "<p>Congratulations!!! Thanks for sharing your solution and insights🥳</p>",
      "rawMarkdown": "Congratulations!!! Thanks for sharing your solution and insights🥳"
    },
    {
      "id": 2376048,
      "postDate": "2023-08-06T06:22:31.023Z",
      "content": "<p>Congrats! Thanks for describing your solution</p>",
      "rawMarkdown": "Congrats! Thanks for describing your solution"
    },
    {
      "id": 2375964,
      "postDate": "2023-08-06T04:01:11.263Z",
      "content": "<p>was tinkering about this from a long time..!</p>",
      "rawMarkdown": "was tinkering about this from a long time..!"
    },
    {
      "id": 2375895,
      "postDate": "2023-08-06T02:38:43.587Z",
      "content": "<p>Congratulations and thank you for sharing your solution.<br>\nI will use this as a reference to study.</p>",
      "rawMarkdown": "Congratulations and thank you for sharing your solution.\nI will use this as a reference to study."
    },
    {
      "id": 2372838,
      "postDate": "2023-08-04T02:08:37.537Z",
      "content": "<p>Congratulations on winning first place. <a href=\"https://www.kaggle.com/tascj0\" target=\"_blank\">@tascj0</a> 🎊<br>\nThanks for sharing your solid work!  I got inspired by the tips and mask supervision part.</p>",
      "rawMarkdown": "Congratulations on winning first place. @tascj0 🎊\nThanks for sharing your solid work!  I got inspired by the tips and mask supervision part.",
      "votes": 2,
      "isDeleted": true
    },
    {
      "id": 3231508,
      "postDate": "2025-06-24T14:04:01.963Z",
      "content": "<p>Nice notebook. Thank you for sharing.</p>",
      "rawMarkdown": "Nice notebook. Thank you for sharing."
    },
    {
      "id": 2375594,
      "postDate": "2023-08-05T18:32:15.150Z",
      "content": "<p>Thank you for sharing this work!</p>",
      "rawMarkdown": "Thank you for sharing this work!"
    }
  ],
  "comments": [
    {
      "id": 2374519,
      "author_name": "Muhammad Usman",
      "author_url": "",
      "post_date": "2023-08-05T04:04:37.390000",
      "content": "<p>Congratulations man! Great achievement.</p>\n<p>Thanks for sharing the solution.</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 2374405,
      "author_name": "Guillermo Perez G",
      "author_url": "",
      "post_date": "2023-08-05T00:19:37.600000",
      "content": "<p>Congratulations and thanks for sharing your thoughts and code to learn from your success!</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 2373350,
      "author_name": "ryankert",
      "author_url": "",
      "post_date": "2023-08-04T08:22:30.830000",
      "content": "<p>Magnificent !</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 2373306,
      "author_name": "Aurora Rabbit",
      "author_url": "",
      "post_date": "2023-08-04T07:54:18.580000",
      "content": "<p>Congratulations !</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 2372958,
      "author_name": "Danushkumar Venkadesh",
      "author_url": "",
      "post_date": "2023-08-04T04:52:51.230000",
      "content": "<p>Kudos, <a href=\"https://www.kaggle.com/tascj0\" target=\"_blank\">@tascj0</a> . It shows your dedication and efforts!! You deserve it…</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 2372848,
      "author_name": "devchopin",
      "author_url": "",
      "post_date": "2023-08-04T02:23:45.603000",
      "content": "<p>Congratulations!🥳</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 2372818,
      "author_name": "Suraj",
      "author_url": "",
      "post_date": "2023-08-04T01:45:42.510000",
      "content": "<p>Kudos on winning the competition <a href=\"https://www.kaggle.com/tascj0\" target=\"_blank\">@tascj0</a>  🎉<br>\nThanks for sharing. Hope to learn a lot from your notebook. </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 2379142,
      "author_name": "Holmes0610",
      "author_url": "",
      "post_date": "2023-08-08T02:54:32.130000",
      "content": "<p>Thanks for sharing. Hope to learn a lot from your notebook.</p>",
      "votes": 2,
      "replies": []
    },
    {
      "id": 2375399,
      "author_name": "abhamidi",
      "author_url": "",
      "post_date": "2023-08-05T15:47:34.830000",
      "content": "<p>Congratulations and thanks for sharing your solution!</p>",
      "votes": 2,
      "replies": []
    },
    {
      "id": 2375365,
      "author_name": "Yassine Alouini",
      "author_url": "",
      "post_date": "2023-08-05T15:19:24.450000",
      "content": "<p>Thanks for sharing your solution and insights. 🥳<br>\nFocusing on bounding box prediction for instance segmentation makes sense indeed since it is mAP that is measured and not mIoU. 👍</p>",
      "votes": 2,
      "replies": []
    },
    {
      "id": 2943225,
      "author_name": "Vladimir Sashin",
      "author_url": "",
      "post_date": "2024-08-01T12:43:36.733000",
      "content": "<p>Congratulations and thank you for sharing! Great job!</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 2717618,
      "author_name": "chinaman",
      "author_url": "",
      "post_date": "2024-03-26T17:07:04.030000",
      "content": "<p>Congratulations and thanks for your sharing!</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 2590548,
      "author_name": "smallpoxscattered",
      "author_url": "",
      "post_date": "2024-01-07T09:23:13.027000",
      "content": "<p>Congratulations and thanks for sharing your ideas</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 2486912,
      "author_name": "ClementCalu",
      "author_url": "",
      "post_date": "2023-10-18T08:33:36.743000",
      "content": "<p>Really good !</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 2387195,
      "author_name": "富贵",
      "author_url": "",
      "post_date": "2023-08-12T13:32:49.890000",
      "content": "<p>ths，bro ！very nice notebook！</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 2379458,
      "author_name": "Tariq Mahmood",
      "author_url": "",
      "post_date": "2023-08-08T06:58:16.233000",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/tascj0\" target=\"_blank\">@tascj0</a> for attaining the position. Thanks for sharing motivational stuff. 👏</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 2378954,
      "author_name": "Jazz Honegger",
      "author_url": "",
      "post_date": "2023-08-07T22:02:40.043000",
      "content": "<p>Thanks for sharing your solution and congrats! Excited to learn from your notebook 🙏</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 2377469,
      "author_name": "samkaranth",
      "author_url": "",
      "post_date": "2023-08-07T06:59:38.530000",
      "content": "<p>Congratulations!!! Thanks for sharing your solution and insights🥳</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 2376048,
      "author_name": "Viktor Taranenko",
      "author_url": "",
      "post_date": "2023-08-06T06:22:31.023000",
      "content": "<p>Congrats! Thanks for describing your solution</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 2375964,
      "author_name": "MLV Prasad",
      "author_url": "",
      "post_date": "2023-08-06T04:01:11.263000",
      "content": "<p>was tinkering about this from a long time..!</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 2375895,
      "author_name": "kou take",
      "author_url": "",
      "post_date": "2023-08-06T02:38:43.587000",
      "content": "<p>Congratulations and thank you for sharing your solution.<br>\nI will use this as a reference to study.</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 2372838,
      "author_name": "",
      "author_url": "",
      "post_date": "2023-08-04T02:08:37.537000",
      "content": "<p>Congratulations on winning first place. <a href=\"https://www.kaggle.com/tascj0\" target=\"_blank\">@tascj0</a> 🎊<br>\nThanks for sharing your solid work!  I got inspired by the tips and mask supervision part.</p>",
      "votes": 2,
      "replies": []
    },
    {
      "id": 3231508,
      "author_name": "XCN826",
      "author_url": "",
      "post_date": "2025-06-24T14:04:01.963000",
      "content": "<p>Nice notebook. Thank you for sharing.</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 2375594,
      "author_name": "WiseK9",
      "author_url": "",
      "post_date": "2023-08-05T18:32:15.150000",
      "content": "<p>Thank you for sharing this work!</p>",
      "votes": 0,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "2372816": "Thank you to the organizers for hosting this competition.\n\nThanks to @nghiahoangtrung for sharing the [notebook and dataset](https://www.kaggle.com/code/nghiahoangtrung/hubmap-mmdet3-1-single-fold-inference/notebook), which helped me make submissions within a short time.\n\nTraining code of my best single model is shared on [GitHub](https://github.com/tascj/kaggle-hubmap-hacking-the-human-vasculature). (Update 2023/08/12)\n\nInference notebook is public [here](https://www.kaggle.com/tascj0/hubmap-2023-release).\n\n## Overal strategy\n\nFor most instance segmentation models, the AP mainly relies on bounding box (bbox) prediction, while the precision of mask prediction has a minor impact. Additionally, mask prediction can be handled by other models (like the mask head of Mask R-CNN or any semantic segmentation model). Therefore, when dealing with instance segmentation tasks, I usually focus my efforts on optimizing bbox accuracy.\n\nAfter trying out several models, I found RTMDet to perform exceptionally well and train fast. Hence, I chose RTMDet as the primary model for my experiments.\n\n## EMA\n\nI highlighted this because it's the most crucial technique I found in my experiments. The Exponential Moving Average (EMA) models not only demonstrates higher accuracy on the validation set but also achieves higher accuracy on the training set. In most of my experiments, I utilized EMA along with a fixed learning rate. This approach provided me with a stable foundation for conducting various experiments.\n\n![ema](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F381412%2Fc7fe742970beb68fdeca794c40919644%2Fema.png?generation=1691111824367027&alt=media)\n\n## Dataset\n\nI trained the final submitted models using both dataset1 and dataset2. dataset1 was split into train and val sets based on 'i' location.\nSplitting based on 'i' is more difficult than random splitting. The validation score is approximately (0.47 bbox_mAP, 0.72 segm_mAP60) for random splitting and around (0.43 bbox_mAP, 0.68 segm_mAP60) for 'i' splitting.\n\n## Modeling\n\nRTMDet-x is my baseline. I trained models with all 3 classes. Input size is 768.\n\n### add mask supervision\n\nIn the early experiments, I compared Faster R-CNN and Mask R-CNN, using the same Faster R-CNN pre-trained weights. The latter exhibited higher bbox mAP, indicating the helpfulness of mask annotation.\n\nWithout using mask supervision, RTMDet-x already achieves a higher bbox mAP compared to models like Mask R-CNN. The addition of mask supervision further improves performance.\n\nThere are two ways to utilize mask annotation:\n\n1. Indirectly use mask information through random rotation. Recalculate bboxes after rotation.\n2. Add a mask head to the model.\n\nBoth worked well.\n\n| random rotate | mask head | bbox_mAP | segm_mAP60 |\n|---------------|-----------|----------|------------|\n| N             | N         | 0.424    |            |\n| Y             | N         | 0.434    |            |\n| N             | Y         | 0.43     | 0.68       |\n| Y             | Y         | 0.432    | 0.688      |\n\nDue to minimal instance overlap, mask prediction is much simpler compared to typical instance segmentation scenarios.\nI added a naive mask head in training to enhance bbox prediction. Surprisingly, the predictions from the mask head turned out not bad. Using the same bboxes, segm_mAP60 is slightly high than Mask R-CNN, while segm_mAP75 is slightly lower than Mask R-CNN. A single fold model without tta scored 0.565+ on the private LB, which is sufficient for a gold medal.\n\n### augmentations\n\nI used strong geometric augmentations.\n\n```\n    dict(type='RandomRotateScaleCrop',\n         img_scale=(768, 768),\n         angle_range=(-180, 180),\n         scale_range=(0.1, 2.0),\n         border_value=(114, 114, 114),\n         rotate_prob=0.5,\n         scale_prob=1.0,\n         hflip_prob=0.5,\n         rot90_prob=1.0,\n    ),\n```\n\n### training\n\nI trained with a batch size of 8, comprising 3 images from dataset1 and 5 images from dataset2. This approach led to a slight improvement.\n\n### ensemble\n\nMy final model is an ensemble, where bbox prediction is a WBF of 3 RTMDet models, a YOLOX-x (with mask supervision), and a Mask R-CNN. All models has two different weights (2 of 5 folds). Mask prediction is generated by mask head of Mask R-CNN using input size 1440. TTA was not used.\n\nThe ensemble scored 0.589 private and 0.317 public.\n\n## dilation\n\nIn fact, I forgot about dilation until I saw my public score on the final day of the competition.\n\nIn my local validation, adding wsi3dataset2 to the training set improved the mAP of wsi1dataset1 (all wsi1 holdout) and wsi2dataset2 (all wsi2 holdout). So I choose to trust wsi1dataset1 and wsi2dataset2.\n\nThis was mostly a stroke of luck. If I had made the submission earlier, I might have made different choices in experiments. Anyway, I would definitely keep one final submission without dilation in the end.\n\n## A few tips\n\n1. keep multiple EMA models in a single training run.\n2. use `torch._foreach_lerp_` to calculate EMA. It could save some time.\n3. use a fast COCOeval implementation. Since evaluation needs to be conducted on multiple EMA models with different momentums, faster evaluation can also save some time.\n",
    "2374519": "Congratulations man! Great achievement.\n\nThanks for sharing the solution.",
    "2374405": "Congratulations and thanks for sharing your thoughts and code to learn from your success!",
    "2373350": "Magnificent !",
    "2373306": "Congratulations !",
    "2372958": "Kudos, @tascj0 . It shows your dedication and efforts!! You deserve it...",
    "2372848": "Congratulations!🥳",
    "2372818": "Kudos on winning the competition @tascj0  🎉\nThanks for sharing. Hope to learn a lot from your notebook. ",
    "2379142": "Thanks for sharing. Hope to learn a lot from your notebook.",
    "2375399": "Congratulations and thanks for sharing your solution!",
    "2375365": "Thanks for sharing your solution and insights. 🥳\nFocusing on bounding box prediction for instance segmentation makes sense indeed since it is mAP that is measured and not mIoU. 👍",
    "2943225": "Congratulations and thank you for sharing! Great job!",
    "2717618": "Congratulations and thanks for your sharing!",
    "2590548": "Congratulations and thanks for sharing your ideas",
    "2486912": "Really good !",
    "2387195": "ths，bro ！very nice notebook！",
    "2379458": "Congratulations @tascj0 for attaining the position. Thanks for sharing motivational stuff. 👏",
    "2378954": "Thanks for sharing your solution and congrats! Excited to learn from your notebook 🙏",
    "2377469": "Congratulations!!! Thanks for sharing your solution and insights🥳",
    "2376048": "Congrats! Thanks for describing your solution",
    "2375964": "was tinkering about this from a long time..!",
    "2375895": "Congratulations and thank you for sharing your solution.\nI will use this as a reference to study.",
    "2372838": "Congratulations on winning first place. @tascj0 🎊\nThanks for sharing your solid work!  I got inspired by the tips and mask supervision part.",
    "3231508": "Nice notebook. Thank you for sharing.",
    "2375594": "Thank you for sharing this work!"
  }
}