我正在努力正确地实现弹性传播。我已经实现了反向传播算法来训练神经网络,并且对于XOR-Net可以按预期工作,即将误差降至1%以下大约需要600个纪元。现在,我尝试针对同一问题实施弹性传播(http://en.wikipedia.org/wiki/Rprop),对于前几个时期,错误迅速下降至23%,但随后又上升至50%并保持在那里。
我完全按照http://www.heatonresearch.com/book/introduction-neural-network-math.html中的描述实现了它,但这是一个令人困惑的描述:据我所知,它与Wikipedia Rprop-Page和encog的实现不同,encog的实现与本书相同。
我也已经尝试了来自不同来源的不同实现,但是没有任何效果。
各种来源之间的一些差异:

使用signum(currentPartialDerivative)代替signum(currentPartialDerivative * previousPartialDerivative)计算权重变化
使用最近的重量变化,而不是新的重量变化的新更新值首先计算重量变化,然后计算新的更新值

实施此方法的正确方法是什么?随后根据书的实现:

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;
}


正常反向传播的相同方法效果很好:

@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;
}

最佳答案

RPROP算法有几种不同的变体。自本书出版以来,对Encog进行了修改以支持其中的更多内容。这本书着重介绍Reidmiller的论文所定义的经典RPROP。随后的论文提出了其他算法。这说明了Encog的优化RPROP算法与本书所描述内容之间的一些差异。

查看上面的代码,我有一些建议可能会有所帮助。通常,我不确定您的最终else条款。您有“ double weightChange = 0”,这将不起作用。我认为您需要删除双打。您还需要为“零”设置一些容差。渐变的变化很少会精确地为零,因此我会为else子句设置约零的范围,从-0.00001到+0.00001。然后确保您将weightChange实际设置为零。

我从自己的rprop实现中回想起的另一个问题是,用于反向传播的渐变符号是用于反向传播的渐变的符号。您可以尝试翻转RPROP的渐变符号,这在我的Encog实现中是必需的。

RPROP的此实现可能对您有用,这是经典的Reidmiller实现。它确实可以正常运行并且错误收敛。

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

不知道这是否有帮助。无需运行代码,这就是我所看到的全部。

关于artificial-intelligence - 弹性反向传播中的错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27334121/

10-12 23:23