We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Best Model not provided
The AR example has a bestmodel with an address to a personal computer, this bestmodel is not provided and cause errors when running the notebook.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pytorch_forecasting/models/nbeats/__init__.py`
Content:
```
1 """
2 N-Beats model for timeseries forecasting without covariates.
3 """
4 from typing import Dict, List
5 
6 import matplotlib.pyplot as plt
7 import torch
8 from torch import nn
9 
10 from pytorch_forecasting.data import TimeSeriesDataSet
11 from pytorch_forecasting.metrics import SMAPE
12 from pytorch_forecasting.models.base_model import BaseModel
13 from pytorch_forecasting.models.nbeats.sub_modules import NBEATSGenericBlock, NBEATSSeasonalBlock, NBEATSTrendBlock
14 
15 
16 class NBeats(BaseModel):
17     def __init__(
18         self,
19         stack_types: List[str] = ["trend", "seasonality"],
20         num_blocks=[3, 3],
21         num_block_layers=[3, 3],
22         widths=[16, 128, 16],
23         sharing: List[int] = [True, True],
24         expansion_coefficient_lengths: List[int] = [5, 7],
25         prediction_length: int = 1,
26         context_length: int = 1,
27         dropout: float = 0.1,
28         learning_rate: float = 1e-2,
29         log_interval: int = -1,
30         log_gradient_flow: bool = False,
31         log_val_interval: int = None,
32         weight_decay: float = 1e-3,
33         loss=SMAPE(),
34         reduce_on_plateau_patience: int = 1000,
35         **kwargs,
36     ):
37         """
38         Initialize NBeats Model - use its :py:meth:`~from_dataset` method if possible.
39 
40         Based on the article
41         `N-BEATS: Neural basis expansion analysis for interpretable time series
42         forecasting <http://arxiv.org/abs/1905.10437>`_. The network has (if used as ensemble) outperformed all
43         other methods
44         including ensembles of traditional statical methods in the M4 competition. The M4 competition is arguably
45         the most
46         important benchmark for univariate time series forecasting.
47 
48         Args:
49             stack_types: One of the following values: “generic”, “seasonality" or “trend". A list of strings
50                 of length 1 or ‘num_stacks’. Default and recommended value
51                 for generic mode: [“generic”] Recommended value for interpretable mode: [“trend”,”seasonality”]
52             num_blocks: The number of blocks per stack. A list of ints of length 1 or ‘num_stacks’.
53                 Default and recommended value for generic mode: [1] Recommended value for interpretable mode: [3]
54             num_block_layers: Number of fully connected layers with ReLu activation per block. A list of ints of length
55                 1 or ‘num_stacks’.
56                 Default and recommended value for generic mode: [4] Recommended value for interpretable mode: [4]
57             width: Widths of the fully connected layers with ReLu activation in the blocks.
58                 A list of ints of length 1 or ‘num_stacks’. Default and recommended value for generic mode: [512]
59                 Recommended value for interpretable mode: [256, 2048]
60             sharing: Whether the weights are shared with the other blocks per stack.
61                 A list of ints of length 1 or ‘num_stacks’. Default and recommended value for generic mode: [False]
62                 Recommended value for interpretable mode: [True]
63             expansion_coefficient_length: If the type is “G” (generic), then the length of the expansion
64                 coefficient.
65                 If type is “T” (trend), then it corresponds to the degree of the polynomial. If the type is “S”
66                 (seasonal) then this is the minimum period allowed, e.g. 2 for changes every timestep.
67                 A list of ints of length 1 or ‘num_stacks’. Default value for generic mode: [32] Recommended value for
68                 interpretable mode: [3]
69             prediction_length: Length of the prediction. Also known as 'horizon'.
70             context_length: Number of time units that condition the predictions. Also known as 'lookback period'.
71                 Should be between 1-10 times the prediction length.
72             has_backcast: Only the last block of the network doesn't.
73             log_gradient_flow: if to log gradient flow, this takes time and should be only done to diagnose training
74                 failures
75             reduce_on_plateau_patience (int): patience after which learning rate is reduced by a factor of 10
76         """
77         self.save_hyperparameters()
78         super().__init__(**kwargs)
79         self.loss = loss
80 
81         # setup stacks
82         self.net_blocks = nn.ModuleList()
83         for stack_id, stack_type in enumerate(stack_types):
84             for _ in range(num_blocks[stack_id]):
85                 if stack_type == "generic":
86                     net_block = NBEATSGenericBlock(
87                         units=self.hparams.widths[stack_id],
88                         thetas_dim=self.hparams.expansion_coefficient_lengths[stack_id],
89                         num_block_layers=self.hparams.num_block_layers[stack_id],
90                         backcast_length=context_length,
91                         forecast_length=prediction_length,
92                         dropout=self.hparams.dropout,
93                     )
94                 elif stack_type == "seasonality":
95                     net_block = NBEATSSeasonalBlock(
96                         units=self.hparams.widths[stack_id],
97                         num_block_layers=self.hparams.num_block_layers[stack_id],
98                         backcast_length=context_length,
99                         forecast_length=prediction_length,
100                         min_period=self.hparams.expansion_coefficient_lengths[stack_id],
101                         dropout=self.hparams.dropout,
102                     )
103                 elif stack_type == "trend":
104                     net_block = NBEATSTrendBlock(
105                         units=self.hparams.widths[stack_id],
106                         thetas_dim=self.hparams.expansion_coefficient_lengths[stack_id],
107                         num_block_layers=self.hparams.num_block_layers[stack_id],
108                         backcast_length=context_length,
109                         forecast_length=prediction_length,
110                         dropout=self.hparams.dropout,
111                     )
112                 else:
113                     raise ValueError(f"Unknown stack type {stack_type}")
114 
115                 self.net_blocks.append(net_block)
116 
117     def forward(self, x: Dict[str, torch.Tensor]) -> Dict[str, torch.Tensor]:
118         """
119         Pass forward of network.
120 
121         Args:
122             x (Dict[str, torch.Tensor]): input from dataloader generated from
123                 :py:class:`~pytorch_forecasting.data.timeseries.TimeSeriesDataSet`.
124 
125         Returns:
126             Dict[str, torch.Tensor]: output of model
127         """
128         target = x["encoder_cont"][..., 0]
129 
130         timesteps = self.hparams.context_length + self.hparams.prediction_length
131         generic_forecast = [torch.zeros((target.size(0), timesteps), dtype=torch.float32, device=self.device)]
132         trend_forecast = [torch.zeros((target.size(0), timesteps), dtype=torch.float32, device=self.device)]
133         seasonal_forecast = [torch.zeros((target.size(0), timesteps), dtype=torch.float32, device=self.device)]
134         forecast = torch.zeros(
135             (target.size(0), self.hparams.prediction_length), dtype=torch.float32, device=self.device
136         )
137 
138         backcast = target  # initialize backcast
139         for i, block in enumerate(self.net_blocks):
140             # evaluate block
141             backcast_block, forecast_block = block(backcast)
142 
143             # add for interpretation
144             full = torch.cat([backcast_block.detach(), forecast_block.detach()], dim=1)
145             if isinstance(block, NBEATSTrendBlock):
146                 trend_forecast.append(full)
147             elif isinstance(block, NBEATSSeasonalBlock):
148                 seasonal_forecast.append(full)
149             else:
150                 generic_forecast.append(full)
151 
152             # update backcast and forecast
153             backcast = (
154                 backcast - backcast_block
155             )  # do not use backcast -= backcast_block as this signifies an inline operation
156             forecast = forecast + forecast_block
157 
158         return dict(
159             prediction=forecast,
160             target_scale=x["target_scale"],
161             backcast=backcast,
162             trend=torch.stack(trend_forecast, dim=0).sum(0),
163             seasonality=torch.stack(seasonal_forecast, dim=0).sum(0),
164             generic=torch.stack(generic_forecast, dim=0).sum(0),
165         )
166 
167     @classmethod
168     def from_dataset(cls, dataset: TimeSeriesDataSet, **kwargs):
169         """
170         Convenience function to create network from :py:class`~pytorch_forecasting.data.timeseries.TimeSeriesDataSet`.
171 
172         Args:
173             dataset (TimeSeriesDataSet): dataset where sole predictor is the target.
174             **kwargs: additional arguments to be passed to ``__init__`` method.
175 
176         Returns:
177             NBeats
178         """
179         new_kwargs = {"prediction_length": dataset.max_prediction_length, "context_length": dataset.max_encoder_length}
180         new_kwargs.update(kwargs)
181 
182         # validate arguments
183         assert (
184             dataset.min_encoder_length == dataset.max_encoder_length
185         ), "only fixed encoder length is allowed, but min_encoder_length != max_encoder_length"
186 
187         assert (
188             dataset.max_prediction_length == dataset.min_prediction_length
189         ), "only fixed prediction length is allowed, but max_prediction_length != min_prediction_length"
190 
191         assert dataset.randomize_length is None, "length has to be fixed, but randomize_length is not None"
192         assert not dataset.add_relative_time_idx, "add_relative_time_idx has to be False"
193 
194         assert (
195             len(dataset.flat_categoricals) == 0
196             and len(dataset.reals) == 1
197             and len(dataset.time_varying_unknown_reals) == 1
198             and dataset.time_varying_unknown_reals[0] == dataset.target
199         ), "The only variable as input should be the target which is part of time_varying_unknown_reals"
200 
201         # initialize class
202         return super().from_dataset(dataset, **new_kwargs)
203 
204     def step(self, x, y, batch_idx, label) -> Dict[str, torch.Tensor]:
205         """
206         Take training / validation step.
207         """
208         log, out = super().step(x, y, batch_idx=batch_idx, label=label)
209         self._log_interpretation(x, out, batch_idx=batch_idx, label=label)
210         return log, out
211 
212     def _log_interpretation(self, x, out, batch_idx, label="train"):
213         """
214         Log interpretation of network predictions in tensorboard.
215         """
216         if self.log_interval(label == "train") > 0 and batch_idx % self.log_interval(label == "train") == 0:
217             fig = self.plot_interpretation(x, out, idx=0)
218             name = f"{label.capitalize()} interpretation of item 0 in "
219             if label == "train":
220                 name += f"step {self.global_step}"
221             else:
222                 name += f"batch {batch_idx}"
223             self.logger.experiment.add_figure(name, fig, global_step=self.global_step)
224 
225     def plot_interpretation(
226         self,
227         x: Dict[str, torch.Tensor],
228         output: Dict[str, torch.Tensor],
229         idx: int,
230         ax=None,
231         plot_seasonality_and_generic_on_secondary_axis: bool = False,
232     ) -> plt.Figure:
233         """
234         Plot interpretation.
235 
236         Plot two pannels: prediction and backcast vs actuals and
237         decomposition of prediction into trend, seasonality and generic forecast.
238 
239         Args:
240             x (Dict[str, torch.Tensor]): network input
241             output (Dict[str, torch.Tensor]): network output
242             idx (int): index of sample for which to plot the interpretation.
243             ax (List[matplotlib axes], optional): list of two matplotlib axes onto which to plot the interpretation.
244                 Defaults to None.
245             plot_seasonality_and_generic_on_secondary_axis (bool, optional): if to plot seasonality and
246                 generic forecast on secondary axis in second panel. Defaults to False.
247 
248         Returns:
249             plt.Figure: matplotlib figure
250         """
251         if ax is None:
252             fig, ax = plt.subplots(2, 1, figsize=(6, 8))
253         else:
254             fig = ax.get_figure()
255 
256         time = torch.arange(-self.hparams.context_length, self.hparams.prediction_length)
257 
258         def to_prediction(y):
259             return self.transform_output(dict(prediction=y[[idx]], target_scale=x["target_scale"][[idx]]))[0]
260 
261         # plot target vs prediction
262         ax[0].plot(time, torch.cat([x["encoder_target"][idx], x["decoder_target"][idx]]), label="target")
263         ax[0].plot(
264             time,
265             torch.cat(
266                 [
267                     to_prediction(x["encoder_cont"][idx, :, 0] - output["backcast"].detach()),
268                     output["prediction"][idx].detach(),
269                 ],
270                 dim=0,
271             ),
272             label="prediction",
273         )
274         ax[0].set_xlabel("Time")
275 
276         # plot blocks
277         if plot_seasonality_and_generic_on_secondary_axis:
278             ax2 = ax[1].twinx()
279             ax2.set_ylabel("Seasonality / Generic")
280         else:
281             ax2 = ax[1]
282         for title in ["trend", "seasonality", "generic"]:
283             if title not in self.hparams.stack_types:
284                 continue
285             if title == "trend":
286                 ax[1].plot(time, to_prediction(output[title]), label=title.capitalize())
287             else:
288                 ax2.plot(time, to_prediction(output[title]), label=title.capitalize())
289         ax[1].set_xlabel("Time")
290         ax[1].set_ylabel("Trend")
291 
292         fig.legend()
293         return fig
294
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pytorch_forecasting/models/nbeats/__init__.py b/pytorch_forecasting/models/nbeats/__init__.py
--- a/pytorch_forecasting/models/nbeats/__init__.py
+++ b/pytorch_forecasting/models/nbeats/__init__.py
@@ -287,7 +287,7 @@
             else:
                 ax2.plot(time, to_prediction(output[title]), label=title.capitalize())
         ax[1].set_xlabel("Time")
