Module WUT.Variance_Network

Expand source code
import numpy as np
import tensorflow as tf
import types
from tensorflow.python.keras.layers.ops import core as core_ops
import mdn
from tensorflow.compat.v1.keras import layers
from tensorflow.python.keras import activations
from tensorflow_probability import distributions as tfd
from keras import backend as K
from keras import activations, initializers
import tensorflow_probability as tfp


class Variance_Network():
    def __init__(self, Model, Std_Model = None, error_activation = None, one_hot = True):
        
        
        """Variance Network Initializer. Turns a neural network into Variance network.

        Args:
            Model: Input Keras Model.
            Std_Model: what model would you like to use to predict variance. If not specified, assumes default model. (We Thoughtfully remove the activation on your last layer for you.)
            error_activation: use this only if you don't specify Std_Model, it will change the activation function on the last layer of the Std model to this
            one_hot: if True, assumes you're feeding us one hot vectors as targets. If false, assumes its just labels, and we'll make it a one hot.

        Returns:
            Nothing lol

        """

        
        
        
        if Std_Model is None:
            Std_Model = Model
        self.model = Model()
        self.std_model = Std_Model()

        self.error_norm = 1
        self.error_activation = error_activation
        self.one_hot = one_hot
            



        layer = self.std_model.layers[-1]
        layer.activation = activations.get(error_activation)


    def compile(self, *args, Std_loss = None, **kwargs):
        
        """compile. Literally use this as you'd use the normal compile, but you can also specify a loss for the variance predictor. defaults to MSE.

        Args:
            Std_loss: loss function for Std_Model.

        Returns:
            Nothing lol

        """

        
        self.model.compile(*args, **kwargs)
        new_kwargs = kwargs
        if Std_loss == None:
            Std_loss = tf.keras.losses.MSE
        new_kwargs['loss'] = Std_loss
        self.std_model.compile(*args, **new_kwargs)



    def fit(self, *args, **kwargs):
        
        """fit. Literally use this as you'd use the normal keras fit.

        Returns:
            Nothing lol.

        """

        
        self.model.fit(*args, **kwargs)
        preds = self.model.predict(args[0])
        if self.one_hot == False:
            args = list(args)
            max_val = tf.reduce_max(args[1])
            max_val = tf.cast(max_val + 1, tf.int32)
            onehot = tf.one_hot(args[1], max_val)
            args[1] = onehot
            args = tuple(args)
        preds = preds.reshape(args[1].shape)
        errors = ((args[1] - preds)**2)**.5
        new_args = list(args)
        new_args[1] = tf.reshape(errors, args[1].shape)
        new_args = tuple(new_args)
        self.std_model.fit(*new_args, **kwargs)

    def evaluate(self, *args, **kwargs):
        
        """evaluate. Literally use this as you'd use the normal keras evaluate.

        Returns:
            Nothing lol.

        """

        
        return self.model.evaluate( *args, **kwargs)

    def predict(self, *args, return_std = True, **kwargs):
        
        """predict. Literally use this as you'd use the normal keras predict.
        Args:
            return_std: checks if you would even like the std.
            
        Returns:
            a mean and variance, for each input.

        """        
        
        mean_preds = self.model.predict(*args, **kwargs)
        std_preds = self.std_model.predict(*args, **kwargs)
        mean_preds = tf.expand_dims(mean_preds, 1)
        std_preds = (tf.expand_dims(std_preds, 1) * self.error_norm)

        if not return_std:
            return np.mean(tf.stack(predictions), 0)
        return tf.concat([mean_preds, std_preds], axis = 1)

Classes

class Variance_Network (Model, Std_Model=None, error_activation=None, one_hot=True)

Variance Network Initializer. Turns a neural network into Variance network.

Args

Model
Input Keras Model.
Std_Model
what model would you like to use to predict variance. If not specified, assumes default model. (We Thoughtfully remove the activation on your last layer for you.)
error_activation
use this only if you don't specify Std_Model, it will change the activation function on the last layer of the Std model to this
one_hot
if True, assumes you're feeding us one hot vectors as targets. If false, assumes its just labels, and we'll make it a one hot.

Returns

Nothing lol

