Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resetting processes is not intuitive #616

Closed
celiasmith opened this issue Jan 14, 2015 · 11 comments
Closed

Resetting processes is not intuitive #616

celiasmith opened this issue Jan 14, 2015 · 11 comments
Milestone

Comments

@celiasmith
Copy link
Contributor

If you have a process and set its duration, it is sometimes helpful to do the same process again when running a model again. Right now, the process just continues from where it left off if the simulation is less than the duration.

I looked deep into my soul and figured out that if I typed:

node.output.func_closure[0].cell_contents.keywords['t'] = np.array([0])

It would reset the process to start from the beginning (it was either my soul or @tbekolay, I'm not sure)

Some simpler resetter would be great!

@tbekolay
Copy link
Member

For the record, I think that line only works for whitenoise; would be good too implement a reset function for each process though, for sure. I wasn't sure that the things set in the partial object are accessible, but Chris's soul proves it is!

@studywolf
Copy link
Collaborator

whitenoise resets with sim.reset(), is that what you guys are talking
about?

On Tue, Jan 13, 2015 at 9:55 PM, Trevor Bekolay notifications@github.com
wrote:

For the record, I think that line only works for whitenoise; would be good
too implement a reset function for each process though, for sure. I wasn't
sure that the things set in the partial object are accessible, but Chris's
soul proves it is!


Reply to this email directly or view it on GitHub
#616 (comment).

@tbekolay
Copy link
Member

Actually, nengo.processes.WhiteNoise doesn't reset with sim.reset, nor do other stochastic processes. The way they're implemented, the simulator just sees them as functions when they're part of a node. Technically we can reset them (as shown in the first post) but the simulator can't differentiate between functions that were exposed from processes and those written by a user (which we also can't reset, if they include some state).

@tcstewar
Copy link
Contributor

Yikes... I had no idea that Processes behaved this way. Why? Why don't they reset? These seems like a very large bug to me, and a loss of functionality from the old way of doing things.

Is there a reason we can't just notice when the t value being passed in isn't what we expect? Right now, the system just ignores the t value, but it could notice when t is going back to 0.

@tcstewar
Copy link
Contributor

One other thing to keep in mind with these new Process things: any realtime backend can't guarantee that they can call the Node function every timestep. So this would cause the Process to get completely out of sync.

One possibility to get back the functionality of the old system is to have the f() function take a look at the incoming t value and reset if it's zero, and skip forward however many steps are needed if it's larger than expected.

@tcstewar
Copy link
Contributor

Oh, and another issue: if you build the model twice and try running two Simulators at the same time, it's going to get very confused.

@hunse
Copy link
Collaborator

hunse commented Jan 15, 2015

One other thing to keep in mind with these new Process things: any realtime backend can't guarantee that they can call the Node function every timestep.

This is a good reason why I think we need to do Processes as another thing that Nodes can accept (along with functions and arrays). This way, the builder can deal with them as the special case that they are, and have special logic for certain types of processes just like we do for neuron types. We should also be able to fix the resetting issue like this, since we could pass in the state/RNG just like we do for neuron types.

@tcstewar
Copy link
Contributor

This is a good reason why I think we need to do Processes as another thing that Nodes can accept (along with functions and arrays).

I still disagree with that, but it could just be that I don't have an idea of how complex that spec would be and how much effort it would take to add all sorts of special-case logic for each backend. Are you proposing that each backend needs to have special code to handle Whitenoise and special code for Brownnoise and special code for any other sorts of Process that people want to make up (the same way that backends have special logic for different neuron types)? Or are you suggesting special code for handling Processes in general, so it'd only have to be written once per backend? What would the interface look like?

For this situation here, it doesn't look like much complexity to just add logic to StochasticProcess.f() that actually checks the t value being passed in and handle it appropriately (resetting or skipping steps). If that covers the sorts of things you want this special Process-handling code for, then I don't think it's worth it. But I'm also feeling like I'm missing what the other use-cases are...

@tcstewar
Copy link
Contributor

As I was trying to go to sleep a possible idea for a relatively small change to the Node API came to mind that might address this issue. #622

@hunse
Copy link
Collaborator

hunse commented Jan 15, 2015

Are you proposing that each backend needs to have special code to handle Whitenoise and special code for Brownnoise and special code for any other sorts of Process that people want to make up (the same way that backends have special logic for different neuron types)?

I think neuron types are a good analogy. Ultimately, it's up to the backend whether each one needs separate code, or they can have common code with only some parameter differences between processes. I think a lot of our process needs can be handled with filtered white noise, which should ideally combine the filtering code that backends should already have with a random number generator.

For this situation here, it doesn't look like much complexity to just add logic to StochasticProcess.f() that actually checks the t value being passed in and handle it appropriately (resetting or skipping steps).

But this doesn't handle the problem that it will still be a Node function that can't be guaranteed to be called every time step. If we keep it as a Process, then backends can handle it natively (if they want), truly making it part of the simulation, just like I assume they'd do with the processes that inject directly into the neuron membrane voltage. If they want to run these processes as Python functions instead (or perhaps just the more exotic/custom processes), and not guarantee that they'll be done every time step, that's always an option.

@tcstewar
Copy link
Contributor

I think a lot of our process needs can be handled with filtered white noise, which should ideally combine the filtering code that backends should already have with a random number generator.

I guess I still don't understand what you're proposing, or what sort of things the special-case Process stuff needs to do. Do you mean that every backend will have to implement something like this in the builder:

if isinstance(node.output, nengo.process.WhiteNoise):
    ...  # do something special
elif isinstance(node.output, nengo.process.BrownNoise):
    ...  # do something special
elif ...

or do you mean there should be some standardization in the Process base class that helps this process along? What would that standardization be?

I think a lot of our process needs can be handled with filtered white noise, which should ideally combine the filtering code that backends should already have with a random number generator.

Remember that not all backends do anything like this. Both SpiNNaker and Neurogrid (indeed, any hardware system) do filters very differently than the reference backend.

hunse added a commit that referenced this issue Feb 6, 2015
Renamed StochasticProcess to Process (since it is now more general),
and updated the interface as per discussion in #622.

TODO: fix the #616 issue (resetting). This should be easy now.
TODO: get rid of all references to StochasticProcess, and update
  tests and examples.
TODO: do we want to somehow "deprecate" the old `.f` function so
  that existing code won't break?
hunse added a commit that referenced this issue Feb 9, 2015
Renamed StochasticProcess to Process (since it is now more general),
and updated the interface as per discussion in #622.

TODO: fix the #616 issue (resetting). This should be easy now.
TODO: get rid of all references to StochasticProcess, and update
  tests and examples.
TODO: do we want to somehow "deprecate" the old `.f` function so
  that existing code won't break?
hunse added a commit that referenced this issue Feb 11, 2015
Renamed StochasticProcess to Process (since it is now more general),
and updated the interface as per discussion in #622.

TODO: fix the #616 issue (resetting). This should be easy now.
TODO: get rid of all references to StochasticProcess, and update
  tests and examples.
TODO: do we want to somehow "deprecate" the old `.f` function so
  that existing code won't break?
hunse added a commit that referenced this issue Feb 11, 2015
The simulator now re-makes all `step` functions on a reset, which
should reset all operators. Fixes #616.

The simulator seed (currently only used by Processes, I think) can
be changed when calling `Simulator.reset`.
hunse added a commit that referenced this issue Feb 11, 2015
The simulator now re-makes all `step` functions on a reset, which
should reset all operators. Fixes #616.

The simulator seed (currently only used by Processes, I think) can
be changed when calling `Simulator.reset`.
hunse added a commit that referenced this issue Feb 12, 2015
The simulator now re-makes all `step` functions on a reset, which
should reset all operators. Fixes #616.

The simulator seed (currently only used by Processes, I think) can
be changed when calling `Simulator.reset`.
hunse added a commit that referenced this issue Feb 12, 2015
The simulator now re-makes all `step` functions on a reset, which
should reset all operators. Fixes #616.

The simulator seed (currently only used by Processes, I think) can
be changed when calling `Simulator.reset`.
hunse added a commit that referenced this issue Feb 13, 2015
The simulator now re-makes all `step` functions on a reset, which
should reset all operators. Fixes #616.

The simulator seed (currently only used by Processes, I think) can
be changed when calling `Simulator.reset`.
hunse added a commit that referenced this issue Feb 17, 2015
The simulator now re-makes all `step` functions on a reset, which
should reset all operators. Fixes #616.

The simulator seed (currently only used by Processes, I think) can
be changed when calling `Simulator.reset`.
hunse added a commit that referenced this issue Feb 18, 2015
The simulator now re-makes all `step` functions on a reset, which
should reset all operators. Fixes #616.

The simulator seed (currently only used by Processes, I think) can
be changed when calling `Simulator.reset`.
hunse added a commit that referenced this issue Feb 18, 2015
The simulator now re-makes all `step` functions on a reset, which
should reset all operators. Fixes #616.

The simulator seed (currently only used by Processes, I think) can
be changed when calling `Simulator.reset`.
@tbekolay tbekolay added this to the 2.1.0 release milestone Mar 3, 2015
hunse added a commit that referenced this issue May 14, 2015
The simulator now re-makes all `step` functions on a reset, which
should reset all operators. Fixes #616.

The simulator seed (currently only used by Processes, I think) can
be changed when calling `Simulator.reset`.
hunse added a commit that referenced this issue May 14, 2015
The simulator now re-makes all `step` functions on a reset, which
should reset all operators. Fixes #616.

The simulator seed (currently only used by Processes, I think) can
be changed when calling `Simulator.reset`.
hunse added a commit that referenced this issue May 14, 2015
The simulator now re-makes all `step` functions on a reset, which
should reset all operators. Fixes #616.

The simulator seed (currently only used by Processes, I think) can
be changed when calling `Simulator.reset`.
hunse added a commit that referenced this issue May 15, 2015
The simulator now re-makes all `step` functions on a reset, which
should reset all operators. Fixes #616.

The simulator seed (currently only used by Processes, I think) can
be changed when calling `Simulator.reset`. Fixes #582.
hunse added a commit that referenced this issue May 15, 2015
The simulator now re-makes all `step` functions on a reset, which
should reset all operators. Fixes #616.

The simulator seed (currently only used by Processes, I think) can
be changed when calling `Simulator.reset`. Fixes #582.
@hunse hunse closed this as completed in f912d1f May 15, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

5 participants