Künstliche Intelligenz mit Java
Maschinelles Lernen mit Neuronalen Netzwerken

Will man zu Testzwecken oder zu didaktischen Zwecken den Prozess des Lernens dokumentieren, muss man diese Methode über Ausgabebefehle leider „aufblähen“:

  public void trainWithSupervisedLearning() {
    for (int epoche = 1; epoche <= TrainingParameter.numberOfEpochs; epoche++) {
      int sample = new Random().nextInt(TrainingParameter.inputs.length);
      System.out.println("\nsample: " + sample + "   epoche: " +
                         epoche +
 "   number of data: " + (sample+1));
      calculateOutput(TrainingParameter.inputs[sample]);
      DisplayMachineLearning.showOutput(ProcessMonitoring.lastOutputs);
      double totalError = calculateTotalError(TrainingParameter.targets[sample]);
      System.out.println("\ntotal error before: " + totalError);
      makeBackPropagationForOutputLayer(TrainingParameter.targets[sample]);
      makeBackPropagationForHiddenLayer(TrainingParameter.inputs[sample],
                                        TrainingParameter.targets[sample]);
      calculateOutput(TrainingParameter.inputs[sample]);
      totalError = calculateTotalError(TrainingParameter.targets[sample]);
      System.out.println("\ntotal error after backpropagation: " + totalError);
    }
  }

  // die Klasse FeedForwardNetwork geht gleich weiter

Es können unterschiedliche Formeln für die Fehlerberechnung verwendet werden (s. Seite 30). Bei dieser Implementierung wird für jeden der Ausgänge der Quadratische Fehler berechnet und alle Einzelfehler werden dann aufsummiert zum „totalen Fehler“ für eine spezielle Eingabe:

Etotal = ∑ 1/2 * (target–output)²

  private double calculateTotalError(double[] targets) {
    double totalError = 0;
    for (int i = 0; i < ProcessMonitoring.lastOutputs.length; i++)
      totalError += 0.5 * Math.pow(ProcessMonitoring.lastOutputs[i]- targets[i], 2);
    return totalError;
  }

  // die Klasse FeedForwardNetwork geht gleich weiter

Will man den Fehler des Gesamtsystems berechnen, kann man den Durchschnitt aller einzelnen totalen Fehler berechnen:

EtotalAtAll = (Etotal1 + Etotal2 + … + Etotaln) / n

Dies geschieht in der Testmethode testAllInputsAndShowResults(), die für alle Eingangskombinationen die Ausgangswerte ermittelt und diese mit weiteren Prozessdaten (Durchschnittsfehler und Lernerfolg) ausgibt:

  public void testAllInputsAndShowResults() {
    int learnedInPercent = 0;
    double totalErrorAtAll = 0;
    System.out.println();
    for (int i = 0; i < TrainingParameter.inputs.length; i++) {
      calculateOutput(TrainingParameter.inputs[i]);
      System.out.print("output " + (i+1) + ": ");
      totalErrorAtAll += calculateTotalError(TrainingParameter.targets[i]);
      boolean areAllOutputsOK = true;
      for (int j = 0; j < TrainingParameter.targets[0].length; j++) {
        System.out.print(ProcessMonitoring.lastOutputs[j] + "  ");
        if (Math.abs(ProcessMonitoring.lastOutputs[j] - TrainingParameter.targets[i][j]) >
                                                        TrainingParameter.faultTolerance)
          areAllOutputsOK = false;
      }
      if (areAllOutputsOK)
        learnedInPercent++;
      System.out.println();
    }
    learnedInPercent /= TrainingParameter.inputs.length * 0.01;
    totalErrorAtAll /= TrainingParameter.inputs.length;
    System.out.println("\naverage of total errors: " + totalErrorAtAll);
    System.out.println("\nlearned in percent: " + learnedInPercent);
  }

  // die Klasse FeedForwardNetwork geht auf der nächsten Seite weiter

Ist nach dem Training bei einer der n möglichen Eingangskombinationen einer der Ausgangswerte nicht innerhalb der Fehlertoleranz, dann hat das Lernen nicht hundertprozentig funktioniert.

- 44 -