Beispiel #1
0
def reproducible_network_train(seed=0, epochs=500, **additional_params):
    """
    Make a reproducible train for Gradient Descent based neural
    network with a XOR problem and return trained network.

    Parameters
    ----------
    seed : int
        Random State seed number for reproducibility. Defaults to ``0``.
    epochs : int
        Number of epochs for training. Defaults to ``500``.
    **additional_params
        Aditional parameters for Neural Network.

    Returns
    -------
    GradientDescent instance
        Returns trained network.
    """
    environment.reproducible(seed)

    xavier_normal = init.XavierNormal()
    tanh_weight1 = xavier_normal.sample((2, 5), return_array=True)
    tanh_weight2 = xavier_normal.sample((5, 1), return_array=True)

    network = algorithms.GradientDescent(connection=[
        layers.Input(2),
        layers.Tanh(5, weight=tanh_weight1),
        layers.Tanh(1, weight=tanh_weight2),
    ],
                                         batch_size='all',
                                         **additional_params)
    network.train(xor_input_train, xor_target_train, epochs=epochs)
    return network
Beispiel #2
0
    def test_full_batch_training(self):
        fullbatch_identifiers = BatchSizeProperty.fullbatch_identifiers
        x_train, _, y_train, _ = simple_classification()

        xavier_normal = init.XavierNormal()
        weight1 = xavier_normal.sample((10, 20), return_array=True)
        weight2 = xavier_normal.sample((20, 1), return_array=True)

        for network_class in self.network_classes:
            errors = []

            for fullbatch_value in fullbatch_identifiers:
                net = network_class(
                    [
                        layers.Input(10),
                        layers.Sigmoid(20, weight=weight1),
                        layers.Sigmoid(1, weight=weight2),
                    ],
                    batch_size=fullbatch_value,
                )
                net.train(x_train, y_train, epochs=10)

                errors.append(net.errors.last())

            self.assertTrue(
                np.all(np.abs(errors - errors[0]) < 1e-3),
                msg=errors,
            )
Beispiel #3
0
class Relu(ActivationLayer):
    """
    The layer with the rectifier (ReLu) activation function.

    Parameters
    ----------
    alpha : float
        Alpha parameter defines the decreasing rate
        for the negative values. If ``alpha``
        is non-zero value then layer behave like a
        leaky ReLu. Defaults to ``0``.

    {ActivationLayer.Parameters}

    Methods
    -------
    {ActivationLayer.Methods}

    Attributes
    ----------
    {ActivationLayer.Attributes}
    """
    alpha = NumberProperty(default=0, minval=0)
    weight = ParameterProperty(default=init.XavierNormal(gain='relu'))

    def activation_function(self, input_value):
        alpha = asfloat(self.alpha)
        return T.nnet.relu(input_value, alpha)
Beispiel #4
0
    def test_xavier_normal(self):
        n_inputs, n_outputs = 30, 30

        xavier_normal = init.XavierNormal()
        weight = self.eval(xavier_normal.sample((n_inputs, n_outputs)))

        self.assertNormalyDistributed(weight)
        self.assertAlmostEqual(weight.mean(), 0, places=1)
        self.assertAlmostEqual(weight.std(),
                               math.sqrt(1. / (n_inputs + n_outputs)),
                               places=2)
Beispiel #5
0
    def assertCanNetworkOverfit(self,
                                network_class,
                                epochs=100,
                                min_accepted_loss=0.001):

        x_train = 2 * np.random.random((10, 2)) - 1  # zero centered
        y_train = np.random.random((10, 1))

        relu_xavier_normal = init.XavierNormal(gain=4)
        relu_weight = relu_xavier_normal.sample((2, 20), return_array=True)

        xavier_normal = init.XavierNormal(gain=2)
        sigmoid_weight = xavier_normal.sample((20, 1), return_array=True)

        optimizer = network_class([
            layers.Input(2),
            layers.Relu(20, weight=relu_weight),
            layers.Sigmoid(1, weight=sigmoid_weight),
        ])

        optimizer.train(x_train, y_train, epochs=epochs)
        self.assertLess(optimizer.errors.train[-1], min_accepted_loss)
