{
  "id": 356201,
  "title": "1st place solution",
  "url": "/competitions/hubmap-organ-segmentation/discussion/356201",
  "author_name": "opusen",
  "post_date": "2022-09-29T16:07:17.843000",
  "votes": 48,
  "comment_count": 15,
  "views": 0,
  "content": "<p>First of all, I’d like to express my gratitude to kaggle and the competition hosts for holding such an amazing competition.<br>\nI’d like to thank MMSegmentation developers too. MMSegmentation is really nice and useful tool. Also great thanks to <a href=\"https://www.kaggle.com/ayuraj\" target=\"_blank\">@ayuraj</a> who incorporated a hook of Weight &amp; Biases into MMSegmentation, which helped a lot to manage training history.</p>\n<p>In the contest, I learned a lot from <a href=\"https://www.kaggle.com/hengck23\" target=\"_blank\">@hengck23</a>. Thank you so much for sharing knowledge with us:)</p>\n<h3><strong>Overview</strong></h3>\n<p>I used the following methods.<br>\n・ End-to-end MMSegmentation(with customization)<br>\n・ Ensemble of SegFormers<br>\n・ Used group normalization and trained with batch_size=1 in Colab<br>\n・ Hand-labeling of lung from scratch<br>\n・ External dataset and pseudo labeling.</p>\n<h3><strong>DataSet</strong></h3>\n<p>Used dataset:<br>\n・ HPA images [351 images]<br>\n・ HPA images stained with H&amp;E or PAS [351 images x 4 stain patterns]<br>\n・ external spleen [39 images + 39 images x 4 stain patterns]    *from a single image<br>\n・ external lung [73 images]    *from a single image</p>\n<p><strong>(Lung)</strong>When I noticed that unstable results were from lung prediction, I imagined  hand labeling is better than predicting lung by low threshold, which might lead to unstable and unconfident results. So  I researched how lung alveolus/alveoli look alike and hand-labeled lung images from scratch. Since there is no information on how to annotate alveolus/alveoli anywhere, I made about 7 annotation sets where potential alveolus was gradually annotated and probed which one is the best. Then I created an external dataset with pseudo labels and with the best threshold. After training with it, the best threshold for lung increased to 0.60, which gave the best result ever. I guess good modeling is better than hand labeling since there are those who got 0.11/0.22 in public/private. <br>\n<strong>(Spleen)</strong>Used pseudo label for an external dataset<br>\n<strong>(Prostate/ Largeintestine)</strong>Used pseudo label for the HPA dataset.<br>\nI had a feeling that my models underfit HPA dataset because these dataset didn’t put weight on HPA datasets in terms of colors. The torchstain was used for the stain tool.</p>\n<h3><strong>Models</strong></h3>\n<p>Ensemble of the following models:<br>\n・ 1x SegFormer mit-b3, image_size: 1024x1024<br>\n・ 2x SegFormer mit-b4, image_size: 960x960<br>\n・ 1x SegFormer mit-b5, image_size: 928x928<br>\n・ 2x SegFormer mit-b5, image_size: 960x960<br>\nDifferent pretrained models, seed and additional stain dataset were used in some models. The reason all models are SegFormer is I chose models only from MMSegmentation and it worked well.<br>\n*Best single model was mit-b4(private: 0.82821).</p>\n<h3><strong>Traning</strong></h3>\n<p>I used google colaboratory. Since GPU resources are limited, I trained segformer with batch_size=1 with group normalization.  In my experiment, it was better than batch_size=4 with batch normalization in both CV and LB. I chose 2 class rather than 6 class segmentation because it showed better results consistently, especially in lung. In 6 classes, the area of the lung tends to shrink and even if the area was equivalent to 2 classes, LB lung score was worse.</p>\n<p>settings:<br>\n・ norm: group normalization(num_groups=32) for decoder<br>\n・ num_classes:2<br>\n・ loss_decode: CE:LovaszLoss=1:3<br>\n・ steps: 45000<br>\n・ optimization: AdamW with lr=0.00006 </p>\n<p>augmentations:<br>\n・ Dataset image size: 2000x2000<br>\n・ Downscale for prostate<br>\n・ Crop/ Flip/ RandomRotate90/ HueSaturationValue/ RandomGamma/ RandomBrightness<br>\n・ (mmseg)Resize to (480~1600, 480~1600)  * such as (480, 1600), (1024,1024), (1500,480)<br>\n・ (mmseg)RandomCrop(crop_size=model input size)</p>\n<h3><strong>Inference</strong></h3>\n<p>・ Whole image and ignored pixel_size<br>\n・ TTA: horizontal flip and different scales (approximately x0.8, x1.0, x1.2) .<br>\n・ Thresholds for each organ were  kidney: 0.3 | large intestine: 0.2 | lung: 0.6 | prostate: 0.3 | spleen: 0.5</p>\n<h3><strong>Results</strong></h3>\n<p>all        private: 0.83562    public: 0.82716 <br>\nkidney        private: 0.16940        public: 0.12175<br>\nlarge intestine    private: 0.09005        public: 0.05730<br>\nlung        private: 0.21586        public: 0.10963<br>\nprostate    private: 0.17784        public: 0.14772<br>\nspleen        private: 0.18246        public: 0.17515</p>\n<h3><strong>About license</strong></h3>\n<p>Pretrained SegFormer and its encoder “mit” are unavailable for commercial use.  It seems that other winners also use this model. However, I got an answer from the host, which permits the use of SegFormer in this competiion. The reasons are:</p>\n<ol>\n<li>Since competition hosts are non-profit, the commercial restriction isn’t applied.</li>\n<li>The model was Apache 2.0 license at the competition launch and  the license was changed during the competition.</li>\n</ol>",
  "messages": [
    {
      "id": 1962297,
      "postDate": "2022-09-29T16:07:17.843Z",
      "content": "<p>First of all, I’d like to express my gratitude to kaggle and the competition hosts for holding such an amazing competition.<br>\nI’d like to thank MMSegmentation developers too. MMSegmentation is really nice and useful tool. Also great thanks to <a href=\"https://www.kaggle.com/ayuraj\" target=\"_blank\">@ayuraj</a> who incorporated a hook of Weight &amp; Biases into MMSegmentation, which helped a lot to manage training history.</p>\n<p>In the contest, I learned a lot from <a href=\"https://www.kaggle.com/hengck23\" target=\"_blank\">@hengck23</a>. Thank you so much for sharing knowledge with us:)</p>\n<h3><strong>Overview</strong></h3>\n<p>I used the following methods.<br>\n・ End-to-end MMSegmentation(with customization)<br>\n・ Ensemble of SegFormers<br>\n・ Used group normalization and trained with batch_size=1 in Colab<br>\n・ Hand-labeling of lung from scratch<br>\n・ External dataset and pseudo labeling.</p>\n<h3><strong>DataSet</strong></h3>\n<p>Used dataset:<br>\n・ HPA images [351 images]<br>\n・ HPA images stained with H&amp;E or PAS [351 images x 4 stain patterns]<br>\n・ external spleen [39 images + 39 images x 4 stain patterns]    *from a single image<br>\n・ external lung [73 images]    *from a single image</p>\n<p><strong>(Lung)</strong>When I noticed that unstable results were from lung prediction, I imagined  hand labeling is better than predicting lung by low threshold, which might lead to unstable and unconfident results. So  I researched how lung alveolus/alveoli look alike and hand-labeled lung images from scratch. Since there is no information on how to annotate alveolus/alveoli anywhere, I made about 7 annotation sets where potential alveolus was gradually annotated and probed which one is the best. Then I created an external dataset with pseudo labels and with the best threshold. After training with it, the best threshold for lung increased to 0.60, which gave the best result ever. I guess good modeling is better than hand labeling since there are those who got 0.11/0.22 in public/private. <br>\n<strong>(Spleen)</strong>Used pseudo label for an external dataset<br>\n<strong>(Prostate/ Largeintestine)</strong>Used pseudo label for the HPA dataset.<br>\nI had a feeling that my models underfit HPA dataset because these dataset didn’t put weight on HPA datasets in terms of colors. The torchstain was used for the stain tool.</p>\n<h3><strong>Models</strong></h3>\n<p>Ensemble of the following models:<br>\n・ 1x SegFormer mit-b3, image_size: 1024x1024<br>\n・ 2x SegFormer mit-b4, image_size: 960x960<br>\n・ 1x SegFormer mit-b5, image_size: 928x928<br>\n・ 2x SegFormer mit-b5, image_size: 960x960<br>\nDifferent pretrained models, seed and additional stain dataset were used in some models. The reason all models are SegFormer is I chose models only from MMSegmentation and it worked well.<br>\n*Best single model was mit-b4(private: 0.82821).</p>\n<h3><strong>Traning</strong></h3>\n<p>I used google colaboratory. Since GPU resources are limited, I trained segformer with batch_size=1 with group normalization.  In my experiment, it was better than batch_size=4 with batch normalization in both CV and LB. I chose 2 class rather than 6 class segmentation because it showed better results consistently, especially in lung. In 6 classes, the area of the lung tends to shrink and even if the area was equivalent to 2 classes, LB lung score was worse.</p>\n<p>settings:<br>\n・ norm: group normalization(num_groups=32) for decoder<br>\n・ num_classes:2<br>\n・ loss_decode: CE:LovaszLoss=1:3<br>\n・ steps: 45000<br>\n・ optimization: AdamW with lr=0.00006 </p>\n<p>augmentations:<br>\n・ Dataset image size: 2000x2000<br>\n・ Downscale for prostate<br>\n・ Crop/ Flip/ RandomRotate90/ HueSaturationValue/ RandomGamma/ RandomBrightness<br>\n・ (mmseg)Resize to (480~1600, 480~1600)  * such as (480, 1600), (1024,1024), (1500,480)<br>\n・ (mmseg)RandomCrop(crop_size=model input size)</p>\n<h3><strong>Inference</strong></h3>\n<p>・ Whole image and ignored pixel_size<br>\n・ TTA: horizontal flip and different scales (approximately x0.8, x1.0, x1.2) .<br>\n・ Thresholds for each organ were  kidney: 0.3 | large intestine: 0.2 | lung: 0.6 | prostate: 0.3 | spleen: 0.5</p>\n<h3><strong>Results</strong></h3>\n<p>all        private: 0.83562    public: 0.82716 <br>\nkidney        private: 0.16940        public: 0.12175<br>\nlarge intestine    private: 0.09005        public: 0.05730<br>\nlung        private: 0.21586        public: 0.10963<br>\nprostate    private: 0.17784        public: 0.14772<br>\nspleen        private: 0.18246        public: 0.17515</p>\n<h3><strong>About license</strong></h3>\n<p>Pretrained SegFormer and its encoder “mit” are unavailable for commercial use.  It seems that other winners also use this model. However, I got an answer from the host, which permits the use of SegFormer in this competiion. The reasons are:</p>\n<ol>\n<li>Since competition hosts are non-profit, the commercial restriction isn’t applied.</li>\n<li>The model was Apache 2.0 license at the competition launch and  the license was changed during the competition.</li>\n</ol>",
      "rawMarkdown": "First of all, I’d like to express my gratitude to kaggle and the competition hosts for holding such an amazing competition.\nI’d like to thank MMSegmentation developers too. MMSegmentation is really nice and useful tool. Also great thanks to @ayuraj who incorporated a hook of Weight & Biases into MMSegmentation, which helped a lot to manage training history.\n \nIn the contest, I learned a lot from @hengck23. Thank you so much for sharing knowledge with us:)\n \n\n### **Overview**\nI used the following methods.\n・ End-to-end MMSegmentation(with customization)\n・ Ensemble of SegFormers\n・ Used group normalization and trained with batch_size=1 in Colab\n・ Hand-labeling of lung from scratch\n・ External dataset and pseudo labeling.\n \n\n### **DataSet**\nUsed dataset:\n・ HPA images [351 images]\n・ HPA images stained with H&E or PAS [351 images x 4 stain patterns]\n・ external spleen [39 images + 39 images x 4 stain patterns]    *from a single image\n・ external lung [73 images]    *from a single image\n \n**(Lung)**When I noticed that unstable results were from lung prediction, I imagined  hand labeling is better than predicting lung by low threshold, which might lead to unstable and unconfident results. So  I researched how lung alveolus/alveoli look alike and hand-labeled lung images from scratch. Since there is no information on how to annotate alveolus/alveoli anywhere, I made about 7 annotation sets where potential alveolus was gradually annotated and probed which one is the best. Then I created an external dataset with pseudo labels and with the best threshold. After training with it, the best threshold for lung increased to 0.60, which gave the best result ever. I guess good modeling is better than hand labeling since there are those who got 0.11/0.22 in public/private. \n**(Spleen)**Used pseudo label for an external dataset\n**(Prostate/ Largeintestine)**Used pseudo label for the HPA dataset.\nI had a feeling that my models underfit HPA dataset because these dataset didn’t put weight on HPA datasets in terms of colors. The torchstain was used for the stain tool.\n \n\n### **Models**\nEnsemble of the following models:\n・ 1x SegFormer mit-b3, image_size: 1024x1024\n・ 2x SegFormer mit-b4, image_size: 960x960\n・ 1x SegFormer mit-b5, image_size: 928x928\n・ 2x SegFormer mit-b5, image_size: 960x960\nDifferent pretrained models, seed and additional stain dataset were used in some models. The reason all models are SegFormer is I chose models only from MMSegmentation and it worked well.\n*Best single model was mit-b4(private: 0.82821).\n\n\n### **Traning**\nI used google colaboratory. Since GPU resources are limited, I trained segformer with batch_size=1 with group normalization.  In my experiment, it was better than batch_size=4 with batch normalization in both CV and LB. I chose 2 class rather than 6 class segmentation because it showed better results consistently, especially in lung. In 6 classes, the area of the lung tends to shrink and even if the area was equivalent to 2 classes, LB lung score was worse.\n\nsettings:\n・ norm: group normalization(num_groups=32) for decoder\n・ num_classes:2\n・ loss_decode: CE:LovaszLoss=1:3\n・ steps: 45000\n・ optimization: AdamW with lr=0.00006 \n\naugmentations:\n・ Dataset image size: 2000x2000\n・ Downscale for prostate\n・ Crop/ Flip/ RandomRotate90/ HueSaturationValue/ RandomGamma/ RandomBrightness\n・ (mmseg)Resize to (480~1600, 480~1600)  * such as (480, 1600), (1024,1024), (1500,480)\n・ (mmseg)RandomCrop(crop_size=model input size)\n\n\n### **Inference**\n・ Whole image and ignored pixel_size\n・ TTA: horizontal flip and different scales (approximately x0.8, x1.0, x1.2) .\n・ Thresholds for each organ were  kidney: 0.3 | large intestine: 0.2 | lung: 0.6 | prostate: 0.3 | spleen: 0.5\n \n\n### **Results**\nall\t\tprivate: 0.83562\tpublic: 0.82716 \nkidney\t\tprivate: 0.16940\t\tpublic: 0.12175\nlarge intestine\tprivate: 0.09005\t\tpublic: 0.05730\nlung\t\tprivate: 0.21586\t\tpublic: 0.10963\nprostate\tprivate: 0.17784\t\tpublic: 0.14772\nspleen\t\tprivate: 0.18246\t\tpublic: 0.17515\n \n \n### **About license**\nPretrained SegFormer and its encoder “mit” are unavailable for commercial use.  It seems that other winners also use this model. However, I got an answer from the host, which permits the use of SegFormer in this competiion. The reasons are:\n1. Since competition hosts are non-profit, the commercial restriction isn’t applied.\n2. The model was Apache 2.0 license at the competition launch and  the license was changed during the competition.\n",
      "votes": 48
    },
    {
      "id": 1965406,
      "postDate": "2022-10-01T10:27:02.797Z",
      "content": "<p>hi can you share your mmsegmentation config file only ?  i want to know how to modify input image size. i use swin,convnext,twins,segformer in mmsegmentation but i finally get 0.72 in private. i find that when i use  input image size large than defult setting(like 640, 768), the performance will bad </p>",
      "rawMarkdown": "hi can you share your mmsegmentation config file only ?  i want to know how to modify input image size. i use swin,convnext,twins,segformer in mmsegmentation but i finally get 0.72 in private. i find that when i use  input image size large than defult setting(like 640, 768), the performance will bad ",
      "votes": 1,
      "replies": [
        {
          "id": 1965504,
          "postDate": "2022-10-01T12:03:44.753Z",
          "content": "<p>Did you downscale prostate images?  The image size for prostate is said to be 160x160.</p>\n<p>I used train_pipeline like below.</p>\n<hr>\n<p>crop_size = (960, 960)<br>\ntrain_pipeline = [<br>\n    dict(type='LoadImageFromFile'),<br>\n    dict(type='LoadAnnotations'),<br>\n    dict(type='CustomAug'), # Customized for each organs<br>\n    dict(type='Resize', img_scale=[(480,480),(1600, 1600)], keep_ratio=False, ratio_range=None),<br>\n    dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.5), <br>\n    dict(type='RandomFlip', direction='horizontal', prob=0),<br>\n    dict(type='SaveOverlay', save_root_dir='/content', save_num=500, no_overlay=True), # Customized for visualization<br>\n    dict(type='Convert2Class1'), # Customized for converting 6 class masks to 2 class one.<br>\n    dict(type='Normalize', **img_norm_cfg),<br>\n    dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),<br>\n    dict(type='DefaultFormatBundle'),<br>\n    dict(type='Collect', keys=['img', 'gt_semantic_seg']),<br>\n]</p>\n<p>Prostate were processed with Albumentations in CustomAug:<br>\n    A.Downscale(scale_min=0.08, scale_max=0.4, interpolation=cv2.INTER_LINEAR, p=0.9)<br>\nI used 2000x2000 images. So, downscale to from 160x160 to 800x800 and upscale to 2000x2000 in this case.</p>",
          "rawMarkdown": "Did you downscale prostate images?  The image size for prostate is said to be 160x160.\n\nI used train_pipeline like below.\n\n----------\ncrop_size = (960, 960)\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations'),\n    dict(type='CustomAug'), # Customized for each organs\n    dict(type='Resize', img_scale=[(480,480),(1600, 1600)], keep_ratio=False, ratio_range=None),\n    dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.5), \n    dict(type='RandomFlip', direction='horizontal', prob=0),\n    dict(type='SaveOverlay', save_root_dir='/content', save_num=500, no_overlay=True), # Customized for visualization\n    dict(type='Convert2Class1'), # Customized for converting 6 class masks to 2 class one.\n    dict(type='Normalize', **img_norm_cfg),\n    dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),\n    dict(type='DefaultFormatBundle'),\n    dict(type='Collect', keys=['img', 'gt_semantic_seg']),\n]\n\nProstate were processed with Albumentations in CustomAug:\n    A.Downscale(scale_min=0.08, scale_max=0.4, interpolation=cv2.INTER_LINEAR, p=0.9)\nI used 2000x2000 images. So, downscale to from 160x160 to 800x800 and upscale to 2000x2000 in this case."
        }
      ]
    },
    {
      "id": 1980298,
      "postDate": "2022-10-10T04:30:19.753Z",
      "content": "<p>Hi, <a href=\"https://www.kaggle.com/opusen\" target=\"_blank\">@opusen</a>. My evaluation mDice is low for 2-class. Loss and Acc is normal. For multi-class it work well.  What is your evaluation metric?<br>\nI don't know whether my custom Convert2Class is correct? Is there anything else to be aware of?<br>\n<a href=\"https://www.kaggle.com/PIPELINES.register\" target=\"_blank\">@PIPELINES.register</a>_module()<br>\nclass MaskTo2Class:</p>\n<pre><code>def __call__(self, results):\n    for key in results.get('seg_fields', []):\n        gt_seg = (results[key]!=0).astype(np.uint8)\n        results[key] = gt_seg\n    return results\n</code></pre>\n<p>Is there anything else to be aware of?</p>",
      "rawMarkdown": "Hi, @opusen. My evaluation mDice is low for 2-class. Loss and Acc is normal. For multi-class it work well.  What is your evaluation metric?\nI don't know whether my custom Convert2Class is correct? Is there anything else to be aware of?\n@PIPELINES.register_module()\nclass MaskTo2Class:\n\n    def __call__(self, results):\n        for key in results.get('seg_fields', []):\n            gt_seg = (results[key]!=0).astype(np.uint8)\n            results[key] = gt_seg\n        return results\nIs there anything else to be aware of?",
      "replies": [
        {
          "id": 1980349,
          "postDate": "2022-10-10T05:23:37.310Z",
          "content": "<p>Hi, how degree is it low? Although I used mDice, I haven't compared the metrics of 2 class with multi class because I customized mDice calculation for 2 class, from \"calculation from total area\" to \"average of each image\".<br>\nI recommend you to submit the model.</p>\n<p>By the way, did you take \"class 255\" into account?<br>\nClass 255 means 'ignore' and  would be converted to \"class 1\" in your code depending on pipeline position.<br>\nFor example, RandomRotate and Pad would create class 255.<br>\nHere is an example. </p>\n<pre><code>@PIPELINES.register_module()\nclass MaskTo2Class:\n    def __call__(self, data):\n        mask = data['gt_semantic_seg']\n\n        mask_ignore = (mask == 255)\n        mask = np.where((mask &gt;= 1) &amp; (mask &lt; 255), 1, 0)\n        mask[mask_ignore] = 255\n\n        data['gt_semantic_seg'] = mask\n\n        return data\n</code></pre>\n<p>Anyway, creating custom pipeline for visualization would be helpful for future works:)</p>",
          "rawMarkdown": "Hi, how degree is it low? Although I used mDice, I haven't compared the metrics of 2 class with multi class because I customized mDice calculation for 2 class, from \"calculation from total area\" to \"average of each image\".\nI recommend you to submit the model.\n\nBy the way, did you take \"class 255\" into account?\nClass 255 means 'ignore' and  would be converted to \"class 1\" in your code depending on pipeline position.\nFor example, RandomRotate and Pad would create class 255.\nHere is an example. \n\n```\n@PIPELINES.register_module()\nclass MaskTo2Class:\n    def __call__(self, data):\n        mask = data['gt_semantic_seg']\n\n        mask_ignore = (mask == 255)\n        mask = np.where((mask >= 1) & (mask < 255), 1, 0)\n        mask[mask_ignore] = 255\n\n        data['gt_semantic_seg'] = mask\n\n        return data\n```\n\nAnyway, creating custom pipeline for visualization would be helpful for future works:)",
          "votes": 1
        },
        {
          "id": 1981034,
          "postDate": "2022-10-10T14:34:48.407Z",
          "content": "<p>Yes. I didn't take 255 class into account. The evaluation mDice with MMSeg is about 16. Loss is normal. I don't know how to custom mDice in MMSeg?  Could you share your method?</p>",
          "rawMarkdown": "Yes. I didn't take 255 class into account. The evaluation mDice with MMSeg is about 16. Loss is normal. I don't know how to custom mDice in MMSeg?  Could you share your method?"
        },
        {
          "id": 1982404,
          "postDate": "2022-10-11T12:06:27.637Z",
          "content": "<blockquote>\n  <p>Loss and Acc is normal.<br>\n  The evaluation mDice with MMSeg is about 16</p>\n</blockquote>\n<p>is mDice 0.16? Do you mean Acc is decode.acc_seg?</p>\n<blockquote>\n  <p>Yes. I didn't take 255 class into account.</p>\n</blockquote>\n<p>I feel like test accuracy is also low. Did you check it?</p>\n<blockquote>\n  <p>Could you share your method?</p>\n</blockquote>\n<p>Actually I don't recommend to use it.<br>\nI couldn't modify the code to work also in multi-class and the code was written in messy way. <br>\nAlso, CV wasn't useful in this competition:)</p>",
          "rawMarkdown": "> Loss and Acc is normal.\nThe evaluation mDice with MMSeg is about 16\n\nis mDice 0.16? Do you mean Acc is decode.acc_seg?\n\n> Yes. I didn't take 255 class into account.\n\nI feel like test accuracy is also low. Did you check it?\n\n> Could you share your method?\n\nActually I don't recommend to use it.\nI couldn't modify the code to work also in multi-class and the code was written in messy way. \nAlso, CV wasn't useful in this competition:)",
          "votes": 1
        }
      ]
    },
    {
      "id": 1978706,
      "postDate": "2022-10-08T23:54:28.693Z",
      "content": "<p>Congratulations for your first place! I wasn't familiar with the technique of group normalization. Could you share how did you use it, specially in the context of mmsegmentation?</p>",
      "rawMarkdown": "Congratulations for your first place! I wasn't familiar with the technique of group normalization. Could you share how did you use it, specially in the context of mmsegmentation?",
      "replies": [
        {
          "id": 1979778,
          "postDate": "2022-10-09T17:25:21.153Z",
          "content": "<p>Thanks:)</p>\n<p><strong>norm_cfg = dict(type='GN', num_groups=32, requires_grad=True)</strong><br>\nmodel = dict(<br>\n    type='EncoderDecoder',<br>\n    backbone=dict(<br>\n        type='MixVisionTransformer',<br>\n        …<br>\n    decode_head=dict(<br>\n        type='SegformerHead',<br>\n        …</p>\n<p>SegFormer is composed of 'MixVisionTransformer' and 'SegformerHead'.</p>\n<p>For MixVisionTransformer, Layer Normalization was used as default.<br>\n<a href=\"https://github.com/open-mmlab/mmsegmentation/blob/master/mmseg/models/backbones/mit.py#L329-L330\" target=\"_blank\">https://github.com/open-mmlab/mmsegmentation/blob/master/mmseg/models/backbones/mit.py#L329-L330</a></p>\n<p>For SegformerHead, default settings is SyncBN.<br>\n<a href=\"https://github.com/open-mmlab/mmsegmentation/blob/master/configs/_base_/models/segformer_mit-b0.py#L2\" target=\"_blank\">https://github.com/open-mmlab/mmsegmentation/blob/master/configs/_base_/models/segformer_mit-b0.py#L2</a><br>\nSo you can change SyncBN to 'GN'.</p>\n<p>Supported normalizations would be<br>\n<a href=\"https://github.com/open-mmlab/mmcv/blob/master/mmcv/cnn/bricks/norm.py#L11-L21\" target=\"_blank\">https://github.com/open-mmlab/mmcv/blob/master/mmcv/cnn/bricks/norm.py#L11-L21</a></p>",
          "rawMarkdown": "Thanks:)\n\n**norm_cfg = dict(type='GN', num_groups=32, requires_grad=True)**\nmodel = dict(\n    type='EncoderDecoder',\n    backbone=dict(\n        type='MixVisionTransformer',\n        ...\n    decode_head=dict(\n        type='SegformerHead',\n        ...\n\nSegFormer is composed of 'MixVisionTransformer' and 'SegformerHead'.\n\nFor MixVisionTransformer, Layer Normalization was used as default.\nhttps://github.com/open-mmlab/mmsegmentation/blob/master/mmseg/models/backbones/mit.py#L329-L330\n\nFor SegformerHead, default settings is SyncBN.\nhttps://github.com/open-mmlab/mmsegmentation/blob/master/configs/_base_/models/segformer_mit-b0.py#L2\nSo you can change SyncBN to 'GN'.\n\nSupported normalizations would be\nhttps://github.com/open-mmlab/mmcv/blob/master/mmcv/cnn/bricks/norm.py#L11-L21\n",
          "votes": 2
        }
      ]
    },
    {
      "id": 1977924,
      "postDate": "2022-10-08T10:42:31.893Z",
      "content": "<p>hi, can you share your competition-dataset-only scores?</p>",
      "rawMarkdown": "hi, can you share your competition-dataset-only scores?",
      "replies": [
        {
          "id": 1979751,
          "postDate": "2022-10-09T17:06:55.637Z",
          "content": "<p>The boost of external spleen was 0.00594 and lung was 0.00622.<br>\nIn simple calculation, 0.83562(final score) - (0.00594+0.00622)=0.82346</p>\n<p>It was a good opportunity to check my submission history :)</p>",
          "rawMarkdown": "The boost of external spleen was 0.00594 and lung was 0.00622.\nIn simple calculation, 0.83562(final score) - (0.00594+0.00622)=0.82346\n\nIt was a good opportunity to check my submission history :)"
        },
        {
          "id": 1981816,
          "postDate": "2022-10-11T04:10:25.343Z",
          "content": "<p>thanks for your reply.  : )</p>",
          "rawMarkdown": "thanks for your reply.  : )"
        }
      ]
    },
    {
      "id": 1965705,
      "postDate": "2022-10-01T13:36:32.817Z",
      "content": "<p>Great methods, thanks for your sharing. I have two questions. For MMSegmentation the activation function is to use argmax. How to set thresholds for each organ? Can you share your test config? </p>",
      "rawMarkdown": "Great methods, thanks for your sharing. I have two questions. For MMSegmentation the activation function is to use argmax. How to set thresholds for each organ? Can you share your test config? ",
      "replies": [
        {
          "id": 1965861,
          "postDate": "2022-10-01T15:20:02.887Z",
          "content": "<blockquote>\n  <p>How to set thresholds for each organ?</p>\n</blockquote>\n<p>You need to customize encorder_decoder.py<br>\nI created a notebook.<br>\n<a href=\"https://www.kaggle.com/code/opusen/customize-mmseg\" target=\"_blank\">https://www.kaggle.com/code/opusen/customize-mmseg</a></p>\n<p>Then you can use sigmoid raw outputs of each class for thresholds or ensemble.<br>\nI ensembled 'cell class' sigmoid of several models.</p>\n<blockquote>\n  <p>Can you share your test config?</p>\n</blockquote>\n<p>Not much different from the others.</p>\n<p>dataset_type = 'xxx'<br>\ndata_root = 'xxx'<br>\nimg_norm_cfg = dict(<br>\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)<br>\ncrop_size = (960, 960)<br>\ntrain_pipeline = []<br>\nval_pipeline = []<br>\ntest_pipeline = [<br>\n    dict(type='LoadImageFromFile'),<br>\n    dict(<br>\n        type='MultiScaleFlipAug',<br>\n        img_scale=crop_size,<br>\n        img_ratios=[0.8, 1.0, 1.2], #[0.8125, 1.0, 1.1875] for 1024x1024.<br>\n        flip=True,<br>\n        transforms=[<br>\n            dict(type='Resize', keep_ratio=True),<br>\n            dict(type='RandomFlip'),<br>\n            dict(type='Normalize', **img_norm_cfg),<br>\n            dict(type='ImageToTensor', keys=['img']),<br>\n            dict(type='Collect', keys=['img']),<br>\n        ])<br>\n]</p>",
          "rawMarkdown": "> How to set thresholds for each organ?\n\nYou need to customize encorder_decoder.py\nI created a notebook.\nhttps://www.kaggle.com/code/opusen/customize-mmseg\n\nThen you can use sigmoid raw outputs of each class for thresholds or ensemble.\nI ensembled 'cell class' sigmoid of several models.\n\n> Can you share your test config?\n\nNot much different from the others.\n\ndataset_type = 'xxx'\ndata_root = 'xxx'\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ncrop_size = (960, 960)\ntrain_pipeline = []\nval_pipeline = []\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=crop_size,\n        img_ratios=[0.8, 1.0, 1.2], #[0.8125, 1.0, 1.1875] for 1024x1024.\n        flip=True,\n        transforms=[\n            dict(type='Resize', keep_ratio=True),\n            dict(type='RandomFlip'),\n            dict(type='Normalize', **img_norm_cfg),\n            dict(type='ImageToTensor', keys=['img']),\n            dict(type='Collect', keys=['img']),\n        ])\n]",
          "votes": 2
        },
        {
          "id": 1968871,
          "postDate": "2022-10-03T08:43:39.527Z",
          "content": "<p>Thanks for your response.</p>",
          "rawMarkdown": "Thanks for your response."
        }
      ]
    },
    {
      "id": 2095663,
      "postDate": "2023-01-11T14:50:22.463Z",
      "rawMarkdown": "",
      "isDeleted": true
    }
  ],
  "comments": [
    {
      "id": 1965406,
      "author_name": "ananzeng",
      "author_url": "",
      "post_date": "2022-10-01T10:27:02.797000",
      "content": "<p>hi can you share your mmsegmentation config file only ?  i want to know how to modify input image size. i use swin,convnext,twins,segformer in mmsegmentation but i finally get 0.72 in private. i find that when i use  input image size large than defult setting(like 640, 768), the performance will bad </p>",
      "votes": 1,
      "replies": [
        {
          "id": 1965504,
          "author_name": "opusen",
          "author_url": "",
          "post_date": "2022-10-01T12:03:44.753000",
          "content": "<p>Did you downscale prostate images?  The image size for prostate is said to be 160x160.</p>\n<p>I used train_pipeline like below.</p>\n<hr>\n<p>crop_size = (960, 960)<br>\ntrain_pipeline = [<br>\n    dict(type='LoadImageFromFile'),<br>\n    dict(type='LoadAnnotations'),<br>\n    dict(type='CustomAug'), # Customized for each organs<br>\n    dict(type='Resize', img_scale=[(480,480),(1600, 1600)], keep_ratio=False, ratio_range=None),<br>\n    dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.5), <br>\n    dict(type='RandomFlip', direction='horizontal', prob=0),<br>\n    dict(type='SaveOverlay', save_root_dir='/content', save_num=500, no_overlay=True), # Customized for visualization<br>\n    dict(type='Convert2Class1'), # Customized for converting 6 class masks to 2 class one.<br>\n    dict(type='Normalize', **img_norm_cfg),<br>\n    dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),<br>\n    dict(type='DefaultFormatBundle'),<br>\n    dict(type='Collect', keys=['img', 'gt_semantic_seg']),<br>\n]</p>\n<p>Prostate were processed with Albumentations in CustomAug:<br>\n    A.Downscale(scale_min=0.08, scale_max=0.4, interpolation=cv2.INTER_LINEAR, p=0.9)<br>\nI used 2000x2000 images. So, downscale to from 160x160 to 800x800 and upscale to 2000x2000 in this case.</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1980298,
      "author_name": "ynhuhu",
      "author_url": "",
      "post_date": "2022-10-10T04:30:19.753000",
      "content": "<p>Hi, <a href=\"https://www.kaggle.com/opusen\" target=\"_blank\">@opusen</a>. My evaluation mDice is low for 2-class. Loss and Acc is normal. For multi-class it work well.  What is your evaluation metric?<br>\nI don't know whether my custom Convert2Class is correct? Is there anything else to be aware of?<br>\n<a href=\"https://www.kaggle.com/PIPELINES.register\" target=\"_blank\">@PIPELINES.register</a>_module()<br>\nclass MaskTo2Class:</p>\n<pre><code>def __call__(self, results):\n    for key in results.get('seg_fields', []):\n        gt_seg = (results[key]!=0).astype(np.uint8)\n        results[key] = gt_seg\n    return results\n</code></pre>\n<p>Is there anything else to be aware of?</p>",
      "votes": 0,
      "replies": [
        {
          "id": 1980349,
          "author_name": "opusen",
          "author_url": "",
          "post_date": "2022-10-10T05:23:37.310000",
          "content": "<p>Hi, how degree is it low? Although I used mDice, I haven't compared the metrics of 2 class with multi class because I customized mDice calculation for 2 class, from \"calculation from total area\" to \"average of each image\".<br>\nI recommend you to submit the model.</p>\n<p>By the way, did you take \"class 255\" into account?<br>\nClass 255 means 'ignore' and  would be converted to \"class 1\" in your code depending on pipeline position.<br>\nFor example, RandomRotate and Pad would create class 255.<br>\nHere is an example. </p>\n<pre><code>@PIPELINES.register_module()\nclass MaskTo2Class:\n    def __call__(self, data):\n        mask = data['gt_semantic_seg']\n\n        mask_ignore = (mask == 255)\n        mask = np.where((mask &gt;= 1) &amp; (mask &lt; 255), 1, 0)\n        mask[mask_ignore] = 255\n\n        data['gt_semantic_seg'] = mask\n\n        return data\n</code></pre>\n<p>Anyway, creating custom pipeline for visualization would be helpful for future works:)</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 1981034,
          "author_name": "ynhuhu",
          "author_url": "",
          "post_date": "2022-10-10T14:34:48.407000",
          "content": "<p>Yes. I didn't take 255 class into account. The evaluation mDice with MMSeg is about 16. Loss is normal. I don't know how to custom mDice in MMSeg?  Could you share your method?</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 1982404,
          "author_name": "opusen",
          "author_url": "",
          "post_date": "2022-10-11T12:06:27.637000",
          "content": "<blockquote>\n  <p>Loss and Acc is normal.<br>\n  The evaluation mDice with MMSeg is about 16</p>\n</blockquote>\n<p>is mDice 0.16? Do you mean Acc is decode.acc_seg?</p>\n<blockquote>\n  <p>Yes. I didn't take 255 class into account.</p>\n</blockquote>\n<p>I feel like test accuracy is also low. Did you check it?</p>\n<blockquote>\n  <p>Could you share your method?</p>\n</blockquote>\n<p>Actually I don't recommend to use it.<br>\nI couldn't modify the code to work also in multi-class and the code was written in messy way. <br>\nAlso, CV wasn't useful in this competition:)</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 1978706,
      "author_name": "CarlosRunner",
      "author_url": "",
      "post_date": "2022-10-08T23:54:28.693000",
      "content": "<p>Congratulations for your first place! I wasn't familiar with the technique of group normalization. Could you share how did you use it, specially in the context of mmsegmentation?</p>",
      "votes": 0,
      "replies": [
        {
          "id": 1979778,
          "author_name": "opusen",
          "author_url": "",
          "post_date": "2022-10-09T17:25:21.153000",
          "content": "<p>Thanks:)</p>\n<p><strong>norm_cfg = dict(type='GN', num_groups=32, requires_grad=True)</strong><br>\nmodel = dict(<br>\n    type='EncoderDecoder',<br>\n    backbone=dict(<br>\n        type='MixVisionTransformer',<br>\n        …<br>\n    decode_head=dict(<br>\n        type='SegformerHead',<br>\n        …</p>\n<p>SegFormer is composed of 'MixVisionTransformer' and 'SegformerHead'.</p>\n<p>For MixVisionTransformer, Layer Normalization was used as default.<br>\n<a href=\"https://github.com/open-mmlab/mmsegmentation/blob/master/mmseg/models/backbones/mit.py#L329-L330\" target=\"_blank\">https://github.com/open-mmlab/mmsegmentation/blob/master/mmseg/models/backbones/mit.py#L329-L330</a></p>\n<p>For SegformerHead, default settings is SyncBN.<br>\n<a href=\"https://github.com/open-mmlab/mmsegmentation/blob/master/configs/_base_/models/segformer_mit-b0.py#L2\" target=\"_blank\">https://github.com/open-mmlab/mmsegmentation/blob/master/configs/_base_/models/segformer_mit-b0.py#L2</a><br>\nSo you can change SyncBN to 'GN'.</p>\n<p>Supported normalizations would be<br>\n<a href=\"https://github.com/open-mmlab/mmcv/blob/master/mmcv/cnn/bricks/norm.py#L11-L21\" target=\"_blank\">https://github.com/open-mmlab/mmcv/blob/master/mmcv/cnn/bricks/norm.py#L11-L21</a></p>",
          "votes": 2,
          "replies": []
        }
      ]
    },
    {
      "id": 1977924,
      "author_name": "Forte Lean",
      "author_url": "",
      "post_date": "2022-10-08T10:42:31.893000",
      "content": "<p>hi, can you share your competition-dataset-only scores?</p>",
      "votes": 0,
      "replies": [
        {
          "id": 1979751,
          "author_name": "opusen",
          "author_url": "",
          "post_date": "2022-10-09T17:06:55.637000",
          "content": "<p>The boost of external spleen was 0.00594 and lung was 0.00622.<br>\nIn simple calculation, 0.83562(final score) - (0.00594+0.00622)=0.82346</p>\n<p>It was a good opportunity to check my submission history :)</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 1981816,
          "author_name": "Forte Lean",
          "author_url": "",
          "post_date": "2022-10-11T04:10:25.343000",
          "content": "<p>thanks for your reply.  : )</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1965705,
      "author_name": "ynhuhu",
      "author_url": "",
      "post_date": "2022-10-01T13:36:32.817000",
      "content": "<p>Great methods, thanks for your sharing. I have two questions. For MMSegmentation the activation function is to use argmax. How to set thresholds for each organ? Can you share your test config? </p>",
      "votes": 0,
      "replies": [
        {
          "id": 1965861,
          "author_name": "opusen",
          "author_url": "",
          "post_date": "2022-10-01T15:20:02.887000",
          "content": "<blockquote>\n  <p>How to set thresholds for each organ?</p>\n</blockquote>\n<p>You need to customize encorder_decoder.py<br>\nI created a notebook.<br>\n<a href=\"https://www.kaggle.com/code/opusen/customize-mmseg\" target=\"_blank\">https://www.kaggle.com/code/opusen/customize-mmseg</a></p>\n<p>Then you can use sigmoid raw outputs of each class for thresholds or ensemble.<br>\nI ensembled 'cell class' sigmoid of several models.</p>\n<blockquote>\n  <p>Can you share your test config?</p>\n</blockquote>\n<p>Not much different from the others.</p>\n<p>dataset_type = 'xxx'<br>\ndata_root = 'xxx'<br>\nimg_norm_cfg = dict(<br>\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)<br>\ncrop_size = (960, 960)<br>\ntrain_pipeline = []<br>\nval_pipeline = []<br>\ntest_pipeline = [<br>\n    dict(type='LoadImageFromFile'),<br>\n    dict(<br>\n        type='MultiScaleFlipAug',<br>\n        img_scale=crop_size,<br>\n        img_ratios=[0.8, 1.0, 1.2], #[0.8125, 1.0, 1.1875] for 1024x1024.<br>\n        flip=True,<br>\n        transforms=[<br>\n            dict(type='Resize', keep_ratio=True),<br>\n            dict(type='RandomFlip'),<br>\n            dict(type='Normalize', **img_norm_cfg),<br>\n            dict(type='ImageToTensor', keys=['img']),<br>\n            dict(type='Collect', keys=['img']),<br>\n        ])<br>\n]</p>",
          "votes": 2,
          "replies": []
        },
        {
          "id": 1968871,
          "author_name": "ynhuhu",
          "author_url": "",
          "post_date": "2022-10-03T08:43:39.527000",
          "content": "<p>Thanks for your response.</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 2095663,
      "author_name": "",
      "author_url": "",
      "post_date": "2023-01-11T14:50:22.463000",
      "content": "",
      "votes": 0,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "1962297": "First of all, I’d like to express my gratitude to kaggle and the competition hosts for holding such an amazing competition.\nI’d like to thank MMSegmentation developers too. MMSegmentation is really nice and useful tool. Also great thanks to @ayuraj who incorporated a hook of Weight & Biases into MMSegmentation, which helped a lot to manage training history.\n \nIn the contest, I learned a lot from @hengck23. Thank you so much for sharing knowledge with us:)\n \n\n### **Overview**\nI used the following methods.\n・ End-to-end MMSegmentation(with customization)\n・ Ensemble of SegFormers\n・ Used group normalization and trained with batch_size=1 in Colab\n・ Hand-labeling of lung from scratch\n・ External dataset and pseudo labeling.\n \n\n### **DataSet**\nUsed dataset:\n・ HPA images [351 images]\n・ HPA images stained with H&E or PAS [351 images x 4 stain patterns]\n・ external spleen [39 images + 39 images x 4 stain patterns]    *from a single image\n・ external lung [73 images]    *from a single image\n \n**(Lung)**When I noticed that unstable results were from lung prediction, I imagined  hand labeling is better than predicting lung by low threshold, which might lead to unstable and unconfident results. So  I researched how lung alveolus/alveoli look alike and hand-labeled lung images from scratch. Since there is no information on how to annotate alveolus/alveoli anywhere, I made about 7 annotation sets where potential alveolus was gradually annotated and probed which one is the best. Then I created an external dataset with pseudo labels and with the best threshold. After training with it, the best threshold for lung increased to 0.60, which gave the best result ever. I guess good modeling is better than hand labeling since there are those who got 0.11/0.22 in public/private. \n**(Spleen)**Used pseudo label for an external dataset\n**(Prostate/ Largeintestine)**Used pseudo label for the HPA dataset.\nI had a feeling that my models underfit HPA dataset because these dataset didn’t put weight on HPA datasets in terms of colors. The torchstain was used for the stain tool.\n \n\n### **Models**\nEnsemble of the following models:\n・ 1x SegFormer mit-b3, image_size: 1024x1024\n・ 2x SegFormer mit-b4, image_size: 960x960\n・ 1x SegFormer mit-b5, image_size: 928x928\n・ 2x SegFormer mit-b5, image_size: 960x960\nDifferent pretrained models, seed and additional stain dataset were used in some models. The reason all models are SegFormer is I chose models only from MMSegmentation and it worked well.\n*Best single model was mit-b4(private: 0.82821).\n\n\n### **Traning**\nI used google colaboratory. Since GPU resources are limited, I trained segformer with batch_size=1 with group normalization.  In my experiment, it was better than batch_size=4 with batch normalization in both CV and LB. I chose 2 class rather than 6 class segmentation because it showed better results consistently, especially in lung. In 6 classes, the area of the lung tends to shrink and even if the area was equivalent to 2 classes, LB lung score was worse.\n\nsettings:\n・ norm: group normalization(num_groups=32) for decoder\n・ num_classes:2\n・ loss_decode: CE:LovaszLoss=1:3\n・ steps: 45000\n・ optimization: AdamW with lr=0.00006 \n\naugmentations:\n・ Dataset image size: 2000x2000\n・ Downscale for prostate\n・ Crop/ Flip/ RandomRotate90/ HueSaturationValue/ RandomGamma/ RandomBrightness\n・ (mmseg)Resize to (480~1600, 480~1600)  * such as (480, 1600), (1024,1024), (1500,480)\n・ (mmseg)RandomCrop(crop_size=model input size)\n\n\n### **Inference**\n・ Whole image and ignored pixel_size\n・ TTA: horizontal flip and different scales (approximately x0.8, x1.0, x1.2) .\n・ Thresholds for each organ were  kidney: 0.3 | large intestine: 0.2 | lung: 0.6 | prostate: 0.3 | spleen: 0.5\n \n\n### **Results**\nall\t\tprivate: 0.83562\tpublic: 0.82716 \nkidney\t\tprivate: 0.16940\t\tpublic: 0.12175\nlarge intestine\tprivate: 0.09005\t\tpublic: 0.05730\nlung\t\tprivate: 0.21586\t\tpublic: 0.10963\nprostate\tprivate: 0.17784\t\tpublic: 0.14772\nspleen\t\tprivate: 0.18246\t\tpublic: 0.17515\n \n \n### **About license**\nPretrained SegFormer and its encoder “mit” are unavailable for commercial use.  It seems that other winners also use this model. However, I got an answer from the host, which permits the use of SegFormer in this competiion. The reasons are:\n1. Since competition hosts are non-profit, the commercial restriction isn’t applied.\n2. The model was Apache 2.0 license at the competition launch and  the license was changed during the competition.\n",
    "1965406": "hi can you share your mmsegmentation config file only ?  i want to know how to modify input image size. i use swin,convnext,twins,segformer in mmsegmentation but i finally get 0.72 in private. i find that when i use  input image size large than defult setting(like 640, 768), the performance will bad ",
    "1980298": "Hi, @opusen. My evaluation mDice is low for 2-class. Loss and Acc is normal. For multi-class it work well.  What is your evaluation metric?\nI don't know whether my custom Convert2Class is correct? Is there anything else to be aware of?\n@PIPELINES.register_module()\nclass MaskTo2Class:\n\n    def __call__(self, results):\n        for key in results.get('seg_fields', []):\n            gt_seg = (results[key]!=0).astype(np.uint8)\n            results[key] = gt_seg\n        return results\nIs there anything else to be aware of?",
    "1978706": "Congratulations for your first place! I wasn't familiar with the technique of group normalization. Could you share how did you use it, specially in the context of mmsegmentation?",
    "1977924": "hi, can you share your competition-dataset-only scores?",
    "1965705": "Great methods, thanks for your sharing. I have two questions. For MMSegmentation the activation function is to use argmax. How to set thresholds for each organ? Can you share your test config? ",
    "2095663": ""
  }
}