Expand source code
class Variance_Network():
    def __init__(self, Model, Std_Model = None, error_activation = None, one_hot = True):
        
        
        """Variance Network Initializer. Turns a neural network into Variance network.

        Args:
            Model: Input Keras Model.
            Std_Model: what model would you like to use to predict variance. If not specified, assumes default model. (We Thoughtfully remove the activation on your last layer for you.)
            error_activation: use this only if you don't specify Std_Model, it will change the activation function on the last layer of the Std model to this
            one_hot: if True, assumes you're feeding us one hot vectors as targets. If false, assumes its just labels, and we'll make it a one hot.

        Returns:
            Nothing lol

        """

        
        
        
        if Std_Model is None:
            Std_Model = Model
        self.model = Model()
        self.std_model = Std_Model()

        self.error_norm = 1
        self.error_activation = error_activation
        self.one_hot = one_hot
            



        layer = self.std_model.layers[-1]
        layer.activation = activations.get(error_activation)


    def compile(self, *args, Std_loss = None, **kwargs):
        
        """compile. Literally use this as you'd use the normal compile, but you can also specify a loss for the variance predictor. defaults to MSE.

        Args:
            Std_loss: loss function for Std_Model.

        Returns:
            Nothing lol

        """

        
        self.model.compile(*args, **kwargs)
        new_kwargs = kwargs
        if Std_loss == None:
            Std_loss = tf.keras.losses.MSE
        new_kwargs['loss'] = Std_loss
        self.std_model.compile(*args, **new_kwargs)



    def fit(self, *args, **kwargs):
        
        """fit. Literally use this as you'd use the normal keras fit.

        Returns:
            Nothing lol.

        """

        
        self.model.fit(*args, **kwargs)
        preds = self.model.predict(args[0])
        if self.one_hot == False:
            args = list(args)
            max_val = tf.reduce_max(args[1])
            max_val = tf.cast(max_val + 1, tf.int32)
            onehot = tf.one_hot(args[1], max_val)
            args[1] = onehot
            args = tuple(args)
        preds = preds.reshape(args[1].shape)
        errors = ((args[1] - preds)**2)**.5
        new_args = list(args)
        new_args[1] = tf.reshape(errors, args[1].shape)
        new_args = tuple(new_args)
        self.std_model.fit(*new_args, **kwargs)

    def evaluate(self, *args, **kwargs):
        
        """evaluate. Literally use this as you'd use the normal keras evaluate.

        Returns:
            Nothing lol.

        """

        
        return self.model.evaluate( *args, **kwargs)

    def predict(self, *args, return_std = True, **kwargs):
        
        """predict. Literally use this as you'd use the normal keras predict.
        Args:
            return_std: checks if you would even like the std.
            
        Returns:
            a mean and variance, for each input.

        """        
        
        mean_preds = self.model.predict(*args, **kwargs)
        std_preds = self.std_model.predict(*args, **kwargs)
        mean_preds = tf.expand_dims(mean_preds, 1)
        std_preds = (tf.expand_dims(std_preds, 1) * self.error_norm)

        if not return_std:
            return np.mean(tf.stack(predictions), 0)
        return tf.concat([mean_preds, std_preds], axis = 1)

Methods

def compile(self, *args, Std_loss=None, **kwargs)

compile. Literally use this as you'd use the normal compile, but you can also specify a loss for the variance predictor. defaults to MSE.

Args

Std_loss
loss function for Std_Model.

Returns

Nothing lol

Expand source code
def compile(self, *args, Std_loss = None, **kwargs):
    
    """compile. Literally use this as you'd use the normal compile, but you can also specify a loss for the variance predictor. defaults to MSE.

    Args:
        Std_loss: loss function for Std_Model.

    Returns:
        Nothing lol

    """

    
    self.model.compile(*args, **kwargs)
    new_kwargs = kwargs
    if Std_loss == None:
        Std_loss = tf.keras.losses.MSE
    new_kwargs['loss'] = Std_loss
    self.std_model.compile(*args, **new_kwargs)
def evaluate(self, *args, **kwargs)

evaluate. Literally use this as you'd use the normal keras evaluate.

Returns

Nothing lol.

Expand source code
def evaluate(self, *args, **kwargs):
    
    """evaluate. Literally use this as you'd use the normal keras evaluate.

    Returns:
        Nothing lol.

    """

    
    return self.model.evaluate( *args, **kwargs)
def fit(self, *args, **kwargs)

fit. Literally use this as you'd use the normal keras fit.

Returns

Nothing lol.

Expand source code
def fit(self, *args, **kwargs):
    
    """fit. Literally use this as you'd use the normal keras fit.

    Returns:
        Nothing lol.

    """

    
    self.model.fit(*args, **kwargs)
    preds = self.model.predict(args[0])
    if self.one_hot == False:
        args = list(args)
        max_val = tf.reduce_max(args[1])
        max_val = tf.cast(max_val + 1, tf.int32)
        onehot = tf.one_hot(args[1], max_val)
        args[1] = onehot
        args = tuple(args)
    preds = preds.reshape(args[1].shape)
    errors = ((args[1] - preds)**2)**.5
    new_args = list(args)
    new_args[1] = tf.reshape(errors, args[1].shape)
    new_args = tuple(new_args)
    self.std_model.fit(*new_args, **kwargs)
def predict(self, *args, return_std=True, **kwargs)

predict. Literally use this as you'd use the normal keras predict.

Args

return_std
checks if you would even like the std.

Returns

a mean and variance, for each input.

Expand source code
def predict(self, *args, return_std = True, **kwargs):
    
    """predict. Literally use this as you'd use the normal keras predict.
    Args:
        return_std: checks if you would even like the std.
        
    Returns:
        a mean and variance, for each input.

    """        
    
    mean_preds = self.model.predict(*args, **kwargs)
    std_preds = self.std_model.predict(*args, **kwargs)
    mean_preds = tf.expand_dims(mean_preds, 1)
    std_preds = (tf.expand_dims(std_preds, 1) * self.error_norm)

    if not return_std:
        return np.mean(tf.stack(predictions), 0)
    return tf.concat([mean_preds, std_preds], axis = 1)