Beispiel #6
0
class RBM(BaseAlgorithm, BaseNetwork, MinibatchTrainingMixin):
    """
    Boolean/Bernoulli Restricted Boltzmann Machine (RBM).
    Algorithm assumes that inputs are either binary
    values or values between 0 and 1.

    Parameters
    ----------
    n_visible : int
        Number of visible units.

    n_hidden : int
        Number of hidden units.

    {MinibatchTrainingMixin.batch_size}

    weight : array-like, Theano variable, Initializer or scalar
        Default initialization methods
        you can find :ref:`here <init-methods>`.
        Defaults to :class:`XavierNormal <neupy.init.XavierNormal>`.

    hidden_bias : array-like, Theano variable, Initializer or scalar
        Default initialization methods
        you can find :ref:`here <init-methods>`.
        Defaults to :class:`Constant(value=0) <neupy.init.Constant>`.

    visible_bias : array-like, Theano variable, Initializer or scalar
        Default initialization methods
        you can find :ref:`here <init-methods>`.
        Defaults to :class:`Constant(value=0) <neupy.init.Constant>`.

    {BaseNetwork.Parameters}

    Methods
    -------
    train(input_train, epochs=100)
        Trains network.

    {BaseSkeleton.fit}

    visible_to_hidden(visible_input)
        Populates data throught the network and returns output
        from the hidden layer.

    hidden_to_visible(hidden_input)
        Propagates output from the hidden layer backward
        to the visible.

    gibbs_sampling(visible_input, n_iter=1)
        Makes Gibbs sampling ``n`` times using visible input.

    Examples
    --------
    >>> import numpy as np
    >>> from neupy import algorithms
    >>>
    >>> data = np.array([
    ...     [1, 0, 1, 0],
    ...     [1, 0, 1, 0],
    ...     [1, 0, 0, 0],  # incomplete sample
    ...     [1, 0, 1, 0],
    ...
    ...     [0, 1, 0, 1],
    ...     [0, 0, 0, 1],  # incomplete sample
    ...     [0, 1, 0, 1],
    ...     [0, 1, 0, 1],
    ...     [0, 1, 0, 1],
    ...     [0, 1, 0, 1],
    ... ])
    >>>
    >>> rbm = algorithms.RBM(n_visible=4, n_hidden=1)
    >>> rbm.train(data, epochs=100)
    >>>
    >>> hidden_states = rbm.visible_to_hidden(data)
    >>> hidden_states.round(2)
    array([[ 0.99],
           [ 0.99],
           [ 0.95],
           [ 0.99],
           [ 0.  ],
           [ 0.01],
           [ 0.  ],
           [ 0.  ],
           [ 0.  ],
           [ 0.  ]])

    References
    ----------
    [1] G. Hinton, A Practical Guide to Training Restricted
        Boltzmann Machines, 2010.
        http://www.cs.toronto.edu/~hinton/absps/guideTR.pdf
    """
    n_visible = IntProperty(minval=1)
    n_hidden = IntProperty(minval=1)

    weight = ParameterProperty(default=init.XavierNormal())
    hidden_bias = ParameterProperty(default=init.Constant(value=0))
    visible_bias = ParameterProperty(default=init.Constant(value=0))

    def __init__(self, n_visible, n_hidden, **options):
        self.theano_random = theano_random_stream()

        super(ConfigurableABC, self).__init__(n_hidden=n_hidden,
                                              n_visible=n_visible,
                                              **options)

        self.weight = create_shared_parameter(value=self.weight,
                                              name='algo:rbm/matrix:weight',
                                              shape=(n_visible, n_hidden))
        self.hidden_bias = create_shared_parameter(
            value=self.hidden_bias,
            name='algo:rbm/vector:hidden-bias',
            shape=(n_hidden, ),
        )
        self.visible_bias = create_shared_parameter(
            value=self.visible_bias,
            name='algo:rbm/vector:visible-bias',
            shape=(n_visible, ),
        )

        super(RBM, self).__init__(**options)

    def init_input_output_variables(self):
        self.variables.update(
            network_input=T.matrix(name='algo:rbm/var:network-input'), )

    def init_variables(self):
        self.variables.update(h_samples=theano.shared(
            name='algo:rbm/matrix:hidden-samples',
            value=asint(np.zeros((self.batch_size, self.n_hidden))),
        ), )

    def init_methods(self):
        def free_energy(visible_sample):
            wx_b = T.dot(visible_sample, self.weight) + self.hidden_bias
            visible_bias_term = T.dot(visible_sample, self.visible_bias)
            hidden_term = T.log(asfloat(1) + T.exp(wx_b)).sum(axis=1)
            return -visible_bias_term - hidden_term

        def visible_to_hidden(visible_sample):
            wx_b = T.dot(visible_sample, self.weight) + self.hidden_bias
            return T.nnet.sigmoid(wx_b)

        def hidden_to_visible(hidden_sample):
            wx_b = T.dot(hidden_sample, self.weight.T) + self.visible_bias
            return T.nnet.sigmoid(wx_b)

        def sample_hidden_from_visible(visible_sample):
            theano_random = self.theano_random
            hidden_prob = visible_to_hidden(visible_sample)
            hidden_sample = theano_random.binomial(n=1,
                                                   p=hidden_prob,
                                                   dtype=theano.config.floatX)
            return hidden_sample

        def sample_visible_from_hidden(hidden_sample):
            theano_random = self.theano_random
            visible_prob = hidden_to_visible(hidden_sample)
            visible_sample = theano_random.binomial(n=1,
                                                    p=visible_prob,
                                                    dtype=theano.config.floatX)
            return visible_sample

        network_input = self.variables.network_input
        n_samples = asfloat(network_input.shape[0])
        theano_random = self.theano_random

        weight = self.weight
        h_bias = self.hidden_bias
        v_bias = self.visible_bias
        h_samples = self.variables.h_samples
        step = asfloat(self.step)

        sample_indeces = theano_random.random_integers(
            low=0, high=n_samples - 1, size=(self.batch_size, ))
        v_pos = ifelse(
            T.eq(n_samples, self.batch_size),
            network_input,
            # In case if final batch has less number of
            # samples then expected
            network_input[sample_indeces])
        h_pos = visible_to_hidden(v_pos)

        v_neg = sample_visible_from_hidden(h_samples)
        h_neg = visible_to_hidden(v_neg)

        weight_update = v_pos.T.dot(h_pos) - v_neg.T.dot(h_neg)
        h_bias_update = (h_pos - h_neg).mean(axis=0)
        v_bias_update = (v_pos - v_neg).mean(axis=0)

        # Stochastic pseudo-likelihood
        feature_index_to_flip = theano_random.random_integers(
            low=0,
            high=self.n_visible - 1,
        )
        rounded_input = T.round(network_input)
        rounded_input = network_input
        rounded_input_flip = T.set_subtensor(
            rounded_input[:, feature_index_to_flip],
            1 - rounded_input[:, feature_index_to_flip])
        error = T.mean(self.n_visible * T.log(
            T.nnet.sigmoid(
                free_energy(rounded_input_flip) - free_energy(rounded_input))))

        self.methods.update(train_epoch=theano.function(
            [network_input],
            error,
            name='algo:rbm/func:train-epoch',
            updates=[
                (weight, weight + step * weight_update / n_samples),
                (h_bias, h_bias + step * h_bias_update),
                (v_bias, v_bias + step * v_bias_update),
                (h_samples, asint(theano_random.binomial(n=1, p=h_neg))),
            ]),
                            prediction_error=theano.function(
                                [network_input],
                                error,
                                name='algo:rbm/func:prediction-error',
                            ),
                            visible_to_hidden=theano.function(
                                [network_input],
                                visible_to_hidden(network_input),
                                name='algo:rbm/func:visible-to-hidden',
                            ),
                            hidden_to_visible=theano.function(
                                [network_input],
                                hidden_to_visible(network_input),
                                name='algo:rbm/func:hidden-to-visible',
                            ),
                            gibbs_sampling=theano.function(
                                [network_input],
                                sample_visible_from_hidden(
                                    sample_hidden_from_visible(network_input)),
                                name='algo:rbm/func:gibbs-sampling',
                            ))

    def train(self, input_train, input_test=None, epochs=100, summary='table'):
        """
        Train RBM.

        Parameters
        ----------
        input_train : 1D or 2D array-like
        input_test : 1D or 2D array-like or None
            Defaults to ``None``.
        epochs : int
            Number of training epochs. Defaults to ``100``.
        summary : {'table', 'inline'}
            Training summary type. Defaults to ``'table'``.
        """
        return super(RBM, self).train(input_train=input_train,
                                      target_train=None,
                                      input_test=input_test,
                                      target_test=None,
                                      epochs=epochs,
                                      epsilon=None,
                                      summary=summary)

    def train_epoch(self, input_train, target_train=None):
        """
        Train one epoch.

        Parameters
        ----------
        input_train : array-like (n_samples, n_features)

        Returns
        -------
        float
        """
        errors = self.apply_batches(
            function=self.methods.train_epoch,
            input_data=input_train,
            description='Training batches',
            show_error_output=True,
        )

        n_samples = len(input_train)
        return average_batch_errors(errors, n_samples, self.batch_size)

    def visible_to_hidden(self, visible_input):
        """
        Populates data throught the network and returns output
        from the hidden layer.

        Parameters
        ----------
        visible_input : array-like (n_samples, n_visible_features)

        Returns
        -------
        array-like
        """
        is_input_feature1d = (self.n_visible == 1)
        visible_input = format_data(visible_input, is_input_feature1d)

        outputs = self.apply_batches(function=self.methods.visible_to_hidden,
                                     input_data=visible_input,
                                     description='Hidden from visible batches',
                                     show_progressbar=True,
                                     show_error_output=False)

        return np.concatenate(outputs, axis=0)

    def hidden_to_visible(self, hidden_input):
        """
        Propagates output from the hidden layer backward
        to the visible.

        Parameters
        ----------
        hidden_input : array-like (n_samples, n_hidden_features)

        Returns
        -------
        array-like
        """
        is_input_feature1d = (self.n_hidden == 1)
        hidden_input = format_data(hidden_input, is_input_feature1d)

        outputs = self.apply_batches(function=self.methods.hidden_to_visible,
                                     input_data=hidden_input,
                                     description='Visible from hidden batches',
                                     show_progressbar=True,
                                     show_error_output=False)

        return np.concatenate(outputs, axis=0)

    def prediction_error(self, input_data, target_data=None):
        """
        Compute the pseudo-likelihood of input samples.

        Parameters
        ----------
        input_data : array-like
            Values of the visible layer

        Returns
        -------
        float
            Value of the pseudo-likelihood.
        """
        is_input_feature1d = (self.n_visible == 1)
        input_data = format_data(input_data, is_input_feature1d)

        errors = self.apply_batches(
            function=self.methods.prediction_error,
            input_data=input_data,
            description='Validation batches',
            show_error_output=True,
        )
        return average_batch_errors(errors,
                                    n_samples=len(input_data),
                                    batch_size=self.batch_size)

    def gibbs_sampling(self, visible_input, n_iter=1):
        """
        Makes Gibbs sampling n times using visible input.

        Parameters
        ----------
        visible_input : 1d or 2d array
        n_iter : int
            Number of Gibbs sampling iterations. Defaults to ``1``.

        Returns
        -------
        array-like
            Output from the visible units after perfoming n
            Gibbs samples. Array will contain only binary
            units (0 and 1).
        """
        is_input_feature1d = (self.n_visible == 1)
        visible_input = format_data(visible_input, is_input_feature1d)

        gibbs_sampling = self.methods.gibbs_sampling

        input_ = visible_input
        for iteration in range(n_iter):
            input_ = gibbs_sampling(input_)

        return input_
