""" numpynet_common Contains common code shared across different modules @author: Chronocook (chronocook@gmail.com) """ import numpy as np from numpynet.loggit import log class Activation: """ A class to hold all of the activation functions, ensures all have derivatives """ function = None available = ["tanh", "tanhpos", "sigmoid", "relu", "softplus", "leakyrelu"] def __init__(self, choice="sigmoid"): """ :param choice: Which activation function you want, must be in self.available """ if choice not in self.available: msg = "Choice of activation (" + choice + ") not available!" log.out.error(msg) raise ValueError(msg) elif choice == "tanh": self.function = self._tanh elif choice == "tanhpos": self.function = self._tanhpos elif choice == "sigmoid": self.function = self._sigmoid elif choice == "softplus": self.function = self._softplus elif choice == "relu": self.function = self._relu elif choice == "leakyrelu": self.function = self._leakyrelu @staticmethod def _tanh(x, deriv=False): """ Hyperbolic tangent activation """ if deriv: return 1.0 - np.power(np.tanh(x), 2) return np.tanh(x) @staticmethod def _tanhpos(x, deriv=False): """ Positive hyperbolic tangent activation """ if deriv: return (1.0 - np.power(np.tanh(x), 2)) / 2.0 return (np.tanh(x) + 1.0) / 2.0 @staticmethod def _sigmoid(x, deriv=False): """ The sigmoid function and its derivative """ y = 1.0 / (1.0 + np.exp(-x)) if deriv: return y * (1.0 - y) return y @staticmethod def _softplus(x, deriv=False): """ The soft-plus function and its derivative """ y = np.log(1.0 + (np.exp(x))) if deriv: return 1.0 / (1.0 + np.exp(-x)) return y @staticmethod def _relu(x, deriv=False): """ Rectified linear unit activation function """ if deriv: return 1.0 * (x >= 0) return np.maximum(x, 0) @staticmethod def _leakyrelu(x, deriv=False): """ Rectified linear unit activation function with small value for negatives """ if deriv: return 1.0 * (x >= 0) - 0.01 * (x < 0) return np.maximum(x, 0.01 * x) def predict_2d_space(net, delta=0.05): """ Iterate predictions over a 2d space :param net: (object) A NumpyNet model object :param delta: space between predictions :return: prediction_matrix: the actual predictions axis_x and axis_y: the axes (useful for plotting) """ axis_x = np.arange(net.predict_space[0], net.predict_space[1] + delta, delta) axis_y = np.arange(net.predict_space[2], net.predict_space[3] + delta, delta) prediction_matrix = np.empty((len(axis_x), len(axis_y))) for i, x in enumerate(axis_x): for j, y in enumerate(axis_y): test_prediction = np.array([x, y]) test_prediction = net.predict(test_prediction) prediction_matrix[i, j] = test_prediction return prediction_matrix, axis_x, axis_y