Skip to content

Commit 77846a9

Browse files
authored
Merge pull request #30 from Project-Resilience/jacob/lstm
Add test for no change to ELUC
2 parents 828b567 + cd69c4f commit 77846a9

1 file changed

Lines changed: 73 additions & 7 deletions

File tree

model/lstm.py

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545

4646
# Simple LSTM model
4747
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):
4949
super().__init__()
5050
self.lstm = torch.nn.LSTM(input_dim, hidden_dim, num_layers=layers, batch_first=True)
5151
self.average = torch.nn.AdaptiveAvgPool1d(1)
@@ -149,14 +149,80 @@ def train_country_lstm(country_code):
149149
num += 1
150150
print(f"Test {country_code} MSE: {test_mse/num}")
151151
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]
153153
# Join the names together
154154
name = ''.join(names)
155-
torch.save(model, f"lstm_model_{name}.pt")
155+
torch.save(model, f"lstm_model{name}.pt")
156156
# 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)
158158

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
162227
# Check ELUC when no change
228+
test_no_change([143, 29])

0 commit comments

Comments
 (0)