OILMMs

http://proceedings.mlr.press/v119/bruinsma20a.html

https://github.com/willtebbutt/oilmms.jl

Science Score: 28.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
  • .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
    2 of 3 committers (66.7%) from academic institutions
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (12.6%) to scientific vocabulary
Last synced: 10 months ago · JSON representation ·

Repository

http://proceedings.mlr.press/v119/bruinsma20a.html

Basic Info
  • Host: GitHub
  • Owner: willtebbutt
  • License: mit
  • Language: Julia
  • Default Branch: master
  • Homepage:
  • Size: 106 KB
Statistics
  • Stars: 6
  • Watchers: 1
  • Forks: 1
  • Open Issues: 0
  • Releases: 0
Created almost 6 years ago · Last pushed almost 5 years ago
Metadata Files
Readme License Citation

README.md

OILMMs.jl: Orthogonal Instantaneous Linear Mixing Models in Julia

Build Status Codecov ColPrac: Contributor's Guide on Collaborative Practices for Community Packages

An implementation of the Orthogonal Instantaneous Linear Mixing Model (OILMM).

The Python implementation can be found here.

Examples

Please refer to the examples directory for basic usage, or below for a very quick intro.

API

The API broadly follows Stheno.jl's. julia f = OILMM(...) constructs an Orthogonal Instantaneous Linear Mixing Model. This object represents a distribution over vector-valued functions -- see the docstring for more info.

julia f(x) represents f at the input locations x. julia logpdf(f(x), y) # compute the log marginal probability of `y` under the model. rand(rng, f(x)) # sample from `f` at `x`, for random number generator `rng`. marginals(f(x)) # compute the marginal statistics of `f` at `x`. y should be an AbstractVector{<:Real} of the same length as x.

To perform inference, simply invoke the posterior function: f_post = posterior(f(x), y) f_post is then another OILMM that is the posterior distribution. That this works is one of the very convenient properties of the OILMM.

All public functions should have docstrings. If you encounter something that is unclear, please raise an issue so that it can be fixed.

Worked Example

```julia using AbstractGPs using LinearAlgebra using OILMMs using Random

Specify and construct an OILMM.

p = 10 m = 3 U, s, _ = svd(randn(p, m)) σ² = 0.1

f = OILMM( [GP(SEKernel()) for _ in 1:m], U, Diagonal(s), Diagonal(rand(m) .+ 0.1), );

Sample from the model.

x = MOInput(randn(10), p); fx = f(x, σ²);

rng = MersenneTwister(123456); y = rand(rng, fx);

Compute the logpdf of the data under the model.

logpdf(fx, y)

Perform posterior inference. This produces another OILMM.

f_post = posterior(fx, y)

Compute the posterior marginals. We can also use rand and logpdf as before.

postmarginals = marginals(fpost(x)); ```

Worked Example using TemporalGPs.jl.

TemporalGPs.jl makes inference and learning in GPs for time series much more efficient than performing exact inference. It plays nicely with this package, and can be used to accelerate inference in an OILMM simply by wrapping each of the base processes using to_sde. See the TemporalGPs.jl docs for more info on this.

```julia using AbstractGPs using LinearAlgebra using OILMMs using Random using TemporalGPs

Specify and construct an OILMM.

p = 10 m = 3 U, s, _ = svd(randn(p, m)) σ² = 0.1

f = OILMM( [to_sde(GP(Matern52Kernel()), SArrayStorage(Float64)) for _ in 1:m], U, Diagonal(s), Diagonal(rand(m) .+ 0.1), );

Sample from the model. LARGE DATA SET!

x = MOInput(RegularSpacing(0.0, 1.0, 1000000), p); fx = f(x, σ²); rng = MersenneTwister(123456); y = rand(rng, fx);

Compute the logpdf of the data under the model.

logpdf(fx, y)

Perform posterior inference. This produces another OILMM.

f_post = posterior(fx, y)

Compute the posterior marginals. We can also use rand and logpdf as before.

postmarginals = marginals(fpost(x)); ```

Notice that this example is nearly identical to the one above, because all GP-related packages used utilise the AbstractGPs.jl APIs.

Worked Example Learning Parameters

We don't provide a fit+predict interface, instead we rely on external packages to provide something similar that is more flexible. Specifically, we recommend using a mixture of ParameterHandling.jl, Optim.jl or some other general non-linear optimisation package), and Zygote.jl. Below we provide a small example: ```julia

Load GP-related packages.

using AbstractGPs using OILMMs using TemporalGPs

Load standard packages from the Julia ecosystem

using LinearAlgebra using Optim # Standard optimisation algorithms. using ParameterHandling # Helper functionality for dealing with model parameters. using Random using Zygote # Algorithmic Differentiation

Specify OILMM parameters as a NamedTuple.

Utilise orthogonal, and positive from ParameterHandling.jl to constrain appropriately.

