We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add a tabular_forecasting example


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `flash_examples/integrations/pytorch_forecasting/tabular_forecasting_interpretable.py`
Content:
```
1 # Copyright The PyTorch Lightning team.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 import torch
15 
16 import flash
17 from flash.core.integrations.pytorch_forecasting import convert_predictions
18 from flash.core.utilities.imports import example_requires
19 from flash.tabular.forecasting import TabularForecaster, TabularForecastingData
20 
21 example_requires(["tabular", "matplotlib"])
22 
23 import matplotlib.pyplot as plt  # noqa: E402
24 import pandas as pd  # noqa: E402
25 from pytorch_forecasting.data import NaNLabelEncoder  # noqa: E402
26 from pytorch_forecasting.data.examples import generate_ar_data  # noqa: E402
27 
28 # Example based on this tutorial: https://pytorch-forecasting.readthedocs.io/en/latest/tutorials/ar.html
29 # 1. Create the DataModule
30 data = generate_ar_data(seasonality=10.0, timesteps=400, n_series=100, seed=42)
31 data["date"] = pd.Timestamp("2020-01-01") + pd.to_timedelta(data.time_idx, "D")
32 
33 max_prediction_length = 20
34 
35 training_cutoff = data["time_idx"].max() - max_prediction_length
36 
37 datamodule = TabularForecastingData.from_data_frame(
38     time_idx="time_idx",
39     target="value",
40     categorical_encoders={"series": NaNLabelEncoder().fit(data.series)},
41     group_ids=["series"],
42     # only unknown variable is "value" - and N-Beats can also not take any additional variables
43     time_varying_unknown_reals=["value"],
44     max_encoder_length=60,
45     max_prediction_length=max_prediction_length,
46     train_data_frame=data[lambda x: x.time_idx <= training_cutoff],
47     val_data_frame=data,
48     batch_size=32,
49 )
50 
51 # 2. Build the task
52 model = TabularForecaster(datamodule.parameters, backbone="n_beats", widths=[32, 512], backcast_loss_ratio=0.1)
53 
54 # 3. Create the trainer and train the model
55 trainer = flash.Trainer(max_epochs=1, gpus=torch.cuda.device_count(), gradient_clip_val=0.01)
56 trainer.fit(model, datamodule=datamodule)
57 
58 # 4. Generate predictions
59 predictions = model.predict(data)
60 print(predictions)
61 
62 # Convert predictions
63 predictions, inputs = convert_predictions(predictions)
64 
65 # Plot predictions
66 for idx in range(10):  # plot 10 examples
67     model.pytorch_forecasting_model.plot_prediction(inputs, predictions, idx=idx, add_loss_to_title=True)
68 
69 # Plot interpretation
70 for idx in range(10):  # plot 10 examples
71     model.pytorch_forecasting_model.plot_interpretation(inputs, predictions, idx=idx)
72 
73 # Show the plots!
74 plt.show()
75
```