Beispiel #7
0
class ParameterBasedLayer(BaseLayer):
    """
    Layer that creates weight and bias parameters.

    Parameters
    ----------
    size : int
        Layer's output size.

    weight : array-like, Theano variable, scalar or Initializer
        Defines layer's weights. Default initialization methods
        you can find :ref:`here <init-methods>`.
        Defaults to :class:`XavierNormal() <neupy.init.XavierNormal>`.

    bias : 1D array-like, Theano variable, scalar, Initializer or None
        Defines layer's bias.
        Default initialization methods you can find
        :ref:`here <init-methods>`. Defaults to
        :class:`Constant(0) <neupy.init.Constant>`.
        The ``None`` value excludes bias from the calculations and
        do not add it into parameters list.

    {BaseLayer.Parameters}

    Methods
    -------
    {BaseLayer.Methods}

    Attributes
    ----------
    {BaseLayer.Attributes}
    """
    size = IntProperty(minval=1)
    weight = ParameterProperty(default=init.XavierNormal())
    bias = ParameterProperty(default=init.Constant(value=0), allow_none=True)

    def __init__(self, size, **options):
        super(ParameterBasedLayer, self).__init__(size=size, **options)

    @property
    def weight_shape(self):
        return as_tuple(self.input_shape, self.output_shape)

    @property
    def bias_shape(self):
        if self.bias is not None:
            return as_tuple(self.output_shape)

    def initialize(self):
        super(ParameterBasedLayer, self).initialize()

        self.add_parameter(value=self.weight, name='weight',
                           shape=self.weight_shape, trainable=True)

        if self.bias is not None:
            self.add_parameter(value=self.bias, name='bias',
                               shape=self.bias_shape, trainable=True)

    def __repr__(self):
        classname = self.__class__.__name__
        return '{name}({size})'.format(name=classname, size=self.size)
