AIStream-Peelout / flow-forecast

Deep learning PyTorch library for time series forecasting, classification, and anomaly detection (originally for flood forecasting).
https://flow-forecast.atlassian.net/wiki/spaces/FF/overview
GNU General Public License v3.0
1.96k stars 289 forks source link

Inverted Transformer errors when only forecasting a single target (or not all) #741

Open isaacmg opened 3 months ago

isaacmg commented 3 months ago

When using the Inverted Transformer takes multiple feature columns but has only one target it results in an error in the decoding process. ERROR Run oy5tkp61 errored: RuntimeError('The expanded size of the tensor (1) must match the existing size (4) at non-singleton dimension 2. Target sizes: [1, 6, 1]. Tensor sizes [6, 4]).


---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In[5], line 4
      2 from flood_forecast.trainer import train_function 
      3 config = make_config_file("", "", "")
----> 4 final_model = train_function("PyTorch", config)

File /kaggle/working/flow-forecast/flood_forecast/trainer.py:172, in train_function(model_type, params)
    170     # TODO Move to other func
    171     if params["dataset_params"]["class"] != "GeneralClassificationLoader" and params["dataset_params"]["class"] !="VariableSequenceLength":
--> 172         handle_core_eval(trained_model, params, model_type)
    174 else:
    175     raise Exception("Please supply valid model type for forecasting or classification")

File /kaggle/working/flow-forecast/flood_forecast/trainer.py:84, in handle_core_eval(trained_model, params, model_type)
     74 def handle_core_eval(trained_model, params: Dict, model_type: str):
     75     """_summary_
     76 
     77     :param trained_model: _description_
   (...)
     82     :type model_type: str
     83     """
---> 84     test_acc = evaluate_model(
     85         trained_model,
     86         model_type,
     87         params["dataset_params"]["target_col"],
     88         params["metrics"],
     89         params["inference_params"],
     90         {})
     91     if params["dataset_params"]["class"] == "SeriesIDLoader":
     92        data = test_acc[1]

File /kaggle/working/flow-forecast/flood_forecast/evaluator.py:112, in evaluate_model(model, model_type, target_col, evaluation_metrics, inference_params, eval_log)
     87 """
     88 A function to evaluate a model. Called automatically at end of training.
     89 Can be imported for continuing to evaluate a model in other places as well.
   (...)
    101 '''
    102 """
    103 if model_type == "PyTorch":
    104     (
    105         df_train_and_test,
    106         end_tensor,
    107         forecast_history,
    108         forecast_start_idx,
    109         test_data,
    110         df_predictions,
    111         # df_prediction_samples_std_dev,
--> 112     ) = infer_on_torch_model(model, **inference_params)
    113     if model.params["dataset_params"]["class"] == "SeriesIDLoader":
    114         print(end_tensor[0].shape)

File /kaggle/working/flow-forecast/flood_forecast/evaluator.py:320, in infer_on_torch_model(model, test_csv_path, datetime_start, hours_to_forecast, decoder_params, dataset_params, num_prediction_samples, probabilistic, criterion_params)
    314 else:
    315     (
    316         history,
    317         df_train_and_test,
    318         forecast_start_idx,
    319     ) = csv_test_loader.get_from_start_date(datetime_start)
--> 320 end_tensor = generate_predictions(
    321     model,
    322     df_train_and_test,
    323     csv_test_loader,
    324     history,
    325     device,
    326     forecast_start_idx,
    327     forecast_length,
    328     hours_to_forecast,
    329     decoder_params,
    330     multi_params=multi_params,
    331     targs=targ
    332 )
    333 return handle_later_ev(model, df_train_and_test, end_tensor, model.params, csv_test_loader, multi_params,
    334                        forecast_start_idx, history, datetime_start)

File /kaggle/working/flow-forecast/flood_forecast/evaluator.py:541, in generate_predictions(model, df, test_data, history, device, forecast_start_idx, forecast_length, hours_to_forecast, decoder_params, targs, multi_params)
    531     end_tensor = generate_predictions_non_decoded(
    532         model, df, test_data, history_dim, forecast_length, hours_to_forecast,
    533     )
    534 else:
    535     # model, src, max_seq_len, real_target, output_len=1, unsqueeze_dim=1
    536     # hours_to_forecast 336
   (...)
    539     # real_target:torch.Tensor, start_symbol:torch.Tensor
    540     # unsqueeze_dim=1, device='cpu')
--> 541     end_tensor = generate_decoded_predictions(
    542         model,
    543         test_data,
    544         forecast_start_idx,
    545         device,
    546         history_dim,
    547         hours_to_forecast,
    548         decoder_params,
    549         multi_targets=multi_params,
    550         targs=targs
    551     )
    552 return end_tensor

File /kaggle/working/flow-forecast/flood_forecast/evaluator.py:656, in generate_decoded_predictions(model, test_data, forecast_start_idx, device, history_dim, hours_to_forecast, decoder_params, multi_targets, targs)
    654     else:
    655         decoder_seq_len = model.params["model_params"]["label_len"]
--> 656     end_tensor = decoding_function(model.model, src0, trg[1], model.params["dataset_params"]["forecast_length"],
    657                                    src[1], trg[0], 1, decoder_seq_len, hours_to_forecast, device)
    658 else:
    659     end_tensor = decoding_functions[decoder_params["decoder_function"]](
    660         model.model,
    661         history_dim,
   (...)
    669         scaler=scaler
    670     )

File /kaggle/working/flow-forecast/flood_forecast/temporal_decoding.py:63, in decoding_function(model, src, trg, forecast_length, src_temp, tar_temp, unknown_cols_st, decoder_seq_len, max_len, device)
     61 out = model(src, src_temp, filled_target, tar_temp[:, i:i + residual, :])
     62 residual1 = forecast_length if i + forecast_length <= max_len else max_len % forecast_length
---> 63 out1[:, i: i + residual1, :n_target] = out[:, -residual1:, :]
     64 # Need better variable names
     65 filled_target1 = torch.zeros_like(filled_target[:, 0:forecast_length * 2, :])

RuntimeError: The expanded size of the tensor (1) must match the existing size (4) at non-singleton dimension 2.  Target sizes: [1, 96, 1].  Tensor sizes: [96, 4]```