Path: `flash/tabular/forecasting/data.py`
Content:
```
1 # Copyright The PyTorch Lightning team.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 from copy import copy
15 from dataclasses import dataclass
16 from typing import Any, Callable, Dict, List, Mapping, Optional, Union
17 
18 from pytorch_lightning.utilities.exceptions import MisconfigurationException
19 
20 from flash.core.data.callback import BaseDataFetcher
21 from flash.core.data.data_module import DataModule
22 from flash.core.data.data_source import DataSource, DefaultDataKeys, DefaultDataSources
23 from flash.core.data.process import Deserializer, Preprocess
24 from flash.core.data.properties import ProcessState
25 from flash.core.utilities.imports import _FORECASTING_AVAILABLE, _PANDAS_AVAILABLE, requires
26 
27 if _PANDAS_AVAILABLE:
28     from pandas.core.frame import DataFrame
29 else:
30     DataFrame = object
31 
32 if _FORECASTING_AVAILABLE:
33     from pytorch_forecasting import TimeSeriesDataSet
34 
35 
36 @dataclass(unsafe_hash=True, frozen=True)
37 class TimeSeriesDataSetParametersState(ProcessState):
38     """A :class:`~flash.core.data.properties.ProcessState` containing ``labels``, a mapping from class index to
39     label."""
40 
41     time_series_dataset_parameters: Optional[Dict[str, Any]]
42 
43 
44 class TabularForecastingDataFrameDataSource(DataSource[DataFrame]):
45     @requires("tabular")
46     def __init__(
47         self,
48         time_idx: str,
49         target: Union[str, List[str]],
50         group_ids: List[str],
51         parameters: Optional[Dict[str, Any]] = None,
52         **data_source_kwargs: Any,
53     ):
54         super().__init__()
55         self.time_idx = time_idx
56         self.target = target
57         self.group_ids = group_ids
58         self.data_source_kwargs = data_source_kwargs
59 
60         self.set_state(TimeSeriesDataSetParametersState(parameters))
61 
62     def load_data(self, data: DataFrame, dataset: Optional[Any] = None):
63         if self.training:
64             time_series_dataset = TimeSeriesDataSet(
65                 data, time_idx=self.time_idx, group_ids=self.group_ids, target=self.target, **self.data_source_kwargs
66             )
67             parameters = time_series_dataset.get_parameters()
68 
69             # Add some sample data so that we can recreate the `TimeSeriesDataSet` later on
70             parameters["data_sample"] = data.iloc[[0]]
71 
72             self.set_state(TimeSeriesDataSetParametersState(parameters))
73             dataset.parameters = parameters
74         else:
75             parameters = copy(self.get_state(TimeSeriesDataSetParametersState).time_series_dataset_parameters)
76             if parameters is None:
77                 raise MisconfigurationException(
78                     "Loading data for evaluation or inference requires parameters from the train data. Either "
79                     "construct the train data at the same time as evaluation and inference or provide the train "
80                     "`datamodule.parameters` to `from_data_frame` in the `parameters` argument."
81                 )
82             parameters.pop("data_sample")
83             time_series_dataset = TimeSeriesDataSet.from_parameters(
84                 parameters,
85                 data,
86                 predict=True,
87                 stop_randomization=True,
88             )
89         dataset.time_series_dataset = time_series_dataset
90         return time_series_dataset
91 
92     def load_sample(self, sample: Mapping[str, Any], dataset: Optional[Any] = None) -> Any:
93         return {DefaultDataKeys.INPUT: sample[0], DefaultDataKeys.TARGET: sample[1]}
94 
95 
96 class TabularForecastingPreprocess(Preprocess):
97     def __init__(
98         self,
99         train_transform: Optional[Dict[str, Callable]] = None,
100         val_transform: Optional[Dict[str, Callable]] = None,
101         test_transform: Optional[Dict[str, Callable]] = None,
102         predict_transform: Optional[Dict[str, Callable]] = None,
103         deserializer: Optional[Deserializer] = None,
104         **data_source_kwargs: Any,
105     ):
106         self.data_source_kwargs = data_source_kwargs
107         super().__init__(
108             train_transform=train_transform,
109             val_transform=val_transform,
110             test_transform=test_transform,
111             predict_transform=predict_transform,
112             data_sources={
113                 DefaultDataSources.DATAFRAME: TabularForecastingDataFrameDataSource(**data_source_kwargs),
114             },
115             deserializer=deserializer,
116             default_data_source=DefaultDataSources.DATAFRAME,
117         )
118 
119     def get_state_dict(self, strict: bool = False) -> Dict[str, Any]:
120         return {**self.transforms, **self.data_source_kwargs}
121 
122     @classmethod
123     def load_state_dict(cls, state_dict: Dict[str, Any], strict: bool = True) -> "Preprocess":
124         return cls(**state_dict)
125 
126 
127 class TabularForecastingData(DataModule):
128     """Data module for tabular tasks."""
129 
130     preprocess_cls = TabularForecastingPreprocess
131 
132     @property
133     def parameters(self) -> Optional[Dict[str, Any]]:
134         return getattr(self.train_dataset, "parameters", None)
135 
136     @classmethod
137     def from_data_frame(
138         cls,
139         time_idx: Optional[str] = None,
140         target: Optional[Union[str, List[str]]] = None,
141         group_ids: Optional[List[str]] = None,
142         parameters: Optional[Dict[str, Any]] = None,
143         train_data_frame: Optional[DataFrame] = None,
144         val_data_frame: Optional[DataFrame] = None,
145         test_data_frame: Optional[DataFrame] = None,
146         predict_data_frame: Optional[DataFrame] = None,
147         train_transform: Optional[Dict[str, Callable]] = None,
148         val_transform: Optional[Dict[str, Callable]] = None,
149         test_transform: Optional[Dict[str, Callable]] = None,
150         predict_transform: Optional[Dict[str, Callable]] = None,
151         data_fetcher: Optional[BaseDataFetcher] = None,
152         preprocess: Optional[Preprocess] = None,
153         val_split: Optional[float] = None,
154         batch_size: int = 4,
155         num_workers: Optional[int] = None,
156         **preprocess_kwargs: Any,
157     ):
158         """Creates a :class:`~flash.tabular.data.TabularClassificationData` object from the given data frames.
159 
160         Args:
161             group_ids:
162             target:
163             time_idx:
164             train_data_frame: The pandas ``DataFrame`` containing the training data.
165             val_data_frame: The pandas ``DataFrame`` containing the validation data.
166             test_data_frame: The pandas ``DataFrame`` containing the testing data.
167             predict_data_frame: The pandas ``DataFrame`` containing the data to use when predicting.
168             train_transform: The dictionary of transforms to use during training which maps
169                 :class:`~flash.core.data.process.Preprocess` hook names to callable transforms.
170             val_transform: The dictionary of transforms to use during validation which maps
171                 :class:`~flash.core.data.process.Preprocess` hook names to callable transforms.
172             test_transform: The dictionary of transforms to use during testing which maps
173                 :class:`~flash.core.data.process.Preprocess` hook names to callable transforms.
174             predict_transform: The dictionary of transforms to use during predicting which maps
175                 :class:`~flash.core.data.process.Preprocess` hook names to callable transforms.
176             data_fetcher: The :class:`~flash.core.data.callback.BaseDataFetcher` to pass to the
177                 :class:`~flash.core.data.data_module.DataModule`.
178             preprocess: The :class:`~flash.core.data.data.Preprocess` to pass to the
179                 :class:`~flash.core.data.data_module.DataModule`. If ``None``, ``cls.preprocess_cls``
180                 will be constructed and used.
181             val_split: The ``val_split`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`.
182             batch_size: The ``batch_size`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`.
183             num_workers: The ``num_workers`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`.
184             preprocess_kwargs: Additional keyword arguments to use when constructing the preprocess. Will only be used
185                 if ``preprocess = None``.
186 
187         Returns:
188             The constructed data module.
189 
190         Examples::
191 
192             data_module = TabularClassificationData.from_data_frame(
193                 "categorical_input",
194                 "numerical_input",
195                 "target",
196                 train_data_frame=train_data,
197             )
198         """
199 
200         return cls.from_data_source(
201             time_idx=time_idx,
202             target=target,
203             group_ids=group_ids,
204             parameters=parameters,
205             data_source=DefaultDataSources.DATAFRAME,
206             train_data=train_data_frame,
207             val_data=val_data_frame,
208             test_data=test_data_frame,
209             predict_data=predict_data_frame,
210             train_transform=train_transform,
211             val_transform=val_transform,
212             test_transform=test_transform,
213             predict_transform=predict_transform,
214             data_fetcher=data_fetcher,
215             preprocess=preprocess,
216             val_split=val_split,
217             batch_size=batch_size,
218             num_workers=num_workers,
219             **preprocess_kwargs,
220         )
221
```
--- 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/flash/tabular/forecasting/data.py b/flash/tabular/forecasting/data.py
--- a/flash/tabular/forecasting/data.py
+++ b/flash/tabular/forecasting/data.py
@@ -125,12 +125,14 @@
 
 
 class TabularForecastingData(DataModule):
-    """Data module for tabular tasks."""
+    """Data module for the tabular forecasting task."""
 
     preprocess_cls = TabularForecastingPreprocess
 
     @property
     def parameters(self) -> Optional[Dict[str, Any]]:
+        """The parameters dictionary from the ``TimeSeriesDataSet`` object created from the train data when
+        constructing the ``TabularForecastingData`` object."""
         return getattr(self.train_dataset, "parameters", None)
 
     @classmethod
@@ -155,12 +157,24 @@
         num_workers: Optional[int] = None,
         **preprocess_kwargs: Any,
     ):
-        """Creates a :class:`~flash.tabular.data.TabularClassificationData` object from the given data frames.
+        """Creates a :class:`~flash.tabular.forecasting.data.TabularForecastingData` object from the given data
+        frames.
+
+        .. note::
+
+            The ``time_idx``, ``target``, and ``group_ids`` do not need to be provided if ``parameters`` are passed
+            instead. These can be obtained from the
+            :attr:`~flash.tabular.forecasting.data.TabularForecastingData.parameters` attribute of the
+            :class:`~flash.tabular.forecasting.data.TabularForecastingData` object that contains your training data.
 
         Args:
-            group_ids:
-            target:
             time_idx:
+            target: Column denoting the target or list of columns denoting the target.
+            group_ids: List of column names identifying a time series. This means that the group_ids identify a sample
+                together with the time_idx. If you have only one timeseries, set this to the name of column that is
+                constant.
+            parameters: Parameters to use for the timeseries if ``time_idx``, ``target``, and ``group_ids`` are not
+                provided (e.g. when loading data for inference or validation).
             train_data_frame: The pandas ``DataFrame`` containing the training data.
             val_data_frame: The pandas ``DataFrame`` containing the validation data.
             test_data_frame: The pandas ``DataFrame`` containing the testing data.
@@ -189,10 +203,10 @@
 
         Examples::
 
