Types API
This page includes docstrings for some types defined in Bijectors.
General types
Bijectors.Transform — Type
Abstract type for a transformation.
Implementing
A subtype of Transform of should at least implement transform(b, x).
If the Transform is also invertible:
- Required:
- Either of the following:
transform(::Inverse{<:MyTransform}, x): thetransformfor its inverse.InverseFunctions.inverse(b::MyTransform): returns an existingTransform.
logabsdetjac: computes the log-abs-det jacobian factor.
- Either of the following:
- Optional:
with_logabsdet_jacobian:transformandlogabsdetjaccombined. Useful in cases where we can exploit shared computation in the two.
For the above methods, there are mutating versions which can optionally be implemented:
Bijectors.Bijector — Type
Abstract type of a bijector, i.e. differentiable bijection with differentiable inverse.
Bijectors.Inverse — Type
inverse(b::Transform)
Inverse(b::Transform)A Transform representing the inverse transform of b.
Specific bijectors
Bijectors.CorrBijector — Type
CorrBijector <: BijectorA bijector implementation of Stan's parametrization method for Correlation matrix: https://mc-stan.org/docs/reference-manual/transforms.html#correlation-matrix-transform.section
Basically, a unconstrained strictly upper triangular matrix y is transformed to a correlation matrix by following readable but not that efficient form:
K = size(y, 1)
z = tanh.(y)
for j=1:K, i=1:K
if i>j
w[i,j] = 0
elseif 1==i==j
w[i,j] = 1
elseif 1<i==j
w[i,j] = prod(sqrt(1 .- z[1:i-1, j].^2))
elseif 1==i<j
w[i,j] = z[i,j]
elseif 1<i<j
w[i,j] = z[i,j] * prod(sqrt(1 .- z[1:i-1, j].^2))
end
endIt is easy to see that every column is a unit vector, for example:
w3' w3 ==
w[1,3]^2 + w[2,3]^2 + w[3,3]^2 ==
z[1,3]^2 + (z[2,3] * sqrt(1 - z[1,3]^2))^2 + (sqrt(1-z[1,3]^2) * sqrt(1-z[2,3]^2))^2 ==
z[1,3]^2 + z[2,3]^2 * (1-z[1,3]^2) + (1-z[1,3]^2) * (1-z[2,3]^2) ==
z[1,3]^2 + z[2,3]^2 - z[2,3]^2 * z[1,3]^2 + 1 -z[1,3]^2 - z[2,3]^2 + z[1,3]^2 * z[2,3]^2 ==
1And diagonal elements are positive, so w is a cholesky factor for a positive matrix.
x = w' * wConsider block matrix representation for x
x = [w1'; w2'; ... wn'] * [w1 w2 ... wn] ==
[w1'w1 w1'w2 ... w1'wn;
w2'w1 w2'w2 ... w2'wn;
...
]The diagonal elements are given by wk'wk = 1, thus x is a correlation matrix.
Every step is invertible, so this is a bijection(bijector).
Note: The implementation doesn't follow their "manageable expression" directly, because their equation seems wrong (7/30/2020). Insteadly it follows definition above the "manageable expression" directly, which is also described in above doc.
Bijectors.LeakyReLU — Type
LeakyReLU{T}(α::T) <: BijectorDefines the invertible mapping
x ↦ x if x ≥ 0 else αxwhere α > 0.
Bijectors.Stacked — Type
Stacked(bs)
Stacked(bs, ranges)
Stacked(bs::Bijector...)A Bijector which stacks bijectors together which can then be applied to a vector where bs[i]::Bijector is applied to x[ranges[i]]::UnitRange{Int}.
Arguments
bscan be either aTupleor anAbstractArrayof 0- and/or 1-dimensional bijectors- If
bsis aTuple, implementations are type-stable using generated functions - If
bsis anAbstractArray, implementations are not type-stable and use iterative methods
- If
rangesneeds to be an iterable consisting ofUnitRange{Int}length(bs) == length(ranges)needs to be true.
Examples
using Bijectors: Logit, Stacked
b1 = Logit(0.0, 1.0)
b2 = identity
b = Stacked(b1, b2)
b([0.0, 1.0]) == [b1(0.0), 1.0] # => trueBijectors.RationalQuadraticSpline — Type
RationalQuadraticSpline{T} <: BijectorImplementation of the Rational Quadratic Spline flow [1].
- Outside of the interval
[minimum(widths), maximum(widths)], this mapping is given by the identity map. - Inside the interval it's given by a monotonic spline (i.e. monotonic polynomials connected at intermediate points) with endpoints fixed so as to continuously transform into the identity map.
For the sake of efficiency, there are separate implementations for 0-dimensional and 1-dimensional inputs.
Notes
There are two constructors for RationalQuadraticSpline:
RationalQuadraticSpline(widths, heights, derivatives): it is assumed thatwidths,
heights, and derivatives satisfy the constraints that makes this a valid bijector, i.e.
widths: monotonically increasing andlength(widths) == K,heights: monotonically increasing andlength(heights) == K,derivatives: non-negative andderivatives[1] == derivatives[end] == 1.RationalQuadraticSpline(widths, heights, derivatives, B): other than than the lengths, no assumptions are made on parameters. Therefore we will transform the parameters s.t.:widths_new∈ [-B, B]ᴷ⁺¹, whereK == length(widths),heights_new∈ [-B, B]ᴷ⁺¹, whereK == length(heights),derivatives_new∈ (0, ∞)ᴷ⁺¹ withderivatives_new[1] == derivates_new[end] == 1, where(K - 1) == length(derivatives).
Examples
Univariate
julia> using StableRNGs: StableRNG; rng = StableRNG(42); # For reproducibility.
julia> using Bijectors: RationalQuadraticSpline
julia> K = 3; B = 2;
julia> # Monotonic spline on '[-B, B]' with `K` intermediate knots/"connection points".
b = RationalQuadraticSpline(randn(rng, K), randn(rng, K), randn(rng, K - 1), B);
julia> b(0.5) # inside of `[-B, B]` → transformed
1.1943325397834206
julia> b(5.) # outside of `[-B, B]` → not transformed
5.0
julia> b = RationalQuadraticSpline(b.widths, b.heights, b.derivatives);
julia> b(0.5) # inside of `[-B, B]` → transformed
1.1943325397834206
julia> d = 2; K = 3; B = 2;
julia> b = RationalQuadraticSpline(randn(rng, d, K), randn(rng, d, K), randn(rng, d, K - 1), B);
julia> b([-1., 1.])
2-element Vector{Float64}:
-1.5660106244288925
0.5384702734738573
julia> b([-5., 5.])
2-element Vector{Float64}:
-5.0
5.0
julia> b([-1., 5.])
2-element Vector{Float64}:
-1.5660106244288925
5.0References
[1] Durkan, C., Bekasov, A., Murray, I., & Papamakarios, G., Neural Spline Flows, CoRR, arXiv:1906.04032 [stat.ML], (2019).
Bijectors.Coupling — Type
Coupling{F, M}(θ::F, mask::M)Implements a coupling-layer as defined in [1].
Examples
julia> using Bijectors: Shift, Coupling, PartitionMask, coupling, couple
julia> m = PartitionMask(3, [1], [2]); # <= going to use x[2] to parameterize transform of x[1]
julia> cl = Coupling(Shift, m); # <= will do `y[1:1] = x[1:1] + x[2:2]`;
julia> x = [1., 2., 3.];
julia> cl(x)
3-element Vector{Float64}:
3.0
2.0
3.0
julia> inverse(cl)(cl(x))
3-element Vector{Float64}:
1.0
2.0
3.0
julia> coupling(cl) # get the `Bijector` map `θ -> b(⋅, θ)`
Shift
julia> couple(cl, x) # get the `Bijector` resulting from `x`
Shift{Vector{Float64}}([2.0])
julia> with_logabsdet_jacobian(cl, x)
([3.0, 2.0, 3.0], 0.0)References
[1] Kobyzev, I., Prince, S., & Brubaker, M. A., Normalizing flows: introduction and ideas, CoRR, (), (2019).
Bijectors.OrderedBijector — Type
OrderedBijector()A bijector mapping unordered vectors in ℝᵈ to ordered vectors in ℝᵈ.
See also
- Stan's documentation
- Note that this transformation and its inverse are the opposite of in this reference.
Bijectors.NamedTransform — Type
NamedTransform <: AbstractNamedTransformWraps a NamedTuple of key -> Bijector pairs, implementing evaluation, inversion, etc.
Examples
julia> using Bijectors: NamedTransform, Scale
julia> b = NamedTransform((a = Scale(2.0), b = exp));
julia> x = (a = 1., b = 0., c = 42.);
julia> b(x)
(a = 2.0, b = 1.0, c = 42.0)
julia> (a = 2 * x.a, b = exp(x.b), c = x.c)
(a = 2.0, b = 1.0, c = 42.0)Bijectors.NamedCoupling — Type
NamedCoupling{target, deps, F} <: AbstractNamedTransformImplements a coupling layer for named bijectors.
See also: Coupling
Examples
julia> using Bijectors: NamedCoupling, Scale
julia> b = NamedCoupling(:b, (:a, :c), (a, c) -> Scale(a + c));
julia> x = (a = 1., b = 2., c = 3.);
julia> b(x)
(a = 1.0, b = 8.0, c = 3.0)
julia> (a = x.a, b = (x.a + x.c) * x.b, c = x.c)
(a = 1.0, b = 8.0, c = 3.0)