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

FrEIA.modules #3

Closed
psteinb opened this issue Feb 8, 2021 · 17 comments
Closed

FrEIA.modules #3

psteinb opened this issue Feb 8, 2021 · 17 comments
Assignees
Labels
help wanted Extra attention is needed

Comments

@psteinb
Copy link
Collaborator

psteinb commented Feb 8, 2021

What?

There are many modules that are 2-3 years old, introduced for some specific purpose.
Sometimes it turned out that the concept didn't even work and the module is useless.
In some cases, they overlap in functionality with other modules.
Some of them also don't have docstrings or explanations what it does.

How?

Ensure that

  1. all the modules are useful
  2. the same functionality isn't implemented in two different modules
  3. all modules have a useful docstring explaining the arguments
  4. the modules work correctly

Go through all the modules listed in FrEIA/modules/__init__.py.
Check points 1-3 above, and perhaps 4 (overlap with unittests).

Then deprecate modules that are old or unnecessary, or can be combined with similar ones,
and add docstrings.
Delete the ones that were already deprecated with v0.2 (see FrEIA/modules/coupling_layers.py, lines 430-434)

@psteinb psteinb added the help wanted Extra attention is needed label Feb 8, 2021
@psteinb
Copy link
Collaborator Author

psteinb commented Feb 8, 2021

it might be worth considering to create a PR for this and to drop tags in the code, so people know where to direct their attention to.

@ardizzone ardizzone self-assigned this Feb 8, 2021
@ardizzone
Copy link
Member

Thank you! I will consider that.

@ardizzone
Copy link
Member

Another point that came up:

  • Adding an absttract base class for FrEIA.modules, to make it clear what methods have to be implemented if one writes their own invertible function.

@fdraxler
Copy link
Collaborator

fdraxler commented Feb 9, 2021

I really like the ReversibleSequential returning a tuple of output, jacobian (set to None if expensive and not requested). Can we extend this to all modules?

So we could aim for a signature like this:

TensorOrTensorList = Union[Tensor, List[Tensor]]

def forward(self, x: TensorOrTensorList, c=None, rev=False, jac=True) -> Tuple[TensorOrTensorList, Union[TensorOrTensorList, None]]:
    ...
    if jac:
        return z, jac
    return z, None

Pro: This would also solve #7 and simplify #8, because there is no state to be stored between forward() and jacobian().
Con: This is a breaking change and people have to modify their self-implemented modules.

@ardizzone
Copy link
Member

Let's think about this, it seems like a very good idea, except for ruining existing code if people update FrEIA.
(Also because the return of ReversibleGraphNet will be different, maybe even worse than just the FrEIA.modules changing).

But I admit the current system is pretty janky. (with the run_forward kwarg in .log_jacobian() etc.) It was the best we could do at the time without breaking code. But maybe it's the right time to just do it.

@ardizzone
Copy link
Member

Also:

@wapu
Copy link
Collaborator

wapu commented Feb 9, 2021

I am in favor of this breaking change. We are super inconsistent with the log-Jacobian functions and buffered values anyway. Also it seems that most other normalizing flow implementations chose that signature, so might make it easier for people to understand our API.

@fdraxler
Copy link
Collaborator

fdraxler commented Feb 9, 2021

Any opinion on how do we handle multiple in- & outputs, i.e. split and merge modules? Do we make all modules to work with tuples of tensors everywhere? Then ReversibleSequential is inconsistent with the new signature.

Compromise: We enforce that a module spits out a tuple exactly when it got a tuple in (unit tests #4 for the win!)? This makes minimal breaking changes for users.
Then I would propose what I requested in vislearn/FrEIA#54

Tuples of Jacobian make no sense from a mathematic stand point, I think.

@ardizzone
Copy link
Member

ardizzone commented Feb 10, 2021

No, I think we keep tuples for in- and outut of the individual nodes i.e. return (out1, out2), jac (as you said, there can be only one jacobian). That's the way it is now, except that the (out1, out2) and the jac are returned by different methods.

I don't think the internal stuff necessarily has to be consistent with the Reversible*-interface.
And I am always weary of the kinds of solutions à la "maybe it's a tuple, maybe not, you just have to check and do something different depending" (danger for confusion, need to explain more instead of just saying "ART: Always Return Tuples", and so on)

@ardizzone
Copy link
Member

ardizzone commented Feb 10, 2021

Also, I don't understand:
What if i'm a module with multiple outputs.
I only get a single tensor from the module before me.
Therefore, a single tensor will be output? But I have multiple outputs and need to return a tuple?

@fdraxler
Copy link
Collaborator

We should also have the output_dims(input_dims) abstract method in InvertibleModule. We should add this, right?

@ardizzone
Copy link
Member

Yes, that is true!

@fdraxler
Copy link
Collaborator

Good, I added it in my branch.

Maybe even slicker: Modules should not have a method output_dims, put should tell their output dimension to the InvertibleModule in the constructor. The output_dims method gets exactly the same shapes passed in as the constructor.
Disadvantage: All shape computations have to be done as the first thing in each constructor and we have to do another pass through all modules.

@wapu
Copy link
Collaborator

wapu commented Feb 11, 2021

If it can't be missed by users implementing their own modules how and where to do that, I like the idea.

@ardizzone
Copy link
Member

I think this is a very good idea, just let me know before you go ahead so that i can it around in all the modules.

@fdraxler
Copy link
Collaborator

Ok, the PR vislearn/FrEIA#69 is a proposal.

@ardizzone
Copy link
Member

Did I understand correctly, the proposal is rejected?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants