We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Anomaly detection example is not working anymore
## Description
Probably due to code changes, the `anomaly_detecion.py` inside `examples` folder is not working
## To Reproduce


Here's the original code:

```python
if __name__ == "__main__":

    dataset = get_dataset(dataset_name="electricity")

    estimator = DeepAREstimator(
        prediction_length=dataset.metadata.prediction_length,
        freq=dataset.metadata.freq,
        trainer=Trainer(
            learning_rate=1e-3, epochs=50, num_batches_per_epoch=100
        ),
    )

    # instead of calling `train` method, we call `train_model` that returns more things including the training model
    train_output = estimator.train_model(dataset.train)

    # we construct a data_entry that contains 500 random windows
    batch_size = 500
    num_samples = 100
    training_data_loader = TrainDataLoader(
        dataset=dataset.train,
        transform=train_output.transformation,
        batch_size=batch_size,
        num_batches_per_epoch=estimator.trainer.num_batches_per_epoch,
        ctx=mx.cpu(),
    )

    for data_entry in islice(training_data_loader, 1):
        pass

    # we now call the train model to get the predicted distribution on each window
    # this allows us to investigate where are the biggest anomalies
    context_length = train_output.trained_net.context_length
    prediction_length = train_output.trained_net.prediction_length

    input_names = get_hybrid_forward_input_names(train_output.trained_net)

    distr = train_output.trained_net.distribution(
        *[data_entry[k] for k in input_names]
    )

    # gets all information into numpy array for further plotting
    samples = distr.sample(num_samples).asnumpy()
    percentiles = np.percentile(samples, axis=0, q=[10.0, 90.0])
    target = mx.ndarray.concat(
        data_entry["past_target"], data_entry["future_target"], dim=1
    )
    target = target[:, -(context_length + prediction_length) :]
    nll = -distr.log_prob(target).asnumpy()
    target = target.asnumpy()
    mean = samples.mean(axis=0)
    percentiles = np.percentile(samples, axis=0, q=[10.0, 90.0])

    # NLL indices from largest to smallest
    sorted_indices = np.argsort(nll.reshape(-1))[::-1]

    # shows the series and times when the 20 largest NLL were observed
    for k in sorted_indices[:20]:
        i = k // nll.shape[1]
        t = k % nll.shape[1]

        time_index = pd.date_range(
            pd.Timestamp(data_entry["forecast_start"][i]),
            periods=context_length + prediction_length,
        )
        time_index -= context_length * time_index.freq

        plt.figure(figsize=(10, 4))
        plt.fill_between(
            time_index,
            percentiles[0, i],
            percentiles[-1, i],
            alpha=0.5,
            label="80% CI predicted",
        )
        plt.plot(time_index, target[i], label="target")
        plt.axvline(time_index[t], alpha=0.5, color="r")
        plt.title(f"NLL: {nll[i, t]}")
        plt.legend()
        plt.show()
```




I made some changes when trying to run it.
More specifically:

I changed  `training_data_loader` (as it now requires `stack_fn` ) to 

```python
    training_data_loader = TrainDataLoader(
                                            dataset=dataset.train, 
                                            transform=train_output.transformation,        
                                            batch_size=batch_size,
                                            num_batches_per_epoch=estimator.trainer.num_batches_per_epoch,
                                            stack_fn=partial(batchify,ctx=estimator.trainer.ctx, dtype=estimator.dtype))
```

and added `type` to

```python
input_names = get_hybrid_forward_input_names(type(train_output.trained_net))
```

but I still get error in 

```python
distr = train_output.trained_net.distribution(
    *[data_entry[k] for k in input_names]
)
```
## Error message or code output

```
KeyError                                  Traceback (most recent call last)
<ipython-input-6-dee0a4a5f14a> in <module>()
     38 
     39 distr = train_output.trained_net.distribution(
---> 40     *[data_entry[k] for k in input_names]
     41 )
     42 

<ipython-input-6-dee0a4a5f14a> in <listcomp>(.0)
     38 
     39 distr = train_output.trained_net.distribution(
---> 40     *[data_entry[k] for k in input_names]
     41 )
     42 

KeyError: 'past_time_feat'
```

