view pylearn/formulas/activations.py @ 1382:00116be92710

First try to use numpy documentation syntax.
author Frederic Bastien <nouiz@nouiz.org>
date Wed, 08 Dec 2010 14:30:13 -0500
parents f21693eecec7
children
line wrap: on
line source

"""
Activation function for artificial neural units. 

"""

__authors__   = "Razvan Pascanu, .."
__copyright__ = "(c) 2010, Universite de Montreal"
__license__   = "3-clause BSD License"
__contact__   = "Razvan Pascanu <r.pascanu@gmail.com>"

import theano
from theano import tensor

import tags



@tags.tags('activation', 'unary',
           'sigmoid', 'logistic',
           'non-negative', 'increasing')
def sigmoid(x):
    """
    Return a symbolic variable representing the sigmoid (logistic)
    function of the input x.

    .. math::

        \\textrm{sigmoid}(x) = \\frac{1}{1 + e^x}

    The image of :math:`\\textrm{sigmoid}(x)` is the open interval (0,
    1), *in theory*. *In practice*, due to rounding errors in floating
    point representations, :math:`\\textrm{sigmoid}(x)` will lie in the
    closed range [0, 1].

    Parameters
    ----------
    x : tensor-like
        A Theano variable with type theano.Tensor, or a value that can be 
        converted to one :math:`\in \mathbb{R}^n`

    Returns
    -------
    ret : a Theano variable with the same shape as the input
        where the sigmoid function is mapped to each element of the 
        input `x`.

    """
    return theano.tensor.nnet.sigmoid(x)



@tags.tags('activation', 'unary',
           'tanh', 'hyperbolic tangent',
           'odd', 'increasing')
def tanh(x):
    """
    Return a symbolic variable representing the tanh (hyperbolic
    tangent) of the input x.

    .. math::

        \\textrm{tanh}(x) = \\frac{e^{2x} - 1}{e^{2x} + 1}

    The image of :math:`\\textrm{tanh}(x)` is the open interval (-1,
    1), *in theory*. *In practice*, due to rounding errors in floating
    point representations, :math:`\\textrm{tanh}(x)` will lie in the
    closed range [-1, 1].

    Parameters
    ----------
    x : tensor-like
        A Theano variable with type theano.Tensor, or a value that can be 
        converted to one :math:`\in \mathbb{R}^n`

    Returns
    -------
    ret : a Theano variable with the same shape as the input
        where the tanh function is mapped to each element of the input `x`.
    """
    return theano.tensor.tanh(x)



@tags.tags('activation', 'unary',
           'tanh', 'hyperbolic tangent', 'normalized',
           'odd', 'increasing')
def tanh_normalized(x):
    """
    Return a symbolic variable representing a normalized tanh
    (hyperbolic tangent) of the input x.
    TODO: where does 1.759 come from? why is it normalized like that?

    .. math::

        \\textrm{tanh\_normalized}(x) = 1.759\\textrm{ tanh}\left(\\frac{2x}{3}\\right)

    The image of :math:`\\textrm{tanh\_normalized}(x)` is the open
    interval (-1.759, 1.759), *in theory*. *In practice*, due to
    rounding errors in floating point representations,
    :math:`\\textrm{tanh\_normalized}(x)` will lie in the approximative
    closed range [-1.759, 1.759]. The exact bound depends on the
    precision of the floating point representation.

    Parameters
    ----------
    x : tensor-like
        A Theano variable with type theano.Tensor, or a value that can be 
        converted to one :math:`\in \mathbb{R}^n`

    Returns
    -------
    ret : a Theano variable with the same shape as the input
        where the tanh_normalized function is mapped to each element of 
        the input `x`.
    """
    return 1.759*theano.tensor.tanh(0.6666*x)



@tags.tags('activation', 'unary',
           'abs_tanh', 'abs', 'tanh', 'hyperbolic tangent',
           'non-negative', 'even')
def abs_tanh(x):
    """
    Return a symbolic variable representing the absolute value of the
    hyperbolic tangent of x.

    .. math::

        \\textrm{abs\_tanh}(x) = |\\textrm{tanh}(x)|

    The image of :math:`\\textrm{abs\_tanh}(x)` is the interval [0, 1),
    *in theory*. *In practice*, due to rounding errors in floating
    point representations, :math:`\\textrm{abs\_tanh}(x)` will lie in
    the range [0, 1].

    Parameters
    ----------
    x : tensor-like
        A Theano variable with type theano.Tensor, or a value that can be 
        converted to one :math:`\in \mathbb{R}^n`

    Returns
    -------
    ret : a Theano variable with the same shape as the input
        where the abs_tanh function is mapped to each element of 
        the input `x`.
    """
    return theano.tensor.abs_(theano.tensor.tanh(x))



