出于学术目的,我试图使用递归实现反向传播,但似乎在某个地方出了问题。我已经摆弄了一段时间,但要么完全没有学习效果,要么在第二个模式上没有学习效果。
请告诉我哪里出了问题。(这是JavaScript语法)注意:每次学习周期前错误都会被重置为null
。
this.backpropagate = function(oAnn, aTargetOutput, nLearningRate) { nLearningRate = nLearningRate || 1; var oNode, n = 0; for (sNodeId in oAnn.getOutputGroup().getNodes()) { oNode = oAnn.getOutputGroup().getNodes()[sNodeId]; oNode.setError(aTargetOutput[n] - oNode.getOutputValue()); n ++; } for (sNodeId in oAnn.getInputGroup().getNodes()) { this.backpropagateNode(oAnn.getInputGroup().getNodes()[sNodeId], nLearningRate); }}this.backpropagateNode = function(oNode, nLearningRate) { var nError = oNode.getError(), oOutputNodes, oConn, nWeight, nOutputError, nDerivative = oNode.getOutputValue() * (1 - oNode.getOutputValue()), // Derivative for sigmoid activation funciton nInputValue = oNode.getInputValue(), n; if (nError === null /* Dont do the same node twice */ && oNode.hasOutputs()) { nDerivative = nDerivative || 0.000000000000001; nInputValue = nInputValue || 0.000000000000001; oOutputNodes = oNode.getOutputNodes(); for (n=0; n<oOutputNodes.length; n++) { nOutputError = this.backpropagateNode(oOutputNodes[n], nLearningRate); oConn = oAnn.getConnection(oNode, oOutputNodes[n]); nWeight = oConn.getWeight(); oConn.setWeight(nWeight + nLearningRate * nOutputError * nDerivative * nInputValue); nError += nOutputError * nWeight; } oNode.setError(nError); } return oNode.getError();}
回答:
问题已解决。显然,低维网络更容易陷入局部最小值。了解到高维网络不太可能达到任何最小值,甚至是全局最小值,这一点很容易理解。
实现随每次迭代增加的动量可以让我通过大多数最小值。因此,将权重重新初始化为随机值(-0.5到0.5)并进行多次训练,最终可以让我通过所有这些最小值。
我很高兴地宣布,如果数据是可分类的,我的网络现在在100%的情况下都能完成训练。