Add AutoregressionTask
This PR adds the following:
- Autoregression Trainer (see #2382)
- LSTM Sequence-to-Sequence (Seq2Seq) model for time series forecasting
- Air Quality time series data set from the UCI Machine Learning Repository
Together these additions enable training air quality forecasting models as well as other autoregression tasks as additional datasets and models are added.
@adamjstewart See below, this test passes when I run it locally but it is failing here. I don't understand this error message, do you know how to resolve this?
FAILED tests/trainers/test_autoregression.py::TestAutoregressionTask::test_trainer[True-air_quality] - ValueError: Does not validate against any of the Union subtypes
Subtypes: [<class 'NoneType'>, <class 'torchgeo.trainers.base.BaseTask'>]
Errors:
- Expected a <class 'NoneType'>
- Unexpected keyword arguments: `num_outputs`
Given value type: <class 'jsonargparse._namespace.Namespace'>
Given value: Namespace(class_path='torchgeo.trainers.AutoregressionTask', init_args=Namespace(model='lstm_seq2seq', input_size=3, input_size_decoder=1, hidden_size=1, output_size=1, target_indices=[2], encoder_indices=[2, 12, 13], decoder_indices=[2], timesteps_ahead=1, num_layers=1, loss='mse', lr=0.001, patience=10, teacher_force_prob=None))
This keeps coming up due to my own ignorance, but @nilsleh and others keep reminding me:
- Autoregression: when a model takes its own output as input at the next time step
- Forecasting: when a model predicts the future
Should we rename this to ForecastingTask?
This name might still be too generic, since right now it only supports pointwise datasets. Should we make the name more specific, or add support for other possible target types like CDL masks in future PRs?
This model seems like it's performing forecasting via autoregression so I think AutoRegressiveTask is still the right naming.
This keeps coming up due to my own ignorance, but @nilsleh and others keep reminding me:
* Autoregression: when a model takes its own output as input at the next time step * Forecasting: when a model predicts the future
To my understanding, "AutoRegression" is one way to do time-series forecasting, so in a sense a methodological subset of "Forecasting". So like Isaac said, in this case one is doing forecasting via autoregression.
This model seems like it's performing forecasting via autoregression so I think AutoRegressiveTask is still the right naming.
I agree, this is how I intended the model to be implemented so I think it is the right name.
RtD tests may require a rebase, pillow 11.2.0 was yanked but 11.3.0 is now used in main.
@adamjstewart I've been realizing there are some issues with the Seq2Seq implementation here, for supporting inference (when there are no future values) and for covariates. I've found there is a lot of complexity to properly supporting different forecasting situations when you start to include covariates that may or may not be present for the decoder (i.e. for the future). So for now I simplified it down to just supporting using the target time series as an input, with no extra variables. It does work now for inference where there are no future values. How much do we want to support here? Is this an ok starting point for this PR? I also found that there would need to be some changes to logging to properly log multiple outputs, and I saw that RegressionTask only does single output right now as well, so I assume leaving this as single output for now is fine.
@adamjstewart I've been realizing there are some issues with the Seq2Seq implementation here, for supporting inference (when there are no future values) and for covariates. I've found there is a lot of complexity to properly supporting different forecasting situations when you start to include covariates that may or may not be present for the decoder (i.e. for the future). So for now I simplified it down to just supporting using the target time series as an input, with no extra variables. It does work now for inference where there are no future values.
Trying to understand this. Are you saying for past events, both inputs and expected outputs work, but for future events, the model can only make all predictions without regard to any potential new inputs?
How much do we want to support here? Is this an ok starting point for this PR?
Probably fine, don't want to hold this up much longer. My main concern is backwards-compatibility. If it's easy to add new features without breaking backwards-compatibility, then we are fine.
I also found that there would need to be some changes to logging to properly log multiple outputs, and I saw that
RegressionTaskonly does single output right now as well, so I assume leaving this as single output for now is fine.
Single output doesn't seem like Seq2Seq, it seems like Seq2Int. Can't we compare predicted sequences to expected sequences and log only the averaged metrics?
@keves1 I would like to move this PR forward again. Would it be possible to split the dataset, model, and trainer into separate PRs? I think the dataset is already ready to merge, and we can hack on the model separately. The trainer could use one of the other 1D models we've already added or it could wait until after the Seq2Seq model is merged.