Пример #1
0
    def log_likelihood_lower_bound(self, x):
        x_sequence = tensor.tile(x.dimshuffle('x', 0, 1), (self.T, 1, 1))
        rval = self.apply(x_sequence)
        c_states, mu_phi, log_sigma_phi = rval[0], rval[-2], rval[-1]

        prior_mu = self.prior_mu.dimshuffle('x', 'x', 0)
        prior_log_sigma = self.prior_log_sigma.dimshuffle('x', 'x', 0)
        kl_term = (
            prior_log_sigma - log_sigma_phi +
            0.5 * (
                tensor.exp(2 * log_sigma_phi) + (mu_phi - prior_mu) ** 2
            ) / tensor.exp(2 * prior_log_sigma) - 0.5).sum(axis=2).sum(axis=0)
        kl_term.name = 'kl_term'

        reconstruction_term = - (
            x * tensor.nnet.softplus(-c_states[-1]) +
            (1 - x) * tensor.nnet.softplus(c_states[-1])).sum(axis=1)
        reconstruction_term.name = 'reconstruction_term'

        log_likelihood_lower_bound = reconstruction_term - kl_term
        log_likelihood_lower_bound.name = 'log_likelihood_lower_bound'

        annotation = Annotation()
        annotation.add_auxiliary_variable(kl_term, name='kl_term')
        annotation.add_auxiliary_variable(-reconstruction_term,
                                          name='reconstruction_term')
        add_annotation(log_likelihood_lower_bound, annotation)

        return log_likelihood_lower_bound
Пример #2
0
 def add_auxiliary_variable(self, variable, roles=None, name=None):
     if name:
         variable.name = _variable_name(
             self.application.brick.name, self.application.name, name)
         variable.tag.name = name
         name = None
     add_annotation(variable, self.application.brick)
     return super(ApplicationCall, self).add_auxiliary_variable(
         variable, roles, name)
Пример #3
0
 def add_auxiliary_variable(self, variable, roles=None, name=None):
     if name:
         variable.name = _variable_name(self.brick.name,
                                        self.application.name, name)
         variable.tag.name = name
         name = None
     add_annotation(variable, self.brick)
     return super(ApplicationCall,
                  self).add_auxiliary_variable(variable, roles, name)
Пример #4
0
def copy_and_tag_noise(variable, brick, role, name):
    """Helper method to copy a variable and annotate it."""
    copy = variable.copy()
    # Theano name
    copy.name = "{}_apply_{}".format(brick.name, name)
    add_annotation(copy, brick)
    # Blocks name
    copy.tag.name = name
    add_role(copy, role)
    return copy
Пример #5
0
def copy_and_tag_noise(variable, brick, role, name):
    """Helper method to copy a variable and annotate it."""
    copy = variable.copy()
    # Theano name
    copy.name = "{}_apply_{}".format(brick.name, name)
    add_annotation(copy, brick)
    # Blocks name
    copy.tag.name = name
    add_role(copy, role)
    return copy
Пример #6
0
 def apply(self, *args, **kwargs):
     out = self._apply(*args, **kwargs)
     # ====== add roles ====== #
     tmp = out
     if not isinstance(tmp, (tuple, list)):
         tmp = [out]
     for o in tmp:
         add_role(o, OUTPUT)
         add_annotation(o, self)
     # return outputs
     return out
Пример #7
0
 def copy_and_tag(variable, role, name):
     """Helper method to copy a variable and annotate it."""
     copy = variable.copy()
     # Theano name
     copy.name = _variable_name(brick.name, self.name, name)
     add_annotation(copy, brick)
     add_annotation(copy, call)
     # Blocks name
     copy.tag.name = name
     add_role(copy, role)
     return copy
Пример #8
0
 def copy_and_tag(variable, role, name):
     """Helper method to copy a variable and annotate it."""
     copy = variable.copy()
     # Theano name
     copy.name = _variable_name(brick.name, self.name, name)
     add_annotation(copy, brick)
     add_annotation(copy, call)
     # Blocks name
     copy.tag.name = name
     add_role(copy, role)
     return copy
