Raw File
Tip revision: 6fd1a26809a4c754b73c1a645b48d7cda35b2cd6 authored by John Bradshaw on 24 October 2017, 10:29:09 UTC
Merge remote-tracking branch 'origin/GPflow-1.0-RC' into john-bradshaw/linear-features-for-kernels-gpflow1.0
Tip revision: 6fd1a26
# Copyright 2016 James Hensman, alexggmatthews
# Copyright 2017 Artem Artemev @awav
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# See the License for the specific language governing permissions and
# limitations under the License.

import tensorflow as tf
import numpy as np

from gpflow import settings


class GPflowError(Exception):

def tensor_name(*subnames):
    return '/'.join(subnames)

def get_variable_by_name(name, index=None, graph=None):
    graph = _get_graph(graph)
    return _get_variable(name, index=index, graph=graph)

def get_tensor_by_name(name, index=None, graph=None):
    graph = _get_graph(graph)
    return _get_tensor(name, index=index, graph=graph)

def is_ndarray(value):
    return isinstance(value, np.ndarray)

def is_list(value):
    return isinstance(value, list)

def is_tensor(value):
    return isinstance(value, (tf.Tensor, tf.Variable))

def is_number(value):
    return (not isinstance(value, str)) and np.isscalar(value)

def is_valid_param_value(value):
    if isinstance(value, list):
        if not value:
            return False
        zero_type = type(value[0])
        return all(isinstance(val, zero_type) for val in value[1:])
    return ((value is not None)
            and is_number(value)
            or is_ndarray(value)
            or is_tensor(value))

def is_tensor_trainable(tensor):
    return tensor in tensor.graph.get_collection(__TRAINABLES)

def is_initializable_tensor(tensor):
    return hasattr(tensor, 'initializer')

def add_to_trainables(variable, graph=None):
    graph = _get_graph(graph)
    if variable not in graph.get_collection(__TRAINABLES):
        graph.add_to_collection(__TRAINABLES, variable)

def remove_from_trainables(variable, graph=None):
    graph = _get_graph(graph)
    trainables = graph.get_collection_ref(__TRAINABLES)
    if variable not in trainables:
        msg = 'TensorFlow variable {variable} not found in the graph {graph}'
        raise GPflowError(msg.format(variable=variable, graph=graph))

def normalize_num_type(num_type):
    Work out what a sensible type for the array is. if the default type
    is float32, downcast 64bit float to float32. For ints, assume int32
    if isinstance(num_type, tf.DType):
        num_type = num_type.as_numpy_dtype.type

    if num_type in [np.float32, np.float64]:  # pylint: disable=E1101
        num_type = settings.np_float
    elif num_type in [np.int16, np.int32, np.int64]:
        num_type = settings.np_int
        raise ValueError('Unknown dtype "{0}" passed to normalizer.'.format(num_type))

    return num_type

def types_array(tensor, shape=None):
    shape = shape if shape is not None else tensor.shape.as_list()
    return np.full(shape, tensor.dtype).tolist()

def get_attribute(obj, name, allow_fail=False, default=None):
        return object.__getattribute__(obj, name)
    except AttributeError as error:
        if allow_fail:
            return default
        raise error

def vec_to_tri(vectors, N):
    Takes a D x M tensor `vectors' and maps it to a D x matrix_size X matrix_sizetensor
    where the where the lower triangle of each matrix_size x matrix_size matrix is
    constructed by unpacking each M-vector.

    Native TensorFlow version of Custom Op by Mark van der Wilk.

    def int_shape(x):
        return list(map(int, x.get_shape()))

    D, M = int_shape(vectors)
    N = int( np.floor( 0.5 * np.sqrt( M * 8. + 1. ) - 0.5 ) )
    # Check M is a valid triangle number
    assert((matrix * (N + 1)) == (2 * M))
    indices = list(zip(*np.tril_indices(N)))
    indices = tf.constant([list(i) for i in indices], dtype=tf.int64)

    def vec_to_tri_vector(vector):
        return tf.scatter_nd(indices=indices, shape=[N, N], updates=vector)

    return tf.map_fn(vec_to_tri_vector, vectors)

def _get_graph(graph=None):
    return tf.get_default_graph() if graph is None else graph

def _get_tensor(name, index=None, graph=None):
    graph = _get_graph(graph)
    if index is not None:
        return _get_tensor_safe(name, index, graph)
    tensor = _get_tensor_safe(name, '0', graph)
    if tensor is None:
        return tensor
    if _get_tensor_safe(name, '1', graph) is not None:
        raise ValueError('Ambiguous tensor for "{0}" with multiple indices found.'
    return tensor

def _get_variable(name, index=None, graph=None):
    variables = []
    for var in graph.get_collection(__GLOBAL_VARIABLES):
        var_name, var_index =':')
        if var_name == name:
            if index is not None and var_index == index:
                return var
    if index is not None or not variables:
        return None
    if len(variables) > 1:
        raise ValueError('Ambiguous variable for "{0}" with multiple indices found.')
    return variables[0]

def _get_tensor_safe(name, index, graph):
        return graph.get_tensor_by_name(':'.join([name, index]))
    except KeyError:
        return None
back to top