Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 9 additions & 20 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
matrix:
version:
- '1'
- '1.6'
- 'lts'
os:
- ubuntu-latest
arch:
Expand All @@ -27,29 +27,18 @@ jobs:
arch: x64
coverage: true
steps:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: actions/cache@v1
env:
cache-name: cache-artifacts
with:
path: ~/.julia/artifacts
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
restore-keys: |
${{ runner.os }}-test-${{ env.cache-name }}-
${{ runner.os }}-test-
${{ runner.os }}-
include-all-prereleases: false
- uses: julia-actions/cache@v2
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
with:
coverage: ${{ matrix.coverage || false }}
- uses: julia-actions/julia-processcoverage@v1
if: matrix.coverage
- name: Send coverage
if: matrix.coverage
uses: codecov/codecov-action@v2
- uses: codecov/codecov-action@v5
with:
file: lcov.info
files: lcov.info
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false
16 changes: 12 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "BayesianLinearRegressors"
uuid = "f579363c-4606-5e5c-a623-c4549f609c4b"
authors = ["Will Tebbutt <wt0881@my.bristol.ac.uk>"]
version = "0.3.8"
authors = ["Will Tebbutt"]
version = "0.3.9"

[deps]
AbstractGPs = "99985d1d-32ba-4be9-9821-2ec096f28918"
Expand All @@ -11,6 +11,14 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[compat]
AbstractGPs = "0.3, 0.4, 0.5"
AbstractGPs = "0.5"
LinearAlgebra = "1"
PDMats = "0.11"
julia = "1.3"
Test = "1"
julia = "1.10"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test"]
6 changes: 1 addition & 5 deletions src/BayesianLinearRegressors.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
module BayesianLinearRegressors

using AbstractGPs
using LinearAlgebra
using Random
using Statistics
using PDMats
using AbstractGPs, LinearAlgebra, PDMats, Random

using AbstractGPs: AbstractGP, _cholesky, FiniteGP

Expand Down
13 changes: 0 additions & 13 deletions test/Project.toml

This file was deleted.

57 changes: 3 additions & 54 deletions test/bayesian_linear_regression.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,39 +18,13 @@
Σ_empirical = (Y .- mean(Y; dims=2)) * (Y .- mean(Y; dims=2))' ./ samples
@test mean(f(X, Σy)) ≈ m_empirical atol = 1e-2 rtol = 1e-2
@test cov(f(X, Σy)) ≈ Σ_empirical atol = 1e-2 rtol = 1e-2

@testset "Zygote (everything dense)" begin
function rand_blr(X, A_Σy, mw, A_Λw)
Σy, Λw = Symmetric(A_Σy * A_Σy' + I), Symmetric(A_Λw * A_Λw' + I)
f = BayesianLinearRegressor(mw, Λw)
return rand(MersenneTwister(123456), f(X, Σy), 3)
end
mw, A_Σy, A_Λw = f.mw, 0.1 .* randn(rng, N, N), 0.1 .* randn(rng, D, D)

# Run the model forwards and check that output agrees with non-Zygote output
z, back = Zygote.pullback(rand_blr, X, A_Σy, mw, A_Λw)
@test z == rand_blr(X, A_Σy, mw, A_Λw)

# Compute adjoints using Zygote.
z̄ = randn(rng, size(z))
dX, dA_Σy, dmw, dA_Λw = back(z̄)

# Verify adjoints via finite differencing.
fdm = central_fdm(5, 1)
@test dX ≈ first(j′vp(fdm, X -> rand_blr(X, A_Σy, mw, A_Λw), z̄, X))
@test dA_Σy ≈
first(j′vp(fdm, A_Σy -> rand_blr(X, A_Σy, mw, A_Λw), z̄, A_Σy))
@test dmw ≈ first(j′vp(fdm, mw -> rand_blr(X, A_Σy, mw, A_Λw), z̄, mw))
@test dA_Λw ≈
first(j′vp(fdm, A_Λw -> rand_blr(X, A_Σy, mw, A_Λw), z̄, A_Λw))
end
end
@testset "logpdf" begin
rng, N, D = MersenneTwister(123456), 13, 7
X, f, Σy = generate_toy_problem(rng, N, D, Tx)
y = rand(rng, f(X, Σy))

# Construct MvNormal using a naive but simple computation for the mean / cov.
# Compute logpdf using a naive but simple computation for the mean / cov.
function naive_normal_stats(X::Matrix)
return (X' * f.mw, Symmetric(X' * (cholesky(f.Λw) \ X) + Σy))
end
Expand All @@ -59,33 +33,8 @@
m, Σ = naive_normal_stats(X)

