From 6e59f18662784db9e73b189fa77380c2054decc4 Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Thu, 24 Feb 2022 19:00:29 -0800 Subject: [PATCH 01/19] added sphinx stuff --- .github/workflows/docs.yml | 2 +- .gitignore | 2 + docs/source/_templates/theme_variables.jinja | 2 +- docs/source/conf.py | 2 +- scripts/build_docs.sh | 22 ++++ website/.gitignore | 2 + website/docusaurus.config.js | 103 ++++++++++--------- 7 files changed, 83 insertions(+), 52 deletions(-) create mode 100644 scripts/build_docs.sh diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 4aea716c..de4d3a8d 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -36,7 +36,7 @@ jobs: node-version: 14 - name: Build documentation - run: poetry run make -C docs html + run: ./scripts/build_docs.sh - name: Build Docusaurus website run: | diff --git a/.gitignore b/.gitignore index a072a3de..618daadc 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ dist/ *.h5 *.npz *.pkl + +venv diff --git a/docs/source/_templates/theme_variables.jinja b/docs/source/_templates/theme_variables.jinja index 66d44028..046b27cd 100644 --- a/docs/source/_templates/theme_variables.jinja +++ b/docs/source/_templates/theme_variables.jinja @@ -1,6 +1,6 @@ {%- set external_urls = { 'github': 'https://github.com/Rose-STL-Lab/torchTS', - 'home': 'https://github.com/Rose-STL-Lab/torchTS/', + 'home': 'https://rose-stl-lab.github.io/torchTS/docs/', 'get_started': ' ', 'blog': 'https://github.com/Rose-STL-Lab/torchTS', 'resources': 'https://github.com/Rose-STL-Lab/torchTS', diff --git a/docs/source/conf.py b/docs/source/conf.py index cb406d71..5ee69b2c 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -88,7 +88,7 @@ # documentation. html_theme_options = { "pytorch_project": "tutorials", - "canonical_url": "https://github.com/Rose-STL-Lab/torchTS", + "canonical_url": "https://rose-stl-lab.github.io/torchTS/docs/", "collapse_navigation": False, "display_version": True, "logo": "_static/images/torchTS_logo.png", diff --git a/scripts/build_docs.sh b/scripts/build_docs.sh new file mode 100644 index 00000000..b8404244 --- /dev/null +++ b/scripts/build_docs.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# run this script from the project root using `./scripts/build_docs.sh` + +echo "-----------------------------------" +echo "Generating API reference via Sphinx" +echo "-----------------------------------" +cd docs || exit +make html +cd .. || exit + + +# run script to parse html generated by sphinx +echo "--------------------------------------------" +echo "Parsing Sphinx docs and moving to Docusaurus" +echo "--------------------------------------------" +mkdir -p "website/static/api/" + +cwd=$(pwd) +SPHINX_HTML_DIR="website/static/api/" +cp -R "${cwd}/docs/build/html/" "${cwd}/${SPHINX_HTML_DIR}" +echo "Parsed Sucessfully" +echo "Moved location: ${SPHINX_HTML_DIR}" \ No newline at end of file diff --git a/website/.gitignore b/website/.gitignore index b2d6de30..73206c3b 100644 --- a/website/.gitignore +++ b/website/.gitignore @@ -1,8 +1,10 @@ # Dependencies /node_modules +yarn.lock # Production /build +/static/api # Generated files .docusaurus diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 1bb12336..35331616 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -1,66 +1,71 @@ -const lightCodeTheme = require("prism-react-renderer/themes/github"); -const darkCodeTheme = require("prism-react-renderer/themes/dracula"); -const math = require("remark-math"); -const katex = require("rehype-katex"); +const lightCodeTheme = require('prism-react-renderer/themes/github'); +const darkCodeTheme = require('prism-react-renderer/themes/dracula'); +const math = require('remark-math'); +const katex = require('rehype-katex'); /** @type {import('@docusaurus/types').DocusaurusConfig} */ module.exports = { - title: "TorchTS", - tagline: "Time series forecasting with PyTorch", - url: "https://rose-stl-lab.github.io", - baseUrl: "/torchTS/", - onBrokenLinks: "throw", - onBrokenMarkdownLinks: "warn", - favicon: "img/logo2.png", + title: 'TorchTS', + tagline: 'Time series forecasting with PyTorch', + url: 'https://rose-stl-lab.github.io', + baseUrl: '/torchTS/', + onBrokenLinks: 'throw', + onBrokenMarkdownLinks: 'warn', + favicon: 'img/logo2.png', scripts: [ - "https://buttons.github.io/buttons.js", - "https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js", + 'https://buttons.github.io/buttons.js', + 'https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js', ], stylesheets: [ - "https://fonts.googleapis.com/css?family=IBM+Plex+Mono:500,700|Source+Code+Pro:500,700|Source+Sans+Pro:400,400i,700", + 'https://fonts.googleapis.com/css?family=IBM+Plex+Mono:500,700|Source+Code+Pro:500,700|Source+Sans+Pro:400,400i,700', { - href: "https://cdn.jsdelivr.net/npm/katex@0.13.11/dist/katex.min.css", + href: 'https://cdn.jsdelivr.net/npm/katex@0.13.11/dist/katex.min.css', integrity: - "sha384-Um5gpz1odJg5Z4HAmzPtgZKdTBHZdw8S29IecapCSB31ligYPhHQZMIlWLYQGVoc", - crossorigin: "anonymous", + 'sha384-Um5gpz1odJg5Z4HAmzPtgZKdTBHZdw8S29IecapCSB31ligYPhHQZMIlWLYQGVoc', + crossorigin: 'anonymous', }, ], - organizationName: "Rose-STL-Lab", // Usually your GitHub org/user name. - projectName: "torchTS", // Usually your repo name. + organizationName: 'Rose-STL-Lab', // Usually your GitHub org/user name. + projectName: 'torchTS', // Usually your repo name. themeConfig: { // colorMode: { // defaultMode: "light", // disableSwitch: true, // }, navbar: { - title: "TorchTS", + title: 'TorchTS', logo: { - alt: "My Site Logo", - src: "img/logo2.png", + alt: 'My Site Logo', + src: 'img/logo2.png', }, items: [ { - type: "doc", - docId: "intro", - position: "left", - label: "Docs", + type: 'doc', + docId: 'intro', + position: 'left', + label: 'Docs', }, { - href: "https://github.com/Rose-STL-Lab/torchTS", - label: "GitHub", - position: "right", + href: 'https://rose-stl-lab.github.io/torchTS/api', + label: 'API Reference', + position: 'left', + }, + { + href: 'https://github.com/Rose-STL-Lab/torchTS', + label: 'GitHub', + position: 'right', }, ], }, footer: { links: [ { - title: "Docs", + title: 'Docs', items: [ { - label: "Getting Started", - to: "docs", + label: 'Getting Started', + to: 'docs', }, // { // label: 'Tutorials', @@ -73,20 +78,20 @@ module.exports = { ], }, { - title: "Community", + title: 'Community', items: [ { - label: "Slack", - href: "https://github.com/Rose-STL-Lab/torchTS", + label: 'Slack', + href: 'https://github.com/Rose-STL-Lab/torchTS', }, { - label: "Discord", - href: "https://github.com/Rose-STL-Lab/torchTS", + label: 'Discord', + href: 'https://github.com/Rose-STL-Lab/torchTS', }, ], }, { - title: "More", + title: 'More', items: [ { html: ` @@ -100,19 +105,19 @@ module.exports = { `, }, { - label: "GitHub", - href: "https://github.com/Rose-STL-Lab/torchTS", + label: 'GitHub', + href: 'https://github.com/Rose-STL-Lab/torchTS', }, { - label: "Edit Docs on GitHub", - href: "https://github.com/Rose-STL-Lab/torchTS", + label: 'Edit Docs on GitHub', + href: 'https://github.com/Rose-STL-Lab/torchTS', }, ], }, ], copyright: `Copyright © ${new Date().getFullYear()} TorchTS Team`, logo: { - src: "img/octopus-128x128.png", + src: 'img/octopus-128x128.png', }, }, prism: { @@ -120,25 +125,25 @@ module.exports = { darkTheme: darkCodeTheme, }, fonts: { - fontMain: ["Source Sans Pro", "sans-serif"], - fontCode: ["IBM Plex Mono", "monospace"], + fontMain: ['Source Sans Pro', 'sans-serif'], + fontCode: ['IBM Plex Mono', 'monospace'], }, }, presets: [ [ - "@docusaurus/preset-classic", + '@docusaurus/preset-classic', { docs: { - sidebarPath: require.resolve("./sidebars.js"), + sidebarPath: require.resolve('./sidebars.js'), remarkPlugins: [math], showLastUpdateAuthor: true, showLastUpdateTime: true, rehypePlugins: [katex], // Please change this to your repo. - editUrl: "https://github.com/Rose-STL-Lab/torchTS/edit/main/website/", + editUrl: 'https://github.com/Rose-STL-Lab/torchTS/edit/main/website/', }, theme: { - customCss: require.resolve("./src/css/custom.css"), + customCss: require.resolve('./src/css/custom.css'), }, }, ], From 3c6c078b061942ea4d876e137bc9849f82daebf8 Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Thu, 24 Feb 2022 19:10:13 -0800 Subject: [PATCH 02/19] Update README.md --- website/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/website/README.md b/website/README.md index 231a499c..d8d44f60 100644 --- a/website/README.md +++ b/website/README.md @@ -16,6 +16,13 @@ yarn start This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. +**Important**: API Reference page doesn't get updated automatically. We will have to run the following commands in order to build API Docs with Sphinx + +```bash +source ./scripts/build_docs.sh # mac +./scripts/build_docs.sh # window +``` + ## Build ```console From 3c1b86da6c29b2cef62c2c1ec113d91954b6bd9f Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Thu, 24 Feb 2022 19:16:42 -0800 Subject: [PATCH 03/19] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 618daadc..dfca5dcb 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ dist/ *.pkl venv +.vscode \ No newline at end of file From 1ea3fa1110ad1122234065e5e23f3e809b4e7318 Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Sat, 26 Feb 2022 14:17:53 -0800 Subject: [PATCH 04/19] added skeleton file for docs --- docs/source/contributing.rst | 4 ++++ docs/source/index.rst | 10 ++++++++-- docs/source/installation.rst | 4 ++++ docs/source/modules.rst | 7 ------- docs/source/torchts.nn.rst | 5 +++++ docs/source/torchts.utils.rst | 5 +++++ scripts/build_docs.sh | 0 7 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 docs/source/contributing.rst create mode 100644 docs/source/installation.rst delete mode 100644 docs/source/modules.rst create mode 100644 docs/source/torchts.nn.rst create mode 100644 docs/source/torchts.utils.rst mode change 100644 => 100755 scripts/build_docs.sh diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst new file mode 100644 index 00000000..60fd3228 --- /dev/null +++ b/docs/source/contributing.rst @@ -0,0 +1,4 @@ +Contributing to TorchTS +======================= + + diff --git a/docs/source/index.rst b/docs/source/index.rst index 1e5a177d..4015d617 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -6,12 +6,18 @@ Welcome to TorchTS's documentation! =================================== +Models Intro here! +Code here! + + .. toctree:: :maxdepth: 2 :caption: Contents: - modules - torchts + installation + torchts.nn + torchts.utils + contributing diff --git a/docs/source/installation.rst b/docs/source/installation.rst new file mode 100644 index 00000000..2b432e1d --- /dev/null +++ b/docs/source/installation.rst @@ -0,0 +1,4 @@ +Installation +=============== + + diff --git a/docs/source/modules.rst b/docs/source/modules.rst deleted file mode 100644 index 43287c00..00000000 --- a/docs/source/modules.rst +++ /dev/null @@ -1,7 +0,0 @@ -torchts -======= - -.. toctree:: - :maxdepth: 4 - - torchts diff --git a/docs/source/torchts.nn.rst b/docs/source/torchts.nn.rst new file mode 100644 index 00000000..a5e21147 --- /dev/null +++ b/docs/source/torchts.nn.rst @@ -0,0 +1,5 @@ +torchts.nn +=============== + + +.. automodule:: torchts.nn.models.dcrnn diff --git a/docs/source/torchts.utils.rst b/docs/source/torchts.utils.rst new file mode 100644 index 00000000..333aa49b --- /dev/null +++ b/docs/source/torchts.utils.rst @@ -0,0 +1,5 @@ +torchts.utils +=============== + + +.. automodule:: torchts.utils.data diff --git a/scripts/build_docs.sh b/scripts/build_docs.sh old mode 100644 new mode 100755 From b2f655e4f0c45205574ea3d89789e73d0bce9a48 Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Sat, 26 Feb 2022 14:33:28 -0800 Subject: [PATCH 05/19] Update index.rst --- docs/source/index.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/source/index.rst b/docs/source/index.rst index 4015d617..5be7e762 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -6,10 +6,6 @@ Welcome to TorchTS's documentation! =================================== -Models Intro here! -Code here! - - .. toctree:: :maxdepth: 2 :caption: Contents: From f398ca53f0a41ce349116dab3a25445284a9f8e3 Mon Sep 17 00:00:00 2001 From: Miles <44444826+MilesLabrador@users.noreply.github.com> Date: Sat, 26 Feb 2022 17:59:43 -0800 Subject: [PATCH 06/19] Added instructions on installing torchTS in two methods --- docs/source/installation.rst | 74 +++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/docs/source/installation.rst b/docs/source/installation.rst index 2b432e1d..df9ef757 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -1,4 +1,74 @@ -Installation -=============== +Installing torchTS +=================== +Dependencies +^^^^^^^^^^^^ +* Python 3.7+ +* `PyTorch `_ +* `PyTorch Lightning `_ +* `SciPy `_ + +Installing the Latest Release +------------------------------ + +PyTorch Configuration +^^^^^^^^^^^^^^^^^^^^^ +- Since torchTS is built upon PyTorch, you may want to customize your PyTorch configuration for your specific needs by following the `PyTorch installation instructions `_. + +**Important note for MacOS users:** + +- If you need CUDA on MacOS, you will need to build PyTorch from source. Please consult the PyTorch installation instructions above. + +Typical Installation +^^^^^^^^^^^^^^^^^^^^ + +- To install torchTS through PyPI, execute this command:: + + pip install torchts + +Conda Installation +^^^^^^^^^^^^^^^^^^ + +- If you would like to install torchTS through conda, it is available through this command:: + + conda install -c conda-forge torchts + +torchTS Installation for Development Local Environment +------------------------------------------------------ + +- In order to develop torchTS, it is important to ensure you have the most up-to-date dependencies. `Poetry `_ is used by torchTS to help manage these dependencies in a elegant manner. + +Clone repository +^^^^^^^^^^^^^^^^^^ +- Begin by cloning the GitHub Repository:: + + # Clone the latest version of torchTS from GitHub and navigate to the root directory + git clone https://github.com/Rose-STL-Lab/torchTS.git + cd torchTS + + +Use Poetry to Install Dependencies +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Once you are in the root directory for torchTS, you can use the following command to install the most up-to-date dependencies for torchTS +- If you are unfamiliar with Poetry, follow the guides on `installation `_ and `basic usage `_ from the Poetry project’s documentation.:: + + # install torchTS' dependencies through poetry + poetry install + +Running a simple notebook with your local environment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Poetry essentially sets up a virtual environment that automatically configures itself with the dependencies needed to work with torchTS. +- Once you’ve installed the dependencies for torchTS through Poetry, we can run a Jupyter Notebook with a base kernel built upon torchTS’ using these commands:: + + # Run this from the root directory of torchTS + poetry run jupyter notebook + +- Similarly, we can run Python scripts through our compatible environment using this code configuration:: + + # Run any python script through our new + poetry run [PYTHON FILE] + +- Poetry is a very capable package management tool and we recommend you explore it’s functionalities further with `their documentation `_ to get the most out of it. From dfd46c007b5f30ee5ea62c63e93414da4d4ae704 Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Mon, 28 Feb 2022 15:50:06 -0800 Subject: [PATCH 07/19] added docs for torchts.nn and utils --- docs/source/index.rst | 7 +-- docs/source/torchts.nn.loss.rst | 7 +++ .../{torchts.nn.rst => torchts.nn/dcrnn.rst} | 6 +-- docs/source/torchts.nn/index.rst | 8 ++++ docs/source/torchts.nn/seq2seq.rst | 5 ++ docs/source/torchts.utils.data.rst | 5 ++ docs/source/torchts.utils.rst | 5 -- torchts/nn/models/dcrnn.py | 47 +++++++++++++++---- torchts/nn/models/seq2seq.py | 40 +++++++++++++--- 9 files changed, 104 insertions(+), 26 deletions(-) create mode 100644 docs/source/torchts.nn.loss.rst rename docs/source/{torchts.nn.rst => torchts.nn/dcrnn.rst} (59%) create mode 100644 docs/source/torchts.nn/index.rst create mode 100644 docs/source/torchts.nn/seq2seq.rst create mode 100644 docs/source/torchts.utils.data.rst delete mode 100644 docs/source/torchts.utils.rst diff --git a/docs/source/index.rst b/docs/source/index.rst index 5be7e762..c4eeee38 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -7,12 +7,13 @@ Welcome to TorchTS's documentation! =================================== .. toctree:: - :maxdepth: 2 + :maxdepth: 1 :caption: Contents: installation - torchts.nn - torchts.utils + torchts.nn/index + torchts.nn.loss + torchts.utils.data contributing diff --git a/docs/source/torchts.nn.loss.rst b/docs/source/torchts.nn.loss.rst new file mode 100644 index 00000000..6693b53e --- /dev/null +++ b/docs/source/torchts.nn.loss.rst @@ -0,0 +1,7 @@ +torchts.nn.loss +=============== + +.. automodule:: torchts.nn.loss + :members: + :show-inheritance: + diff --git a/docs/source/torchts.nn.rst b/docs/source/torchts.nn/dcrnn.rst similarity index 59% rename from docs/source/torchts.nn.rst rename to docs/source/torchts.nn/dcrnn.rst index a5e21147..9354fc70 100644 --- a/docs/source/torchts.nn.rst +++ b/docs/source/torchts.nn/dcrnn.rst @@ -1,5 +1,5 @@ -torchts.nn -=============== - +DCRNN +===== .. automodule:: torchts.nn.models.dcrnn + :members: \ No newline at end of file diff --git a/docs/source/torchts.nn/index.rst b/docs/source/torchts.nn/index.rst new file mode 100644 index 00000000..4f0ae355 --- /dev/null +++ b/docs/source/torchts.nn/index.rst @@ -0,0 +1,8 @@ +torchts.nn +=============== + +.. toctree:: + :caption: Models: + + seq2seq + dcrnn diff --git a/docs/source/torchts.nn/seq2seq.rst b/docs/source/torchts.nn/seq2seq.rst new file mode 100644 index 00000000..0db55c73 --- /dev/null +++ b/docs/source/torchts.nn/seq2seq.rst @@ -0,0 +1,5 @@ +Seq2seq +======= + +.. automodule:: torchts.nn.models.seq2seq + :members: \ No newline at end of file diff --git a/docs/source/torchts.utils.data.rst b/docs/source/torchts.utils.data.rst new file mode 100644 index 00000000..48f2fc9f --- /dev/null +++ b/docs/source/torchts.utils.data.rst @@ -0,0 +1,5 @@ +torchts.utils.data +================== + +.. automodule:: torchts.utils.data + :members: diff --git a/docs/source/torchts.utils.rst b/docs/source/torchts.utils.rst deleted file mode 100644 index 333aa49b..00000000 --- a/docs/source/torchts.utils.rst +++ /dev/null @@ -1,5 +0,0 @@ -torchts.utils -=============== - - -.. automodule:: torchts.utils.data diff --git a/torchts/nn/models/dcrnn.py b/torchts/nn/models/dcrnn.py index 174e4200..24cff5be 100644 --- a/torchts/nn/models/dcrnn.py +++ b/torchts/nn/models/dcrnn.py @@ -7,6 +7,13 @@ class Encoder(nn.Module): + """Encoder + + Args: + input_dim: the dimension of input sequences. + seq_len: sequence length. + """ + def __init__(self, input_dim, seq_len, **kwargs): super().__init__() self.input_dim = input_dim @@ -19,6 +26,13 @@ def forward(self, inputs, hidden_state): class Decoder(nn.Module): + """Decoder + + Args: + output_dim: the dimension of output sequences. + horizon: prediction horizon. + """ + def __init__(self, output_dim, horizon, **kwargs): super().__init__() self.output_dim = output_dim @@ -36,6 +50,24 @@ def forward(self, inputs, hidden_state): class DCRNN(TimeSeriesModel): + """DCRNN + + Args: + adj_mx: torch tensor of shape [num_nodes, num_nodes] + num_units: the dimension of the hidden state. + seq_len: sequence length. + horizon: prediction horizon. + input_dim: the dimension of input sequences. + output_dim: the dimension of output sequences. + max_diffusion_step: the maximum diffusion time step + filter_type: the type of filter to use. + num_nodes: number of nodes in the graph. + num_layers: number of hidden layers. + use_gc_for_ru: whether to use graph convolution + use_curriculum_learning: whether to use curriculum learning. + cl_decay_steps: the number of steps to use curriculum learning. + """ + def __init__( self, adj_mx, @@ -76,8 +108,7 @@ def __init__( def _compute_sampling_threshold(self, batches_seen): return self.cl_decay_steps / ( - self.cl_decay_steps + np.exp(batches_seen / self.cl_decay_steps) - ) + self.cl_decay_steps + np.exp(batches_seen / self.cl_decay_steps)) def encoder(self, inputs): batch_size = inputs.size(1) @@ -86,8 +117,7 @@ def encoder(self, inputs): for t in range(self.encoder_model.seq_len): _, encoder_hidden_state = self.encoder_model( - inputs[t], encoder_hidden_state - ) + inputs[t], encoder_hidden_state) return encoder_hidden_state @@ -101,8 +131,7 @@ def decoder(self, encoder_hidden_state, labels=None, batches_seen=None): for t in range(self.decoder_model.horizon): decoder_output, decoder_hidden_state = self.decoder_model( - decoder_input, decoder_hidden_state - ) + decoder_input, decoder_hidden_state) decoder_input = decoder_output outputs.append(decoder_output) @@ -117,7 +146,9 @@ def decoder(self, encoder_hidden_state, labels=None, batches_seen=None): def forward(self, inputs, labels=None, batches_seen=None): encoder_hidden_state = self.encoder(inputs) - outputs = self.decoder(encoder_hidden_state, labels, batches_seen=batches_seen) + outputs = self.decoder(encoder_hidden_state, + labels, + batches_seen=batches_seen) return outputs @@ -132,7 +163,7 @@ def prepare_batch(self, batch): batch_size, self.num_nodes * self.encoder_model.input_dim, ) - y = y[..., : self.decoder_model.output_dim].view( + y = y[..., :self.decoder_model.output_dim].view( self.decoder_model.horizon, batch_size, self.num_nodes * self.decoder_model.output_dim, diff --git a/torchts/nn/models/seq2seq.py b/torchts/nn/models/seq2seq.py index 9b0ed9c9..a6de8fcf 100644 --- a/torchts/nn/models/seq2seq.py +++ b/torchts/nn/models/seq2seq.py @@ -5,13 +5,22 @@ class Encoder(nn.Module): + """Encoder + + Args: + input_dim: the dimension of input sequences. + hidden_dim: number hidden units. + num_layers: number of encode layers. + dropout_rate: recurrent dropout rate. + """ + def __init__(self, input_dim, hidden_dim, num_layers, dropout_rate): """ Args: input_dim: the dimension of input sequences. hidden_dim: number hidden units. num_layers: number of encode layers. - dropout_rate: recurrent dropout rate. + dropout_rate: dropout rate. """ super().__init__() self.num_layers = num_layers @@ -38,6 +47,15 @@ def forward(self, source): class Decoder(nn.Module): + """Decoder + + Args: + output_dim: the dimension of output sequences. + hidden_dim: number hidden units. + num_layers: number of code layers. + dropout_rate: dropout rate. + """ + def __init__(self, output_dim, hidden_dim, num_layers, dropout_rate): """ Args: @@ -74,6 +92,15 @@ def forward(self, x, hidden): class Seq2Seq(TimeSeriesModel): + """Seq2Seq + + Args: + encoder: Encoder object. + decoder: Decoder object. + output_dim: the dimension of output sequences. + horizon: number of steps to predict. + """ + def __init__(self, encoder, decoder, output_dim, horizon, **kwargs): """ Args: @@ -98,8 +125,8 @@ def forward(self, source, target=None, batches_seen=None): # Concatenate the hidden states of both directions. h = torch.cat( [ - encoder_hidden[0][0 : self.encoder.num_layers, :, :], - encoder_hidden[0][-self.encoder.num_layers :, :, :], + encoder_hidden[0][0:self.encoder.num_layers, :, :], + encoder_hidden[0][-self.encoder.num_layers:, :, :], ], dim=2, out=None, @@ -107,8 +134,8 @@ def forward(self, source, target=None, batches_seen=None): c = torch.cat( [ - encoder_hidden[1][0 : self.encoder.num_layers, :, :], - encoder_hidden[1][-self.encoder.num_layers :, :, :], + encoder_hidden[1][0:self.encoder.num_layers, :, :], + encoder_hidden[1][-self.encoder.num_layers:, :, :], ], dim=2, out=None, @@ -122,8 +149,7 @@ def forward(self, source, target=None, batches_seen=None): for _ in range(self.horizon): decoder_output, decoder_hidden = self.decoder( - decoder_output, decoder_hidden - ) + decoder_output, decoder_hidden) outputs.append(decoder_output) return torch.cat(outputs, dim=1) From fa479aed2760758179b1cace3b8b7409fab6ac9b Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Mon, 28 Feb 2022 16:34:50 -0800 Subject: [PATCH 08/19] added getting_started section --- .../images/getting_started__dataset_plot.png | Bin 0 -> 17187 bytes .../getting_started__pred_results_1.png | Bin 0 -> 26128 bytes .../getting_started__sample_dataset.png | Bin 0 -> 29165 bytes .../getting_started__sample_results.png | Bin 0 -> 43439 bytes docs/source/build_your_own_model.rst | 9 ++ docs/source/getting_started.rst | 83 ++++++++++++++++++ docs/source/index.rst | 18 +++- docs/source/torchts.nn.loss.rst | 1 - docs/source/torchts.rst | 18 ---- 9 files changed, 108 insertions(+), 21 deletions(-) create mode 100644 docs/source/_static/images/getting_started__dataset_plot.png create mode 100644 docs/source/_static/images/getting_started__pred_results_1.png create mode 100644 docs/source/_static/images/getting_started__sample_dataset.png create mode 100644 docs/source/_static/images/getting_started__sample_results.png create mode 100644 docs/source/build_your_own_model.rst create mode 100644 docs/source/getting_started.rst delete mode 100644 docs/source/torchts.rst diff --git a/docs/source/_static/images/getting_started__dataset_plot.png b/docs/source/_static/images/getting_started__dataset_plot.png new file mode 100644 index 0000000000000000000000000000000000000000..3b8c9980b01404c5cd28770f6280032a70fb7a24 GIT binary patch literal 17187 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�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 UE_Z@&XTg9gYbupIvUvS}0LH1nj{pDw literal 0 HcmV?d00001 diff --git a/docs/source/_static/images/getting_started__sample_dataset.png b/docs/source/_static/images/getting_started__sample_dataset.png new file mode 100644 index 0000000000000000000000000000000000000000..16caab307e68f4d9ea64ee407cd482610f9a43b5 GIT binary patch literal 29165 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%0Ayj)FSs~A3)O^T)!+b~Wz_mwlf3P`j<^PGJy8u% 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 Lc{A_E!{`48$8aO) literal 0 HcmV?d00001 diff --git a/docs/source/_static/images/getting_started__sample_results.png b/docs/source/_static/images/getting_started__sample_results.png new file mode 100644 index 0000000000000000000000000000000000000000..d8e56c235a30ff42af6c536edad7c31bdd8f4981 GIT binary patch literal 43439 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 LL$UIi`MduCp0(RB literal 0 HcmV?d00001 diff --git a/docs/source/build_your_own_model.rst b/docs/source/build_your_own_model.rst new file mode 100644 index 00000000..bdcdb0f8 --- /dev/null +++ b/docs/source/build_your_own_model.rst @@ -0,0 +1,9 @@ +Build Your Own Model +==================== + + + +TimeSeriesModel +--------------- + +.. automodule:: torchts.nn.model diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst new file mode 100644 index 00000000..c25c9d2f --- /dev/null +++ b/docs/source/getting_started.rst @@ -0,0 +1,83 @@ +Getting Started +=============== + +Make sure you have installed `torchTS` + +In the following example, we will use the `torchTS` package to train a simple LSTM model on a time-series datasets. We will also enable uncertainty quantification so that we can get prediction intervals. + +1. First, we will import necessary package. + +.. code-block:: python + + import torch + import torchts + import numpy as np + + +2. Let's randomly generate a time-series dataset. + +.. code-block:: python + + # generate linear time series data with some noise + n = 200 + x_max = 10 + slope = 2 + scale = 2 + + x = torch.from_numpy(np.linspace(-x_max, x_max, n).reshape(-1, 1).astype(np.float32)) + y = slope * x + np.random.normal(0, scale, n).reshape(-1, 1).astype(np.float32) + + plt.plot(x, y) + plt.show() + +We will get the following plots: + +.. image:: ./_static/images/getting_started__dataset_plot.png + :scale: 100% + + +3. Then, we can start selecting and training our model. In this example, we will use LSTM model. + +.. code-block:: python + + model = LSTM( + input_size, + output_size, + hidden_size, + optimizer, + interval=interval, + optimizer_args=optimizer_args, + ) + model.fit(x, y, max_epochs=max_epochs, batch_size=batch_size) + + +4. After model is trained, we can use it to predict the future values. And more importantly, since we enable uncertainty quantification method, we can also get a prediction interval! + +.. code-block:: python + + y_preds = model.predict(x) + + +5. Let's plot prediction results + +.. code-block:: python + + plt.plot(x, y, label="y_true") + plt.plot(x, y_preds, label=["lower", "upper"]) + plt.legend() + plt.show() + + +.. image:: ./_static/images/getting_started__pred_results_1.png + :scale: 100% + + +Example prediction results for other datasets: + + +.. image:: ./_static/images/getting_started__sample_dataset.png + :scale: 100% + + +.. image:: ./_static/images/getting_started__sample_results.png + :scale: 100% diff --git a/docs/source/index.rst b/docs/source/index.rst index c4eeee38..9ce3cfa5 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -6,16 +6,30 @@ Welcome to TorchTS's documentation! =================================== + + .. toctree:: :maxdepth: 1 - :caption: Contents: + :caption: Getting Started: installation + getting_started + + +.. toctree:: + :maxdepth: 1 + :caption: TorchTS Documentation: + torchts.nn/index torchts.nn.loss torchts.utils.data - contributing +.. toctree:: + :maxdepth: 1 + :caption: More Advanced + + build_your_own_model + contributing Indices and tables diff --git a/docs/source/torchts.nn.loss.rst b/docs/source/torchts.nn.loss.rst index 6693b53e..debf7c22 100644 --- a/docs/source/torchts.nn.loss.rst +++ b/docs/source/torchts.nn.loss.rst @@ -3,5 +3,4 @@ torchts.nn.loss .. automodule:: torchts.nn.loss :members: - :show-inheritance: diff --git a/docs/source/torchts.rst b/docs/source/torchts.rst deleted file mode 100644 index 08e1916f..00000000 --- a/docs/source/torchts.rst +++ /dev/null @@ -1,18 +0,0 @@ -torchts package -=============== - -Submodules ----------- - -Base classes ------------- - -.. automodule:: torchts.nn.model - -Module contents ---------------- - -.. automodule:: torchts - :members: - :undoc-members: - :show-inheritance: From ba380d71ca093cc32ec5d805736ee97e4b956098 Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Mon, 28 Feb 2022 16:51:15 -0800 Subject: [PATCH 09/19] added math functions --- docs/source/getting_started.rst | 2 +- docs/source/torchts.nn.loss.rst | 29 +++++++++++++++++++++++++++-- docs/source/torchts.nn/dcrnn.rst | 10 ++++++++++ docs/source/torchts.nn/seq2seq.rst | 12 ++++++++++++ torchts/nn/models/seq2seq.py | 2 +- 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index c25c9d2f..b30f1ec7 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -73,7 +73,7 @@ We will get the following plots: Example prediction results for other datasets: - + .. image:: ./_static/images/getting_started__sample_dataset.png :scale: 100% diff --git a/docs/source/torchts.nn.loss.rst b/docs/source/torchts.nn.loss.rst index debf7c22..36abcaeb 100644 --- a/docs/source/torchts.nn.loss.rst +++ b/docs/source/torchts.nn.loss.rst @@ -1,6 +1,31 @@ torchts.nn.loss =============== -.. automodule:: torchts.nn.loss - :members: +Quatile Loss +------------ + +Quantile regression uses the one-sided quantile loss to predict specific percentiles of the dependent variable. +The quantile regression model uses the pinball loss function written as: + +.. math:: + L_{Quantile}\big(y,f(x),\theta,p\big) = min_\theta\{\mathbb{E}_{(x,y)\sim D}[(y - f(x))(p - \mathbb{1}\{y < f(x)\})]\} + +where :math:`p` is our fixed confidence interval parameterized by :math:`\theta`. When the pinball loss is minimized, the result is the optimal quantile. + +.. autofunction:: torchts.nn.loss.quantile_loss + :noindex: + + +Mean Interval Score Loss +------------------------ + +.. autofunction:: torchts.nn.loss.mis_loss + :noindex: + + +Masked Mean Absolute Error Loss +-------------------------------- + +.. autofunction:: torchts.nn.loss.masked_mae_loss + :noindex: diff --git a/docs/source/torchts.nn/dcrnn.rst b/docs/source/torchts.nn/dcrnn.rst index 9354fc70..e72994a1 100644 --- a/docs/source/torchts.nn/dcrnn.rst +++ b/docs/source/torchts.nn/dcrnn.rst @@ -1,5 +1,15 @@ DCRNN ===== +In spatiotemporal forecasting, assume we have multiple time series generated from a fixed space :math:`x(s,t)`. +`Diffusion Convolutional LSTM `_ models the time series on an irregular grid (graph) as a diffusion process. +Diffusion Convolutional LSTM replaces the matrix multiplication in a regular LSTM with diffusion convolution. It determines the future state of a certain cell in the graph by the inputs and past states of its local neighbors: + +.. math:: + \begin{bmatrix} i_t \\ f_t \\ o_t \end{bmatrix} = \sigma\big(W^{x} \star_g x_t + W^h \star_g h_{t-1} + W^c \circ c_{t-1} + b\big) + + +where :math:`W \star_g x = \sum_{i=1}^k \big(D^{-1}A\big)^i \cdot W \cdot x` is the diffusion convolution. + .. automodule:: torchts.nn.models.dcrnn :members: \ No newline at end of file diff --git a/docs/source/torchts.nn/seq2seq.rst b/docs/source/torchts.nn/seq2seq.rst index 0db55c73..f7155272 100644 --- a/docs/source/torchts.nn/seq2seq.rst +++ b/docs/source/torchts.nn/seq2seq.rst @@ -1,5 +1,17 @@ Seq2seq ======= +The `sequence to sequence model `_ originates from language translation. +Our implementation adapts the model for multi-step time series forecasting. Specifically, given the input series :math:`x_1, +\ldots, x_{t}`, the model maps the input series to the output series: + +.. math:: + x_{t-p}, x_{t-p+1}, \ldots, x_{t-1} \longrightarrow x_t, x_{t+1}, \ldots, x_{t+h-1} + +where :math:`p` is the input history length and :math:`h` is the forecasting horizon. +Sequence to sequence (Seq2Seq) models consist of an encoder and a decoder. The final state of the encoder is fed as the initial state of the decoder. +We can use various models tor both the encoder and decoder. This function implements a Long Short Term Memory (LSTM). + + .. automodule:: torchts.nn.models.seq2seq :members: \ No newline at end of file diff --git a/torchts/nn/models/seq2seq.py b/torchts/nn/models/seq2seq.py index a6de8fcf..5a094811 100644 --- a/torchts/nn/models/seq2seq.py +++ b/torchts/nn/models/seq2seq.py @@ -93,7 +93,7 @@ def forward(self, x, hidden): class Seq2Seq(TimeSeriesModel): """Seq2Seq - + Args: encoder: Encoder object. decoder: Decoder object. From 16e14af3bab07d8e245b26fba0157e48a168a110 Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Sun, 6 Mar 2022 16:44:34 -0800 Subject: [PATCH 10/19] fixed lint --- docs/source/torchts.nn/dcrnn.rst | 2 +- docs/source/torchts.nn/seq2seq.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/torchts.nn/dcrnn.rst b/docs/source/torchts.nn/dcrnn.rst index e72994a1..362caad4 100644 --- a/docs/source/torchts.nn/dcrnn.rst +++ b/docs/source/torchts.nn/dcrnn.rst @@ -12,4 +12,4 @@ Diffusion Convolutional LSTM replaces the matrix multiplication in a regular LST where :math:`W \star_g x = \sum_{i=1}^k \big(D^{-1}A\big)^i \cdot W \cdot x` is the diffusion convolution. .. automodule:: torchts.nn.models.dcrnn - :members: \ No newline at end of file + :members: diff --git a/docs/source/torchts.nn/seq2seq.rst b/docs/source/torchts.nn/seq2seq.rst index f7155272..520a2c0e 100644 --- a/docs/source/torchts.nn/seq2seq.rst +++ b/docs/source/torchts.nn/seq2seq.rst @@ -14,4 +14,4 @@ We can use various models tor both the encoder and decoder. This function implem .. automodule:: torchts.nn.models.seq2seq - :members: \ No newline at end of file + :members: From b2cd135ef0867a60af0799596ecdd414d16a84c1 Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Tue, 8 Mar 2022 21:03:17 -0800 Subject: [PATCH 11/19] Update getting_started.rst --- docs/source/getting_started.rst | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index b30f1ec7..520a9ea9 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -10,11 +10,14 @@ In the following example, we will use the `torchTS` package to train a simple LS .. code-block:: python import torch - import torchts import numpy as np + import matplotlib.pyplot as plt + from torchts.nn.models.lstm import LSTM + from torchts.nn.loss import quantile_loss -2. Let's randomly generate a time-series dataset. + +1. Let's randomly generate a time-series dataset. .. code-block:: python @@ -39,19 +42,25 @@ We will get the following plots: 3. Then, we can start selecting and training our model. In this example, we will use LSTM model. .. code-block:: python + # model configs + inputDim = 1 + outputDim = 1 + optimizer_args = {"lr": 0.01} + quantile = 0.025 # confidence level = 0.025 + batch_size = 10 model = LSTM( - input_size, - output_size, - hidden_size, - optimizer, - interval=interval, - optimizer_args=optimizer_args, + inputDim, + outputDim, + torch.optim.Adam, + criterion=quantile_loss, + criterion_args={"quantile": quantile}, + optimizer_args= ) - model.fit(x, y, max_epochs=max_epochs, batch_size=batch_size) + model.fit(x, y, max_epochs=100, batch_size=batch_size) -4. After model is trained, we can use it to predict the future values. And more importantly, since we enable uncertainty quantification method, we can also get a prediction interval! +1. After model is trained, we can use it to predict the future values. And more importantly, since we enable uncertainty quantification method, we can also get a prediction interval! .. code-block:: python From 7369b36010433cab415d439684b708b005dd4197 Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Tue, 8 Mar 2022 21:07:01 -0800 Subject: [PATCH 12/19] Update getting_started.rst --- docs/source/getting_started.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index 520a9ea9..d4906dd2 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -55,7 +55,7 @@ We will get the following plots: torch.optim.Adam, criterion=quantile_loss, criterion_args={"quantile": quantile}, - optimizer_args= + optimizer_args=optimizer_args ) model.fit(x, y, max_epochs=100, batch_size=batch_size) From e2c0469586d663c463ad42c0745279267d29ad59 Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Tue, 8 Mar 2022 21:07:47 -0800 Subject: [PATCH 13/19] Update build_docs.sh --- scripts/build_docs.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/build_docs.sh b/scripts/build_docs.sh index 60da84b1..872d7325 100755 --- a/scripts/build_docs.sh +++ b/scripts/build_docs.sh @@ -15,4 +15,3 @@ SPHINX_HTML_DIR="website/static/api/" cp -R "./docs/build/html/" "./${SPHINX_HTML_DIR}" echo "Sucessfully moved Sphinx docs to ${SPHINX_HTML_DIR}" - From 93b002d38c6db0c6539ef3dbac44702259993044 Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Tue, 8 Mar 2022 21:09:16 -0800 Subject: [PATCH 14/19] Update getting_started.rst --- docs/source/getting_started.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index d4906dd2..76b74c43 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -43,18 +43,19 @@ We will get the following plots: .. code-block:: python # model configs - inputDim = 1 - outputDim = 1 + inputDim = 1 + outputDim = 1 optimizer_args = {"lr": 0.01} - quantile = 0.025 # confidence level = 0.025 + # confidence level = 0.025 + quantile = 0.025 batch_size = 10 model = LSTM( - inputDim, - outputDim, + inputDim, + outputDim, torch.optim.Adam, - criterion=quantile_loss, - criterion_args={"quantile": quantile}, + criterion=quantile_loss, + criterion_args={"quantile": quantile}, optimizer_args=optimizer_args ) model.fit(x, y, max_epochs=100, batch_size=batch_size) From c2edfaad0800bf73f0620b0f9d5324b909196163 Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Tue, 8 Mar 2022 21:12:27 -0800 Subject: [PATCH 15/19] Update contributing.rst --- docs/source/contributing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst index 60fd3228..02192c9c 100644 --- a/docs/source/contributing.rst +++ b/docs/source/contributing.rst @@ -1,4 +1,4 @@ Contributing to TorchTS ======================= - +Start Contributing From 8f1f938257b9c85ab988a22c975bfdec97d12eb0 Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Tue, 8 Mar 2022 21:14:20 -0800 Subject: [PATCH 16/19] Update torchts.nn.loss.rst --- docs/source/torchts.nn.loss.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/source/torchts.nn.loss.rst b/docs/source/torchts.nn.loss.rst index 36abcaeb..53af1bee 100644 --- a/docs/source/torchts.nn.loss.rst +++ b/docs/source/torchts.nn.loss.rst @@ -15,14 +15,12 @@ where :math:`p` is our fixed confidence interval parameterized by :math:`\theta` .. autofunction:: torchts.nn.loss.quantile_loss :noindex: - Mean Interval Score Loss ------------------------ .. autofunction:: torchts.nn.loss.mis_loss :noindex: - Masked Mean Absolute Error Loss -------------------------------- From a00a692be66e4d15319cbc15c4e007a99ee5d626 Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Tue, 8 Mar 2022 21:14:52 -0800 Subject: [PATCH 17/19] Update torchts.nn.loss.rst --- docs/source/torchts.nn.loss.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/source/torchts.nn.loss.rst b/docs/source/torchts.nn.loss.rst index 53af1bee..e8b6098f 100644 --- a/docs/source/torchts.nn.loss.rst +++ b/docs/source/torchts.nn.loss.rst @@ -26,4 +26,3 @@ Masked Mean Absolute Error Loss .. autofunction:: torchts.nn.loss.masked_mae_loss :noindex: - From 5b2d7f0c5086d5bbf58f10b510dc1c6eca747981 Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Tue, 8 Mar 2022 21:15:45 -0800 Subject: [PATCH 18/19] Update dcrnn.rst --- docs/source/torchts.nn/dcrnn.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/source/torchts.nn/dcrnn.rst b/docs/source/torchts.nn/dcrnn.rst index 362caad4..21276f07 100644 --- a/docs/source/torchts.nn/dcrnn.rst +++ b/docs/source/torchts.nn/dcrnn.rst @@ -8,7 +8,6 @@ Diffusion Convolutional LSTM replaces the matrix multiplication in a regular LST .. math:: \begin{bmatrix} i_t \\ f_t \\ o_t \end{bmatrix} = \sigma\big(W^{x} \star_g x_t + W^h \star_g h_{t-1} + W^c \circ c_{t-1} + b\big) - where :math:`W \star_g x = \sum_{i=1}^k \big(D^{-1}A\big)^i \cdot W \cdot x` is the diffusion convolution. .. automodule:: torchts.nn.models.dcrnn From 68c22e1a90da8ea8869b51b26415f836d1085910 Mon Sep 17 00:00:00 2001 From: Kailing Ding Date: Tue, 8 Mar 2022 21:18:58 -0800 Subject: [PATCH 19/19] fixed pre-commit --- docs/source/getting_started.rst | 8 -------- docs/source/installation.rst | 5 ++--- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index 76b74c43..50150f9c 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -16,7 +16,6 @@ In the following example, we will use the `torchTS` package to train a simple LS from torchts.nn.models.lstm import LSTM from torchts.nn.loss import quantile_loss - 1. Let's randomly generate a time-series dataset. .. code-block:: python @@ -38,7 +37,6 @@ We will get the following plots: .. image:: ./_static/images/getting_started__dataset_plot.png :scale: 100% - 3. Then, we can start selecting and training our model. In this example, we will use LSTM model. .. code-block:: python @@ -60,14 +58,12 @@ We will get the following plots: ) model.fit(x, y, max_epochs=100, batch_size=batch_size) - 1. After model is trained, we can use it to predict the future values. And more importantly, since we enable uncertainty quantification method, we can also get a prediction interval! .. code-block:: python y_preds = model.predict(x) - 5. Let's plot prediction results .. code-block:: python @@ -77,17 +73,13 @@ We will get the following plots: plt.legend() plt.show() - .. image:: ./_static/images/getting_started__pred_results_1.png :scale: 100% - Example prediction results for other datasets: - .. image:: ./_static/images/getting_started__sample_dataset.png :scale: 100% - .. image:: ./_static/images/getting_started__sample_results.png :scale: 100% diff --git a/docs/source/installation.rst b/docs/source/installation.rst index df9ef757..d1f19ebe 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -8,7 +8,6 @@ Dependencies * `PyTorch Lightning `_ * `SciPy `_ - Installing the Latest Release ------------------------------ @@ -63,12 +62,12 @@ Running a simple notebook with your local environment - Poetry essentially sets up a virtual environment that automatically configures itself with the dependencies needed to work with torchTS. - Once you’ve installed the dependencies for torchTS through Poetry, we can run a Jupyter Notebook with a base kernel built upon torchTS’ using these commands:: - # Run this from the root directory of torchTS + # Run this from the root directory of torchTS poetry run jupyter notebook - Similarly, we can run Python scripts through our compatible environment using this code configuration:: - # Run any python script through our new + # Run any python script through our new poetry run [PYTHON FILE] - Poetry is a very capable package management tool and we recommend you explore it’s functionalities further with `their documentation `_ to get the most out of it.