Beispiel #8
0
class Oja(BaseNetwork):
    """
    Oja is an unsupervised technique used for the
    dimensionality reduction tasks.

    Notes
    -----
    - In practice use step as very small value.
      For instance, value ``1e-7`` can be a good choice.

    - Normalize the input data before use Oja algorithm.
      Input data shouldn't contains large values.

    - Set up smaller values for weight if error for a few
      first iterations is big compare to the input values scale.
      For instance, if your input data have values between
      ``0`` and ``1`` error value equal to ``100`` is big.

    - During the training network report mean absolute error (MAE)

    Parameters
    ----------
    minimized_data_size : int
        Expected number of features after minimization,
        defaults to ``1``.

    weight : array-like or ``None``
        Defines networks weights.
        Defaults to :class:`XavierNormal() <neupy.init.XavierNormal>`.

    {BaseNetwork.Parameters}

    Methods
    -------
    reconstruct(X)
        Reconstruct original dataset from the minimized input.

    train(X, epochs=100)
        Trains the network to the data X. Network trains until maximum
        number of ``epochs`` was reached.

    predict(X)
        Returns hidden representation of the input data ``X``. Basically,
        it applies dimensionality reduction.

    {BaseSkeleton.fit}

    Examples
    --------
    >>> import numpy as np
    >>> from neupy import algorithms
    >>>
    >>> data = np.array([[2, 2], [1, 1], [4, 4], [5, 5]])
    >>>
    >>> ojanet = algorithms.Oja(
    ...     minimized_data_size=1,
    ...     step=0.01,
    ...     verbose=False
    ... )
    >>>
    >>> ojanet.train(data, epochs=100)
    >>> minimized = ojanet.predict(data)
    >>> minimized
    array([[-2.82843122],
           [-1.41421561],
           [-5.65686243],
           [-7.07107804]])
    >>> ojanet.reconstruct(minimized)
    array([[ 2.00000046,  2.00000046],
           [ 1.00000023,  1.00000023],
           [ 4.00000093,  4.00000093],
           [ 5.00000116,  5.00000116]])
    """
    minimized_data_size = IntProperty(minval=1)
    weight = ParameterProperty(default=init.XavierNormal())

    def one_training_update(self, X, y_train):
        weight = self.weight

        minimized = np.dot(X, weight)
        reconstruct = np.dot(minimized, weight.T)
        error = X - reconstruct

        weight += self.step * np.dot(error.T, minimized)
        mae = np.sum(np.abs(error)) / X.size

        # Clean objects from the memory
        del minimized
        del reconstruct
        del error

        return mae

    def train(self, X, epochs=100):
        X = format_data(X)
        n_input_features = X.shape[1]

        if isinstance(self.weight, init.Initializer):
            weight_shape = (n_input_features, self.minimized_data_size)
            self.weight = self.weight.sample(weight_shape, return_array=True)

        if n_input_features != self.weight.shape[0]:
            raise ValueError("Invalid number of features. Expected {}, got {}"
                             "".format(self.weight.shape[0], n_input_features))

        super(Oja, self).train(X, epochs=epochs)

    def reconstruct(self, X):
        if not isinstance(self.weight, np.ndarray):
            raise NotTrained("Network hasn't been trained yet")

        X = format_data(X)
        if X.shape[1] != self.minimized_data_size:
            raise ValueError("Invalid input data feature space, expected "
                             "{}, got {}.".format(X.shape[1],
                                                  self.minimized_data_size))

        return np.dot(X, self.weight.T)

    def predict(self, X):
        if not isinstance(self.weight, np.ndarray):
            raise NotTrained("Network hasn't been trained yet")

        X = format_data(X)
        return np.dot(X, self.weight)
