Skip to content

Commit 70e4873

Browse files
committed
[DOC]: Add RecurrentNetwork usage example
- Add doctest example showing complete workflow: data -> dataset -> model -> train -> predict - Uses generate_ar_data for self-contained example - Includes target_lags demonstration for RNN Fixes #2377
1 parent 36ac67f commit 70e4873

1 file changed

Lines changed: 57 additions & 17 deletions

File tree

  • pytorch_forecasting/models/rnn

‎pytorch_forecasting/models/rnn/_rnn.py‎

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,49 @@ def __init__(
9898
loss (MultiHorizonMetric, optional): loss: loss function taking prediction and targets.
9999
logging_metrics (nn.ModuleList, optional): Metrics to log during training.
100100
Defaults to nn.ModuleList([SMAPE(), MAE(), RMSE(), MAPE(), MASE()]).
101+
Example:
102+
>>> import lightning.pytorch as pl
103+
>>> from pytorch_forcasting import RecurrentNetwork,TimeSeriesDataSet
104+
>>> from pytorch_forcasting.data.examples import generate_ar_data
105+
>>> data = generate_ar_data(n_series=10, timesteps = 100, seed = 42)
106+
>>> data["time_idx"] = data["time_idx"].astype(int)
107+
>>> max_encoder_length = 24
108+
>>> max_prediction_length = 6
109+
training = TimeSeriesDataSet(
110+
... data,
111+
... time_idx = "time_idx",
112+
... target = "value",
113+
... group_ids = ["series"],
114+
... max_encoder_length = max_encoder_length,
115+
... max_prediction_length = max_prediction_length,
116+
... time_vary_unknown_reals= ["value"],
117+
... target_lags = {"value": [1, 2, 3, 6, 12, 24]},
118+
... add_relative_time_idx = True,
119+
... add_target_scales = True,
120+
... add_encoder_length = True,
121+
... )
122+
>>> validation = TimeSeriesDataSet.from_dataset(
123+
... training, data, predict=True, stop_randomization=True
124+
... )
125+
>>> train_dataloader = training.to_dataloader(train=True, batch_size=32, num_workers=0)
126+
>>> val_dataloader = validation.to_dataloader(train=False, batch_size=32, num_workers=0)
127+
>>> rnn = RecurrentNetwork.from_dataset(
128+
... training,
129+
... cell_type = "LSTM",
130+
... hidden_size = 32,
131+
... rnn_layers = 2,
132+
... dropout = 0.1,
133+
... learning_rate = 1e-3,
134+
... log_interval = 10,
135+
...)
136+
>>> trainer = pl.Trainer(
137+
... max_epochs = 1,
138+
... accelerator = "cpu",
139+
... enable_checkpointing = False,
140+
... logger = False
141+
... )
142+
>>> trainer.fit(rnn, train_dataloaders = train_dataloader, val_dataloaders = val_dataloader)
143+
>>> predictions = rnn.predict(val_dataloader, trainer = trainer)
101144
""" # noqa : E501
102145
if static_categoricals is None:
103146
static_categoricals = []
@@ -148,9 +191,9 @@ def __init__(
148191
" be the same apart from target variable"
149192
)
150193
for targeti in to_list(target):
151-
assert (
152-
targeti in time_varying_reals_encoder
153-
), f"target {targeti} has to be real" # todo: remove this restriction
194+
assert targeti in time_varying_reals_encoder, (
195+
f"target {targeti} has to be real"
196+
) # todo: remove this restriction
154197
assert (isinstance(target, str) and isinstance(loss, MultiHorizonMetric)) or (
155198
isinstance(target, tuple | list)
156199
and isinstance(loss, MultiLoss)
@@ -174,9 +217,9 @@ def __init__(
174217
self.output_projector = nn.Linear(
175218
self.hparams.hidden_size, self.hparams.output_size
176219
)
177-
assert not isinstance(
178-
self.loss, QuantileLoss
179-
), "QuantileLoss does not work with recurrent network"
220+
assert not isinstance(self.loss, QuantileLoss), (
221+
"QuantileLoss does not work with recurrent network"
222+
)
180223
else: # multi target
181224
self.output_projector = nn.ModuleList(
182225
[
@@ -185,9 +228,9 @@ def __init__(
185228
]
186229
)
187230
for l in self.loss:
188-
assert not isinstance(
189-
l, QuantileLoss
190-
), "QuantileLoss does not work with recurrent network"
231+
assert not isinstance(l, QuantileLoss), (
232+
"QuantileLoss does not work with recurrent network"
233+
)
191234

192235
@classmethod
193236
def from_dataset(
@@ -213,14 +256,11 @@ def from_dataset(
213256
dataset=dataset, kwargs=kwargs, default_loss=MAE()
214257
)
215258
)
216-
assert (
217-
not isinstance(dataset.target_normalizer, NaNLabelEncoder)
218-
and (
219-
not isinstance(dataset.target_normalizer, MultiNormalizer)
220-
or all(
221-
not isinstance(normalizer, NaNLabelEncoder)
222-
for normalizer in dataset.target_normalizer
223-
)
259+
assert not isinstance(dataset.target_normalizer, NaNLabelEncoder) and (
260+
not isinstance(dataset.target_normalizer, MultiNormalizer)
261+
or all(
262+
not isinstance(normalizer, NaNLabelEncoder)
263+
for normalizer in dataset.target_normalizer
224264
)
225265
), (
226266
"target(s) should be continuous - categorical targets are not supported"

0 commit comments

Comments
 (0)