-
Notifications
You must be signed in to change notification settings - Fork 48
Closed
Description
I've begun to think about 2.0. The reason is that there are are certainly a couple of choices I made early on in development which weren't optimal. Now could be a good time to fix these as the community is growing but still small enough it won't be super disruptive. Also fixing them will make it easier to maintain RiaB in the long run.
I'm opening this issue to get community thoughts on this. @SynapticSage @colleenjg @jquinnlee @mehulrastogi you're some of the most active users I know fairly well so I'm tagging you to get your input (if you have any), but anyone can chip in here. Here's my thoughts:
Essential and backwards incompatible changes (do first):
- Refactoring: As discussed in major refactoring #58 Package structuring #55. E.g. it's not nice having all
Neuronsclasses in one.pyfile. - Args not Dicts: It's increasingly annoying me that parameters are always handed in as dicts. This is unconventional and has warranted very-well-made but hacky work-arounds e.g. Unnoticed, incorrectly typed out parameter names #38 Added params checking for all classes #39
- Global Environment
update(): Given, now,Environmentsknow about theirAgentsandAgentsknow about theirNeuronswe could have just one update function inEnvwhich cascades through else thing else. Cleaner? - Rename
dev-->main -
Environmentstores the global clock. This just makes sense imo. - Better policy API - I don't love the
drift_velocitykwarg. Maybe insteadAgents can have apolicy()method which returns a drift - this would default to the random motion policy, unifying that too. Just something to consider.
Other essential changes
- Type hinting: This is a new thing in python which I've been told to consider. Any thoughts?
- Modularity Break down some of the larger
update()perhaps adding into new agent/neuron/env specific utils scripts. - Dynamic environments Environments can change by adding walls and objects but we should formalise this with setters which, whenever called, save the "state" of the environment alongside a timestamp as a dictionary to an
Env.historydictionary. Then, when plotting / animating the environment we can pass in a time argument and the correct state can be retrieved and plotted. The state of the environment only appends to history whenever it changes (e.g. a setter is called).- Related to the above, if an Environment changes half way through a simulation then animations will not support this since they always replot the last environment which is both wasteful and possibly wrong. To get around this whenever you call
plot_environment()it can be passed afiganaxand a new object which is a list/dict of plot objects,Rwhich are allmatplotlib.Artistsalready existing on the figure. The environment can store an equivalent list of plot objects and whenever this changes (e.g. a wall is added or an object is moved etc.) this change is logged then plotting can (i) get the list of plot objects corresponding to the correct time and (ii) compared it to the passed list, if they aren't equal then repot the env, otherwise don't bother. Something like that. - Alternatively (maybe better):
Environments have anEnv.historydictionary storing the full "state" of the environment (all object locations, walls, boundaries, etc.). ThenEnv.plot_environment()takes a time argument and find the state of the at that time and plots that.
- Related to the above, if an Environment changes half way through a simulation then animations will not support this since they always replot the last environment which is both wasteful and possibly wrong. To get around this whenever you call
- Plotting: To me at least the visualisation ability of RiaB is really important but animations are slow and I like animating things so this annoying. Could improve by being smarter about how we render stuff in matplotlib, and not re-rendering the Environment or trajectories each frame. Stuff like that. See Slow animations #54
- For example if this Environment state dictionary was stored inside the figure itself with some kind of hash code we could just check on each call whether the desired state matches the state thats been plotted. Only replot if they aren't equal.
- Only pass
axnotfigto figure plotting functions. This may throw up some things but likely minor. - Break up
utils.pyinto separate ones for theAgentpackage,Neuronspackage andEnvpackage and maybe also amisc. - Documentation: Would be great to have a sustainable ReadTheDocs page. We should think about how to structure doc strings so they are all uniform. Documentation #36
- Unit testing: I have been pretty sloppy about this but will add loads more.
- Testing on PRs Run RiaB tests, test doc strings and text styling.
- **Move this to
RatInABox/RatInABoxnotTomGeorge1234/RatInABoxRatInABox/RatInABox_RL** package containing all the RL stuff (Actor,Critic,ValueNeuron,TDError,TaskEnvetc.)
-
IntermediateNeuronssubclass for neurons which aren't "fundamental" but take other neurons as inputs. Current examples areFeedForwardLayerandNeuralNetworkNeurons -
DynamicNeuronssubclass for neurons which aren't static i.e. you can't callNeurons.plot_rate_map()because they actually depend on the past history. Examples includeTDErrorNeurons(to be made) or anything with recurrency. - **
SmoothRandomFeatureNeuronsjust some spatially tuned but random neurons. Users just provide a length scale. Would be useful for a lot of feature learning studies. Probably something like a gaussian process underlying these neurons.
Things to consider
-
Neuronsshould followtorch.nn.moduleAPI - this would make more efficient the evaluation of complex feedforward graphs which currently happens in a backwards manner. This might require renaming the.get_state()method with.forward(). Need to think more about this - conda Once all of the above is done it would be nice to publish this on the condo-forge channel.
- Jax compatibility: Very on the fence about this one. Probably leaning towards not doing it. Would be great to have speed ups, autograd and gpu capacity but it could be just a bit too much / unnecessary / off-putting for non-python geeks (tbh, like me). But if jax is the future I want to consider it. Options include:
- Don't do it
- Partial jax to hit a few heavy-lifting utils functions. Q: Does this even work, would converting to/from jax arrays not be inconveniently slow here?
- Full jax no numpy.
np-->jnpeverywhere. - Both jax and numpy. Users choose which backend. This should hard but I've played around and probably could be done. Has complications though.
I'm not a software guy so @SynapticSage @mehulrastogi feel free to give high level comments about best way to go forward.
Metadata
Metadata
Assignees
Labels
No labels