Beispiel #9
0
class Oja(UnsupervisedLearningMixin, BaseNetwork):
    """
    Oja unsupervised algorithm that minimize input data feature
    space.

    Notes
    -----
    * In practice use step as very small value. For example ``1e-7``.
    * Normalize the input data before use Oja algorithm. Input data \
    shouldn't contains large values.
    * Set up smaller values for weight if error for a few first iterations \
    is big compare to the input values scale. For example, if your input \
    data have values between 0 and 1 error value equal to 100 is big.

    Parameters
    ----------
    minimized_data_size : int
        Expected number of features after minimization, defaults to ``1``
    weight : array-like or ``None``
        Defines networks weights.
        Defaults to :class:`XavierNormal() <neupy.core.init.XavierNormal>`.
    {BaseNetwork.step}
    {BaseNetwork.show_epoch}
    {BaseNetwork.epoch_end_signal}
    {BaseNetwork.train_end_signal}
    {Verbose.verbose}

    Methods
    -------
    reconstruct(input_data):
        Reconstruct your minimized data.
    {BaseSkeleton.predict}
    {UnsupervisedLearningMixin.train}
    {BaseSkeleton.fit}

    Raises
    ------
    ValueError
        * Try reconstruct without training.
        * Invalid number of input data features for ``train`` and \
        ``reconstruct`` methods.

    Examples
    --------
    >>> import numpy as np
    >>> from neupy import algorithms
    >>>
    >>> data = np.array([[2, 2], [1, 1], [4, 4], [5, 5]])
    >>>
    >>> ojanet = algorithms.Oja(
    ...     minimized_data_size=1,
    ...     step=0.01,
    ...     verbose=False
    ... )
    >>>
    >>> ojanet.train(data, epsilon=1e-5)
    >>> minimized = ojanet.predict(data)
    >>> minimized
    array([[-2.82843122],
           [-1.41421561],
           [-5.65686243],
           [-7.07107804]])
    >>> ojanet.reconstruct(minimized)
    array([[ 2.00000046,  2.00000046],
           [ 1.00000023,  1.00000023],
           [ 4.00000093,  4.00000093],
           [ 5.00000116,  5.00000116]])
    """
    minimized_data_size = IntProperty(minval=1)
    weight = ParameterProperty(default=init.XavierNormal())

    def init_properties(self):
        del self.shuffle_data
        super(Oja, self).init_properties()

    def train_epoch(self, input_data, target_train):
        weight = self.weight

        minimized = np.dot(input_data, weight)
        reconstruct = np.dot(minimized, weight.T)
        error = input_data - reconstruct

        weight += self.step * np.dot(error.T, minimized)

        mae = np.sum(np.abs(error)) / input_data.size

        # Clear memory
        del minimized
        del reconstruct
        del error

        return mae

    def train(self, input_data, epsilon=1e-2, epochs=100):
        input_data = format_data(input_data)
        n_input_features = input_data.shape[1]

        if isinstance(self.weight, init.Initializer):
            weight_shape = (n_input_features, self.minimized_data_size)
            self.weight = self.weight.sample(weight_shape)

        if n_input_features != self.weight.shape[0]:
            raise ValueError(
                "Invalid number of features. Expected {}, got {}".format(
                    self.weight.shape[0],
                    n_input_features
                )
            )

        super(Oja, self).train(input_data, epsilon=epsilon, epochs=epochs)

    def reconstruct(self, input_data):
        if not isinstance(self.weight, np.ndarray):
            raise NotTrainedException("Train network before use "
                                      "reconstruct method.")

        input_data = format_data(input_data)
        if input_data.shape[1] != self.minimized_data_size:
            raise ValueError(
                "Invalid input data feature space, expected "
                "{}, got {}.".format(
                    input_data.shape[1],
                    self.minimized_data_size
                )
            )

        return np.dot(input_data, self.weight.T)

    def predict(self, input_data):
        if not isinstance(self.weight, np.ndarray):
            raise NotTrainedException("Train network before use "
                                      "prediction method.")

        input_data = format_data(input_data)
        return np.dot(input_data, self.weight)
