GithubHelp home page GithubHelp logo

python-adaptive / adaptive Goto Github PK

View Code? Open in Web Editor NEW
1.1K 1.1K 58.0 5.76 MB

:chart_with_upwards_trend: Adaptive: parallel active learning of mathematical functions

Home Page: http://adaptive.readthedocs.io/

License: BSD 3-Clause "New" or "Revised" License

Python 89.59% Jupyter Notebook 10.41%
active-learning adaptive adaptive-learning adaptive-sampling live-plots machine-learning parallel parallel-computing python

adaptive's People

Contributors

aeantipov avatar akhmerov avatar alvarogi avatar basnijholt avatar caenrigen avatar davide-sd avatar eendebakpt avatar github-actions[bot] avatar jbweston avatar jhoofwijk avatar juandaanieel avatar maiani avatar philippeitis avatar pre-commit-ci[bot] avatar sultanorazbayev avatar tacaswell avatar thomasaarholt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

adaptive's Issues

(BalancingLearner) make new balancinglearner that looks at the total loss rather than loss improvement

(original issue on GitLab)

opened by Jorn Hoofwijk (@Jorn) at 2018-09-20T11:19:48.680Z

Suggestion is to implement a new balancing-learner that is a drop-in replacement for the old one, which doesn't requests points from the learners unless they are actually going to be used. So we would look at the total loss of each learner rather than the loss-improvement.

  • This would probably be faster as we do not need to suggest a new point in order to sort the learners. The actual difference should be tested
  • We do not require the learners to support ask(..., add_data=False)
    • This would very likely also solve gitlab:#87
    • This would also be nice for the ND-learner
  • Probably in practice, the outcome would be the similar to the normal balancinglearner
  • The logic should be simpler (as in less code to maintain) and we do not need to keep track of the suggested points
  • We should analyse in what cases the current implementation behaves differently from the proposed implementation and if it is an improvement or worse.

Suggestion is to test it out, if it works nicely we will adopt

suggested points lie outside of domain

(original issue on GitLab)

opened by Bas Nijholt (@basnijholt) at 2018-12-14T13:25:39.155Z

This happens because of some numerical precision issues.

import adaptive

adaptive.notebook_extension()
def f(xy):
    import random
    import time
    time.sleep(4 + random.random()/10)
    return random.randint(1, 10)
learner = adaptive.Learner2D(
    f,
    bounds=[
        (0.16, 0.2),
        (0.6, 2.4)
        ]
)

runner = adaptive.Runner(learner, goal=lambda l: l.npoints > 1000, ntasks=10, log=True)

runner.live_info()

Will fail after ~20 points.

How to handle NaN?

(original issue on GitLab)

opened by Jorn Hoofwijk (@Jorn) at 2018-10-29T11:13:53.243Z

Suppose some function returns NaN for some input value, how should this be handled?

I think the user should at least be warned that the function is ill-behaved.

Then we could still continue learning the function but then ignoring this point for any further evaluation, so we then more or less keep those points in the pending points indefinitely, which could slow down the learner a lot if there are many points that return NaN.

Or we could simply raise an exception and terminate the runner. Which could be inconvenient if you let it run overnight and find in the morning that your learner stopped.

(Learner1D) improve time complexity

(original issue on GitLab)

opened by Jorn Hoofwijk (@Jorn) at 2018-12-02T12:45:11.532Z

As it appears the Learner1D is quite fast. Yet once add many points, it slows down quite a lot. Even though I am aware that in practice you will not add more than say, a thousand points. For testing I sometimes need to add 5000 points, which takes up to 50 seconds (on my slow laptop), which is slightly annoying.

Reason being that some parts of the Learner1D have a time complexity higher than should be strictly neccesary. i.e. : _ask_points_without_adding and _subdivide_quals have time complexity O(N), and they are called every time that ask is called, resulting in a total runtime of O(N^2) where N is the total number of added points.

And since I will make it faster anyway, I might as well make a MR

Learner1D fails when a point (x, None) is added when x already exists

(original issue on GitLab)

opened by Bas Nijholt (@basnijholt) at 2018-09-14T10:45:43.818Z

l = adaptive.Learner1D(lambda x: x, (0, 4))

l.tell(0, 0)
l.tell(1, 0)
l.tell(2, 0)

l.tell(1, None)

Traceback

KeyError                                  Traceback (most recent call last)
<ipython-input-73-d3d3808f7af0> in <module>()
      5 l.tell(2, 0)
      6 
----> 7 l.tell(1, None)

/opt/conda/lib/python3.6/site-packages/adaptive/learner/learner1D.py in tell(self, x, y)
    239 
    240         # Update the losses
--> 241         self.update_losses(x, real)
    242 
    243         # If the scale has increased enough, recompute all losses.

/opt/conda/lib/python3.6/site-packages/adaptive/learner/learner1D.py in update_losses(self, x, real)
    159             if x_left is not None and x_right is not None:
    160                 dx = x_right - x_left
--> 161                 loss = self.losses[x_left, x_right]
    162                 losses_combined[a, x] = (x - a) * loss / dx
    163                 losses_combined[x, b] = (b - x) * loss / dx

KeyError: (0, 2)

How should learners handle data that is outside of the domain

(original issue on GitLab)

opened by Jorn Hoofwijk (@Jorn) at 2018-09-19T09:25:27.165Z

Since giving a user the freedom to add points outside the domain would introduce some bugs that require careful rewriting of the code to mitigate.
Apart from that, IMHO it doesn't make much sense to add a point outside of the domain. Therefore I propose we raise an exception whenever a user tries to tell a point outside of the domain, because it then forces users to think about what they are doing if they do not use the provided adaptive runners.

release 0.6.0

(original issue on GitLab)

opened by Bas Nijholt (@basnijholt) at 2018-09-24T16:59:55.276Z

Since 0.5.0 we fixed the following issues:

  • gitlab:#66: (refactor) learner.tell(x, None) might be renamed to learner.tell_pending(x)
  • gitlab:#92: DeprecationWarning: sorted_dict.iloc is deprecated. Use SortedDict.keys() instead.
  • gitlab:#94: Learner1D breaks if right bound is added before the left bound
  • gitlab:#95: Learner1D's bound check algo in self.ask doesn't take self.data or self.pending_points
  • gitlab:#96: Learner1D fails when function returns a list instead of a numpy.array
  • gitlab:#97: Learner1D fails when a point (x, None) is added when x already exists
  • gitlab:#98: Learner1D.ask breaks when adding points in some order
  • gitlab:#99: Learner1D doesn't correctly set the interpolated loss when a point is added
  • gitlab:#101: How should learners handle data that is outside of the domain
  • gitlab:#102: No tests for the 'BalancingLearner'
  • gitlab:#105: LearnerND fails for BalancingLearner test
  • gitlab:#108: (BalancingLearner) loss is cached incorrectly
  • gitlab:#109: Learner2D suggests same point twice

and merged the following Merge Requests:

  • gitlab:!93: add a release guide
  • gitlab:!94: add runner.max_retries
  • gitlab:!95: 1D: fix the rare case where the right boundary point exists before the left bound
  • gitlab:!96: More efficient 'tell_many'
  • gitlab:!97: Fix gitlab:#97 and gitlab:#98
  • gitlab:!98: Resolve "DeprecationWarning: sorted_dict.iloc is deprecated. Use SortedDict.keys() instead."
  • gitlab:!99: Resolve "Learner1D's bound check algo in self.ask doesn't take self.data or self.pending_points"
  • gitlab:!100: Resolve "Learner1D doesn't correctly set the interpolated loss when a point is added"
  • gitlab:!101: Resolve "Learner1D fails when function returns a list instead of a numpy.array"
  • gitlab:!102: introduce 'runner.retries' and 'runner.raise_if_retries_exceeded'
  • gitlab:!103: 2D: rename 'learner._interp' to 'learner.pending_points' as in other learners
  • gitlab:!104: Make the AverageLearner only return new points ...
  • gitlab:!105: move specific tests for a particular learner to separate files
  • gitlab:!107: Introduce 'tell_pending' which replaces 'tell(x, None)'
  • gitlab:!112: Resolve "LearnerND fails for BalancingLearner test"
  • gitlab:!113: Resolve "(BalancingLearner) loss is cached incorrectly"
  • gitlab:!114: update release guide to add a 'dev' tag on top of regular tags
  • gitlab:!115: Resolve "How should learners handle data that is outside of the domain"
  • gitlab:!116: 2D: fix gitlab:#109

New features

  • add learner.tell_pending which replaces learner.tell(x, None)
  • add error-handling with runner.retries and runner.raise_if_retries_exceeded
  • make learner.pending_points and runner.pending_points public API
  • rename learner.ask(n, add_data) -> learner.ask(n, tell_pending)
  • added the overhead method to the BlockingRunner

I think we should release 0.6.0 since we introduce some new features. @jbweston and @anton-akhmerov do you have a different opinion?

divide by zero warnings in LearnerND

(original issue on GitLab)

opened by Joseph Weston (@jbweston) at 2018-12-12T10:57:01.525Z

jbw@broadway adaptive-evaluation ((HEAD detached at v0.7.0)) $ python
Python 3.6.5 | packaged by conda-forge | (default, Apr  6 2018, 13:39:56) 
[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import adaptive
>>> import numpy as np
>>> adaptive.__version__
'0.7.0'
>>> np.__version__
'1.15.2'
>>> def f(xy):
...     return 1
... 
>>> learner = adaptive.LearnerND(f, ((-1, 1), (-1, 1)))
>>> adaptive.runner.simple(learner, lambda l: l.npoints >= 100)
/home/jbw/work/code/2017/adaptive-evaluation/adaptive/learner/learnerND.py:524: RuntimeWarning: divide by zero encountered in long_scalars
  scale_multiplier = 1 / self._scale
/home/jbw/work/code/2017/adaptive-evaluation/adaptive/learner/learnerND.py:543: RuntimeWarning: invalid value encountered in long_scalars
  scale_factor = np.max(np.nan_to_num(self._scale / self._old_scale))

I guess we should explicitly set the places where _scale is zero to have an infinite multiplier?

Learner2D suggests same point twice

(original issue on GitLab)

opened by Bas Nijholt (@basnijholt) at 2018-09-27T14:52:40.085Z

import adaptive, collections
l = adaptive.Learner2D(ring, bounds=[(-1, 1), (-1, 1)])
collections.Counter(l.ask(48)[0]).most_common(10)
[((-0.70370370370370361, -0.40740740740740744), 11),
 ((0.33333333333333331, -0.33333333333333331), 2),
 ((-0.33333333333333331, 0.33333333333333331), 2),
 ((0.11111111111111109, -0.77777777777777768), 2),
 ((0.77777777777777768, -0.11111111111111109), 2),
 ((-0.77777777777777768, 0.11111111111111109), 2),
 ((-0.11111111111111109, 0.77777777777777768), 2),
 ((0.33333333333333331, 0.33333333333333331), 2),
 ((-0.33333333333333331, -0.33333333333333331), 2),
 ((-1, -1), 1)]

This means that some points are suggested multiple times.

(LearnerND) allow any convex hull as domain

(original issue on GitLab)

opened by Jorn Hoofwijk (@Jorn) at 2018-10-15T13:20:13.194Z

Allow a user to define a convex domain where we should learn the function.

I found it to be very nice to be able to define a convex hull as domain, especially when looking at fermi surfaces in 3d. As we have no use for evaluating any value outside the Brillouin zone.

(BalancingLearner) loss is cached incorrectly

(original issue on GitLab)

opened by Jorn Hoofwijk (@Jorn) at 2018-09-25T11:16:11.892Z

there is this corner case where you ask for the real loss and for the pending loss, then the BalancingLearner makes a mistake in which loss it should return.

I would say it is a minor bug because the issue would almost never occur in practice. Yet in theory it could.

Typo in documentation for` adaptive.learner.learner2D.uniform_loss(ip)`

(original issue on GitLab)

opened by Adriaan (@AdriaanRol) at 2018-12-05T12:44:28.826Z

In the example for adaptive.learner.learner2D.uniform_loss(ip) the loss_per_triangle variable is set to uniform_sampling_2d, a variable that is undefined in the example snippet. I would expect this to be set to learner2D.uniform_loss combined with the appropriate import statement as is done in the example above it.

https://adaptive.readthedocs.io/en/latest/reference/adaptive.learner.learner2D.html#adaptive.Learner2D

Issues that can potentially be closed

(original issue on GitLab)

opened by Bas Nijholt (@basnijholt) at 2018-12-07T19:57:55.908Z

I closed a bunch of issues that I think could be closed, however, there are some more that I don't know what to do with:

The example given in data_saver.py doesn't compile.

(original issue on GitLab)

opened by Piotr (@Benedysiuk) at 2018-09-04T18:55:17.775Z

Data_saver.py is broken.
There is a missing import and even with it one gets Attribute Error when trying to run it.
Full trace back:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-24-9aee42ca60f3> in <module>()
      1 _learner = adaptive.Learner1D(simulate, bounds=(-0.001, 0.001))
----> 2 learner = adaptive.DataSaver(_learner, arg_picker=operator.itemgetter('particles'))

/opt/conda/lib/python3.6/site-packages/adaptive/learner/data_saver.py in __init__(self, learner, arg_picker)
     34 
     35         # Methods that the BaseLearner implements
---> 36         self.add_data = self.learner.add_data
     37         self.__getstate__ = self.learner.__getstate__
     38         self.__setstate__ = self.learner.__setstate__

AttributeError: 'Learner1D' object has no attribute 'add_data'

(LearnerND) add advanced usage example

(original issue on GitLab)

opened by Bas Nijholt (@basnijholt) at 2018-10-20T12:51:05.772Z

We should add the following "real world usage" code to the tutorial as an "Advanced example" once we merged gitlab:!127 and gitlab:!124.

This as a downloadable file kwant_functions.py

from functools import lru_cache
import numpy as np
import scipy.linalg
import scipy.spatial
import kwant


@lru_cache()
def create_syst(unit_cell):
    lat = kwant.lattice.Polyatomic(unit_cell, [(0, 0, 0)])
    syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))
    syst[lat.shape(lambda _: True, (0, 0, 0))] = 6
    syst[lat.neighbors()] = -1
    return kwant.wraparound.wraparound(syst).finalized()


