Failover error?

I am struggling to implement Resilient Propagation. I have already implemented the backpropagation algorithm for training the neural network and it works as expected for the XOR-Net i.e. It takes about 600 Epochs to reset the error below 1%. Now I have tried implementing Resilient Propagation ( http://en.wikipedia.org/wiki/Rprop ) for the same problem and for the first few Epochs the Error drops quickly to 23% but then goes up to 50% and stays there.
I implemented it exactly as described at http://www.heatonresearch.com/book/introduction-neural-network-math.htmlbut this is a perplexing description: it differs from the wikipedia Rprop-Page AND from the implementation, as far as I know it was written by the same author as the book. I've also tried different implementations from different sources already, but nothing worked. Some differences between different sources:

  • using signum (currentPartialDerivative) instead of signum (currentPartialDerivative * previousPartialDerivative) to calculate weight changes
  • using the last weight change instead of the new update value for the new weight change
  • Calculating weight change first and new update values ​​second

What's the correct way to implement this? Subsequently Implementation according to the book:

public ResilientPropagation() {
    initialUpdateValue = 0.01;
    deltaMaximum = 50;
    deltaMinimum = 0.000001;
    negativeEta = 0.5;
    positiveEta = 1.2;
    double zeroTolerance = 0.0000000000000001;
    signum = new Signum(zeroTolerance);

    init();
}

@Override
public double calculateWeightChange(Synapse synapse, double partialDerivative) {
    if (!synapseValues.containsKey(synapse)){
        double initialPartialDerivative = 0;
        synapseValues.put(synapse, new SynapseValues(initialUpdateValue, initialPartialDerivative));
    }

    SynapseValues values = synapseValues.get(synapse);
    double signChange = signum.value(values.lastPartialDerivative * partialDerivative);
    values.lastPartialDerivative = partialDerivative;
    double weightChange = 0;
    if (signChange > 0){
        newUpdateValue = Math.min(positiveEta * values.updateValue, deltaMaximum);
        weightChange = -1*newUpdateValue;
    } else if (signChange < 0){
        newUpdateValue = Math.max(negativeEta * values.updateValue, deltaMinimum);
        weightChange = newUpdateValue;
    } else {
        newUpdateValue = values.updateValue;
        double weightChange = 0;
    }
    values.updateValue = newUpdateValue;
    return weightChange;
}

      

The same method for normal Backpropagation works great:

@Override
public double calculateWeightChange(Synapse synapse, double partialDerivative) {
    double previousChange = previousWeightChange.get(synapse) != null ? previousWeightChange.get(synapse) : 0;
    double weightChange = learningRate * partialDerivative + momentum * previousChange;
    previousWeightChange.put(synapse, weightChange);
    return weightChange;
}

      

+3


source to share


1 answer


There are several different variants of the RPROP algorithm. Encog was modified to support more of these after the book was published. The book focuses on the classic RPROP as defined in Reidmiller's article. Additional algorithms were made in subsequent documents. This explains some of the differences between the optimized RPROP Encog algorithm and what the book describes.

After looking at my code above, I have some tips that might help. Basically I'm not sure about your last phrase. You have "double weightChange = 0" which will do nothing. I think you need to remove the double. You also need to establish some tolerance for what "zero" is. Changing gradients will rarely go to zero exactly, so I would set some range around zero, maybe -0.00001 to +0.00001 for an else clause to shoot. Then make sure you actually set weightChange to zero.

Another problem I remember from my own rprop implementation was that the gradient sign used for backpropagation was the opposite of the gradient sign used for backpropagation. You can try flipping the gradient sign for RPROP, this was needed in my Encog implementation.



This RPROP implementation might be useful for you, this is the classic Reidmiller implementation. It works correctly and the error converges.

https://github.com/encog/encog-java-core/blob/master/src/main/java/org/encog/neural/freeform/training/FreeformResilientPropagation.java

Not sure if this will help. Without running the code, that's all I can see.

+1


source







All Articles