Skip to content

Commit b739a5e

Browse files
authored
Merge pull request #35 from strongio/develop
Develop
2 parents e392a96 + bce3283 commit b739a5e

16 files changed

Lines changed: 676 additions & 650 deletions

File tree

CHANGELOG.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,64 @@
11
# CHANGELOG
22

3+
## v0.6.0 (2025-04-25)
4+
5+
### Updated default `fit()` behavior
6+
7+
The `fit()` method of `torchcast.state_space.StateSpaceModel` has been updated:
8+
9+
* The default `LBFGS` settings have been updated to avoid the unnecessary inner loop (see [here](https://discuss.pytorch.org/t/unclear-purpose-of-max-iter-kwarg-in-the-lbfgs-optimizer/65695/4)).
10+
* The default convergence settings have been updated to increase `patience` to 2 (instead of 1) and increase `max_iter` to 300 (instead of 200).
11+
* To restore the old behavior, pass `optimizer=lambda p: torch.optim.LBFGS(p, max_eval=8, line_search_fn='strong_wolfe'), stopping={'patience' : 1, 'max_iter' : 200}`.
12+
* Convergence is now controlled by a `torch.utils.Stopping` instance (or kwargs for one). This means passing `tol`, `patience`, and `max_iter` directly to `fit` is deprecated; instead call `fit(stopping={'patience' : ... etc})`.
13+
14+
### Updated default `Covariance` behavior
15+
16+
* The 'low_rank' method is never chosen by default; if desired it must be selected manually using the 'method' kwarg (previously would automatically be chosen if rank was >= 10). This was based on poor performance empirically.
17+
* The starting values for the covariance diagonal have been increased.
18+
* Added `initial_covariance` kwarg to `KalmanFilter` and subclasses.
19+
20+
### Updates to `BinomialFilter`
21+
22+
* Added the `observed_counts` argument, allowing the user to specify whether observations are counts or proportions. If `num_obs==1` then this argument is not required (since they are the same).
23+
* Fix bug in BinomialStep's kalman-gain calculation when num_obs > 1
24+
* Fix issues with BinomialFilter on the GPU.
25+
* Fix `__getitem__()` for BinomialPredictions.
26+
* Fix monte-carlo `BinomialPredictions.log_prob()` to properly marginalize over samples.
27+
28+
### Other Fixes
29+
30+
* Fix `get_durations()` on GPU.
31+
* Remove redundant matmul in `KalmanStep._update()`
32+
* `ss_step` is no longer a property but is instead an attribute, avoids unnecessary re-instantiation on each timestep
33+
34+
## v0.5.1 (2025-01-09)
35+
36+
### Documentation
37+
38+
* New [Using NN’s for Long-Range Forecasts: Electricity Data](https://docs.strong.io/torchcast/examples/electricity.html#Using-NN's-for-Long-Range-Forecasts:-Electricity-Data) example
39+
* Documentation/README cleanup
40+
41+
### Trainers
42+
43+
Add `torchcast.utils.training` module with...
44+
45+
* `SimpleTrainer` for training simple `nn.Module`s
46+
* `SeasonalEmbeddingsTrainer` for training `nn.Module`s to embed seasonal patterns.
47+
* `StateSpaceTrainer` for training torchcast's `StateSpaceModel`s (when data are too big for the `fit()` method)
48+
49+
### Baseline
50+
51+
* Add `make_baseline` helper to generate baseline forecasts using a simple n-back method 3641e7c137fb7574d13eb744312584dafc622650
52+
53+
### Fixes
54+
55+
* Ensure consistent column-ordering and default RangeIndex in output of `Predictions.to_dataframe()` 0a0fc810a78d4508b029d580483484790005cc6b, f33c6380b94548be5158eb2e2344bd7277a05e48
56+
* Fix default behavior in how `TimeSeriesDataLoader` forward-fills nans for the `X` tensor 0a0fc810a78d4508b029d580483484790005cc6b
57+
* Fix seasonal initial values when passing `initial_value` to forward cae28795095110da56f081b3e2ec4fd942c546d1
58+
* Fix behavior of `StateSpaceModel.simulate()` when num_sims > 1 cae28795095110da56f081b3e2ec4fd942c546d1
59+
* Fix extra arg in `ExpSmoother._generate_predictions()` b55324879384e30517045b51d475cf5c9d2cf5e2
60+
* Make `TimeSeriesDataset.split_measures()` usable by removing `which` argument 8f1001b039ce5e6c901774bafe0ffac78b40f02f
61+
362

463
## v0.4.1 (2024-10-09)
564

docs/api/utils.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ Utils
44
.. include:: ../macros.hrst
55

66
.. automodule:: torchcast.utils
7-
:members: TimeSeriesDataset, TimeSeriesDataLoader, add_season_features, complete_times, make_baseline, SimpleTrainer, StateSpaceTrainer, SeasonalEmbeddingsTrainer
7+
:members: TimeSeriesDataset, TimeSeriesDataLoader, add_season_features, complete_times, make_baseline, SimpleTrainer, StateSpaceTrainer, SeasonalEmbeddingsTrainer, Stopping

docs/examples/air_quality.ipynb

Lines changed: 80 additions & 81 deletions
Large diffs are not rendered by default.

docs/examples/electricity.ipynb

Lines changed: 128 additions & 350 deletions
Large diffs are not rendered by default.

tests/test_training.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ def closure():
246246
try:
247247
kf = _train()
248248
except (RuntimeError, ValueError) as e:
249-
if 'cholesky' not in str(e) and 'has invalid values' not in str(e):
249+
if 'cholesky' not in str(e) and 'has invalid values' not in str(e) and 'nans' not in str(e):
250250
raise e
251251
if kf is not None:
252252
break

torchcast/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '0.5.2'
1+
__version__ = '0.6.0'

torchcast/covariance/base.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,8 @@ def from_processes(cls,
7878
if cov_type == 'process':
7979
# by default, assume process cov is less than measure cov:
8080
if 'init_diag_multi' not in kwargs:
81-
kwargs['init_diag_multi'] = .01
82-
if 'method' in kwargs and kwargs['method'] == 'low_rank':
83-
warn("``method='low_rank'`` not recommended for processes")
84-
elif cov_type == 'initial':
85-
if (state_rank - len(no_cov_idx)) >= 10:
86-
# by default, use low-rank parameterization for initial cov:
87-
if 'method' not in kwargs:
88-
kwargs['method'] = 'low_rank'
89-
else:
81+
kwargs['init_diag_multi'] = .05
82+
elif cov_type != 'initial':
9083
raise ValueError(f"Unrecognized cov_type {cov_type}, expected 'initial' or 'process'.")
9184

9285
if predict_variance is True:
@@ -165,7 +158,7 @@ def __init__(self,
165158
This can be useful to provide intelligent starting-values to speed up optimization.
166159
"""
167160

168-
super(Covariance, self).__init__()
161+
super().__init__()
169162

170163
self.id = id
171164
self.rank = rank
@@ -196,6 +189,7 @@ def _set_params(self, method: str, init_diag_multi: float):
196189
self.cholesky_log_diag = nn.Parameter(.1 * torch.randn(self.param_rank) + math.log(init_diag_multi))
197190
self.cholesky_off_diag = nn.Parameter(.1 * torch.randn(num_off_diag(self.param_rank)))
198191
elif method.startswith('low_rank'):
192+
warn("``method='low_rank'`` is experimental")
199193
self.method = 'low_rank'
200194
low_rank = method.replace('low_rank', '')
201195
if low_rank:

0 commit comments

Comments
 (0)