Skip to content

[Backlog Item]: Build a prototype of differentiable wofost72_pp #3

@SarahAlidoost

Description

@SarahAlidoost

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Backlog itemA collection of tasksEpic 1Optimizing parameters in Wofost72_PP using pytorchscientificThis needs scientific solutions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions