<commit_before>"""
Classes representing loss functions.
Currently, these are primarily used to specify
the objective function for the SGD and BGD
training algorithms.
"""

# NOTE: As of 2013/12/2 this file is PEP8 compliant. Please keep it that way.

from itertools import izip
import warnings

import theano.tensor as T
from theano.compat.python2x import OrderedDict

from pylearn2.utils import safe_zip
from pylearn2.utils import safe_union
from pylearn2.space import CompositeSpace, NullSpace
from pylearn2.utils.data_specs import DataSpecsMapping


class DefaultDataSpecsMixin(object):
    """
    .. todo::

        WRITEME
    """
    def get_data_specs(self, model):
        """
        .. todo::

            WRITEME
        """
        if self.supervised:
            space = CompositeSpace([model.get_input_space(),
                                    model.get_output_space()])
            sources = (model.get_input_source(), model.get_target_source())
            return (space, sources)
        else:
            return (model.get_input_space(), model.get_input_source())


class NullDataSpecsMixin(object):
    """
    .. todo::

        WRITEME
    """
    def get_data_specs(self, model):
        """
        .. todo::

            WRITEME
        """
        return (NullSpace(), '')


class Cost(object):
    """
    Represents a cost that can be called either as a supervised cost or an
    unsupervised cost.
    """

    # If True, the data argument to expr and get_gradients must be a
    # (X, Y) pair, and Y cannot be None.
    supervised = False

    def expr(self, model, data, ** kwargs):
        """
        .. todo::

            WRITEME

        Parameters
        ----------
        model: a pylearn2 Model instance
        data : a batch in cost.get_data_specs() form

        Returns a symbolic expression for a cost function applied to the
        minibatch of data.
        Optionally, may return None. This represents that the cost function
        is intractable but may be optimized via the get_gradients method.

        """
        raise NotImplementedError(str(type(self)) + " does not implement "
                                  "expr.")

    def get_gradients(self, model, data, ** kwargs):
        """
        .. todo::

            WRITEME

        Parameters
        ----------
        model: a pylearn2 Model instance
        data : a batch in cost.get_data_specs() form

        returns: gradients, updates
            gradients:
                a dictionary mapping from the model's parameters
                         to their gradients
                The default implementation is to compute the gradients
                using T.grad applied to the value returned by expr.
                However, subclasses may return other values for the gradient.
                For example, an intractable cost may return a sampling-based
                approximation to its gradient.
            updates:
                a dictionary mapping shared variables to updates that must
                be applied to them each time these gradients are computed.
                This is to facilitate computation of sampling-based approximate
                gradients.
                The parameters should never appear in the updates dictionary.
                This would imply that computing their gradient changes
                their value, thus making the gradient value outdated.
        """

        try:
            cost = self.expr(model=model, data=data, **kwargs)
        except TypeError, e:
            # If anybody knows how to add type(seslf) to the exception message
            # but still preserve the stack trace, please do so
            # The current code does neither
            e.message += " while calling " + str(type(self)) + ".expr"
            print str(type(self))
            print e.message
            raise e

        if cost is None:
            raise NotImplementedError(str(type(self)) +
                                      " represents an intractable cost and "
                                      "does not provide a gradient "
                                      "approximation scheme.")

        params = list(model.get_params())

        grads = T.grad(cost, params, disconnected_inputs='ignore')

        gradients = OrderedDict(izip(params, grads))

        updates = OrderedDict()

        return gradients, updates

    def get_monitoring_channels(self, model, data, **kwargs):
        """
        .. todo::

            WRITEME<commit_msg>fixed typo<commit_after>"""
Classes representing loss functions.
Currently, these are primarily used to specify
the objective function for the SGD and BGD
training algorithms.
"""

# NOTE: As of 2013/12/2 this file is PEP8 compliant. Please keep it that way.

from itertools import izip
import warnings

import theano.tensor as T
from theano.compat.python2x import OrderedDict

from pylearn2.utils import safe_zip
from pylearn2.utils import safe_union
from pylearn2.space import CompositeSpace, NullSpace
from pylearn2.utils.data_specs import DataSpecsMapping


class DefaultDataSpecsMixin(object):
    """
    .. todo::

        WRITEME
    """
    def get_data_specs(self, model):
        """
        .. todo::

            WRITEME
        """
        if self.supervised:
            space = CompositeSpace([model.get_input_space(),
                                    model.get_output_space()])
            sources = (model.get_input_source(), model.get_target_source())
            return (space, sources)
        else:
            return (model.get_input_space(), model.get_input_source())


class NullDataSpecsMixin(object):
    """
    .. todo::

        WRITEME
    """
    def get_data_specs(self, model):
        """
        .. todo::

            WRITEME
        """
        return (NullSpace(), '')


class Cost(object):
    """
    Represents a cost that can be called either as a supervised cost or an
    unsupervised cost.
    """

    # If True, the data argument to expr and get_gradients must be a
    # (X, Y) pair, and Y cannot be None.
    supervised = False

    def expr(self, model, data, ** kwargs):
        """
        .. todo::

            WRITEME

        Parameters
        ----------
        model: a pylearn2 Model instance
        data : a batch in cost.get_data_specs() form

        Returns a symbolic expression for a cost function applied to the
        minibatch of data.
        Optionally, may return None. This represents that the cost function
        is intractable but may be optimized via the get_gradients method.

        """
        raise NotImplementedError(str(type(self)) + " does not implement "
                                  "expr.")

    def get_gradients(self, model, data, ** kwargs):
        """
        .. todo::

            WRITEME

        Parameters
        ----------
        model: a pylearn2 Model instance
        data : a batch in cost.get_data_specs() form

        returns: gradients, updates
            gradients:
                a dictionary mapping from the model's parameters
                         to their gradients
                The default implementation is to compute the gradients
                using T.grad applied to the value returned by expr.
                However, subclasses may return other values for the gradient.
                For example, an intractable cost may return a sampling-based
                approximation to its gradient.
            updates:
                a dictionary mapping shared variables to updates that must
                be applied to them each time these gradients are computed.
                This is to facilitate computation of sampling-based approximate
                gradients.
                The parameters should never appear in the updates dictionary.
                This would imply that computing their gradient changes
                their value, thus making the gradient value outdated.
        """

        try:
            cost = self.expr(model=model, data=data, **kwargs)
        except TypeError, e:
            # If anybody knows how to add type(self) to the exception message
            # but still preserve the stack trace, please do so
            # The current code does neither
            e.message += " while calling " + str(type(self)) + ".expr"
            print str(type(self))
            print e.message
            raise e

        if cost is None:
            raise NotImplementedError(str(type(self)) +
                                      " represents an intractable cost and "
                                      "does not provide a gradient "
                                      "approximation scheme.")

        params = list(model.get_params())

        grads = T.grad(cost, params, disconnected_inputs='ignore')

        gradients = OrderedDict(izip(params, grads))

        updates = OrderedDict()

        return gradients, updates

    def get_monitoring_channels(self, model, data, **kwargs):
        """
        .. todo::

            WRITEME
{'fraction_non_alphanumeric': 0.07436010591350398, 'fraction_numerical': 0.0033097969991173876, 'mean_word_length': 1.770476772616137, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3270083', 'n_tokens_mistral': 2299, 'n_tokens_neox': 2173, 'n_words': 822}