Beispiel #10
0
    def test_prelu_alpha_init_random_params(self):
        prelu_layer = layers.PRelu(10, alpha=init.XavierNormal())
        prelu_layer.create_variables((None, 5))

        alpha = self.eval(prelu_layer.alpha)
        self.assertEqual(10, np.unique(alpha).size)
Beispiel #11
0
    def test_prelu_random_params(self):
        prelu_layer = layers.PRelu(10, alpha=init.XavierNormal())
        layers.Input(10) > prelu_layer

        alpha = self.eval(prelu_layer.alpha)
        self.assertEqual(10, np.unique(alpha).size)
class Oja(BaseNetwork):
    """
    Oja is an unsupervised technique used for the
    dimensionality reduction tasks.

    Notes
    -----
    - In practice use step as very small value.
      For instance, value ``1e-7`` can be a good choice.

    - Normalize the input data before use Oja algorithm.
      Input data shouldn't contains large values.

    - Set up smaller values for weight if error for a few
      first iterations is big compare to the input values scale.
      For instance, if your input data have values between
      ``0`` and ``1`` error value equal to ``100`` is big.

    Parameters
    ----------
    minimized_data_size : int
        Expected number of features after minimization,
        defaults to ``1``.

    weight : array-like or ``None``
        Defines networks weights.
        Defaults to :class:`XavierNormal() <neupy.init.XavierNormal>`.

    {BaseNetwork.step}

    {BaseNetwork.show_epoch}

    {BaseNetwork.epoch_end_signal}

    {BaseNetwork.train_end_signal}

    {Verbose.verbose}

    Methods
    -------
    reconstruct(input_data)
        Reconstruct original dataset from the minimized input.

    train(input_data, epsilon=1e-2, epochs=100)
        Trains algorithm based on the input dataset.
        For the dimensionality reduction input dataset
        assumes to be also a target.

    {BaseSkeleton.predict}

    {BaseSkeleton.fit}

    Raises
    ------
    ValueError
        - Triggers when you try to reconstruct output
          without training.

        - Invalid number of input data features for the
          ``train`` and ``reconstruct`` methods.

    Examples
    --------
    >>> import numpy as np
    >>> from neupy import algorithms
    >>>
    >>> data = np.array([[2, 2], [1, 1], [4, 4], [5, 5]])
    >>>
    >>> ojanet = algorithms.Oja(
    ...     minimized_data_size=1,
    ...     step=0.01,
    ...     verbose=False
    ... )
    >>>
    >>> ojanet.train(data, epsilon=1e-5)
    >>> minimized = ojanet.predict(data)
    >>> minimized
    array([[-2.82843122],
           [-1.41421561],
           [-5.65686243],
           [-7.07107804]])
    >>> ojanet.reconstruct(minimized)
    array([[ 2.00000046,  2.00000046],
           [ 1.00000023,  1.00000023],
           [ 4.00000093,  4.00000093],
           [ 5.00000116,  5.00000116]])
    """
    minimized_data_size = IntProperty(minval=1)
    weight = ParameterProperty(default=init.XavierNormal())

    def train_epoch(self, input_data, target_train):
        weight = self.weight

        minimized = np.dot(input_data, weight)
        reconstruct = np.dot(minimized, weight.T)
        error = input_data - reconstruct

        weight += self.step * np.dot(error.T, minimized)

        mae = np.sum(np.abs(error)) / input_data.size

        # Clean objects from the memory
        del minimized
        del reconstruct
        del error

        return mae

    def train(self, input_data, epsilon=1e-2, epochs=100):
        input_data = format_data(input_data)
        n_input_features = input_data.shape[1]

        if isinstance(self.weight, init.Initializer):
            weight_shape = (n_input_features, self.minimized_data_size)
            self.weight = self.weight.sample(weight_shape)

        if n_input_features != self.weight.shape[0]:
            raise ValueError(
                "Invalid number of features. Expected {}, got {}".format(
                    self.weight.shape[0], n_input_features))

        super(Oja, self).train(input_data, epsilon=epsilon, epochs=epochs)

    def reconstruct(self, input_data):
        if not isinstance(self.weight, np.ndarray):
            raise NotTrained("Network hasn't been trained yet")

        input_data = format_data(input_data)
        if input_data.shape[1] != self.minimized_data_size:
            raise ValueError("Invalid input data feature space, expected "
                             "{}, got {}.".format(input_data.shape[1],
                                                  self.minimized_data_size))

        return np.dot(input_data, self.weight.T)

    def predict(self, input_data):
        if not isinstance(self.weight, np.ndarray):
            raise NotTrained("Network hasn't been trained yet")

        input_data = format_data(input_data)
        return np.dot(input_data, self.weight)