WUR-AI / WUR-AI/diffWOFOST

[Backlog Item]: Build a prototype of differentiable wofost72_pp

Open
#3 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Backlog item Epic 1 scientific
Dominant language
Python
Stars
25
Forks
6
Avg merge
2d 23h
Merged PRs (30d)
1

Description

The goal is to build a working differentiable wofost72_pp, supporting gradient-based optimization. To make the entire model end-to-end differentiable, the mathematics would be:

$$
\frac{\partial \text{loss}}{\partial \text{(ML model weights)}} =
\frac{\partial \text{loss}}{\partial \text{(differentiable wofost72-pp output)}} \cdot
\frac{\partial \text{(differentiable wofost72-pp output)}}{\partial \text{(wofost72-pp parameters)}} \cdot
\frac{\partial \text{(wofost72-pp parameters)}}{\partial \text{(ML model weights)}}
$$

This approach where an ML model predicts physical parameters, which are then used in a physics-based model, and combines both in a hybrid architecture, is a state-of-the-art approach and is known under various names. See recent publication "Scientific Machine Learning". See similar works at #7 and #13.

The prototype might be:

import torch.nn as nn

# Step 1: ML model that outputs physical parameters e.g. LSTM
class MLModel(nn.Module):
    def __init__(self, input_size, hidden_size, num_physical_params):
        super().__init__()
        self.lstm = nn.LSTM(input_size=input_size, hidden_size=hidden_size, batch_first=True)
        self.linear = nn.Linear(hidden_size, num_physical_params)

    def forward(self, x):
        lstm_out, _ = self.lstm(x)              
        physical_params = self.linear(lstm_out[:, -1, :]) 
        return physical_params

# Step 2: Physical model using Euler integration
class PhysicalModel(nn.Module):
    def __init__(self, dt):
        super().__init__()

    def forward(self, params):
        wofost = Wofost72_PP(params, ...) # this is differentiable version
        wofost.run_till_terminate()
        output = wofost.get_output()
        return output

# Step 3: Hybrid model integrating ML and physical model
class HybridModel(nn.Module):
    def __init__(self, input_size, hidden_size, num_physical_params):
        super().__init__()
        self.ml_model = MLModel(input_size, hidden_size, num_physical_params)
        self.physical_model = PhysicalModel()

    def forward(self, x):
        physical_params = self.ml_model(x)
        output = self.physical_model(physical_params)
        return output, physical_params

Regarding this structure, add your comments/suggestions below.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the current WOFOST72_PP implementation and reviewing the related work in issues #7 and #13. Define the prototype’s differentiability and optimization acceptance criteria before attempting the end-to-end design; this issue names no target files or tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, pytorch
Domain
machine-learning
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.