{
  "id": 670730,
  "title": "SegFormer  + Depth Pro -> DinoV3Base w/Lora -> Learned Fusion module",
  "url": "/competitions/csiro-biomass/writeups/segformer-depth-pro-dinov3base-wlora-lea",
  "author_name": "",
  "post_date": "2026-01-29T11:39:02.903Z",
  "votes": 6,
  "comment_count": 2,
  "views": 0,
  "content": "<h1>Pasture Biomass Estimation: Solution Write-Up</h1>\n<h2>Summary</h2>\n<p>This solution treats pasture biomass estimation as a multi-modal fusion problem rather than a straightforward image regression task. The pipeline combines foundation models for visual understanding with physically constrained predictions and evolutionary optimisation for post-processing.</p>\n<p>The core insight is that predicting biomass components separately and then summing them yields more accurate results than predicting total biomass directly. This approach enforces mathematical consistency whilst allowing the model to learn distinct patterns for each vegetation type.</p>\n<h2>Key Ideas</h2>\n<h3>Multi-Modal Feature Engineering</h3>\n<p>For each image, we extract 18 auxiliary features that capture biological and structural properties beyond what raw pixels can convey.</p>\n<p><strong>Semantic Segmentation</strong> uses a fine-tuned SegFormer-b2 to classify every pixel into one of five categories: soil, clover, grass, weeds, or dead matter. From these masks we calculate coverage ratios for each class.</p>\n<p><strong>Depth Estimation</strong> leverages Depth Pro to generate metric depth maps. We estimate camera height by taking the median depth of soil pixels, then derive canopy height as the difference between camera height and pixel depth. This allows us to compute volume metrics for each vegetation component.</p>\n<p><strong>Texture Features</strong> help distinguish visual greenness from actual dense biomass. We calculate Shannon entropy of the green channel to capture leaf complexity. Shadow ratio serves as a proxy for canopy depth. Height distribution skewness provides additional structural information.</p>\n<h3>Architecture</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F11034213%2Faed5442975d28a41c54a40de847ebcb9%2FMermaid%20Chart%20-%20Create%20complex%20visual%20diagrams%20with%20text.-2026-01-29-113708.png?generation=1769686658772408&amp;alt=media\" alt=\"\"></p>\n<p>The model uses DINOv3 ViT-Base as its backbone with LoRA adaptation (rank 32). This allows fine-tuning without destroying pre-trained weights or risking overfitting on our limited dataset.</p>\n<p>The 2000×1000 input images are split into two 1000×1000 halves. Each half is resized to 518×518 and processed independently through the backbone.</p>\n<p>A learned fusion module projects image features and auxiliary features into a common 512-dimensional space. LayerNorm and GELU activation are applied before combining them into a unified representation.</p>\n<p><strong>Component Prediction</strong> is central to this approach. Rather than predicting total biomass directly, we use separate heads for dry green mass, dry dead mass, and dry clover mass. Total biomass is derived by summing these components, which enforces physical consistency.</p>\n<h3>Training</h3>\n<p>We employ a high-biomass weighted loss function to address the saturation effect where models tend to under-predict dense canopies. Sample weights scale linearly with true biomass: a 100g sample contributes three times more to the loss than a 0g sample.</p>\n<p>Component losses use MSE for green and clover predictions. Huber loss handles dead matter to provide robustness against outliers. We also compute a derived loss on the sum of predictions against true total biomass, applied in log space.</p>\n<p>Training used AdamW with a learning rate of 1e-4 and mixed precision. We trained on the full dataset for 50 epochs to maximise learning from all available samples.</p>\n<h3>Inference and Post-Processing</h3>\n<p>Test-time augmentation uses the original image plus a horizontal flip. We tested 4× TTA but found 2× offered the best balance of accuracy and speed.</p>\n<p><strong>Evolutionary Optimisation</strong> via differential evolution found optimal post-processing parameters to maximise a weighted R² score. The final rules apply bias corrections to each component. Conditional interactions correct for occlusion effects and prediction artefacts. Saturation scaling boosts predictions when derived total exceeds 80g.</p>\n<p>Specific corrections include adding 3.54g to green predictions and subtracting 4.38g from clover predictions. When predicted clover exceeds about 15.6g, we add roughly 1.9g to green to account for occlusion. High green predictions trigger a reduction in dead matter to correct for hallucination effects.</p>\n<h2>What Worked</h2>\n<ul>\n<li>Predicting components separately rather than total biomass directly</li>\n<li>LoRA adaptation of the foundation model backbone</li>\n<li>High-biomass weighted loss to counter saturation effects</li>\n<li>Depth-derived volume features as auxiliary inputs</li>\n<li>Evolutionary search for post-processing parameters</li>\n</ul>\n<h2>What Didn't Work</h2>\n<ul>\n<li>4× TTA provided marginal gains that didn't justify the computational cost</li>\n<li>Direct total biomass prediction struggled with component consistency</li>\n<li>Simple concatenation fusion underperformed the learned fusion module</li>\n</ul>\n<p>It would have been interesting to see how using a larger backbone would impact the results.</p>",
  "messages": [
    {
      "id": "3398605",
      "postDate": "01/29/2026 11:38:52",
      "content": "<h1>Pasture Biomass Estimation: Solution Write-Up</h1>\n<h2>Summary</h2>\n<p>This solution treats pasture biomass estimation as a multi-modal fusion problem rather than a straightforward image regression task. The pipeline combines foundation models for visual understanding with physically constrained predictions and evolutionary optimisation for post-processing.</p>\n<p>The core insight is that predicting biomass components separately and then summing them yields more accurate results than predicting total biomass directly. This approach enforces mathematical consistency whilst allowing the model to learn distinct patterns for each vegetation type.</p>\n<h2>Key Ideas</h2>\n<h3>Multi-Modal Feature Engineering</h3>\n<p>For each image, we extract 18 auxiliary features that capture biological and structural properties beyond what raw pixels can convey.</p>\n<p><strong>Semantic Segmentation</strong> uses a fine-tuned SegFormer-b2 to classify every pixel into one of five categories: soil, clover, grass, weeds, or dead matter. From these masks we calculate coverage ratios for each class.</p>\n<p><strong>Depth Estimation</strong> leverages Depth Pro to generate metric depth maps. We estimate camera height by taking the median depth of soil pixels, then derive canopy height as the difference between camera height and pixel depth. This allows us to compute volume metrics for each vegetation component.</p>\n<p><strong>Texture Features</strong> help distinguish visual greenness from actual dense biomass. We calculate Shannon entropy of the green channel to capture leaf complexity. Shadow ratio serves as a proxy for canopy depth. Height distribution skewness provides additional structural information.</p>\n<h3>Architecture</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F11034213%2Faed5442975d28a41c54a40de847ebcb9%2FMermaid%20Chart%20-%20Create%20complex%20visual%20diagrams%20with%20text.-2026-01-29-113708.png?generation=1769686658772408&amp;alt=media\" alt=\"\"></p>\n<p>The model uses DINOv3 ViT-Base as its backbone with LoRA adaptation (rank 32). This allows fine-tuning without destroying pre-trained weights or risking overfitting on our limited dataset.</p>\n<p>The 2000×1000 input images are split into two 1000×1000 halves. Each half is resized to 518×518 and processed independently through the backbone.</p>\n<p>A learned fusion module projects image features and auxiliary features into a common 512-dimensional space. LayerNorm and GELU activation are applied before combining them into a unified representation.</p>\n<p><strong>Component Prediction</strong> is central to this approach. Rather than predicting total biomass directly, we use separate heads for dry green mass, dry dead mass, and dry clover mass. Total biomass is derived by summing these components, which enforces physical consistency.</p>\n<h3>Training</h3>\n<p>We employ a high-biomass weighted loss function to address the saturation effect where models tend to under-predict dense canopies. Sample weights scale linearly with true biomass: a 100g sample contributes three times more to the loss than a 0g sample.</p>\n<p>Component losses use MSE for green and clover predictions. Huber loss handles dead matter to provide robustness against outliers. We also compute a derived loss on the sum of predictions against true total biomass, applied in log space.</p>\n<p>Training used AdamW with a learning rate of 1e-4 and mixed precision. We trained on the full dataset for 50 epochs to maximise learning from all available samples.</p>\n<h3>Inference and Post-Processing</h3>\n<p>Test-time augmentation uses the original image plus a horizontal flip. We tested 4× TTA but found 2× offered the best balance of accuracy and speed.</p>\n<p><strong>Evolutionary Optimisation</strong> via differential evolution found optimal post-processing parameters to maximise a weighted R² score. The final rules apply bias corrections to each component. Conditional interactions correct for occlusion effects and prediction artefacts. Saturation scaling boosts predictions when derived total exceeds 80g.</p>\n<p>Specific corrections include adding 3.54g to green predictions and subtracting 4.38g from clover predictions. When predicted clover exceeds about 15.6g, we add roughly 1.9g to green to account for occlusion. High green predictions trigger a reduction in dead matter to correct for hallucination effects.</p>\n<h2>What Worked</h2>\n<ul>\n<li>Predicting components separately rather than total biomass directly</li>\n<li>LoRA adaptation of the foundation model backbone</li>\n<li>High-biomass weighted loss to counter saturation effects</li>\n<li>Depth-derived volume features as auxiliary inputs</li>\n<li>Evolutionary search for post-processing parameters</li>\n</ul>\n<h2>What Didn't Work</h2>\n<ul>\n<li>4× TTA provided marginal gains that didn't justify the computational cost</li>\n<li>Direct total biomass prediction struggled with component consistency</li>\n<li>Simple concatenation fusion underperformed the learned fusion module</li>\n</ul>\n<p>It would have been interesting to see how using a larger backbone would impact the results.</p>",
      "rawMarkdown": "# Pasture Biomass Estimation: Solution Write-Up\n\n## Summary\n\nThis solution treats pasture biomass estimation as a multi-modal fusion problem rather than a straightforward image regression task. The pipeline combines foundation models for visual understanding with physically constrained predictions and evolutionary optimisation for post-processing.\n\nThe core insight is that predicting biomass components separately and then summing them yields more accurate results than predicting total biomass directly. This approach enforces mathematical consistency whilst allowing the model to learn distinct patterns for each vegetation type.\n\n## Key Ideas\n\n### Multi-Modal Feature Engineering\n\nFor each image, we extract 18 auxiliary features that capture biological and structural properties beyond what raw pixels can convey.\n\n**Semantic Segmentation** uses a fine-tuned SegFormer-b2 to classify every pixel into one of five categories: soil, clover, grass, weeds, or dead matter. From these masks we calculate coverage ratios for each class.\n\n**Depth Estimation** leverages Depth Pro to generate metric depth maps. We estimate camera height by taking the median depth of soil pixels, then derive canopy height as the difference between camera height and pixel depth. This allows us to compute volume metrics for each vegetation component.\n\n**Texture Features** help distinguish visual greenness from actual dense biomass. We calculate Shannon entropy of the green channel to capture leaf complexity. Shadow ratio serves as a proxy for canopy depth. Height distribution skewness provides additional structural information.\n\n### Architecture\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F11034213%2Faed5442975d28a41c54a40de847ebcb9%2FMermaid%20Chart%20-%20Create%20complex%20visual%20diagrams%20with%20text.-2026-01-29-113708.png?generation=1769686658772408&alt=media)\n\n\nThe model uses DINOv3 ViT-Base as its backbone with LoRA adaptation (rank 32). This allows fine-tuning without destroying pre-trained weights or risking overfitting on our limited dataset.\n\nThe 2000×1000 input images are split into two 1000×1000 halves. Each half is resized to 518×518 and processed independently through the backbone.\n\nA learned fusion module projects image features and auxiliary features into a common 512-dimensional space. LayerNorm and GELU activation are applied before combining them into a unified representation.\n\n**Component Prediction** is central to this approach. Rather than predicting total biomass directly, we use separate heads for dry green mass, dry dead mass, and dry clover mass. Total biomass is derived by summing these components, which enforces physical consistency.\n\n### Training\n\nWe employ a high-biomass weighted loss function to address the saturation effect where models tend to under-predict dense canopies. Sample weights scale linearly with true biomass: a 100g sample contributes three times more to the loss than a 0g sample.\n\nComponent losses use MSE for green and clover predictions. Huber loss handles dead matter to provide robustness against outliers. We also compute a derived loss on the sum of predictions against true total biomass, applied in log space.\n\nTraining used AdamW with a learning rate of 1e-4 and mixed precision. We trained on the full dataset for 50 epochs to maximise learning from all available samples.\n\n### Inference and Post-Processing\n\nTest-time augmentation uses the original image plus a horizontal flip. We tested 4× TTA but found 2× offered the best balance of accuracy and speed.\n\n**Evolutionary Optimisation** via differential evolution found optimal post-processing parameters to maximise a weighted R² score. The final rules apply bias corrections to each component. Conditional interactions correct for occlusion effects and prediction artefacts. Saturation scaling boosts predictions when derived total exceeds 80g.\n\nSpecific corrections include adding 3.54g to green predictions and subtracting 4.38g from clover predictions. When predicted clover exceeds about 15.6g, we add roughly 1.9g to green to account for occlusion. High green predictions trigger a reduction in dead matter to correct for hallucination effects.\n\n## What Worked\n\n- Predicting components separately rather than total biomass directly\n- LoRA adaptation of the foundation model backbone\n- High-biomass weighted loss to counter saturation effects\n- Depth-derived volume features as auxiliary inputs\n- Evolutionary search for post-processing parameters\n\n## What Didn't Work\n\n- 4× TTA provided marginal gains that didn't justify the computational cost\n- Direct total biomass prediction struggled with component consistency\n- Simple concatenation fusion underperformed the learned fusion module\n\nIt would have been interesting to see how using a larger backbone would impact the results.",
      "votes": null
    },
    {
      "id": "3409250",
      "postDate": "02/22/2026 13:28:42",
      "content": "<p>Interesting write-up! Could you share your code, please?</p>",
      "rawMarkdown": "Interesting write-up! Could you share your code, please?",
      "votes": null
    },
    {
      "id": "3424055",
      "postDate": "03/19/2026 09:58:23",
      "content": "<p>Apologies for the late reply. Here’s the link to the inference however I do not have the training code anymore. <a href=\"https://www.kaggle.com/code/joshuaburnsblack/csiro-final-submission\" target=\"_blank\">https://www.kaggle.com/code/joshuaburnsblack/csiro-final-submission</a></p>",
      "rawMarkdown": "Apologies for the late reply. Here’s the link to the inference however I do not have the training code anymore. https://www.kaggle.com/code/joshuaburnsblack/csiro-final-submission",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 3409250,
      "author_name": "nacefmbarek",
      "author_url": "",
      "post_date": "02/22/2026 13:28:42",
      "content": "<p>Interesting write-up! Could you share your code, please?</p>",
      "votes": null,
      "replies": [
        {
          "id": 3424055,
          "author_name": "joshuaburnsblack",
          "author_url": "",
          "post_date": "03/19/2026 09:58:23",
          "content": "<p>Apologies for the late reply. Here’s the link to the inference however I do not have the training code anymore. <a href=\"https://www.kaggle.com/code/joshuaburnsblack/csiro-final-submission\" target=\"_blank\">https://www.kaggle.com/code/joshuaburnsblack/csiro-final-submission</a></p>",
          "votes": null,
          "replies": []
        }
      ]
    }
  ],
  "raw_markdown_by_id": {
    "3398605": "# Pasture Biomass Estimation: Solution Write-Up\n\n## Summary\n\nThis solution treats pasture biomass estimation as a multi-modal fusion problem rather than a straightforward image regression task. The pipeline combines foundation models for visual understanding with physically constrained predictions and evolutionary optimisation for post-processing.\n\nThe core insight is that predicting biomass components separately and then summing them yields more accurate results than predicting total biomass directly. This approach enforces mathematical consistency whilst allowing the model to learn distinct patterns for each vegetation type.\n\n## Key Ideas\n\n### Multi-Modal Feature Engineering\n\nFor each image, we extract 18 auxiliary features that capture biological and structural properties beyond what raw pixels can convey.\n\n**Semantic Segmentation** uses a fine-tuned SegFormer-b2 to classify every pixel into one of five categories: soil, clover, grass, weeds, or dead matter. From these masks we calculate coverage ratios for each class.\n\n**Depth Estimation** leverages Depth Pro to generate metric depth maps. We estimate camera height by taking the median depth of soil pixels, then derive canopy height as the difference between camera height and pixel depth. This allows us to compute volume metrics for each vegetation component.\n\n**Texture Features** help distinguish visual greenness from actual dense biomass. We calculate Shannon entropy of the green channel to capture leaf complexity. Shadow ratio serves as a proxy for canopy depth. Height distribution skewness provides additional structural information.\n\n### Architecture\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F11034213%2Faed5442975d28a41c54a40de847ebcb9%2FMermaid%20Chart%20-%20Create%20complex%20visual%20diagrams%20with%20text.-2026-01-29-113708.png?generation=1769686658772408&alt=media)\n\n\nThe model uses DINOv3 ViT-Base as its backbone with LoRA adaptation (rank 32). This allows fine-tuning without destroying pre-trained weights or risking overfitting on our limited dataset.\n\nThe 2000×1000 input images are split into two 1000×1000 halves. Each half is resized to 518×518 and processed independently through the backbone.\n\nA learned fusion module projects image features and auxiliary features into a common 512-dimensional space. LayerNorm and GELU activation are applied before combining them into a unified representation.\n\n**Component Prediction** is central to this approach. Rather than predicting total biomass directly, we use separate heads for dry green mass, dry dead mass, and dry clover mass. Total biomass is derived by summing these components, which enforces physical consistency.\n\n### Training\n\nWe employ a high-biomass weighted loss function to address the saturation effect where models tend to under-predict dense canopies. Sample weights scale linearly with true biomass: a 100g sample contributes three times more to the loss than a 0g sample.\n\nComponent losses use MSE for green and clover predictions. Huber loss handles dead matter to provide robustness against outliers. We also compute a derived loss on the sum of predictions against true total biomass, applied in log space.\n\nTraining used AdamW with a learning rate of 1e-4 and mixed precision. We trained on the full dataset for 50 epochs to maximise learning from all available samples.\n\n### Inference and Post-Processing\n\nTest-time augmentation uses the original image plus a horizontal flip. We tested 4× TTA but found 2× offered the best balance of accuracy and speed.\n\n**Evolutionary Optimisation** via differential evolution found optimal post-processing parameters to maximise a weighted R² score. The final rules apply bias corrections to each component. Conditional interactions correct for occlusion effects and prediction artefacts. Saturation scaling boosts predictions when derived total exceeds 80g.\n\nSpecific corrections include adding 3.54g to green predictions and subtracting 4.38g from clover predictions. When predicted clover exceeds about 15.6g, we add roughly 1.9g to green to account for occlusion. High green predictions trigger a reduction in dead matter to correct for hallucination effects.\n\n## What Worked\n\n- Predicting components separately rather than total biomass directly\n- LoRA adaptation of the foundation model backbone\n- High-biomass weighted loss to counter saturation effects\n- Depth-derived volume features as auxiliary inputs\n- Evolutionary search for post-processing parameters\n\n## What Didn't Work\n\n- 4× TTA provided marginal gains that didn't justify the computational cost\n- Direct total biomass prediction struggled with component consistency\n- Simple concatenation fusion underperformed the learned fusion module\n\nIt would have been interesting to see how using a larger backbone would impact the results.",
    "3409250": "Interesting write-up! Could you share your code, please?",
    "3424055": "Apologies for the late reply. Here’s the link to the inference however I do not have the training code anymore. https://www.kaggle.com/code/joshuaburnsblack/csiro-final-submission"
  },
  "source": "meta"
}