Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT] DeepNPTS model #990

Merged
merged 12 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion action_files/test_models/src/evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def evaluate(model: str, dataset: str, group: str):
groups = ['Monthly']
models = ['AutoDilatedRNN', 'RNN', 'TCN', 'DeepAR',
'NHITS', 'TFT', 'AutoMLP', 'DLinear', 'VanillaTransformer',
'BiTCN', 'TiDE']
'BiTCN', 'TiDE', 'DeepNPTS']
datasets = ['M3']
evaluation = [evaluate(model, dataset, group) for model, group in product(models, groups) for dataset in datasets]
evaluation = [eval_ for eval_ in evaluation if eval_ is not None]
Expand Down
2 changes: 2 additions & 0 deletions action_files/test_models/src/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from neuralforecast.models.dlinear import DLinear
from neuralforecast.models.bitcn import BiTCN
from neuralforecast.models.tide import TiDE
from neuralforecast.models.deepnpts import DeepNPTS

from neuralforecast.auto import (
AutoMLP,
Expand Down Expand Up @@ -76,6 +77,7 @@ def main(dataset: str = 'M3', group: str = 'Monthly') -> None:
DeepAR(h=horizon, input_size=2 * horizon, scaler_type='minmax1', max_steps=1000),
BiTCN(h=horizon, input_size=2 * horizon, loss=MAE(), dropout=0.0, max_steps=1000, val_check_steps=500),
TiDE(h=horizon, input_size=2 * horizon, loss=MAE(), max_steps=1000, val_check_steps=500),
DeepNPTS(h=horizon, input_size=2 * horizon, loss=MAE(), max_steps=1000, val_check_steps=500),
]

# Models
Expand Down
4 changes: 2 additions & 2 deletions nbs/common.scalers.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -567,8 +567,8 @@
" shape = list(x.shape)\n",
" shape[dim] = 1\n",
"\n",
" x_shift = torch.zeros(shape)\n",
" x_scale = torch.ones(shape)\n",
" x_shift = torch.zeros(shape, device=x.device)\n",
" x_scale = torch.ones(shape, device=x.device)\n",
"\n",
" return x_shift, x_scale"
]
Expand Down
4 changes: 3 additions & 1 deletion nbs/core.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
" Informer, Autoformer, FEDformer,\n",
" StemGNN, PatchTST, TimesNet, TimeLLM, TSMixer, TSMixerx,\n",
" MLPMultivariate, iTransformer,\n",
" BiTCN, TiDE\n",
" BiTCN, TiDE, DeepNPTS,\n",
")"
]
},
Expand Down Expand Up @@ -239,6 +239,8 @@
" 'itransformer': iTransformer, 'autoitransformer': iTransformer,\n",
" 'bitcn': BiTCN, 'autobitcn': BiTCN,\n",
" 'tide': TiDE, 'autotide': TiDE,\n",
" 'deepnpts': DeepNPTS, 'autodeepnpts': DeepNPTS,\n",
"\n",
"}"
]
},
Expand Down
2 changes: 1 addition & 1 deletion nbs/losses.pytorch.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
" Normal, \n",
" StudentT, \n",
" Poisson,\n",
" NegativeBinomial\n",
" NegativeBinomial,\n",
")\n",
"\n",
"from torch.distributions import constraints"
Expand Down
373 changes: 373 additions & 0 deletions nbs/models.deepnpts.ipynb

Large diffs are not rendered by default.

