'Compute loss and also deriv w.r.t to it if asked for.
Compute the loss function. Targets should be in self.data, predictions
should be in self.state.
Args:
get_deriv: If True, compute the derivative w.r.t the loss function and put
it in self.deriv.'

def GetLoss(self, get_deriv=False, **kwargs):

    perf = deepnet_pb2.Metrics()
    perf.MergeFrom(self.proto.performance_stats)
    perf.count = self.batchsize
    tiny = self.tiny
    batchsize = self.batchsize
    dimensions = self.dimensions
    numlabels = self.numlabels
    state = self.state
    data = self.data
    state.reshape((numlabels, (dimensions * batchsize)))
    data.reshape((1, (dimensions * batchsize)))
    if (self.loss_function == deepnet_pb2.Layer.CROSS_ENTROPY):
        temp = self.batchsize_temp
        state.get_softmax_correct(data, target=temp)
        perf.correct_preds = temp.sum()
        state.get_softmax_cross_entropy(data, target=temp, tiny=tiny)
        perf.cross_entropy = temp.sum()
        if get_deriv:
            state.apply_softmax_grad(data, target=self.deriv)
    elif (self.loss_function == deepnet_pb2.Layer.SQUARED_LOSS):
        state.apply_softmax_grad(data, target=self.deriv)
        error = (self.deriv.euclid_norm() ** 2)
        perf.error = error
    else:
        raise Exception('Unknown    loss    function    for    Softmax    units.')
    state.reshape(((numlabels * dimensions), batchsize))
    data.reshape((dimensions, batchsize))
    return perf
