https://github.com/GPflow/GPflow
Revision 834ed79b351ed88fcbc51bba3977bf347227f7ec authored by James Hensman on 24 March 2020, 18:09:29 UTC, committed by GitHub on 24 March 2020, 18:09:29 UTC
This gives GPflow likelihoods a stronger contract re what input shapes are expected and what shapes are returned. In particular, we should obey something akin to tensorflow_probability’s event-shape/batch-shape/sample-shape. Very little changes for most users, except that some shapes will be asserted. Advanced users will benefit from more shape checks and better defined return shapes for methods attached to likelihoods.

Likelihoods now need to define:
 - self.observation_dim: what is the last dimension of Y supposed to be?
 - self.latent_dim: what is the last dimension of F, F_mu and F_var expected to be?
We’ll check that the dimensions of tensors passed in match up.
Return shapes for all methods will be the broadcast-shape of the tensors passed in, with the last dimension removed.
Example: likelihood.variational_expectations(F_mu, F_var, Y) might take tensors of dimensions [..., 2], [..., 2], [..., 2] and return a tensor of shape [...]

The shape checks are handled by the public methods log_prob, predict_mean_and_var, predict_log_density, and variational_expectations; new likelihoods should implement the corresponding private methods with leading underscore.

## Standard likelihoods
Most likelihoods in GPflow are univariate, and treat columns of Y and F as independent variables. For these observation_dim and latent_dim are None, and we shape-check F and Y on-the-fly for matching last-column dimensions. Note that the return shape contract changes as per that above, and the likelihood methods return the sum over observation dimensions.

## Fancy likelihoods
Likelihoods that depart from the univariate standard include:
SwitchedLikelihood [we’ll check that latent_dim = observation_dim - 1]
MultiClass/Softmax [observation_dim = 1, latent_dim = number of classes (e.g. 10 for MNIST)]
HeteroskedasticGaussian e.g. see GPflow notebook [observation_dim = 1, latent_dim = 2]

Note that this change deprecates Likelihood.predict_density in favour of Likelihood.predict_log_density.
1 parent 0919a92
Raw File
Tip revision: 834ed79b351ed88fcbc51bba3977bf347227f7ec authored by James Hensman on 24 March 2020, 18:09:29 UTC
improve shape robustness in likelihoods (#1334)
Tip revision: 834ed79
setup.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# pylint: skip-file

import os
import sys
from pathlib import Path

from pkg_resources import parse_version
from setuptools import find_packages, setup

is_py37 = sys.version_info.major == 3 and sys.version_info.minor == 7
on_rtd = os.environ.get("READTHEDOCS", None) == "True"  # copied from the docs

# Dependencies of GPflow
requirements = ["numpy>=1.10.0", "scipy>=0.18.0", "multipledispatch>=0.4.9", "tabulate"]

if not is_py37:
    requirements.append("dataclasses")

if not on_rtd:
    requirements.append("tensorflow-probability>=0.9")

min_tf_version = "2.1.0"
tf_cpu = "tensorflow"
tf_gpu = "tensorflow-gpu"


# for latest_version() [see https://github.com/GPflow/GPflow/issues/1348]:
def latest_version(package_name):
    import json
    from urllib import request
    import re

    url = f"https://pypi.python.org/pypi/{package_name}/json"
    data = json.load(request.urlopen(url))
    # filter out rc and beta releases and, more generally, any releases that
    # do not contain exclusively numbers and dots.
    versions = [parse_version(v) for v in data["releases"].keys() if re.match("^[0-9.]+$", v)]
    versions.sort()
    return versions[-1]  # return latest version


# Only detect TF if not installed or outdated. If not, do not do not list as
# requirement to avoid installing over e.g. tensorflow-gpu
# To avoid this, rely on importing rather than the package name (like pip).

try:
    # If tf not installed, import raises ImportError
    import tensorflow as tf

    if parse_version(tf.__version__) < parse_version(min_tf_version):
        # TF pre-installed, but below the minimum required version
        raise DeprecationWarning("TensorFlow version below minimum requirement")
except (ImportError, DeprecationWarning):
    # Add TensorFlow to dependencies to trigger installation/update
    if not on_rtd:
        # Do not add TF if we are installing GPflow on readthedocs
        requirements.append(tf_cpu)
        gast_requirement = (
            "gast>=0.2.2,<0.3"
            if latest_version("tensorflow") < parse_version("2.2")
            else "gast>=0.3.3"
        )
        requirements.append(gast_requirement)


with open(str(Path(".", "VERSION").absolute())) as version_file:
    version = version_file.read().strip()

packages = find_packages(".", exclude=["tests"])

setup(
    name="gpflow",
    version=version,
    author="James Hensman, Alex Matthews",
    author_email="james.hensman@gmail.com",
    description="Gaussian process methods in TensorFlow",
    license="Apache License 2.0",
    keywords="machine-learning gaussian-processes kernels tensorflow",
    url="http://github.com/GPflow/GPflow",
    packages=packages,
    include_package_data=True,
    install_requires=requirements,
    extras_require={"Tensorflow with GPU": [tf_gpu]},
    python_requires=">=3.6",
    classifiers=[
        "License :: OSI Approved :: Apache Software License",
        "Natural Language :: English",
        "Operating System :: MacOS :: MacOS X",
        "Operating System :: Microsoft :: Windows",
        "Operating System :: POSIX :: Linux",
        "Programming Language :: Python :: 3.6",
        "Topic :: Scientific/Engineering :: Artificial Intelligence",
    ],
)
back to top