def get_brillouin_zone(unit_cell):
    syst = create_syst(unit_cell)
    A = get_A(syst)
    neighbours = kwant.linalg.lll.voronoi(A)
    lattice_points = np.concatenate(([[0, 0, 0]], neighbours))
    lattice_points = 2 * np.pi * (lattice_points @ A.T)
    vor = scipy.spatial.Voronoi(lattice_points)
    brillouin_zone = vor.vertices[vor.regions[vor.point_region[0]]]
    return scipy.spatial.ConvexHull(brillouin_zone)


def momentum_to_lattice(k, syst):
    A = get_A(syst)
    k, residuals = scipy.linalg.lstsq(A, k)[:2]
    if np.any(abs(residuals) > 1e-7):
        raise RuntimeError("Requested momentum doesn't correspond"
                           " to any lattice momentum.")
    return k


def get_A(syst):
    B = np.asarray(syst._wrapped_symmetry.periods).T
    return np.linalg.pinv(B).T


def energies(k, unit_cell):
    syst = create_syst(unit_cell)
    k_x, k_y, k_z = momentum_to_lattice(k, syst)
    params = {'k_x': k_x, 'k_y': k_y, 'k_z': k_z}
    H = syst.hamiltonian_submatrix(params=params)
    energies = np.linalg.eigvalsh(H)
    return min(energies)

This in the tutorial:

from functools import partial

from ipywidgets import interact_manual
import numpy as np

import adaptive
from kwant_functions import get_brillouin_zone, energies

adaptive.notebook_extension()

# Define the lattice vectors of some common unit cells
lattices = dict(
    hexegonal=(
        (0, 1, 0),
        (np.cos(-np.pi / 6), np.sin(-np.pi / 6), 0),
        (0, 0, 1)
    ),
    simple_cubic=(
        (1, 0, 0),
        (0, 1, 0),
        (0, 0, 1)
    ),
    fcc=(
        (0, .5, .5),
        (.5, .5, 0),
        (.5, 0, .5)
    ),
    bcc=(
        (-.5, .5, .5),
        (.5, -.5, .5),
        (.5, .5, -.5)
    )
)

learners = []
fnames = []
for name, unit_cell in lattices.items():
    hull = get_brillouin_zone(unit_cell)
    learner = adaptive.LearnerND(
        partial(energies, unit_cell=unit_cell), hull, loss_per_simplex=None
    )
    fnames.append(name)
    learners.append(learner)

learner = adaptive.BalancingLearner(learners, strategy="npoints")
adaptive.runner.simple(learner, goal=lambda l: l.learners[0].npoints > 1000)

