adaptive merge requestshttps://gitlab.kwant-project.org/qt/adaptive/-/merge_requests2018-11-30T11:08:06Zhttps://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/118add 'save' and 'load' to the learners and periodic saving to the Runner2018-11-30T11:08:06ZBas Nijholtadd 'save' and 'load' to the learners and periodic saving to the Runnertl;dr, this MR introduces:
* `learner.save`, `learner.load` that saves/loads **only** the data
* `learner.copy_from(other_learner)`
* `runner.start_periodic_saving(save_kwargs, interval)`
This adds saving and loading methods to t...tl;dr, this MR introduces:
* `learner.save`, `learner.load` that saves/loads **only** the data
* `learner.copy_from(other_learner)`
* `runner.start_periodic_saving(save_kwargs, interval)`
This adds saving and loading methods to the learner.
Now each learner has a `save` and `load` method that can be used to save and load **only** the data of a learner.
There are __two ways__ of naming the files:
1. Using the `fname` argument in `learner.save(fname=...)`
2. Setting the `fname` attribute, like `learner.fname = 'data/example.p` and then `learner.save()`
The second way _must be used_ when saving the `learner`s of a `BalancingLearner`.
By default the resulting pickle files are compressed, to turn this off use `learner.save(fname=..., compress=False)`
```python
learner = Learner2D(...)
learner.save(fname='filename.p')
learner = Learner2D(...)
learner.load(fname='filename.p')
```
in a `BalancingLearner` one can for example
```python
def combo_fname(val):
return '__'.join([f'{k}_{v}' for k, v in val.items()])
combos = adaptive.utils.named_product(a=[1, 2], b=[1])
learners = []
for combo in combos:
l = Learner(partial(f, combo=combo))
l.fname = combo_fname(combo)
learners.append(l)
learner = BalancingLearner(learners)
learner.load(folder='data_folder')
```
then the next time when you add more parameters to `combos`, the data will be loaded for the learners that have the data saved.
This also adds `leaner.copy_from(learner2)` to get a new learner with the same data where one (for example) uses different `bounds` or `loss_per_interval`.
Finally, it adds periodic saving while running with the `Runner`.
I've tested this over the last year in [`adaptive_tools`](https://github.com/basnijholt/adaptive-tools) and seems to work nicely for me.
Still need to
- [x] test with BalancingLearner
- [x] test with DataSaver
- [x] add doc-strings
- [x] add examples to the notebookJoseph WestonJoseph Westonhttps://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/134change resolution_loss to a factory function2018-11-30T11:08:06ZBas Nijholtchange resolution_loss to a factory functionhttps://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/136build the Dockerimage used in CI2018-11-30T11:08:06ZBas Nijholtbuild the Dockerimage used in CIhttps://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/133make 'fname' a parameter to 'save' and 'load' only2018-11-30T11:08:06ZJoseph Westonmake 'fname' a parameter to 'save' and 'load' onlyThis simplifies the API by making sure that the filenames are
only provided in one place (the calls to save and load).
Closes #122This simplifies the API by making sure that the filenames are
only provided in one place (the calls to save and load).
Closes #122https://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/135test all the different loss functions in each test2018-11-30T11:08:06ZBas Nijholttest all the different loss functions in each testImprove the tests
* test all the different loss functions in each test
* add `Learner1D._recompute_losses_factor` to remove `xfail` from two tests
* speed up the testsImprove the tests
* test all the different loss functions in each test
* add `Learner1D._recompute_losses_factor` to remove `xfail` from two tests
* speed up the testshttps://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/137adhere to PEP008 by using absolute imports2018-11-30T11:08:06ZBas Nijholtadhere to PEP008 by using absolute importsSee https://www.python.org/dev/peps/pep-0008/#imports.
This is also how it's done in all of Python's standard library.
@jbweston and @anton\-akhmerov is this good to merge?See https://www.python.org/dev/peps/pep-0008/#imports.
This is also how it's done in all of Python's standard library.
@jbweston and @anton\-akhmerov is this good to merge?https://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/131Resolve "(Learner1D) add possibility to use the direct neighbors in the loss"2018-11-30T11:08:06ZJorn HoofwijkResolve "(Learner1D) add possibility to use the direct neighbors in the loss"Closes #119
Currently works for one $`R^1 \to R^1`$
Still have to make it work for $`R^1 \to R^N`$
Also performance is actually quite good. As in: the learner slows down about 1.5 times. Going (on my laptop) from 3 seconds per 1000 p...Closes #119
Currently works for one $`R^1 \to R^1`$
Still have to make it work for $`R^1 \to R^N`$
Also performance is actually quite good. As in: the learner slows down about 1.5 times. Going (on my laptop) from 3 seconds per 1000 points to 4.5 seconds per 1000 points.
Which, I believe, will be more than compensated by the fact that the chosen points are generally betterAnton AkhmerovAnton Akhmerovhttps://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/138Fix typo in curvature-loss computation2018-11-28T20:07:41ZJorn HoofwijkFix typo in curvature-loss computationI had a typo in !131.
actually compute the dx by subtracting two DIFFERENT numbers.
The commit is self-explanatory I supposeI had a typo in !131.
actually compute the dx by subtracting two DIFFERENT numbers.
The commit is self-explanatory I supposehttps://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/1162D: fix #1092018-10-04T13:32:27ZBas Nijholt2D: fix #109https://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/113Resolve "(BalancingLearner) loss is cached incorrectly"2018-10-01T11:32:07ZJorn HoofwijkResolve "(BalancingLearner) loss is cached incorrectly"Closes #108Closes #108v0.6https://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/96More efficient 'tell_many'2018-09-28T14:18:36ZBas NijholtMore efficient 'tell_many'```python
import adaptive
def f(x, offset=0):
a = 0.01
return x + a**2 / (a**2 + (x - offset)**2)
learner = adaptive.Learner1D(f, bounds=(-1, 1))
adaptive.runner.simple(learner, goal=lambda l: l.npoints > 200)
```
T...```python
import adaptive
def f(x, offset=0):
a = 0.01
return x + a**2 / (a**2 + (x - offset)**2)
learner = adaptive.Learner1D(f, bounds=(-1, 1))
adaptive.runner.simple(learner, goal=lambda l: l.npoints > 200)
```
Timing new implementation
```python
%%timeit
learner2 = adaptive.Learner1D(f, bounds=(-1, 1))
learner2.tell_many(*zip(*learner.data.items()))
```
`1.17 ms ± 24.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)`
Timing old implementation
```python
%%timeit
learner2 = adaptive.Learner1D(f, bounds=(-1, 1))
for x, y in learner.data.items():
learner2.tell(x, y)
```
`6.82 ms ± 447 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)`
This makes it ~6 times faster for functions that return scalars and is >10 times faster for vectors.
v0.6Joseph WestonJoseph Westonhttps://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/115Resolve "How should learners handle data that is outside of the domain"2018-09-26T12:33:49ZJorn HoofwijkResolve "How should learners handle data that is outside of the domain"Closes #101Closes #101v0.6Joseph WestonJoseph Westonhttps://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/114update release guide to add a 'dev' tag on top of regular tags2018-09-26T12:32:45ZJoseph Westonupdate release guide to add a 'dev' tag on top of regular tagsv0.6Bas NijholtBas Nijholthttps://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/112Resolve "LearnerND fails for BalancingLearner test"2018-09-25T11:02:19ZJorn HoofwijkResolve "LearnerND fails for BalancingLearner test"Closes #105Closes #105https://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/107Introduce 'tell_pending' which replaces 'tell(x, None)'2018-09-24T16:59:57ZBas NijholtIntroduce 'tell_pending' which replaces 'tell(x, None)'and I also tackle
* `lower_bound <= learner.ask()[0] <= upper_bound`
* if we `tell(x, y)` with `x` outside the bounds, the point should be added to `data`, but not any of the other internal datastructures. This will mean that the poin...and I also tackle
* `lower_bound <= learner.ask()[0] <= upper_bound`
* if we `tell(x, y)` with `x` outside the bounds, the point should be added to `data`, but not any of the other internal datastructures. This will mean that the point will be "invisible" to the learning algorithm, and only useful for plotting and data extraction
for **both** the `Learner1D` and `Learner2D` in that MR. I included this in here to avoid merge conflicts later.Joseph WestonJoseph Westonhttps://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/105move specific tests for a particular learner to separate files2018-09-24T16:59:57ZBas Nijholtmove specific tests for a particular learner to separate filesand rename `test_learner.py` -> `test_learners.py`.
We leave tests that are general (apply to multiple learners) in `test_learners.py`.and rename `test_learner.py` -> `test_learners.py`.
We leave tests that are general (apply to multiple learners) in `test_learners.py`.Joseph WestonJoseph Westonhttps://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/104Make the AverageLearner only return new points ...2018-09-24T16:59:57ZBas NijholtMake the AverageLearner only return new points ...and introduce `learner.pending_points` to make it more similar to the rest of Adaptive.
I've added a test that will fail with the current master.and introduce `learner.pending_points` to make it more similar to the rest of Adaptive.
I've added a test that will fail with the current master.Joseph WestonJoseph Westonhttps://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/1032D: rename 'learner._interp' to 'learner.pending_points' as in other learners2018-09-24T16:59:57ZBas Nijholt2D: rename 'learner._interp' to 'learner.pending_points' as in other learnersThis is what it's called in the `Learner1D`, `AverageLearner` (!104), and `Runner`.This is what it's called in the `Learner1D`, `AverageLearner` (!104), and `Runner`.Joseph WestonJoseph Westonhttps://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/102introduce 'runner.retries' and 'runner.raise_if_retries_exceeded'2018-09-24T16:59:57ZBas Nijholtintroduce 'runner.retries' and 'runner.raise_if_retries_exceeded'Continuing !94.Continuing !94.https://gitlab.kwant-project.org/qt/adaptive/-/merge_requests/101Resolve "Learner1D fails when function returns a list instead of a numpy.array"2018-09-24T16:59:57ZJorn HoofwijkResolve "Learner1D fails when function returns a list instead of a numpy.array"Closes #96Closes #96Joseph WestonJoseph Weston