/**
   * Prints network output for the each element from the specified training set.
   *
   * @param neuralNet neural network
   * @param testSet test data set
   */
  public static void testNeuralNetwork(NeuralNetwork neuralNet, DataSet testSet) {

    for (DataSetRow testSetRow : testSet.getRows()) {
      neuralNet.setInput(testSetRow.getInput());
      neuralNet.calculate();
      double[] networkOutput = neuralNet.getOutput();

      System.out.print("Input: " + Arrays.toString(testSetRow.getInput()));
      System.out.print(" Output: " + Arrays.toString(networkOutput));
    }
  }
  /**
   * Calculates predict values for every possible class that instance can be classified as that
   *
   * @param instnc Instance
   * @return Map<Object, Double>
   */
  @Override
  public Map<Object, Double> classDistribution(Instance instnc) {

    // Convert instance to double array
    double[] item = convertInstanceToDoubleArray(instnc);

    // set neural network input
    neuralNet.setInput(item);
    // calculate neural network output
    neuralNet.calculate();

    // find neuron with highest output
    Map<Object, Double> possibilities = new HashMap<Object, Double>();

    for (Neuron neuron : neuralNet.getOutputNeurons()) {
      possibilities.put(neuron.getLabel(), neuron.getOutput());
    }

    return possibilities;
  }
  /**
   * Classifies instance as one of possible classes
   *
   * @param instnc Instance to classify
   * @return Object class as Object
   */
  @Override
  public Object classify(Instance instnc) {

    double[] item = convertInstanceToDoubleArray(instnc);

    // set neural network input
    neuralNet.setInput(item);
    // calculate neural network output
    neuralNet.calculate();

    // find neuron with highest output
    Neuron maxNeuron = null;
    double maxOut = Double.NEGATIVE_INFINITY;
    for (Neuron neuron : neuralNet.getOutputNeurons()) {
      if (neuron.getOutput() > maxOut) {
        maxNeuron = neuron;
        maxOut = neuron.getOutput();
      }
    }

    // and return its label
    return maxNeuron.getLabel();
  }