# XXX: maybe this could even be a `BalancingLearner` method.
def select(name, learners, fnames):
    return learners[fnames.index(name)]


def iso(unit_cell, level=8.5):
    l = select(unit_cell, learners, fnames)
    return l.plot_isosurface(level=level)


def plot_tri(unit_cell):
    l = select(unit_cell, learners, fnames)
    return l.plot_3D()

What should learners do when fed the same point twice

(original issue on GitLab)

opened by Joseph Weston (@jbweston) at 2018-09-17T14:44:24.594Z

def tell(self, x, y):
     if x in self.data:
         return

This is what we do for LearnerND (and I think Learner2D also, but I'm not sure).

Does this make sense? In what cases would someone call tell if the point was already evaluated? Would it make more sense to raise an exception because this indicates an error?

If I say

learner.tell(1, 2)
learner.tell(1, 4)

I would either expect:

  • An exception to be raised
  • The new data to overwrite the old data, losses to be updated etc.

Set up documentation

(original issue on GitLab)

opened by Joseph Weston (@jbweston) at 2018-07-26T10:01:13.269Z

Easiest is use use ReadTheDocs, but this will still require setting up landing/description pages etc.

Even though we're not super strict about our versioning yet (we always just bump the minor version and break
backwards compatibility because we are <v1.0), it's nevertheless useful to know about the state of the software
at a given version.

In addition we can ship versions of the example notebook that correspond to our released version. This would prevent confusion e.g. gitlab:#90.

Release v0.7.0

(original issue on GitLab)

opened by Bas Nijholt (@basnijholt) at 2018-11-30T11:08:04.471Z

Since 0.6.0 we fixed the following issues:

  • gitlab:#122: Remove public 'fname' learner attribute
  • gitlab:#119: (Learner1D) add possibility to use the direct neighbors in the loss
  • gitlab:#114: (LearnerND) allow any convex hull as domain
  • gitlab:#121: How to handle NaN?
  • gitlab:#107: Make BaseRunner an abstract base class
  • gitlab:#112: (LearnerND) add iso-surface plot feature
  • gitlab:#56: Improve plotting for learners
  • gitlab:#118: widgets don't show up on adaptive.readthedocs.io
  • gitlab:#91: Set up documentation
  • gitlab:#62: AverageLearner math domain error
  • gitlab:#113: make BalancingLearner work with the live_plot
  • gitlab:#111: (LearnerND) flat simplices are sometimes added on the surface of the triangulation
  • gitlab:#103: (BalancingLearner) make new balancinglearner that looks at the total loss rather than loss improvement
  • gitlab:#110: LearnerND triangulation incomplete
  • gitlab:#127: Typo in documentation for adaptive.learner.learner2D.uniform_loss(ip)
  • gitlab:#126: (Learner1D) improve time complexity
  • gitlab:#104: Learner1D could in some situations return -inf as loss improvement, which would make balancinglearner never choose to improve
  • gitlab:#128: (LearnerND) fix plotting of scaled domains
  • gitlab:#78: (LearnerND) scale y-values

and merged the following Merge Requests:

  • gitlab:!131: Resolve "(Learner1D) add possibility to use the direct neighbors in the loss"
  • gitlab:!137: adhere to PEP008 by using absolute imports
  • gitlab:!135: test all the different loss functions in each test
  • gitlab:!133: make 'fname' a parameter to 'save' and 'load' only
  • gitlab:!136: build the Dockerimage used in CI
  • gitlab:!134: change resolution_loss to a factory function
  • gitlab:!118: add 'save' and 'load' to the learners and periodic saving to the Runner
  • gitlab:!127: Resolve "(LearnerND) allow any convex hull as domain"
  • gitlab:!130: save execution time on futures inside runners
  • gitlab:!111: Resolve "Make BaseRunner an abstract base class"
  • gitlab:!124: Resolve "(LearnerND) add iso-surface plot feature"
  • gitlab:!108: exponentially decay message frequency in live_info
  • gitlab:!129: add tutorials
  • gitlab:!120: add documentation
  • gitlab:!125: update to the latest miniver
  • gitlab:!126: add check_whitespace
  • gitlab:!123: add an option to plot a HoloMap with the BalancingLearner
  • gitlab:!122: implement 'npoints' strategy for the 'BalancingLearner'
  • gitlab:!119: (learnerND) no more (almost) flat simplices in the triangulation
  • gitlab:!109: make a BalancingLearner strategy that compares the total loss rather than loss improvement
  • gitlab:!117: Cache loss and display it in the live_info widget
  • gitlab:!121: 2D: add loss that minimizes the area of the triangle in 3D
  • gitlab:!139: Resolve "(Learner1D) improve time complexity"
  • gitlab:!140: Resolve "(LearnerND) fix plotting of scaled domains"
  • gitlab:!128: LearnerND scale output values before computing loss

