| """ |
| NB: this script is for illustration purposes only and is not runnable as our |
| full dataset is not provided as part of the submission due to size constraints. |
| Many of the relevant paths to the data have been thus replaced by dummy paths. |
| """ |
|
|
| import argparse |
| import pickle |
|
|
| import numpy as np |
| import pandas as pd |
| from tqdm import tqdm |
| import torch |
| import torch.nn as nn |
| import torch.utils.data.distributed |
| from torch.utils.data import DataLoader |
|
|
| from loader import WeatherDatasetAssimilation |
| from models import * |
|
|
| torch.set_float32_matmul_precision("medium") |
|
|
|
|
| def unnorm(x, mean, std, diff=False, av_2019=None): |
|
|
| x = x * std + mean |
| if diff: |
| return x + av_2019.transpose(0, 3, 2, 1) |
| return x |
|
|
|
|
| if __name__ == "__main__": |
|
|
| """ |
| Generate encoder predictions to be used as finetuning data for the processor module |
| """ |
|
|
| parser = argparse.ArgumentParser() |
| parser.add_argument("--encoder_model_path") |
| args = parser.parse_args() |
|
|
| |
| with open(args.encoder_model_path + "/config.pkl", "rb") as handle: |
| forecast_config = pickle.load(handle) |
|
|
| device = "cuda" |
|
|
| |
| era5_mean_spatial = None |
| means = np.load( |
| "aux_data_path/norm_factors/mean_{}_{}.npy".format( |
| forecast_config["era5_mode"], forecast_config["res"] |
| ) |
| )[np.newaxis, np.newaxis, np.newaxis, :] |
| stds = np.load( |
| "aux_data_path/norm_factors/std_{}_{}.npy".format( |
| forecast_config["era5_mode"], forecast_config["res"] |
| ) |
| )[np.newaxis, np.newaxis, np.newaxis, :] |
|
|
| |
| labels = ["train", "test", "val"] |
| dates = [ |
| ["2007-01-02", "2017-12-31"], |
| ["2018-01-01", "2018-12-31"], |
| ["2019-01-01", "2019-12-31"], |
| ] |
|
|
| |
| for label, date in zip(labels, dates): |
|
|
| n_times = pd.date_range(date[0], date[1], freq="6H") |
|
|
| |
| ic = np.memmap( |
| "{}/ic_{}.mmap".format(args.encoder_model_path, label), |
| dtype="float32", |
| mode="w+", |
| shape=(len(n_times), 121, 240, 24), |
| ) |
|
|
| var_group_preds = [] |
| var_group_targets = [] |
|
|
| |
| dataset = WeatherDatasetAssimilation( |
| device="cuda", |
| hadisd_mode="train", |
| start_date=date[0], |
| end_date=date[1], |
| lead_time=0, |
| era5_mode="4u", |
| res=1, |
| var_start=0, |
| var_end=24, |
| diff=False, |
| ) |
|
|
| loader = DataLoader(dataset, batch_size=64, shuffle=False) |
|
|
| |
| model = ConvCNPWeather( |
| in_channels=forecast_config["in_channels"], |
| out_channels=forecast_config["out_channels"], |
| int_channels=forecast_config["int_channels"], |
| device="cuda", |
| res=forecast_config["res"], |
| gnp=bool(0), |
| decoder=forecast_config["decoder"], |
| mode=forecast_config["mode"], |
| film=bool(0), |
| ) |
|
|
| best_epoch = np.argmin( |
| np.load("{}/losses_0.npy".format(args.encoder_model_path)) |
| ) |
| state_dict = torch.load( |
| "{}/epoch_{}".format(args.encoder_model_path, best_epoch), |
| map_location=device, |
| )["model_state_dict"] |
| state_dict = {k[7:]: v for k, v in zip(state_dict.keys(), state_dict.values())} |
| model.load_state_dict(state_dict) |
| model = nn.DataParallel(model) |
| model = model.cuda() |
|
|
| model.eval() |
|
|
| |
| total = [] |
| target = [] |
|
|
| sum_count = 0 |
| with torch.no_grad(): |
| with tqdm(loader, unit="batch") as tepoch: |
| for count, batch in enumerate(tepoch): |
|
|
| out = model(batch, film_index=batch["lt"]).detach().cpu().numpy() |
|
|
| out_unnorm = unnorm( |
| out, |
| means, |
| stds, |
| diff=False, |
| av_2019=era5_mean_spatial, |
| ) |
|
|
| ic[sum_count : sum_count + out.shape[0], ...] = out_unnorm |
| sum_count += out.shape[0] |
|
|