# Check that logpdf agrees between distributions and BLR.
@test logpdf(f(X, Σy), y) ≈ logpdf(MvNormal(m, Σ), y)

@testset "Zygote (everything dense)" begin
function logpdf_blr(X, A_Σy, y, mw, A_Λw)
Σy, Λw = Symmetric(A_Σy * A_Σy' + I), Symmetric(A_Λw * A_Λw' + I)
f = BayesianLinearRegressor(mw, Λw)
return logpdf(f(X, Σy), y)
end
mw, A_Σy, A_Λw = f.mw, 0.1 .* randn(rng, N, N), 0.1 .* randn(rng, D, D)

z, back = Zygote.pullback(logpdf_blr, X, A_Σy, y, mw, A_Λw)
@test z == logpdf_blr(X, A_Σy, y, mw, A_Λw)

# Compute gradients using Zygote.
z̄ = randn(rng)
dX, dA_Σy, dy, dmw, dA_Λw = back(z̄)

# Check correctness via finite differencing.
fdm = central_fdm(5, 1)
@test dX ≈ first(j′vp(fdm, X -> logpdf_blr(X, A_Σy, y, mw, A_Λw), z̄, X))
@test dA_Σy ≈
first(j′vp(fdm, A_Σy -> logpdf_blr(X, A_Σy, y, mw, A_Λw), z̄, A_Σy))
@test dy ≈ first(j′vp(fdm, y -> logpdf_blr(X, A_Σy, y, mw, A_Λw), z̄, y))
@test dmw ≈ first(j′vp(fdm, mw -> logpdf_blr(X, A_Σy, y, mw, A_Λw), z̄, mw))
@test dA_Λw ≈
first(j′vp(fdm, A_Λw -> logpdf_blr(X, A_Σy, y, mw, A_Λw), z̄, A_Λw))
end
δ = y - m
@test logpdf(f(X, Σy), y) ≈ -(N * log(2π) + logdet(Σ) + δ' * (Σ \ δ)) / 2
end
@testset "posterior" begin
@testset "low noise" begin
Expand Down
11 changes: 1 addition & 10 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
using AbstractGPs
using BayesianLinearRegressors
using Distributions
using FiniteDifferences
using LinearAlgebra
using Random
using Test
using Zygote
using PDMats
using AbstractGPs, BayesianLinearRegressors, LinearAlgebra, PDMats, Random, Test

using BayesianLinearRegressors: BayesianLinearRegressor, posterior, marginals, cov, mean
using FiniteDifferences: j′vp

include("test_utils.jl")

Expand Down
40 changes: 0 additions & 40 deletions test/sampling_functions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,46 +44,6 @@
@test mean(f(X, Σy)) ≈ m_empirical atol = 1e-3 rtol = 1e-3
@test cov(f(X, Σy)) ≈ Σ_empirical + Σy atol = 1e-2 rtol = 1e-2
end

@testset "Zygote (everything dense)" begin
function test_rand_funcs_adjoints(sample_function)
rng, N, D = MersenneTwister(123456), 11, 5
X, f, _ = generate_toy_problem(rng, N, D, Tx)
mw, A_Λw = f.mw, 0.1 .* randn(rng, D, D)

# Run the model forwards and check that output agrees with non-Zygote.
z, back = Zygote.pullback(sample_function, X, mw, A_Λw)
@test z == sample_function(X, mw, A_Λw)

# Compute adjoints using Zygote.
z̄ = randn(rng, size(z))
dX, dmw, dA_Λw = back(z̄)

# Verify adjoints via finite differencing.
fdm = central_fdm(5, 1)
@test dX ≈ first(j′vp(fdm, X -> sample_function(X, mw, A_Λw), z̄, X))
@test dmw ≈ first(j′vp(fdm, mw -> sample_function(X, mw, A_Λw), z̄, mw))
@test dA_Λw ≈
first(j′vp(fdm, A_Λw -> sample_function(X, mw, A_Λw), z̄, A_Λw))
end

function rand_funcs_single(X, mw, A_Λw)
Λw = Symmetric(A_Λw * A_Λw' + I)
f = BayesianLinearRegressor(mw, Λw)
g = rand(MersenneTwister(123456), f)
return g(X)
end

function rand_funcs_multi(X, mw, A_Λw)
Λw = Symmetric(A_Λw * A_Λw' + I)
f = BayesianLinearRegressor(mw, Λw)
gs = rand(MersenneTwister(123456), f, 1, 1)
return reduce(hcat, map(h -> h(X), reshape(gs, :)))
end

test_rand_funcs_adjoints(rand_funcs_single)
test_rand_funcs_adjoints(rand_funcs_multi)
end
end

@testset "basis_function_regression" begin
Expand Down
Loading