When there is v0.7.0 we can set up the documentation for the latest release and master.

Document and test loss function signatures

(original issue on GitLab)

opened by Anton Akhmerov (@anton-akhmerov) at 2018-07-23T19:06:55.212Z

A loss function is a significant part of the interface of each learner. It provides the users with nearly infinite ways to customize the learner's behavior, and it is also the main way for the users to do so.

As a consequence I believe we need to do the following:

  • Each learner that allows a custom loss function must specify the detailed call signature of this function in the docstring.
  • We should test whether a learner provides a correct input to the loss function. For example if we say that Learner2D passes an interpolation instance to the loss, we should try and run Learner2D with the loss that verifies that its input is indeed an instance of interpolation. We did not realize this, but loss is a part of the learner's public API.
  • All loss functions that we provide should instead be factory functions that return a loss function whose call signature conforms to the spec. For example learner2D.resolution_loss(ip, min_distance=0, max_distance=1) does not conform to the spec, and is not directly reusable. Instead this should have been a functools.partial(learner2D.resolution_loss, min_distance=0, max_distance=1).
  • We should convert all our loss functions that have arbitrary hard-coded parameters into such factory functions, and we should test their conformance to the spec.

Learner1D fails when function returns a list instead of a numpy.array

(original issue on GitLab)

opened by Bas Nijholt (@basnijholt) at 2018-09-13T14:18:58.918Z

def f(x):
    return [x, -x]

learner = adaptive.Learner1D(f, bounds=(-1, 1))
adaptive.runner.simple(learner, goal=lambda l: l.npoints > 200)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-10-e4aced43ce7b> in <module>()
      3 
      4 learner = adaptive.Learner1D(f, bounds=(-1, 1))
----> 5 adaptive.runner.simple(learner, goal=lambda l: l.npoints > 200)

~/Sync/Work/adaptive/adaptive/runner.py in simple(learner, goal)
    458         for x in xs:
    459             y = learner.function(x)
--> 460             learner.tell(x, y)
    461 
    462 

~/Sync/Work/adaptive/adaptive/learner/learner1D.py in tell(self, x, y)
    237 
    238         # Update the scale
--> 239         self.update_scale(x, y)
    240 
    241         # Update the losses

~/Sync/Work/adaptive/adaptive/learner/learner1D.py in update_scale(self, x, y)
    207                     y_min = y_max = y
    208                 self._bbox[1] = [y_min, y_max]
--> 209                 self._scale[1] = np.max(y_max - y_min)
    210             else:
    211                 self._bbox[1][0] = min(self._bbox[1][0], y)

TypeError: unsupported operand type(s) for -: 'list' and 'list'

Learner1D.ask breaks when adding points in some order

(original issue on GitLab)

opened by Bas Nijholt (@basnijholt) at 2018-09-14T11:16:49.789Z

l = adaptive.Learner1D(lambda x: x, (0, 1))
l.tell_many([1, 0, 0.5], [0, 0, 0])
l.ask(1)

Traceback

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-17-1b520d635f37> in <module>()
      2 l = adaptive.Learner1D(lambda x: x, (0, 1))
      3 l.tell_many([1, 0, 0.5], [0, 0, 0])
----> 4 l.ask(1)

~/Work/adaptive/adaptive/learner/learner1D.py in ask(self, n, add_data)
    301                      in self.neighbors.items()][:-1]
    302 
