-
Notifications
You must be signed in to change notification settings - Fork 8
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
Basis refactor pr1 #273
Basis refactor pr1 #273
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Boy this is a big PR. I think we covered most of the content / architectures questions as we've discussed this in person, but I have some tweaks throughout.
Additionally, I think, bigger picture, we will need to rework developer notes.
- There are two different variants of them: how to write a nemos-compliant basis for your own use, and how we write new basis objects to include in nemos. Those might both belong in the docs, or not (maybe one of them is in contributing?).
- The developer notes docs should contain a minimum working example of whatever we explain (to serve as a test as well).
- We also should probably write up "how to do a basis mixin"
I think this is a separate PR though -- should I paste this in #274? or would it be a new one?
Co-authored-by: William F. Broderick <[email protected]>
Co-authored-by: William F. Broderick <[email protected]>
Co-authored-by: William F. Broderick <[email protected]>
Co-authored-by: William F. Broderick <[email protected]>
Co-authored-by: William F. Broderick <[email protected]>
Co-authored-by: William F. Broderick <[email protected]>
Co-authored-by: William F. Broderick <[email protected]>
Co-authored-by: William F. Broderick <[email protected]>
Co-authored-by: William F. Broderick <[email protected]>
Co-authored-by: William F. Broderick <[email protected]>
Co-authored-by: William F. Broderick <[email protected]>
Co-authored-by: William F. Broderick <[email protected]>
Co-authored-by: William F. Broderick <[email protected]>
I think a separate PR, because i am still editing the basis module in the following PRs... I would do fix the notes once the module is more stable |
@billbrod I should have gone through everything. You should ignore the documentation for this PR, and focus just on the code, since in the next PR I'll focus on the documentation. I plan to merge this by the end of the day if there are no more major concerns |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Double-check that the changes I just pushed look good, but this looks good to me!
Great, thanks Billy! |
Basis API Refactor
Overview
This is a massive PR that revisiting the basis API. In particular it addresses #266 and notably breaks backwards compatibility.
The goal was to simplify the initialization and control logic of the basis class. Before this PR the classes for basis could operate in two modes: convolving the input with basis elements, or maps non-linearly the input through the basis, in what was originally
mode="conv"
andmode="eval"
respectively. The issue with this approach is that the initialization presented a number of parameters that only applied to one modality (bounds applies to "eval", "window_size" to "conv").To design our classes we had to operate under the following constraints:
get_params
andset_params
to work. The name of the attribute must match the name of the parameter defined at initialization.compute_features
method, so that we can guarantee that complex basis (addition and multiplication of a number of bases) can call recursively thecompute_features
method of the components. Also, this makes it easier to map a basis to a scikit-learn transformer.These requirements are incompatible with the original plan of having a single class with default mode of operation, and a method for switching mode. The reason is that if the default initialization requires only a subset of the parameters, the other mode of operation will not respect the scikit-learn API (having parameter set outside the initialization).
We settled for 2 distinct classes for each operational mode, at the cost of doubling the size of the basis API. The pros of this approach is: simpler initialization, and improved modularity of the implementation.
Module Refactor Details
The
basis
module has been moved from to a folder with the following scripts:_basis.py
: contains theBasis
abstract class,AdditiveBasis
andMultiplicativeBasis
(classes that cannot/should not be initialized directly)._basis_mixin.py
: containsConvBasisMixin
andEvalBasisMixin
, implementing all mode specific methods and the parameter control logic.BasisTransformerMixin
equips basis with theto_transformer
method. These classes cannot be initialized on their own but add the mode of operation and extra methods to concrete sublcasses ofBasis
._transformer_basis.py
: Implements the transformer API for basis.basis.py
: contains all the concrete basis for both modality. Each basis name starts with eitherConv
andEval
depending on the mixin super-class._
_raised_cosine_basis.py
,_decaying_exponential.py
,_spline_basis.py
implements the__call__
method and check logic that is specific to each basis type.