Comments (3)
IMO a macro seems to complicated and leads to un-julian syntax. I also don't think it is necessarily easier for users to figure out how to write the macro than just implementing the three functions currently. I'm not sure if forward
is part of the API or just an implementation detail, and how often it happens that . In any case, I think maybe the following could work:
- Define all methods that apply bijectors to multiple inputs (i.e., vectors, matrices, etc.) generically for all bijectors since we do not support Julia < 1.3 anymore.
- Use something like
@thunk
in ChainRulesCore (see https://www.juliadiff.org/ChainRulesCore.jl/dev/writing_good_rules.html#Use-Thunks-appropriately and https://www.juliadiff.org/ChainRulesCore.jl/dev/api.html#ChainRulesCore.Thunk) to implement the following default:
(f::Bijector)(x) = unthunk(forward(f, x).rv)
logabsdetjac(f::Bijector, x) = unthunk(forward(f, x).logabsdetjac)
(BTW I'm not sure about these names, maybe just make it a tuple or use something else than rv
?)
- Let users (mainly) implement
function Bijectors.forward(f::MyCoolBijector, x)
....
return (rv = ..., logabsdetjac = ...)
end
possibly using @thunk
- Add implementations of a reduced
logabsdetjac
version for andloglikelihood_with_trans
(see #120) that avoid the intermediate allocations of arrays inlogabsdetjac
from bijectors.jl.
IMO a macro seems to complicated and leads to un-julian syntax.
But the "un-Julian syntax" is mostly due to the fact that we're dropping the return
statement, right? If so, we could just make the user add it manually, i.e. return (rv = rv, logabsdetjac = logabsdetjac)
, or make this optional. Other than that, there's not much un-julian about the macro, IMO.
I also don't think it is necessarily easier for users to figure out how to write the macro than just implementing the three functions currently.
That's true but the goal here isn't to make it easier to understand, but easier to go from "I want this bijector" to "I have this bijector". Using a macro we could make it so that there is a minimal amount of work on the user, in addition to getting the most efficient implementation for all the necessary functions. E.g. RadialLayer
and PlanarLayer
would require waaay less code in addition to being more efficient than the current implementation (the fact that these unnecessarily compute logabsdetjac
in the (b::Bijector)(x)
method, kind of proves the point that people aren't bothered to implement all the different methods, haha).
I'm not sure if forward is part of the API or just an implementation detail, and how often it happens that .
It's part of the API 👍 And there are cases where it's definitively worth it, e.g. RadialLayer
for high-dimensional input. It's not particularly useful for stuff like Exp
, but once you start working with 500-dimensional normalizing flows this becomes very important.
Define all methods that apply bijectors to multiple inputs (i.e., vectors, matrices, etc.) generically for all bijectors since we do not support Julia < 1.3 anymore.
I'm potentially for this. But it's worth noting that Bijectors.jl still works for Julia <1.3, it's just that we don't test properly + certain AD-backends doesn't work. This introduction would completely break Bijectors.jl for Julia <1.3.
Use something like
@thunk
in ChainRulesCore
You're thinking along the lines of
function _forward(b, x)
rv = @thunk ...
logabsdetjac = @thunk ...
return (rv = rv, logabsdetjac = logabsdetjac)
end
forward(b, x) = unthunk(_forward(b, x))
(b::Bijector)(x) = unthunk(_forward(b, x).rv)
logabsdetjac(b, x) = unthunk(_forward(b, x).logabsdetjac)
right?
I'd argue that this is both a) more complicated to understand for the user, b) way worse performance as closures have comparatively significant overhead.
Add implementations of a reduced
logabsdetjac
version for andloglikelihood_with_trans
(see #120) that avoid the intermediate allocations of arrays inlogabsdetjac
I'm in favour of the suggestion, but it seems like a slightly different issue, no?
from bijectors.jl.
(BTW I'm not sure about these names, maybe just make it a tuple or use something else than rv?)
Agree, but also separate issue. We discussed renaming rv
to res
(#41) but the issue sort of lost it's momentum and we ended up getting stuck with it.. And I'm not certain about just making it a tuple
, since NamedTuple
means you can access it both using indexing and .varname
.
from bijectors.jl.
Related Issues (20)
- rational quadratic flows not supporting Float32 input HOT 1
- What to do with `CorrBijector` ? HOT 1
- Improve `PDVecBijector`
- Matrix factorization bijectors HOT 4
- Domain Error for VecCholeskyBijector bijector when calling logabsdetjac HOT 4
- Question on simplex bijector implementation HOT 9
- Can't apply Bijectors.ordered to TDist() and MvTDist() HOT 1
- Incorrect bijector for heterogeneous Product distribution HOT 3
- Radial flow to a simplex HOT 5
- Stackoverflow in custom bijector HOT 2
- Missing implementation of `Bijectors.bijector` for `arraydist` distributions. HOT 1
- Bijectors.ordered and MvLogNormal interaction .. only supported for unconstrained distributions. HOT 1
- `TruncatedBijectors` not defined in `Distributions` extension
- support ProductDistribution HOT 3
- Fixes to correlation bijectors
- Improve `with_logabsdet_jacobian` performance for `SimplexBijector` HOT 1
- Tests are failing for `VecCorrBijector` in _very_ rare scenarios
- Add Tapir to Bijectors tests. HOT 2
- README links to dead docs HOT 2
- StackOverflow on calling inverse VecCorrBijector with a multidimensional array
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bijectors.jl.