Пример #9
0
 def get_mean_logsigma(self, x):
     b_mean = 0. if not hasattr(self, 'b_mean') else self.b_mean
     b_logsigma = 0. if not hasattr(self, 'b_logsigma') else self.b_logsigma
     mean = self.activation(K.dot(x, self.W_mean) + b_mean)
     logsigma = self.activation(K.dot(x, self.W_logsigma) + b_logsigma)
     mean.name = 'variational_mean'
     logsigma.name = 'variational_logsigma'
     add_role(mean, VARIATIONAL_MEAN)
     add_annotation(mean, self)
     add_role(logsigma, VARIATIONAL_LOGSIGMA)
     add_annotation(logsigma, self)
     return mean, logsigma
Пример #10
0
    def _allocate(self):
        input_dim = ((self.input_dim, )
                     if not isinstance(self.input_dim, collections.Sequence)
                     else self.input_dim)
        broadcastable = (tuple(False for _ in input_dim)
                         if self.broadcastable is None else self.broadcastable)
        if len(input_dim) != len(broadcastable):
            raise ValueError("input_dim and broadcastable must be same length")
        var_dim = tuple(
            1 if broadcast else dim
            for dim, broadcast in equizip(input_dim, broadcastable))
        broadcastable = broadcastable

        # "gamma", from the Ioffe & Szegedy manuscript.
        self.scale = shared_floatx_nans(var_dim,
                                        name='batch_norm_scale',
                                        broadcastable=broadcastable)

        # "beta", from the Ioffe & Szegedy manuscript.
        self.shift = shared_floatx_nans(var_dim,
                                        name='batch_norm_shift',
                                        broadcastable=broadcastable)
        add_role(self.scale, BATCH_NORM_SCALE_PARAMETER)
        add_role(self.shift, BATCH_NORM_SHIFT_PARAMETER)
        self.parameters.append(self.scale)
        self.parameters.append(self.shift)

        # These aren't technically parameters, in that they should not be
        # learned using the same cost function as other model parameters.
        self.population_mean = shared_floatx_zeros(
            ((self.n_iter, ) if self.n_iter else ()) + var_dim,
            name='population_mean',
            broadcastable=((False, ) if self.n_iter else ()) + broadcastable)
        self.population_stdev = shared_floatx(
            numpy.ones(((self.n_iter, ) if self.n_iter else ()) + var_dim),
            name='population_stdev',
            broadcastable=((False, ) if self.n_iter else ()) + broadcastable)
        add_role(self.population_mean, BATCH_NORM_POPULATION_MEAN)
        add_role(self.population_stdev, BATCH_NORM_POPULATION_STDEV)

        # Normally these would get annotated by an AnnotatingList, but they
        # aren't in self.parameters.
        add_annotation(self.population_mean, self)
        add_annotation(self.population_stdev, self)
Пример #11
0
    def _allocate(self):
        input_dim = ((self.input_dim,)
                     if not isinstance(self.input_dim, collections.Sequence)
                     else self.input_dim)
        broadcastable = (tuple(False for _ in input_dim)
                         if self.broadcastable is None else self.broadcastable)
        if len(input_dim) != len(broadcastable):
            raise ValueError("input_dim and broadcastable must be same length")
        var_dim = tuple(1 if broadcast else dim for dim, broadcast in
                        equizip(input_dim, broadcastable))
        broadcastable = broadcastable

        # "gamma", from the Ioffe & Szegedy manuscript.
        self.scale = shared_floatx_nans(var_dim, name='batch_norm_scale',
                                        broadcastable=broadcastable)

        # "beta", from the Ioffe & Szegedy manuscript.
        self.shift = shared_floatx_nans(var_dim, name='batch_norm_shift',
                                        broadcastable=broadcastable)
        add_role(self.scale, BATCH_NORM_SCALE_PARAMETER)
        add_role(self.shift, BATCH_NORM_SHIFT_PARAMETER)
        self.parameters.append(self.scale)
        self.parameters.append(self.shift)

        # These aren't technically parameters, in that they should not be
        # learned using the same cost function as other model parameters.
        self.population_mean = shared_floatx_zeros(((self.n_iter,) if self.n_iter else ()) + var_dim,
                                                   name='population_mean',
                                                   broadcastable=((False,) if self.n_iter else ()) + broadcastable)
        self.population_stdev = shared_floatx(numpy.ones(((self.n_iter,) if self.n_iter else ()) + var_dim),
                                              name='population_stdev',
                                              broadcastable=((False,) if self.n_iter else ()) + broadcastable)
        add_role(self.population_mean, BATCH_NORM_POPULATION_MEAN)
        add_role(self.population_stdev, BATCH_NORM_POPULATION_STDEV)

        # Normally these would get annotated by an AnnotatingList, but they
        # aren't in self.parameters.
        add_annotation(self.population_mean, self)
        add_annotation(self.population_stdev, self)