@tags.tags('activation', 'unary',
           'abs_tanh', 'abs', 'tanh', 'hyperbolic tangent', 'normalized',
           'non-negative', 'even')
def abs_tanh_normalized(x):
    """
    Return a symbolic variable representing the absolute value of a
    normalized tanh (hyperbolic tangent) of the input x.
    TODO: where does 1.759 come from? why is it normalized like that?

    .. math::

        \\textrm{abs\_tanh\_normalized}(x) = \left|1.759\\textrm{ tanh}\left(\\frac{2x}{3}\\right)\\right|

    The image of :math:`\\textrm{abs\_tanh\_normalized}(x)` is the range
    [0, 1.759), *in theory*. *In practice*, due to rounding errors in
    floating point representations,
    :math:`\\textrm{abs\_tanh\_normalized}(x)` will lie in the
    approximative closed range [0, 1.759]. The exact upper bound
    depends on the precision of the floating point representation.

    Parameters
    ----------
    x: tensor-like
        A Theano variable with type theano.Tensor, or a value that can be 
        converted to one :math:`\in \mathbb{R}^n`

    Returns
    -------
    ret: a Theano variable with the same shape as the input
        where the abs_tanh_normalized function is mapped to each
        element of the input `x`.
    """
    return theano.tensor.abs_(1.759*theano.tensor.tanh(0.6666*x))



@tags.tags('activation','softsign')
def softsign_act(input):
    """
    Returns a symbolic variable that computes the softsign of ``input``.
    
    .. math::

                f(input) = \\frac{input}{1.0 + |input|}

    Parameters
    ----------
    input : tensor-like
        A Theano variable with type theano.Tensor, or a value that can be 
        converted to one :math:`\in \mathbb{R}^n`

    Returns
    -------
    ret : a Theano variable with the same shape as the input
        where the softsign function is mapped to each
        element of the input `x`.
    """
    return input/(1.0 + tensor.abs_(input))

@tags.tags('activation','softsign','abs')
def abssoftsign_act(input):
    """
    Returns a symbolic variable that computes the absolute value of the
    softsign function on the input tensor ``input``.

    .. math::
                f(input) = \left| \\frac{input}{1.0 +|input|} \\right|

    Parameters
    ----------
    input : tensor-like
        A Theano variable with type theano.Tensor, or a value that can be 
        converted to one :math:`\in \mathbb{R}^n`

    Returns
    -------
    ret : a Theano variable with the same shape as the input
        where the absolute value of the softsign function is mapped to each
        element of the input `x`.
    """
    return tensor.abs_(input)/(1.0 + tensor.abs_(input))


@tags.tags('activation','rectifier')
def rectifier_act(input):
    """
    Returns a symbolic variable that computes the value of the ``input`` if
    and only if it is positive, 0 otherwise.

    .. math::

                f(input) = \left \lbrace \\begin{array}{l}
                            input \quad \\text{ if } input > 0 \\
                            0     \quad \\text{ else }
                         \end{array}
                         \\right \}

    Parameters
    ----------
    input : tensor-like
        A Theano variable with type theano.Tensor, or a value that can be 
        converted to one :math:`\in \mathbb{R}^n`

    Returns
    -------
    ret : a Theano variable with the same shape as the input
        A tensor always positive whose element equals the inputs if it is also 
        positive or to 0 otherwise
    """
    return input*(input>=0)

@tags.tags('activation','softplus')
def softplus_act(input):
    """
    Returns a symbolic variable that computes the softplus of ``input``.
    Note : (TODO) rescale in order to have a steady state regime close to 0 
           at initialization.

    .. math::

                f(input) = ln \left( 1 + e^{input} \\right)

    Parameters
    ----------
    input : tensor-like
        A Theano variable with type theano.Tensor, or a value that can be 
        converted to one :math:`\in \mathbb{R}^n`

    Returns
    -------
    ret : a Theano variable with the same shape as the input
        where the softsign function is mapped to each
        element of the input `x`.
    """
    return tensor.nnet.softplus(input)

@tags.tags('activation','abs')
def abs_act(input):
    """
    Returns the symbolic variable that represents the absolute value of
    ``input``.

    .. math::

                f(input) = |input|

    Parameters
    ----------
    input : tensor-like
        A Theano variable with type theano.Tensor, or a value that can be 
        converted to one :math:`\in \mathbb{R}^n`

    Returns
    -------
    ret : a Theano variable with the same shape as the input
        where the absolute function is mapped to each
        element of the input `x`.
     """
    return theano.tensor.abs_(input)