Skip to content
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

Add KL divergence between Deterministic + others for pytorch #36

Merged
merged 13 commits into from
Dec 23, 2020
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
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 2.1.0
current_version = 2.1.1

[bumpversion:file:setup.py]

Expand Down
4 changes: 3 additions & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
[flake8]
ignore = E203,E501,W503,E731,E741,F401,F403,F405
ignore = E203,E501,W503,E731,E741
per-file-ignores =
src/probflow/__init__.py:F401,F403
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ test-pytorch:

format:
. venv/bin/activate; \
autoflake -r --in-place --remove-all-unused-imports --ignore-init-module-imports src/probflow tests; \
isort src/probflow tests; \
black src/probflow tests; \
flake8 src/probflow tests
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name="probflow",
version="2.1.0",
version="2.1.1",
author="Brendan Hasz",
author_email="winsto99@gmail.com",
description="A Python package for building Bayesian models with TensorFlow or PyTorch",
Expand Down Expand Up @@ -41,6 +41,7 @@
"torch >= 1.5.0",
],
"dev": [
"autoflake >= 1.4",
"black >= 19.10b0",
"bumpversion",
"flake8 >= 3.8.3",
Expand Down
2 changes: 1 addition & 1 deletion src/probflow/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
from probflow.utils.io import *
from probflow.utils.settings import *

__version__ = "2.1.0"
__version__ = "2.1.1"
2 changes: 0 additions & 2 deletions src/probflow/applications/linear_regression.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from typing import Callable, List, Union

import probflow.utils.ops as O
from probflow.distributions import Normal
from probflow.models import ContinuousModel
Expand Down
2 changes: 1 addition & 1 deletion src/probflow/callbacks/monitor_parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class MonitorParameter(Callback):

"""

def __init__(self, x, y=None, params=None):
def __init__(self, params):

# Store metrics and epochs
self.params = params
Expand Down
1 change: 0 additions & 1 deletion src/probflow/models/categorical_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,4 @@ def calibration_curve(
TODO: Docs...

"""
pass
# TODO
1 change: 0 additions & 1 deletion src/probflow/models/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -895,5 +895,4 @@ def summary(self):
model would have to add to it the observation dist

"""
pass
# TODO
1 change: 0 additions & 1 deletion src/probflow/modules/dense.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import probflow.utils.ops as O
from probflow.parameters import DeterministicParameter, Parameter
from probflow.utils.settings import get_backend, get_flipout

Expand Down
2 changes: 1 addition & 1 deletion src/probflow/modules/dense_network.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Callable, List, Union
from typing import Callable, List

import probflow.utils.ops as O

Expand Down
5 changes: 1 addition & 4 deletions src/probflow/modules/embedding.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
from typing import Callable, Dict, List, Type, Union
from typing import List, Union

import probflow.utils.ops as O
from probflow.distributions import Deterministic, Normal
from probflow.parameters import DeterministicParameter, Parameter
from probflow.utils.base import BaseDistribution
from probflow.utils.initializers import xavier

from .module import Module

Expand Down
1 change: 0 additions & 1 deletion src/probflow/parameters/bounded_parameter.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import probflow.utils.ops as O
from probflow.distributions import Normal
from probflow.utils.casting import to_numpy
from probflow.utils.initializers import scale_xavier, xavier

from .parameter import Parameter
Expand Down
1 change: 0 additions & 1 deletion src/probflow/parameters/deterministic_parameter.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import probflow.utils.ops as O
from probflow.distributions import Deterministic, Normal
from probflow.utils.initializers import xavier

Expand Down
1 change: 0 additions & 1 deletion src/probflow/parameters/multivariate_normal_parameter.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import probflow.utils.ops as O
from probflow.distributions import MultivariateNormal
from probflow.utils.initializers import xavier
from probflow.utils.settings import get_backend

from .parameter import Parameter

Expand Down
2 changes: 0 additions & 2 deletions src/probflow/utils/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,6 @@ def abs(val):
def square(val):
"""Power of 2"""
if get_backend() == "pytorch":
import torch

return val ** 2
else:
import tensorflow as tf
Expand Down
1 change: 0 additions & 1 deletion src/probflow/utils/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from matplotlib.colors import to_rgba

COLORS = plt.rcParams["axes.prop_cycle"].by_key()["color"]

Expand Down
8 changes: 7 additions & 1 deletion src/probflow/utils/torch_distributions.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def get_TorchDeterministic():

import torch
from torch.distributions import constraints
from torch.distributions.distribution import Distribution
from torch.distributions.kl import register_kl
from torch.distributions.utils import broadcast_all

class TorchDeterministic(torch.distributions.distribution.Distribution):
Expand Down Expand Up @@ -77,4 +77,10 @@ def icdf(self, value):
def entropy(self):
return torch.log(torch.zeros([1]))

@register_kl(
TorchDeterministic, torch.distributions.distribution.Distribution
)
def kl_deterministic_continuous(p, q):
return -q.log_prob(p.mean)

return TorchDeterministic
1 change: 0 additions & 1 deletion tests/examples/test_example_correlation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import matplotlib.pyplot as plt
import numpy as np
import pytest
import tensorflow as tf
import tensorflow_probability as tfp

Expand Down
2 changes: 0 additions & 2 deletions tests/examples/test_example_gan.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
"""Tests example GAN model"""


import matplotlib.pyplot as plt
import numpy as np
import pytest
import tensorflow as tf
import tensorflow_probability as tfp

Expand Down
3 changes: 0 additions & 3 deletions tests/examples/test_example_gmm.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
"""Tests exmaple gaussian mixture model"""


import matplotlib.pyplot as plt
import numpy as np
import pytest
import tensorflow as tf
import tensorflow_probability as tfp

import probflow as pf
Expand Down
2 changes: 0 additions & 2 deletions tests/examples/test_example_heteroscedastic.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
"""Tests example robust heteroscedastic regression"""


import matplotlib.pyplot as plt
import numpy as np
import pytest
import tensorflow as tf
import tensorflow_probability as tfp

Expand Down
1 change: 0 additions & 1 deletion tests/examples/test_example_linear_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import numpy as np
import pandas as pd
import tensorflow as tf

import probflow as pf

Expand Down
2 changes: 0 additions & 2 deletions tests/examples/test_example_ppca.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
"""Tests example probabilistic PCA"""


import matplotlib.pyplot as plt
import numpy as np
import pytest
import tensorflow as tf
import tensorflow_probability as tfp

Expand Down
1 change: 0 additions & 1 deletion tests/stats/test_LogisticRegression.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@


import numpy as np
import tensorflow as tf

import probflow as pf

Expand Down
42 changes: 42 additions & 0 deletions tests/unit/pytorch/applications/test_dense_classifier.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import numpy as np

from probflow.applications import DenseClassifier


def test_DenseClassifier():
"""Tests probflow.applications.DenseClassifier"""

# Data
x = np.random.randn(100, 5).astype("float32")
w = np.random.randn(5, 1).astype("float32")
y = x @ w + 1
y = np.round(1.0 / (1.0 + np.exp(-y))).astype("float32")

# Create the model
model = DenseClassifier([5, 20, 15, 2])

# Fit the model
model.fit(x, y, batch_size=10, epochs=3)

# Predictive functions
model.predict(x)


def test_MultinomialDenseClassifier():
"""Tests probflow.applications.DenseClassifier w/ >2 output classes"""

# Data
x = np.random.randn(100, 5).astype("float32")
w = np.random.randn(5, 3).astype("float32")
b = np.random.randn(1, 3).astype("float32")
y = x @ w + b
y = np.argmax(y, axis=1).astype("int32")

# Create the model
model = DenseClassifier([5, 20, 15, 3])

# Fit the model
model.fit(x, y, batch_size=10, epochs=3)

# Predictive functions
model.predict(x)
103 changes: 103 additions & 0 deletions tests/unit/pytorch/applications/test_dense_regression.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import numpy as np

from probflow.applications import DenseRegression


def test_DenseRegression():
"""Tests probflow.applications.DenseRegression"""

# Data
x = np.random.randn(100, 5).astype("float32")
w = np.random.randn(5, 1).astype("float32")
y = x @ w + 1

# Create the model
model = DenseRegression([5, 20, 15, 1])

# Fit the model
model.fit(x, y, batch_size=10, epochs=3)

# Predictive functions
preds = model.predict(x[:11, :])
assert isinstance(preds, np.ndarray)
assert preds.ndim == 2
assert preds.shape[0] == 11
assert preds.shape[1] == 1

# predictive interval
lb, ub = model.predictive_interval(x[:12, :], ci=0.9)
assert isinstance(lb, np.ndarray)
assert lb.ndim == 2
assert lb.shape[0] == 12
assert lb.shape[1] == 1
assert isinstance(ub, np.ndarray)
assert ub.ndim == 2
assert ub.shape[0] == 12
assert ub.shape[1] == 1


def test_DenseRegression_heteroscedastic():
"""Tests probflow.applications.DenseRegression w/ heteroscedastic"""

# Data
x = np.random.randn(100, 5).astype("float32")
w = np.random.randn(5, 1).astype("float32")
y = x @ w + 1
y = y + np.exp(y) * np.random.randn(100, 1).astype("float32")

# Create the model
model = DenseRegression([5, 20, 15, 1], heteroscedastic=True)

# Fit the model
model.fit(x, y, batch_size=10, epochs=3)

# Predictive functions
preds = model.predict(x[:11, :])
assert isinstance(preds, np.ndarray)
assert preds.ndim == 2
assert preds.shape[0] == 11
assert preds.shape[1] == 1

# predictive interval
lb, ub = model.predictive_interval(x[:12, :], ci=0.9)
assert isinstance(lb, np.ndarray)
assert lb.ndim == 2
assert lb.shape[0] == 12
assert lb.shape[1] == 1
assert isinstance(ub, np.ndarray)
assert ub.ndim == 2
assert ub.shape[0] == 12
assert ub.shape[1] == 1


def test_DenseRegression_multivariate():
"""Tests probflow.applications.DenseRegression w/ >1 output dims"""

# Data
N = 256
Di = 7
Do = 3
x = np.random.randn(N, Di).astype("float32")
w = np.random.randn(Di, Do).astype("float32")
y = x @ w + 0.1 * np.random.randn(N, Do).astype("float32")

# Create the model
model = DenseRegression([Di, 16, Do])

# Fit the model
model.fit(x, y, batch_size=128, epochs=3)

# Predictive functions
preds = model.predict(x[:11, :])
assert isinstance(preds, np.ndarray)
assert preds.ndim == 2
assert preds.shape[0] == 11
assert preds.shape[1] == Do

# Predictive functions
preds = model.predictive_sample(x[:11, :], n=13)
assert isinstance(preds, np.ndarray)
assert preds.ndim == 3
assert preds.shape[0] == 13
assert preds.shape[1] == 11
assert preds.shape[2] == Do
Loading