{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Tutorial for Mixture of Expert (MoE) Forecasting Model\n", "\n", "This notebook provides a minimal example on how to use the MoE forecasting model.\n", "\n", "MoE runs in 2 settings:\n", "1. Using external expert models\n", "2. Using free parameters (no external experts)\n", "\n", "Example codes are provided for both cases below." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "ERROR:root:The 'log_level' trait of an IPKernelApp instance expected any of [0, 10, 20, 30, 40, 50, 'DEBUG', 'INFO', 'WARN', 'ERROR', 'CRITICAL'], not the str 'WORKAROUND'.\n" ] } ], "source": [ "# workaround to enable info-level logging in Jupyter notebook\n", "%config Application.log_level='WORKAROUND'\n", "%config Application.log_level='INFO'\n", "import logging\n", "logging.getLogger().setLevel(logging.INFO)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Load dataset\n", "\n", "Note: change data dir below if inappropriate" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "scrolled": true }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:numexpr.utils:Note: NumExpr detected 16 cores but \"NUMEXPR_MAX_THREADS\" not set, so enforcing safe limit of 8.\n", "INFO:numexpr.utils:NumExpr defaulting to 8 threads.\n", "100%|██████████| 414/414 [00:00<00:00, 610.42it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "(748, 1)\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import pandas as pd\n", "\n", "from ts_datasets.forecast import *\n", "\n", "time_series, metadata = M4()[0]\n", "print(time_series.shape)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, we'll split the data into train & test splits. Visualize the 0th dim of the data." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "train timeseries shape: (700, 1)\n", "test timeseries shape: (48, 1)\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "<Figure size 432x288 with 1 Axes>" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "text/plain": [ "[<matplotlib.lines.Line2D at 0x7fda90599730>]" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "<Figure size 432x288 with 1 Axes>" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "from merlion.utils import TimeSeries\n", "\n", "train_data = TimeSeries.from_pd(time_series[metadata[\"trainval\"]])\n", "test_data = TimeSeries.from_pd(time_series[~metadata[\"trainval\"]])\n", "\n", "\n", "print('train timeseries shape: ', train_data.to_pd().values.shape)\n", "print('test timeseries shape: ', test_data.to_pd().values.shape)\n", "\n", "column_names = list(train_data.to_pd().columns)\n", "idx=0\n", "tr = train_data.to_pd()[column_names[idx]]\n", "plt.plot(tr)\n", "plt.show()\n", "\n", "te = test_data.to_pd()[column_names[idx]]\n", "plt.plot(te)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create MoE model composed of external expert models and train" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Specify hyper-parameters" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# save directory for ensemble state. Replace it with your own choice.\n", "save_dir = 'models/moe'\n", "\n", "###\n", "nfree_experts=0 # <- no free parameters provided\n", "lookback_len=20\n", "max_forecast_steps=3\n", "target_seq_index = 0\n", "use_gpu=False\n", "###\n", "\n", "\n", "## Pytorch network hyper-params. These are the also the hyper-params that are used in case moe_model=None is passed to MoE_ForecasterEnsemble.\n", "hidden_dim=256\n", "dim_head = 2\n", "mlp_dim=256\n", "dim_dropout=0. # if data is multi-dimensionsal, this can be set to a non-zero value to allow model to handle missing dimensions during test time\n", "time_step_dropout=0\n", "## Pytorch network hyper-params" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Create expert models and MoE ensembler and train" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "scrolled": true }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:merlion.models.ensemble.MoE_forecast:Training model 1/3...\n", "INFO:merlion.models.ensemble.MoE_forecast:Training model 2/3...\n", "INFO:merlion.models.ensemble.MoE_forecast:Training model 3/3...\n", "INFO:merlion.models.ensemble.MoE_forecast:Extracting and storing expert predictions\n", " 0%| | 0/6 [00:00<?, ?it/s]INFO:merlion.models.ensemble.MoE_forecast:Getting model 1/3 predictions...\n", "INFO:merlion.models.ensemble.MoE_forecast:Getting model 2/3 predictions...\n", "INFO:merlion.models.ensemble.MoE_forecast:Getting model 3/3 predictions...\n", " 17%|█▋ | 1/6 [00:06<00:33, 6.78s/it]INFO:merlion.models.ensemble.MoE_forecast:Getting model 1/3 predictions...\n", "INFO:merlion.models.ensemble.MoE_forecast:Getting model 2/3 predictions...\n", "INFO:merlion.models.ensemble.MoE_forecast:Getting model 3/3 predictions...\n", " 33%|███▎ | 2/6 [00:10<00:19, 4.91s/it]INFO:merlion.models.ensemble.MoE_forecast:Getting model 1/3 predictions...\n", "INFO:merlion.models.ensemble.MoE_forecast:Getting model 2/3 predictions...\n", "INFO:merlion.models.ensemble.MoE_forecast:Getting model 3/3 predictions...\n", " 50%|█████ | 3/6 [00:14<00:13, 4.52s/it]INFO:merlion.models.ensemble.MoE_forecast:Getting model 1/3 predictions...\n", "INFO:merlion.models.ensemble.MoE_forecast:Getting model 2/3 predictions...\n", "INFO:merlion.models.ensemble.MoE_forecast:Getting model 3/3 predictions...\n", " 67%|██████▋ | 4/6 [00:17<00:08, 4.11s/it]INFO:merlion.models.ensemble.MoE_forecast:Getting model 1/3 predictions...\n", "INFO:merlion.models.ensemble.MoE_forecast:Getting model 2/3 predictions...\n", "INFO:merlion.models.ensemble.MoE_forecast:Getting model 3/3 predictions...\n", " 83%|████████▎ | 5/6 [00:22<00:04, 4.34s/it]INFO:merlion.models.ensemble.MoE_forecast:Getting model 1/3 predictions...\n", "INFO:merlion.models.ensemble.MoE_forecast:Getting model 2/3 predictions...\n", "INFO:merlion.models.ensemble.MoE_forecast:Getting model 3/3 predictions...\n", "100%|██████████| 6/6 [00:23<00:00, 3.91s/it]\n", "Epoch 1 Loss: 1.304425: 100%|██████████| 6/6 [00:03<00:00, 1.92it/s]\n", "Epoch 2 Loss: 1.326118: 100%|██████████| 6/6 [00:03<00:00, 1.85it/s]\n", "Epoch 3 Loss: 1.285732: 100%|██████████| 6/6 [00:03<00:00, 1.61it/s]\n", "Epoch 4 Loss: 1.239944: 100%|██████████| 6/6 [00:03<00:00, 1.86it/s]\n", "Epoch 5 Loss: 1.217539: 100%|██████████| 6/6 [00:03<00:00, 1.92it/s]\n", "Epoch 6 Loss: 1.194959: 100%|██████████| 6/6 [00:04<00:00, 1.43it/s]\n", "Epoch 7 Loss: 1.182055: 100%|██████████| 6/6 [00:03<00:00, 1.86it/s]\n", "Epoch 8 Loss: 1.175249: 100%|██████████| 6/6 [00:02<00:00, 2.15it/s]\n", "Epoch 9 Loss: 1.173702: 100%|██████████| 6/6 [00:02<00:00, 2.43it/s]\n", "Epoch 10 Loss: 1.186111: 100%|██████████| 6/6 [00:02<00:00, 2.36it/s]\n", "Epoch 11 Loss: 1.184515: 100%|██████████| 6/6 [00:02<00:00, 2.08it/s]\n", "Epoch 12 Loss: 1.169571: 100%|██████████| 6/6 [00:02<00:00, 2.29it/s]\n", "Epoch 13 Loss: 1.174548: 100%|██████████| 6/6 [00:02<00:00, 2.42it/s]\n", "Epoch 14 Loss: 1.180143: 100%|██████████| 6/6 [00:02<00:00, 2.30it/s]\n", "Epoch 15 Loss: 1.186909: 100%|██████████| 6/6 [00:03<00:00, 1.95it/s]\n", "Epoch 16 Loss: 1.175635: 100%|██████████| 6/6 [00:02<00:00, 2.36it/s]\n", "Epoch 17 Loss: 1.189920: 100%|██████████| 6/6 [00:02<00:00, 2.23it/s]\n", "Epoch 18 Loss: 1.182831: 100%|██████████| 6/6 [00:03<00:00, 1.88it/s]\n", "Epoch 19 Loss: 1.176439: 100%|██████████| 6/6 [00:03<00:00, 1.90it/s]\n", "Epoch 20 Loss: 1.174525: 100%|██████████| 6/6 [00:02<00:00, 2.06it/s]\n", "Epoch 21 Loss: 1.172877: 100%|██████████| 6/6 [00:02<00:00, 2.07it/s]\n", "Epoch 22 Loss: 1.182378: 100%|██████████| 6/6 [00:03<00:00, 1.80it/s]\n", "Epoch 23 Loss: 1.165431: 100%|██████████| 6/6 [00:02<00:00, 2.23it/s]\n", "Epoch 24 Loss: 1.178699: 100%|██████████| 6/6 [00:02<00:00, 2.48it/s]\n", "Epoch 25 Loss: 1.179477: 100%|██████████| 6/6 [00:02<00:00, 2.32it/s]\n", "Epoch 26 Loss: 1.174176: 100%|██████████| 6/6 [00:02<00:00, 2.10it/s]\n", "Epoch 27 Loss: 1.187021: 100%|██████████| 6/6 [00:02<00:00, 2.32it/s]\n", "Epoch 28 Loss: 1.175006: 100%|██████████| 6/6 [00:02<00:00, 2.47it/s]\n", "Epoch 29 Loss: 1.179644: 100%|██████████| 6/6 [00:02<00:00, 2.39it/s]\n", "Epoch 30 Loss: 1.172667: 100%|██████████| 6/6 [00:02<00:00, 2.01it/s]\n", "Epoch 31 Loss: 1.166672: 100%|██████████| 6/6 [00:02<00:00, 2.45it/s]\n", "Epoch 32 Loss: 1.180196: 100%|██████████| 6/6 [00:02<00:00, 2.21it/s]\n", "Epoch 33 Loss: 1.180659: 100%|██████████| 6/6 [00:02<00:00, 2.03it/s]\n", "Epoch 34 Loss: 1.172211: 100%|██████████| 6/6 [00:02<00:00, 2.04it/s]\n", "Epoch 35 Loss: 1.179359: 100%|██████████| 6/6 [00:02<00:00, 2.39it/s]\n", "Epoch 36 Loss: 1.171128: 100%|██████████| 6/6 [00:03<00:00, 1.97it/s]\n", "Epoch 37 Loss: 1.175621: 100%|██████████| 6/6 [00:03<00:00, 1.65it/s]\n", "Epoch 38 Loss: 1.178169: 100%|██████████| 6/6 [00:02<00:00, 2.02it/s]\n", "Epoch 39 Loss: 1.171359: 100%|██████████| 6/6 [00:03<00:00, 1.94it/s]\n", "Epoch 40 Loss: 1.178329: 100%|██████████| 6/6 [00:02<00:00, 2.09it/s]\n", "Epoch 41 Loss: 1.183362: 100%|██████████| 6/6 [00:03<00:00, 1.99it/s]\n", "Epoch 42 Loss: 1.192560: 100%|██████████| 6/6 [00:02<00:00, 2.57it/s]\n", "Epoch 43 Loss: 1.180345: 100%|██████████| 6/6 [00:02<00:00, 2.41it/s]\n", "Epoch 44 Loss: 1.173638: 100%|██████████| 6/6 [00:02<00:00, 2.13it/s]\n", "Epoch 45 Loss: 1.152926: 100%|██████████| 6/6 [00:02<00:00, 2.26it/s]\n", "Epoch 46 Loss: 1.173875: 100%|██████████| 6/6 [00:02<00:00, 2.49it/s]\n", "Epoch 47 Loss: 1.164550: 100%|██████████| 6/6 [00:02<00:00, 2.30it/s]\n", "Epoch 48 Loss: 1.159929: 100%|██████████| 6/6 [00:03<00:00, 1.90it/s]\n", "Epoch 49 Loss: 1.153424: 100%|██████████| 6/6 [00:02<00:00, 2.29it/s]\n", "Epoch 50 Loss: 1.154480: 100%|██████████| 6/6 [00:02<00:00, 2.25it/s]\n", "Epoch 51 Loss: 1.140436: 100%|██████████| 6/6 [00:02<00:00, 2.04it/s]\n", "Epoch 52 Loss: 1.146496: 100%|██████████| 6/6 [00:03<00:00, 1.67it/s]\n", "Epoch 53 Loss: 1.103287: 100%|██████████| 6/6 [00:03<00:00, 1.95it/s]\n", "Epoch 54 Loss: 1.126842: 100%|██████████| 6/6 [00:03<00:00, 1.91it/s]\n", "Epoch 55 Loss: 1.090270: 100%|██████████| 6/6 [00:03<00:00, 1.89it/s]\n", "Epoch 56 Loss: 1.083246: 100%|██████████| 6/6 [00:02<00:00, 2.12it/s]\n", "Epoch 57 Loss: 1.103495: 100%|██████████| 6/6 [00:02<00:00, 2.47it/s]\n", "Epoch 58 Loss: 1.081064: 100%|██████████| 6/6 [00:02<00:00, 2.38it/s]\n", "Epoch 59 Loss: 1.031706: 100%|██████████| 6/6 [00:02<00:00, 2.14it/s]\n", "Epoch 60 Loss: 1.028626: 100%|██████████| 6/6 [00:02<00:00, 2.26it/s]\n", "Epoch 61 Loss: 1.070291: 100%|██████████| 6/6 [00:02<00:00, 2.40it/s]\n", "Epoch 62 Loss: 1.070380: 100%|██████████| 6/6 [00:02<00:00, 2.25it/s]\n", "Epoch 63 Loss: 1.057747: 100%|██████████| 6/6 [00:03<00:00, 1.96it/s]\n", "Epoch 64 Loss: 1.022432: 100%|██████████| 6/6 [00:02<00:00, 2.37it/s]\n", "Epoch 65 Loss: 1.092833: 100%|██████████| 6/6 [00:02<00:00, 2.26it/s]\n", "Epoch 66 Loss: 1.046667: 100%|██████████| 6/6 [00:02<00:00, 2.01it/s]\n", "Epoch 67 Loss: 1.024409: 100%|██████████| 6/6 [00:03<00:00, 1.95it/s]\n", "Epoch 68 Loss: 1.006745: 100%|██████████| 6/6 [00:02<00:00, 2.12it/s]\n", "Epoch 69 Loss: 1.026753: 100%|██████████| 6/6 [00:03<00:00, 1.99it/s]\n", "Epoch 70 Loss: 1.035914: 100%|██████████| 6/6 [00:03<00:00, 1.78it/s]\n", "Epoch 71 Loss: 1.011550: 100%|██████████| 6/6 [00:03<00:00, 1.76it/s]\n", "Epoch 72 Loss: 1.025698: 100%|██████████| 6/6 [00:02<00:00, 2.32it/s]\n", "Epoch 73 Loss: 1.021778: 100%|██████████| 6/6 [00:02<00:00, 2.44it/s]\n", "Epoch 74 Loss: 0.999083: 100%|██████████| 6/6 [00:02<00:00, 2.38it/s]\n", "Epoch 75 Loss: 1.003671: 100%|██████████| 6/6 [00:02<00:00, 2.02it/s]\n", "Epoch 76 Loss: 1.007998: 100%|██████████| 6/6 [00:02<00:00, 2.34it/s]\n", "Epoch 77 Loss: 0.992967: 100%|██████████| 6/6 [00:02<00:00, 2.45it/s]\n", "Epoch 78 Loss: 1.039574: 100%|██████████| 6/6 [00:02<00:00, 2.33it/s]\n", "Epoch 79 Loss: 0.979768: 100%|██████████| 6/6 [00:03<00:00, 1.85it/s]\n", "Epoch 80 Loss: 0.980897: 100%|██████████| 6/6 [00:02<00:00, 2.22it/s]\n", "Epoch 81 Loss: 1.021148: 100%|██████████| 6/6 [00:02<00:00, 2.36it/s]\n", "Epoch 82 Loss: 0.964973: 100%|██████████| 6/6 [00:02<00:00, 2.26it/s]\n", "Epoch 83 Loss: 0.970942: 100%|██████████| 6/6 [00:03<00:00, 1.83it/s]\n", "Epoch 84 Loss: 0.996262: 100%|██████████| 6/6 [00:03<00:00, 1.74it/s]\n", "Epoch 85 Loss: 0.961435: 100%|██████████| 6/6 [00:02<00:00, 2.04it/s]\n", "Epoch 86 Loss: 0.975354: 100%|██████████| 6/6 [00:02<00:00, 2.07it/s]\n", "Epoch 87 Loss: 0.980454: 100%|██████████| 6/6 [00:02<00:00, 2.06it/s]\n", "Epoch 88 Loss: 0.957371: 100%|██████████| 6/6 [00:02<00:00, 2.04it/s]\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Epoch 89 Loss: 0.940112: 100%|██████████| 6/6 [00:02<00:00, 2.39it/s]\n", "Epoch 90 Loss: 0.939432: 100%|██████████| 6/6 [00:02<00:00, 2.41it/s]\n", "Epoch 91 Loss: 0.952867: 100%|██████████| 6/6 [00:02<00:00, 2.38it/s]\n", "Epoch 92 Loss: 0.973232: 100%|██████████| 6/6 [00:02<00:00, 2.08it/s]\n", "Epoch 93 Loss: 0.988913: 100%|██████████| 6/6 [00:02<00:00, 2.53it/s]\n", "Epoch 94 Loss: 0.954114: 100%|██████████| 6/6 [00:02<00:00, 2.44it/s]\n", "Epoch 95 Loss: 0.906431: 100%|██████████| 6/6 [00:02<00:00, 2.29it/s]\n", "Epoch 96 Loss: 0.909996: 100%|██████████| 6/6 [00:03<00:00, 1.94it/s]\n", "Epoch 97 Loss: 0.945528: 100%|██████████| 6/6 [00:02<00:00, 2.18it/s]\n", "Epoch 98 Loss: 0.922009: 100%|██████████| 6/6 [00:02<00:00, 2.39it/s]\n", "Epoch 99 Loss: 0.920070: 100%|██████████| 6/6 [00:02<00:00, 2.21it/s]\n", "Epoch 100 Loss: 0.912859: 100%|██████████| 6/6 [00:03<00:00, 1.72it/s]\n" ] } ], "source": [ "from merlion.models.factory import ModelFactory\n", "from merlion.models.ensemble.MoE_forecast import MoE_ForecasterEnsemble, MoE_ForecasterEnsembleConfig, TransformerModel\n", "from merlion.models.ensemble.base import EnsembleTrainConfig\n", "from merlion.transform.base import Identity\n", "from merlion.transform.resample import TemporalResample\n", "\n", "\n", "## Define configs for all the experts as well as the MoE ensembler\n", "conf_sarima = {\n", " \"order\": [15, 1, 5],\n", " \"seasonal_order\": [2, 0, 1, 24],\n", " \"max_forecast_steps\": max_forecast_steps,\n", " \"target_seq_index\":target_seq_index,\n", " \"transform\": Identity()\n", " }\n", "\n", "config_arima = {\n", " \"order\": [15, 1, 5],\n", " \"max_forecast_steps\": max_forecast_steps,\n", " \"target_seq_index\": target_seq_index,\n", " \"transform\": Identity()\n", " }\n", "\n", "config_vector_ar = {\"max_forecast_steps\": max_forecast_steps, \"target_seq_index\": target_seq_index, \"maxlags\": 14}\n", "\n", "config_ensemble = MoE_ForecasterEnsembleConfig(batch_size=64, lr=0.0001,\\\n", " nfree_experts=nfree_experts, epoch_max=100,\\\n", " lookback_len=lookback_len,\\\n", " max_forecast_steps=max_forecast_steps,\\\n", " target_seq_index=target_seq_index,\n", " use_gpu=use_gpu,\\\n", " transform=TemporalResample())\n", "\n", "train_config_ensemble = EnsembleTrainConfig(valid_frac=0.5)\n", "\n", "# Define expert models\n", "model = ModelFactory.create(\"Sarima\", **conf_sarima)\n", "model2 = ModelFactory.create(\"Arima\", **config_arima)\n", "model3 = ModelFactory.create(\"VectorAR\", **config_vector_ar)\n", "\n", "models = [model, model2, model3]\n", "nexperts = len(models)\n", "\n", "'''\n", "Instantiate deep network for MoE. It can also be instantiated as None. In that case, the default Pytorch network \n", "specified in the MoE_ForecasterEnsemble class will be used. FYI, the network below is used as the default network in \n", "MoE_ForecasterEnsemble.\n", "\n", "'''\n", "moe_model = TransformerModel(input_dim=train_data.dim, lookback_len=lookback_len, nexperts=nexperts,\\\n", " output_dim=max_forecast_steps, nfree_experts=nfree_experts,\\\n", " hid_dim=hidden_dim, dim_head = dim_head, mlp_dim=mlp_dim,\\\n", " pool='cls', dim_dropout=dim_dropout,\\\n", " time_step_dropout=time_step_dropout)\n", "# moe_model = None # use me if you want to see the default model in use\n", "\n", "# create MoE forecaster model\n", "ensemble = MoE_ForecasterEnsemble(config=config_ensemble, models= models, moe_model=moe_model)\n", "\n", "# train & save MoE\n", "loss_list = ensemble.train(train_data=train_data, train_config = train_config_ensemble)\n", "ensemble.save(save_dir)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Load the saved ensemble model" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "scrolled": true }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:merlion.models.ensemble.base:When initializing an ensemble, you must either provide the dict `model_configs` (mapping each model's name to its config) when creating the `DetectorEnsembleConfig`, or provide a list of `models` to the constructor of `EnsembleBase`. Received both. Overriding `model_configs` with the configs belonging to `models`.\n" ] } ], "source": [ "ensemble_loaded = MoE_ForecasterEnsemble.load(save_dir)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Forecast using the loaded model" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True output:\n", "\n", "[803. 769. 751.]\n", "Performing single forecast:\n", "\n", "Forecast\n", " H1\n", "1677-10-28 00:00:00 810.339722\n", "1677-10-28 01:00:00 796.296448\n", "1677-10-28 02:00:00 760.550842\n", "Standard Error\n", " H1_err\n", "1677-10-28 00:00:00 42.765224\n", "1677-10-28 01:00:00 198.829971\n", "1677-10-28 02:00:00 350.278381\n", "\n", "\n", "Performing batch forecast (notice the output is a list):\n", "\n", "Forecasts\n", " [ H1_0\n", "1677-10-28 00:00:00 810.339722\n", "1677-10-28 01:00:00 796.296448\n", "1677-10-28 02:00:00 760.550842]\n", "Standard Errors\n", " [ H1_err_0\n", "1677-10-28 00:00:00 42.765224\n", "1677-10-28 01:00:00 198.829971\n", "1677-10-28 02:00:00 350.278381]\n" ] } ], "source": [ "lookback_len=20\n", "forecast_len=3\n", "\n", "sample_length = lookback_len + forecast_len\n", "\n", "target_seq_index=0\n", "start_idx = 0\n", "end_idx = sample_length\n", "\n", "timestamps = test_data.univariates[test_data.names[0]].time_stamps[start_idx: end_idx]\n", "data = test_data.to_pd().values\n", "data = data[start_idx: end_idx]\n", "\n", "timestamps = timestamps[lookback_len:]\n", "x = data[:lookback_len]\n", "x_ts = test_data[start_idx: start_idx+ lookback_len]\n", "y = data[lookback_len:, target_seq_index]\n", "\n", "print('True output:\\n')\n", "print(y)\n", "\n", "# perform single forecast\n", "print('Performing single forecast:\\n')\n", "forecast, se = ensemble_loaded.forecast(time_stamps=timestamps,\n", " time_series_prev=x_ts, expert_idx=None, mode='max', use_gpu=False)\n", "\n", "print('Forecast\\n', forecast)\n", "print('Standard Error\\n', se)\n", "\n", "# perform batch forecast (for simplicity, just feeding a list of single sample)\n", "print('\\n\\nPerforming batch forecast (notice the output is a list):\\n')\n", "forecast, se = ensemble_loaded.batch_forecast(time_stamps_list=[timestamps],\n", " time_series_prev_list = [x_ts], expert_idx=None, mode='max', use_gpu=False)\n", "\n", "print('Forecasts\\n', forecast)\n", "print('Standard Errors\\n', se)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Retrieve forecasts of individual experts along with their confidence from the loaded model" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True output:\n", "\n", "[803. 769. 751.]\n", "Getting individual expert forecast and standard deviation for single data (notice the array shape):\n", "\n", "Forecast (shape: (3, 3))\n", " [[828.93043244 796.29646378 760.5508621 ]\n", " [812.10700752 760.22152836 709.16665671]\n", " [810.33973458 757.56872591 700.9503937 ]]\n", "Standard deviation (shape: (3, 3))\n", " [[0.361902 0.47081903 0.7306497 ]\n", " [0.26711744 0.3186435 0.14048512]\n", " [0.3709806 0.21053748 0.12886517]]\n", "\n", "\n", "Getting individual expert forecast and standard deviation for a batch of data (notice the array shape):\n", "\n", "Forecast (shape: (1, 3, 3))\n", " [[[828.93043244 796.29646378 760.5508621 ]\n", " [812.10700752 760.22152836 709.16665671]\n", " [810.33973458 757.56872591 700.9503937 ]]]\n", "Standard deviation (shape: (1, 3, 3))\n", " [[[0.361902 0.47081903 0.7306497 ]\n", " [0.26711744 0.3186435 0.14048512]\n", " [0.3709806 0.21053748 0.12886517]]]\n" ] } ], "source": [ "# perform forecast at the beginning of the test_data timestamp of length 3 and lookback=20\n", "lookback_len=20\n", "forecast_len=3\n", "\n", "sample_length = lookback_len + forecast_len\n", "\n", "target_seq_index=0\n", "start_idx = 0\n", "end_idx = sample_length\n", "\n", "timestamps = test_data.univariates[test_data.names[0]].time_stamps[start_idx: end_idx]\n", "data = test_data.to_pd().values\n", "data = data[start_idx: end_idx]\n", "\n", "timestamps = timestamps[lookback_len:]\n", "x = data[:lookback_len] # shape (20,1)\n", "x_ts = test_data[start_idx: start_idx+ lookback_len]\n", "y = data[lookback_len:, target_seq_index]\n", "\n", "print('True output:\\n')\n", "print(y)\n", "\n", "# perform single forecast\n", "print('Getting individual expert forecast and standard deviation for single data (notice the array shape):\\n')\n", "forecast, std = ensemble_loaded._forecast(time_stamps=timestamps,\n", " time_series_prev=x_ts, expert_idx=None, use_gpu=False)\n", "\n", "print(f'Forecast (shape: {forecast.shape})\\n', forecast)\n", "print(f'Standard deviation (shape: {std.shape})\\n', std)\n", "\n", "# perform batch forecast (for simplicity, just feeding a list of single sample)\n", "print('\\n\\nGetting individual expert forecast and standard deviation for a batch of data (notice the array shape):\\n')\n", "forecast, std = ensemble_loaded._batch_forecast(time_stamps_list=[timestamps],\n", " time_series_prev_array=np.expand_dims(x, axis=0), # shape (1,20,1)\n", " time_series_prev_list = [x_ts], expert_idx=None, use_gpu=False)\n", "\n", "print(f'Forecast (shape: {forecast.shape})\\n', forecast)\n", "print(f'Standard deviation (shape: {std.shape})\\n', std)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Evaluate MoE\n", "\n", "The code below shows how to evaluate MoE." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "scrolled": true }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ " 0%| | 0/1 [00:00<?, ?it/s]\n", " 0%| | 0/1 [00:00<?, ?it/s]\u001b[A\n", "\n", "sMAPE_conf: 2.184 sMAPE_not_conf: 0.000 recall: 100.000% | Plain sMAPE 2.184: 0%| | 0/1 [00:01<?, ?it/s]\u001b[A\n", "sMAPE_conf: 2.184 sMAPE_not_conf: 0.000 recall: 100.000% | Plain sMAPE 2.184: 100%|██████████| 1/1 [00:01<00:00, 1.71s/it]\u001b[A\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "torch.Size([25, 3])\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "<Figure size 432x288 with 1 Axes>" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "sMAPE on confident samples: 2.18\n", "sMAPE on not confident samples: 0.00\n", "Percentage of samples on which MoE was confident: 100.00% (use a different confidence_thres to change this)\n", "sMAPE on all samples: 2.18\n" ] } ], "source": [ "\n", "\n", "expert_idx=None\n", "# if expert_idx=None, MoE uses all the experts provided and uses the 'mode' strategy specified below to forecast\n", "# if value is int (E.g. 0), MoE only uses the external expert at the corresponding index of `models` to make forecasts\n", "mode='max' # either mean or max. Max picks the expert with the highest confidence; mean computes the weighted average.\n", "use_gpu=False # set True if GPU available for faster speed\n", "use_batch_forecast=True # set True for higher speed\n", "\n", "y_pred_list, std_list, y_list, sMAPE_conf, sMAPE_not_conf, recall, overall_sMAPE =\\\n", " ensemble_loaded.evaluate(test_data, mode=mode, expert_idx=expert_idx,\\\n", " use_gpu=use_gpu, use_batch_forecast=use_batch_forecast, confidence_thres=100)\n", "\n", "out_idx=0 # plot this idx of all the steps forecasted by MoE\n", "print(y_pred_list.shape)\n", "plt.plot(y_pred_list[:100, out_idx], '--', color='k', label='prediction', linewidth=1) # plotting 1st 100 for clarity\n", "plt.plot(y_list[:100, out_idx], color='b', label='data', linewidth=1)\n", "# plt.fill_between(range(y_pred_list[:100, out_idx].shape[0]), y_pred_list[:100, out_idx]-std_list[:100, out_idx],\\\n", "# y_pred_list[:100, out_idx]+std_list[:100, out_idx]) # standard deviation error band \n", "plt.legend()\n", "plt.show()\n", "\n", "print(f'sMAPE on confident samples: {sMAPE_conf:.2f}')\n", "print(f'sMAPE on not confident samples: {sMAPE_not_conf:.2f}')\n", "print(f'Percentage of samples on which MoE was confident: {recall:.2f}% (use a different confidence_thres to change this)')\n", "print(f'sMAPE on all samples: {overall_sMAPE:.2f}')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create MoE model containing free parameters (no external experts) and train" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Specify hyper-parameters" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "import os\n", "# save directory for ensemble state. Replace it with your own choice.\n", "save_dir = 'models/moe2'\n", "\n", "###\n", "nfree_experts= 3000 # <- number of free experts\n", "lookback_len=20\n", "max_forecast_steps=3\n", "target_seq_index = 0\n", "use_gpu=False\n", "###\n", "\n", "\n", "## Pytorch network hyper-params. These are the also the hyper-params that are used in case moe_model=None is passed to MoE_ForecasterEnsemble.\n", "hidden_dim=256\n", "dim_head = 2\n", "mlp_dim=256\n", "dim_dropout=0. # if data is multi-dimensionsal, this can be set to a non-zero value to allow model to handle missing dimensions during test time\n", "time_step_dropout=0\n", "## Pytorch network hyper-params\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Create MoE ensembler and train" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "scrolled": true }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Epoch 1 Loss: 8.253956: 100%|██████████| 11/11 [00:03<00:00, 3.00it/s]\n", "Epoch 2 Loss: 8.215341: 100%|██████████| 11/11 [00:03<00:00, 3.09it/s]\n", "Epoch 3 Loss: 8.140997: 100%|██████████| 11/11 [00:03<00:00, 3.37it/s]\n", "Epoch 4 Loss: 8.030143: 100%|██████████| 11/11 [00:02<00:00, 3.70it/s]\n", "Epoch 5 Loss: 7.880345: 100%|██████████| 11/11 [00:03<00:00, 3.66it/s]\n", "Epoch 6 Loss: 7.679686: 100%|██████████| 11/11 [00:03<00:00, 3.23it/s]\n", "Epoch 7 Loss: 7.431627: 100%|██████████| 11/11 [00:03<00:00, 3.65it/s]\n", "Epoch 8 Loss: 7.121155: 100%|██████████| 11/11 [00:03<00:00, 3.66it/s]\n", "Epoch 9 Loss: 6.788598: 100%|██████████| 11/11 [00:03<00:00, 3.32it/s]\n", "Epoch 10 Loss: 6.469567: 100%|██████████| 11/11 [00:03<00:00, 2.98it/s]\n", "Epoch 11 Loss: 6.230416: 100%|██████████| 11/11 [00:03<00:00, 3.48it/s]\n", "Epoch 12 Loss: 6.048095: 100%|██████████| 11/11 [00:03<00:00, 3.60it/s]\n", "Epoch 13 Loss: 5.915649: 100%|██████████| 11/11 [00:03<00:00, 2.79it/s]\n", "Epoch 14 Loss: 5.811184: 100%|██████████| 11/11 [00:04<00:00, 2.69it/s]\n", "Epoch 15 Loss: 5.744193: 100%|██████████| 11/11 [00:03<00:00, 3.31it/s]\n", "Epoch 16 Loss: 5.686575: 100%|██████████| 11/11 [00:03<00:00, 3.11it/s]\n", "Epoch 17 Loss: 5.657169: 100%|██████████| 11/11 [00:03<00:00, 3.31it/s]\n", "Epoch 18 Loss: 5.635586: 100%|██████████| 11/11 [00:03<00:00, 3.36it/s]\n", "Epoch 19 Loss: 5.627381: 100%|██████████| 11/11 [00:03<00:00, 3.62it/s]\n", "Epoch 20 Loss: 5.592227: 100%|██████████| 11/11 [00:03<00:00, 3.46it/s]\n", "Epoch 21 Loss: 5.565175: 100%|██████████| 11/11 [00:03<00:00, 3.18it/s]\n", "Epoch 22 Loss: 5.561776: 100%|██████████| 11/11 [00:03<00:00, 3.66it/s]\n", "Epoch 23 Loss: 5.541681: 100%|██████████| 11/11 [00:03<00:00, 3.61it/s]\n", "Epoch 24 Loss: 5.545103: 100%|██████████| 11/11 [00:03<00:00, 3.17it/s]\n", "Epoch 25 Loss: 5.522188: 100%|██████████| 11/11 [00:03<00:00, 3.21it/s]\n", "Epoch 26 Loss: 5.508581: 100%|██████████| 11/11 [00:03<00:00, 3.52it/s]\n", "Epoch 27 Loss: 5.489652: 100%|██████████| 11/11 [00:03<00:00, 3.46it/s]\n", "Epoch 28 Loss: 5.476248: 100%|██████████| 11/11 [00:04<00:00, 2.51it/s]\n", "Epoch 29 Loss: 5.466399: 100%|██████████| 11/11 [00:03<00:00, 3.08it/s]\n", "Epoch 30 Loss: 5.475472: 100%|██████████| 11/11 [00:03<00:00, 3.17it/s]\n", "Epoch 31 Loss: 5.461387: 100%|██████████| 11/11 [00:03<00:00, 2.90it/s]\n", "Epoch 32 Loss: 5.433480: 100%|██████████| 11/11 [00:03<00:00, 3.43it/s]\n", "Epoch 33 Loss: 5.417164: 100%|██████████| 11/11 [00:03<00:00, 3.66it/s]\n", "Epoch 34 Loss: 5.391122: 100%|██████████| 11/11 [00:03<00:00, 3.55it/s]\n", "Epoch 35 Loss: 5.355259: 100%|██████████| 11/11 [00:03<00:00, 3.24it/s]\n", "Epoch 36 Loss: 5.324664: 100%|██████████| 11/11 [00:03<00:00, 3.55it/s]\n", "Epoch 37 Loss: 5.289907: 100%|██████████| 11/11 [00:03<00:00, 3.53it/s]\n", "Epoch 38 Loss: 5.252770: 100%|██████████| 11/11 [00:03<00:00, 3.27it/s]\n", "Epoch 39 Loss: 5.224870: 100%|██████████| 11/11 [00:03<00:00, 3.06it/s]\n", "Epoch 40 Loss: 5.189947: 100%|██████████| 11/11 [00:03<00:00, 3.58it/s]\n", "Epoch 41 Loss: 5.141784: 100%|██████████| 11/11 [00:03<00:00, 3.42it/s]\n", "Epoch 42 Loss: 5.089564: 100%|██████████| 11/11 [00:03<00:00, 2.83it/s]\n", "Epoch 43 Loss: 5.053859: 100%|██████████| 11/11 [00:03<00:00, 2.92it/s]\n", "Epoch 44 Loss: 5.017187: 100%|██████████| 11/11 [00:03<00:00, 3.16it/s]\n", "Epoch 45 Loss: 4.980298: 100%|██████████| 11/11 [00:03<00:00, 2.88it/s]\n", "Epoch 46 Loss: 4.946596: 100%|██████████| 11/11 [00:03<00:00, 2.99it/s]\n", "Epoch 47 Loss: 4.913864: 100%|██████████| 11/11 [00:03<00:00, 3.65it/s]\n", "Epoch 48 Loss: 4.886967: 100%|██████████| 11/11 [00:03<00:00, 3.64it/s]\n", "Epoch 49 Loss: 4.860845: 100%|██████████| 11/11 [00:03<00:00, 3.38it/s]\n", "Epoch 50 Loss: 4.831104: 100%|██████████| 11/11 [00:03<00:00, 3.44it/s]\n", "Epoch 51 Loss: 4.816362: 100%|██████████| 11/11 [00:03<00:00, 3.58it/s]\n", "Epoch 52 Loss: 4.779174: 100%|██████████| 11/11 [00:03<00:00, 3.39it/s]\n", "Epoch 53 Loss: 4.736116: 100%|██████████| 11/11 [00:03<00:00, 2.90it/s]\n", "Epoch 54 Loss: 4.717974: 100%|██████████| 11/11 [00:03<00:00, 3.40it/s]\n", "Epoch 55 Loss: 4.690528: 100%|██████████| 11/11 [00:03<00:00, 3.47it/s]\n", "Epoch 56 Loss: 4.657373: 100%|██████████| 11/11 [00:04<00:00, 2.68it/s]\n", "Epoch 57 Loss: 4.630430: 100%|██████████| 11/11 [00:04<00:00, 2.64it/s]\n", "Epoch 58 Loss: 4.626685: 100%|██████████| 11/11 [00:03<00:00, 3.33it/s]\n", "Epoch 59 Loss: 4.576031: 100%|██████████| 11/11 [00:03<00:00, 3.12it/s]\n", "Epoch 60 Loss: 4.536126: 100%|██████████| 11/11 [00:03<00:00, 3.28it/s]\n", "Epoch 61 Loss: 4.522658: 100%|██████████| 11/11 [00:03<00:00, 3.41it/s]\n", "Epoch 62 Loss: 4.482119: 100%|██████████| 11/11 [00:02<00:00, 3.70it/s]\n", "Epoch 63 Loss: 4.440992: 100%|██████████| 11/11 [00:03<00:00, 3.66it/s]\n", "Epoch 64 Loss: 4.420945: 100%|██████████| 11/11 [00:03<00:00, 3.26it/s]\n", "Epoch 65 Loss: 4.380464: 100%|██████████| 11/11 [00:03<00:00, 3.59it/s]\n", "Epoch 66 Loss: 4.354569: 100%|██████████| 11/11 [00:03<00:00, 3.41it/s]\n", "Epoch 67 Loss: 4.330108: 100%|██████████| 11/11 [00:03<00:00, 3.27it/s]\n", "Epoch 68 Loss: 4.302790: 100%|██████████| 11/11 [00:03<00:00, 3.11it/s]\n", "Epoch 69 Loss: 4.276388: 100%|██████████| 11/11 [00:03<00:00, 3.63it/s]\n", "Epoch 70 Loss: 4.252587: 100%|██████████| 11/11 [00:03<00:00, 3.08it/s]\n", "Epoch 71 Loss: 4.220399: 100%|██████████| 11/11 [00:03<00:00, 2.80it/s]\n", "Epoch 72 Loss: 4.197742: 100%|██████████| 11/11 [00:03<00:00, 2.84it/s]\n", "Epoch 73 Loss: 4.184703: 100%|██████████| 11/11 [00:03<00:00, 3.26it/s]\n", "Epoch 74 Loss: 4.177047: 100%|██████████| 11/11 [00:03<00:00, 3.37it/s]\n", "Epoch 75 Loss: 4.132162: 100%|██████████| 11/11 [00:03<00:00, 3.12it/s]\n", "Epoch 76 Loss: 4.098515: 100%|██████████| 11/11 [00:03<00:00, 3.65it/s]\n", "Epoch 77 Loss: 4.085912: 100%|██████████| 11/11 [00:03<00:00, 3.63it/s]\n", "Epoch 78 Loss: 4.072778: 100%|██████████| 11/11 [00:03<00:00, 3.48it/s]\n", "Epoch 79 Loss: 4.026296: 100%|██████████| 11/11 [00:03<00:00, 3.13it/s]\n", "Epoch 80 Loss: 4.000065: 100%|██████████| 11/11 [00:03<00:00, 3.65it/s]\n", "Epoch 81 Loss: 3.971918: 100%|██████████| 11/11 [00:03<00:00, 3.48it/s]\n", "Epoch 82 Loss: 3.954153: 100%|██████████| 11/11 [00:03<00:00, 3.20it/s]\n", "Epoch 83 Loss: 3.924814: 100%|██████████| 11/11 [00:03<00:00, 3.21it/s]\n", "Epoch 84 Loss: 3.895262: 100%|██████████| 11/11 [00:03<00:00, 3.16it/s]\n", "Epoch 85 Loss: 3.874157: 100%|██████████| 11/11 [00:03<00:00, 3.06it/s]\n", "Epoch 86 Loss: 3.862910: 100%|██████████| 11/11 [00:03<00:00, 3.02it/s]\n", "Epoch 87 Loss: 3.845997: 100%|██████████| 11/11 [00:03<00:00, 2.90it/s]\n", "Epoch 88 Loss: 3.811604: 100%|██████████| 11/11 [00:03<00:00, 3.11it/s]\n", "Epoch 89 Loss: 3.794181: 100%|██████████| 11/11 [00:03<00:00, 3.51it/s]\n", "Epoch 90 Loss: 3.760030: 100%|██████████| 11/11 [00:03<00:00, 3.47it/s]\n", "Epoch 91 Loss: 3.738671: 100%|██████████| 11/11 [00:03<00:00, 3.12it/s]\n", "Epoch 92 Loss: 3.720268: 100%|██████████| 11/11 [00:03<00:00, 3.55it/s]\n", "Epoch 93 Loss: 3.713584: 100%|██████████| 11/11 [00:02<00:00, 3.70it/s]\n", "Epoch 94 Loss: 3.671633: 100%|██████████| 11/11 [00:03<00:00, 3.62it/s]\n", "Epoch 95 Loss: 3.651652: 100%|██████████| 11/11 [00:03<00:00, 3.31it/s]\n", "Epoch 96 Loss: 3.639432: 100%|██████████| 11/11 [00:03<00:00, 3.07it/s]\n", "Epoch 97 Loss: 3.607364: 100%|██████████| 11/11 [00:03<00:00, 3.26it/s]\n", "Epoch 98 Loss: 3.583107: 100%|██████████| 11/11 [00:03<00:00, 3.33it/s]\n", "Epoch 99 Loss: 3.562718: 100%|██████████| 11/11 [00:03<00:00, 3.03it/s]\n", "Epoch 100 Loss: 3.548420: 100%|██████████| 11/11 [00:03<00:00, 2.93it/s]\n", "Epoch 101 Loss: 3.531171: 100%|██████████| 11/11 [00:04<00:00, 2.66it/s]\n", "Epoch 102 Loss: 3.509029: 100%|██████████| 11/11 [00:03<00:00, 3.47it/s]\n", "Epoch 103 Loss: 3.485391: 100%|██████████| 11/11 [00:03<00:00, 3.54it/s]\n", "Epoch 104 Loss: 3.450888: 100%|██████████| 11/11 [00:03<00:00, 3.43it/s]\n", "Epoch 105 Loss: 3.424491: 100%|██████████| 11/11 [00:03<00:00, 3.10it/s]\n", "Epoch 106 Loss: 3.403693: 100%|██████████| 11/11 [00:02<00:00, 3.74it/s]\n", "Epoch 107 Loss: 3.390665: 100%|██████████| 11/11 [00:03<00:00, 3.58it/s]\n", "Epoch 108 Loss: 3.359253: 100%|██████████| 11/11 [00:03<00:00, 3.43it/s]\n", "Epoch 109 Loss: 3.345198: 100%|██████████| 11/11 [00:03<00:00, 2.97it/s]\n", "Epoch 110 Loss: 3.349600: 100%|██████████| 11/11 [00:03<00:00, 3.52it/s]\n", "Epoch 111 Loss: 3.329763: 100%|██████████| 11/11 [00:03<00:00, 3.44it/s]\n", "Epoch 112 Loss: 3.303129: 100%|██████████| 11/11 [00:03<00:00, 3.32it/s]\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Epoch 113 Loss: 3.266704: 100%|██████████| 11/11 [00:03<00:00, 2.82it/s]\n", "Epoch 114 Loss: 3.240781: 100%|██████████| 11/11 [00:03<00:00, 2.94it/s]\n", "Epoch 115 Loss: 3.215163: 100%|██████████| 11/11 [00:03<00:00, 3.25it/s]\n", "Epoch 116 Loss: 3.198615: 100%|██████████| 11/11 [00:03<00:00, 2.92it/s]\n", "Epoch 117 Loss: 3.169775: 100%|██████████| 11/11 [00:03<00:00, 3.29it/s]\n", "Epoch 118 Loss: 3.152784: 100%|██████████| 11/11 [00:03<00:00, 3.47it/s]\n", "Epoch 119 Loss: 3.128009: 100%|██████████| 11/11 [00:03<00:00, 3.60it/s]\n", "Epoch 120 Loss: 3.106502: 100%|██████████| 11/11 [00:03<00:00, 3.67it/s]\n", "Epoch 121 Loss: 3.093420: 100%|██████████| 11/11 [00:03<00:00, 3.51it/s]\n", "Epoch 122 Loss: 3.078810: 100%|██████████| 11/11 [00:03<00:00, 3.31it/s]\n", "Epoch 123 Loss: 3.050844: 100%|██████████| 11/11 [00:03<00:00, 3.17it/s]\n", "Epoch 124 Loss: 3.052847: 100%|██████████| 11/11 [00:03<00:00, 3.52it/s]\n", "Epoch 125 Loss: 3.025279: 100%|██████████| 11/11 [00:03<00:00, 3.37it/s]\n", "Epoch 126 Loss: 3.009476: 100%|██████████| 11/11 [00:03<00:00, 3.38it/s]\n", "Epoch 127 Loss: 2.985609: 100%|██████████| 11/11 [00:04<00:00, 2.57it/s]\n", "Epoch 128 Loss: 2.966175: 100%|██████████| 11/11 [00:03<00:00, 2.95it/s]\n", "Epoch 129 Loss: 2.948951: 100%|██████████| 11/11 [00:03<00:00, 3.23it/s]\n", "Epoch 130 Loss: 2.939453: 100%|██████████| 11/11 [00:03<00:00, 3.16it/s]\n", "Epoch 131 Loss: 2.932430: 100%|██████████| 11/11 [00:03<00:00, 3.57it/s]\n", "Epoch 132 Loss: 2.893917: 100%|██████████| 11/11 [00:03<00:00, 3.20it/s]\n", "Epoch 133 Loss: 2.855756: 100%|██████████| 11/11 [00:03<00:00, 3.59it/s]\n", "Epoch 134 Loss: 2.839368: 100%|██████████| 11/11 [00:02<00:00, 3.70it/s]\n", "Epoch 135 Loss: 2.817158: 100%|██████████| 11/11 [00:03<00:00, 3.30it/s]\n", "Epoch 136 Loss: 2.791486: 100%|██████████| 11/11 [00:03<00:00, 3.09it/s]\n", "Epoch 137 Loss: 2.780610: 100%|██████████| 11/11 [00:03<00:00, 3.17it/s]\n", "Epoch 138 Loss: 2.761558: 100%|██████████| 11/11 [00:03<00:00, 3.42it/s]\n", "Epoch 139 Loss: 2.750291: 100%|██████████| 11/11 [00:03<00:00, 3.31it/s]\n", "Epoch 140 Loss: 2.730247: 100%|██████████| 11/11 [00:03<00:00, 3.28it/s]\n", "Epoch 141 Loss: 2.698439: 100%|██████████| 11/11 [00:04<00:00, 2.67it/s]\n", "Epoch 142 Loss: 2.685364: 100%|██████████| 11/11 [00:03<00:00, 3.15it/s]\n", "Epoch 143 Loss: 2.662411: 100%|██████████| 11/11 [00:03<00:00, 2.98it/s]\n", "Epoch 144 Loss: 2.658126: 100%|██████████| 11/11 [00:03<00:00, 2.92it/s]\n", "Epoch 145 Loss: 2.632239: 100%|██████████| 11/11 [00:03<00:00, 3.14it/s]\n", "Epoch 146 Loss: 2.610601: 100%|██████████| 11/11 [00:03<00:00, 3.34it/s]\n", "Epoch 147 Loss: 2.583837: 100%|██████████| 11/11 [00:03<00:00, 3.65it/s]\n", "Epoch 148 Loss: 2.556195: 100%|██████████| 11/11 [00:03<00:00, 3.44it/s]\n", "Epoch 149 Loss: 2.547484: 100%|██████████| 11/11 [00:03<00:00, 3.17it/s]\n", "Epoch 150 Loss: 2.525524: 100%|██████████| 11/11 [00:02<00:00, 3.67it/s]\n", "Epoch 151 Loss: 2.514556: 100%|██████████| 11/11 [00:03<00:00, 3.44it/s]\n", "Epoch 152 Loss: 2.501829: 100%|██████████| 11/11 [00:03<00:00, 3.11it/s]\n", "Epoch 153 Loss: 2.478203: 100%|██████████| 11/11 [00:03<00:00, 3.21it/s]\n", "Epoch 154 Loss: 2.457710: 100%|██████████| 11/11 [00:03<00:00, 3.10it/s]\n", "Epoch 155 Loss: 2.436375: 100%|██████████| 11/11 [00:03<00:00, 3.06it/s]\n", "Epoch 156 Loss: 2.412483: 100%|██████████| 11/11 [00:03<00:00, 2.77it/s]\n", "Epoch 157 Loss: 2.394380: 100%|██████████| 11/11 [00:03<00:00, 3.07it/s]\n", "Epoch 158 Loss: 2.380202: 100%|██████████| 11/11 [00:03<00:00, 3.58it/s]\n", "Epoch 159 Loss: 2.355152: 100%|██████████| 11/11 [00:03<00:00, 3.50it/s]\n", "Epoch 160 Loss: 2.347697: 100%|██████████| 11/11 [00:03<00:00, 3.20it/s]\n", "Epoch 161 Loss: 2.345931: 100%|██████████| 11/11 [00:03<00:00, 3.60it/s]\n", "Epoch 162 Loss: 2.296478: 100%|██████████| 11/11 [00:03<00:00, 3.64it/s]\n", "Epoch 163 Loss: 2.282725: 100%|██████████| 11/11 [00:03<00:00, 3.58it/s]\n", "Epoch 164 Loss: 2.249418: 100%|██████████| 11/11 [00:03<00:00, 3.25it/s]\n", "Epoch 165 Loss: 2.241911: 100%|██████████| 11/11 [00:03<00:00, 3.60it/s]\n", "Epoch 166 Loss: 2.215718: 100%|██████████| 11/11 [00:03<00:00, 3.45it/s]\n", "Epoch 167 Loss: 2.194424: 100%|██████████| 11/11 [00:03<00:00, 3.08it/s]\n", "Epoch 168 Loss: 2.184618: 100%|██████████| 11/11 [00:03<00:00, 3.13it/s]\n", "Epoch 169 Loss: 2.156022: 100%|██████████| 11/11 [00:03<00:00, 3.27it/s]\n", "Epoch 170 Loss: 2.152164: 100%|██████████| 11/11 [00:03<00:00, 3.05it/s]\n", "Epoch 171 Loss: 2.128624: 100%|██████████| 11/11 [00:03<00:00, 2.82it/s]\n", "Epoch 172 Loss: 2.109892: 100%|██████████| 11/11 [00:03<00:00, 2.82it/s]\n", "Epoch 173 Loss: 2.137191: 100%|██████████| 11/11 [00:02<00:00, 3.74it/s]\n", "Epoch 174 Loss: 2.118212: 100%|██████████| 11/11 [00:03<00:00, 3.55it/s]\n", "Epoch 175 Loss: 2.092953: 100%|██████████| 11/11 [00:03<00:00, 3.12it/s]\n", "Epoch 176 Loss: 2.065081: 100%|██████████| 11/11 [00:03<00:00, 3.61it/s]\n", "Epoch 177 Loss: 2.064701: 100%|██████████| 11/11 [00:02<00:00, 3.69it/s]\n", "Epoch 178 Loss: 2.061531: 100%|██████████| 11/11 [00:03<00:00, 3.42it/s]\n", "Epoch 179 Loss: 2.041025: 100%|██████████| 11/11 [00:03<00:00, 2.90it/s]\n", "Epoch 180 Loss: 1.999497: 100%|██████████| 11/11 [00:03<00:00, 3.55it/s]\n", "Epoch 181 Loss: 1.953928: 100%|██████████| 11/11 [00:03<00:00, 3.42it/s]\n", "Epoch 182 Loss: 1.929946: 100%|██████████| 11/11 [00:03<00:00, 2.86it/s]\n", "Epoch 183 Loss: 1.923069: 100%|██████████| 11/11 [00:03<00:00, 2.93it/s]\n", "Epoch 184 Loss: 1.905399: 100%|██████████| 11/11 [00:03<00:00, 3.23it/s]\n", "Epoch 185 Loss: 1.892242: 100%|██████████| 11/11 [00:03<00:00, 3.06it/s]\n", "Epoch 186 Loss: 1.869357: 100%|██████████| 11/11 [00:03<00:00, 3.02it/s]\n", "Epoch 187 Loss: 1.840604: 100%|██████████| 11/11 [00:03<00:00, 3.59it/s]\n", "Epoch 188 Loss: 1.837614: 100%|██████████| 11/11 [00:02<00:00, 3.68it/s]\n", "Epoch 189 Loss: 1.816457: 100%|██████████| 11/11 [00:03<00:00, 3.57it/s]\n", "Epoch 190 Loss: 1.786459: 100%|██████████| 11/11 [00:03<00:00, 3.11it/s]\n", "Epoch 191 Loss: 1.776885: 100%|██████████| 11/11 [00:02<00:00, 3.79it/s]\n", "Epoch 192 Loss: 1.766457: 100%|██████████| 11/11 [00:03<00:00, 3.61it/s]\n", "Epoch 193 Loss: 1.742621: 100%|██████████| 11/11 [00:03<00:00, 3.39it/s]\n", "Epoch 194 Loss: 1.723335: 100%|██████████| 11/11 [00:03<00:00, 2.79it/s]\n", "Epoch 195 Loss: 1.708375: 100%|██████████| 11/11 [00:03<00:00, 3.44it/s]\n", "Epoch 196 Loss: 1.692905: 100%|██████████| 11/11 [00:03<00:00, 3.27it/s]\n", "Epoch 197 Loss: 1.694218: 100%|██████████| 11/11 [00:03<00:00, 2.89it/s]\n", "Epoch 198 Loss: 1.677686: 100%|██████████| 11/11 [00:03<00:00, 2.96it/s]\n", "Epoch 199 Loss: 1.644678: 100%|██████████| 11/11 [00:03<00:00, 3.09it/s]\n", "Epoch 200 Loss: 1.632020: 100%|██████████| 11/11 [00:03<00:00, 3.16it/s]\n", "Epoch 201 Loss: 1.604089: 100%|██████████| 11/11 [00:03<00:00, 3.53it/s]\n", "Epoch 202 Loss: 1.597124: 100%|██████████| 11/11 [00:03<00:00, 3.08it/s]\n", "Epoch 203 Loss: 1.580226: 100%|██████████| 11/11 [00:02<00:00, 3.74it/s]\n", "Epoch 204 Loss: 1.577800: 100%|██████████| 11/11 [00:03<00:00, 3.62it/s]\n", "Epoch 205 Loss: 1.556550: 100%|██████████| 11/11 [00:03<00:00, 3.33it/s]\n", "Epoch 206 Loss: 1.531670: 100%|██████████| 11/11 [00:03<00:00, 3.20it/s]\n", "Epoch 207 Loss: 1.524184: 100%|██████████| 11/11 [00:03<00:00, 3.55it/s]\n", "Epoch 208 Loss: 1.504326: 100%|██████████| 11/11 [00:03<00:00, 3.43it/s]\n", "Epoch 209 Loss: 1.495385: 100%|██████████| 11/11 [00:03<00:00, 3.06it/s]\n", "Epoch 210 Loss: 1.477028: 100%|██████████| 11/11 [00:03<00:00, 2.92it/s]\n", "Epoch 211 Loss: 1.466456: 100%|██████████| 11/11 [00:03<00:00, 3.16it/s]\n", "Epoch 212 Loss: 1.437730: 100%|██████████| 11/11 [00:03<00:00, 2.97it/s]\n", "Epoch 213 Loss: 1.439750: 100%|██████████| 11/11 [00:04<00:00, 2.70it/s]\n", "Epoch 214 Loss: 1.427772: 100%|██████████| 11/11 [00:03<00:00, 3.19it/s]\n", "Epoch 215 Loss: 1.417080: 100%|██████████| 11/11 [00:03<00:00, 3.54it/s]\n", "Epoch 216 Loss: 1.403871: 100%|██████████| 11/11 [00:03<00:00, 3.40it/s]\n", "Epoch 217 Loss: 1.374399: 100%|██████████| 11/11 [00:03<00:00, 3.29it/s]\n", "Epoch 218 Loss: 1.362701: 100%|██████████| 11/11 [00:02<00:00, 3.83it/s]\n", "Epoch 219 Loss: 1.348216: 100%|██████████| 11/11 [00:02<00:00, 3.76it/s]\n", "Epoch 220 Loss: 1.337092: 100%|██████████| 11/11 [00:03<00:00, 3.51it/s]\n", "Epoch 221 Loss: 1.331288: 100%|██████████| 11/11 [00:03<00:00, 3.04it/s]\n", "Epoch 222 Loss: 1.322314: 100%|██████████| 11/11 [00:03<00:00, 3.54it/s]\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Epoch 223 Loss: 1.303005: 100%|██████████| 11/11 [00:03<00:00, 3.46it/s]\n", "Epoch 224 Loss: 1.308330: 100%|██████████| 11/11 [00:03<00:00, 2.86it/s]\n", "Epoch 225 Loss: 1.307320: 100%|██████████| 11/11 [00:05<00:00, 2.17it/s]\n", "Epoch 226 Loss: 1.259610: 100%|██████████| 11/11 [00:04<00:00, 2.59it/s]\n", "Epoch 227 Loss: 1.247879: 100%|██████████| 11/11 [00:04<00:00, 2.44it/s]\n", "Epoch 228 Loss: 1.232500: 100%|██████████| 11/11 [00:03<00:00, 2.84it/s]\n", "Epoch 229 Loss: 1.223805: 100%|██████████| 11/11 [00:04<00:00, 2.71it/s]\n", "Epoch 230 Loss: 1.210760: 100%|██████████| 11/11 [00:03<00:00, 3.23it/s]\n", "Epoch 231 Loss: 1.193618: 100%|██████████| 11/11 [00:03<00:00, 3.09it/s]\n", "Epoch 232 Loss: 1.186537: 100%|██████████| 11/11 [00:03<00:00, 3.09it/s]\n", "Epoch 233 Loss: 1.159970: 100%|██████████| 11/11 [00:03<00:00, 2.82it/s]\n", "Epoch 234 Loss: 1.156743: 100%|██████████| 11/11 [00:03<00:00, 3.41it/s]\n", "Epoch 235 Loss: 1.146074: 100%|██████████| 11/11 [00:03<00:00, 2.96it/s]\n", "Epoch 236 Loss: 1.151413: 100%|██████████| 11/11 [00:03<00:00, 2.90it/s]\n", "Epoch 237 Loss: 1.131100: 100%|██████████| 11/11 [00:03<00:00, 3.30it/s]\n", "Epoch 238 Loss: 1.122501: 100%|██████████| 11/11 [00:03<00:00, 3.11it/s]\n", "Epoch 239 Loss: 1.099850: 100%|██████████| 11/11 [00:03<00:00, 2.81it/s]\n", "Epoch 240 Loss: 1.086024: 100%|██████████| 11/11 [00:04<00:00, 2.57it/s]\n", "Epoch 241 Loss: 1.072572: 100%|██████████| 11/11 [00:03<00:00, 2.93it/s]\n", "Epoch 242 Loss: 1.068453: 100%|██████████| 11/11 [00:03<00:00, 3.37it/s]\n", "Epoch 243 Loss: 1.044812: 100%|██████████| 11/11 [00:03<00:00, 3.52it/s]\n", "Epoch 244 Loss: 1.030824: 100%|██████████| 11/11 [00:03<00:00, 3.23it/s]\n", "Epoch 245 Loss: 1.019708: 100%|██████████| 11/11 [00:03<00:00, 3.34it/s]\n", "Epoch 246 Loss: 1.011575: 100%|██████████| 11/11 [00:03<00:00, 3.59it/s]\n", "Epoch 247 Loss: 0.990726: 100%|██████████| 11/11 [00:03<00:00, 3.46it/s]\n", "Epoch 248 Loss: 0.986041: 100%|██████████| 11/11 [00:03<00:00, 2.91it/s]\n", "Epoch 249 Loss: 0.981658: 100%|██████████| 11/11 [00:03<00:00, 3.21it/s]\n", "Epoch 250 Loss: 0.980595: 100%|██████████| 11/11 [00:03<00:00, 3.37it/s]\n", "Epoch 251 Loss: 0.968010: 100%|██████████| 11/11 [00:03<00:00, 3.13it/s]\n", "Epoch 252 Loss: 0.962707: 100%|██████████| 11/11 [00:03<00:00, 2.80it/s]\n", "Epoch 253 Loss: 0.942022: 100%|██████████| 11/11 [00:03<00:00, 3.11it/s]\n", "Epoch 254 Loss: 0.944430: 100%|██████████| 11/11 [00:03<00:00, 2.89it/s]\n", "Epoch 255 Loss: 0.929161: 100%|██████████| 11/11 [00:03<00:00, 2.88it/s]\n", "Epoch 256 Loss: 0.937370: 100%|██████████| 11/11 [00:03<00:00, 2.90it/s]\n", "Epoch 257 Loss: 0.903115: 100%|██████████| 11/11 [00:03<00:00, 3.54it/s]\n", "Epoch 258 Loss: 0.883225: 100%|██████████| 11/11 [00:03<00:00, 3.25it/s]\n", "Epoch 259 Loss: 0.879743: 100%|██████████| 11/11 [00:03<00:00, 2.87it/s]\n", "Epoch 260 Loss: 0.868025: 100%|██████████| 11/11 [00:03<00:00, 3.35it/s]\n", "Epoch 261 Loss: 0.871274: 100%|██████████| 11/11 [00:03<00:00, 3.52it/s]\n", "Epoch 262 Loss: 0.845327: 100%|██████████| 11/11 [00:03<00:00, 3.02it/s]\n", "Epoch 263 Loss: 0.830346: 100%|██████████| 11/11 [00:03<00:00, 2.75it/s]\n", "Epoch 264 Loss: 0.824749: 100%|██████████| 11/11 [00:03<00:00, 3.36it/s]\n", "Epoch 265 Loss: 0.825509: 100%|██████████| 11/11 [00:03<00:00, 3.28it/s]\n", "Epoch 266 Loss: 0.826433: 100%|██████████| 11/11 [00:04<00:00, 2.64it/s]\n", "Epoch 267 Loss: 0.803352: 100%|██████████| 11/11 [00:04<00:00, 2.58it/s]\n", "Epoch 268 Loss: 0.803057: 100%|██████████| 11/11 [00:03<00:00, 3.02it/s]\n", "Epoch 269 Loss: 0.779101: 100%|██████████| 11/11 [00:03<00:00, 3.00it/s]\n", "Epoch 270 Loss: 0.776825: 100%|██████████| 11/11 [00:03<00:00, 3.17it/s]\n", "Epoch 271 Loss: 0.781099: 100%|██████████| 11/11 [00:03<00:00, 3.20it/s]\n", "Epoch 272 Loss: 0.785840: 100%|██████████| 11/11 [00:03<00:00, 3.28it/s]\n", "Epoch 273 Loss: 0.802700: 100%|██████████| 11/11 [00:03<00:00, 3.29it/s]\n", "Epoch 274 Loss: 0.772463: 100%|██████████| 11/11 [00:03<00:00, 3.00it/s]\n", "Epoch 275 Loss: 0.764557: 100%|██████████| 11/11 [00:03<00:00, 3.41it/s]\n", "Epoch 276 Loss: 0.756142: 100%|██████████| 11/11 [00:03<00:00, 3.40it/s]\n", "Epoch 277 Loss: 0.749000: 100%|██████████| 11/11 [00:03<00:00, 3.18it/s]\n", "Epoch 278 Loss: 0.727899: 100%|██████████| 11/11 [00:03<00:00, 2.91it/s]\n", "Epoch 279 Loss: 0.736639: 100%|██████████| 11/11 [00:03<00:00, 3.44it/s]\n", "Epoch 280 Loss: 0.732949: 100%|██████████| 11/11 [00:04<00:00, 2.73it/s]\n", "Epoch 281 Loss: 0.714376: 100%|██████████| 11/11 [00:03<00:00, 2.79it/s]\n", "Epoch 282 Loss: 0.706372: 100%|██████████| 11/11 [00:04<00:00, 2.62it/s]\n", "Epoch 283 Loss: 0.718250: 100%|██████████| 11/11 [00:03<00:00, 3.10it/s]\n", "Epoch 284 Loss: 0.702688: 100%|██████████| 11/11 [00:03<00:00, 3.32it/s]\n", "Epoch 285 Loss: 0.683941: 100%|██████████| 11/11 [00:03<00:00, 3.02it/s]\n", "Epoch 286 Loss: 0.669917: 100%|██████████| 11/11 [00:03<00:00, 3.04it/s]\n", "Epoch 287 Loss: 0.657017: 100%|██████████| 11/11 [00:03<00:00, 3.44it/s]\n", "Epoch 288 Loss: 0.645382: 100%|██████████| 11/11 [00:03<00:00, 3.27it/s]\n", "Epoch 289 Loss: 0.646296: 100%|██████████| 11/11 [00:03<00:00, 3.01it/s]\n", "Epoch 290 Loss: 0.640179: 100%|██████████| 11/11 [00:03<00:00, 2.87it/s]\n", "Epoch 291 Loss: 0.632041: 100%|██████████| 11/11 [00:03<00:00, 3.20it/s]\n", "Epoch 292 Loss: 0.623746: 100%|██████████| 11/11 [00:03<00:00, 3.01it/s]\n", "Epoch 293 Loss: 0.606923: 100%|██████████| 11/11 [00:04<00:00, 2.67it/s]\n", "Epoch 294 Loss: 0.608943: 100%|██████████| 11/11 [00:04<00:00, 2.50it/s]\n", "Epoch 295 Loss: 0.607394: 100%|██████████| 11/11 [00:03<00:00, 2.89it/s]\n", "Epoch 296 Loss: 0.594561: 100%|██████████| 11/11 [00:04<00:00, 2.60it/s]\n", "Epoch 297 Loss: 0.581359: 100%|██████████| 11/11 [00:04<00:00, 2.61it/s]\n", "Epoch 298 Loss: 0.581903: 100%|██████████| 11/11 [00:03<00:00, 3.34it/s]\n", "Epoch 299 Loss: 0.572175: 100%|██████████| 11/11 [00:03<00:00, 3.24it/s]\n", "Epoch 300 Loss: 0.570626: 100%|██████████| 11/11 [00:03<00:00, 3.02it/s]\n" ] } ], "source": [ "config_ensemble = MoE_ForecasterEnsembleConfig(\n", " batch_size=64, lr=0.0001, nfree_experts=nfree_experts, epoch_max=300,\n", " lookback_len=lookback_len, max_forecast_steps=max_forecast_steps,\n", " target_seq_index=target_seq_index, use_gpu=use_gpu,\n", " transform=TemporalResample())\n", "\n", "train_config_ensemble = EnsembleTrainConfig(valid_frac=0.5)\n", "\n", "# Define expert models\n", "models = [] # <- no external experts provided\n", "nexperts = len(models)\n", "\n", "# instantiate deep network for MoE\n", "moe_model = TransformerModel(input_dim=len(train_data.names), lookback_len=lookback_len, nexperts=nexperts,\\\n", " output_dim=max_forecast_steps, nfree_experts=nfree_experts,\\\n", " hid_dim=hidden_dim, dim_head = dim_head, mlp_dim=mlp_dim,\\\n", " pool='cls', dim_dropout=dim_dropout,\\\n", " time_step_dropout=time_step_dropout)\n", "moe_model = None # use me if you want to see the default model in use\n", "\n", "# create MoE forecaster model\n", "ensemble = MoE_ForecasterEnsemble(config=config_ensemble, models= models, moe_model=moe_model)\n", "\n", "# train MoE\n", "loss_list = ensemble.train(train_data=train_data, train_config = train_config_ensemble)\n", "\n", "ensemble.save(save_dir)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Evaluate MoE\n", "\n", "The code below shows how to evaluate MoE." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:merlion.models.ensemble.base:When initializing an ensemble, you must either provide the dict `model_configs` (mapping each model's name to its config) when creating the `DetectorEnsembleConfig`, or provide a list of `models` to the constructor of `EnsembleBase`. Received both. Overriding `model_configs` with the configs belonging to `models`.\n" ] } ], "source": [ "ensemble_loaded = MoE_ForecasterEnsemble.load(save_dir)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Load the saved ensemble model" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ " 0%| | 0/1 [00:00<?, ?it/s]\n", " 0%| | 0/1 [00:00<?, ?it/s]\u001b[A\n", "\n", "sMAPE_conf: 1.872 sMAPE_not_conf: 2.411 recall: 21.333% | Plain sMAPE 2.296: 100%|██████████| 1/1 [00:00<00:00, 37.30it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "torch.Size([25, 3])\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "<Figure size 432x288 with 1 Axes>" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "sMAPE on confident samples: 1.87\n", "sMAPE on not confident samples: 2.41\n", "Percentage of samples on which MoE was confident: 21.33% (use a different confidence_thres to change this)\n", "sMAPE on all samples: 2.30\n" ] } ], "source": [ "\n", "\n", "expert_idx=None\n", "# when no external experts are used, the value of expert_idx is not used in the \n", "# forecast/batch_forecast/evaluate functions\n", "mode='max' # either mean or max. Max picks the expert with the highest confidence; mean computes the weighted average.\n", "use_gpu=False # set True if GPU available for faster speed\n", "use_batch_forecast=True # set True for higher speed\n", "\n", "y_pred_list, std_list, y_list, sMAPE_conf, sMAPE_not_conf, recall, overall_sMAPE =\\\n", " ensemble_loaded.evaluate(test_data, mode=mode, expert_idx=expert_idx,\\\n", " use_gpu=use_gpu, use_batch_forecast=use_batch_forecast, confidence_thres=1.)\n", "\n", "out_idx=0 # plot this idx of all the steps forecasted by MoE\n", "print(y_pred_list.shape)\n", "plt.plot(y_pred_list[:100, out_idx], '--', color='k', label='prediction', linewidth=1)\n", "plt.plot(y_list[:100, out_idx], color='b', label='data', linewidth=1)\n", "# plt.fill_between(range(y_pred_list[:100, out_idx].shape[0]), y_pred_list[:100, out_idx]-std_list[:100, out_idx],\\\n", "# y_pred_list[:100, out_idx]+std_list[:100, out_idx]) # standard deviation error band \n", "plt.legend()\n", "plt.show()\n", "\n", "print(f'sMAPE on confident samples: {sMAPE_conf:.2f}')\n", "print(f'sMAPE on not confident samples: {sMAPE_not_conf:.2f}')\n", "print(f'Percentage of samples on which MoE was confident: {recall:.2f}% (use a different confidence_thres to change this)')\n", "print(f'sMAPE on all samples: {overall_sMAPE:.2f}')\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.5" } }, "nbformat": 4, "nbformat_minor": 4 }