--> 303         for x_left, x_right in intervals:
    304             self.losses[x_left, x_right] = (
    305                 self.loss_per_interval((x_left, x_right), self._scale, self.data)

~/Work/adaptive/adaptive/learner/base_learner.py in tell_many(self, xs, ys)
     43         """
     44         for x, y in zip(xs, ys):
---> 45             self.tell(x, y)
     46 
     47     @abc.abstractmethod

~/Work/adaptive/adaptive/learner/learner1D.py in tell(self, x, y)
    239         self.update_scale(x, y)
    240 
--> 241         # Update the losses
    242         self.update_losses(x, real)
    243 

~/Work/adaptive/adaptive/learner/learner1D.py in update_losses(self, x, real)
    159             a, b = self.find_neighbors(x, self.neighbors_combined)
    160             if x_left is not None and x_right is not None:
--> 161                 dx = x_right - x_left
    162                 loss = self.losses[x_left, x_right]
    163                 losses_combined[a, x] = (x - a) * loss / dx

KeyError: (0, 1)

tell_many method

(original issue on GitLab)

opened by Vanessa Gall (@vgall) at 2018-07-25T13:07:39.891Z

I'm using adaptive version 0.4.1 and it seems, the method tell_many used in the learner.ipynb example both in the 1d and the 2d case does not exist.

learner2 = adaptive.Learner1D(f, bounds=learner.bounds)
xs = np.linspace(*learner.bounds, len(learner.data))
learner2.tell_many(xs, map(partial(f, wait=False), xs))

Maybe it should just be the tell method?

Learner1D could in some situations return -inf as loss improvement, which would make balancinglearner never choose to improve

(original issue on GitLab)

opened by Jorn Hoofwijk (@Jorn) at 2018-09-20T13:50:40.821Z

The following discussion from gitlab:!99 should be addressed:

to show an example: try running:

import adaptive
import numpy as np
adaptive.notebook_extension()

# if we would define f1 to have some features in the interval -1,0 we would never see them using the balancinglearner

def f1(x):
    return -1 if x <= 0.1 else 1

def f2(x):
    return x**2


l1 = adaptive.Learner1D(f1, (-1, 1))
l2 = adaptive.Learner1D(f2, (-1, 1))

# now let's create the balancinglearner and do some balancing :D
bl = adaptive.BalancingLearner([l1, l2])
for i in range(1000):
    xs, _ = bl.ask(1)
    x, = xs
    y = bl.function(x)
    bl.tell(x, y)
    
asked = l1.ask(1, add_data=False)
print(f"l1 requested {asked}, but since loss_improvement is -inf, \n\tbalancinglearner will never choose this")
print(f"npoints: l1: {l1.npoints}, l2: {l2.npoints}, almost all points are added to l2")
print(f"loss():  l1: {l1.loss()}, l2: {l2.loss()}, the actual loss of l1 is much higher than l2.loss")

l1.plot() + l2.plot()

this will output:

l1 requested ([0.10000000000000009], [-inf]), but since loss_improvement is -inf, 
	balancinglearner will never choose this
npoints: l1: 53, l2: 947, almost all points are added to l2
loss():  l1: 1.0, l2: 0.003584776382870768, the actual loss of l1 is much higher than l2.loss

I also have a notebook here: bug_learner1d_infinite_loss_improvement.ipynb that constructs what is happening artificially and indicates on why this happens a bit more.

The reason why this happens:

the interval is bigger than _dx_eps, so it has a finite loss associated with it. When asked to improve, it finds that by dividing this interval, it creates two intervals which are smaller than dx_eps, so it claims the loss_improvement is -inf. Which results in the balancinglearner always choosing another learner to add a point (this second bug is a result of the first one).

the problem with the balancinglearner can be solved by solving gitlab:#103 however, the underlying issue (returning -inf as loss_improvement) is then still not really solved, although one will almost never notice anymore.

Issue using distributed

When using a distributed client for adaptive I get the following error:
Attached a notebook which reproduces the issue
Issue with adaptive.txt

distributed.client - WARNING - Couldn't gather keys {'f_divergent_1d-e860261558c8b0627742c060e2601e1a': []}
tornado.application - ERROR - Exception in callback functools.partial(<function wrap..null_wrapper at 0x7fce980e1950>, <tornado.concurrent.Future object at 0x7fce98146240>)
Traceback (most recent call last):
File "/opt/conda/lib/python3.6/site-packages/tornado/ioloop.py", line 605, in _run_callback
ret = callback()
File "/opt/conda/lib/python3.6/site-packages/tornado/stack_context.py", line 277, in null_wrapper
return fn(*args, **kwargs)
File "/opt/conda/lib/python3.6/site-packages/tornado/ioloop.py", line 626, in _discard_future_result
future.result()
File "/opt/conda/lib/python3.6/site-packages/tornado/concurrent.py", line 238, in result
raise_exc_info(self._exc_info)
File "", line 4, in raise_exc_info
File "/opt/conda/lib/python3.6/site-packages/tornado/gen.py", line 1063, in run
yielded = self.gen.throw(*exc_info)
File "/opt/conda/lib/python3.6/site-packages/distributed/cfexecutor.py", line 22, in _cascade_future
result = yield future._result(raiseit=False)
File "/opt/conda/lib/python3.6/site-packages/tornado/gen.py", line 1055, in run
value = future.result()
File "/opt/conda/lib/python3.6/site-packages/tornado/concurrent.py", line 238, in result
raise_exc_info(self._exc_info)
File "", line 4, in raise_exc_info
File "/opt/conda/lib/python3.6/site-packages/tornado/gen.py", line 1063, in run
yielded = self.gen.throw(*exc_info)
File "/opt/conda/lib/python3.6/site-packages/distributed/client.py", line 194, in _result
result = yield self.client._gather([self])
File "/opt/conda/lib/python3.6/site-packages/tornado/gen.py", line 1055, in run
value = future.result()
File "/opt/conda/lib/python3.6/site-packages/tornado/concurrent.py", line 238, in result
raise_exc_info(self._exc_info)
File "", line 4, in raise_exc_info
File "/opt/conda/lib/python3.6/site-packages/tornado/gen.py", line 1069, in run
yielded = self.gen.send(value)
File "/opt/conda/lib/python3.6/site-packages/distributed/client.py", line 1415, in _gather
self.futures[key].reset()
KeyError: 'f_divergent_1d-e860261558c8b0627742c060e2601e1a'
distributed.scheduler - ERROR - 'f_divergent_1d-e860261558c8b0627742c060e2601e1a'
Traceback (most recent call last):
File "/opt/conda/lib/python3.6/site-packages/distributed/scheduler.py", line 1954, in handle_client
result = handler(**msg)
File "/opt/conda/lib/python3.6/site-packages/distributed/scheduler.py", line 2838, in report_on_key
ts = self.tasks[key]
KeyError: 'f_divergent_1d-e860261558c8b0627742c060e2601e1a'
distributed.scheduler - ERROR - Exception in handle_client
Traceback (most recent call last):
File "/opt/conda/lib/python3.6/site-packages/distributed/scheduler.py", line 1954, in handle_client
result = handler(**msg)
File "/opt/conda/lib/python3.6/site-packages/distributed/scheduler.py", line 2838, in report_on_key
ts = self.tasks[key]
KeyError: 'f_divergent_1d-e860261558c8b0627742c060e2601e1a'

Learner1D doesn't correctly set the interpolated loss when a point is added

(original issue on GitLab)

opened by Bas Nijholt (@basnijholt) at 2018-09-14T13:34:07.649Z

l = adaptive.Learner1D(lambda x: x, (0, 4))

l.tell(0, 0)
l.tell(1, 0)
l.tell(2, 0)

assert l.ask(1) == ([4], [np.inf])
assert l.losses == {(0, 1): 0.25, (1, 2): 0.25}
assert l.losses_combined == {(0, 1): 0.25, (1, 2): 0.25, (2, 4.0): np.inf}

# assert l.ask(1) == ([3], [np.inf])
l.ask(1)
assert l.losses == {(0, 1): 0.25, (1, 2): 0.25}
assert l.losses_combined == {(0, 1): 0.25, (1, 2): 0.25, (2, 3.0): np.inf, (3.0, 4.0): np.inf}

l.tell(4, 0)

assert l.losses_combined == {(0, 1): 0.25, (1, 2): 0.25, (2, 3): 0.25, (3, 4): 0.25}
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-93-ff4ff3682c03> in <module>()
     18 l.tell(4, 0)
     19 
---> 20 assert l.losses_combined == {(0, 1): 0.25, (1, 2): 0.25, (2, 3): 0.25, (3, 4): 0.25}

AssertionError: 

Instead l.losses_combined == {(0, 1): 0.25, (1, 2): 0.25, (2, 3.0): inf, (3.0, 4.0): 0.25}

Where (2, 3.0): inf should be (2, 3.0): 0.25.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.