{
  "id": 679238,
  "title": "1st Place Solution for the Vesuvius Challenge - Surface Detection Competition",
  "url": "/competitions/vesuvius-challenge-surface-detection/discussion/679238",
  "author_name": "PaulG",
  "post_date": "2026-02-28T03:12:25.848000",
  "votes": 66,
  "comment_count": 31,
  "views": 0,
  "content": "<p>Thanks to the organizers for this fun and important competition, and congratulations to all the winners!</p>\n<h2>Context</h2>\n<ul>\n<li><strong><a href=\"https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/overview\" target=\"_blank\">https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/overview</a></strong></li>\n<li><strong><a href=\"https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/data\" target=\"_blank\">https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/data</a></strong></li>\n</ul>\n<h2>Overview of the approach</h2>\n<p>Our solution consisted of an nnU-Net ensemble plus post-processing.</p>\n<h2>Details of the submission</h2>\n<h3>nnU-Net</h3>\n<p>First, we would like to appreciate <a href=\"https://www.kaggle.com/jirkaborovec\" target=\"_blank\">@jirkaborovec</a> 's work! His <a href=\"https://www.kaggle.com/code/jirkaborovec/surface-nnunet-training-inference-with-2xt4\" target=\"_blank\">notebook</a> served as the starting point of our training pipeline.</p>\n<h4>Single Model Strategy</h4>\n<ul>\n<li>We used all available data for training and built our baseline nnU-Net model (Model 1) with the following settings:</li>\n</ul>\n<pre><code>patch size: 128\nbatch size: 2\nepochs: 4000\n</code></pre>\n<ul>\n<li><p>We then fine-tuned Model 1 with larger patch sizes of 192 and 256, training for 250 epochs each.</p></li>\n<li><p>Due to the extension of the competition, we trained additional models from scratch (for 4000 epochs) with patch sizes of 160, 192, and 224 to increase model diversity. Among these, the 192-patch model was included in our final ensemble.</p></li>\n<li><p>As for the single model performance, , and two of our best single models are (due to submission quota, we only did basic post processing on single model submission for A/B tests, so full post processing may produce better results):</p></li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>Setting</th>\n<th>Public LB</th>\n<th>Private LB</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>fine-tuned 192-patch model at 250 epochs</td>\n<td>0.577</td>\n<td>0.614</td>\n</tr>\n<tr>\n<td>from-scratch 192-patch model at 4000 epochs</td>\n<td>0.587</td>\n<td>0.613</td>\n</tr>\n</tbody>\n</table>\n<h4>Ensemble Strategy</h4>\n<p>We prepared two sets of 4-model ensembles as our final submissions:</p>\n<ul>\n<li><strong>Set 1:</strong> Baseline 128-patch Model 1 (weight: 0.12) + fine-tuned 192-patch model (0.28) + fine-tuned 256-patch model at 100 epochs (0.18) + fine-tuned 256-patch model at 250 epochs (0.42).</li>\n<li><strong>Set 2:</strong> Baseline 128-patch Model 1 (weight: 0.12) + fine-tuned 192-patch model (0.28) + fine-tuned 256-patch model at 250 epochs (0.18) + from-scratch 192-patch model at 4000 epochs (0.42).</li>\n</ul>\n<p>For each ensemble, we fused the post-softmax probabilities using the assigned model weights and applied different thresholds and post processing methods (will be discussed in the following section).</p>\n<table>\n<thead>\n<tr>\n<th>Ensemble</th>\n<th>Public LB</th>\n<th>Private LB</th>\n<th>Threshold</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Set 1</td>\n<td>0.613</td>\n<td>0.620</td>\n<td>0.20</td>\n</tr>\n<tr>\n<td>Set 2</td>\n<td>0.606</td>\n<td>0.627</td>\n<td>0.26</td>\n</tr>\n</tbody>\n</table>\n<h3>Post-processing</h3>\n<p>As discussed in many of the forum posts, minimizing holes and cavities in the predicted masks was essential for getting a good score.\nTo that end, we applied five post-processing steps:</p>\n<p>0. We removed mask components that have less than 20K voxels.</p>\n<p>Then for each sheet (where a sheet is a connected-component in a predicted mask), we did the following:</p>\n<p>1. Applied scipy.ndimage.binary_closing(), with a spherical footprint of radius 3. This closes holes and cavities of radius 3 or less.</p>\n<p>2. Patching: To repair larger holes, we represented each sheet as a height map, and filled any gaps in the height map by linear interpolation across the gap. We did this separately along the x and y directions, and averaged the two results, weighted by distance to the nearest gap-edge. The projection axis for creating the height map was chosen to be the one that gave the largest projected sheet area. This method is capable of significant repairs: </p>\n<p><img src=\"https://github.com/Paul-G2/VesuviusSurfaceDetection/raw/main/PatchHoles03.jpg\" alt=\"\"></p>\n<p>3. We created a simple function to plug any small (1-voxel) remaining holes. For each voxel in a given sheet, we look at it's 2 x 2 x 2 neighborhood\nand add whatever voxels are needed to make that neighborhood 6-connected watertight. For example:</p>\n<p><img src=\"https://github.com/Paul-G2/VesuviusSurfaceDetection/raw/main/Cubes.jpg\" alt=\"\"></p>\n<p>(This method was inspired by the scikit-image euler_number() function, which uses such neighborhoods to compute the Euler number.) We don't have a proof that our function plugs all 1-voxel holes, but it seems to work well in practice. The algorithm is implemented as a lookup table, with 256 entries for the 256 possible neigborhoods. To create the lookup table, we used a very high tech scotch-tape-and-paper model to visualize all the cases:</p>\n<p><img src=\"https://github.com/Paul-G2/VesuviusSurfaceDetection/raw/main/PaperCubes1.jpg\" alt=\"\"></p>\n<p>(Ordinary dilation will also plug holes, but it tends to add too many voxels, which can degrade the dice score.)</p>\n<p>4. Finally,  we called scipy.ndimage.binary_fill_holes() on the whole mask, which fills arbitrary-size cavities.</p>\n<p>Our best version of this post-processing pipeline also included a check of the number of holes before and after patching, because the patching can actually introduce small holes, for example when the sheet is very curved. In such cases we discard the patch. </p>\n<p>The following table shows the cumulative effect of each post-processing step on our best nnU-Net ensemble:</p>\n<table>\n<thead>\n<tr>\n<th>Step</th>\n<th>Public Score</th>\n<th>Private Score</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>No post-proc</td>\n<td>.572</td>\n<td>.596</td>\n</tr>\n<tr>\n<td>Remove small components</td>\n<td>.586</td>\n<td>.614</td>\n</tr>\n<tr>\n<td>Plug small holes</td>\n<td>.598</td>\n<td>.622</td>\n</tr>\n<tr>\n<td>Patch large holes</td>\n<td>.601</td>\n<td>.625</td>\n</tr>\n<tr>\n<td>Binary closing</td>\n<td>.606</td>\n<td>.627</td>\n</tr>\n<tr>\n<td>Fill_holes</td>\n<td>.606</td>\n<td>.627</td>\n</tr>\n</tbody>\n</table>\n<h2>What didn't work</h2>\n<p>Unfortunately, we did not find an effective solution to the problem of touching sheets. We just relied on nnu-Net to minimize their occurrence.</p>\n<h2>What we misled by public LB</h2>\n<ul>\n<li>logits fusion performs better on private LB, but we trusted (overfitted) on probability fusion</li>\n<li>larger threshold (Like 0.35-0.4 is the best searched value on our model on training set) performs better on private LB</li>\n</ul>\n<h2>How Vibe Coding helps</h2>\n<p>Initially, our ensemble pipeline got resources issues (GPU memory, hard disk space, …) even with 2 models ensemble, ChatGPT helps us redesign the pipeline, and enables 4 models ensemble.</p>\n<h2>Sources</h2>\n<ul>\n<li><strong><a href=\"https://www.kaggle.com/code/jirkaborovec/surface-nnunet-training-inference-with-2xt4\" target=\"_blank\">https://www.kaggle.com/code/jirkaborovec/surface-nnunet-training-inference-with-2xt4</a></strong></li>\n<li><a href=\"https://www.kaggle.com/code/tonylica/nnunet-4-model-7-5-2-1-final-submit-so-long?scriptVersionId=300373304\" target=\"_blank\">0.627 solution notebook</a></li>\n</ul>",
  "messages": [
    {
      "id": 3414991,
      "postDate": "2026-02-28T03:12:25.850Z",
      "content": "<p>Thanks to the organizers for this fun and important competition, and congratulations to all the winners!</p>\n<h2>Context</h2>\n<ul>\n<li><strong><a href=\"https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/overview\" target=\"_blank\">https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/overview</a></strong></li>\n<li><strong><a href=\"https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/data\" target=\"_blank\">https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/data</a></strong></li>\n</ul>\n<h2>Overview of the approach</h2>\n<p>Our solution consisted of an nnU-Net ensemble plus post-processing.</p>\n<h2>Details of the submission</h2>\n<h3>nnU-Net</h3>\n<p>First, we would like to appreciate <a href=\"https://www.kaggle.com/jirkaborovec\" target=\"_blank\">@jirkaborovec</a> 's work! His <a href=\"https://www.kaggle.com/code/jirkaborovec/surface-nnunet-training-inference-with-2xt4\" target=\"_blank\">notebook</a> served as the starting point of our training pipeline.</p>\n<h4>Single Model Strategy</h4>\n<ul>\n<li>We used all available data for training and built our baseline nnU-Net model (Model 1) with the following settings:</li>\n</ul>\n<pre><code>patch size: 128\nbatch size: 2\nepochs: 4000\n</code></pre>\n<ul>\n<li><p>We then fine-tuned Model 1 with larger patch sizes of 192 and 256, training for 250 epochs each.</p></li>\n<li><p>Due to the extension of the competition, we trained additional models from scratch (for 4000 epochs) with patch sizes of 160, 192, and 224 to increase model diversity. Among these, the 192-patch model was included in our final ensemble.</p></li>\n<li><p>As for the single model performance, , and two of our best single models are (due to submission quota, we only did basic post processing on single model submission for A/B tests, so full post processing may produce better results):</p></li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>Setting</th>\n<th>Public LB</th>\n<th>Private LB</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>fine-tuned 192-patch model at 250 epochs</td>\n<td>0.577</td>\n<td>0.614</td>\n</tr>\n<tr>\n<td>from-scratch 192-patch model at 4000 epochs</td>\n<td>0.587</td>\n<td>0.613</td>\n</tr>\n</tbody>\n</table>\n<h4>Ensemble Strategy</h4>\n<p>We prepared two sets of 4-model ensembles as our final submissions:</p>\n<ul>\n<li><strong>Set 1:</strong> Baseline 128-patch Model 1 (weight: 0.12) + fine-tuned 192-patch model (0.28) + fine-tuned 256-patch model at 100 epochs (0.18) + fine-tuned 256-patch model at 250 epochs (0.42).</li>\n<li><strong>Set 2:</strong> Baseline 128-patch Model 1 (weight: 0.12) + fine-tuned 192-patch model (0.28) + fine-tuned 256-patch model at 250 epochs (0.18) + from-scratch 192-patch model at 4000 epochs (0.42).</li>\n</ul>\n<p>For each ensemble, we fused the post-softmax probabilities using the assigned model weights and applied different thresholds and post processing methods (will be discussed in the following section).</p>\n<table>\n<thead>\n<tr>\n<th>Ensemble</th>\n<th>Public LB</th>\n<th>Private LB</th>\n<th>Threshold</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Set 1</td>\n<td>0.613</td>\n<td>0.620</td>\n<td>0.20</td>\n</tr>\n<tr>\n<td>Set 2</td>\n<td>0.606</td>\n<td>0.627</td>\n<td>0.26</td>\n</tr>\n</tbody>\n</table>\n<h3>Post-processing</h3>\n<p>As discussed in many of the forum posts, minimizing holes and cavities in the predicted masks was essential for getting a good score.\nTo that end, we applied five post-processing steps:</p>\n<p>0. We removed mask components that have less than 20K voxels.</p>\n<p>Then for each sheet (where a sheet is a connected-component in a predicted mask), we did the following:</p>\n<p>1. Applied scipy.ndimage.binary_closing(), with a spherical footprint of radius 3. This closes holes and cavities of radius 3 or less.</p>\n<p>2. Patching: To repair larger holes, we represented each sheet as a height map, and filled any gaps in the height map by linear interpolation across the gap. We did this separately along the x and y directions, and averaged the two results, weighted by distance to the nearest gap-edge. The projection axis for creating the height map was chosen to be the one that gave the largest projected sheet area. This method is capable of significant repairs: </p>\n<p><img src=\"https://github.com/Paul-G2/VesuviusSurfaceDetection/raw/main/PatchHoles03.jpg\" alt=\"\"></p>\n<p>3. We created a simple function to plug any small (1-voxel) remaining holes. For each voxel in a given sheet, we look at it's 2 x 2 x 2 neighborhood\nand add whatever voxels are needed to make that neighborhood 6-connected watertight. For example:</p>\n<p><img src=\"https://github.com/Paul-G2/VesuviusSurfaceDetection/raw/main/Cubes.jpg\" alt=\"\"></p>\n<p>(This method was inspired by the scikit-image euler_number() function, which uses such neighborhoods to compute the Euler number.) We don't have a proof that our function plugs all 1-voxel holes, but it seems to work well in practice. The algorithm is implemented as a lookup table, with 256 entries for the 256 possible neigborhoods. To create the lookup table, we used a very high tech scotch-tape-and-paper model to visualize all the cases:</p>\n<p><img src=\"https://github.com/Paul-G2/VesuviusSurfaceDetection/raw/main/PaperCubes1.jpg\" alt=\"\"></p>\n<p>(Ordinary dilation will also plug holes, but it tends to add too many voxels, which can degrade the dice score.)</p>\n<p>4. Finally,  we called scipy.ndimage.binary_fill_holes() on the whole mask, which fills arbitrary-size cavities.</p>\n<p>Our best version of this post-processing pipeline also included a check of the number of holes before and after patching, because the patching can actually introduce small holes, for example when the sheet is very curved. In such cases we discard the patch. </p>\n<p>The following table shows the cumulative effect of each post-processing step on our best nnU-Net ensemble:</p>\n<table>\n<thead>\n<tr>\n<th>Step</th>\n<th>Public Score</th>\n<th>Private Score</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>No post-proc</td>\n<td>.572</td>\n<td>.596</td>\n</tr>\n<tr>\n<td>Remove small components</td>\n<td>.586</td>\n<td>.614</td>\n</tr>\n<tr>\n<td>Plug small holes</td>\n<td>.598</td>\n<td>.622</td>\n</tr>\n<tr>\n<td>Patch large holes</td>\n<td>.601</td>\n<td>.625</td>\n</tr>\n<tr>\n<td>Binary closing</td>\n<td>.606</td>\n<td>.627</td>\n</tr>\n<tr>\n<td>Fill_holes</td>\n<td>.606</td>\n<td>.627</td>\n</tr>\n</tbody>\n</table>\n<h2>What didn't work</h2>\n<p>Unfortunately, we did not find an effective solution to the problem of touching sheets. We just relied on nnu-Net to minimize their occurrence.</p>\n<h2>What we misled by public LB</h2>\n<ul>\n<li>logits fusion performs better on private LB, but we trusted (overfitted) on probability fusion</li>\n<li>larger threshold (Like 0.35-0.4 is the best searched value on our model on training set) performs better on private LB</li>\n</ul>\n<h2>How Vibe Coding helps</h2>\n<p>Initially, our ensemble pipeline got resources issues (GPU memory, hard disk space, …) even with 2 models ensemble, ChatGPT helps us redesign the pipeline, and enables 4 models ensemble.</p>\n<h2>Sources</h2>\n<ul>\n<li><strong><a href=\"https://www.kaggle.com/code/jirkaborovec/surface-nnunet-training-inference-with-2xt4\" target=\"_blank\">https://www.kaggle.com/code/jirkaborovec/surface-nnunet-training-inference-with-2xt4</a></strong></li>\n<li><a href=\"https://www.kaggle.com/code/tonylica/nnunet-4-model-7-5-2-1-final-submit-so-long?scriptVersionId=300373304\" target=\"_blank\">0.627 solution notebook</a></li>\n</ul>",
      "rawMarkdown": "Thanks to the organizers for this fun and important competition, and congratulations to all the winners!\n\n\n## Context\n\n- __[https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/overview](https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/overview)__\n- __[https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/data](https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/data)__\n\n\n## Overview of the approach\nOur solution consisted of an nnU-Net ensemble plus post-processing.\n\n## Details of the submission\n\n### nnU-Net\nFirst, we would like to appreciate @jirkaborovec 's work! His [notebook](https://www.kaggle.com/code/jirkaborovec/surface-nnunet-training-inference-with-2xt4) served as the starting point of our training pipeline.\n\n#### Single Model Strategy\n\n- We used all available data for training and built our baseline nnU-Net model (Model 1) with the following settings:\n\n```\npatch size: 128\nbatch size: 2\nepochs: 4000\n```\n\n- We then fine-tuned Model 1 with larger patch sizes of 192 and 256, training for 250 epochs each.\n\n- Due to the extension of the competition, we trained additional models from scratch (for 4000 epochs) with patch sizes of 160, 192, and 224 to increase model diversity. Among these, the 192-patch model was included in our final ensemble.\n\n- As for the single model performance, , and two of our best single models are (due to submission quota, we only did basic post processing on single model submission for A/B tests, so full post processing may produce better results):\n\n\n| Setting | Public LB | Private LB |\n|----------|-----------|------------|\n| fine-tuned 192-patch model at 250 epochs    | 0.577     | 0.614     |\n| from-scratch 192-patch model at 4000 epochs    | 0.587     | 0.613     |\n\n#### Ensemble Strategy\n\nWe prepared two sets of 4-model ensembles as our final submissions:\n\n- **Set 1:** Baseline 128-patch Model 1 (weight: 0.12) + fine-tuned 192-patch model (0.28) + fine-tuned 256-patch model at 100 epochs (0.18) + fine-tuned 256-patch model at 250 epochs (0.42).\n- **Set 2:** Baseline 128-patch Model 1 (weight: 0.12) + fine-tuned 192-patch model (0.28) + fine-tuned 256-patch model at 250 epochs (0.18) + from-scratch 192-patch model at 4000 epochs (0.42).\n\nFor each ensemble, we fused the post-softmax probabilities using the assigned model weights and applied different thresholds and post processing methods (will be discussed in the following section).\n\n| Ensemble | Public LB | Private LB | Threshold |\n|----------|-----------|------------|-----------|\n| Set 1    | 0.613     | 0.620      | 0.20      |\n| Set 2    | 0.606     | 0.627      | 0.26      |\n\n\n\n### Post-processing\nAs discussed in many of the forum posts, minimizing holes and cavities in the predicted masks was essential for getting a good score.\nTo that end, we applied five post-processing steps:\n\n&#48;. We removed mask components that have less than 20K voxels.\n\nThen for each sheet (where a sheet is a connected-component in a predicted mask), we did the following:\n\n&#49;. Applied scipy.ndimage.binary_closing(), with a spherical footprint of radius 3. This closes holes and cavities of radius 3 or less.\n\n&#50;. Patching: To repair larger holes, we represented each sheet as a height map, and filled any gaps in the height map by linear interpolation across the gap. We did this separately along the x and y directions, and averaged the two results, weighted by distance to the nearest gap-edge. The projection axis for creating the height map was chosen to be the one that gave the largest projected sheet area. This method is capable of significant repairs: \n   \n![](https://github.com/Paul-G2/VesuviusSurfaceDetection/raw/main/PatchHoles03.jpg)\n\n&#51;. We created a simple function to plug any small (1-voxel) remaining holes. For each voxel in a given sheet, we look at it's 2 x 2 x 2 neighborhood\nand add whatever voxels are needed to make that neighborhood 6-connected watertight. For example:\n\n![](https://github.com/Paul-G2/VesuviusSurfaceDetection/raw/main/Cubes.jpg)\n\n(This method was inspired by the scikit-image euler_number() function, which uses such neighborhoods to compute the Euler number.) We don't have a proof that our function plugs all 1-voxel holes, but it seems to work well in practice. The algorithm is implemented as a lookup table, with 256 entries for the 256 possible neigborhoods. To create the lookup table, we used a very high tech scotch-tape-and-paper model to visualize all the cases:\n\n![](https://github.com/Paul-G2/VesuviusSurfaceDetection/raw/main/PaperCubes1.jpg)\n\n(Ordinary dilation will also plug holes, but it tends to add too many voxels, which can degrade the dice score.)\n\n&#52;. Finally,  we called scipy.ndimage.binary_fill_holes() on the whole mask, which fills arbitrary-size cavities.\n\nOur best version of this post-processing pipeline also included a check of the number of holes before and after patching, because the patching can actually introduce small holes, for example when the sheet is very curved. In such cases we discard the patch. \n\nThe following table shows the cumulative effect of each post-processing step on our best nnU-Net ensemble:\n\n| Step | Public Score | Private Score |\n|-------|--------------|---------------|\n| No post-proc | .572 | .596 |\n| Remove small components | .586 | .614 |\n| Plug small holes | .598 | .622 |\n| Patch large holes | .601 | .625 |\n| Binary closing | .606 | .627 |\n| Fill_holes | .606 | .627 |\n\n\n## What didn't work\nUnfortunately, we did not find an effective solution to the problem of touching sheets. We just relied on nnu-Net to minimize their occurrence.\n\n## What we misled by public LB\n\n- logits fusion performs better on private LB, but we trusted (overfitted) on probability fusion\n- larger threshold (Like 0.35-0.4 is the best searched value on our model on training set) performs better on private LB\n\n## How Vibe Coding helps\n\nInitially, our ensemble pipeline got resources issues (GPU memory, hard disk space, ...) even with 2 models ensemble, ChatGPT helps us redesign the pipeline, and enables 4 models ensemble.\n\n## Sources\n\n- __[https://www.kaggle.com/code/jirkaborovec/surface-nnunet-training-inference-with-2xt4](https://www.kaggle.com/code/jirkaborovec/surface-nnunet-training-inference-with-2xt4)__\n- [0.627 solution notebook](https://www.kaggle.com/code/tonylica/nnunet-4-model-7-5-2-1-final-submit-so-long?scriptVersionId=300373304)",
      "votes": 66
    },
    {
      "id": 3415033,
      "postDate": "2026-02-28T04:49:09.127Z",
      "content": "<p>Nice work guys, I would love to see any code you have on post processing. Looks like for us we had a really solid setup but we had basically 0 post processing. Anything I could learn about how you found it and what you used would be great. I feel like I tried lots of things that many are describing but it didn’t improve score</p>",
      "rawMarkdown": "Nice work guys, I would love to see any code you have on post processing. Looks like for us we had a really solid setup but we had basically 0 post processing. Anything I could learn about how you found it and what you used would be great. I feel like I tried lots of things that many are describing but it didn’t improve score",
      "votes": 3,
      "replies": [
        {
          "id": 3415120,
          "postDate": "2026-02-28T07:45:56.360Z",
          "content": "<p>Shared our solution: <a href=\"https://www.kaggle.com/code/tonylica/nnunet-4-model-7-5-2-1-final-submit-so-long?scriptVersionId=300373304\" target=\"_blank\">https://www.kaggle.com/code/tonylica/nnunet-4-model-7-5-2-1-final-submit-so-long?scriptVersionId=300373304</a></p>",
          "rawMarkdown": "Shared our solution: https://www.kaggle.com/code/tonylica/nnunet-4-model-7-5-2-1-final-submit-so-long?scriptVersionId=300373304",
          "votes": 2
        }
      ]
    },
    {
      "id": 3415068,
      "postDate": "2026-02-28T05:56:12.190Z",
      "content": "<p>Congrats for all <a href=\"https://www.kaggle.com/yiheng\" target=\"_blank\">@yiheng</a> , <a href=\"https://www.kaggle.com/tonylica\" target=\"_blank\">@tonylica</a> . Rank1 in both public and private. You really worth it! 🥳</p>\n<p>But It's so sad for us to read this posts. We found that more epochs works better before the first update, and that's why we placed top1 for a long time before the first update. But After the first update and before the second update, this trick does not work. So we just throw it away. We just didn't try it after the second update. Sooooo Sad 😭</p>",
      "rawMarkdown": "Congrats for all @yiheng , @tonylica . Rank1 in both public and private. You really worth it! 🥳\n\nBut It's so sad for us to read this posts. We found that more epochs works better before the first update, and that's why we placed top1 for a long time before the first update. But After the first update and before the second update, this trick does not work. So we just throw it away. We just didn't try it after the second update. Sooooo Sad 😭",
      "votes": 4,
      "replies": [
        {
          "id": 3415115,
          "postDate": "2026-02-28T07:34:58.493Z",
          "content": "<p>Hi <a href=\"https://www.kaggle.com/forcewithme\" target=\"_blank\">@forcewithme</a> , as for the long epochs trick, yes it's really helpful. We found the following tricks: long epochs + small batch size performs better than less epochs + large batch size.\nRegret that you missed a gold medal, but I do think you are a role model within our Chinese Kagglers ❤️</p>",
          "rawMarkdown": "Hi @forcewithme , as for the long epochs trick, yes it's really helpful. We found the following tricks: long epochs + small batch size performs better than less epochs + large batch size.\nRegret that you missed a gold medal, but I do think you are a role model within our Chinese Kagglers ❤️",
          "votes": 4,
          "replies": [
            {
              "id": 3415386,
              "postDate": "2026-02-28T20:16:18.067Z",
              "content": "<p>Congratulations! May I ask why you chose to set the epoch of the nnUNet model to 4000？Initially, I set the epoch to 500, and the public score was only 0.533. When adjusting the epoch to 1000, the score was 0.537, which only increased by 0.004. I think it consumes a lot of kaggle GPU but benefits very little. By setting the TransUNet epoch to 500, the public score can reach 0.555. Eventually, I gave up the nnUNet model.</p>",
              "rawMarkdown": "Congratulations! May I ask why you chose to set the epoch of the nnUNet model to 4000？Initially, I set the epoch to 500, and the public score was only 0.533. When adjusting the epoch to 1000, the score was 0.537, which only increased by 0.004. I think it consumes a lot of kaggle GPU but benefits very little. By setting the TransUNet epoch to 500, the public score can reach 0.555. Eventually, I gave up the nnUNet model.",
              "votes": 1
            }
          ]
        },
        {
          "id": 3415116,
          "postDate": "2026-02-28T07:35:14.307Z",
          "content": "<p>Yeaah, the models started overfitting as soon as 120-30 epochs.</p>",
          "rawMarkdown": "Yeaah, the models started overfitting as soon as 120-30 epochs.",
          "votes": 1
        }
      ]
    },
    {
      "id": 3417006,
      "postDate": "2026-03-04T10:04:06.530Z",
      "content": "<p>Hey, can you share your train/val curves while training?\nWhat things let you decide, that this needs to train for 100, 250 even 4000 epochs. which is a large number.\nAnd yes congrats to the whole team.</p>",
      "rawMarkdown": "Hey, can you share your train/val curves while training?\nWhat things let you decide, that this needs to train for 100, 250 even 4000 epochs. which is a large number.\nAnd yes congrats to the whole team.",
      "votes": 1,
      "replies": [
        {
          "id": 3417203,
          "postDate": "2026-03-04T20:44:04.407Z",
          "content": "<p>Thanks!</p>\n<p>Here's a training graph from one of our 4000-epoch runs, but runs with a smaller number of epochs all had a similar shape. That up-surge at the end of the graph made it impossible to resist increasing the number of epochs even further!  <a href=\"https://www.kaggle.com/sugupoko\" target=\"_blank\">@sugupoko</a> posted a <a href=\"https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/discussion/679371\" target=\"_blank\">very nice discussion</a> about why more epochs improve the score.</p>\n<p><img src=\"https://raw.githubusercontent.com/Paul-G2/VesuviusSurfaceDetection/refs/heads/main/progress4k-1.jpg\" alt=\"\"></p>",
          "rawMarkdown": "Thanks!\n\nHere's a training graph from one of our 4000-epoch runs, but runs with a smaller number of epochs all had a similar shape. That up-surge at the end of the graph made it impossible to resist increasing the number of epochs even further!  @sugupoko posted a [very nice discussion](https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/discussion/679371) about why more epochs improve the score.\n\n![](https://raw.githubusercontent.com/Paul-G2/VesuviusSurfaceDetection/refs/heads/main/progress4k-1.jpg)",
          "votes": 3,
          "replies": [
            {
              "id": 3417479,
              "postDate": "2026-03-05T13:45:10.323Z",
              "content": "<p>Impressive. I'll try it</p>",
              "rawMarkdown": "Impressive. I'll try it"
            },
            {
              "id": 3420965,
              "postDate": "2026-03-14T10:25:21.940Z",
              "content": "<p><a href=\"https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/discussion/681341\" target=\"_blank\">https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/discussion/681341</a></p>",
              "rawMarkdown": "https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/discussion/681341",
              "votes": 1
            },
            {
              "id": 3426737,
              "postDate": "2026-03-23T06:19:55.233Z",
              "content": "<p>thanks for sharing</p>",
              "rawMarkdown": "thanks for sharing"
            }
          ]
        }
      ]
    },
    {
      "id": 3415762,
      "postDate": "2026-03-01T09:21:12.487Z",
      "content": "<p>Congrats for the great achievement! 🥳</p>\n<p>Do you feel that your silver bullet has been the heightmap based post processing?</p>",
      "rawMarkdown": "Congrats for the great achievement! 🥳\n\nDo you feel that your silver bullet has been the heightmap based post processing?",
      "votes": 1,
      "replies": [
        {
          "id": 3415869,
          "postDate": "2026-03-01T14:15:01.227Z",
          "content": "<p>Thanks!</p>\n<p>The heightmap code targets large holes and, although it's really satisfying to see those big holes disappear, it doesn't lead to much of a score improvement, unfortunately.\nThe reason is that there aren't very many holes like that, and their area, as a fraction of the total area of all the sheets in a volume, is usually small.</p>",
          "rawMarkdown": "Thanks!\n\nThe heightmap code targets large holes and, although it's really satisfying to see those big holes disappear, it doesn't lead to much of a score improvement, unfortunately.\nThe reason is that there aren't very many holes like that, and their area, as a fraction of the total area of all the sheets in a volume, is usually small.",
          "votes": 3
        }
      ]
    },
    {
      "id": 3415077,
      "postDate": "2026-02-28T06:08:18.500Z",
      "content": "<p>Our notebook link is broken means its not yet to be shared? </p>",
      "rawMarkdown": "Our notebook link is broken means its not yet to be shared? ",
      "votes": 1,
      "replies": [
        {
          "id": 3415121,
          "postDate": "2026-02-28T07:46:17.783Z",
          "content": "<p>Thanks for point it out, we public it. Could you re-check?</p>",
          "rawMarkdown": "Thanks for point it out, we public it. Could you re-check?",
          "votes": 1,
          "replies": [
            {
              "id": 3415329,
              "postDate": "2026-02-28T17:33:54.273Z",
              "content": "<p>works now,  thanks.</p>",
              "rawMarkdown": "works now,  thanks."
            }
          ]
        }
      ]
    },
    {
      "id": 3415044,
      "postDate": "2026-02-28T05:08:25.683Z",
      "content": "<p>Great job, team! Congratulations! I've been reading through a few other top solutions and noticed that nnU-Net is used very frequently. I'm quite surprised why nnU-Net is the go-to choice for this problem. Have SOTA backbones like DINOv3 been benchmarked/compared against it yet?</p>",
      "rawMarkdown": "Great job, team! Congratulations! I've been reading through a few other top solutions and noticed that nnU-Net is used very frequently. I'm quite surprised why nnU-Net is the go-to choice for this problem. Have SOTA backbones like DINOv3 been benchmarked/compared against it yet?",
      "votes": 1,
      "replies": [
        {
          "id": 3415046,
          "postDate": "2026-02-28T05:13:28.223Z",
          "content": "<p>other frameworks like MONAI, and public code shared JAX pipelines perform worse than nnUNet under same training time, therefore we focus on nnUNet</p>",
          "rawMarkdown": "other frameworks like MONAI, and public code shared JAX pipelines perform worse than nnUNet under same training time, therefore we focus on nnUNet",
          "votes": 3
        }
      ]
    },
    {
      "id": 3415000,
      "postDate": "2026-02-28T03:36:19.740Z",
      "content": "<p>great solution thanks for sharing and congrats on the win!</p>\n<p>looking at how you close holes I just realized my mistakes\nregarding touching sheets problem this really gets me back to my proposed solution I discussed in my write up which I didn't complete due to time constraints, this is a qoute in case someone doesn't have the energy so go the write up which I understand given that am now awake for like 30 hours</p>\n<blockquote>\n  <p>also I had an idea in the last 3 days were I though about an algorithm that looks at the volume from top where it sees the upper edges of the papers and then go down from slice to slice, if 2 lines/components that are slightly parallel combined into a single one then it is a wrong merge and it add a small cut, they should be parallel and not close to each other tips or else that is just the end of a hole/tunnel in a sheet that merge again, unfortunately I didn't have enough time to try and refine it specially that we had other experiments to try, but I thought that it was worth mentioning this is a simple clauded sample of the code which probably have problems and buggy</p>\n</blockquote>\n<p>I really want to see someone smart trying to work with this and see how it goes</p>",
      "rawMarkdown": "great solution thanks for sharing and congrats on the win!\n\nlooking at how you close holes I just realized my mistakes\nregarding touching sheets problem this really gets me back to my proposed solution I discussed in my write up which I didn't complete due to time constraints, this is a qoute in case someone doesn't have the energy so go the write up which I understand given that am now awake for like 30 hours\n\n> also I had an idea in the last 3 days were I though about an algorithm that looks at the volume from top where it sees the upper edges of the papers and then go down from slice to slice, if 2 lines/components that are slightly parallel combined into a single one then it is a wrong merge and it add a small cut, they should be parallel and not close to each other tips or else that is just the end of a hole/tunnel in a sheet that merge again, unfortunately I didn't have enough time to try and refine it specially that we had other experiments to try, but I thought that it was worth mentioning this is a simple clauded sample of the code which probably have problems and buggy\n\n\nI really want to see someone smart trying to work with this and see how it goes",
      "votes": 1
    },
    {
      "id": 3415534,
      "postDate": "2026-03-01T01:21:36.600Z",
      "content": "<p>Congrats guys great work! I love the blocks. Also great to see some familiar faces here from the discord! </p>",
      "rawMarkdown": "Congrats guys great work! I love the blocks. Also great to see some familiar faces here from the discord! ",
      "votes": 2,
      "replies": [
        {
          "id": 3417708,
          "postDate": "2026-03-06T01:14:36.403Z",
          "rawMarkdown": "",
          "isDeleted": true
        }
      ]
    },
    {
      "id": 3464061,
      "postDate": "2026-05-28T17:42:45.760Z",
      "content": "<p>**nice work guys **</p>",
      "rawMarkdown": "**nice work guys **"
    },
    {
      "id": 3416404,
      "postDate": "2026-03-02T19:08:30.890Z",
      "content": "<p>Congrats to the team on the win! Do you know how much your post processing improved your Public/Private scores?</p>",
      "rawMarkdown": "Congrats to the team on the win! Do you know how much your post processing improved your Public/Private scores?",
      "replies": [
        {
          "id": 3416432,
          "postDate": "2026-03-02T21:21:50.790Z",
          "content": "<p>That's a great question. I am curious about it too, so I'll do some runs with all post-processing turned off, and then with the post-processing steps turned on one-by-one. I'll post the results here when I have them. </p>",
          "rawMarkdown": "That's a great question. I am curious about it too, so I'll do some runs with all post-processing turned off, and then with the post-processing steps turned on one-by-one. I'll post the results here when I have them. ",
          "votes": 3,
          "replies": [
            {
              "id": 3416717,
              "postDate": "2026-03-03T14:50:14.983Z",
              "content": "<p>I added a table near the end of the write-up. Thanks for the suggestion!</p>",
              "rawMarkdown": "I added a table near the end of the write-up. Thanks for the suggestion!",
              "votes": 3
            }
          ]
        }
      ]
    },
    {
      "id": 3416356,
      "postDate": "2026-03-02T17:10:36.547Z",
      "content": "<p>1st congratulations on getting first positione in competition and creating a real world problem solving solution with us with great and detail understanding of information </p>",
      "rawMarkdown": "1st congratulations on getting first positione in competition and creating a real world problem solving solution with us with great and detail understanding of information "
    },
    {
      "id": 3416008,
      "postDate": "2026-03-01T19:48:27.627Z",
      "content": "<p>Big congrats to <a href=\"https://www.kaggle.com/yiheng\" target=\"_blank\">@yiheng</a>, <a href=\"https://www.kaggle.com/tonylica\" target=\"_blank\">@tonylica</a> for dominating both the public and private leaderboards - Rank 1 in both is seriously impressive!🥳</p>",
      "rawMarkdown": "Big congrats to @yiheng, @tonylica for dominating both the public and private leaderboards - Rank 1 in both is seriously impressive!🥳"
    },
    {
      "id": 3415650,
      "postDate": "2026-03-01T04:38:14.930Z",
      "content": "<p>Congratualtions, Winning Team. You did a great job.\nCan you please make the dataset you used public now?</p>",
      "rawMarkdown": "Congratualtions, Winning Team. You did a great job.\nCan you please make the dataset you used public now?"
    },
    {
      "id": 3415024,
      "postDate": "2026-02-28T04:33:57.653Z",
      "content": "<p>what is the contribution of threshold tuning?</p>",
      "rawMarkdown": "what is the contribution of threshold tuning?",
      "replies": [
        {
          "id": 3415049,
          "postDate": "2026-02-28T05:19:10.383Z",
          "content": "<p>Impact is much less than post processing, like 1e-3 level. Since we don't have validation set, changing thresholds is just a way we choose to make full use of submission quota</p>",
          "rawMarkdown": "Impact is much less than post processing, like 1e-3 level. Since we don't have validation set, changing thresholds is just a way we choose to make full use of submission quota",
          "votes": 1,
          "replies": [
            {
              "id": 3415128,
              "postDate": "2026-02-28T08:07:18.833Z",
              "content": "<p>add one more comment: it's a place that can be enhanced (updated the writeup). Larger thresholds like 0.35-0.4 perform better on local search &amp; and private LB, but worse on public LB. We overfitted on this part.</p>",
              "rawMarkdown": "add one more comment: it's a place that can be enhanced (updated the writeup). Larger thresholds like 0.35-0.4 perform better on local search & and private LB, but worse on public LB. We overfitted on this part.",
              "votes": 1
            }
          ]
        }
      ]
    }
  ],
  "comments": [
    {
      "id": 3415033,
      "author_name": "Cody_Null",
      "author_url": "",
      "post_date": "2026-02-28T04:49:09.127000",
      "content": "<p>Nice work guys, I would love to see any code you have on post processing. Looks like for us we had a really solid setup but we had basically 0 post processing. Anything I could learn about how you found it and what you used would be great. I feel like I tried lots of things that many are describing but it didn’t improve score</p>",
      "votes": 3,
      "replies": [
        {
          "id": 3415120,
          "author_name": "Yiheng Wang",
          "author_url": "",
          "post_date": "2026-02-28T07:45:56.360000",
          "content": "<p>Shared our solution: <a href=\"https://www.kaggle.com/code/tonylica/nnunet-4-model-7-5-2-1-final-submit-so-long?scriptVersionId=300373304\" target=\"_blank\">https://www.kaggle.com/code/tonylica/nnunet-4-model-7-5-2-1-final-submit-so-long?scriptVersionId=300373304</a></p>",
          "votes": 2,
          "replies": []
        }
      ]
    },
    {
      "id": 3415068,
      "author_name": "ForcewithMe",
      "author_url": "",
      "post_date": "2026-02-28T05:56:12.190000",
      "content": "<p>Congrats for all <a href=\"https://www.kaggle.com/yiheng\" target=\"_blank\">@yiheng</a> , <a href=\"https://www.kaggle.com/tonylica\" target=\"_blank\">@tonylica</a> . Rank1 in both public and private. You really worth it! 🥳</p>\n<p>But It's so sad for us to read this posts. We found that more epochs works better before the first update, and that's why we placed top1 for a long time before the first update. But After the first update and before the second update, this trick does not work. So we just throw it away. We just didn't try it after the second update. Sooooo Sad 😭</p>",
      "votes": 4,
      "replies": [
        {
          "id": 3415115,
          "author_name": "Yiheng Wang",
          "author_url": "",
          "post_date": "2026-02-28T07:34:58.493000",
          "content": "<p>Hi <a href=\"https://www.kaggle.com/forcewithme\" target=\"_blank\">@forcewithme</a> , as for the long epochs trick, yes it's really helpful. We found the following tricks: long epochs + small batch size performs better than less epochs + large batch size.\nRegret that you missed a gold medal, but I do think you are a role model within our Chinese Kagglers ❤️</p>",
          "votes": 4,
          "replies": [
            {
              "id": 3415386,
              "author_name": "Adam",
              "author_url": "",
              "post_date": "2026-02-28T20:16:18.067000",
              "content": "<p>Congratulations! May I ask why you chose to set the epoch of the nnUNet model to 4000？Initially, I set the epoch to 500, and the public score was only 0.533. When adjusting the epoch to 1000, the score was 0.537, which only increased by 0.004. I think it consumes a lot of kaggle GPU but benefits very little. By setting the TransUNet epoch to 500, the public score can reach 0.555. Eventually, I gave up the nnUNet model.</p>",
              "votes": 1,
              "replies": []
            }
          ]
        },
        {
          "id": 3415116,
          "author_name": "Manas Choudhary",
          "author_url": "",
          "post_date": "2026-02-28T07:35:14.307000",
          "content": "<p>Yeaah, the models started overfitting as soon as 120-30 epochs.</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 3417006,
      "author_name": "Arpit1Bansal",
      "author_url": "",
      "post_date": "2026-03-04T10:04:06.530000",
      "content": "<p>Hey, can you share your train/val curves while training?\nWhat things let you decide, that this needs to train for 100, 250 even 4000 epochs. which is a large number.\nAnd yes congrats to the whole team.</p>",
      "votes": 1,
      "replies": [
        {
          "id": 3417203,
          "author_name": "PaulG",
          "author_url": "",
          "post_date": "2026-03-04T20:44:04.407000",
          "content": "<p>Thanks!</p>\n<p>Here's a training graph from one of our 4000-epoch runs, but runs with a smaller number of epochs all had a similar shape. That up-surge at the end of the graph made it impossible to resist increasing the number of epochs even further!  <a href=\"https://www.kaggle.com/sugupoko\" target=\"_blank\">@sugupoko</a> posted a <a href=\"https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/discussion/679371\" target=\"_blank\">very nice discussion</a> about why more epochs improve the score.</p>\n<p><img src=\"https://raw.githubusercontent.com/Paul-G2/VesuviusSurfaceDetection/refs/heads/main/progress4k-1.jpg\" alt=\"\"></p>",
          "votes": 3,
          "replies": [
            {
              "id": 3417479,
              "author_name": "GG Ayo (AyoGG)",
              "author_url": "",
              "post_date": "2026-03-05T13:45:10.323000",
              "content": "<p>Impressive. I'll try it</p>",
              "votes": 0,
              "replies": []
            },
            {
              "id": 3420965,
              "author_name": "GG Ayo (AyoGG)",
              "author_url": "",
              "post_date": "2026-03-14T10:25:21.940000",
              "content": "<p><a href=\"https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/discussion/681341\" target=\"_blank\">https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/discussion/681341</a></p>",
              "votes": 1,
              "replies": []
            },
            {
              "id": 3426737,
              "author_name": "Arpit1Bansal",
              "author_url": "",
              "post_date": "2026-03-23T06:19:55.233000",
              "content": "<p>thanks for sharing</p>",
              "votes": 0,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 3415762,
      "author_name": "Giorgio Angelotti",
      "author_url": "",
      "post_date": "2026-03-01T09:21:12.487000",
      "content": "<p>Congrats for the great achievement! 🥳</p>\n<p>Do you feel that your silver bullet has been the heightmap based post processing?</p>",
      "votes": 1,
      "replies": [
        {
          "id": 3415869,
          "author_name": "PaulG",
          "author_url": "",
          "post_date": "2026-03-01T14:15:01.227000",
          "content": "<p>Thanks!</p>\n<p>The heightmap code targets large holes and, although it's really satisfying to see those big holes disappear, it doesn't lead to much of a score improvement, unfortunately.\nThe reason is that there aren't very many holes like that, and their area, as a fraction of the total area of all the sheets in a volume, is usually small.</p>",
          "votes": 3,
          "replies": []
        }
      ]
    },
    {
      "id": 3415077,
      "author_name": "Maapu",
      "author_url": "",
      "post_date": "2026-02-28T06:08:18.500000",
      "content": "<p>Our notebook link is broken means its not yet to be shared? </p>",
      "votes": 1,
      "replies": [
        {
          "id": 3415121,
          "author_name": "Yiheng Wang",
          "author_url": "",
          "post_date": "2026-02-28T07:46:17.783000",
          "content": "<p>Thanks for point it out, we public it. Could you re-check?</p>",
          "votes": 1,
          "replies": [
            {
              "id": 3415329,
              "author_name": "Maapu",
              "author_url": "",
              "post_date": "2026-02-28T17:33:54.273000",
              "content": "<p>works now,  thanks.</p>",
              "votes": 0,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 3415044,
      "author_name": "Quan Vu",
      "author_url": "",
      "post_date": "2026-02-28T05:08:25.683000",
      "content": "<p>Great job, team! Congratulations! I've been reading through a few other top solutions and noticed that nnU-Net is used very frequently. I'm quite surprised why nnU-Net is the go-to choice for this problem. Have SOTA backbones like DINOv3 been benchmarked/compared against it yet?</p>",
      "votes": 1,
      "replies": [
        {
          "id": 3415046,
          "author_name": "Yiheng Wang",
          "author_url": "",
          "post_date": "2026-02-28T05:13:28.223000",
          "content": "<p>other frameworks like MONAI, and public code shared JAX pipelines perform worse than nnUNet under same training time, therefore we focus on nnUNet</p>",
          "votes": 3,
          "replies": []
        }
      ]
    },
    {
      "id": 3415000,
      "author_name": "Taha_Alshatiri",
      "author_url": "",
      "post_date": "2026-02-28T03:36:19.740000",
      "content": "<p>great solution thanks for sharing and congrats on the win!</p>\n<p>looking at how you close holes I just realized my mistakes\nregarding touching sheets problem this really gets me back to my proposed solution I discussed in my write up which I didn't complete due to time constraints, this is a qoute in case someone doesn't have the energy so go the write up which I understand given that am now awake for like 30 hours</p>\n<blockquote>\n  <p>also I had an idea in the last 3 days were I though about an algorithm that looks at the volume from top where it sees the upper edges of the papers and then go down from slice to slice, if 2 lines/components that are slightly parallel combined into a single one then it is a wrong merge and it add a small cut, they should be parallel and not close to each other tips or else that is just the end of a hole/tunnel in a sheet that merge again, unfortunately I didn't have enough time to try and refine it specially that we had other experiments to try, but I thought that it was worth mentioning this is a simple clauded sample of the code which probably have problems and buggy</p>\n</blockquote>\n<p>I really want to see someone smart trying to work with this and see how it goes</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 3415534,
      "author_name": "Sean Johnson_SP",
      "author_url": "",
      "post_date": "2026-03-01T01:21:36.600000",
      "content": "<p>Congrats guys great work! I love the blocks. Also great to see some familiar faces here from the discord! </p>",
      "votes": 2,
      "replies": [
        {
          "id": 3417708,
          "author_name": "",
          "author_url": "",
          "post_date": "2026-03-06T01:14:36.403000",
          "content": "",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 3464061,
      "author_name": "saifeddinelakhadar",
      "author_url": "",
      "post_date": "2026-05-28T17:42:45.760000",
      "content": "<p>**nice work guys **</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 3416404,
      "author_name": "Bartley",
      "author_url": "",
      "post_date": "2026-03-02T19:08:30.890000",
      "content": "<p>Congrats to the team on the win! Do you know how much your post processing improved your Public/Private scores?</p>",
      "votes": 0,
      "replies": [
        {
          "id": 3416432,
          "author_name": "PaulG",
          "author_url": "",
          "post_date": "2026-03-02T21:21:50.790000",
          "content": "<p>That's a great question. I am curious about it too, so I'll do some runs with all post-processing turned off, and then with the post-processing steps turned on one-by-one. I'll post the results here when I have them. </p>",
          "votes": 3,
          "replies": [
            {
              "id": 3416717,
              "author_name": "PaulG",
              "author_url": "",
              "post_date": "2026-03-03T14:50:14.983000",
              "content": "<p>I added a table near the end of the write-up. Thanks for the suggestion!</p>",
              "votes": 3,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 3416356,
      "author_name": "Wasiq Ali",
      "author_url": "",
      "post_date": "2026-03-02T17:10:36.547000",
      "content": "<p>1st congratulations on getting first positione in competition and creating a real world problem solving solution with us with great and detail understanding of information </p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 3416008,
      "author_name": "Durga Kumari",
      "author_url": "",
      "post_date": "2026-03-01T19:48:27.627000",
      "content": "<p>Big congrats to <a href=\"https://www.kaggle.com/yiheng\" target=\"_blank\">@yiheng</a>, <a href=\"https://www.kaggle.com/tonylica\" target=\"_blank\">@tonylica</a> for dominating both the public and private leaderboards - Rank 1 in both is seriously impressive!🥳</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 3415650,
      "author_name": "Abdulmuiz Abdullateef",
      "author_url": "",
      "post_date": "2026-03-01T04:38:14.930000",
      "content": "<p>Congratualtions, Winning Team. You did a great job.\nCan you please make the dataset you used public now?</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 3415024,
      "author_name": "artineon",
      "author_url": "",
      "post_date": "2026-02-28T04:33:57.653000",
      "content": "<p>what is the contribution of threshold tuning?</p>",
      "votes": 0,
      "replies": [
        {
          "id": 3415049,
          "author_name": "Yiheng Wang",
          "author_url": "",
          "post_date": "2026-02-28T05:19:10.383000",
          "content": "<p>Impact is much less than post processing, like 1e-3 level. Since we don't have validation set, changing thresholds is just a way we choose to make full use of submission quota</p>",
          "votes": 1,
          "replies": [
            {
              "id": 3415128,
              "author_name": "Yiheng Wang",
              "author_url": "",
              "post_date": "2026-02-28T08:07:18.833000",
              "content": "<p>add one more comment: it's a place that can be enhanced (updated the writeup). Larger thresholds like 0.35-0.4 perform better on local search &amp; and private LB, but worse on public LB. We overfitted on this part.</p>",
              "votes": 1,
              "replies": []
            }
          ]
        }
      ]
    }
  ],
  "raw_markdown_by_id": {
    "3414991": "Thanks to the organizers for this fun and important competition, and congratulations to all the winners!\n\n\n## Context\n\n- __[https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/overview](https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/overview)__\n- __[https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/data](https://www.kaggle.com/competitions/vesuvius-challenge-surface-detection/data)__\n\n\n## Overview of the approach\nOur solution consisted of an nnU-Net ensemble plus post-processing.\n\n## Details of the submission\n\n### nnU-Net\nFirst, we would like to appreciate @jirkaborovec 's work! His [notebook](https://www.kaggle.com/code/jirkaborovec/surface-nnunet-training-inference-with-2xt4) served as the starting point of our training pipeline.\n\n#### Single Model Strategy\n\n- We used all available data for training and built our baseline nnU-Net model (Model 1) with the following settings:\n\n```\npatch size: 128\nbatch size: 2\nepochs: 4000\n```\n\n- We then fine-tuned Model 1 with larger patch sizes of 192 and 256, training for 250 epochs each.\n\n- Due to the extension of the competition, we trained additional models from scratch (for 4000 epochs) with patch sizes of 160, 192, and 224 to increase model diversity. Among these, the 192-patch model was included in our final ensemble.\n\n- As for the single model performance, , and two of our best single models are (due to submission quota, we only did basic post processing on single model submission for A/B tests, so full post processing may produce better results):\n\n\n| Setting | Public LB | Private LB |\n|----------|-----------|------------|\n| fine-tuned 192-patch model at 250 epochs    | 0.577     | 0.614     |\n| from-scratch 192-patch model at 4000 epochs    | 0.587     | 0.613     |\n\n#### Ensemble Strategy\n\nWe prepared two sets of 4-model ensembles as our final submissions:\n\n- **Set 1:** Baseline 128-patch Model 1 (weight: 0.12) + fine-tuned 192-patch model (0.28) + fine-tuned 256-patch model at 100 epochs (0.18) + fine-tuned 256-patch model at 250 epochs (0.42).\n- **Set 2:** Baseline 128-patch Model 1 (weight: 0.12) + fine-tuned 192-patch model (0.28) + fine-tuned 256-patch model at 250 epochs (0.18) + from-scratch 192-patch model at 4000 epochs (0.42).\n\nFor each ensemble, we fused the post-softmax probabilities using the assigned model weights and applied different thresholds and post processing methods (will be discussed in the following section).\n\n| Ensemble | Public LB | Private LB | Threshold |\n|----------|-----------|------------|-----------|\n| Set 1    | 0.613     | 0.620      | 0.20      |\n| Set 2    | 0.606     | 0.627      | 0.26      |\n\n\n\n### Post-processing\nAs discussed in many of the forum posts, minimizing holes and cavities in the predicted masks was essential for getting a good score.\nTo that end, we applied five post-processing steps:\n\n&#48;. We removed mask components that have less than 20K voxels.\n\nThen for each sheet (where a sheet is a connected-component in a predicted mask), we did the following:\n\n&#49;. Applied scipy.ndimage.binary_closing(), with a spherical footprint of radius 3. This closes holes and cavities of radius 3 or less.\n\n&#50;. Patching: To repair larger holes, we represented each sheet as a height map, and filled any gaps in the height map by linear interpolation across the gap. We did this separately along the x and y directions, and averaged the two results, weighted by distance to the nearest gap-edge. The projection axis for creating the height map was chosen to be the one that gave the largest projected sheet area. This method is capable of significant repairs: \n   \n![](https://github.com/Paul-G2/VesuviusSurfaceDetection/raw/main/PatchHoles03.jpg)\n\n&#51;. We created a simple function to plug any small (1-voxel) remaining holes. For each voxel in a given sheet, we look at it's 2 x 2 x 2 neighborhood\nand add whatever voxels are needed to make that neighborhood 6-connected watertight. For example:\n\n![](https://github.com/Paul-G2/VesuviusSurfaceDetection/raw/main/Cubes.jpg)\n\n(This method was inspired by the scikit-image euler_number() function, which uses such neighborhoods to compute the Euler number.) We don't have a proof that our function plugs all 1-voxel holes, but it seems to work well in practice. The algorithm is implemented as a lookup table, with 256 entries for the 256 possible neigborhoods. To create the lookup table, we used a very high tech scotch-tape-and-paper model to visualize all the cases:\n\n![](https://github.com/Paul-G2/VesuviusSurfaceDetection/raw/main/PaperCubes1.jpg)\n\n(Ordinary dilation will also plug holes, but it tends to add too many voxels, which can degrade the dice score.)\n\n&#52;. Finally,  we called scipy.ndimage.binary_fill_holes() on the whole mask, which fills arbitrary-size cavities.\n\nOur best version of this post-processing pipeline also included a check of the number of holes before and after patching, because the patching can actually introduce small holes, for example when the sheet is very curved. In such cases we discard the patch. \n\nThe following table shows the cumulative effect of each post-processing step on our best nnU-Net ensemble:\n\n| Step | Public Score | Private Score |\n|-------|--------------|---------------|\n| No post-proc | .572 | .596 |\n| Remove small components | .586 | .614 |\n| Plug small holes | .598 | .622 |\n| Patch large holes | .601 | .625 |\n| Binary closing | .606 | .627 |\n| Fill_holes | .606 | .627 |\n\n\n## What didn't work\nUnfortunately, we did not find an effective solution to the problem of touching sheets. We just relied on nnu-Net to minimize their occurrence.\n\n## What we misled by public LB\n\n- logits fusion performs better on private LB, but we trusted (overfitted) on probability fusion\n- larger threshold (Like 0.35-0.4 is the best searched value on our model on training set) performs better on private LB\n\n## How Vibe Coding helps\n\nInitially, our ensemble pipeline got resources issues (GPU memory, hard disk space, ...) even with 2 models ensemble, ChatGPT helps us redesign the pipeline, and enables 4 models ensemble.\n\n## Sources\n\n- __[https://www.kaggle.com/code/jirkaborovec/surface-nnunet-training-inference-with-2xt4](https://www.kaggle.com/code/jirkaborovec/surface-nnunet-training-inference-with-2xt4)__\n- [0.627 solution notebook](https://www.kaggle.com/code/tonylica/nnunet-4-model-7-5-2-1-final-submit-so-long?scriptVersionId=300373304)",
    "3415033": "Nice work guys, I would love to see any code you have on post processing. Looks like for us we had a really solid setup but we had basically 0 post processing. Anything I could learn about how you found it and what you used would be great. I feel like I tried lots of things that many are describing but it didn’t improve score",
    "3415068": "Congrats for all @yiheng , @tonylica . Rank1 in both public and private. You really worth it! 🥳\n\nBut It's so sad for us to read this posts. We found that more epochs works better before the first update, and that's why we placed top1 for a long time before the first update. But After the first update and before the second update, this trick does not work. So we just throw it away. We just didn't try it after the second update. Sooooo Sad 😭",
    "3417006": "Hey, can you share your train/val curves while training?\nWhat things let you decide, that this needs to train for 100, 250 even 4000 epochs. which is a large number.\nAnd yes congrats to the whole team.",
    "3415762": "Congrats for the great achievement! 🥳\n\nDo you feel that your silver bullet has been the heightmap based post processing?",
    "3415077": "Our notebook link is broken means its not yet to be shared? ",
    "3415044": "Great job, team! Congratulations! I've been reading through a few other top solutions and noticed that nnU-Net is used very frequently. I'm quite surprised why nnU-Net is the go-to choice for this problem. Have SOTA backbones like DINOv3 been benchmarked/compared against it yet?",
    "3415000": "great solution thanks for sharing and congrats on the win!\n\nlooking at how you close holes I just realized my mistakes\nregarding touching sheets problem this really gets me back to my proposed solution I discussed in my write up which I didn't complete due to time constraints, this is a qoute in case someone doesn't have the energy so go the write up which I understand given that am now awake for like 30 hours\n\n> also I had an idea in the last 3 days were I though about an algorithm that looks at the volume from top where it sees the upper edges of the papers and then go down from slice to slice, if 2 lines/components that are slightly parallel combined into a single one then it is a wrong merge and it add a small cut, they should be parallel and not close to each other tips or else that is just the end of a hole/tunnel in a sheet that merge again, unfortunately I didn't have enough time to try and refine it specially that we had other experiments to try, but I thought that it was worth mentioning this is a simple clauded sample of the code which probably have problems and buggy\n\n\nI really want to see someone smart trying to work with this and see how it goes",
    "3415534": "Congrats guys great work! I love the blocks. Also great to see some familiar faces here from the discord! ",
    "3464061": "**nice work guys **",
    "3416404": "Congrats to the team on the win! Do you know how much your post processing improved your Public/Private scores?",
    "3416356": "1st congratulations on getting first positione in competition and creating a real world problem solving solution with us with great and detail understanding of information ",
    "3416008": "Big congrats to @yiheng, @tonylica for dominating both the public and private leaderboards - Rank 1 in both is seriously impressive!🥳",
    "3415650": "Congratualtions, Winning Team. You did a great job.\nCan you please make the dataset you used public now?",
    "3415024": "what is the contribution of threshold tuning?"
  }
}