'Computes loss and its derivatives.'

def GetLoss(self, train=False):

    input_layer = self.input_layer
    code_layer = self.code_layer
    hyp = code_layer.hyperparams
    wd = self.decoder.params['weight']
    bd = input_layer.params['bias']
    z = code_layer.state
    input_recon = input_layer.approximator
    cm.dot(wd.T, z, target=input_recon)
    input_recon.add_col_vec(bd)
    code_approx = code_layer.approximator
    alpha = hyp.sc_alpha
    gamma = hyp.sc_gamma
    beta = hyp.sc_beta
    input_recon.subtract(input_layer.state, target=input_layer.deriv)
    code_approx.subtract(z, target=code_layer.deriv)
    cm.abs(z, target=code_layer.temp)
    code_layer.temp.sum(axis=1, target=code_layer.dimsize)
    code_layer.dimsize.sum(axis=0, target=code_layer.unitcell)
    loss1 = ((0.5 * beta) * (input_layer.deriv.euclid_norm() ** 2))
    loss2 = ((0.5 * alpha) * (code_layer.deriv.euclid_norm() ** 2))
    loss3 = (gamma * code_layer.unitcell.euclid_norm())
    loss4 = ((loss1 + loss2) + loss3)
    err = []
    for l in [loss1, loss2, loss3, loss4]:
        perf = deepnet_pb2.Metrics()
        perf.MergeFrom(code_layer.proto.performance_stats)
        perf.count = self.batchsize
        perf.error = l
        err.append(perf)
    return err
