diff --git a/README.md b/README.md index b3a7d90..ca0e223 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@


- Torch Spatiotemporal + Torch Spatiotemporal

Neural spatiotemporal forecasting with PyTorch


PyPI PyPI - Python Version + Total downloads Documentation Status @@ -16,21 +17,21 @@

-

tsl (Torch Spatiotemporal) is a library built to accelerate research on neural spatiotemporal data processing +

tsl (Torch Spatiotemporal) is a library built to accelerate research on neural spatiotemporal data processing methods, with a focus on Graph Neural Networks.

-

tsl is built on several libraries of the Python scientific computing ecosystem, with the final objective of providing a straightforward process that goes from data preprocessing to model prototyping. -In particular, tsl offers a wide range of utilities to develop neural networks in PyTorch for processing spatiotemporal data signals.

+

tsl is built on several libraries of the Python scientific computing ecosystem, with the final objective of providing a straightforward process that goes from data preprocessing to model prototyping. +In particular, tsl offers a wide range of utilities to develop neural networks in PyTorch for processing spatiotemporal data signals.

## Getting Started -Before you start using tsl, please review the documentation to get an understanding of the library and its capabilities. +Before you start using tsl, please review the documentation to get an understanding of the library and its capabilities. You can also explore the examples provided in the `examples` directory to see how train deep learning models working with spatiotemporal data. ## Installation -Before installing tsl, make sure you have installed PyTorch (>=1.9.0) and PyG (>=2.0.3) in your virtual environment (see [PyG installation guidelines](https://pytorch-geometric.readthedocs.io/en/latest/install/installation.html)). tsl is available for Python>=3.8. We recommend installation from github to be up-to-date with the latest version: +Before installing tsl, make sure you have installed PyTorch (>=1.9.0) and PyG (>=2.0.3) in your virtual environment (see [PyG installation guidelines](https://pytorch-geometric.readthedocs.io/en/latest/install/installation.html)). tsl is available for Python>=3.8. We recommend installation from github to be up-to-date with the latest version: ```bash pip install git+https://github.com/TorchSpatiotemporal/tsl.git @@ -50,7 +51,7 @@ conda env create -f conda_env.yml ## Tutorial -The best way to start using tsl is by following the tutorial notebook in `examples/notebooks/a_gentle_introduction_to_tsl.ipynb`. +The best way to start using tsl is by following the tutorial notebook in `examples/notebooks/a_gentle_introduction_to_tsl.ipynb`. ## Documentation @@ -73,7 +74,7 @@ If you use Torch Spatiotemporal for your research, please consider citing the li By [Andrea Cini](https://andreacini.github.io/) and [Ivan Marisca](https://marshka.github.io/). -Thanks to all contributors! Check the [Contributing guidelines](https://github.com/TorchSpatiotemporal/tsl/blob/dev/.github/CONTRIBUTING.md) and help us build a better tsl. +Thanks to all contributors! Check the [Contributing guidelines](https://github.com/TorchSpatiotemporal/tsl/blob/dev/.github/CONTRIBUTING.md) and help us build a better tsl. diff --git a/examples/imputation/run_imputation_experiment.py b/examples/imputation/run_imputation_experiment.py index 8232f3c..0017f52 100644 --- a/examples/imputation/run_imputation_experiment.py +++ b/examples/imputation/run_imputation_experiment.py @@ -164,12 +164,14 @@ def run_imputation(cfg: DictConfig): mode='min', ) - trainer = Trainer(max_epochs=cfg.epochs, - default_root_dir=cfg.run.dir, - logger=exp_logger, - gpus=1 if torch.cuda.is_available() else None, - gradient_clip_val=cfg.grad_clip_val, - callbacks=[early_stop_callback, checkpoint_callback]) + trainer = Trainer( + max_epochs=cfg.epochs, + default_root_dir=cfg.run.dir, + logger=exp_logger, + accelerator='gpu' if torch.cuda.is_available() else 'cpu', + devices=1, + gradient_clip_val=cfg.grad_clip_val, + callbacks=[early_stop_callback, checkpoint_callback]) trainer.fit(imputer, datamodule=dm) diff --git a/tsl/datasets/pems_bay.py b/tsl/datasets/pems_bay.py index 0a9b2a5..4c3162c 100644 --- a/tsl/datasets/pems_bay.py +++ b/tsl/datasets/pems_bay.py @@ -77,11 +77,8 @@ def load_raw(self): # load traffic data traffic_path = os.path.join(self.root_dir, 'pems_bay.h5') df = pd.read_hdf(traffic_path) - # add missing values - datetime_idx = sorted(df.index) - date_range = pd.date_range(datetime_idx[0], - datetime_idx[-1], - freq='5T') + # add missing values (index is sorted) + date_range = pd.date_range(df.index[0], df.index[-1], freq='5T') df = df.reindex(index=date_range) # load distance matrix path = os.path.join(self.root_dir, 'pems_bay_dist.npy') diff --git a/tsl/datasets/prototypes/casting.py b/tsl/datasets/prototypes/casting.py index 45a3421..47bba37 100644 --- a/tsl/datasets/prototypes/casting.py +++ b/tsl/datasets/prototypes/casting.py @@ -99,4 +99,4 @@ def time_unit_to_nanoseconds(time_unit: str): return 365.2425 * 24 * 60 * 60 * 10**9 elif time_unit == 'week': time_unit = 'W' - return pd.Timedelta('1' + time_unit).delta + return pd.Timedelta('1' + time_unit).value diff --git a/tsl/metrics/torch/metric_base.py b/tsl/metrics/torch/metric_base.py index 58fe948..f187f03 100644 --- a/tsl/metrics/torch/metric_base.py +++ b/tsl/metrics/torch/metric_base.py @@ -65,10 +65,9 @@ def __init__(self, if metric_fn_kwargs is None: metric_fn_kwargs = dict() - if metric_fn is None: - self.metric_fn = None - else: - self.metric_fn = partial(metric_fn, **metric_fn_kwargs) + + self.metric_fn = partial(metric_fn, **metric_fn_kwargs) + self.mask_nans = mask_nans self.mask_inf = mask_inf if at is None: diff --git a/tsl/nn/layers/base/embedding.py b/tsl/nn/layers/base/embedding.py index 8e1ed68..2df8e8c 100644 --- a/tsl/nn/layers/base/embedding.py +++ b/tsl/nn/layers/base/embedding.py @@ -63,19 +63,18 @@ def get_emb(self): def forward(self, expand: Optional[List] = None, - token_index: OptTensor = None, - tokens_first: bool = True): + node_index: OptTensor = None, + nodes_first: bool = True): """""" emb = self.get_emb() - if token_index is not None: - emb = emb[token_index] - if not tokens_first: + if node_index is not None: + emb = emb[node_index] + if not nodes_first: emb = emb.T if expand is None: return emb shape = [*emb.size()] view = [ - 1 if d > 0 else shape.pop(0 if tokens_first else -1) - for d in expand + 1 if d > 0 else shape.pop(0 if nodes_first else -1) for d in expand ] return emb.view(*view).expand(*expand)