logLoss = (
  targets = [],
  predictions = [],
  labels = [],
  eps = 1e-15
) => {
  if (!targets.length || !predictions.length || !labels.length) {
    return;
  }
  return tf.tidy(() => {
    const targetOneHot = tf.oneHot(
      tf.tensor1d(
        targets.map(target => labels.indexOf(String(target))),
        'int32'
      ),
      labels.length
    );
    return tf
      .sub(
        tf.scalar(0),
        tf.sum(
          tf.mul(
            tf.cast(targetOneHot, 'float32'),
            tf.log(
              tf.clipByValue(
                tf.transpose(tf.tensor2d(predictions)),
                eps,
                1 - eps
              )
            )
          ),
          1
        )
      )
      .dataSync();
  });
}
@param {Array} targets - 1-D array of targets
@param {Array} predictions - 2-D array of predictions. shape = [numClasses, numInstances]
@param {Array} labels - array of class labels
@param {Number} eps - small number to prevent Infinity
@return 1-D array of errors