Skip to content

Commit 908dec4

Browse files
JubekuMatKbauerJulian Kuehnert
authored
Jk/develop/gamma decay (ecmwf#998)
* Update to develop, prepare for new experiment series * gamma decay over fsteps first commit * add gamma decay factor to config * working gamma decay weighting * rm breakpoint * rm eval and plot configs * reverting default config --------- Co-authored-by: Matthias Karlbauer <matthias.karlbauer@ecmwf.int> Co-authored-by: Julian Kuehnert <julian.kuehnert@ecwmf.int>
1 parent d0e103e commit 908dec4

2 files changed

Lines changed: 21 additions & 2 deletions

File tree

src/weathergen/train/loss.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,9 @@ def mse_channel_location_weighted(
147147
def cosine_latitude(stream_data, forecast_offset, fstep, min_value=1e-3, max_value=1.0):
148148
latitudes_radian = stream_data.target_coords_raw[forecast_offset + fstep][:, 0] * np.pi / 180
149149
return (max_value - min_value) * np.cos(latitudes_radian) + min_value
150+
151+
152+
def gamma_decay(forecast_steps, gamma):
153+
fsteps = np.arange(forecast_steps)
154+
weights = gamma**fsteps
155+
return weights * (len(fsteps) / np.sum(weights))

src/weathergen/train/loss_calculator.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,13 @@ def _get_weights(self, stream_info):
107107

108108
return stream_info_loss_weight, weights_channels
109109

110+
def _get_fstep_weights(self, forecast_steps):
111+
timestep_weight_config = self.cf.get("timestep_weight")
112+
if timestep_weight_config is None:
113+
return [1.0 for _ in range(forecast_steps)]
114+
weights_timestep_fct = getattr(losses, timestep_weight_config[0])
115+
return weights_timestep_fct(forecast_steps, timestep_weight_config[1])
116+
110117
def _get_location_weights(self, stream_info, stream_data, forecast_offset, fstep):
111118
location_weight_type = stream_info.get("location_weight", None)
112119
if location_weight_type is None:
@@ -232,14 +239,18 @@ def compute_loss(
232239

233240
stream_data = streams_data[i_batch][i_stream_info]
234241

242+
fstep_loss_weights = self._get_fstep_weights(len(targets))
243+
235244
loss_fsteps = torch.tensor(0.0, device=self.device, requires_grad=True)
236245
ctr_fsteps = 0
237246
stream_is_spoof = streams_data[i_batch][i_stream_info].is_spoof
238247
if stream_is_spoof:
239248
mask = torch.tensor(0.0, device=self.device, requires_grad=False)
240249
else:
241250
mask = torch.tensor(1.0, device=self.device, requires_grad=False)
242-
for fstep, target in enumerate(targets):
251+
for fstep, (target, fstep_weight) in enumerate(
252+
zip(targets, fstep_loss_weights, strict=False)
253+
):
243254
# skip if either target or prediction has no data points
244255
pred = preds[fstep][i_stream_info]
245256
if not (target.shape[0] > 0 and pred.shape[0] > 0):
@@ -280,7 +291,9 @@ def compute_loss(
280291

281292
# Add the weighted and normalized loss from this loss function to the total
282293
# batch loss
283-
loss_fstep = loss_fstep + (loss_fct_weight * loss_lfct * stream_loss_weight)
294+
loss_fstep = loss_fstep + (
295+
loss_fct_weight * loss_lfct * stream_loss_weight * fstep_weight
296+
)
284297
ctr_loss_fcts += 1 if loss_lfct > 0.0 else 0
285298

286299
loss_fsteps = loss_fsteps + (loss_fstep / ctr_loss_fcts if ctr_loss_fcts > 0 else 0)

0 commit comments

Comments
 (0)