{
  "id": 54923,
  "title": "repeating topcoders unet results",
  "url": "/competitions/data-science-bowl-2018/discussion/54923",
  "author_name": "hengck23",
  "post_date": "2018-04-19T17:59:47.863000",
  "votes": 59,
  "comment_count": 19,
  "views": 0,
  "content": "<p>Unet seems to be an important approach for future kaggle challenge as well. Hence I have decided to repeat topcoder results, making modifications if required. My target is 0.580 on public LB on stage1 dataset first. (there is an evaluation code in my code base for scoring your csv file against the released stage1 test solution csv)</p>\n\n<p>My code base is at: <a href=\"https://drive.google.com/drive/folders/1EtBdlPK3BVahHBZtB103QQxNUdWaJ6di\">https://drive.google.com/drive/folders/1EtBdlPK3BVahHBZtB103QQxNUdWaJ6di</a> </p>\n\n<p>. It is based on pytorch.</p>\n\n<p>It is still in progress. you can follow this thread for update.</p>\n\n<p>The attached ppt shows current progress.</p>\n\n<hr>\n\n<p>latest : 20180427 folder</p>\n\n<ul>\n<li><p>unet (fpn se-resnext152 backbone)</p></li>\n<li><p>learning watershed line as border</p></li>\n</ul>",
  "messages": [
    {
      "id": 316709,
      "postDate": "2018-04-19T17:59:47.863Z",
      "content": "<p>Unet seems to be an important approach for future kaggle challenge as well. Hence I have decided to repeat topcoder results, making modifications if required. My target is 0.580 on public LB on stage1 dataset first. (there is an evaluation code in my code base for scoring your csv file against the released stage1 test solution csv)</p>\n\n<p>My code base is at: <a href=\"https://drive.google.com/drive/folders/1EtBdlPK3BVahHBZtB103QQxNUdWaJ6di\">https://drive.google.com/drive/folders/1EtBdlPK3BVahHBZtB103QQxNUdWaJ6di</a> </p>\n\n<p>. It is based on pytorch.</p>\n\n<p>It is still in progress. you can follow this thread for update.</p>\n\n<p>The attached ppt shows current progress.</p>\n\n<hr>\n\n<p>latest : 20180427 folder</p>\n\n<ul>\n<li><p>unet (fpn se-resnext152 backbone)</p></li>\n<li><p>learning watershed line as border</p></li>\n</ul>",
      "rawMarkdown": "Unet seems to be an important approach for future kaggle challenge as well. Hence I have decided to repeat topcoder results, making modifications if required. My target is 0.580 on public LB on stage1 dataset first. (there is an evaluation code in my code base for scoring your csv file against the released stage1 test solution csv)\n\nMy code base is at: https://drive.google.com/drive/folders/1EtBdlPK3BVahHBZtB103QQxNUdWaJ6di \n\n. It is based on pytorch.\n\nIt is still in progress. you can follow this thread for update.\n\nThe attached ppt shows current progress.\n\n------------------------------------------------------------------------------\n\nlatest : 20180427 folder\n  \n - unet (fpn se-resnext152 backbone)\n\n - learning watershed line as border",
      "votes": 59
    },
    {
      "id": 317009,
      "postDate": "2018-04-20T12:58:13Z",
      "content": "<p>Hi! What about to use github? I am also interested to participate</p>",
      "rawMarkdown": "Hi! What about to use github? I am also interested to participate",
      "votes": 7,
      "replies": [
        {
          "id": 317010,
          "postDate": "2018-04-20T12:59:49.040Z",
          "content": "<p>hi, currently google drive is most convenient for me. I suggest that you can take my code and put on github?</p>",
          "rawMarkdown": "hi, currently google drive is most convenient for me. I suggest that you can take my code and put on github?",
          "votes": 1
        }
      ]
    },
    {
      "id": 318873,
      "postDate": "2018-04-24T16:38:43.870Z",
      "content": "<p>updated results. please see \"20180425\". Below are results on training images. The next stage is to do evaluation on stage1 test set. The border pixels are minority class, class balancing are important and tricky. </p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/318873/9292/8efed2e62c919e6d70a2ab548b1a33014877fe8a23f177ef25a9dee25ffe8842.png\" alt=\"enter image description here\"></p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/318873/9294/2f929b067a59f88530b6bfa6f6889bc3a38adf88d594895973d1c8b2549fd93d.png\" alt=\"enter image description here\"></p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/318873/9296/a102535b0e88374bea4a1cfd9ee7cb3822ff54f4ab2a9845d428ec22f9ee2288.png\" alt=\"enter image description here\"></p>",
      "rawMarkdown": "updated results. please see \"20180425\". Below are results on training images. The next stage is to do evaluation on stage1 test set. The border pixels are minority class, class balancing are important and tricky. \n\n  ![enter image description here][1]\n\n  ![enter image description here][2]\n\n  ![enter image description here][3]\n\n\n  [1]: https://kaggle2.blob.core.windows.net/forum-message-attachments/318873/9292/8efed2e62c919e6d70a2ab548b1a33014877fe8a23f177ef25a9dee25ffe8842.png\n  [2]: https://kaggle2.blob.core.windows.net/forum-message-attachments/318873/9294/2f929b067a59f88530b6bfa6f6889bc3a38adf88d594895973d1c8b2549fd93d.png\n  [3]: https://kaggle2.blob.core.windows.net/forum-message-attachments/318873/9296/a102535b0e88374bea4a1cfd9ee7cb3822ff54f4ab2a9845d428ec22f9ee2288.png",
      "votes": 3,
      "replies": [
        {
          "id": 318897,
          "postDate": "2018-04-24T17:46:24.790Z",
          "content": "<p>This imbalance problem could be solved if  you make your  loss function like this  </p><pre>bce(all_channels) +  dice_loss(mask_channel) + dice_loss(border_channel) </pre><p></p>",
          "rawMarkdown": "This imbalance problem could be solved if  you make your  loss function like this  <pre>bce(all_channels) +  dice_loss(mask_channel) + dice_loss(border_channel) </pre>",
          "votes": 9
        },
        {
          "id": 319780,
          "postDate": "2018-04-26T20:21:18.697Z",
          "content": "<p>In <a href=\"https://arxiv.org/pdf/1802.07465.pdf\">https://arxiv.org/pdf/1802.07465.pdf</a>  we alse use “overlapping boundary” or “ touching borders” (Alg. 1). In my opinion it is much better than using the boundary. For the imbalance we use weight maps.  In this competition I use boundary. I did not have time to translate the matlab code from the weight maps for the second stage :(. </p>\n\n<p>I calculate of the touching borders as follows:</p>\n\n<pre><code>def get_touchs( edges ):       \n    A = np.array([ morph.binary_dilation( c, morph.square(3) )  for c in edges ]) \n    A = np.sum(A,axis=0)&gt;1  \n    I = morph.remove_small_objects( A, 3 )\n    I = morph.skeletonize(I)\n    I = morph.binary_dilation( I, morph.square(3) )    \n    return I\n</code></pre>",
          "rawMarkdown": "In https://arxiv.org/pdf/1802.07465.pdf  we alse use “overlapping boundary” or “ touching borders” (Alg. 1). In my opinion it is much better than using the boundary. For the imbalance we use weight maps.  In this competition I use boundary. I did not have time to translate the matlab code from the weight maps for the second stage :(. \n\nI calculate of the touching borders as follows:\n\n    def get_touchs( edges ):       \n        A = np.array([ morph.binary_dilation( c, morph.square(3) )  for c in edges ]) \n        A = np.sum(A,axis=0)&gt;1  \n        I = morph.remove_small_objects( A, 3 )\n        I = morph.skeletonize(I)\n        I = morph.binary_dilation( I, morph.square(3) )    \n        return I\n\n",
          "votes": 4
        },
        {
          "id": 320121,
          "postDate": "2018-04-27T14:52:22.363Z",
          "content": "<p>thanks for the post. I will try to use it</p>",
          "rawMarkdown": "thanks for the post. I will try to use it"
        }
      ]
    },
    {
      "id": 316773,
      "postDate": "2018-04-19T21:26:55.450Z",
      "content": "<p>Thanks very much for the code! I am quite new to computer vision and image segmentation. After this competition, I still have some questions in my head. When I first look at this problem, it seems U-Net is intrinsically only good at semantic segmentation(correct me if I am wrong :), and Mask R-CNN combines object detection and segmentation, so it seems to be good at instance segmentation. However, the result of this competition shows U-Net is better at this problem. What's the reason about this? I can guess of two reasons but don't know if they are correct, 1. U-Net will predict more precise boundaries, which contributes more to the metric. 2. There is actually no overlaps of nuclei instances in the given masks.</p>",
      "rawMarkdown": "Thanks very much for the code! I am quite new to computer vision and image segmentation. After this competition, I still have some questions in my head. When I first look at this problem, it seems U-Net is intrinsically only good at semantic segmentation(correct me if I am wrong :), and Mask R-CNN combines object detection and segmentation, so it seems to be good at instance segmentation. However, the result of this competition shows U-Net is better at this problem. What's the reason about this? I can guess of two reasons but don't know if they are correct, 1. U-Net will predict more precise boundaries, which contributes more to the metric. 2. There is actually no overlaps of nuclei instances in the given masks.",
      "votes": 3,
      "replies": [
        {
          "id": 316927,
          "postDate": "2018-04-20T07:41:29.840Z",
          "content": "<p>I think it's problem-specific.  </p>\n\n<p>Mask R-CNN  (and variants) make a lot of sense if you have a lot of classes and want to quickly find lots of small patches that you can then analyse individually with a (relatively heavyweight) classifier/segmenter.  Your region proposer tunes itself to discriminating between potential target areas and the background clutter; your classifier concentrates on being extremely good at assigning classes and boundaries to small objects (perhaps resized to a standard size).  This has several advantages in applications where there is <em>lots</em> of clutter and <em>lots</em> of object classes - you get to make a cursory scan of the scene, then focus your real classification muscle on the interesting parts.  It comes at the cost of additional complexity/parameters/depth/training effort: to some extent your region proposer and classifier have to learn the same textures.  But it's a great tradeoff for things like street view: you can tune how you deal with different regions (you could even attach different back-end recognisers to different region types), and it's all integrated into a single framework - all jointly learnable.  Beautiful in its way, and very effective.</p>\n\n<p>When segmenting nucleii with U-net, there's only two classes (nuclear and background tissue), plus an extra hack: you need some way to predict borders between nucleii, and devise some postprocessing step which can use those predictions to make high quality cuts between adjacent nucleii.  In the simplest case, this means predicting only three classes of pixel (though you can get much fancier: my model actually predicted the manhatten distance to the nearest foreign nucleus in each of 8 directions and used that to generate a heatmap for accurate cuts - which, in retrospect, is an insane and somewhat embarrassing design choice).  So the U-net models-with-postprocessing are solving a fundamentally simpler problem, have fewer parameters, but aren't <em>quite</em> end-end learnable.  They have been very effective here, but it was because of the structure of this specific problem.</p>\n\n<p>I expect that if we had been asked to discriminate between several dozen <em>types</em> of nucleii, Mask R-CNN would have swept the board (or innovative variants of it).</p>",
          "rawMarkdown": "I think it's problem-specific.  \n\nMask R-CNN  (and variants) make a lot of sense if you have a lot of classes and want to quickly find lots of small patches that you can then analyse individually with a (relatively heavyweight) classifier/segmenter.  Your region proposer tunes itself to discriminating between potential target areas and the background clutter; your classifier concentrates on being extremely good at assigning classes and boundaries to small objects (perhaps resized to a standard size).  This has several advantages in applications where there is _lots_ of clutter and _lots_ of object classes - you get to make a cursory scan of the scene, then focus your real classification muscle on the interesting parts.  It comes at the cost of additional complexity/parameters/depth/training effort: to some extent your region proposer and classifier have to learn the same textures.  But it's a great tradeoff for things like street view: you can tune how you deal with different regions (you could even attach different back-end recognisers to different region types), and it's all integrated into a single framework - all jointly learnable.  Beautiful in its way, and very effective.\n\nWhen segmenting nucleii with U-net, there's only two classes (nuclear and background tissue), plus an extra hack: you need some way to predict borders between nucleii, and devise some postprocessing step which can use those predictions to make high quality cuts between adjacent nucleii.  In the simplest case, this means predicting only three classes of pixel (though you can get much fancier: my model actually predicted the manhatten distance to the nearest foreign nucleus in each of 8 directions and used that to generate a heatmap for accurate cuts - which, in retrospect, is an insane and somewhat embarrassing design choice).  So the U-net models-with-postprocessing are solving a fundamentally simpler problem, have fewer parameters, but aren't *quite* end-end learnable.  They have been very effective here, but it was because of the structure of this specific problem.\n\nI expect that if we had been asked to discriminate between several dozen _types_ of nucleii, Mask R-CNN would have swept the board (or innovative variants of it).\n\n",
          "votes": 5
        }
      ]
    },
    {
      "id": 320117,
      "postDate": "2018-04-27T14:46:14.450Z",
      "content": "<p>latest results on se-resnext152: here are results on stage1 test (not used in training). It looks good!</p>\n\n<p>However, there something that are not correct and i need to improve:</p>\n\n<ol>\n<li><p>the ground truth border should be have different thickness (i use too thick ground truth, making small overlapped nuclei being occluded) </p></li>\n<li><p>loss balancing. I will try @Selim_Sef suggestion of bce + soft-dice in the next update</p></li>\n<li><p>Train data augmentation. I need to improve this.</p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/320117/9315/0a849e0eb15faa8a6d7329c3dd66aabe9a294cccb52ed30a90c8ca99092ae732.png\" alt=\"enter image description here\"></p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/320117/9319/4f949bd8d914bbfa06f40d6a0e2b5b75c38bf53dbcbafc48c97f105bee4f8fac.png\" alt=\"enter image description here\"></p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/320117/9320/432f367a4c5b5674de2e2977744d10289a064e5704b21af6607b4975be47c580.png\" alt=\"enter image description here\"></p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/320117/9317/1962d0c5faf3e85cda80e0578e0cb7aca50826d781620e5c1c4cc586bc69f81a.png\" alt=\"enter image description here\"></p></li>\n</ol>",
      "rawMarkdown": "latest results on se-resnext152: here are results on stage1 test (not used in training). It looks good!\n\nHowever, there something that are not correct and i need to improve:\n\n 1. the ground truth border should be have different thickness (i use too thick ground truth, making small overlapped nuclei being occluded) \n\n 2. loss balancing. I will try @Selim_Sef suggestion of bce + soft-dice in the next update\n\n 3. Train data augmentation. I need to improve this.\n\n  ![enter image description here][1]\n\n  ![enter image description here][2]\n\n  ![enter image description here][3]\n\n  ![enter image description here][4]\n\n\n  [1]: https://kaggle2.blob.core.windows.net/forum-message-attachments/320117/9315/0a849e0eb15faa8a6d7329c3dd66aabe9a294cccb52ed30a90c8ca99092ae732.png\n  [2]: https://kaggle2.blob.core.windows.net/forum-message-attachments/320117/9319/4f949bd8d914bbfa06f40d6a0e2b5b75c38bf53dbcbafc48c97f105bee4f8fac.png\n  [3]: https://kaggle2.blob.core.windows.net/forum-message-attachments/320117/9320/432f367a4c5b5674de2e2977744d10289a064e5704b21af6607b4975be47c580.png\n  [4]: https://kaggle2.blob.core.windows.net/forum-message-attachments/320117/9317/1962d0c5faf3e85cda80e0578e0cb7aca50826d781620e5c1c4cc586bc69f81a.png",
      "votes": 4
    },
    {
      "id": 317103,
      "postDate": "2018-04-20T18:42:26.983Z",
      "content": "<p>results after over fitting train data with more iterations:</p>\n\n<ul>\n<li><p>i start to understand why @topcoders want to focus on overlapping boundary and also using size dependent boundary</p></li>\n<li><p>one can also thinks of cascade of unet, where the next unet learns the weak points of the previous one and then add up the prediction for watershed post processing</p></li>\n<li><p>the next plan is to try if watershed can give close to zero error on these over-fitted train data. this will be the upper bound of the processing pipeline</p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/317103/9225/0ea221716cf13710214dcd331a61cea48308c3940df1d28cfc7fd817c83714e1.png\" alt=\"enter image description here\"></p></li>\n</ul>",
      "rawMarkdown": "results after over fitting train data with more iterations:\n\n  - i start to understand why @topcoders want to focus on overlapping boundary and also using size dependent boundary\n \n  - one can also thinks of cascade of unet, where the next unet learns the weak points of the previous one and then add up the prediction for watershed post processing\n\n  - the next plan is to try if watershed can give close to zero error on these over-fitted train data. this will be the upper bound of the processing pipeline\n\n  ![enter image description here][1]\n\n\n  [1]: https://kaggle2.blob.core.windows.net/forum-message-attachments/317103/9225/0ea221716cf13710214dcd331a61cea48308c3940df1d28cfc7fd817c83714e1.png",
      "votes": 2,
      "replies": [
        {
          "id": 317145,
          "postDate": "2018-04-20T21:46:55.310Z",
          "content": "<p>What would you use as input for the cascade unet ? </p>\n\n<p>It reminds of the approach from this paper (point 4):\n<a href=\"http://www.cs.toronto.edu/~fritz/absps/road_detection.pdf\">http://www.cs.toronto.edu/~fritz/absps/road_detection.pdf</a></p>\n\n<p>They used a second network, feeding it with the output from the first one, to only learn structures - it was about road detection, so the second network quickly learned to join roads that seems to be very close.</p>",
          "rawMarkdown": "What would you use as input for the cascade unet ? \n\nIt reminds of the approach from this paper (point 4):\nhttp://www.cs.toronto.edu/~fritz/absps/road_detection.pdf\n\nThey used a second network, feeding it with the output from the first one, to only learn structures - it was about road detection, so the second network quickly learned to join roads that seems to be very close.\n\n",
          "votes": 1
        },
        {
          "id": 317192,
          "postDate": "2018-04-21T01:22:15.130Z",
          "content": "<p>maybe cascade is not the correct word. Because the intention is to use watershed as post processing, one can think of the following design cycle for a solution:</p>\n\n<ol>\n<li><p>Using the ground truth, we find the best marker and distance transform that would give error-free water transform. Assume the best distance transform is call T_best. We now must think of a way to predict T_best from unet.</p></li>\n<li><p>Say we intent to train a unet to output one channel, just the foreground mask. Let call this C1.</p></li>\n<li><p>Assume the results are not ideal. We want to improve results by another channel C2. What should C2 be? If we are going add up the channels, then we need T_best = C1+C2, so C2=T_best-C1</p></li>\n<li><p>Assume the results is still no good. We think we can learn another channels C3. then we could have use  C3=T_best-C2-C1</p></li>\n<li><p>By observation, C2 is the  border. The mistakes of C2 channel from unet is usually the border at the overlapping nuclei. So we add a channel C3 = mistakes of C2, to correct the mistake of C2</p></li>\n</ol>",
          "rawMarkdown": "maybe cascade is not the correct word. Because the intention is to use watershed as post processing, one can think of the following design cycle for a solution:\n\n1.  Using the ground truth, we find the best marker and distance transform that would give error-free water transform. Assume the best distance transform is call T_best. We now must think of a way to predict T_best from unet.\n\n2. Say we intent to train a unet to output one channel, just the foreground mask. Let call this C1.\n\n3. Assume the results are not ideal. We want to improve results by another channel C2. What should C2 be? If we are going add up the channels, then we need T_best = C1+C2, so C2=T_best-C1\n\n4. Assume the results is still no good. We think we can learn another channels C3. then we could have use  C3=T_best-C2-C1\n\n5. By observation, C2 is the  border. The mistakes of C2 channel from unet is usually the border at the overlapping nuclei. So we add a channel C3 = mistakes of C2, to correct the mistake of C2\n\n "
        },
        {
          "id": 317242,
          "postDate": "2018-04-21T03:24:26.870Z",
          "content": "<p>Would multi class Unet be useful?  This paper was referenced:\n<a href=\"https://arxiv.org/pdf/1802.07465.pdf\">https://arxiv.org/pdf/1802.07465.pdf</a>\nMULTICLASS WEIGHTED LOSS FOR INSTANCE SEGMENTATION OF CLUTTERED CELLS</p>\n\n<p>And posted use in the competition:\n<a href=\"https://www.kaggle.com/c/data-science-bowl-2018/discussion/49909\">https://www.kaggle.com/c/data-science-bowl-2018/discussion/49909</a>\n\"We did some training of the Multi-output U-Net, which learns mask, contour, and center. We put all our predictions available on-line via neptune.ml\"</p>",
          "rawMarkdown": "Would multi class Unet be useful?  This paper was referenced:\nhttps://arxiv.org/pdf/1802.07465.pdf\nMULTICLASS WEIGHTED LOSS FOR INSTANCE SEGMENTATION OF CLUTTERED CELLS\n\nAnd posted use in the competition:\nhttps://www.kaggle.com/c/data-science-bowl-2018/discussion/49909\n\"We did some training of the Multi-output U-Net, which learns mask, contour, and center. We put all our predictions available on-line via neptune.ml\"",
          "votes": 1
        }
      ]
    },
    {
      "id": 317042,
      "postDate": "2018-04-20T15:00:17.203Z",
      "content": "<p>20180420 version (early iterations):\n  <img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/317042/9224/unet.png\" alt=\"enter image description here\"></p>",
      "rawMarkdown": "20180420 version (early iterations):\n  ![enter image description here][1]\n\n\n  [1]: https://kaggle2.blob.core.windows.net/forum-message-attachments/317042/9224/unet.png",
      "votes": 2
    },
    {
      "id": 320039,
      "postDate": "2018-04-27T10:36:35.493Z",
      "content": "<p>You are really amazing, great work.</p>",
      "rawMarkdown": "You are really amazing, great work.",
      "replies": [
        {
          "id": 320122,
          "postDate": "2018-04-27T14:53:40.300Z",
          "content": "<p>repeat top kaggler results is to first step to be a top kaggler :)</p>",
          "rawMarkdown": "repeat top kaggler results is to first step to be a top kaggler :)",
          "votes": 11
        }
      ]
    },
    {
      "id": 319561,
      "postDate": "2018-04-26T10:04:45.007Z",
      "content": "<p>just a quick update: i am implementing resnext152 based on inplace BN which will saved 50% memory as claimed here:</p>\n\n<p><a href=\"https://github.com/mapillary/inplace_abn\">https://github.com/mapillary/inplace_abn</a></p>",
      "rawMarkdown": "just a quick update: i am implementing resnext152 based on inplace BN which will saved 50% memory as claimed here:\n\nhttps://github.com/mapillary/inplace_abn"
    },
    {
      "id": 320005,
      "postDate": "2018-04-27T09:15:12.663Z",
      "rawMarkdown": "",
      "votes": -3,
      "isDeleted": true,
      "replies": [
        {
          "id": 320007,
          "postDate": "2018-04-27T09:18:30.097Z",
          "content": "<p>Yes. They will open source later. But I would like to do an implementation myself first and then compare it with their version. It would be a great learning experience and this process will uncover a lots of implementation details.</p>",
          "rawMarkdown": "Yes. They will open source later. But I would like to do an implementation myself first and then compare it with their version. It would be a great learning experience and this process will uncover a lots of implementation details.",
          "votes": 4
        }
      ]
    }
  ],
  "comments": [
    {
      "id": 317009,
      "author_name": "Kostiantyn Maksymov",
      "author_url": "",
      "post_date": "2018-04-20T12:58:13",
      "content": "<p>Hi! What about to use github? I am also interested to participate</p>",
      "votes": 7,
      "replies": [
        {
          "id": 317010,
          "author_name": "hengck23",
          "author_url": "",
          "post_date": "2018-04-20T12:59:49.040000",
          "content": "<p>hi, currently google drive is most convenient for me. I suggest that you can take my code and put on github?</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 318873,
      "author_name": "hengck23",
      "author_url": "",
      "post_date": "2018-04-24T16:38:43.870000",
      "content": "<p>updated results. please see \"20180425\". Below are results on training images. The next stage is to do evaluation on stage1 test set. The border pixels are minority class, class balancing are important and tricky. </p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/318873/9292/8efed2e62c919e6d70a2ab548b1a33014877fe8a23f177ef25a9dee25ffe8842.png\" alt=\"enter image description here\"></p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/318873/9294/2f929b067a59f88530b6bfa6f6889bc3a38adf88d594895973d1c8b2549fd93d.png\" alt=\"enter image description here\"></p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/318873/9296/a102535b0e88374bea4a1cfd9ee7cb3822ff54f4ab2a9845d428ec22f9ee2288.png\" alt=\"enter image description here\"></p>",
      "votes": 3,
      "replies": [
        {
          "id": 318897,
          "author_name": "Selim Seferbekov",
          "author_url": "",
          "post_date": "2018-04-24T17:46:24.790000",
          "content": "<p>This imbalance problem could be solved if  you make your  loss function like this  </p><pre>bce(all_channels) +  dice_loss(mask_channel) + dice_loss(border_channel) </pre><p></p>",
          "votes": 9,
          "replies": []
        },
        {
          "id": 319780,
          "author_name": "Pedro Marrero Fernández",
          "author_url": "",
          "post_date": "2018-04-26T20:21:18.697000",
          "content": "<p>In <a href=\"https://arxiv.org/pdf/1802.07465.pdf\">https://arxiv.org/pdf/1802.07465.pdf</a>  we alse use “overlapping boundary” or “ touching borders” (Alg. 1). In my opinion it is much better than using the boundary. For the imbalance we use weight maps.  In this competition I use boundary. I did not have time to translate the matlab code from the weight maps for the second stage :(. </p>\n\n<p>I calculate of the touching borders as follows:</p>\n\n<pre><code>def get_touchs( edges ):       \n    A = np.array([ morph.binary_dilation( c, morph.square(3) )  for c in edges ]) \n    A = np.sum(A,axis=0)&gt;1  \n    I = morph.remove_small_objects( A, 3 )\n    I = morph.skeletonize(I)\n    I = morph.binary_dilation( I, morph.square(3) )    \n    return I\n</code></pre>",
          "votes": 4,
          "replies": []
        },
        {
          "id": 320121,
          "author_name": "hengck23",
          "author_url": "",
          "post_date": "2018-04-27T14:52:22.363000",
          "content": "<p>thanks for the post. I will try to use it</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 316773,
      "author_name": "Boltzmann",
      "author_url": "",
      "post_date": "2018-04-19T21:26:55.450000",
      "content": "<p>Thanks very much for the code! I am quite new to computer vision and image segmentation. After this competition, I still have some questions in my head. When I first look at this problem, it seems U-Net is intrinsically only good at semantic segmentation(correct me if I am wrong :), and Mask R-CNN combines object detection and segmentation, so it seems to be good at instance segmentation. However, the result of this competition shows U-Net is better at this problem. What's the reason about this? I can guess of two reasons but don't know if they are correct, 1. U-Net will predict more precise boundaries, which contributes more to the metric. 2. There is actually no overlaps of nuclei instances in the given masks.</p>",
      "votes": 3,
      "replies": [
        {
          "id": 316927,
          "author_name": "Snorkle",
          "author_url": "",
          "post_date": "2018-04-20T07:41:29.840000",
          "content": "<p>I think it's problem-specific.  </p>\n\n<p>Mask R-CNN  (and variants) make a lot of sense if you have a lot of classes and want to quickly find lots of small patches that you can then analyse individually with a (relatively heavyweight) classifier/segmenter.  Your region proposer tunes itself to discriminating between potential target areas and the background clutter; your classifier concentrates on being extremely good at assigning classes and boundaries to small objects (perhaps resized to a standard size).  This has several advantages in applications where there is <em>lots</em> of clutter and <em>lots</em> of object classes - you get to make a cursory scan of the scene, then focus your real classification muscle on the interesting parts.  It comes at the cost of additional complexity/parameters/depth/training effort: to some extent your region proposer and classifier have to learn the same textures.  But it's a great tradeoff for things like street view: you can tune how you deal with different regions (you could even attach different back-end recognisers to different region types), and it's all integrated into a single framework - all jointly learnable.  Beautiful in its way, and very effective.</p>\n\n<p>When segmenting nucleii with U-net, there's only two classes (nuclear and background tissue), plus an extra hack: you need some way to predict borders between nucleii, and devise some postprocessing step which can use those predictions to make high quality cuts between adjacent nucleii.  In the simplest case, this means predicting only three classes of pixel (though you can get much fancier: my model actually predicted the manhatten distance to the nearest foreign nucleus in each of 8 directions and used that to generate a heatmap for accurate cuts - which, in retrospect, is an insane and somewhat embarrassing design choice).  So the U-net models-with-postprocessing are solving a fundamentally simpler problem, have fewer parameters, but aren't <em>quite</em> end-end learnable.  They have been very effective here, but it was because of the structure of this specific problem.</p>\n\n<p>I expect that if we had been asked to discriminate between several dozen <em>types</em> of nucleii, Mask R-CNN would have swept the board (or innovative variants of it).</p>",
          "votes": 5,
          "replies": []
        }
      ]
    },
    {
      "id": 320117,
      "author_name": "hengck23",
      "author_url": "",
      "post_date": "2018-04-27T14:46:14.450000",
      "content": "<p>latest results on se-resnext152: here are results on stage1 test (not used in training). It looks good!</p>\n\n<p>However, there something that are not correct and i need to improve:</p>\n\n<ol>\n<li><p>the ground truth border should be have different thickness (i use too thick ground truth, making small overlapped nuclei being occluded) </p></li>\n<li><p>loss balancing. I will try @Selim_Sef suggestion of bce + soft-dice in the next update</p></li>\n<li><p>Train data augmentation. I need to improve this.</p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/320117/9315/0a849e0eb15faa8a6d7329c3dd66aabe9a294cccb52ed30a90c8ca99092ae732.png\" alt=\"enter image description here\"></p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/320117/9319/4f949bd8d914bbfa06f40d6a0e2b5b75c38bf53dbcbafc48c97f105bee4f8fac.png\" alt=\"enter image description here\"></p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/320117/9320/432f367a4c5b5674de2e2977744d10289a064e5704b21af6607b4975be47c580.png\" alt=\"enter image description here\"></p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/320117/9317/1962d0c5faf3e85cda80e0578e0cb7aca50826d781620e5c1c4cc586bc69f81a.png\" alt=\"enter image description here\"></p></li>\n</ol>",
      "votes": 4,
      "replies": []
    },
    {
      "id": 317103,
      "author_name": "hengck23",
      "author_url": "",
      "post_date": "2018-04-20T18:42:26.983000",
      "content": "<p>results after over fitting train data with more iterations:</p>\n\n<ul>\n<li><p>i start to understand why @topcoders want to focus on overlapping boundary and also using size dependent boundary</p></li>\n<li><p>one can also thinks of cascade of unet, where the next unet learns the weak points of the previous one and then add up the prediction for watershed post processing</p></li>\n<li><p>the next plan is to try if watershed can give close to zero error on these over-fitted train data. this will be the upper bound of the processing pipeline</p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/317103/9225/0ea221716cf13710214dcd331a61cea48308c3940df1d28cfc7fd817c83714e1.png\" alt=\"enter image description here\"></p></li>\n</ul>",
      "votes": 2,
      "replies": [
        {
          "id": 317145,
          "author_name": "Alchemist",
          "author_url": "",
          "post_date": "2018-04-20T21:46:55.310000",
          "content": "<p>What would you use as input for the cascade unet ? </p>\n\n<p>It reminds of the approach from this paper (point 4):\n<a href=\"http://www.cs.toronto.edu/~fritz/absps/road_detection.pdf\">http://www.cs.toronto.edu/~fritz/absps/road_detection.pdf</a></p>\n\n<p>They used a second network, feeding it with the output from the first one, to only learn structures - it was about road detection, so the second network quickly learned to join roads that seems to be very close.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 317192,
          "author_name": "hengck23",
          "author_url": "",
          "post_date": "2018-04-21T01:22:15.130000",
          "content": "<p>maybe cascade is not the correct word. Because the intention is to use watershed as post processing, one can think of the following design cycle for a solution:</p>\n\n<ol>\n<li><p>Using the ground truth, we find the best marker and distance transform that would give error-free water transform. Assume the best distance transform is call T_best. We now must think of a way to predict T_best from unet.</p></li>\n<li><p>Say we intent to train a unet to output one channel, just the foreground mask. Let call this C1.</p></li>\n<li><p>Assume the results are not ideal. We want to improve results by another channel C2. What should C2 be? If we are going add up the channels, then we need T_best = C1+C2, so C2=T_best-C1</p></li>\n<li><p>Assume the results is still no good. We think we can learn another channels C3. then we could have use  C3=T_best-C2-C1</p></li>\n<li><p>By observation, C2 is the  border. The mistakes of C2 channel from unet is usually the border at the overlapping nuclei. So we add a channel C3 = mistakes of C2, to correct the mistake of C2</p></li>\n</ol>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 317242,
          "author_name": "something4kag",
          "author_url": "",
          "post_date": "2018-04-21T03:24:26.870000",
          "content": "<p>Would multi class Unet be useful?  This paper was referenced:\n<a href=\"https://arxiv.org/pdf/1802.07465.pdf\">https://arxiv.org/pdf/1802.07465.pdf</a>\nMULTICLASS WEIGHTED LOSS FOR INSTANCE SEGMENTATION OF CLUTTERED CELLS</p>\n\n<p>And posted use in the competition:\n<a href=\"https://www.kaggle.com/c/data-science-bowl-2018/discussion/49909\">https://www.kaggle.com/c/data-science-bowl-2018/discussion/49909</a>\n\"We did some training of the Multi-output U-Net, which learns mask, contour, and center. We put all our predictions available on-line via neptune.ml\"</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 317042,
      "author_name": "hengck23",
      "author_url": "",
      "post_date": "2018-04-20T15:00:17.203000",
      "content": "<p>20180420 version (early iterations):\n  <img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/317042/9224/unet.png\" alt=\"enter image description here\"></p>",
      "votes": 2,
      "replies": []
    },
    {
      "id": 320039,
      "author_name": "good good study",
      "author_url": "",
      "post_date": "2018-04-27T10:36:35.493000",
      "content": "<p>You are really amazing, great work.</p>",
      "votes": 0,
      "replies": [
        {
          "id": 320122,
          "author_name": "hengck23",
          "author_url": "",
          "post_date": "2018-04-27T14:53:40.300000",
          "content": "<p>repeat top kaggler results is to first step to be a top kaggler :)</p>",
          "votes": 11,
          "replies": []
        }
      ]
    },
    {
      "id": 319561,
      "author_name": "hengck23",
      "author_url": "",
      "post_date": "2018-04-26T10:04:45.007000",
      "content": "<p>just a quick update: i am implementing resnext152 based on inplace BN which will saved 50% memory as claimed here:</p>\n\n<p><a href=\"https://github.com/mapillary/inplace_abn\">https://github.com/mapillary/inplace_abn</a></p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 320005,
      "author_name": "",
      "author_url": "",
      "post_date": "2018-04-27T09:15:12.663000",
      "content": "",
      "votes": -3,
      "replies": [
        {
          "id": 320007,
          "author_name": "hengck23",
          "author_url": "",
          "post_date": "2018-04-27T09:18:30.097000",
          "content": "<p>Yes. They will open source later. But I would like to do an implementation myself first and then compare it with their version. It would be a great learning experience and this process will uncover a lots of implementation details.</p>",
          "votes": 4,
          "replies": []
        }
      ]
    }
  ],
  "raw_markdown_by_id": {
    "316709": "Unet seems to be an important approach for future kaggle challenge as well. Hence I have decided to repeat topcoder results, making modifications if required. My target is 0.580 on public LB on stage1 dataset first. (there is an evaluation code in my code base for scoring your csv file against the released stage1 test solution csv)\n\nMy code base is at: https://drive.google.com/drive/folders/1EtBdlPK3BVahHBZtB103QQxNUdWaJ6di \n\n. It is based on pytorch.\n\nIt is still in progress. you can follow this thread for update.\n\nThe attached ppt shows current progress.\n\n------------------------------------------------------------------------------\n\nlatest : 20180427 folder\n  \n - unet (fpn se-resnext152 backbone)\n\n - learning watershed line as border",
    "317009": "Hi! What about to use github? I am also interested to participate",
    "318873": "updated results. please see \"20180425\". Below are results on training images. The next stage is to do evaluation on stage1 test set. The border pixels are minority class, class balancing are important and tricky. \n\n  ![enter image description here][1]\n\n  ![enter image description here][2]\n\n  ![enter image description here][3]\n\n\n  [1]: https://kaggle2.blob.core.windows.net/forum-message-attachments/318873/9292/8efed2e62c919e6d70a2ab548b1a33014877fe8a23f177ef25a9dee25ffe8842.png\n  [2]: https://kaggle2.blob.core.windows.net/forum-message-attachments/318873/9294/2f929b067a59f88530b6bfa6f6889bc3a38adf88d594895973d1c8b2549fd93d.png\n  [3]: https://kaggle2.blob.core.windows.net/forum-message-attachments/318873/9296/a102535b0e88374bea4a1cfd9ee7cb3822ff54f4ab2a9845d428ec22f9ee2288.png",
    "316773": "Thanks very much for the code! I am quite new to computer vision and image segmentation. After this competition, I still have some questions in my head. When I first look at this problem, it seems U-Net is intrinsically only good at semantic segmentation(correct me if I am wrong :), and Mask R-CNN combines object detection and segmentation, so it seems to be good at instance segmentation. However, the result of this competition shows U-Net is better at this problem. What's the reason about this? I can guess of two reasons but don't know if they are correct, 1. U-Net will predict more precise boundaries, which contributes more to the metric. 2. There is actually no overlaps of nuclei instances in the given masks.",
    "320117": "latest results on se-resnext152: here are results on stage1 test (not used in training). It looks good!\n\nHowever, there something that are not correct and i need to improve:\n\n 1. the ground truth border should be have different thickness (i use too thick ground truth, making small overlapped nuclei being occluded) \n\n 2. loss balancing. I will try @Selim_Sef suggestion of bce + soft-dice in the next update\n\n 3. Train data augmentation. I need to improve this.\n\n  ![enter image description here][1]\n\n  ![enter image description here][2]\n\n  ![enter image description here][3]\n\n  ![enter image description here][4]\n\n\n  [1]: https://kaggle2.blob.core.windows.net/forum-message-attachments/320117/9315/0a849e0eb15faa8a6d7329c3dd66aabe9a294cccb52ed30a90c8ca99092ae732.png\n  [2]: https://kaggle2.blob.core.windows.net/forum-message-attachments/320117/9319/4f949bd8d914bbfa06f40d6a0e2b5b75c38bf53dbcbafc48c97f105bee4f8fac.png\n  [3]: https://kaggle2.blob.core.windows.net/forum-message-attachments/320117/9320/432f367a4c5b5674de2e2977744d10289a064e5704b21af6607b4975be47c580.png\n  [4]: https://kaggle2.blob.core.windows.net/forum-message-attachments/320117/9317/1962d0c5faf3e85cda80e0578e0cb7aca50826d781620e5c1c4cc586bc69f81a.png",
    "317103": "results after over fitting train data with more iterations:\n\n  - i start to understand why @topcoders want to focus on overlapping boundary and also using size dependent boundary\n \n  - one can also thinks of cascade of unet, where the next unet learns the weak points of the previous one and then add up the prediction for watershed post processing\n\n  - the next plan is to try if watershed can give close to zero error on these over-fitted train data. this will be the upper bound of the processing pipeline\n\n  ![enter image description here][1]\n\n\n  [1]: https://kaggle2.blob.core.windows.net/forum-message-attachments/317103/9225/0ea221716cf13710214dcd331a61cea48308c3940df1d28cfc7fd817c83714e1.png",
    "317042": "20180420 version (early iterations):\n  ![enter image description here][1]\n\n\n  [1]: https://kaggle2.blob.core.windows.net/forum-message-attachments/317042/9224/unet.png",
    "320039": "You are really amazing, great work.",
    "319561": "just a quick update: i am implementing resnext152 based on inplace BN which will saved 50% memory as claimed here:\n\nhttps://github.com/mapillary/inplace_abn",
    "320005": ""
  },
  "complete": true,
  "source": "existing_discussion",
  "competition_id": 8089,
  "competition_slug": "data-science-bowl-2018",
  "team_id": 1453519,
  "solution_url": "/competitions/data-science-bowl-2018/writeups/daydreamers-repeating-topcoders-unet-results"
}