-
Notifications
You must be signed in to change notification settings - Fork 32
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
MixedComposite and NameLayerMapComposite for combining arbitrary Composites #160
MixedComposite and NameLayerMapComposite for combining arbitrary Composites #160
Conversation
0383f9b
to
cfd2bff
Compare
Hey @dkrako thank you for the PR! ImplementationI originally thought of either adding a new mixing Composite type (e.g. For simplicity's sake, I think the latter solution may be preferable over changing Thinking about the actual fall-backs a user may have, I think instead of using a With this in mind, I actually tend more towards the A composite = MixedComposite([
NameMapComposite([(('conv_1, 'conv_2'), Flat())]),
LayerMapComposite([((zennit.types.Convolution, ), AlphaBeta())])
]) A class NameLayerMapComposite(MixedComposite):
def __init__(self, name_map=None, layer_map=None, canonizers=None):
super().__init__([
NameMapComposite(name_map=name_map),
LayerMapComposite(layer_map=layer_map),
], canonizers=canonizers) And finally, a draft prototype for class MixedComposite(Composite):
def __init__(self, composites, canonizers=None):
if canonizers is None:
canonizers = []
self.composites = composites
super().__init__(
module_map=self.mapping,
canonizers=sum([composite.canonizers for composite in composites], canonizers)
)
def mapping(self, ctx, name, child):
# create a context for each of the sub-composites if ctx is empty
if not ctx:
ctx.update({composite: {} for composite in self.composites})
# evaluate all hooks so all composites can update their context
hooks = [composite.module_map(ctx[composite], name, child) for composite in self.composite]
return next((hook for hook in hooks if hook is not None), None) RequirementsI think it would be better to implement the more general The To-Do's associated with this would then be
Would you be willing to complete the implementation and change the PR accordingly? |
Thank you very much for the suggestions. I agree, a general MixedComposite is an even more flexible and elegant approach. I think the name is good and describes what the class is actually doing. One thing to note will be that the list order of the composites corresponds to their "priority". Regarding your draft prototype, I don't really understand why you are summing up the canonizers. As far as I see, the implementation of the two new composite classes doesn't need any more work apart from adding docstrings, right? So what's left to do would be just adding documentation and tests to your draft implementations. I have the feeling that you'd also be better for writing and wording the How-To's, as you have the bigger picture of the usage of your own package. So all in all it seems that it will be more efficient if you would complete this implementation yourself instead of us writing back and forth. I would still be happy to contribute to this, but I think it will take longer as originally expected. Let me know what you think of this. |
Hey @dkrako
I summed them up (they are lists) in the draft so that all canonizers of all composites are used. Since the The
That's the hope, however, I wrote the draft only quickly and without testing it, so there may come things up that I did not yet think of.
If you would like to do it and feel up to it, I do not mind writing back and forth. Otherwise I can also finish it up. |
Thanks @chr5tphr, good to hear and nevermind the delay. The first steps aren't that complex and you'll review the code either way, so I feel up to it and am happy to contribute. I will tackle this next week as I've got a deadline this friday, so expect to hear from me about the end of next week. |
Yes, that would be good. I would keep it general and maybe verify using a
Thank you, looking forward to the first draft! |
see: chr5tphr#160 (comment) - revert additional parameter from NameMapComposite - add MixedComposite - add NameLayerMapComposite
Sorry for the long delay, my schedule was just too tight during the last weeks (but hopefully you will get a new citation soon as I have used your package for LRP attributions in a paper submission) I did the basic stuff now:
I have already created some fixtures and empty failing test stubs for the two new classes. |
Hey @dkrako
No worries, I know how it is, looking forward to reading the paper.
Thanks a lot! In order to better see the actual additions for easier reviewing, could you, for now:
If you would do
|
e51f1c0
to
2ecc11a
Compare
2ecc11a
to
02b91c4
Compare
I have added documentation to the class docstrings and the howto's. I also implemented a first draft of tests for the two new classes. For the Unfortunately the tests for |
The MixedComposite class allows for a list of composites being passed for initialization. The NameLayerMapComposite class allows for both a name and layer map being passed for initialization. - add MixedComposite and NameLayerMapComposite to composites.py - add docstrings for MixedComposite and NameLayerMapComposite - add fixtures for MixedComposite and NameLayerMapComposite to conftest.py - add tests for MixedComposite and NameLayerMapComposite - add howto for MixedComposite and NameLayerMapComposite
02b91c4
to
528e6ae
Compare
@chr5tphr I have fixed the test for |
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.
Hey @dkrako
thanks a lot for your work!
Here's a few things that I noticed.
31e558b
to
0dd7bbe
Compare
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.
Hey @dkrako ,
Thanks a lot again for the work and sorry for the delay!
I think this looks good and can be merged.
The tests for MixedComposite
I will update in a follow-up PR.
This way it is possible to specify a fallback layer map if we want to apply more general rules to the remaining layers.
The parameter is optional. If None is passed, there's no change in functionality.
If a layer_map list is passed with the same format as for the LayerMapComposite, then this will be used as a fallback if there's no hook for this specific layer name.
Just an example, where it's possible to set one Hook for the first two convolutional layers, and a different one for the remaining ones:
I hope you deem this to be a useful addition to this package.