反向传播算法 – 误差导数计算

在计算误差导数时,我使用了以下方法,但不确定为什么这样做是正确的。

double errorDerivative = (-output * (1-output) *(desiredOutput - output));

当我去掉第一个输出前的负号时,算法失败并达到最大轮次限制。我认为这是正确的,因为从这个例子中可以看到http://homepages.gold.ac.uk/nikolaev/311imlti.htm没有使用负号运算符。

double errorDerivative2 = (output * (1-output) *(desiredOutput - output));

我目前正在查看并修改一个使用随机梯度下降的现有反向传播实现,我希望将其改为使用标准的反向传播算法。目前,它看起来是这样的。

public void applyBackpropagation(double expectedOutput[]) {        // 错误检查,归一化值 ]0;1[        /*for (int i = 0; i < expectedOutput.length; i++) {            double d = expectedOutput[i];            if (d < 0 || d > 1) {                if (d < 0)                    expectedOutput[i] = 0 + epsilon;                else                    expectedOutput[i] = 1 - epsilon;            }        }*/        int i = 0;        for (Neuron n : outputLayer) {            System.out.println("neuron");            ArrayList<Connection> connections = n.getAllInConnections();            for (Connection con : connections) {                double output = n.getOutput();                System.out.println("最终输出是 "+output);                double ai = con.leftNeuron.getOutput();                System.out.println("ai 输出是 "+ai);                double desiredOutput = expectedOutput[i];                double errorDerivative = (-output * (1-output) *(desiredOutput - output));                double errorDerivative2 = (output * (1-output) *(desiredOutput - output));                System.out.println("误差导数是 "+errorDerivative);                System.out.println("我的误差导数是 "+(output * (1-output) *(desiredOutput - output)));                double deltaWeight = -learningRate * errorDerivative2;                double newWeight = con.getWeight() + deltaWeight;                con.setDeltaWeight(deltaWeight);                con.setWeight(newWeight + momentum * con.getPrevDeltaWeight());            }            i++;        }        // 更新隐藏层的权重        for (Neuron n : hiddenLayer) {            ArrayList<Connection> connections = n.getAllInConnections();            for (Connection con : connections) {                double output = n.getOutput();                double ai = con.leftNeuron.getOutput();                double sumKoutputs = 0;                int j = 0;                for (Neuron out_neu : outputLayer) {                    double wjk = out_neu.getConnection(n.id).getWeight();                    double desiredOutput = (double) expectedOutput[j];                    double ak = out_neu.getOutput();                    j++;                    sumKoutputs = sumKoutputs                            + (-(desiredOutput - ak) * ak * (1 - ak) * wjk);                }                double partialDerivative = output * (1 - output) * ai * sumKoutputs;                double deltaWeight = -learningRate * partialDerivative;                double newWeight = con.getWeight() + deltaWeight;                con.setDeltaWeight(deltaWeight);                con.setWeight(newWeight + momentum * con.getPrevDeltaWeight());            }        }    }

回答:

抱歉,我没有时间审查你的代码,你需要提出更具体的问题,然后我才能帮助你。

errorDerivative2 能够工作的原因可能是你使用了这样的权重更新规则:
deltaW = learningRate*errorDerivative2*input

通常,你所说的 ‘errorDerivative2’ 被称为 delta,对于使用 sigmoid 传输函数的神经元,它被定义为:
-output * (1-output) *(desiredOutput - output)

权重更新规则为:
deltaW = -learningRate*delta*input

所以,基本原因是你在 errorDerivative2 上没有使用负号,因为你在另一个地方也省略了一个负号..

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注