diff --git a/CHANGELOG.md b/CHANGELOG.md index c93823534d..65d05aa637 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ but cannot always guarantee backwards compatibility. Changes that may **break co - 🔴 We moved `NaiveEnsembleModel` from `darts.models.forecasting.baselines` into a dedicated module `darts.models.forecasting.naive_ensemble_model` to separate the heavier dependencies from the baseline models and improve import times. Models that were saved in older Darts versions (pickled) cannot be loaded anymore. To fix it, simply re-create the model and store it again. [#3066](https://github.com/unit8co/darts/pull/3066) by [Dennis Bader](https://github.com/dennisbader) - Added parameter `name` to all metric functions for customizing the displayed name. [#3084](https://github.com/unit8co/darts/pull/3084) by [Bruno Da Costa](https://github.com/BrunoDaC). +- Warn and document that `add_encoders` are not applied on `TorchForecastingModel` `*_from_dataset`; clarify categorical-embedding keying behavior on `TFTModel` for that path. [#3086](https://github.com/unit8co/darts/pull/3086) by [Jakub Chłapek](https://github.com/jakubchlapek). **Fixed** diff --git a/darts/models/forecasting/tft_model.py b/darts/models/forecasting/tft_model.py index 819fd08383..588874bb88 100644 --- a/darts/models/forecasting/tft_model.py +++ b/darts/models/forecasting/tft_model.py @@ -741,6 +741,9 @@ def __init__( ``{"some_column": (64, 8)}``. Note that ``TorchForecastingModels`` only support numeric data. Consider transforming/encoding your data with `darts.dataprocessing.transformers.static_covariates_transformer.StaticCovariatesTransformer`. + When training via ``fit_from_dataset()``, categorical embeddings are resolved by + static covariate column integer index (not by column name). The keys of ``categorical_embedding_sizes`` + must align positionally with the static covariate columns. add_relative_index Whether to add positional values to future covariates. Defaults to ``False``. This allows to use the TFTModel without having to pass future_covariates to :func:`fit()` and diff --git a/darts/models/forecasting/torch_forecasting_model.py b/darts/models/forecasting/torch_forecasting_model.py index 6bf1f6c628..c0fe9c0416 100644 --- a/darts/models/forecasting/torch_forecasting_model.py +++ b/darts/models/forecasting/torch_forecasting_model.py @@ -1067,7 +1067,7 @@ def fit( future_covariates=seq2series(future_covariates), verbose=verbose, ) - return self.fit_from_dataset(*params) + return self.fit_from_dataset(*params, _called_internally=True) def _setup_for_fit_from_dataset( self, @@ -1208,6 +1208,7 @@ def fit_from_dataset( epochs: int = 0, dataloader_kwargs: dict[str, Any] | None = None, load_best: bool = False, + _called_internally: bool = False, ) -> "TorchForecastingModel": """ Train the model with a specific :class:`darts.utils.data.TorchTrainingDataset` instance. @@ -1223,6 +1224,10 @@ def fit_from_dataset( This function can be called several times to do some extra training. If ``epochs`` is specified, the model will be trained for some (extra) ``epochs`` epochs. + .. note:: + Encoders configured via ``add_encoders`` at model creation are not applied here; ``train_dataset`` + (and ``val_dataset`` if given) must already include any encoder-generated covariates. + Parameters ---------- train_dataset @@ -1256,6 +1261,18 @@ def fit_from_dataset( self Fitted model. """ + if ( + not _called_internally + and self.encoders is not None + and self.encoders.encoding_available + ): + logger.warning( + "The model was created with `add_encoders`, but encoders are not " + "applied when calling `fit_from_dataset()`. The provided " + "`train_dataset` (and `val_dataset`) must already contain any " + "encoder-generated covariates. Use `fit()` if you want encoders " + "to be applied automatically." + ) self._train( *self._setup_for_train( train_dataset=train_dataset, @@ -1820,6 +1837,7 @@ def predict( mc_dropout=mc_dropout, predict_likelihood_parameters=predict_likelihood_parameters, random_state=random_state, + _called_internally=True, ) return predictions[0] if called_with_single_series else predictions @@ -1840,6 +1858,7 @@ def predict_from_dataset( predict_likelihood_parameters: bool = False, random_state: int | None = None, values_only: bool = False, + _called_internally: bool = False, ) -> Sequence[TimeSeries]: """ This method allows for predicting with a specific :class:`darts.utils.data.TorchInferenceDataset` instance. @@ -1852,6 +1871,10 @@ def predict_from_dataset( ``trainer``. For more information on PyTorch Lightning Trainers check out `this link `__. + .. note:: + Encoders configured via ``add_encoders`` at model creation are not applied here; ``dataset`` must already + include any encoder-generated covariates. + Parameters ---------- n @@ -1910,6 +1933,18 @@ def predict_from_dataset( self._verify_inference_dataset_type(dataset) + if ( + not _called_internally + and self.encoders is not None + and self.encoders.encoding_available + ): + logger.warning( + "The model was created with `add_encoders`, but encoders are not " + "applied when calling `predict_from_dataset()`. The provided " + "`dataset` must already contain any encoder-generated covariates. " + "Use `predict()` if you want encoders to be applied automatically." + ) + # check that covariates and dimensions are matching what we had during training self._validate_predict_sample( train_sample=self.train_sample, predict_sample=dataset[0]