@Override
    public INDArray computeScoreArray(INDArray labels, INDArray preOutput, IActivation activationFn, INDArray mask) {
        labels = labels.castTo(preOutput.dataType());   //No-op if already correct dtype
        INDArray output = activationFn.getActivation(preOutput.dup(), false);
        MixtureDensityComponents mdc = extractComponents(output);
        INDArray scoreArr = negativeLogLikelihood(labels, mdc.alpha, mdc.mu, mdc.sigma);

        if (mask != null) {
            LossUtil.applyMask(scoreArr, mask);
        }

        return scoreArr;
    }
@ Override public INDArray computeScoreArray ( INDArray labels , INDArray preOutput , IActivation activationFn , INDArray mask ) { labels = labels . castTo ( preOutput . dataType ( ) ) ; INDArray output = activationFn . getActivation ( preOutput . dup ( ) , false ) ; MixtureDensityComponents mdc = extractComponents ( output ) ; INDArray scoreArr = negativeLogLikelihood ( labels , mdc . alpha , mdc . mu , mdc . sigma ) ; if ( mask != null ) { LossUtil . applyMask ( scoreArr , mask ) ; } return scoreArr ; }
This method returns the score for each of the given outputs against the
given set of labels.  For a mixture density network, this is done by
extracting the "alpha", "mu", and "sigma" components of each gaussian
and computing the negative log likelihood that the labels fall within
a linear combination of these gaussian distributions.  The smaller
the negative log likelihood, the higher the probability that the given
labels actually would fall within the distribution.  Therefore by
minimizing the negative log likelihood, we get to a position of highest
probability that the gaussian mixture explains the phenomenon.

@param labels Labels give the sample output that the network should
be trying to converge on.
@param preOutput The output of the last layer (before applying the activation function).
@param activationFn The activation function of the current layer.
@param mask Mask to apply to score evaluation (not supported for this cost function).
@return