-            data_module = TabularClassificationData.from_data_frame(
-                "categorical_input",
-                "numerical_input",
-                "target",
+            data_module = TabularForecastingData.from_data_frame(
+                time_idx="time_idx",
+                target="value",
+                group_ids=["series"],
                 train_data_frame=train_data,
             )
         """
diff --git a/flash_examples/integrations/pytorch_forecasting/tabular_forecasting_interpretable.py b/flash_examples/integrations/pytorch_forecasting/tabular_forecasting_interpretable.py
--- a/flash_examples/integrations/pytorch_forecasting/tabular_forecasting_interpretable.py
+++ b/flash_examples/integrations/pytorch_forecasting/tabular_forecasting_interpretable.py
@@ -59,16 +59,12 @@
 predictions = model.predict(data)
 print(predictions)
 
-# Convert predictions
+# Plot with PyTorch Forecasting!
 predictions, inputs = convert_predictions(predictions)
 
-# Plot predictions
-for idx in range(10):  # plot 10 examples
-    model.pytorch_forecasting_model.plot_prediction(inputs, predictions, idx=idx, add_loss_to_title=True)
+fig, axs = plt.subplots(2, 3, sharex="col")
 
-# Plot interpretation
-for idx in range(10):  # plot 10 examples
-    model.pytorch_forecasting_model.plot_interpretation(inputs, predictions, idx=idx)
+for idx in range(3):
+    model.pytorch_forecasting_model.plot_interpretation(inputs, predictions, idx=idx, ax=[axs[0][idx], axs[1][idx]])
 
-# Show the plots!
 plt.show()

{"golden_diff": "diff --git a/flash/tabular/forecasting/data.py b/flash/tabular/forecasting/data.py\n--- a/flash/tabular/forecasting/data.py\n+++ b/flash/tabular/forecasting/data.py\n@@ -125,12 +125,14 @@\n \n \n class TabularForecastingData(DataModule):\n-    \"\"\"Data module for tabular tasks.\"\"\"\n+    \"\"\"Data module for the tabular forecasting task.\"\"\"\n \n     preprocess_cls = TabularForecastingPreprocess\n \n     @property\n     def parameters(self) -> Optional[Dict[str, Any]]:\n+        \"\"\"The parameters dictionary from the ``TimeSeriesDataSet`` object created from the train data when\n+        constructing the ``TabularForecastingData`` object.\"\"\"\n         return getattr(self.train_dataset, \"parameters\", None)\n \n     @classmethod\n@@ -155,12 +157,24 @@\n         num_workers: Optional[int] = None,\n         **preprocess_kwargs: Any,\n     ):\n-        \"\"\"Creates a :class:`~flash.tabular.data.TabularClassificationData` object from the given data frames.\n+        \"\"\"Creates a :class:`~flash.tabular.forecasting.data.TabularForecastingData` object from the given data\n+        frames.\n+\n+        .. note::\n+\n+            The ``time_idx``, ``target``, and ``group_ids`` do not need to be provided if ``parameters`` are passed\n+            instead. These can be obtained from the\n+            :attr:`~flash.tabular.forecasting.data.TabularForecastingData.parameters` attribute of the\n+            :class:`~flash.tabular.forecasting.data.TabularForecastingData` object that contains your training data.\n \n         Args:\n-            group_ids:\n-            target:\n             time_idx:\n+            target: Column denoting the target or list of columns denoting the target.\n+            group_ids: List of column names identifying a time series. This means that the group_ids identify a sample\n+                together with the time_idx. If you have only one timeseries, set this to the name of column that is\n+                constant.\n+            parameters: Parameters to use for the timeseries if ``time_idx``, ``target``, and ``group_ids`` are not\n+                provided (e.g. when loading data for inference or validation).\n             train_data_frame: The pandas ``DataFrame`` containing the training data.\n             val_data_frame: The pandas ``DataFrame`` containing the validation data.\n             test_data_frame: The pandas ``DataFrame`` containing the testing data.\n@@ -189,10 +203,10 @@\n \n         Examples::\n \n-            data_module = TabularClassificationData.from_data_frame(\n-                \"categorical_input\",\n-                \"numerical_input\",\n-                \"target\",\n+            data_module = TabularForecastingData.from_data_frame(\n+                time_idx=\"time_idx\",\n+                target=\"value\",\n+                group_ids=[\"series\"],\n                 train_data_frame=train_data,\n             )\n         \"\"\"\ndiff --git a/flash_examples/integrations/pytorch_forecasting/tabular_forecasting_interpretable.py b/flash_examples/integrations/pytorch_forecasting/tabular_forecasting_interpretable.py\n--- a/flash_examples/integrations/pytorch_forecasting/tabular_forecasting_interpretable.py\n+++ b/flash_examples/integrations/pytorch_forecasting/tabular_forecasting_interpretable.py\n@@ -59,16 +59,12 @@\n predictions = model.predict(data)\n print(predictions)\n \n-# Convert predictions\n+# Plot with PyTorch Forecasting!\n predictions, inputs = convert_predictions(predictions)\n \n-# Plot predictions\n-for idx in range(10):  # plot 10 examples\n-    model.pytorch_forecasting_model.plot_prediction(inputs, predictions, idx=idx, add_loss_to_title=True)\n+fig, axs = plt.subplots(2, 3, sharex=\"col\")\n \n-# Plot interpretation\n-for idx in range(10):  # plot 10 examples\n-    model.pytorch_forecasting_model.plot_interpretation(inputs, predictions, idx=idx)\n+for idx in range(3):\n+    model.pytorch_forecasting_model.plot_interpretation(inputs, predictions, idx=idx, ax=[axs[0][idx], axs[1][idx]])\n \n-# Show the plots!\n plt.show()\n", "issue": "Add a tabular_forecasting example\n\n", "before_files": [{"content": "# Copyright The PyTorch Lightning team.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport torch\n\nimport flash\nfrom flash.core.integrations.pytorch_forecasting import convert_predictions\nfrom flash.core.utilities.imports import example_requires\nfrom flash.tabular.forecasting import TabularForecaster, TabularForecastingData\n\nexample_requires([\"tabular\", \"matplotlib\"])\n\nimport matplotlib.pyplot as plt  # noqa: E402\nimport pandas as pd  # noqa: E402\nfrom pytorch_forecasting.data import NaNLabelEncoder  # noqa: E402\nfrom pytorch_forecasting.data.examples import generate_ar_data  # noqa: E402\n\n# Example based on this tutorial: https://pytorch-forecasting.readthedocs.io/en/latest/tutorials/ar.html\n# 1. Create the DataModule\ndata = generate_ar_data(seasonality=10.0, timesteps=400, n_series=100, seed=42)\ndata[\"date\"] = pd.Timestamp(\"2020-01-01\") + pd.to_timedelta(data.time_idx, \"D\")\n\nmax_prediction_length = 20\n\ntraining_cutoff = data[\"time_idx\"].max() - max_prediction_length\n\ndatamodule = TabularForecastingData.from_data_frame(\n    time_idx=\"time_idx\",\n    target=\"value\",\n    categorical_encoders={\"series\": NaNLabelEncoder().fit(data.series)},\n    group_ids=[\"series\"],\n    # only unknown variable is \"value\" - and N-Beats can also not take any additional variables\n    time_varying_unknown_reals=[\"value\"],\n    max_encoder_length=60,\n    max_prediction_length=max_prediction_length,\n    train_data_frame=data[lambda x: x.time_idx <= training_cutoff],\n    val_data_frame=data,\n    batch_size=32,\n)\n\n# 2. Build the task\nmodel = TabularForecaster(datamodule.parameters, backbone=\"n_beats\", widths=[32, 512], backcast_loss_ratio=0.1)\n\n# 3. Create the trainer and train the model\ntrainer = flash.Trainer(max_epochs=1, gpus=torch.cuda.device_count(), gradient_clip_val=0.01)\ntrainer.fit(model, datamodule=datamodule)\n\n# 4. Generate predictions\npredictions = model.predict(data)\nprint(predictions)\n\n# Convert predictions\npredictions, inputs = convert_predictions(predictions)\n\n# Plot predictions\nfor idx in range(10):  # plot 10 examples\n    model.pytorch_forecasting_model.plot_prediction(inputs, predictions, idx=idx, add_loss_to_title=True)\n\n# Plot interpretation\nfor idx in range(10):  # plot 10 examples\n    model.pytorch_forecasting_model.plot_interpretation(inputs, predictions, idx=idx)\n\n# Show the plots!\nplt.show()\n", "path": "flash_examples/integrations/pytorch_forecasting/tabular_forecasting_interpretable.py"}, {"content": "# Copyright The PyTorch Lightning team.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nfrom copy import copy\nfrom dataclasses import dataclass\nfrom typing import Any, Callable, Dict, List, Mapping, Optional, Union\n\nfrom pytorch_lightning.utilities.exceptions import MisconfigurationException\n\nfrom flash.core.data.callback import BaseDataFetcher\nfrom flash.core.data.data_module import DataModule\nfrom flash.core.data.data_source import DataSource, DefaultDataKeys, DefaultDataSources\nfrom flash.core.data.process import Deserializer, Preprocess\nfrom flash.core.data.properties import ProcessState\nfrom flash.core.utilities.imports import _FORECASTING_AVAILABLE, _PANDAS_AVAILABLE, requires\n\nif _PANDAS_AVAILABLE:\n    from pandas.core.frame import DataFrame\nelse:\n    DataFrame = object\n\nif _FORECASTING_AVAILABLE:\n    from pytorch_forecasting import TimeSeriesDataSet\n\n\n@dataclass(unsafe_hash=True, frozen=True)\nclass TimeSeriesDataSetParametersState(ProcessState):\n    \"\"\"A :class:`~flash.core.data.properties.ProcessState` containing ``labels``, a mapping from class index to\n    label.\"\"\"\n\n    time_series_dataset_parameters: Optional[Dict[str, Any]]\n\n\nclass TabularForecastingDataFrameDataSource(DataSource[DataFrame]):\n    @requires(\"tabular\")\n    def __init__(\n        self,\n        time_idx: str,\n        target: Union[str, List[str]],\n        group_ids: List[str],\n        parameters: Optional[Dict[str, Any]] = None,\n        **data_source_kwargs: Any,\n    ):\n        super().__init__()\n        self.time_idx = time_idx\n        self.target = target\n        self.group_ids = group_ids\n        self.data_source_kwargs = data_source_kwargs\n\n        self.set_state(TimeSeriesDataSetParametersState(parameters))\n\n    def load_data(self, data: DataFrame, dataset: Optional[Any] = None):\n        if self.training:\n            time_series_dataset = TimeSeriesDataSet(\n                data, time_idx=self.time_idx, group_ids=self.group_ids, target=self.target, **self.data_source_kwargs\n            )\n            parameters = time_series_dataset.get_parameters()\n\n            # Add some sample data so that we can recreate the `TimeSeriesDataSet` later on\n            parameters[\"data_sample\"] = data.iloc[[0]]\n\n            self.set_state(TimeSeriesDataSetParametersState(parameters))\n            dataset.parameters = parameters\n        else:\n            parameters = copy(self.get_state(TimeSeriesDataSetParametersState).time_series_dataset_parameters)\n            if parameters is None:\n                raise MisconfigurationException(\n                    \"Loading data for evaluation or inference requires parameters from the train data. Either \"\n                    \"construct the train data at the same time as evaluation and inference or provide the train \"\n                    \"`datamodule.parameters` to `from_data_frame` in the `parameters` argument.\"\n                )\n            parameters.pop(\"data_sample\")\n            time_series_dataset = TimeSeriesDataSet.from_parameters(\n                parameters,\n                data,\n                predict=True,\n                stop_randomization=True,\n            )\n        dataset.time_series_dataset = time_series_dataset\n        return time_series_dataset\n\n    def load_sample(self, sample: Mapping[str, Any], dataset: Optional[Any] = None) -> Any:\n        return {DefaultDataKeys.INPUT: sample[0], DefaultDataKeys.TARGET: sample[1]}\n\n\nclass TabularForecastingPreprocess(Preprocess):\n    def __init__(\n        self,\n        train_transform: Optional[Dict[str, Callable]] = None,\n        val_transform: Optional[Dict[str, Callable]] = None,\n        test_transform: Optional[Dict[str, Callable]] = None,\n        predict_transform: Optional[Dict[str, Callable]] = None,\n        deserializer: Optional[Deserializer] = None,\n        **data_source_kwargs: Any,\n    ):\n        self.data_source_kwargs = data_source_kwargs\n        super().__init__(\n            train_transform=train_transform,\n            val_transform=val_transform,\n            test_transform=test_transform,\n            predict_transform=predict_transform,\n            data_sources={\n                DefaultDataSources.DATAFRAME: TabularForecastingDataFrameDataSource(**data_source_kwargs),\n            },\n            deserializer=deserializer,\n            default_data_source=DefaultDataSources.DATAFRAME,\n        )\n\n    def get_state_dict(self, strict: bool = False) -> Dict[str, Any]:\n        return {**self.transforms, **self.data_source_kwargs}\n\n    @classmethod\n    def load_state_dict(cls, state_dict: Dict[str, Any], strict: bool = True) -> \"Preprocess\":\n        return cls(**state_dict)\n\n\nclass TabularForecastingData(DataModule):\n    \"\"\"Data module for tabular tasks.\"\"\"\n\n    preprocess_cls = TabularForecastingPreprocess\n\n    @property\n    def parameters(self) -> Optional[Dict[str, Any]]:\n        return getattr(self.train_dataset, \"parameters\", None)\n\n    @classmethod\n    def from_data_frame(\n        cls,\n        time_idx: Optional[str] = None,\n        target: Optional[Union[str, List[str]]] = None,\n        group_ids: Optional[List[str]] = None,\n        parameters: Optional[Dict[str, Any]] = None,\n        train_data_frame: Optional[DataFrame] = None,\n        val_data_frame: Optional[DataFrame] = None,\n        test_data_frame: Optional[DataFrame] = None,\n        predict_data_frame: Optional[DataFrame] = None,\n        train_transform: Optional[Dict[str, Callable]] = None,\n        val_transform: Optional[Dict[str, Callable]] = None,\n        test_transform: Optional[Dict[str, Callable]] = None,\n        predict_transform: Optional[Dict[str, Callable]] = None,\n        data_fetcher: Optional[BaseDataFetcher] = None,\n        preprocess: Optional[Preprocess] = None,\n        val_split: Optional[float] = None,\n        batch_size: int = 4,\n        num_workers: Optional[int] = None,\n        **preprocess_kwargs: Any,\n    ):\n        \"\"\"Creates a :class:`~flash.tabular.data.TabularClassificationData` object from the given data frames.\n\n        Args:\n            group_ids:\n            target:\n            time_idx:\n            train_data_frame: The pandas ``DataFrame`` containing the training data.\n            val_data_frame: The pandas ``DataFrame`` containing the validation data.\n            test_data_frame: The pandas ``DataFrame`` containing the testing data.\n            predict_data_frame: The pandas ``DataFrame`` containing the data to use when predicting.\n            train_transform: The dictionary of transforms to use during training which maps\n                :class:`~flash.core.data.process.Preprocess` hook names to callable transforms.\n            val_transform: The dictionary of transforms to use during validation which maps\n                :class:`~flash.core.data.process.Preprocess` hook names to callable transforms.\n            test_transform: The dictionary of transforms to use during testing which maps\n                :class:`~flash.core.data.process.Preprocess` hook names to callable transforms.\n            predict_transform: The dictionary of transforms to use during predicting which maps\n                :class:`~flash.core.data.process.Preprocess` hook names to callable transforms.\n            data_fetcher: The :class:`~flash.core.data.callback.BaseDataFetcher` to pass to the\n                :class:`~flash.core.data.data_module.DataModule`.\n            preprocess: The :class:`~flash.core.data.data.Preprocess` to pass to the\n                :class:`~flash.core.data.data_module.DataModule`. If ``None``, ``cls.preprocess_cls``\n                will be constructed and used.\n            val_split: The ``val_split`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`.\n            batch_size: The ``batch_size`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`.\n            num_workers: The ``num_workers`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`.\n            preprocess_kwargs: Additional keyword arguments to use when constructing the preprocess. Will only be used\n                if ``preprocess = None``.\n\n        Returns:\n            The constructed data module.\n\n        Examples::\n\n            data_module = TabularClassificationData.from_data_frame(\n                \"categorical_input\",\n                \"numerical_input\",\n                \"target\",\n                train_data_frame=train_data,\n            )\n        \"\"\"\n\n        return cls.from_data_source(\n            time_idx=time_idx,\n            target=target,\n            group_ids=group_ids,\n            parameters=parameters,\n            data_source=DefaultDataSources.DATAFRAME,\n            train_data=train_data_frame,\n            val_data=val_data_frame,\n            test_data=test_data_frame,\n            predict_data=predict_data_frame,\n            train_transform=train_transform,\n            val_transform=val_transform,\n            test_transform=test_transform,\n            predict_transform=predict_transform,\n            data_fetcher=data_fetcher,\n            preprocess=preprocess,\n            val_split=val_split,\n            batch_size=batch_size,\n            num_workers=num_workers,\n            **preprocess_kwargs,\n        )\n", "path": "flash/tabular/forecasting/data.py"}], "after_files": [{"content": "# Copyright The PyTorch Lightning team.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport torch\n\nimport flash\nfrom flash.core.integrations.pytorch_forecasting import convert_predictions\nfrom flash.core.utilities.imports import example_requires\nfrom flash.tabular.forecasting import TabularForecaster, TabularForecastingData\n\nexample_requires([\"tabular\", \"matplotlib\"])\n\nimport matplotlib.pyplot as plt  # noqa: E402\nimport pandas as pd  # noqa: E402\nfrom pytorch_forecasting.data import NaNLabelEncoder  # noqa: E402\nfrom pytorch_forecasting.data.examples import generate_ar_data  # noqa: E402\n\n# Example based on this tutorial: https://pytorch-forecasting.readthedocs.io/en/latest/tutorials/ar.html\n# 1. Create the DataModule\ndata = generate_ar_data(seasonality=10.0, timesteps=400, n_series=100, seed=42)\ndata[\"date\"] = pd.Timestamp(\"2020-01-01\") + pd.to_timedelta(data.time_idx, \"D\")\n\nmax_prediction_length = 20\n\ntraining_cutoff = data[\"time_idx\"].max() - max_prediction_length\n\ndatamodule = TabularForecastingData.from_data_frame(\n    time_idx=\"time_idx\",\n    target=\"value\",\n    categorical_encoders={\"series\": NaNLabelEncoder().fit(data.series)},\n    group_ids=[\"series\"],\n    # only unknown variable is \"value\" - and N-Beats can also not take any additional variables\n    time_varying_unknown_reals=[\"value\"],\n    max_encoder_length=60,\n    max_prediction_length=max_prediction_length,\n    train_data_frame=data[lambda x: x.time_idx <= training_cutoff],\n    val_data_frame=data,\n    batch_size=32,\n)\n\n# 2. Build the task\nmodel = TabularForecaster(datamodule.parameters, backbone=\"n_beats\", widths=[32, 512], backcast_loss_ratio=0.1)\n\n# 3. Create the trainer and train the model\ntrainer = flash.Trainer(max_epochs=1, gpus=torch.cuda.device_count(), gradient_clip_val=0.01)\ntrainer.fit(model, datamodule=datamodule)\n\n# 4. Generate predictions\npredictions = model.predict(data)\nprint(predictions)\n\n# Plot with PyTorch Forecasting!\npredictions, inputs = convert_predictions(predictions)\n\nfig, axs = plt.subplots(2, 3, sharex=\"col\")\n\nfor idx in range(3):\n    model.pytorch_forecasting_model.plot_interpretation(inputs, predictions, idx=idx, ax=[axs[0][idx], axs[1][idx]])\n\nplt.show()\n", "path": "flash_examples/integrations/pytorch_forecasting/tabular_forecasting_interpretable.py"}, {"content": "# Copyright The PyTorch Lightning team.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nfrom copy import copy\nfrom dataclasses import dataclass\nfrom typing import Any, Callable, Dict, List, Mapping, Optional, Union\n\nfrom pytorch_lightning.utilities.exceptions import MisconfigurationException\n\nfrom flash.core.data.callback import BaseDataFetcher\nfrom flash.core.data.data_module import DataModule\nfrom flash.core.data.data_source import DataSource, DefaultDataKeys, DefaultDataSources\nfrom flash.core.data.process import Deserializer, Preprocess\nfrom flash.core.data.properties import ProcessState\nfrom flash.core.utilities.imports import _FORECASTING_AVAILABLE, _PANDAS_AVAILABLE, requires\n\nif _PANDAS_AVAILABLE:\n    from pandas.core.frame import DataFrame\nelse:\n    DataFrame = object\n\nif _FORECASTING_AVAILABLE:\n    from pytorch_forecasting import TimeSeriesDataSet\n\n\n@dataclass(unsafe_hash=True, frozen=True)\nclass TimeSeriesDataSetParametersState(ProcessState):\n    \"\"\"A :class:`~flash.core.data.properties.ProcessState` containing ``labels``, a mapping from class index to\n    label.\"\"\"\n\n    time_series_dataset_parameters: Optional[Dict[str, Any]]\n\n\nclass TabularForecastingDataFrameDataSource(DataSource[DataFrame]):\n    @requires(\"tabular\")\n    def __init__(\n        self,\n        time_idx: str,\n        target: Union[str, List[str]],\n        group_ids: List[str],\n        parameters: Optional[Dict[str, Any]] = None,\n        **data_source_kwargs: Any,\n    ):\n        super().__init__()\n        self.time_idx = time_idx\n        self.target = target\n        self.group_ids = group_ids\n        self.data_source_kwargs = data_source_kwargs\n\n        self.set_state(TimeSeriesDataSetParametersState(parameters))\n\n    def load_data(self, data: DataFrame, dataset: Optional[Any] = None):\n        if self.training:\n            time_series_dataset = TimeSeriesDataSet(\n                data, time_idx=self.time_idx, group_ids=self.group_ids, target=self.target, **self.data_source_kwargs\n            )\n            parameters = time_series_dataset.get_parameters()\n\n            # Add some sample data so that we can recreate the `TimeSeriesDataSet` later on\n            parameters[\"data_sample\"] = data.iloc[[0]]\n\n            self.set_state(TimeSeriesDataSetParametersState(parameters))\n            dataset.parameters = parameters\n        else:\n            parameters = copy(self.get_state(TimeSeriesDataSetParametersState).time_series_dataset_parameters)\n            if parameters is None:\n                raise MisconfigurationException(\n                    \"Loading data for evaluation or inference requires parameters from the train data. Either \"\n                    \"construct the train data at the same time as evaluation and inference or provide the train \"\n                    \"`datamodule.parameters` to `from_data_frame` in the `parameters` argument.\"\n                )\n            parameters.pop(\"data_sample\")\n            time_series_dataset = TimeSeriesDataSet.from_parameters(\n                parameters,\n                data,\n                predict=True,\n                stop_randomization=True,\n            )\n        dataset.time_series_dataset = time_series_dataset\n        return time_series_dataset\n\n    def load_sample(self, sample: Mapping[str, Any], dataset: Optional[Any] = None) -> Any:\n        return {DefaultDataKeys.INPUT: sample[0], DefaultDataKeys.TARGET: sample[1]}\n\n\nclass TabularForecastingPreprocess(Preprocess):\n    def __init__(\n        self,\n        train_transform: Optional[Dict[str, Callable]] = None,\n        val_transform: Optional[Dict[str, Callable]] = None,\n        test_transform: Optional[Dict[str, Callable]] = None,\n        predict_transform: Optional[Dict[str, Callable]] = None,\n        deserializer: Optional[Deserializer] = None,\n        **data_source_kwargs: Any,\n    ):\n        self.data_source_kwargs = data_source_kwargs\n        super().__init__(\n            train_transform=train_transform,\n            val_transform=val_transform,\n            test_transform=test_transform,\n            predict_transform=predict_transform,\n            data_sources={\n                DefaultDataSources.DATAFRAME: TabularForecastingDataFrameDataSource(**data_source_kwargs),\n            },\n            deserializer=deserializer,\n            default_data_source=DefaultDataSources.DATAFRAME,\n        )\n\n    def get_state_dict(self, strict: bool = False) -> Dict[str, Any]:\n        return {**self.transforms, **self.data_source_kwargs}\n\n    @classmethod\n    def load_state_dict(cls, state_dict: Dict[str, Any], strict: bool = True) -> \"Preprocess\":\n        return cls(**state_dict)\n\n\nclass TabularForecastingData(DataModule):\n    \"\"\"Data module for the tabular forecasting task.\"\"\"\n\n    preprocess_cls = TabularForecastingPreprocess\n\n    @property\n    def parameters(self) -> Optional[Dict[str, Any]]:\n        \"\"\"The parameters dictionary from the ``TimeSeriesDataSet`` object created from the train data when\n        constructing the ``TabularForecastingData`` object.\"\"\"\n        return getattr(self.train_dataset, \"parameters\", None)\n\n    @classmethod\n    def from_data_frame(\n        cls,\n        time_idx: Optional[str] = None,\n        target: Optional[Union[str, List[str]]] = None,\n        group_ids: Optional[List[str]] = None,\n        parameters: Optional[Dict[str, Any]] = None,\n        train_data_frame: Optional[DataFrame] = None,\n        val_data_frame: Optional[DataFrame] = None,\n        test_data_frame: Optional[DataFrame] = None,\n        predict_data_frame: Optional[DataFrame] = None,\n        train_transform: Optional[Dict[str, Callable]] = None,\n        val_transform: Optional[Dict[str, Callable]] = None,\n        test_transform: Optional[Dict[str, Callable]] = None,\n        predict_transform: Optional[Dict[str, Callable]] = None,\n        data_fetcher: Optional[BaseDataFetcher] = None,\n        preprocess: Optional[Preprocess] = None,\n        val_split: Optional[float] = None,\n        batch_size: int = 4,\n        num_workers: Optional[int] = None,\n        **preprocess_kwargs: Any,\n    ):\n        \"\"\"Creates a :class:`~flash.tabular.forecasting.data.TabularForecastingData` object from the given data\n        frames.\n\n        .. note::\n\n            The ``time_idx``, ``target``, and ``group_ids`` do not need to be provided if ``parameters`` are passed\n            instead. These can be obtained from the\n            :attr:`~flash.tabular.forecasting.data.TabularForecastingData.parameters` attribute of the\n            :class:`~flash.tabular.forecasting.data.TabularForecastingData` object that contains your training data.\n\n        Args:\n            time_idx:\n            target: Column denoting the target or list of columns denoting the target.\n            group_ids: List of column names identifying a time series. This means that the group_ids identify a sample\n                together with the time_idx. If you have only one timeseries, set this to the name of column that is\n                constant.\n            parameters: Parameters to use for the timeseries if ``time_idx``, ``target``, and ``group_ids`` are not\n                provided (e.g. when loading data for inference or validation).\n            train_data_frame: The pandas ``DataFrame`` containing the training data.\n            val_data_frame: The pandas ``DataFrame`` containing the validation data.\n            test_data_frame: The pandas ``DataFrame`` containing the testing data.\n            predict_data_frame: The pandas ``DataFrame`` containing the data to use when predicting.\n            train_transform: The dictionary of transforms to use during training which maps\n                :class:`~flash.core.data.process.Preprocess` hook names to callable transforms.\n            val_transform: The dictionary of transforms to use during validation which maps\n                :class:`~flash.core.data.process.Preprocess` hook names to callable transforms.\n            test_transform: The dictionary of transforms to use during testing which maps\n                :class:`~flash.core.data.process.Preprocess` hook names to callable transforms.\n            predict_transform: The dictionary of transforms to use during predicting which maps\n                :class:`~flash.core.data.process.Preprocess` hook names to callable transforms.\n            data_fetcher: The :class:`~flash.core.data.callback.BaseDataFetcher` to pass to the\n                :class:`~flash.core.data.data_module.DataModule`.\n            preprocess: The :class:`~flash.core.data.data.Preprocess` to pass to the\n                :class:`~flash.core.data.data_module.DataModule`. If ``None``, ``cls.preprocess_cls``\n                will be constructed and used.\n            val_split: The ``val_split`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`.\n            batch_size: The ``batch_size`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`.\n            num_workers: The ``num_workers`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`.\n            preprocess_kwargs: Additional keyword arguments to use when constructing the preprocess. Will only be used\n                if ``preprocess = None``.\n\n        Returns:\n            The constructed data module.\n\n        Examples::\n\n            data_module = TabularForecastingData.from_data_frame(\n                time_idx=\"time_idx\",\n                target=\"value\",\n                group_ids=[\"series\"],\n                train_data_frame=train_data,\n            )\n        \"\"\"\n\n        return cls.from_data_source(\n            time_idx=time_idx,\n            target=target,\n            group_ids=group_ids,\n            parameters=parameters,\n            data_source=DefaultDataSources.DATAFRAME,\n            train_data=train_data_frame,\n            val_data=val_data_frame,\n            test_data=test_data_frame,\n            predict_data=predict_data_frame,\n            train_transform=train_transform,\n            val_transform=val_transform,\n            test_transform=test_transform,\n            predict_transform=predict_transform,\n            data_fetcher=data_fetcher,\n            preprocess=preprocess,\n            val_split=val_split,\n            batch_size=batch_size,\n            num_workers=num_workers,\n            **preprocess_kwargs,\n        )\n", "path": "flash/tabular/forecasting/data.py"}]}