Not all names inside `input_names = ['feat_static_cat',
 'feat_static_real',
 'past_time_feat',
 'past_target',
 'past_observed_values',
 'past_is_pad',
 'future_time_feat',
 'future_target',
 'future_observed_values']` are keys of `data_entry = dict_keys(['start', 'target', 'feat_static_cat', 'item_id', 'source', 'feat_static_real', 'observed_values', 'time_feat'])`  


## Environment
- Operating system: Ubuntu
- Python version: 3.7.10
- GluonTS version: 0.7.3
- MXNet version: 1.6

How should I fix it?
Thanks!


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `examples/anomaly_detection.py`
Content:
```
1 # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
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 # A copy of the License is located at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # or in the "license" file accompanying this file. This file is distributed
10 # on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 # express or implied. See the License for the specific language governing
12 # permissions and limitations under the License.
13 
14 """
15 This example shows how to do anomaly detection with DeepAR.
16 The model is first trained and then time-points with the largest negative log-likelihood are plotted.
17 """
18 import numpy as np
19 from itertools import islice
20 import mxnet as mx
21 import matplotlib.pyplot as plt
22 import pandas as pd
23 from pandas.plotting import register_matplotlib_converters
24 
25 register_matplotlib_converters()
26 
27 from gluonts.dataset.loader import TrainDataLoader
28 from gluonts.model.deepar import DeepAREstimator
29 from gluonts.mx.util import get_hybrid_forward_input_names
30 from gluonts.mx.trainer import Trainer
31 from gluonts.dataset.repository.datasets import get_dataset
32 
33 
34 if __name__ == "__main__":
35 
36     dataset = get_dataset(dataset_name="electricity")
37 
38     estimator = DeepAREstimator(
39         prediction_length=dataset.metadata.prediction_length,
40         freq=dataset.metadata.freq,
41         trainer=Trainer(
42             learning_rate=1e-3, epochs=50, num_batches_per_epoch=100
43         ),
44     )
45 
46     # instead of calling `train` method, we call `train_model` that returns more things including the training model
47     train_output = estimator.train_model(dataset.train)
48 
49     # we construct a data_entry that contains 500 random windows
50     batch_size = 500
51     num_samples = 100
52     training_data_loader = TrainDataLoader(
53         dataset=dataset.train,
54         transform=train_output.transformation,
55         batch_size=batch_size,
56         num_batches_per_epoch=estimator.trainer.num_batches_per_epoch,
57         ctx=mx.cpu(),
58     )
59 
60     for data_entry in islice(training_data_loader, 1):
61         pass
62 
63     # we now call the train model to get the predicted distribution on each window
64     # this allows us to investigate where are the biggest anomalies
65     context_length = train_output.trained_net.context_length
66     prediction_length = train_output.trained_net.prediction_length
67 
68     input_names = get_hybrid_forward_input_names(train_output.trained_net)
69 
70     distr = train_output.trained_net.distribution(
71         *[data_entry[k] for k in input_names]
72     )
73 
74     # gets all information into numpy array for further plotting
75     samples = distr.sample(num_samples).asnumpy()
76     percentiles = np.percentile(samples, axis=0, q=[10.0, 90.0])
77     target = mx.ndarray.concat(
78         data_entry["past_target"], data_entry["future_target"], dim=1
79     )
80     target = target[:, -(context_length + prediction_length) :]
81     nll = -distr.log_prob(target).asnumpy()
82     target = target.asnumpy()
83     mean = samples.mean(axis=0)
84     percentiles = np.percentile(samples, axis=0, q=[10.0, 90.0])
85 
86     # NLL indices from largest to smallest
87     sorted_indices = np.argsort(nll.reshape(-1))[::-1]
88 
89     # shows the series and times when the 20 largest NLL were observed
90     for k in sorted_indices[:20]:
91         i = k // nll.shape[1]
92         t = k % nll.shape[1]
93 
94         time_index = pd.date_range(
95             pd.Timestamp(data_entry["forecast_start"][i]),
96             periods=context_length + prediction_length,
97         )
98         time_index -= context_length * time_index.freq
99 
100         plt.figure(figsize=(10, 4))
101         plt.fill_between(
102             time_index,
103             percentiles[0, i],
104             percentiles[-1, i],
105             alpha=0.5,
106             label="80% CI predicted",
107         )
108         plt.plot(time_index, target[i], label="target")
109         plt.axvline(time_index[t], alpha=0.5, color="r")
110         plt.title(f"NLL: {nll[i, t]}")
111         plt.legend()
112         plt.show()
113
```
--- 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/examples/anomaly_detection.py b/examples/anomaly_detection.py
--- a/examples/anomaly_detection.py
+++ b/examples/anomaly_detection.py
@@ -17,6 +17,7 @@
 """
 import numpy as np
 from itertools import islice
+from functools import partial
 import mxnet as mx
 import matplotlib.pyplot as plt
 import pandas as pd
@@ -28,6 +29,7 @@
 from gluonts.model.deepar import DeepAREstimator
 from gluonts.mx.util import get_hybrid_forward_input_names
 from gluonts.mx.trainer import Trainer
+from gluonts.mx.batchify import batchify
 from gluonts.dataset.repository.datasets import get_dataset
 
 
@@ -39,34 +41,38 @@
         prediction_length=dataset.metadata.prediction_length,
         freq=dataset.metadata.freq,
         trainer=Trainer(
-            learning_rate=1e-3, epochs=50, num_batches_per_epoch=100
+            learning_rate=1e-3, epochs=20, num_batches_per_epoch=100
         ),
     )
 
     # instead of calling `train` method, we call `train_model` that returns more things including the training model
     train_output = estimator.train_model(dataset.train)
 
+    input_names = get_hybrid_forward_input_names(
+        type(train_output.trained_net)
+    )
+
     # we construct a data_entry that contains 500 random windows
     batch_size = 500
     num_samples = 100
+    instance_splitter = estimator._create_instance_splitter("training")
     training_data_loader = TrainDataLoader(
         dataset=dataset.train,
-        transform=train_output.transformation,
+        transform=train_output.transformation + instance_splitter,
         batch_size=batch_size,
         num_batches_per_epoch=estimator.trainer.num_batches_per_epoch,
-        ctx=mx.cpu(),
+        stack_fn=partial(
+            batchify, ctx=estimator.trainer.ctx, dtype=estimator.dtype
+        ),
     )
 
-    for data_entry in islice(training_data_loader, 1):
-        pass
+    data_entry = next(iter(training_data_loader))
 
     # we now call the train model to get the predicted distribution on each window
     # this allows us to investigate where are the biggest anomalies
     context_length = train_output.trained_net.context_length
     prediction_length = train_output.trained_net.prediction_length
 
-    input_names = get_hybrid_forward_input_names(train_output.trained_net)
-
     distr = train_output.trained_net.distribution(
         *[data_entry[k] for k in input_names]
     )

{"golden_diff": "diff --git a/examples/anomaly_detection.py b/examples/anomaly_detection.py\n--- a/examples/anomaly_detection.py\n+++ b/examples/anomaly_detection.py\n@@ -17,6 +17,7 @@\n \"\"\"\n import numpy as np\n from itertools import islice\n+from functools import partial\n import mxnet as mx\n import matplotlib.pyplot as plt\n import pandas as pd\n@@ -28,6 +29,7 @@\n from gluonts.model.deepar import DeepAREstimator\n from gluonts.mx.util import get_hybrid_forward_input_names\n from gluonts.mx.trainer import Trainer\n+from gluonts.mx.batchify import batchify\n from gluonts.dataset.repository.datasets import get_dataset\n \n \n@@ -39,34 +41,38 @@\n         prediction_length=dataset.metadata.prediction_length,\n         freq=dataset.metadata.freq,\n         trainer=Trainer(\n-            learning_rate=1e-3, epochs=50, num_batches_per_epoch=100\n+            learning_rate=1e-3, epochs=20, num_batches_per_epoch=100\n         ),\n     )\n \n     # instead of calling `train` method, we call `train_model` that returns more things including the training model\n     train_output = estimator.train_model(dataset.train)\n \n+    input_names = get_hybrid_forward_input_names(\n+        type(train_output.trained_net)\n+    )\n+\n     # we construct a data_entry that contains 500 random windows\n     batch_size = 500\n     num_samples = 100\n+    instance_splitter = estimator._create_instance_splitter(\"training\")\n     training_data_loader = TrainDataLoader(\n         dataset=dataset.train,\n-        transform=train_output.transformation,\n+        transform=train_output.transformation + instance_splitter,\n         batch_size=batch_size,\n         num_batches_per_epoch=estimator.trainer.num_batches_per_epoch,\n-        ctx=mx.cpu(),\n+        stack_fn=partial(\n+            batchify, ctx=estimator.trainer.ctx, dtype=estimator.dtype\n+        ),\n     )\n \n-    for data_entry in islice(training_data_loader, 1):\n-        pass\n+    data_entry = next(iter(training_data_loader))\n \n     # we now call the train model to get the predicted distribution on each window\n     # this allows us to investigate where are the biggest anomalies\n     context_length = train_output.trained_net.context_length\n     prediction_length = train_output.trained_net.prediction_length\n \n-    input_names = get_hybrid_forward_input_names(train_output.trained_net)\n-\n     distr = train_output.trained_net.distribution(\n         *[data_entry[k] for k in input_names]\n     )\n", "issue": "Anomaly detection example is not working anymore\n## Description\r\nProbably due to code changes, the `anomaly_detecion.py` inside `examples` folder is not working\r\n## To Reproduce\r\n\r\n\r\nHere's the original code:\r\n\r\n```python\r\nif __name__ == \"__main__\":\r\n\r\n    dataset = get_dataset(dataset_name=\"electricity\")\r\n\r\n    estimator = DeepAREstimator(\r\n        prediction_length=dataset.metadata.prediction_length,\r\n        freq=dataset.metadata.freq,\r\n        trainer=Trainer(\r\n            learning_rate=1e-3, epochs=50, num_batches_per_epoch=100\r\n        ),\r\n    )\r\n\r\n    # instead of calling `train` method, we call `train_model` that returns more things including the training model\r\n    train_output = estimator.train_model(dataset.train)\r\n\r\n    # we construct a data_entry that contains 500 random windows\r\n    batch_size = 500\r\n    num_samples = 100\r\n    training_data_loader = TrainDataLoader(\r\n        dataset=dataset.train,\r\n        transform=train_output.transformation,\r\n        batch_size=batch_size,\r\n        num_batches_per_epoch=estimator.trainer.num_batches_per_epoch,\r\n        ctx=mx.cpu(),\r\n    )\r\n\r\n    for data_entry in islice(training_data_loader, 1):\r\n        pass\r\n\r\n    # we now call the train model to get the predicted distribution on each window\r\n    # this allows us to investigate where are the biggest anomalies\r\n    context_length = train_output.trained_net.context_length\r\n    prediction_length = train_output.trained_net.prediction_length\r\n\r\n    input_names = get_hybrid_forward_input_names(train_output.trained_net)\r\n\r\n    distr = train_output.trained_net.distribution(\r\n        *[data_entry[k] for k in input_names]\r\n    )\r\n\r\n    # gets all information into numpy array for further plotting\r\n    samples = distr.sample(num_samples).asnumpy()\r\n    percentiles = np.percentile(samples, axis=0, q=[10.0, 90.0])\r\n    target = mx.ndarray.concat(\r\n        data_entry[\"past_target\"], data_entry[\"future_target\"], dim=1\r\n    )\r\n    target = target[:, -(context_length + prediction_length) :]\r\n    nll = -distr.log_prob(target).asnumpy()\r\n    target = target.asnumpy()\r\n    mean = samples.mean(axis=0)\r\n    percentiles = np.percentile(samples, axis=0, q=[10.0, 90.0])\r\n\r\n    # NLL indices from largest to smallest\r\n    sorted_indices = np.argsort(nll.reshape(-1))[::-1]\r\n\r\n    # shows the series and times when the 20 largest NLL were observed\r\n    for k in sorted_indices[:20]:\r\n        i = k // nll.shape[1]\r\n        t = k % nll.shape[1]\r\n\r\n        time_index = pd.date_range(\r\n            pd.Timestamp(data_entry[\"forecast_start\"][i]),\r\n            periods=context_length + prediction_length,\r\n        )\r\n        time_index -= context_length * time_index.freq\r\n\r\n        plt.figure(figsize=(10, 4))\r\n        plt.fill_between(\r\n            time_index,\r\n            percentiles[0, i],\r\n            percentiles[-1, i],\r\n            alpha=0.5,\r\n            label=\"80% CI predicted\",\r\n        )\r\n        plt.plot(time_index, target[i], label=\"target\")\r\n        plt.axvline(time_index[t], alpha=0.5, color=\"r\")\r\n        plt.title(f\"NLL: {nll[i, t]}\")\r\n        plt.legend()\r\n        plt.show()\r\n```\r\n\r\n\r\n\r\n\r\nI made some changes when trying to run it.\r\nMore specifically:\r\n\r\nI changed  `training_data_loader` (as it now requires `stack_fn` ) to \r\n\r\n```python\r\n    training_data_loader = TrainDataLoader(\r\n                                            dataset=dataset.train, \r\n                                            transform=train_output.transformation,        \r\n                                            batch_size=batch_size,\r\n                                            num_batches_per_epoch=estimator.trainer.num_batches_per_epoch,\r\n                                            stack_fn=partial(batchify,ctx=estimator.trainer.ctx, dtype=estimator.dtype))\r\n```\r\n\r\nand added `type` to\r\n\r\n```python\r\ninput_names = get_hybrid_forward_input_names(type(train_output.trained_net))\r\n```\r\n\r\nbut I still get error in \r\n\r\n```python\r\ndistr = train_output.trained_net.distribution(\r\n    *[data_entry[k] for k in input_names]\r\n)\r\n```\r\n## Error message or code output\r\n\r\n```\r\nKeyError                                  Traceback (most recent call last)\r\n<ipython-input-6-dee0a4a5f14a> in <module>()\r\n     38 \r\n     39 distr = train_output.trained_net.distribution(\r\n---> 40     *[data_entry[k] for k in input_names]\r\n     41 )\r\n     42 \r\n\r\n<ipython-input-6-dee0a4a5f14a> in <listcomp>(.0)\r\n     38 \r\n     39 distr = train_output.trained_net.distribution(\r\n---> 40     *[data_entry[k] for k in input_names]\r\n     41 )\r\n     42 \r\n\r\nKeyError: 'past_time_feat'\r\n```\r\n\r\nNot all names inside `input_names = ['feat_static_cat',\r\n 'feat_static_real',\r\n 'past_time_feat',\r\n 'past_target',\r\n 'past_observed_values',\r\n 'past_is_pad',\r\n 'future_time_feat',\r\n 'future_target',\r\n 'future_observed_values']` are keys of `data_entry = dict_keys(['start', 'target', 'feat_static_cat', 'item_id', 'source', 'feat_static_real', 'observed_values', 'time_feat'])`  \r\n\r\n\r\n## Environment\r\n- Operating system: Ubuntu\r\n- Python version: 3.7.10\r\n- GluonTS version: 0.7.3\r\n- MXNet version: 1.6\r\n\r\nHow should I fix it?\r\nThanks!\r\n\n", "before_files": [{"content": "# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.\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# A copy of the License is located at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# or in the \"license\" file accompanying this file. This file is distributed\n# on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either\n# express or implied. See the License for the specific language governing\n# permissions and limitations under the License.\n\n\"\"\"\nThis example shows how to do anomaly detection with DeepAR.\nThe model is first trained and then time-points with the largest negative log-likelihood are plotted.\n\"\"\"\nimport numpy as np\nfrom itertools import islice\nimport mxnet as mx\nimport matplotlib.pyplot as plt\nimport pandas as pd\nfrom pandas.plotting import register_matplotlib_converters\n\nregister_matplotlib_converters()\n\nfrom gluonts.dataset.loader import TrainDataLoader\nfrom gluonts.model.deepar import DeepAREstimator\nfrom gluonts.mx.util import get_hybrid_forward_input_names\nfrom gluonts.mx.trainer import Trainer\nfrom gluonts.dataset.repository.datasets import get_dataset\n\n\nif __name__ == \"__main__\":\n\n    dataset = get_dataset(dataset_name=\"electricity\")\n\n    estimator = DeepAREstimator(\n        prediction_length=dataset.metadata.prediction_length,\n        freq=dataset.metadata.freq,\n        trainer=Trainer(\n            learning_rate=1e-3, epochs=50, num_batches_per_epoch=100\n        ),\n    )\n\n    # instead of calling `train` method, we call `train_model` that returns more things including the training model\n    train_output = estimator.train_model(dataset.train)\n\n    # we construct a data_entry that contains 500 random windows\n    batch_size = 500\n    num_samples = 100\n    training_data_loader = TrainDataLoader(\n        dataset=dataset.train,\n        transform=train_output.transformation,\n        batch_size=batch_size,\n        num_batches_per_epoch=estimator.trainer.num_batches_per_epoch,\n        ctx=mx.cpu(),\n    )\n\n    for data_entry in islice(training_data_loader, 1):\n        pass\n\n    # we now call the train model to get the predicted distribution on each window\n    # this allows us to investigate where are the biggest anomalies\n    context_length = train_output.trained_net.context_length\n    prediction_length = train_output.trained_net.prediction_length\n\n    input_names = get_hybrid_forward_input_names(train_output.trained_net)\n\n    distr = train_output.trained_net.distribution(\n        *[data_entry[k] for k in input_names]\n    )\n\n    # gets all information into numpy array for further plotting\n    samples = distr.sample(num_samples).asnumpy()\n    percentiles = np.percentile(samples, axis=0, q=[10.0, 90.0])\n    target = mx.ndarray.concat(\n        data_entry[\"past_target\"], data_entry[\"future_target\"], dim=1\n    )\n    target = target[:, -(context_length + prediction_length) :]\n    nll = -distr.log_prob(target).asnumpy()\n    target = target.asnumpy()\n    mean = samples.mean(axis=0)\n    percentiles = np.percentile(samples, axis=0, q=[10.0, 90.0])\n\n    # NLL indices from largest to smallest\n    sorted_indices = np.argsort(nll.reshape(-1))[::-1]\n\n    # shows the series and times when the 20 largest NLL were observed\n    for k in sorted_indices[:20]:\n        i = k // nll.shape[1]\n        t = k % nll.shape[1]\n\n        time_index = pd.date_range(\n            pd.Timestamp(data_entry[\"forecast_start\"][i]),\n            periods=context_length + prediction_length,\n        )\n        time_index -= context_length * time_index.freq\n\n        plt.figure(figsize=(10, 4))\n        plt.fill_between(\n            time_index,\n            percentiles[0, i],\n            percentiles[-1, i],\n            alpha=0.5,\n            label=\"80% CI predicted\",\n        )\n        plt.plot(time_index, target[i], label=\"target\")\n        plt.axvline(time_index[t], alpha=0.5, color=\"r\")\n        plt.title(f\"NLL: {nll[i, t]}\")\n        plt.legend()\n        plt.show()\n", "path": "examples/anomaly_detection.py"}], "after_files": [{"content": "# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.\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# A copy of the License is located at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# or in the \"license\" file accompanying this file. This file is distributed\n# on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either\n# express or implied. See the License for the specific language governing\n# permissions and limitations under the License.\n\n\"\"\"\nThis example shows how to do anomaly detection with DeepAR.\nThe model is first trained and then time-points with the largest negative log-likelihood are plotted.\n\"\"\"\nimport numpy as np\nfrom itertools import islice\nfrom functools import partial\nimport mxnet as mx\nimport matplotlib.pyplot as plt\nimport pandas as pd\nfrom pandas.plotting import register_matplotlib_converters\n\nregister_matplotlib_converters()\n\nfrom gluonts.dataset.loader import TrainDataLoader\nfrom gluonts.model.deepar import DeepAREstimator\nfrom gluonts.mx.util import get_hybrid_forward_input_names\nfrom gluonts.mx.trainer import Trainer\nfrom gluonts.mx.batchify import batchify\nfrom gluonts.dataset.repository.datasets import get_dataset\n\n\nif __name__ == \"__main__\":\n\n    dataset = get_dataset(dataset_name=\"electricity\")\n\n    estimator = DeepAREstimator(\n        prediction_length=dataset.metadata.prediction_length,\n        freq=dataset.metadata.freq,\n        trainer=Trainer(\n            learning_rate=1e-3, epochs=20, num_batches_per_epoch=100\n        ),\n    )\n\n    # instead of calling `train` method, we call `train_model` that returns more things including the training model\n    train_output = estimator.train_model(dataset.train)\n\n    input_names = get_hybrid_forward_input_names(\n        type(train_output.trained_net)\n    )\n\n    # we construct a data_entry that contains 500 random windows\n    batch_size = 500\n    num_samples = 100\n    instance_splitter = estimator._create_instance_splitter(\"training\")\n    training_data_loader = TrainDataLoader(\n        dataset=dataset.train,\n        transform=train_output.transformation + instance_splitter,\n        batch_size=batch_size,\n        num_batches_per_epoch=estimator.trainer.num_batches_per_epoch,\n        stack_fn=partial(\n            batchify, ctx=estimator.trainer.ctx, dtype=estimator.dtype\n        ),\n    )\n\n    data_entry = next(iter(training_data_loader))\n\n    # we now call the train model to get the predicted distribution on each window\n    # this allows us to investigate where are the biggest anomalies\n    context_length = train_output.trained_net.context_length\n    prediction_length = train_output.trained_net.prediction_length\n\n    distr = train_output.trained_net.distribution(\n        *[data_entry[k] for k in input_names]\n    )\n\n    # gets all information into numpy array for further plotting\n    samples = distr.sample(num_samples).asnumpy()\n    percentiles = np.percentile(samples, axis=0, q=[10.0, 90.0])\n    target = mx.ndarray.concat(\n        data_entry[\"past_target\"], data_entry[\"future_target\"], dim=1\n    )\n    target = target[:, -(context_length + prediction_length) :]\n    nll = -distr.log_prob(target).asnumpy()\n    target = target.asnumpy()\n    mean = samples.mean(axis=0)\n    percentiles = np.percentile(samples, axis=0, q=[10.0, 90.0])\n\n    # NLL indices from largest to smallest\n    sorted_indices = np.argsort(nll.reshape(-1))[::-1]\n\n    # shows the series and times when the 20 largest NLL were observed\n    for k in sorted_indices[:20]:\n        i = k // nll.shape[1]\n        t = k % nll.shape[1]\n\n        time_index = pd.date_range(\n            pd.Timestamp(data_entry[\"forecast_start\"][i]),\n            periods=context_length + prediction_length,\n        )\n        time_index -= context_length * time_index.freq\n\n        plt.figure(figsize=(10, 4))\n        plt.fill_between(\n            time_index,\n            percentiles[0, i],\n            percentiles[-1, i],\n            alpha=0.5,\n            label=\"80% CI predicted\",\n        )\n        plt.plot(time_index, target[i], label=\"target\")\n        plt.axvline(time_index[t], alpha=0.5, color=\"r\")\n        plt.title(f\"NLL: {nll[i, t]}\")\n        plt.legend()\n        plt.show()\n", "path": "examples/anomaly_detection.py"}]}