【发布时间】:2013-07-06 07:49:48
【问题描述】:
出于学术目的,我正在尝试使用递归实现反向传播,但似乎我在某个地方出错了。一直在修补它,但要么根本没有学习,要么没有学习第二种模式。
请告诉我哪里出错了。 (这是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();
}
【问题讨论】:
-
您的神经网络结构看起来如何?您使用递归是否有原因?您应该能够通过从输出层开始并以您的方式备份来迭代各个层。
-
Vivin,这个练习的学术点是对BP使用递归。 (不,这不是我的作业,我只是想解决这个问题:)此时的网络非常简单:2-2-1 具有 sigmoid 激活函数的 3 层网络,我正在尝试训练使用 [1, 0]->[0.2] 和 [0, 1]->[0.9] 训练样本。
-
我见过的典型算法迭代地执行此操作;我只是想知道你为什么选择递归。 :)
-
你说得对,这并不常见。数据结构建议的递归偏好。对我来说,从递归的角度来看,树和图更容易掌握。
-
没错,如果您将神经网络视为神经元的图。但是你失去了“层”的语义,我认为那一点信息很重要。但我想当你查看神经元的传出和传入突触时,层是隐式定义的。恕我直言,这只会让事情变得更难一些。 :)
标签: javascript recursion artificial-intelligence neural-network backpropagation