397 changes: 142 additions & 255 deletions nbs/models.ipynb

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions neuralforecast/_modidx.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
'neuralforecast/auto.py'),
'neuralforecast.auto.AutoDeepAR.get_default_config': ( 'models.html#autodeepar.get_default_config',
'neuralforecast/auto.py'),
'neuralforecast.auto.AutoDeepNPTS': ('models.html#autodeepnpts', 'neuralforecast/auto.py'),
'neuralforecast.auto.AutoDeepNPTS.__init__': ( 'models.html#autodeepnpts.__init__',
'neuralforecast/auto.py'),
'neuralforecast.auto.AutoDeepNPTS.get_default_config': ( 'models.html#autodeepnpts.get_default_config',
'neuralforecast/auto.py'),
'neuralforecast.auto.AutoDilatedRNN': ('models.html#autodilatedrnn', 'neuralforecast/auto.py'),
'neuralforecast.auto.AutoDilatedRNN.__init__': ( 'models.html#autodilatedrnn.__init__',
'neuralforecast/auto.py'),
Expand Down Expand Up @@ -512,6 +517,12 @@
'neuralforecast/models/deepar.py'),
'neuralforecast.models.deepar.DeepAR.validation_step': ( 'models.deepar.html#deepar.validation_step',
'neuralforecast/models/deepar.py')},
'neuralforecast.models.deepnpts': { 'neuralforecast.models.deepnpts.DeepNPTS': ( 'models.deepnpts.html#deepnpts',
'neuralforecast/models/deepnpts.py'),
'neuralforecast.models.deepnpts.DeepNPTS.__init__': ( 'models.deepnpts.html#deepnpts.__init__',
'neuralforecast/models/deepnpts.py'),
'neuralforecast.models.deepnpts.DeepNPTS.forward': ( 'models.deepnpts.html#deepnpts.forward',
'neuralforecast/models/deepnpts.py')},
'neuralforecast.models.dilated_rnn': { 'neuralforecast.models.dilated_rnn.AttentiveLSTMLayer': ( 'models.dilated_rnn.html#attentivelstmlayer',
'neuralforecast/models/dilated_rnn.py'),
'neuralforecast.models.dilated_rnn.AttentiveLSTMLayer.__init__': ( 'models.dilated_rnn.html#attentivelstmlayer.__init__',
Expand Down
103 changes: 87 additions & 16 deletions neuralforecast/auto.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

# %% auto 0
__all__ = ['AutoRNN', 'AutoLSTM', 'AutoGRU', 'AutoTCN', 'AutoDeepAR', 'AutoDilatedRNN', 'AutoBiTCN', 'AutoMLP', 'AutoNBEATS',
'AutoNBEATSx', 'AutoNHITS', 'AutoDLinear', 'AutoNLinear', 'AutoTiDE', 'AutoTFT', 'AutoVanillaTransformer',
'AutoInformer', 'AutoAutoformer', 'AutoFEDformer', 'AutoPatchTST', 'AutoiTransformer', 'AutoTimesNet',
'AutoStemGNN', 'AutoHINT', 'AutoTSMixer', 'AutoTSMixerx', 'AutoMLPMultivariate']
'AutoNBEATSx', 'AutoNHITS', 'AutoDLinear', 'AutoNLinear', 'AutoTiDE', 'AutoDeepNPTS', 'AutoTFT',
'AutoVanillaTransformer', 'AutoInformer', 'AutoAutoformer', 'AutoFEDformer', 'AutoPatchTST',
'AutoiTransformer', 'AutoTimesNet', 'AutoStemGNN', 'AutoHINT', 'AutoTSMixer', 'AutoTSMixerx',
'AutoMLPMultivariate']

# %% ../nbs/models.ipynb 2
from os import cpu_count
Expand All @@ -31,6 +32,7 @@
from .models.dlinear import DLinear
from .models.nlinear import NLinear
from .models.tide import TiDE
from .models.deepnpts import DeepNPTS

from .models.tft import TFT
from .models.vanillatransformer import VanillaTransformer
Expand Down Expand Up @@ -1033,7 +1035,76 @@ def get_default_config(cls, h, backend, n_series=None):

return config

# %% ../nbs/models.ipynb 71
# %% ../nbs/models.ipynb 70
class AutoDeepNPTS(BaseAuto):

default_config = {
"input_size_multiplier": [1, 2, 3, 4, 5],
"h": None,
"hidden_size": tune.choice([16, 32, 64]),
"dropout": tune.uniform(0.0, 0.99),
"n_layers": tune.choice([1, 2, 4]),
"learning_rate": tune.loguniform(1e-4, 1e-1),
"scaler_type": tune.choice([None, "robust", "standard"]),
"max_steps": tune.quniform(lower=500, upper=1500, q=100),
"batch_size": tune.choice([32, 64, 128, 256]),
"windows_batch_size": tune.choice([128, 256, 512, 1024]),
"loss": None,
"random_seed": tune.randint(lower=1, upper=20),
}

def __init__(
self,
h,
loss=MAE(),
valid_loss=None,
config=None,
search_alg=BasicVariantGenerator(random_state=1),
num_samples=10,
refit_with_val=False,
cpus=cpu_count(),
gpus=torch.cuda.device_count(),
verbose=False,
alias=None,
backend="ray",
callbacks=None,
):

# Define search space, input/output sizes
if config is None:
config = self.get_default_config(h=h, backend=backend)

super(AutoDeepNPTS, self).__init__(
cls_model=DeepNPTS,
h=h,
loss=loss,
valid_loss=valid_loss,
config=config,
search_alg=search_alg,
num_samples=num_samples,
refit_with_val=refit_with_val,
cpus=cpus,
gpus=gpus,
verbose=verbose,
alias=alias,
backend=backend,
callbacks=callbacks,
)

@classmethod
def get_default_config(cls, h, backend, n_series=None):
config = cls.default_config.copy()
config["input_size"] = tune.choice(
[h * x for x in config["input_size_multiplier"]]
)
config["step_size"] = tune.choice([1, h])
del config["input_size_multiplier"]
if backend == "optuna":
config = cls._ray_config_to_optuna(config)

return config

# %% ../nbs/models.ipynb 75
class AutoTFT(BaseAuto):

default_config = {
Expand Down Expand Up @@ -1101,7 +1172,7 @@ def get_default_config(cls, h, backend, n_series=None):

return config

# %% ../nbs/models.ipynb 75
# %% ../nbs/models.ipynb 79
class AutoVanillaTransformer(BaseAuto):

default_config = {
Expand Down Expand Up @@ -1169,7 +1240,7 @@ def get_default_config(cls, h, backend, n_series=None):

return config

# %% ../nbs/models.ipynb 79
# %% ../nbs/models.ipynb 83
class AutoInformer(BaseAuto):

default_config = {
Expand Down Expand Up @@ -1237,7 +1308,7 @@ def get_default_config(cls, h, backend, n_series=None):

return config

# %% ../nbs/models.ipynb 83
# %% ../nbs/models.ipynb 87
class AutoAutoformer(BaseAuto):

default_config = {
Expand Down Expand Up @@ -1305,7 +1376,7 @@ def get_default_config(cls, h, backend, n_series=None):

return config

# %% ../nbs/models.ipynb 87
# %% ../nbs/models.ipynb 91
class AutoFEDformer(BaseAuto):

default_config = {
Expand Down Expand Up @@ -1372,7 +1443,7 @@ def get_default_config(cls, h, backend, n_series=None):

return config

# %% ../nbs/models.ipynb 91
# %% ../nbs/models.ipynb 95
class AutoPatchTST(BaseAuto):

default_config = {
Expand Down Expand Up @@ -1442,7 +1513,7 @@ def get_default_config(cls, h, backend, n_series=None):

return config

# %% ../nbs/models.ipynb 95
# %% ../nbs/models.ipynb 99
class AutoiTransformer(BaseAuto):

default_config = {
Expand Down Expand Up @@ -1527,7 +1598,7 @@ def get_default_config(cls, h, backend, n_series):

return config

# %% ../nbs/models.ipynb 100
# %% ../nbs/models.ipynb 104
class AutoTimesNet(BaseAuto):

default_config = {
Expand Down Expand Up @@ -1595,7 +1666,7 @@ def get_default_config(cls, h, backend, n_series=None):

return config

# %% ../nbs/models.ipynb 105
# %% ../nbs/models.ipynb 109
class AutoStemGNN(BaseAuto):

default_config = {
Expand Down Expand Up @@ -1680,7 +1751,7 @@ def get_default_config(cls, h, backend, n_series):

return config

# %% ../nbs/models.ipynb 109
# %% ../nbs/models.ipynb 113
class AutoHINT(BaseAuto):

def __init__(
Expand Down Expand Up @@ -1752,7 +1823,7 @@ def _fit_model(
def get_default_config(cls, h, backend, n_series=None):
raise Exception("AutoHINT has no default configuration.")

# %% ../nbs/models.ipynb 114
# %% ../nbs/models.ipynb 118
class AutoTSMixer(BaseAuto):

default_config = {
Expand Down Expand Up @@ -1838,7 +1909,7 @@ def get_default_config(cls, h, backend, n_series):

return config

# %% ../nbs/models.ipynb 118
# %% ../nbs/models.ipynb 122
class AutoTSMixerx(BaseAuto):

default_config = {
Expand Down Expand Up @@ -1924,7 +1995,7 @@ def get_default_config(cls, h, backend, n_series):

return config

# %% ../nbs/models.ipynb 122
# %% ../nbs/models.ipynb 126
class AutoMLPMultivariate(BaseAuto):

default_config = {
Expand Down
4 changes: 2 additions & 2 deletions neuralforecast/common/_scalers.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,8 @@ def identity_statistics(x, mask, dim=-1, eps=1e-6):
shape = list(x.shape)
shape[dim] = 1

x_shift = torch.zeros(shape)
x_scale = torch.ones(shape)
x_shift = torch.zeros(shape, device=x.device)
x_scale = torch.ones(shape, device=x.device)

return x_shift, x_scale

Expand Down
3 changes: 3 additions & 0 deletions neuralforecast/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
iTransformer,
BiTCN,
TiDE,
DeepNPTS,
)

# %% ../nbs/core.ipynb 5
Expand Down Expand Up @@ -173,6 +174,8 @@ def _insample_times(
"autobitcn": BiTCN,
"tide": TiDE,
"autotide": TiDE,
"deepnpts": DeepNPTS,
"autodeepnpts": DeepNPTS,
}

# %% ../nbs/core.ipynb 8
Expand Down
8 changes: 7 additions & 1 deletion neuralforecast/losses/pytorch.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@

import torch.nn.functional as F
from torch.distributions import Distribution
from torch.distributions import Bernoulli, Normal, StudentT, Poisson, NegativeBinomial
from torch.distributions import (
Bernoulli,
Normal,
StudentT,
Poisson,
NegativeBinomial,
)

from torch.distributions import constraints

Expand Down
4 changes: 2 additions & 2 deletions neuralforecast/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
'MLP', 'NHITS', 'NBEATS', 'NBEATSx', 'DLinear', 'NLinear',
'TFT', 'VanillaTransformer', 'Informer', 'Autoformer', 'PatchTST', 'FEDformer',
'StemGNN', 'HINT', 'TimesNet', 'TimeLLM', 'TSMixer', 'TSMixerx', 'MLPMultivariate',
'iTransformer', 'BiTCN', 'TiDE',
'iTransformer', 'BiTCN', 'TiDE', 'DeepNPTS'
]

from .rnn import RNN
Expand Down Expand Up @@ -33,4 +33,4 @@
from .itransformer import iTransformer
from .bitcn import BiTCN
from .tide import TiDE

from .deepnpts import DeepNPTS
Loading
Loading