Exploring the different model variants and their architectural details
The Climate-PINN combines neural network components with physics-based constraints to create a model that respects fluid dynamics while making accurate predictions.
The overall architecture of the Climate-PINN model
CNN-based encoder that processes meteorological input variables:
Uses convolutional layers with non-linear activations to extract spatial features.
Processes geographical constraints:
Helps the model understand how geography affects climate patterns.
Handles coordinate information:
Enables the model to understand spatial and temporal relationships.
Integrates features from all encoders:
What makes Climate-PINN unique is its incorporation of fluid dynamics principles from the Navier-Stokes equations directly into the learning process.
Ensures conservation of mass in the fluid flow.
Govern the conservation of momentum in x and y directions.
The model learns an appropriate Reynolds number to balance inertial and viscous forces.
The total loss combines traditional data-driven loss with physics constraint residuals:
Where $L_{physics}$ includes residuals from continuity and momentum equations:
physics_loss = {
'e1': self.MSE(e1, torch.zeros_like(e1)), # Continuity equation
'e2': self.MSE(e2, torch.zeros_like(e2)), # x-momentum
'e3': self.MSE(e3, torch.zeros_like(e3)) # y-momentum
}
The repository includes several model variants with progressive improvements.
The original baseline model with basic architecture.
Improved handling of the Reynolds number parameter with gradient clipping and momentum.
def get_reynolds_number(self):
clamped_log_re = torch.clamp(self.log_re,
min=torch.log(torch.tensor(50.0, device=self.device)),
max=torch.log(torch.tensor(1e5, device=self.device)))
current_re = torch.exp(clamped_log_re)
if self.previous_re is None:
self.previous_re = current_re
smoothed_re = self.re_momentum * self.previous_re + (1 - self.re_momentum) * current_re
self.previous_re = smoothed_re.detach()
return smoothed_re
Introduction of dropout layers for improved generalization.
Note: This model has suboptimal dropout placement which was corrected in Model 2.
Significant architectural improvements including residual connections and proper dropout placement.
class ResBlock(torch.nn.Module):
def __init__(self, in_channel):
super().__init__()
self.conv_block = torch.nn.Sequential(
torch.nn.Conv2d(in_channels=in_channel,
out_channels=in_channel,
kernel_size=3,
stride=1,
padding='same'),
torch.nn.BatchNorm2d(in_channel),
torch.nn.ReLU(),
torch.nn.Conv2d(in_channels=in_channel,
out_channels=in_channel,
kernel_size=3,
stride=1,
padding='same'),
torch.nn.BatchNorm2d(in_channel)
)
self.act = torch.nn.ReLU()
def forward(self, input):
out = self.conv_block(input)
out += input
out = self.act(out)
return out
Advanced model with a dedicated neural network for estimating the Reynolds number.
class ReynoldsNetwork(nn.Module):
def __init__(self, hidden_dim=16):
super().__init__()
self.re_net = nn.Sequential(
nn.Conv2d(2, hidden_dim, kernel_size=3, padding=1),
nn.ReLU(),
nn.Conv2d(hidden_dim, hidden_dim, kernel_size=3, padding=1),
nn.ReLU(),
nn.Dropout(p=0.2),
nn.Conv2d(hidden_dim, 1, kernel_size=3, padding=1),
nn.Sigmoid() # Ensure positive output
)
def forward(self, u, v):
inputs = torch.stack([u, v], dim=1)
re = self.re_net(inputs)
# Scale output to a reasonable range for Reynolds number
re = re * (1e5 - 50.0) + 50.0
return re
Comparison of different model variants across metrics:
Model | Train | Val | Test | Average |
---|---|---|---|---|
model_0 | 0.0017 | 0.0017 | 0.0017 | 0.0017 |
model_1 | 0.0063 | 0.0063 | 0.0080 | 0.0069 |
model_0_Re | 9.42e-04 | 9.62e-04 | 0.0016 | 0.0012 |
model_2 | 5.89e-04 | 6.51e-04 | 0.0012 | 8.22e-04 |
model_3 | 6.08e-04 | 6.57e-04 | 0.0013 | 8.48e-04 |
Model | Train | Val | Test | Average |
---|---|---|---|---|
model_0 | 5.56e-07 | 5.83e-07 | 6.69e-07 | 6.03e-07 |
model_1 | 1.22e-07 | 1.79e-07 | 1.43e-07 | 1.48e-07 |
model_0_Re | 6.08e-05 | 6.59e-05 | 6.11e-05 | 6.26e-05 |
model_2 | 3.29e-06 | 2.70e-06 | 3.51e-06 | 3.17e-06 |
model_3 | 5.04e-06 | 3.72e-06 | 5.50e-06 | 4.75e-06 |
Model | Train | Val | Test | Average |
---|---|---|---|---|
model_0 | 0.0017 | 0.0017 | 0.0017 | 0.0017 |
model_1 | 0.0063 | 0.0063 | 0.0080 | 0.0069 |
model_0_Re | 0.0010 | 0.0010 | 0.0017 | 0.0012 |
model_2 | 5.92e-04 | 6.54e-04 | 0.0012 | 8.25e-04 |
model_3 | 6.13e-04 | 6.61e-04 | 0.0013 | 8.53e-04 |
MSE comparison across models
Physics constraint loss comparison
Model 2 demonstrates the best overall performance with the lowest MSE and total loss across all datasets, while Model 0 shows the lowest physics constraint violations. This suggests that Model 2 offers the best balance between data prediction accuracy and physics-informed constraints.
Pretrained weights for all model variants are available on Hugging Face:
All models are trained on 10 years of ERA5 data with balanced physics and data loss weights.