Skip to content

params(), Flux/Zygote style #41

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

Merged
merged 8 commits into from
Mar 12, 2020
Merged

params(), Flux/Zygote style #41

merged 8 commits into from
Mar 12, 2020

Conversation

theogf
Copy link
Member

@theogf theogf commented Mar 10, 2020

I replaced all scalars by vectors so they can be mutable, and copied the Flux approach of using trainable and params to get out an array of array of parameters to be optimized. Left to be done is to figure out how to fix parameters. @devmotion I saw you helped in making a FixedKernel in GaussianProcesses.jl do you think this is the right solution?

@devmotion
Copy link
Member

Hmm that was quite some time ago, so I don't remember anything about FixedKernel. I think the correct approach would be to follow the instruction in the documentation of Flux if you want to fix specific parameters.

@devmotion
Copy link
Member

BTW quite disappointing that all parameters have to be vectors. I guess there's no way around that currently?

src/generic.jl Outdated

params!(ps,x::AbstractArray) = push!(ps,x)

trainable(x) = ()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
trainable(x) = ()

IMO the implementation of trainable should be removed, since it is already defined in https://github.com/FluxML/Flux.jl/blob/a874bef6f9d8eb1ab2fe376cb8ad068eb36baf33/src/functor.jl#L40.

src/generic.jl Outdated
Comment on lines 17 to 29
function params(k::Kernel)
ps = []
params!(ps,k)
return ps
end

function params!(ps,k::Kernel)
for child in trainable(k)
params!(ps,k)
end
end

params!(ps,x::AbstractArray) = push!(ps,x)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
function params(k::Kernel)
ps = []
params!(ps,k)
return ps
end
function params!(ps,k::Kernel)
for child in trainable(k)
params!(ps,k)
end
end
params!(ps,x::AbstractArray) = push!(ps,x)

Isn't that already defined in https://github.com/FluxML/Flux.jl/blob/a874bef6f9d8eb1ab2fe376cb8ad068eb36baf33/src/functor.jl#L76-L88? It should be sufficient to define trainable for kernels that have trainable parameters.

@theogf
Copy link
Member Author

theogf commented Mar 11, 2020

BTW quite disappointing that all parameters have to be vectors. I guess there's no way around that currently?

I don't think so, Ref would be definitely a better option. But maybe at some point Flux.jl will support it and we can revert it.

@theogf
Copy link
Member Author

theogf commented Mar 11, 2020

I reimplemented Flux params to avoid the dependency, Flux being super heavy...
Do you have an alternative solution?

@devmotion
Copy link
Member

Ah I see. Are params and trainable supposed to be used without Flux at all? If not, one could make Flux an optional dependency and define them only if Flux loaded using Requires.

@theogf
Copy link
Member Author

theogf commented Mar 11, 2020

Ah I see. Are params and trainable supposed to be used without Flux at all? If not, one could make Flux an optional dependency and define them only if Flux loaded using Requires.

Not necessarily. The problem with Requires is that the need to move all the trainable in a different file. It actually feels weird that it is not possible to do all this without importing Flux.jl that would be great that they move this in a different package.

@theogf
Copy link
Member Author

theogf commented Mar 11, 2020

Ah one easy option is to design an internal function _trainable for each kernel and with Requires to add simply Flux.trainable(k::Kernel)= _trainable(k)

@devmotion
Copy link
Member

If the whole purpose of trainable is the integration with Flux, IMO it would be more natural to only define trainable, possibly with Requires. Since all implementations are very short, I don't see an issue with having them in a separate file.

@theogf
Copy link
Member Author

theogf commented Mar 11, 2020

Ok then that's what I did. I just need to write tests now.

@theogf theogf linked an issue Mar 11, 2020 that may be closed by this pull request
@theogf theogf merged commit a0daa6c into master Mar 12, 2020
@theogf theogf deleted the params branch March 26, 2020 14:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create a trainable function for Flux compatibility
2 participants