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

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

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

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

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