p = 2 m = 1 θ_init = ( U = orthogonal(randn(p, m)), s = positive.(rand(m) .+ 0.1), σ² = positive(0.1), )

Define a function which builds an OILMM, given a NamedTuple of parameters.

function buildoilmm(θ::NamedTuple) return OILMM( [tosde(GP(Matern52Kernel()), SArrayStorage(Float64)) for _ in 1:m], θ.U, Diagonal(θ.s), Diagonal(zeros(m)), ) end

Generate some synthetic data to train on.

f = buildoilmm(ParameterHandling.value(θinit)); const x = MOInput(RegularSpacing(0.0, 0.01, 1000000), p); fx = f(x, 0.1); rng = MersenneTwister(123456); const y = rand(rng, fx);

Define a function which computes the NLML given the parameters.

function objective(θ::NamedTuple) f = build_oilmm(θ) return -logpdf(f(x, θ.σ²), y) end

Build a version of the objective function which can be used with Optim.jl.

θinitflat, unflatten = flatten(θ_init); unpack(θ::Vector{<:Real}) = ParameterHandling.value(unflatten(θ)) objective(θ::Vector{<:Real}) = objective(unpack(θ))

Utilise Optim.jl + Zygote.jl to optimise the model parameters.

trainingresults = Optim.optimize( objective, θ -> only(Zygote.gradient(objective, θ)), θinitflat + randn(length(θinitflat)), # Add some noise to make learning non-trivial BFGS( alphaguess = Optim.LineSearches.InitialStatic(scaled=true), linesearch = Optim.LineSearches.BackTracking(), ), Optim.Options(showtrace = true); inplace=false, )

Compute posterior marginals at optimal solution.

θopt = unpack(trainingresults.minimizer) f = buildoilmm(θopt) fpost = posterior(f(x, θopt.σ²), y) fx = marginals(f_post(x)) ```

Bib Info

Please refer to the CITATION.bib file.

Owner

  • Name: Will Tebbutt
  • Login: willtebbutt
  • Kind: user

Citation (CITATION.bib)

@incollection{icml2020_4027,
 abstract = {Multi-output Gaussian processes (MOGPs) leverage the flexibility and interpretability of GPs while capturing structure across outputs, which is desirable, for example, in spatio-temporal modelling. The key problem with MOGPs is their computational scaling O(n\^{}3 p\^{}3), which is cubic in the number of both inputs n (e.g., time points or locations) and outputs p. For this reason, a popular class of MOGPs assumes that the data live around a low-dimensional linear subspace, reducing the complexity to O(n\^{}3 m\^{}3). However, this cost is still cubic in the dimensionality of the subspace m, which is still prohibitively expensive for many applications. We propose the use of a sufficient statistic of the data to accelerate inference and learning in MOGPs with orthogonal bases. The method achieves linear scaling in m, hence allowing these models to scale to virtually any m, without sacrificing significant expressivity or requiring approximation. This advance opens up a wide range of real-world tasks and can be combined with existing GP approximations in a plug-and-play way. We demonstrate the efficacy of the method on various synthetic and real-world data sets.},
 author = {Bruinsma, Wessel and Perim Martins, Eric and Tebbutt, William and Hosking, Scott and Solin, Arno and Turner, Richard},
 booktitle = {Proceedings of Machine Learning and Systems 2020},
 pages = {7141--7152},
 title = {Scalable Exact Inference in Multi-Output Gaussian Processes},
 year = {2020}
}

GitHub Events

Total
  • Fork event: 1
Last Year
  • Fork event: 1

Committers

Last synced: over 3 years ago

All Time
  • Total Commits: 48
  • Total Committers: 3
  • Avg Commits per committer: 16.0
  • Development Distribution Score (DDS): 0.375
Top Committers
Name Email Commits
willtebbutt w****1@m****k 30
willtebbutt w****3@c****k 12
github-actions[bot] 4****]@u****m 6
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: about 1 year ago

All Time
  • Total issues: 1
  • Total pull requests: 19
  • Average time to close issues: less than a minute
  • Average time to close pull requests: 15 days
  • Total issue authors: 1
  • Total pull request authors: 2
  • Average comments per issue: 10.0
  • Average comments per pull request: 0.58
  • Merged pull requests: 14
  • Bot issues: 0
  • Bot pull requests: 11
Past Year
  • Issues: 0
  • Pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Issue authors: 0
  • Pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • JuliaTagBot (1)
Pull Request Authors
  • github-actions[bot] (11)
  • willtebbutt (8)
Top Labels
Issue Labels
Pull Request Labels

Packages

  • Total packages: 1
  • Total downloads: unknown
  • Total dependent packages: 0
  • Total dependent repositories: 0
  • Total versions: 9
juliahub.com: OILMMs

http://proceedings.mlr.press/v119/bruinsma20a.html

  • Versions: 9
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent repos count: 9.9%
Average: 37.7%
Dependent packages count: 38.9%
Stargazers count: 48.5%
Forks count: 53.5%
Last synced: 10 months ago