Artificial intelligence 弹性反向传播中的Bug?
我正在努力正确地实现弹性传播。我已经实现了反向传播算法来训练神经网络,它的工作原理与XOR网络的预期一样,即大约需要600个纪元才能将误差降至1%以下。现在,我尝试为同样的问题实现弹性传播(),在最初的几个时期,错误迅速下降到23%,但随后上升到50%,并保持不变Artificial intelligence 弹性反向传播中的Bug?,artificial-intelligence,neural-network,backpropagation,encog,Artificial Intelligence,Neural Network,Backpropagation,Encog,我正在努力正确地实现弹性传播。我已经实现了反向传播算法来训练神经网络,它的工作原理与XOR网络的预期一样,即大约需要600个纪元才能将误差降至1%以下。现在,我尝试为同样的问题实现弹性传播(),在最初的几个时期,错误迅速下降到23%,但随后上升到50%,并保持不变 我完全按照中的描述实现了它,但这是一个令人费解的描述:它不同于wikipedia Rprop页面和encog中的实现,据我所知,encog是由与本书相同的作者编写的。 我还尝试了来自不同来源的不同实现,但没有任何效果。 不同来源之间的
我完全按照中的描述实现了它,但这是一个令人费解的描述:它不同于wikipedia Rprop页面和encog中的实现,据我所知,encog是由与本书相同的作者编写的。 我还尝试了来自不同来源的不同实现,但没有任何效果。
不同来源之间的一些差异: 使用signum(CurrentPartialDelivative)代替signum(CurrentPartialDelivative*PreviousPartialDelivative)计算权重变化
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;
}
RPROP算法有几种不同的变体。自本书出版以来,Encog已被修改以支持更多的功能。这本书的重点是经典的RPROP,正如Reimiller的一篇论文所定义的那样。随后的论文提出了额外的算法。这就解释了Encog的优化RPROP算法与书中描述的算法之间的一些差异 看看上面的代码,我有一些建议可能会有所帮助。大多数情况下,我对你最后的else条款没有把握。您有“double weightChange=0”,这将不起任何作用。我想你得把这双鞋拆了。您还需要为“零”设置一些公差。梯度的变化很少精确地达到零,所以我会建立一些关于零的范围,可能-0.00001到+0.00001,以便else子句触发。然后确保您实际将weightChange设置为零 我从自己的rprop实现中记得的另一个问题是,用于反向传播的梯度的符号是用于反向传播的梯度的逆符号。您可以尝试翻转RPROP的梯度符号,这在我的Encog实现中是必要的 RPROP的这个实现可能对您有用,它是典型的Reimiller实现。它确实工作正常,误差收敛
不确定这是否有帮助。在不运行代码的情况下,我看到的就是这些。thx以获取帮助。问题是我没有改变梯度符号。关于你的答案还有一些其他的注意事项:我确实有一个零容忍度,你可以在上面的构造函数中看到它(它的大小来自你的书10^-16),如果signumValue=0,权重变化必须为零(根据你的书和维基百科,编码不同)。最后但并非最不重要的一点:赞美你的书,它们真的很有帮助,特别是对这个领域的新手,准确地描述你必须做什么,并展示它如何工作的具体例子。
@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;
}