'Forward pass through the cost layer.
:type state_below: tensor or layer
:param state_below: The theano expression (or groundhog layer)
representing the input of the cost layer
:type temp: float or tensor scalar
:param temp: scalar representing the temperature that should be used
when sampling from the output distribution
:type use_noise: bool
:param use_noise: flag. If true, noise is used when computing the
output of the model
:type no_noise_bias: bool
:param no_noise_bias: flag, stating if weight noise should be added
to the bias as well, or only to the weights'

def fprop(self, state_below, temp=numpy.float32(1), use_noise=True, additional_inputs=None, no_noise_bias=False):

    if self.rank_n_approx:
        if (use_noise and self.noise_params):
            emb_val = self.rank_n_activ(utils.dot(state_below, (self.W_em1 + self.nW_em1)))
            emb_val = TT.dot((self.W_em2 + self.nW_em2), emb_val)
        else:
            emb_val = self.rank_n_activ(utils.dot(state_below, self.W_em1))
            emb_val = TT.dot(self.W_em2, emb_val)
    elif (use_noise and self.noise_params):
        emb_val = utils.dot(state_below, (self.W_em + self.nW_em))
    else:
        emb_val = utils.dot(state_below, self.W_em)
    if additional_inputs:
        if (use_noise and self.noise_params):
            for (inp, weight, noise_weight) in zip(additional_inputs, self.additional_weights, self.noise_additional_weights):
                emb_val += utils.dot(inp, (noise_weight + weight))
        else:
            for (inp, weight) in zip(additional_inputs, self.additional_weights):
                emb_val += utils.dot(inp, weight)
    self.preactiv = emb_val
    if (use_noise and self.noise_params and (not no_noise_bias)):
        emb_val = TT.nnet.sigmoid((temp * ((emb_val + self.b_em) + self.nb_em)))
    else:
        emb_val = TT.nnet.sigmoid((temp * (emb_val + self.b_em)))
    self.out = emb_val
    self.state_below = state_below
    self.model_output = emb_val
    return emb_val
