tslens 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
tslens-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Md. Khairul Islam
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
tslens-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,145 @@
1
+ Metadata-Version: 2.4
2
+ Name: tslens
3
+ Version: 0.1.0
4
+ Summary: A consistent PyTorch interface to attribution methods for time series deep learning models, including WinTSR
5
+ Author: Judy Fox
6
+ Author-email: Md Khairul Islam <khairulislam@virginia.edu>
7
+ License: MIT License
8
+
9
+ Copyright (c) 2023 Md. Khairul Islam
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+
29
+ Project-URL: Homepage, https://github.com/khairulislam/tslens
30
+ Project-URL: Repository, https://github.com/khairulislam/tslens
31
+ Project-URL: Paper, https://arxiv.org/abs/2412.04532
32
+ Keywords: time-series,interpretability,explainable-ai,xai,saliency,captum,pytorch,forecasting
33
+ Classifier: Development Status :: 4 - Beta
34
+ Classifier: Intended Audience :: Science/Research
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Programming Language :: Python :: 3.9
38
+ Classifier: Programming Language :: Python :: 3.10
39
+ Classifier: Programming Language :: Python :: 3.11
40
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
41
+ Requires-Python: >=3.9
42
+ Description-Content-Type: text/markdown
43
+ License-File: LICENSE
44
+ Requires-Dist: torch>=1.13
45
+ Requires-Dist: numpy
46
+ Requires-Dist: captum>=0.6
47
+ Requires-Dist: time-interpret>=0.3.0
48
+ Provides-Extra: dev
49
+ Requires-Dist: pytest>=7; extra == "dev"
50
+ Requires-Dist: matplotlib; extra == "dev"
51
+ Provides-Extra: docs
52
+ Requires-Dist: mkdocs-material>=9; extra == "docs"
53
+ Requires-Dist: mkdocstrings[python]>=0.25; extra == "docs"
54
+ Dynamic: license-file
55
+
56
+ # tslens
57
+
58
+ **Which time steps and which features did your time series model actually use?**
59
+
60
+ tslens is a Captum-compatible interpretability toolkit for deep time series models,
61
+ giving you a consistent PyTorch interface to WinTSR and other established attribution
62
+ methods. WinTSR (Windowed Temporal Saliency Rescaling), the native flagship method,
63
+ accounts for the temporal dependency between neighbouring time steps and scores the
64
+ time and feature dimensions jointly rather than separately — unlike attribution
65
+ methods borrowed from vision and NLP.
66
+
67
+ Paper: [arXiv:2412.04532](https://arxiv.org/abs/2412.04532) ·
68
+ Code: [github.com/khairulislam/tslens](https://github.com/khairulislam/tslens)
69
+
70
+ ## Install
71
+
72
+ ```bash
73
+ pip install tslens
74
+ ```
75
+
76
+ ## Use
77
+
78
+ Works with any PyTorch model that maps `(batch, seq_len, n_features)` to predictions.
79
+ No training framework to adopt, no dataset format to conform to.
80
+
81
+ ```python
82
+ import torch
83
+ from tslens import WinTSR
84
+
85
+ inputs = torch.randn(16, 96, 7) # (batch, seq_len, n_features)
86
+ attr = WinTSR(model).attribute(
87
+ inputs,
88
+ baselines=torch.zeros_like(inputs),
89
+ threshold=0.5, # skip the least relevant time steps
90
+ )
91
+
92
+ attr.shape # (16, n_output, 96, 7) -- (batch, n_output, seq_len, n_features)
93
+ ```
94
+
95
+ Plot it as a heatmap over `(seq_len, n_features)` and you can read off what the model used.
96
+
97
+ ### Options that matter
98
+
99
+ | Argument | Effect |
100
+ | --- | --- |
101
+ | `threshold` | Quantile of time-relevance below which steps are skipped in stage two. Higher is faster and sparser; `0.0` keeps every step. |
102
+ | `sliding_window_shapes` | Window over `(time, features)`. Defaults to `(1, 1)`. Widen the first entry to attribute over multi-step windows. |
103
+ | `baselines` | Replacement values for occluded regions. Defaults to zeros; `tslens.get_baseline(inputs, "normal")` gives other options. |
104
+ | `unflatten` | `True` (default) returns `(batch, n_output, seq_len, n_features)`. `False` returns the flat `(batch * n_output, ...)` layout used internally. |
105
+ | `legacy_normalize` | Constructor flag. Restores the exact normalization used to produce the published numbers — see below. |
106
+
107
+ ### Multi-input models
108
+
109
+ Pass a tuple, get a tuple back. This is how you explain a
110
+ [TSlib](https://github.com/thuml/Time-Series-Library) model (DLinear, iTransformer,
111
+ TimesNet, ...) — its four forward arguments split into two attributed inputs and two
112
+ context tensors, with no wrapper class:
113
+
114
+ ```python
115
+ attr_enc, attr_mark = WinTSR(model).attribute(
116
+ inputs=(x_enc, x_mark_enc),
117
+ baselines=(torch.zeros_like(x_enc), torch.zeros_like(x_mark_enc)),
118
+ additional_forward_args=(x_dec, x_mark_dec),
119
+ )
120
+ ```
121
+
122
+ ### More recipes
123
+
124
+ The [integration cookbook](https://github.com/khairulislam/tslens/blob/main/docs/integration.md)
125
+ has copy-paste snippets for dict/tuple model outputs, classification models, baseline
126
+ choice, explaining a single forecast horizon, speed tuning, and troubleshooting. Two
127
+ runnable notebooks:
128
+ [quickstart](https://colab.research.google.com/github/khairulislam/tslens/blob/main/notebooks/quickstart.ipynb)
129
+ and
130
+ [TSlib models](https://colab.research.google.com/github/khairulislam/tslens/blob/main/notebooks/tslib_models.ipynb).
131
+
132
+ ## Requirements
133
+
134
+ `torch`, `numpy`, `captum`, and [`time-interpret`](https://github.com/josephenguehard/time_interpret).
135
+
136
+ ## Citation
137
+
138
+ ```bibtex
139
+ @article{islam2024wintsr,
140
+ title={WinTSR: A Windowed Temporal Saliency Rescaling Method for Interpreting Time Series Deep Learning Models},
141
+ author={Islam, Md Khairul and Fox, Judy},
142
+ journal={arXiv preprint arXiv:2412.04532},
143
+ year={2024}
144
+ }
145
+ ```
tslens-0.1.0/README.md ADDED
@@ -0,0 +1,219 @@
1
+ # tslens
2
+
3
+ ### A consistent PyTorch interface to time-series attribution methods
4
+
5
+ [![arXiv](https://img.shields.io/badge/arXiv-2412.04532-b31b1b.svg)](https://arxiv.org/abs/2412.04532)
6
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/khairulislam/tslens/blob/main/notebooks/quickstart.ipynb)
7
+ [![Docs](https://img.shields.io/badge/docs-mkdocs--material-blue.svg)](https://khairulislam.github.io/tslens/)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
9
+
10
+ **Which time steps and features did your time-series model actually use?**
11
+
12
+ tslens is a drop-in, Captum-compatible interpretability toolkit for PyTorch
13
+ time-series models. Every method produces a saliency map over the input window so you
14
+ can inspect *when* and *where* a model found evidence for its prediction.
15
+
16
+ Explaining time series models is hard for two reasons that attribution methods borrowed
17
+ from vision and NLP do not handle: subsequent time steps are strongly dependent, and
18
+ feature importance varies over time. Existing studies (1) do not consider the temporal
19
+ dependencies among the feature vectors in the input window, and (2) consider the time
20
+ dimension separately from the feature dimension when calculating importance scores.
21
+ **Windowed Temporal Saliency Rescaling (WinTSR)**, the toolkit's native flagship
22
+ method, addresses both.
23
+
24
+ ![WinTSR attribution heatmap](docs/assets/wintsr_heatmap.png)
25
+
26
+ ## Why tslens?
27
+
28
+ - **Model-agnostic:** explain any callable PyTorch model with the expected input shape.
29
+ - **Time-aware:** preserve relationships between neighbouring observations, via WinTSR.
30
+ - **Joint attribution:** identify important time–feature regions, not just global features.
31
+ - **Practical:** support multi-input models, custom baselines, classification, and forecasting.
32
+ - **One interface:** compare established attribution methods from Captum, Time Interpret,
33
+ and this package's own native implementations side by side.
34
+
35
+ ## Quickstart
36
+
37
+ ```bash
38
+ pip install tslens
39
+ ```
40
+
41
+ Requires Python 3.9+ and PyTorch 1.13+. Works with any PyTorch model mapping
42
+ `(batch, seq_len, n_features)` to predictions — no training framework to adopt, no
43
+ dataset format to conform to:
44
+
45
+ ```python
46
+ import torch
47
+ from tslens import WinTSR
48
+
49
+ inputs = torch.randn(16, 96, 7) # (batch, seq_len, n_features)
50
+ attr = WinTSR(model).attribute(
51
+ inputs,
52
+ baselines=torch.zeros_like(inputs),
53
+ threshold=0.5,
54
+ )
55
+ attr.shape # (16, n_output, 96, 7)
56
+ ```
57
+
58
+ For local development, install the package with its test and documentation tools:
59
+
60
+ ```bash
61
+ pip install -e ".[dev,docs]"
62
+ pytest
63
+ ```
64
+
65
+ Plot `attr` as a heatmap over `(seq_len, n_features)` to read off what the model used.
66
+
67
+ ### Getting started
68
+
69
+ | | |
70
+ | --- | --- |
71
+ | **[Quickstart notebook](https://colab.research.google.com/github/khairulislam/tslens/blob/main/notebooks/quickstart.ipynb)** | 60 seconds, no dataset download. Plants a known signal, trains a small GRU, checks WinTSR recovers it. |
72
+ | **[TSlib models notebook](https://colab.research.google.com/github/khairulislam/tslens/blob/main/notebooks/tslib_models.ipynb)** | Explaining DLinear, iTransformer, TimesNet and friends. No wrapper class needed. |
73
+ | **[Classification notebook](https://colab.research.google.com/github/khairulislam/tslens/blob/main/notebooks/classification.ipynb)** | `n_output` becomes the class count; a padding mask goes through as context, not as an attributed input. |
74
+ | **[Baselines notebook](https://colab.research.google.com/github/khairulislam/tslens/blob/main/notebooks/baselines.ipynb)** | Why the baseline matters, `get_baseline`'s four modes compared by attribution quality, and how to use a custom one. |
75
+ | **[Custom outputs notebook](https://colab.research.google.com/github/khairulislam/tslens/blob/main/notebooks/custom_outputs.ipynb)** | Wrapping models that return a dict or tuple (TimeLLM-style) with a one-line lambda. |
76
+ | **[Integration cookbook](https://khairulislam.github.io/tslens/integration/)** | Copy-paste recipes: dict/tuple outputs, classification, baselines, single horizons, speed, troubleshooting. |
77
+ | **[Interpretation methods](https://khairulislam.github.io/tslens/methods/)** | What WinTSR, TSR, WinIT and GateMask each do differently, and when to reach for which one. |
78
+ | **[API reference](https://khairulislam.github.io/tslens/reference/wintsr/)** | Every argument, generated from the docstrings, including `legacy_normalize=True` to reproduce the published numbers. |
79
+
80
+ Already have a TSlib model? It takes four tensors, so split them into what you want
81
+ attributed and what is just context:
82
+
83
+ ```python
84
+ attr_enc, attr_mark = WinTSR(model).attribute(
85
+ inputs=(x_enc, x_mark_enc),
86
+ baselines=(torch.zeros_like(x_enc), torch.zeros_like(x_mark_enc)),
87
+ additional_forward_args=(x_dec, x_mark_dec),
88
+ )
89
+ ```
90
+
91
+ ## Interpretation methods
92
+
93
+ tslens gives you a broad set of attribution methods through one interface, and works
94
+ with any PyTorch time series model. WinTSR, TSR, WinIT, and GateMask are implemented
95
+ natively here; the rest call [Captum](https://captum.ai/docs/introduction) and
96
+ [tint](https://josephenguehard.github.io/time_interpret/build/html/index.html) directly.
97
+ See [Interpretation methods](https://khairulislam.github.io/tslens/methods/) for what
98
+ each one does differently and when to use it.
99
+
100
+ <details>
101
+ <summary><b>Supported methods</b> (click to expand)</summary>
102
+
103
+ | Method | Type | Paper |
104
+ | --- | --- | --- |
105
+ | WinTSR | Perturbation | [Islam & Fox, arXiv:2412.04532](https://arxiv.org/abs/2412.04532) |
106
+ | TSR | Gradient | [Ismail et al., NeurIPS 2020](https://proceedings.neurips.cc/paper_files/paper/2020/file/47a3893cc405396a5c30d91320572d6d-Paper.pdf) |
107
+ | WinIT | Perturbation | [Leung et al., ICLR 2023](https://arxiv.org/abs/2107.14317) |
108
+ | GateMask | Learned mask | [Liu et al., ICLR 2024](https://arxiv.org/abs/2401.08552) |
109
+ | Occlusion | Perturbation | [Zeiler & Fergus, ECCV 2014](https://arxiv.org/abs/1311.2901) |
110
+ | Feature Ablation | Perturbation | [Kokhlikyan et al., arXiv:2009.07896](https://arxiv.org/abs/2009.07896) |
111
+ | Feature Permutation | Perturbation | [Kokhlikyan et al., arXiv:2009.07896](https://arxiv.org/abs/2009.07896) |
112
+ | Augmented Occlusion | Perturbation | [Enguehard, ICML 2023](https://proceedings.mlr.press/v202/enguehard23a.html) |
113
+ | Integrated Gradients | Gradient | [Sundararajan et al., ICML 2017](https://arxiv.org/abs/1703.01365) |
114
+ | Gradient SHAP | Gradient | [Lundberg & Lee, NeurIPS 2017](https://arxiv.org/abs/1705.07874) |
115
+ | FIT | Perturbation | [Tonekaboni et al., NeurIPS 2020](https://proceedings.neurips.cc/paper/2020/hash/08fa43588c2571ade19bc0fa5936e028-Abstract.html) |
116
+ | Dyna Mask | Learned mask | [Crabbé & van der Schaar, ICML 2021](https://proceedings.mlr.press/v139/crabbe21a.html) |
117
+ | Extremal Mask | Learned mask | [Enguehard, ICML 2023](https://proceedings.mlr.press/v202/enguehard23a.html) |
118
+ | Lime | Surrogate | [Ribeiro et al., KDD 2016](https://arxiv.org/abs/1602.04938) |
119
+
120
+ Full comparison matrix (model requirement, baseline, API doc):
121
+ [Interpretation methods](https://khairulislam.github.io/tslens/methods/).
122
+ </details>
123
+
124
+ ## Supported models
125
+
126
+ tslens attributes any callable that maps `(batch, seq_len, n_features)` — or a tuple of
127
+ tensors — to predictions, so nothing here is hard-coded to a specific architecture. The
128
+ list below is what this package and its [research harness](https://github.com/khairulislam/WinTSR-research)
129
+ have actually been run against.
130
+
131
+ <details>
132
+ <summary><b>Supported model architectures</b> (click to expand)</summary>
133
+
134
+ | Model | Family | Paper |
135
+ | --- | --- | --- |
136
+ | DLinear | Linear | [Zeng et al., AAAI 2023](https://arxiv.org/abs/2205.13504) |
137
+ | LightTS | Linear/MLP | [Zhang et al., arXiv:2207.01186](https://arxiv.org/abs/2207.01186) |
138
+ | TiDE | Linear/MLP | [Das et al., TMLR 2023](https://arxiv.org/abs/2304.08424) |
139
+ | FiLM | Linear/MLP | [Zhou et al., NeurIPS 2022](https://arxiv.org/abs/2205.08897) |
140
+ | TSMixer | MLP-Mixer | [Chen et al., TMLR 2023](https://arxiv.org/abs/2303.06053) |
141
+ | FreTS | Frequency-domain MLP | [Yi et al., NeurIPS 2023](https://arxiv.org/abs/2311.06184) |
142
+ | MICN | Convolutional | [Wang et al., ICLR 2023](https://openreview.net/pdf?id=zt53IDUR1U) |
143
+ | Crossformer | Transformer | [Zhang & Yan, ICLR 2023](https://openreview.net/pdf?id=vSVLM2j9eie) |
144
+ | PatchTST | Transformer | [Nie et al., ICLR 2023](https://arxiv.org/abs/2211.14730) |
145
+ | Pyraformer | Transformer | [Liu et al., ICLR 2022](https://openreview.net/pdf?id=0EXmFzUn5I) |
146
+ | SegRNN | Recurrent | [Lin et al., arXiv:2308.11200](https://arxiv.org/abs/2308.11200) |
147
+ | Koopa | Koopman operator | [Liu et al., NeurIPS 2023](https://arxiv.org/abs/2305.18803) |
148
+ | LSTM | Recurrent | [Hochreiter & Schmidhuber, Neural Computation 1997](https://www.bioinf.jku.at/publications/older/2604.pdf) |
149
+ | TCN | Convolutional | [Bai et al., arXiv:1803.01271](https://arxiv.org/abs/1803.01271) |
150
+ | CALF | LLM-backed foundation model | [Liu et al., arXiv:2403.07300](https://arxiv.org/abs/2403.07300) |
151
+ | OFA (GPT4TS) | LLM-backed foundation model | [Zhou et al., NeurIPS 2023](https://arxiv.org/abs/2302.11939) |
152
+ | TimeLLM | LLM-backed foundation model | [Jin et al., ICLR 2024](https://arxiv.org/abs/2310.01728) |
153
+ | Transformer | Transformer | [Vaswani et al., NeurIPS 2017](https://proceedings.neurips.cc/paper/2017/file/3f5ee243547dee91fbd053c1c4a845aa-Paper.pdf) |
154
+ | Informer | Transformer | [Zhou et al., AAAI 2021](https://ojs.aaai.org/index.php/AAAI/article/view/17325) |
155
+ | Autoformer | Transformer | [Wu et al., NeurIPS 2021](https://openreview.net/pdf?id=I55UqU-M11y) |
156
+ | FEDformer | Transformer | [Zhou et al., ICML 2022](https://proceedings.mlr.press/v162/zhou22g.html) |
157
+ | ETSformer | Transformer | [Woo et al., arXiv:2202.01381](https://arxiv.org/abs/2202.01381) |
158
+ | Nonstationary Transformer | Transformer | [Liu et al., NeurIPS 2022](https://openreview.net/pdf?id=ucNDIDRNjjv) |
159
+ | Reformer | Transformer | [Kitaev et al., ICLR 2020](https://openreview.net/forum?id=rkgNKkHtvB) |
160
+ | iTransformer | Transformer | [Liu et al., ICLR 2024](https://arxiv.org/abs/2310.06625) |
161
+ | TimeXer | Transformer | [Wang et al., NeurIPS 2024](https://arxiv.org/abs/2402.19072) |
162
+ | TimeMixer | MLP-Mixer | [Wang et al., ICLR 2024](https://arxiv.org/abs/2405.14616) |
163
+ | TimesNet | Convolutional | [Wu et al., ICLR 2023](https://openreview.net/pdf?id=ju_Uqw384Oq) |
164
+ | RNN | Recurrent | [Hochreiter & Schmidhuber, Neural Computation 1997](https://www.bioinf.jku.at/publications/older/2604.pdf) |
165
+
166
+ Calling convention (single vs. dual-input) and trained checkpoints:
167
+ [Supported models](https://khairulislam.github.io/tslens/models/).
168
+ </details>
169
+
170
+ ## Repository layout
171
+
172
+ | Path | What it is |
173
+ | --- | --- |
174
+ | [src/tslens/](/src/tslens/) | The installable library. `WinTSR` plus the paper's baseline methods (`TSR`, `WinIT`, `GateMask`). |
175
+ | [notebooks/](/notebooks/) | Runnable quickstart and TSlib walkthrough. |
176
+ | [tests/](/tests/) | Test suite, including a numerical-equivalence check against the pre-refactor implementation. |
177
+ | [docs/](/docs/) | Source for the [docs site](https://khairulislam.github.io/tslens/): tutorials, method explainer, API reference, and the PyPI-page library reference. |
178
+
179
+ This repo is the library only. The training/interpretation harness that produced the
180
+ paper's results — model zoo, experiment scripts, saved results — lives in
181
+ [WinTSR-research](https://github.com/khairulislam/WinTSR-research) and depends on this
182
+ package the same way any user would (`pip install tslens`).
183
+
184
+ ## Reproducing the paper
185
+
186
+ Training the models, running the full benchmark, and the paper's saved results live in
187
+ [WinTSR-research](https://github.com/khairulislam/WinTSR-research), which installs this
188
+ package as a regular dependency. That repo also has the model zoo — DLinear,
189
+ iTransformer, TimesNet, CALF, TimeLLM and 25 others from
190
+ [TSlib](https://github.com/thuml/Time-Series-Library) — dataset download instructions,
191
+ and Docker/Singularity definitions.
192
+
193
+ ## Citation
194
+
195
+ Find our paper on [arXiv](https://arxiv.org/pdf/2412.04532). Please cite the following if you use our work
196
+ (also available as [CITATION.cff](CITATION.cff), used by GitHub's "Cite this repository" button).
197
+
198
+ ```bibtex
199
+ @article{islam2024wintsr,
200
+ title={WinTSR: A Windowed Temporal Saliency Rescaling Method for Interpreting Time Series Deep Learning Models},
201
+ author={Islam, Md Khairul and Fox, Judy},
202
+ journal={arXiv preprint arXiv:2412.04532},
203
+ year={2024}
204
+ }
205
+ ```
206
+
207
+ ## License
208
+
209
+ MIT — see [LICENSE](LICENSE).
210
+
211
+ ## Core libraries
212
+
213
+ tslens builds on these open-source projects:
214
+
215
+ - **[Captum](https://captum.ai/docs/introduction)** — model interpretability library for PyTorch.
216
+ - **[Time Interpret (tint)](https://josephenguehard.github.io/time_interpret/build/html/index.html)** — extends Captum with methods designed for time series.
217
+ - **[Time-Series-Library (TSlib)](https://github.com/thuml/Time-Series-Library)** — deep time series analysis models used in the benchmark.
218
+
219
+ <!-- add here https://github.com/thuml/OpenLTM, https://github.com/thuml/Large-Time-Series-Model, https://github.com/fzi-forschungszentrum-informatik/TSInterpret.git -->
@@ -0,0 +1,90 @@
1
+ # tslens
2
+
3
+ **Which time steps and which features did your time series model actually use?**
4
+
5
+ tslens is a Captum-compatible interpretability toolkit for deep time series models,
6
+ giving you a consistent PyTorch interface to WinTSR and other established attribution
7
+ methods. WinTSR (Windowed Temporal Saliency Rescaling), the native flagship method,
8
+ accounts for the temporal dependency between neighbouring time steps and scores the
9
+ time and feature dimensions jointly rather than separately — unlike attribution
10
+ methods borrowed from vision and NLP.
11
+
12
+ Paper: [arXiv:2412.04532](https://arxiv.org/abs/2412.04532) ·
13
+ Code: [github.com/khairulislam/tslens](https://github.com/khairulislam/tslens)
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ pip install tslens
19
+ ```
20
+
21
+ ## Use
22
+
23
+ Works with any PyTorch model that maps `(batch, seq_len, n_features)` to predictions.
24
+ No training framework to adopt, no dataset format to conform to.
25
+
26
+ ```python
27
+ import torch
28
+ from tslens import WinTSR
29
+
30
+ inputs = torch.randn(16, 96, 7) # (batch, seq_len, n_features)
31
+ attr = WinTSR(model).attribute(
32
+ inputs,
33
+ baselines=torch.zeros_like(inputs),
34
+ threshold=0.5, # skip the least relevant time steps
35
+ )
36
+
37
+ attr.shape # (16, n_output, 96, 7) -- (batch, n_output, seq_len, n_features)
38
+ ```
39
+
40
+ Plot it as a heatmap over `(seq_len, n_features)` and you can read off what the model used.
41
+
42
+ ### Options that matter
43
+
44
+ | Argument | Effect |
45
+ | --- | --- |
46
+ | `threshold` | Quantile of time-relevance below which steps are skipped in stage two. Higher is faster and sparser; `0.0` keeps every step. |
47
+ | `sliding_window_shapes` | Window over `(time, features)`. Defaults to `(1, 1)`. Widen the first entry to attribute over multi-step windows. |
48
+ | `baselines` | Replacement values for occluded regions. Defaults to zeros; `tslens.get_baseline(inputs, "normal")` gives other options. |
49
+ | `unflatten` | `True` (default) returns `(batch, n_output, seq_len, n_features)`. `False` returns the flat `(batch * n_output, ...)` layout used internally. |
50
+ | `legacy_normalize` | Constructor flag. Restores the exact normalization used to produce the published numbers — see below. |
51
+
52
+ ### Multi-input models
53
+
54
+ Pass a tuple, get a tuple back. This is how you explain a
55
+ [TSlib](https://github.com/thuml/Time-Series-Library) model (DLinear, iTransformer,
56
+ TimesNet, ...) — its four forward arguments split into two attributed inputs and two
57
+ context tensors, with no wrapper class:
58
+
59
+ ```python
60
+ attr_enc, attr_mark = WinTSR(model).attribute(
61
+ inputs=(x_enc, x_mark_enc),
62
+ baselines=(torch.zeros_like(x_enc), torch.zeros_like(x_mark_enc)),
63
+ additional_forward_args=(x_dec, x_mark_dec),
64
+ )
65
+ ```
66
+
67
+ ### More recipes
68
+
69
+ The [integration cookbook](https://github.com/khairulislam/tslens/blob/main/docs/integration.md)
70
+ has copy-paste snippets for dict/tuple model outputs, classification models, baseline
71
+ choice, explaining a single forecast horizon, speed tuning, and troubleshooting. Two
72
+ runnable notebooks:
73
+ [quickstart](https://colab.research.google.com/github/khairulislam/tslens/blob/main/notebooks/quickstart.ipynb)
74
+ and
75
+ [TSlib models](https://colab.research.google.com/github/khairulislam/tslens/blob/main/notebooks/tslib_models.ipynb).
76
+
77
+ ## Requirements
78
+
79
+ `torch`, `numpy`, `captum`, and [`time-interpret`](https://github.com/josephenguehard/time_interpret).
80
+
81
+ ## Citation
82
+
83
+ ```bibtex
84
+ @article{islam2024wintsr,
85
+ title={WinTSR: A Windowed Temporal Saliency Rescaling Method for Interpreting Time Series Deep Learning Models},
86
+ author={Islam, Md Khairul and Fox, Judy},
87
+ journal={arXiv preprint arXiv:2412.04532},
88
+ year={2024}
89
+ }
90
+ ```
@@ -0,0 +1,62 @@
1
+ [build-system]
2
+ requires = ["setuptools>=64", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "tslens"
7
+ version = "0.1.0"
8
+ description = "A consistent PyTorch interface to attribution methods for time series deep learning models, including WinTSR"
9
+ readme = "docs/pypi_readme.md"
10
+ requires-python = ">=3.9"
11
+ license = { file = "LICENSE" }
12
+ authors = [
13
+ { name = "Md Khairul Islam", email = "khairulislam@virginia.edu" },
14
+ { name = "Judy Fox" },
15
+ ]
16
+ keywords = [
17
+ "time-series",
18
+ "interpretability",
19
+ "explainable-ai",
20
+ "xai",
21
+ "saliency",
22
+ "captum",
23
+ "pytorch",
24
+ "forecasting",
25
+ ]
26
+ classifiers = [
27
+ "Development Status :: 4 - Beta",
28
+ "Intended Audience :: Science/Research",
29
+ "License :: OSI Approved :: MIT License",
30
+ "Programming Language :: Python :: 3",
31
+ "Programming Language :: Python :: 3.9",
32
+ "Programming Language :: Python :: 3.10",
33
+ "Programming Language :: Python :: 3.11",
34
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
35
+ ]
36
+ dependencies = [
37
+ "torch>=1.13",
38
+ "numpy",
39
+ "captum>=0.6",
40
+ "time-interpret>=0.3.0",
41
+ ]
42
+
43
+ [project.optional-dependencies]
44
+ dev = ["pytest>=7", "matplotlib"]
45
+ docs = ["mkdocs-material>=9", "mkdocstrings[python]>=0.25"]
46
+
47
+ [project.urls]
48
+ Homepage = "https://github.com/khairulislam/tslens"
49
+ Repository = "https://github.com/khairulislam/tslens"
50
+ Paper = "https://arxiv.org/abs/2412.04532"
51
+
52
+ [tool.setuptools]
53
+ # src-layout: only what lives under src/ ships. The training/interpretation
54
+ # harness that reproduces the paper's results lives in a separate repo, see
55
+ # the Homepage README.
56
+ package-dir = { "" = "src" }
57
+
58
+ [tool.setuptools.packages.find]
59
+ where = ["src"]
60
+
61
+ [tool.pytest.ini_options]
62
+ testpaths = ["tests"]
tslens-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,18 @@
1
+ """tslens: attribution methods for time series deep learning models.
2
+
3
+ A drop-in, Captum-compatible interpretability toolkit for any PyTorch model
4
+ that consumes ``(batch, seq_len, n_features)`` tensors. Includes WinTSR and
5
+ other natively implemented methods, plus a consistent interface over Captum
6
+ and Time Interpret baselines.
7
+
8
+ >>> from tslens import WinTSR
9
+ >>> attr = WinTSR(model).attribute(inputs, baselines=torch.zeros_like(inputs))
10
+
11
+ WinTSR paper: https://arxiv.org/abs/2412.04532
12
+ """
13
+
14
+ from .attr import WinTSR
15
+ from .functional import get_baseline, normalize_scale
16
+
17
+ __version__ = "0.1.0"
18
+ __all__ = ["WinTSR", "get_baseline", "normalize_scale", "__version__"]
@@ -0,0 +1,50 @@
1
+ """Attribution methods for time series models.
2
+
3
+ :class:`WinTSR` is the method introduced in the paper it's named after.
4
+ :class:`TSR`, :class:`WinIT` and :class:`GateMask` are the baselines used in
5
+ its evaluation. All four work from a plain ``pip install tslens`` -- none of
6
+ them require the research harness under ``research/``.
7
+
8
+ The baselines are imported lazily so that ``import tslens`` stays cheap and
9
+ does not drag in ``pytorch_lightning`` or ``sklearn`` unless a method that
10
+ needs them is actually requested.
11
+ """
12
+
13
+ from typing import TYPE_CHECKING
14
+
15
+ from .wintsr import WinTSR
16
+
17
+ if TYPE_CHECKING: # pragma: no cover
18
+ from .gate_mask import GateMask
19
+ from .tsr import TSR
20
+ from .winit import WinIT
21
+
22
+ _LAZY = {"TSR": ".tsr", "WinIT": ".winit", "GateMask": ".gate_mask"}
23
+
24
+ __all__ = ["WinTSR", "TSR", "WinIT", "GateMask"]
25
+
26
+
27
+ def __getattr__(name: str):
28
+ """PEP 562 lazy import for the baseline methods."""
29
+ if name not in _LAZY:
30
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
31
+
32
+ from importlib import import_module
33
+
34
+ try:
35
+ module = import_module(_LAZY[name], __name__)
36
+ except ImportError as exc:
37
+ raise ImportError(
38
+ f"{name} could not be imported. It is a baseline method whose "
39
+ "dependencies normally arrive with `time-interpret`; a broken or "
40
+ "partial install is the usual cause. Try reinstalling with "
41
+ f"`pip install --force-reinstall tslens`. Original error: {exc}"
42
+ ) from exc
43
+
44
+ value = getattr(module, name)
45
+ globals()[name] = value # cache so __getattr__ runs once per name
46
+ return value
47
+
48
+
49
+ def __dir__():
50
+ return sorted(__all__)