Пример #12
0
 def _set(self, key, value):
     if isinstance(value, Variable):
         add_role(value, PARAMETER)
         add_annotation(value, self.brick)
Пример #13
0
 def annotate_update(self, update, tag_to):
     a = Annotation()
     for (var, up) in update:
         a.updates[var] = up
     add_annotation(tag_to, a)
Пример #14
0
 def _setitem(self, key, value):
     if isinstance(value, Variable):
         add_role(value, PARAMETER)
         add_annotation(value, self.brick)
Пример #15
0
 def annotate_update(self, update, tag_to):
     a = Annotation()
     for (var, up) in update:
         a.updates[var] = up
     add_annotation(tag_to, a)
Пример #16
0
def _add_role_and_annotate(var, role, annotations=()):
    """Add a role and zero or more annotations to a variable."""
    add_role(var, role)
    for annotation in annotations:
        add_annotation(var, annotation)
Пример #17
0
 def annotated_statistic(self, var):
     add_annotation(var, self)
     var.tag.batch_normalization_brick = self
     return var
Пример #18
0
    def create_params(self, spec, shape, name, roles=[], annotations=[]):
        if not isinstance(roles, (tuple, list)):
            roles = [roles]
        if not isinstance(annotations, (tuple, list)):
            annotations = [annotations]

        shape = tuple(shape)  # convert to tuple if needed
        if any(d <= 0 for d in shape):
            raise ValueError((
                "Cannot create param with a non-positive shape dimension. "
                "Tried to create param with shape=%r, name=%r") %
                (shape, name))

        #####################################
        # 1. Shared variable, just check the shape.
        if K.is_shared_variable(spec):
            spec_shape = K.eval(K.shape(spec))
            if shape is None:
                shape = spec_shape
            elif tuple(shape) != tuple(spec_shape):
                self.raise_arguments('Given variable has different shape '
                                     'from requirement, %s != %s' %
                                     (str(spec_shape), str(shape)))
        #####################################
        # 2. expression, we can only check number of dimension.
        elif K.is_variable(spec):
            # We cannot check the shape here, Theano expressions (even shared
            # variables) do not have a fixed compile-time shape. We can check the
            # dimensionality though.
            # Note that we cannot assign a name here. We could assign to the
            # `name` attribute of the variable, but the user may have already
            # named the variable and we don't want to override this.
            if shape is not None and K.ndim(spec) != len(shape):
                self.raise_arguments("parameter variable has %d dimensions, "
                                   "should be %d" % (spec.ndim, len(shape)))
        #####################################
        # 3. numpy ndarray, create shared variable wraper for it.
        elif isinstance(spec, np.ndarray):
            if shape is not None and spec.shape != shape:
                raise RuntimeError("parameter array has shape %s, should be "
                                   "%s" % (spec.shape, shape))
            spec = K.variable(spec, name=name)
        #####################################
        # 4. initializing function.
        elif hasattr(spec, '__call__'):
            arr = spec(shape)
            if K.is_shared_variable(arr):
                spec = arr
            elif K.is_variable(arr) and K.ndim(arr) == len(shape):
                spec = arr
            elif isinstance(arr, np.ndarray):
                spec = K.variable(arr, name=name)
        #####################################
        # 5. Exception.
        else:
            raise RuntimeError("cannot initialize parameters: 'spec' is not "
                               "a numpy array, a Theano expression, or a "
                               "callable")
        # ====== create and return params ====== #
        for i in roles:
            if isinstance(i, VariableRole):
                add_role(spec, i)
        for i in annotations:
            if isinstance(i, Annotation):
                add_annotation(spec, i)
        spec.name = name
        # return actual variable or expression
        for i, j in enumerate(self._paramters): # override other parameters with same name
            if j.name == name:
                self._paramters[i] = spec
        if spec not in self._paramters:
            self._paramters.append(spec)
        return spec
Пример #19
0
def _add_role_and_annotate(var, role, annotations=()):
    """Add a role and zero or more annotations to a variable."""
    add_role(var, role)
    for annotation in annotations:
        add_annotation(var, annotation)