|
45 | 45 |
|
46 | 46 | # Simple LSTM model |
47 | 47 | class LSTMModel(torch.nn.Module, PyTorchModelHubMixin): |
48 | | - def __init__(self, layers=2, hidden_dim=128, input_dim=26, output_dim=1): |
| 48 | + def __init__(self, layers=2, hidden_dim=128, input_dim=26, output_dim=1, **kwargs): |
49 | 49 | super().__init__() |
50 | 50 | self.lstm = torch.nn.LSTM(input_dim, hidden_dim, num_layers=layers, batch_first=True) |
51 | 51 | self.average = torch.nn.AdaptiveAvgPool1d(1) |
@@ -149,14 +149,80 @@ def train_country_lstm(country_code): |
149 | 149 | num += 1 |
150 | 150 | print(f"Test {country_code} MSE: {test_mse/num}") |
151 | 151 | print(f"Test {country_code} MAE: {test_mae/num}") |
152 | | - names = [f'{c}_' for c in country_code] |
| 152 | + names = [f'_{c}' for c in country_code] |
153 | 153 | # Join the names together |
154 | 154 | name = ''.join(names) |
155 | | - torch.save(model, f"lstm_model_{name}.pt") |
| 155 | + torch.save(model, f"lstm_model{name}.pt") |
156 | 156 | # Save the weights to huggingface |
157 | | - model.save_pretrained(f"project_resilience_lstm_model_{name}", push_to_hub=True, config=model_config) |
| 157 | + model.save_pretrained(f"project_resilience_lstm_model{name}", push_to_hub=True, config=model_config) |
158 | 158 |
|
159 | | -train_country_lstm([143, 29]) # UK and Brazil |
160 | | -train_country_lstm([143]) # UK |
161 | | -train_country_lstm([29]) # Brazil |
| 159 | +def test_no_change(country_code): |
| 160 | + if len(country_code) == 1: |
| 161 | + test_da = dataset.where(country_mask == country_code[0], drop=True).where(dataset.time > 2007, drop=True).load() |
| 162 | + #train_da = dataset.where(country_mask == country_code[0], drop=True).where(dataset.time <= 2007, drop=True).load() # 143 is the code for the UK |
| 163 | + else: |
| 164 | + c_mask = xr.DataArray(np.in1d(country_mask, country_code).reshape(country_mask.shape), |
| 165 | + dims=country_mask.dims, coords=country_mask.coords) |
| 166 | + test_da = dataset.where(c_mask, drop=True).where(dataset.time > 2007, drop=True).load() |
| 167 | + #train_da = dataset.where(c_mask, drop=True).where(dataset.time <= 2007, drop=True).load() # 143 is the code for the UK |
| 168 | + #model = LSTMModel(**model_config).to(device) |
| 169 | + model = LSTMModel.from_pretrained("jacobbieker/project_resilience_lstm_model_143_29_").to(device) |
| 170 | + crit = torch.nn.MSELoss() |
| 171 | + stat = torch.nn.L1Loss() |
| 172 | + |
| 173 | + with torch.no_grad(): |
| 174 | + model.eval() |
| 175 | + test_mse = 0.0 |
| 176 | + test_mae = 0.0 |
| 177 | + num = 0 |
| 178 | + test_times = test_da.time.values[11:] |
| 179 | + for time in test_times: |
| 180 | + for lon in range(0, len(test_da.lon.values), 10): |
| 181 | + for lat in range(0, len(test_da.lat.values), 10): |
| 182 | + example = test_da.isel(lat=slice(lat,lat+10), lon=slice(lon,lon+10)).sel(time=slice(time-10,time)) |
| 183 | + data_names = list(example.data_vars.keys()) |
| 184 | + example = xr.concat([example[var] for var in example.data_vars], dim='variable') |
| 185 | + example = example.assign_coords(variable=data_names) |
| 186 | + example = example.transpose('time', 'lat', 'lon', 'variable') |
| 187 | + target = example.sel(variable='ELUC').isel(time=8) # Set it to ELUC of step 8, which is same as ELUC for the train sample, so no change |
| 188 | + train = example.isel(time=slice(8,9)) # Select only 8, but be 4D still |
| 189 | + #assert np.isfinite(example['ELUC'].values).all() |
| 190 | + # Convert infinite values and NaN to 0.0 |
| 191 | + train = train.fillna(0.0) |
| 192 | + target = target.fillna(0.0) |
| 193 | + #exit() |
| 194 | + # Set the target to be the same as train and set all values of train other than current to the same |
| 195 | + #target = train.isel(time=8) |
| 196 | + #train = train.isel(time=8) |
| 197 | + train = np.repeat(train.values, 9, axis=0) # Copy so no changes across the 9 years of looking |
| 198 | + torch_example = torch.from_numpy(np.nan_to_num(train, posinf=0.0, neginf=0.0)) |
| 199 | + # Flatten with einops to get the shape (batch_size, time, features) |
| 200 | + torch_example = einops.rearrange(torch_example, 'time lat lon features -> (lat lon) time features') |
| 201 | + torch_target = torch.unsqueeze(torch.from_numpy(np.nan_to_num(target.values, posinf=0.0, neginf=0.0)), dim=-1) |
| 202 | + # Flatten with einops to get the shape (batch_size, time, features) |
| 203 | + torch_target = einops.rearrange(torch_target, 'lat lon features -> (lat lon) features') |
| 204 | + num += torch_target.shape[0] |
| 205 | + outputs = model(torch_example.to(device)) |
| 206 | + loss = crit(outputs.cpu(), torch_target) |
| 207 | + mae_loss = stat(outputs.cpu(), torch_target) |
| 208 | + #print(loss.item()) |
| 209 | + test_mse += loss.item() |
| 210 | + test_mae += mae_loss.item() |
| 211 | + # Already averaged, so just need to track num for time, lat, lon |
| 212 | + num += 1 |
| 213 | + print(f"Test {country_code} MSE: {test_mse/num}") |
| 214 | + print(f"Test {country_code} MAE: {test_mae/num}") |
| 215 | + #names = [f'_{c}' for c in country_code] |
| 216 | + # Join the names together |
| 217 | + #name = ''.join(names) |
| 218 | + #torch.save(model, f"lstm_model{name}.pt") |
| 219 | + # Save the weights to huggingface |
| 220 | + #model.save_pretrained(f"project_resilience_lstm_model{name}", push_to_hub=True, config=model_config) |
| 221 | + |
| 222 | + |
| 223 | +#train_country_lstm([143, 29]) # UK and India |
| 224 | +#train_country_lstm([143]) # UK |
| 225 | +#train_country_lstm([29]) # Brazil |
| 226 | +#train_country_lstm(list(range(80))) # First 80 countries |
162 | 227 | # Check ELUC when no change |
| 228 | +test_no_change([143, 29]) |
0 commit comments