我正在努力正确实施Resilient Propagation。我已经实现了反向传播算法来训练神经网络,并且它按照XOR-Net的预期工作,即大约需要600个Epoch才能将误差降低到1%以下。现在我尝试对同样的问题实施弹性传播(http://en.wikipedia.org/wiki/Rprop),并且前几个时期错误迅速下降到23%但随后提高到50%并保持在那里。
我完全按照http://www.heatonresearch.com/book/introduction-neural-network-math.html中的描述实现了它,但这是一个令人费解的描述:它与维基百科的Rprop-Page和来自同一作者的书中的实现不同,就我而言知道。
我也已经尝试过不同来源的不同实现,但没有任何效果。
各种来源之间的一些差异:
实现这个的正确方法是什么?随后按照书中的实施:
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;
}
答案 0 :(得分:1)
RPROP算法有几种不同的变体。自本书出版以来,Encog已被修改为支持更多。本书侧重于经典的RPROP,由Reidmiller的论文定义。随后的论文提出了额外的算法。这解释了Encog的优化RPROP算法与本书描述的内容之间的一些差异。
查看上面的代码,我有一些建议可能有所帮助。大多数情况下,我不确定你的最后一个条款。你有&#34; double weightChange = 0&#34;,它什么都不做。我认为你需要删除双倍。你还需要为什么&#34;零&#34;建立一些容忍度。是。渐变的变化很少会精确地达到零,所以我会建立一个大约零的范围,可能是-0.00001到+0.00001,因为要触发的else子句。然后确保你实际上将weightChange设置为零。
我从自己的rprop实现中回忆起的另一个问题是,用于反向传播的梯度的符号是用于反向传播的梯度的反转符号。您可以尝试翻转RPROP的渐变符号,这在我的Encog实现中是必需的。
这种RPROP实现可能对您有用,它是经典的Reidmiller实现。它运行正常,误差收敛。
不确定这是否有帮助。没有运行代码,这就是我所看到的。