Künstliche Intelligenz mit Java
Maschinelles Lernen mit Neuronalen Netzwerken

Die Backpropagation für den Hidden-Layer sieht algorithmisch auf den ersten Blick nicht viel anders aus als für den Output-Layer:

  private void makeBackPropagationForHiddenLayer(double[] trainingData, double[] targets) {
    System.out.println("\nbackpropagation hidden layer\n");
    double[] possibleBiasValuesForHiddenLayer = new double[hiddenLayer.size()];
    for (int i = 0; i < hiddenLayer.size(); i++) {
      int numberOfWeightsInclBias = hiddenLayer.get(i).getWeights().length;
      for (int j = 0; j < numberOfWeightsInclBias; j++) {
        double deltaW = calculateDeltaW(i, j, trainingData, targets);
        double newWeight = hiddenLayer.get(i).getWeights(j) + deltaW;
        if (isNotABiasWeight(j, numberOfWeightsInclBias)) {
          System.out.println("weight adjustment: " + deltaW + "\nnew weight: " + newWeight);
          hiddenLayer.get(i).setWeights(j, newWeight);
        }
        else {
          System.out.println("bias calculation " + (i + 1) + ": " + newWeight);
          possibleBiasValuesForHiddenLayer[i] = newWeight;
        }
      }
    }
    if (TrainingParameter.isBiasBackPropagationDesired)
      setBias(possibleBiasValuesForHiddenLayer, hiddenLayer);
  }

  // die Klasse FeedForwardNetwork geht gleich weiter


Der große Unterschied verbirgt sich in der ausgelagerten Methode calculateDeltaW(…):

  private double calculateDeltaW(int i, int j, double[] trainingData, double[] targets) {
    double[] errors = new double[ProcessMonitoring.lastOutputs.length];
    double errorSum = 0;
    for (int k = 0; k < ProcessMonitoring.lastOutputs.length; k++) {
      double lastOutputK = ProcessMonitoring.lastOutputs[k];
      errors[k] = (targets[k] - lastOutputK) * lastOutputK * (1 - lastOutputK) *
                                                getWeightsOfOutputLayer()[k][i];
      errorSum += errors[k];
    }
    int numberOfWeights = hiddenLayer.get(i).getWeights().length - 1;
    double inputJ = (j < numberOfWeights) ? trainingData[j] : 1;
    double deltaW = errorSum * ProcessMonitoring.lastOutputsFromHiddenLayer[i] *
                         (1 - ProcessMonitoring.lastOutputsFromHiddenLayer[i]) * 
                                        inputJ * TrainingParameter.learningRate;
    return deltaW;
  }

Diese Implementierung realisiert den Algorithmus von S. 31. Jetzt ist endlich die Klasse FeedForwardNetwork vollständig implementiert:

} class FeedForwardNetwork


-47 -