-        ax[1].set_ylabel("Trend")
+        ax[1].set_ylabel("Decomposition")
 
         fig.legend()
         return fig

{"golden_diff": "diff --git a/pytorch_forecasting/models/nbeats/__init__.py b/pytorch_forecasting/models/nbeats/__init__.py\n--- a/pytorch_forecasting/models/nbeats/__init__.py\n+++ b/pytorch_forecasting/models/nbeats/__init__.py\n@@ -287,7 +287,7 @@\n             else:\n                 ax2.plot(time, to_prediction(output[title]), label=title.capitalize())\n         ax[1].set_xlabel(\"Time\")\n-        ax[1].set_ylabel(\"Trend\")\n+        ax[1].set_ylabel(\"Decomposition\")\n \n         fig.legend()\n         return fig\n", "issue": "Best Model not provided\nThe AR example has a bestmodel with an address to a personal computer, this bestmodel is not provided and cause errors when running the notebook.\n", "before_files": [{"content": "\"\"\"\nN-Beats model for timeseries forecasting without covariates.\n\"\"\"\nfrom typing import Dict, List\n\nimport matplotlib.pyplot as plt\nimport torch\nfrom torch import nn\n\nfrom pytorch_forecasting.data import TimeSeriesDataSet\nfrom pytorch_forecasting.metrics import SMAPE\nfrom pytorch_forecasting.models.base_model import BaseModel\nfrom pytorch_forecasting.models.nbeats.sub_modules import NBEATSGenericBlock, NBEATSSeasonalBlock, NBEATSTrendBlock\n\n\nclass NBeats(BaseModel):\n    def __init__(\n        self,\n        stack_types: List[str] = [\"trend\", \"seasonality\"],\n        num_blocks=[3, 3],\n        num_block_layers=[3, 3],\n        widths=[16, 128, 16],\n        sharing: List[int] = [True, True],\n        expansion_coefficient_lengths: List[int] = [5, 7],\n        prediction_length: int = 1,\n        context_length: int = 1,\n        dropout: float = 0.1,\n        learning_rate: float = 1e-2,\n        log_interval: int = -1,\n        log_gradient_flow: bool = False,\n        log_val_interval: int = None,\n        weight_decay: float = 1e-3,\n        loss=SMAPE(),\n        reduce_on_plateau_patience: int = 1000,\n        **kwargs,\n    ):\n        \"\"\"\n        Initialize NBeats Model - use its :py:meth:`~from_dataset` method if possible.\n\n        Based on the article\n        `N-BEATS: Neural basis expansion analysis for interpretable time series\n        forecasting <http://arxiv.org/abs/1905.10437>`_. The network has (if used as ensemble) outperformed all\n        other methods\n        including ensembles of traditional statical methods in the M4 competition. The M4 competition is arguably\n        the most\n        important benchmark for univariate time series forecasting.\n\n        Args:\n            stack_types: One of the following values: \u201cgeneric\u201d, \u201cseasonality\" or \u201ctrend\". A list of strings\n                of length 1 or \u2018num_stacks\u2019. Default and recommended value\n                for generic mode: [\u201cgeneric\u201d] Recommended value for interpretable mode: [\u201ctrend\u201d,\u201dseasonality\u201d]\n            num_blocks: The number of blocks per stack. A list of ints of length 1 or \u2018num_stacks\u2019.\n                Default and recommended value for generic mode: [1] Recommended value for interpretable mode: [3]\n            num_block_layers: Number of fully connected layers with ReLu activation per block. A list of ints of length\n                1 or \u2018num_stacks\u2019.\n                Default and recommended value for generic mode: [4] Recommended value for interpretable mode: [4]\n            width: Widths of the fully connected layers with ReLu activation in the blocks.\n                A list of ints of length 1 or \u2018num_stacks\u2019. Default and recommended value for generic mode: [512]\n                Recommended value for interpretable mode: [256, 2048]\n            sharing: Whether the weights are shared with the other blocks per stack.\n                A list of ints of length 1 or \u2018num_stacks\u2019. Default and recommended value for generic mode: [False]\n                Recommended value for interpretable mode: [True]\n            expansion_coefficient_length: If the type is \u201cG\u201d (generic), then the length of the expansion\n                coefficient.\n                If type is \u201cT\u201d (trend), then it corresponds to the degree of the polynomial. If the type is \u201cS\u201d\n                (seasonal) then this is the minimum period allowed, e.g. 2 for changes every timestep.\n                A list of ints of length 1 or \u2018num_stacks\u2019. Default value for generic mode: [32] Recommended value for\n                interpretable mode: [3]\n            prediction_length: Length of the prediction. Also known as 'horizon'.\n            context_length: Number of time units that condition the predictions. Also known as 'lookback period'.\n                Should be between 1-10 times the prediction length.\n            has_backcast: Only the last block of the network doesn't.\n            log_gradient_flow: if to log gradient flow, this takes time and should be only done to diagnose training\n                failures\n            reduce_on_plateau_patience (int): patience after which learning rate is reduced by a factor of 10\n        \"\"\"\n        self.save_hyperparameters()\n        super().__init__(**kwargs)\n        self.loss = loss\n\n        # setup stacks\n        self.net_blocks = nn.ModuleList()\n        for stack_id, stack_type in enumerate(stack_types):\n            for _ in range(num_blocks[stack_id]):\n                if stack_type == \"generic\":\n                    net_block = NBEATSGenericBlock(\n                        units=self.hparams.widths[stack_id],\n                        thetas_dim=self.hparams.expansion_coefficient_lengths[stack_id],\n                        num_block_layers=self.hparams.num_block_layers[stack_id],\n                        backcast_length=context_length,\n                        forecast_length=prediction_length,\n                        dropout=self.hparams.dropout,\n                    )\n                elif stack_type == \"seasonality\":\n                    net_block = NBEATSSeasonalBlock(\n                        units=self.hparams.widths[stack_id],\n                        num_block_layers=self.hparams.num_block_layers[stack_id],\n                        backcast_length=context_length,\n                        forecast_length=prediction_length,\n                        min_period=self.hparams.expansion_coefficient_lengths[stack_id],\n                        dropout=self.hparams.dropout,\n                    )\n                elif stack_type == \"trend\":\n                    net_block = NBEATSTrendBlock(\n                        units=self.hparams.widths[stack_id],\n                        thetas_dim=self.hparams.expansion_coefficient_lengths[stack_id],\n                        num_block_layers=self.hparams.num_block_layers[stack_id],\n                        backcast_length=context_length,\n                        forecast_length=prediction_length,\n                        dropout=self.hparams.dropout,\n                    )\n                else:\n                    raise ValueError(f\"Unknown stack type {stack_type}\")\n\n                self.net_blocks.append(net_block)\n\n    def forward(self, x: Dict[str, torch.Tensor]) -> Dict[str, torch.Tensor]:\n        \"\"\"\n        Pass forward of network.\n\n        Args:\n            x (Dict[str, torch.Tensor]): input from dataloader generated from\n                :py:class:`~pytorch_forecasting.data.timeseries.TimeSeriesDataSet`.\n\n        Returns:\n            Dict[str, torch.Tensor]: output of model\n        \"\"\"\n        target = x[\"encoder_cont\"][..., 0]\n\n        timesteps = self.hparams.context_length + self.hparams.prediction_length\n        generic_forecast = [torch.zeros((target.size(0), timesteps), dtype=torch.float32, device=self.device)]\n        trend_forecast = [torch.zeros((target.size(0), timesteps), dtype=torch.float32, device=self.device)]\n        seasonal_forecast = [torch.zeros((target.size(0), timesteps), dtype=torch.float32, device=self.device)]\n        forecast = torch.zeros(\n            (target.size(0), self.hparams.prediction_length), dtype=torch.float32, device=self.device\n        )\n\n        backcast = target  # initialize backcast\n        for i, block in enumerate(self.net_blocks):\n            # evaluate block\n            backcast_block, forecast_block = block(backcast)\n\n            # add for interpretation\n            full = torch.cat([backcast_block.detach(), forecast_block.detach()], dim=1)\n            if isinstance(block, NBEATSTrendBlock):\n                trend_forecast.append(full)\n            elif isinstance(block, NBEATSSeasonalBlock):\n                seasonal_forecast.append(full)\n            else:\n                generic_forecast.append(full)\n\n            # update backcast and forecast\n            backcast = (\n                backcast - backcast_block\n            )  # do not use backcast -= backcast_block as this signifies an inline operation\n            forecast = forecast + forecast_block\n\n        return dict(\n            prediction=forecast,\n            target_scale=x[\"target_scale\"],\n            backcast=backcast,\n            trend=torch.stack(trend_forecast, dim=0).sum(0),\n            seasonality=torch.stack(seasonal_forecast, dim=0).sum(0),\n            generic=torch.stack(generic_forecast, dim=0).sum(0),\n        )\n\n    @classmethod\n    def from_dataset(cls, dataset: TimeSeriesDataSet, **kwargs):\n        \"\"\"\n        Convenience function to create network from :py:class`~pytorch_forecasting.data.timeseries.TimeSeriesDataSet`.\n\n        Args:\n            dataset (TimeSeriesDataSet): dataset where sole predictor is the target.\n            **kwargs: additional arguments to be passed to ``__init__`` method.\n\n        Returns:\n            NBeats\n        \"\"\"\n        new_kwargs = {\"prediction_length\": dataset.max_prediction_length, \"context_length\": dataset.max_encoder_length}\n        new_kwargs.update(kwargs)\n\n        # validate arguments\n        assert (\n            dataset.min_encoder_length == dataset.max_encoder_length\n        ), \"only fixed encoder length is allowed, but min_encoder_length != max_encoder_length\"\n\n        assert (\n            dataset.max_prediction_length == dataset.min_prediction_length\n        ), \"only fixed prediction length is allowed, but max_prediction_length != min_prediction_length\"\n\n        assert dataset.randomize_length is None, \"length has to be fixed, but randomize_length is not None\"\n        assert not dataset.add_relative_time_idx, \"add_relative_time_idx has to be False\"\n\n        assert (\n            len(dataset.flat_categoricals) == 0\n            and len(dataset.reals) == 1\n            and len(dataset.time_varying_unknown_reals) == 1\n            and dataset.time_varying_unknown_reals[0] == dataset.target\n        ), \"The only variable as input should be the target which is part of time_varying_unknown_reals\"\n\n        # initialize class\n        return super().from_dataset(dataset, **new_kwargs)\n\n    def step(self, x, y, batch_idx, label) -> Dict[str, torch.Tensor]:\n        \"\"\"\n        Take training / validation step.\n        \"\"\"\n        log, out = super().step(x, y, batch_idx=batch_idx, label=label)\n        self._log_interpretation(x, out, batch_idx=batch_idx, label=label)\n        return log, out\n\n    def _log_interpretation(self, x, out, batch_idx, label=\"train\"):\n        \"\"\"\n        Log interpretation of network predictions in tensorboard.\n        \"\"\"\n        if self.log_interval(label == \"train\") > 0 and batch_idx % self.log_interval(label == \"train\") == 0:\n            fig = self.plot_interpretation(x, out, idx=0)\n            name = f\"{label.capitalize()} interpretation of item 0 in \"\n            if label == \"train\":\n                name += f\"step {self.global_step}\"\n            else:\n                name += f\"batch {batch_idx}\"\n            self.logger.experiment.add_figure(name, fig, global_step=self.global_step)\n\n    def plot_interpretation(\n        self,\n        x: Dict[str, torch.Tensor],\n        output: Dict[str, torch.Tensor],\n        idx: int,\n        ax=None,\n        plot_seasonality_and_generic_on_secondary_axis: bool = False,\n    ) -> plt.Figure:\n        \"\"\"\n        Plot interpretation.\n\n        Plot two pannels: prediction and backcast vs actuals and\n        decomposition of prediction into trend, seasonality and generic forecast.\n\n        Args:\n            x (Dict[str, torch.Tensor]): network input\n            output (Dict[str, torch.Tensor]): network output\n            idx (int): index of sample for which to plot the interpretation.\n            ax (List[matplotlib axes], optional): list of two matplotlib axes onto which to plot the interpretation.\n                Defaults to None.\n            plot_seasonality_and_generic_on_secondary_axis (bool, optional): if to plot seasonality and\n                generic forecast on secondary axis in second panel. Defaults to False.\n\n        Returns:\n            plt.Figure: matplotlib figure\n        \"\"\"\n        if ax is None:\n            fig, ax = plt.subplots(2, 1, figsize=(6, 8))\n        else:\n            fig = ax.get_figure()\n\n        time = torch.arange(-self.hparams.context_length, self.hparams.prediction_length)\n\n        def to_prediction(y):\n            return self.transform_output(dict(prediction=y[[idx]], target_scale=x[\"target_scale\"][[idx]]))[0]\n\n        # plot target vs prediction\n        ax[0].plot(time, torch.cat([x[\"encoder_target\"][idx], x[\"decoder_target\"][idx]]), label=\"target\")\n        ax[0].plot(\n            time,\n            torch.cat(\n                [\n                    to_prediction(x[\"encoder_cont\"][idx, :, 0] - output[\"backcast\"].detach()),\n                    output[\"prediction\"][idx].detach(),\n                ],\n                dim=0,\n            ),\n            label=\"prediction\",\n        )\n        ax[0].set_xlabel(\"Time\")\n\n        # plot blocks\n        if plot_seasonality_and_generic_on_secondary_axis:\n            ax2 = ax[1].twinx()\n            ax2.set_ylabel(\"Seasonality / Generic\")\n        else:\n            ax2 = ax[1]\n        for title in [\"trend\", \"seasonality\", \"generic\"]:\n            if title not in self.hparams.stack_types:\n                continue\n            if title == \"trend\":\n                ax[1].plot(time, to_prediction(output[title]), label=title.capitalize())\n            else:\n                ax2.plot(time, to_prediction(output[title]), label=title.capitalize())\n        ax[1].set_xlabel(\"Time\")\n        ax[1].set_ylabel(\"Trend\")\n\n        fig.legend()\n        return fig\n", "path": "pytorch_forecasting/models/nbeats/__init__.py"}], "after_files": [{"content": "\"\"\"\nN-Beats model for timeseries forecasting without covariates.\n\"\"\"\nfrom typing import Dict, List\n\nimport matplotlib.pyplot as plt\nimport torch\nfrom torch import nn\n\nfrom pytorch_forecasting.data import TimeSeriesDataSet\nfrom pytorch_forecasting.metrics import SMAPE\nfrom pytorch_forecasting.models.base_model import BaseModel\nfrom pytorch_forecasting.models.nbeats.sub_modules import NBEATSGenericBlock, NBEATSSeasonalBlock, NBEATSTrendBlock\n\n\nclass NBeats(BaseModel):\n    def __init__(\n        self,\n        stack_types: List[str] = [\"trend\", \"seasonality\"],\n        num_blocks=[3, 3],\n        num_block_layers=[3, 3],\n        widths=[16, 128, 16],\n        sharing: List[int] = [True, True],\n        expansion_coefficient_lengths: List[int] = [5, 7],\n        prediction_length: int = 1,\n        context_length: int = 1,\n        dropout: float = 0.1,\n        learning_rate: float = 1e-2,\n        log_interval: int = -1,\n        log_gradient_flow: bool = False,\n        log_val_interval: int = None,\n        weight_decay: float = 1e-3,\n        loss=SMAPE(),\n        reduce_on_plateau_patience: int = 1000,\n        **kwargs,\n    ):\n        \"\"\"\n        Initialize NBeats Model - use its :py:meth:`~from_dataset` method if possible.\n\n        Based on the article\n        `N-BEATS: Neural basis expansion analysis for interpretable time series\n        forecasting <http://arxiv.org/abs/1905.10437>`_. The network has (if used as ensemble) outperformed all\n        other methods\n        including ensembles of traditional statical methods in the M4 competition. The M4 competition is arguably\n        the most\n        important benchmark for univariate time series forecasting.\n\n        Args:\n            stack_types: One of the following values: \u201cgeneric\u201d, \u201cseasonality\" or \u201ctrend\". A list of strings\n                of length 1 or \u2018num_stacks\u2019. Default and recommended value\n                for generic mode: [\u201cgeneric\u201d] Recommended value for interpretable mode: [\u201ctrend\u201d,\u201dseasonality\u201d]\n            num_blocks: The number of blocks per stack. A list of ints of length 1 or \u2018num_stacks\u2019.\n                Default and recommended value for generic mode: [1] Recommended value for interpretable mode: [3]\n            num_block_layers: Number of fully connected layers with ReLu activation per block. A list of ints of length\n                1 or \u2018num_stacks\u2019.\n                Default and recommended value for generic mode: [4] Recommended value for interpretable mode: [4]\n            width: Widths of the fully connected layers with ReLu activation in the blocks.\n                A list of ints of length 1 or \u2018num_stacks\u2019. Default and recommended value for generic mode: [512]\n                Recommended value for interpretable mode: [256, 2048]\n            sharing: Whether the weights are shared with the other blocks per stack.\n                A list of ints of length 1 or \u2018num_stacks\u2019. Default and recommended value for generic mode: [False]\n                Recommended value for interpretable mode: [True]\n            expansion_coefficient_length: If the type is \u201cG\u201d (generic), then the length of the expansion\n                coefficient.\n                If type is \u201cT\u201d (trend), then it corresponds to the degree of the polynomial. If the type is \u201cS\u201d\n                (seasonal) then this is the minimum period allowed, e.g. 2 for changes every timestep.\n                A list of ints of length 1 or \u2018num_stacks\u2019. Default value for generic mode: [32] Recommended value for\n                interpretable mode: [3]\n            prediction_length: Length of the prediction. Also known as 'horizon'.\n            context_length: Number of time units that condition the predictions. Also known as 'lookback period'.\n                Should be between 1-10 times the prediction length.\n            has_backcast: Only the last block of the network doesn't.\n            log_gradient_flow: if to log gradient flow, this takes time and should be only done to diagnose training\n                failures\n            reduce_on_plateau_patience (int): patience after which learning rate is reduced by a factor of 10\n        \"\"\"\n        self.save_hyperparameters()\n        super().__init__(**kwargs)\n        self.loss = loss\n\n        # setup stacks\n        self.net_blocks = nn.ModuleList()\n        for stack_id, stack_type in enumerate(stack_types):\n            for _ in range(num_blocks[stack_id]):\n                if stack_type == \"generic\":\n                    net_block = NBEATSGenericBlock(\n                        units=self.hparams.widths[stack_id],\n                        thetas_dim=self.hparams.expansion_coefficient_lengths[stack_id],\n                        num_block_layers=self.hparams.num_block_layers[stack_id],\n                        backcast_length=context_length,\n                        forecast_length=prediction_length,\n                        dropout=self.hparams.dropout,\n                    )\n                elif stack_type == \"seasonality\":\n                    net_block = NBEATSSeasonalBlock(\n                        units=self.hparams.widths[stack_id],\n                        num_block_layers=self.hparams.num_block_layers[stack_id],\n                        backcast_length=context_length,\n                        forecast_length=prediction_length,\n                        min_period=self.hparams.expansion_coefficient_lengths[stack_id],\n                        dropout=self.hparams.dropout,\n                    )\n                elif stack_type == \"trend\":\n                    net_block = NBEATSTrendBlock(\n                        units=self.hparams.widths[stack_id],\n                        thetas_dim=self.hparams.expansion_coefficient_lengths[stack_id],\n                        num_block_layers=self.hparams.num_block_layers[stack_id],\n                        backcast_length=context_length,\n                        forecast_length=prediction_length,\n                        dropout=self.hparams.dropout,\n                    )\n                else:\n                    raise ValueError(f\"Unknown stack type {stack_type}\")\n\n                self.net_blocks.append(net_block)\n\n    def forward(self, x: Dict[str, torch.Tensor]) -> Dict[str, torch.Tensor]:\n        \"\"\"\n        Pass forward of network.\n\n        Args:\n            x (Dict[str, torch.Tensor]): input from dataloader generated from\n                :py:class:`~pytorch_forecasting.data.timeseries.TimeSeriesDataSet`.\n\n        Returns:\n            Dict[str, torch.Tensor]: output of model\n        \"\"\"\n        target = x[\"encoder_cont\"][..., 0]\n\n        timesteps = self.hparams.context_length + self.hparams.prediction_length\n        generic_forecast = [torch.zeros((target.size(0), timesteps), dtype=torch.float32, device=self.device)]\n        trend_forecast = [torch.zeros((target.size(0), timesteps), dtype=torch.float32, device=self.device)]\n        seasonal_forecast = [torch.zeros((target.size(0), timesteps), dtype=torch.float32, device=self.device)]\n        forecast = torch.zeros(\n            (target.size(0), self.hparams.prediction_length), dtype=torch.float32, device=self.device\n        )\n\n        backcast = target  # initialize backcast\n        for i, block in enumerate(self.net_blocks):\n            # evaluate block\n            backcast_block, forecast_block = block(backcast)\n\n            # add for interpretation\n            full = torch.cat([backcast_block.detach(), forecast_block.detach()], dim=1)\n            if isinstance(block, NBEATSTrendBlock):\n                trend_forecast.append(full)\n            elif isinstance(block, NBEATSSeasonalBlock):\n                seasonal_forecast.append(full)\n            else:\n                generic_forecast.append(full)\n\n            # update backcast and forecast\n            backcast = (\n                backcast - backcast_block\n            )  # do not use backcast -= backcast_block as this signifies an inline operation\n            forecast = forecast + forecast_block\n\n        return dict(\n            prediction=forecast,\n            target_scale=x[\"target_scale\"],\n            backcast=backcast,\n            trend=torch.stack(trend_forecast, dim=0).sum(0),\n            seasonality=torch.stack(seasonal_forecast, dim=0).sum(0),\n            generic=torch.stack(generic_forecast, dim=0).sum(0),\n        )\n\n    @classmethod\n    def from_dataset(cls, dataset: TimeSeriesDataSet, **kwargs):\n        \"\"\"\n        Convenience function to create network from :py:class`~pytorch_forecasting.data.timeseries.TimeSeriesDataSet`.\n\n        Args:\n            dataset (TimeSeriesDataSet): dataset where sole predictor is the target.\n            **kwargs: additional arguments to be passed to ``__init__`` method.\n\n        Returns:\n            NBeats\n        \"\"\"\n        new_kwargs = {\"prediction_length\": dataset.max_prediction_length, \"context_length\": dataset.max_encoder_length}\n        new_kwargs.update(kwargs)\n\n        # validate arguments\n        assert (\n            dataset.min_encoder_length == dataset.max_encoder_length\n        ), \"only fixed encoder length is allowed, but min_encoder_length != max_encoder_length\"\n\n        assert (\n            dataset.max_prediction_length == dataset.min_prediction_length\n        ), \"only fixed prediction length is allowed, but max_prediction_length != min_prediction_length\"\n\n        assert dataset.randomize_length is None, \"length has to be fixed, but randomize_length is not None\"\n        assert not dataset.add_relative_time_idx, \"add_relative_time_idx has to be False\"\n\n        assert (\n            len(dataset.flat_categoricals) == 0\n            and len(dataset.reals) == 1\n            and len(dataset.time_varying_unknown_reals) == 1\n            and dataset.time_varying_unknown_reals[0] == dataset.target\n        ), \"The only variable as input should be the target which is part of time_varying_unknown_reals\"\n\n        # initialize class\n        return super().from_dataset(dataset, **new_kwargs)\n\n    def step(self, x, y, batch_idx, label) -> Dict[str, torch.Tensor]:\n        \"\"\"\n        Take training / validation step.\n        \"\"\"\n        log, out = super().step(x, y, batch_idx=batch_idx, label=label)\n        self._log_interpretation(x, out, batch_idx=batch_idx, label=label)\n        return log, out\n\n    def _log_interpretation(self, x, out, batch_idx, label=\"train\"):\n        \"\"\"\n        Log interpretation of network predictions in tensorboard.\n        \"\"\"\n        if self.log_interval(label == \"train\") > 0 and batch_idx % self.log_interval(label == \"train\") == 0:\n            fig = self.plot_interpretation(x, out, idx=0)\n            name = f\"{label.capitalize()} interpretation of item 0 in \"\n            if label == \"train\":\n                name += f\"step {self.global_step}\"\n            else:\n                name += f\"batch {batch_idx}\"\n            self.logger.experiment.add_figure(name, fig, global_step=self.global_step)\n\n    def plot_interpretation(\n        self,\n        x: Dict[str, torch.Tensor],\n        output: Dict[str, torch.Tensor],\n        idx: int,\n        ax=None,\n        plot_seasonality_and_generic_on_secondary_axis: bool = False,\n    ) -> plt.Figure:\n        \"\"\"\n        Plot interpretation.\n\n        Plot two pannels: prediction and backcast vs actuals and\n        decomposition of prediction into trend, seasonality and generic forecast.\n\n        Args:\n            x (Dict[str, torch.Tensor]): network input\n            output (Dict[str, torch.Tensor]): network output\n            idx (int): index of sample for which to plot the interpretation.\n            ax (List[matplotlib axes], optional): list of two matplotlib axes onto which to plot the interpretation.\n                Defaults to None.\n            plot_seasonality_and_generic_on_secondary_axis (bool, optional): if to plot seasonality and\n                generic forecast on secondary axis in second panel. Defaults to False.\n\n        Returns:\n            plt.Figure: matplotlib figure\n        \"\"\"\n        if ax is None:\n            fig, ax = plt.subplots(2, 1, figsize=(6, 8))\n        else:\n            fig = ax.get_figure()\n\n        time = torch.arange(-self.hparams.context_length, self.hparams.prediction_length)\n\n        def to_prediction(y):\n            return self.transform_output(dict(prediction=y[[idx]], target_scale=x[\"target_scale\"][[idx]]))[0]\n\n        # plot target vs prediction\n        ax[0].plot(time, torch.cat([x[\"encoder_target\"][idx], x[\"decoder_target\"][idx]]), label=\"target\")\n        ax[0].plot(\n            time,\n            torch.cat(\n                [\n                    to_prediction(x[\"encoder_cont\"][idx, :, 0] - output[\"backcast\"].detach()),\n                    output[\"prediction\"][idx].detach(),\n                ],\n                dim=0,\n            ),\n            label=\"prediction\",\n        )\n        ax[0].set_xlabel(\"Time\")\n\n        # plot blocks\n        if plot_seasonality_and_generic_on_secondary_axis:\n            ax2 = ax[1].twinx()\n            ax2.set_ylabel(\"Seasonality / Generic\")\n        else:\n            ax2 = ax[1]\n        for title in [\"trend\", \"seasonality\", \"generic\"]:\n            if title not in self.hparams.stack_types:\n                continue\n            if title == \"trend\":\n                ax[1].plot(time, to_prediction(output[title]), label=title.capitalize())\n            else:\n                ax2.plot(time, to_prediction(output[title]), label=title.capitalize())\n        ax[1].set_xlabel(\"Time\")\n        ax[1].set_ylabel(\"Decomposition\")\n\n        fig.legend()\n        return fig\n", "path": "pytorch_forecasting/models/nbeats/__init__.py"}]}